summaryrefslogtreecommitdiffstats
path: root/ui/qt
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--ui/qt/CMakeLists.txt26
-rw-r--r--ui/qt/about_dialog.cpp102
-rw-r--r--ui/qt/about_dialog.ui2
-rw-r--r--ui/qt/accordion_frame.cpp3
-rw-r--r--ui/qt/address_editor_frame.cpp30
-rw-r--r--ui/qt/bluetooth_att_server_attributes_dialog.cpp81
-rw-r--r--ui/qt/bluetooth_att_server_attributes_dialog.h2
-rw-r--r--ui/qt/bluetooth_att_server_attributes_dialog.ui2
-rw-r--r--ui/qt/bluetooth_device_dialog.cpp10
-rw-r--r--ui/qt/bluetooth_device_dialog.h24
-rw-r--r--ui/qt/bluetooth_devices_dialog.cpp15
-rw-r--r--ui/qt/bluetooth_devices_dialog.h2
-rw-r--r--ui/qt/bluetooth_hci_summary_dialog.cpp13
-rw-r--r--ui/qt/bluetooth_hci_summary_dialog.h2
-rw-r--r--ui/qt/byte_view_tab.cpp2
-rw-r--r--ui/qt/capture_comment_dialog.cpp252
-rw-r--r--ui/qt/capture_comment_dialog.h42
-rw-r--r--ui/qt/capture_comment_dialog.ui33
-rw-r--r--ui/qt/capture_event.h1
-rw-r--r--ui/qt/capture_file.cpp12
-rw-r--r--ui/qt/capture_file.h10
-rw-r--r--ui/qt/capture_file_dialog.cpp209
-rw-r--r--ui/qt/capture_file_dialog.h42
-rw-r--r--ui/qt/capture_file_properties_dialog.cpp241
-rw-r--r--ui/qt/capture_file_properties_dialog.h4
-rw-r--r--ui/qt/capture_file_properties_dialog.ui73
-rw-r--r--ui/qt/capture_filter_syntax_worker.cpp14
-rw-r--r--ui/qt/capture_info_dialog.cpp4
-rw-r--r--ui/qt/capture_options_dialog.cpp194
-rw-r--r--ui/qt/capture_options_dialog.h3
-rw-r--r--ui/qt/capture_options_dialog.ui71
-rw-r--r--ui/qt/capture_preferences_frame.cpp11
-rw-r--r--ui/qt/capture_preferences_frame.h2
-rw-r--r--ui/qt/capture_preferences_frame.ui10
-rw-r--r--ui/qt/coloring_rules_dialog.cpp6
-rw-r--r--ui/qt/column_editor_frame.cpp57
-rw-r--r--ui/qt/column_editor_frame.h1
-rw-r--r--ui/qt/column_editor_frame.ui10
-rw-r--r--ui/qt/column_preferences_frame.cpp2
-rw-r--r--ui/qt/compiled_filter_output.cpp31
-rw-r--r--ui/qt/compiled_filter_output.h14
-rw-r--r--ui/qt/conversation_colorize_action.cpp2
-rw-r--r--ui/qt/conversation_dialog.cpp18
-rw-r--r--ui/qt/conversation_dialog.h2
-rw-r--r--ui/qt/conversation_hash_tables_dialog.cpp18
-rw-r--r--ui/qt/decode_as_dialog.cpp6
-rw-r--r--ui/qt/decode_as_dialog.h2
-rw-r--r--ui/qt/display_filter_expression_dialog.cpp4
-rw-r--r--ui/qt/endpoint_dialog.cpp25
-rw-r--r--ui/qt/expert_info_dialog.h2
-rw-r--r--ui/qt/export_dissection_dialog.cpp137
-rw-r--r--ui/qt/export_dissection_dialog.h15
-rw-r--r--ui/qt/export_object_action.cpp1
-rw-r--r--ui/qt/export_object_action.h1
-rw-r--r--ui/qt/export_pdu_dialog.cpp11
-rw-r--r--ui/qt/export_pdu_dialog.h1
-rw-r--r--ui/qt/export_pdu_dialog.ui22
-rw-r--r--ui/qt/extcap_argument.cpp49
-rw-r--r--ui/qt/extcap_argument.h1
-rw-r--r--ui/qt/extcap_argument_multiselect.cpp2
-rw-r--r--ui/qt/extcap_options_dialog.cpp91
-rw-r--r--ui/qt/extcap_options_dialog.h5
-rw-r--r--ui/qt/extcap_options_dialog.ui2
-rw-r--r--ui/qt/file_set_dialog.cpp2
-rw-r--r--ui/qt/file_set_dialog.h2
-rw-r--r--ui/qt/filter_action.cpp24
-rw-r--r--ui/qt/filter_dialog.cpp144
-rw-r--r--ui/qt/filter_dialog.h8
-rw-r--r--ui/qt/filter_expression_frame.cpp2
-rw-r--r--ui/qt/firewall_rules_dialog.cpp6
-rw-r--r--ui/qt/firewall_rules_dialog.h8
-rw-r--r--ui/qt/follow_stream_action.cpp1
-rw-r--r--ui/qt/follow_stream_action.h1
-rw-r--r--ui/qt/follow_stream_dialog.cpp620
-rw-r--r--ui/qt/follow_stream_dialog.h48
-rw-r--r--ui/qt/follow_stream_dialog.ui47
-rw-r--r--ui/qt/font_color_preferences_frame.cpp5
-rw-r--r--ui/qt/funnel_statistics.cpp72
-rw-r--r--ui/qt/funnel_statistics.h14
-rw-r--r--ui/qt/funnel_string_dialog.cpp2
-rw-r--r--ui/qt/funnel_string_dialog.h2
-rw-r--r--ui/qt/funnel_text_dialog.cpp22
-rw-r--r--ui/qt/funnel_text_dialog.h6
-rw-r--r--ui/qt/geometry_state_dialog.cpp85
-rw-r--r--ui/qt/geometry_state_dialog.h34
-rw-r--r--ui/qt/glib_mainloop_on_qeventloop.cpp4
-rw-r--r--ui/qt/glib_mainloop_on_qeventloop.h5
-rw-r--r--ui/qt/gsm_map_summary_dialog.cpp2
-rw-r--r--ui/qt/iax2_analysis_dialog.cpp66
-rw-r--r--ui/qt/iax2_analysis_dialog.h7
-rw-r--r--ui/qt/import_text_dialog.cpp59
-rw-r--r--ui/qt/import_text_dialog.h4
-rw-r--r--ui/qt/interface_frame.cpp32
-rw-r--r--ui/qt/interface_frame.h5
-rw-r--r--ui/qt/interface_toolbar.cpp16
-rw-r--r--ui/qt/interface_toolbar.h2
-rw-r--r--ui/qt/interface_toolbar_reader.cpp4
-rw-r--r--ui/qt/io_console_dialog.cpp1
-rw-r--r--ui/qt/io_graph_action.cpp134
-rw-r--r--ui/qt/io_graph_action.h47
-rw-r--r--ui/qt/io_graph_dialog.cpp1454
-rw-r--r--ui/qt/io_graph_dialog.h102
-rw-r--r--ui/qt/io_graph_dialog.ui54
-rw-r--r--ui/qt/layout_preferences_frame.cpp12
-rw-r--r--ui/qt/lbm_lbtrm_transport_dialog.cpp116
-rw-r--r--ui/qt/lbm_lbtrm_transport_dialog.h2
-rw-r--r--ui/qt/lbm_lbtru_transport_dialog.cpp173
-rw-r--r--ui/qt/lbm_lbtru_transport_dialog.h2
-rw-r--r--ui/qt/lbm_stream_dialog.cpp62
-rw-r--r--ui/qt/lbm_stream_dialog.h2
-rw-r--r--ui/qt/lte_mac_statistics_dialog.cpp140
-rw-r--r--ui/qt/lte_mac_statistics_dialog.h34
-rw-r--r--ui/qt/lte_rlc_graph_dialog.cpp101
-rw-r--r--ui/qt/lte_rlc_graph_dialog.h13
-rw-r--r--ui/qt/lte_rlc_statistics_dialog.cpp292
-rw-r--r--ui/qt/lte_rlc_statistics_dialog.h12
-rw-r--r--ui/qt/main.cpp178
-rw-r--r--ui/qt/main_application.cpp152
-rw-r--r--ui/qt/main_application.h32
-rw-r--r--ui/qt/main_status_bar.cpp131
-rw-r--r--ui/qt/main_status_bar.h2
-rw-r--r--ui/qt/main_window.cpp88
-rw-r--r--ui/qt/main_window.h24
-rw-r--r--ui/qt/main_window_layout.cpp116
-rw-r--r--ui/qt/main_window_preferences_frame.cpp22
-rw-r--r--ui/qt/main_window_preferences_frame.h1
-rw-r--r--ui/qt/main_window_preferences_frame.ui10
-rw-r--r--ui/qt/manage_interfaces_dialog.cpp180
-rw-r--r--ui/qt/manage_interfaces_dialog.h5
-rw-r--r--ui/qt/manager/wireshark_preference.cpp2
-rw-r--r--ui/qt/manuf_dialog.cpp4
-rw-r--r--ui/qt/models/astringlist_list_model.cpp1
-rw-r--r--ui/qt/models/astringlist_list_model.h1
-rw-r--r--ui/qt/models/atap_data_model.cpp49
-rw-r--r--ui/qt/models/atap_data_model.h8
-rw-r--r--ui/qt/models/coloring_rules_delegate.cpp2
-rw-r--r--ui/qt/models/coloring_rules_model.cpp10
-rw-r--r--ui/qt/models/coloring_rules_model.h1
-rw-r--r--ui/qt/models/column_list_model.cpp105
-rw-r--r--ui/qt/models/column_list_model.h6
-rw-r--r--ui/qt/models/decode_as_delegate.cpp16
-rw-r--r--ui/qt/models/decode_as_delegate.h9
-rw-r--r--ui/qt/models/decode_as_model.cpp71
-rw-r--r--ui/qt/models/decode_as_model.h44
-rw-r--r--ui/qt/models/dissector_tables_model.cpp15
-rw-r--r--ui/qt/models/enabled_protocols_model.cpp7
-rw-r--r--ui/qt/models/enabled_protocols_model.h2
-rw-r--r--ui/qt/models/expert_info_model.cpp6
-rw-r--r--ui/qt/models/export_objects_model.cpp2
-rw-r--r--ui/qt/models/fileset_entry_model.cpp7
-rw-r--r--ui/qt/models/fileset_entry_model.h2
-rw-r--r--ui/qt/models/filter_list_model.cpp49
-rw-r--r--ui/qt/models/filter_list_model.h3
-rw-r--r--ui/qt/models/info_proxy_model.cpp1
-rw-r--r--ui/qt/models/interface_sort_filter_model.cpp39
-rw-r--r--ui/qt/models/interface_sort_filter_model.h2
-rw-r--r--ui/qt/models/interface_tree_cache_model.cpp45
-rw-r--r--ui/qt/models/interface_tree_cache_model.h8
-rw-r--r--ui/qt/models/interface_tree_model.cpp22
-rw-r--r--ui/qt/models/interface_tree_model.h26
-rw-r--r--ui/qt/models/packet_list_model.cpp156
-rw-r--r--ui/qt/models/packet_list_model.h19
-rw-r--r--ui/qt/models/packet_list_record.cpp17
-rw-r--r--ui/qt/models/packet_list_record.h4
-rw-r--r--ui/qt/models/pref_delegate.cpp4
-rw-r--r--ui/qt/models/pref_models.cpp103
-rw-r--r--ui/qt/models/pref_models.h60
-rw-r--r--ui/qt/models/profile_model.cpp99
-rw-r--r--ui/qt/models/profile_model.h10
-rw-r--r--ui/qt/models/proto_tree_model.cpp8
-rw-r--r--ui/qt/models/proto_tree_model.h4
-rw-r--r--ui/qt/models/related_packet_delegate.cpp4
-rw-r--r--ui/qt/models/related_packet_delegate.h4
-rw-r--r--ui/qt/models/resolved_addresses_models.cpp66
-rw-r--r--ui/qt/models/resolved_addresses_models.h7
-rw-r--r--ui/qt/models/sparkline_delegate.cpp2
-rw-r--r--ui/qt/models/uat_delegate.h1
-rw-r--r--ui/qt/models/uat_model.cpp175
-rw-r--r--ui/qt/models/uat_model.h14
-rw-r--r--ui/qt/models/voip_calls_info_model.cpp8
-rw-r--r--ui/qt/models/voip_calls_info_model.h1
-rw-r--r--ui/qt/module_preferences_scroll_area.cpp69
-rw-r--r--ui/qt/module_preferences_scroll_area.h2
-rw-r--r--ui/qt/mtp3_summary_dialog.cpp2
-rw-r--r--ui/qt/multicast_statistics_dialog.cpp8
-rw-r--r--ui/qt/packet_comment_dialog.h2
-rw-r--r--ui/qt/packet_diagram.cpp19
-rw-r--r--ui/qt/packet_dialog.cpp74
-rw-r--r--ui/qt/packet_dialog.h2
-rw-r--r--ui/qt/packet_dialog.ui31
-rw-r--r--ui/qt/packet_list.cpp215
-rw-r--r--ui/qt/packet_list.h13
-rw-r--r--ui/qt/packet_range_group_box.cpp27
-rw-r--r--ui/qt/packet_range_group_box.h2
-rw-r--r--ui/qt/preference_editor_frame.cpp38
-rw-r--r--ui/qt/preference_editor_frame.ui8
-rw-r--r--ui/qt/preferences_dialog.cpp77
-rw-r--r--ui/qt/preferences_dialog.h6
-rw-r--r--ui/qt/preferences_dialog.ui36
-rw-r--r--ui/qt/print_dialog.cpp48
-rw-r--r--ui/qt/print_dialog.h6
-rw-r--r--ui/qt/profile_dialog.cpp82
-rw-r--r--ui/qt/profile_dialog.h20
-rw-r--r--ui/qt/profile_dialog.ui40
-rw-r--r--ui/qt/progress_frame.cpp36
-rw-r--r--ui/qt/progress_frame.h12
-rw-r--r--ui/qt/proto_tree.cpp38
-rw-r--r--ui/qt/proto_tree.h2
-rw-r--r--ui/qt/protocol_hierarchy_dialog.cpp2
-rw-r--r--ui/qt/protocol_hierarchy_dialog.h2
-rw-r--r--ui/qt/protocol_preferences_menu.cpp10
-rw-r--r--ui/qt/remote_capture_dialog.cpp64
-rw-r--r--ui/qt/remote_capture_dialog.h2
-rw-r--r--ui/qt/resolved_addresses_dialog.cpp62
-rw-r--r--ui/qt/resolved_addresses_dialog.h8
-rw-r--r--ui/qt/resolved_addresses_dialog.ui29
-rw-r--r--ui/qt/response_time_delay_dialog.cpp2
-rw-r--r--ui/qt/rpc_service_response_time_dialog.cpp26
-rw-r--r--ui/qt/rpc_service_response_time_dialog.h8
-rw-r--r--ui/qt/rsa_keys_frame.cpp8
-rw-r--r--ui/qt/rsa_keys_frame.h2
-rw-r--r--ui/qt/rtp_analysis_dialog.cpp24
-rw-r--r--ui/qt/rtp_analysis_dialog.h4
-rw-r--r--ui/qt/rtp_audio_stream.cpp32
-rw-r--r--ui/qt/rtp_audio_stream.h8
-rw-r--r--ui/qt/rtp_player_dialog.cpp75
-rw-r--r--ui/qt/rtp_player_dialog.h7
-rw-r--r--ui/qt/rtp_stream_dialog.cpp15
-rw-r--r--ui/qt/sctp_all_assocs_dialog.cpp42
-rw-r--r--ui/qt/sctp_all_assocs_dialog.h4
-rw-r--r--ui/qt/sctp_assoc_analyse_dialog.cpp8
-rw-r--r--ui/qt/sctp_assoc_analyse_dialog.h6
-rw-r--r--ui/qt/sctp_chunk_statistics_dialog.cpp12
-rw-r--r--ui/qt/sctp_chunk_statistics_dialog.h3
-rw-r--r--ui/qt/sctp_graph_arwnd_dialog.cpp6
-rw-r--r--ui/qt/sctp_graph_arwnd_dialog.h7
-rw-r--r--ui/qt/sctp_graph_byte_dialog.cpp10
-rw-r--r--ui/qt/sctp_graph_byte_dialog.h5
-rw-r--r--ui/qt/sctp_graph_dialog.cpp26
-rw-r--r--ui/qt/sctp_graph_dialog.h61
-rw-r--r--ui/qt/search_frame.cpp88
-rw-r--r--ui/qt/search_frame.h2
-rw-r--r--ui/qt/search_frame.ui156
-rw-r--r--ui/qt/sequence_diagram.cpp43
-rw-r--r--ui/qt/sequence_diagram.h6
-rw-r--r--ui/qt/sequence_dialog.cpp276
-rw-r--r--ui/qt/sequence_dialog.h19
-rw-r--r--ui/qt/sequence_dialog.ui10
-rw-r--r--ui/qt/service_response_time_dialog.cpp10
-rw-r--r--ui/qt/show_packet_bytes_dialog.cpp94
-rw-r--r--ui/qt/show_packet_bytes_dialog.h9
-rw-r--r--ui/qt/show_packet_bytes_dialog.ui7
-rw-r--r--ui/qt/simple_dialog.cpp12
-rw-r--r--ui/qt/simple_dialog.h2
-rw-r--r--ui/qt/simple_statistics_dialog.cpp6
-rw-r--r--ui/qt/stats_tree_dialog.cpp16
-rw-r--r--ui/qt/stats_tree_dialog.h2
-rw-r--r--ui/qt/strip_headers_dialog.cpp11
-rw-r--r--ui/qt/strip_headers_dialog.h1
-rw-r--r--ui/qt/strip_headers_dialog.ui22
-rw-r--r--ui/qt/supported_protocols_dialog.cpp2
-rw-r--r--ui/qt/tap_parameter_dialog.cpp15
-rw-r--r--ui/qt/tap_parameter_dialog.h2
-rw-r--r--ui/qt/tcp_stream_dialog.cpp164
-rw-r--r--ui/qt/tcp_stream_dialog.h7
-rw-r--r--ui/qt/time_shift_dialog.cpp10
-rw-r--r--ui/qt/time_shift_dialog.h2
-rw-r--r--ui/qt/uat_dialog.cpp126
-rw-r--r--ui/qt/uat_dialog.h4
-rw-r--r--ui/qt/uat_dialog.ui14
-rw-r--r--ui/qt/uat_frame.cpp127
-rw-r--r--ui/qt/uat_frame.h3
-rw-r--r--ui/qt/uat_frame.ui14
-rw-r--r--ui/qt/utils/color_utils.cpp19
-rw-r--r--ui/qt/utils/color_utils.h10
-rw-r--r--ui/qt/utils/data_printer.cpp98
-rw-r--r--ui/qt/utils/data_printer.h5
-rw-r--r--ui/qt/utils/frame_information.cpp4
-rw-r--r--ui/qt/utils/profile_switcher.cpp140
-rw-r--r--ui/qt/utils/profile_switcher.h48
-rw-r--r--ui/qt/utils/proto_node.cpp4
-rw-r--r--ui/qt/utils/qt_ui_utils.cpp116
-rw-r--r--ui/qt/utils/qt_ui_utils.h12
-rw-r--r--ui/qt/utils/rtp_audio_file.cpp16
-rw-r--r--ui/qt/utils/rtp_audio_file.h10
-rw-r--r--ui/qt/utils/rtp_audio_routing_filter.cpp2
-rw-r--r--ui/qt/utils/wireshark_zip_helper.cpp9
-rw-r--r--ui/qt/utils/wireshark_zip_helper.h6
-rw-r--r--ui/qt/voip_calls_dialog.cpp23
-rw-r--r--ui/qt/voip_calls_dialog.h3
-rw-r--r--ui/qt/welcome_page.cpp125
-rw-r--r--ui/qt/welcome_page.h2
-rw-r--r--ui/qt/welcome_page.ui3
-rw-r--r--ui/qt/widgets/additional_toolbar.cpp24
-rw-r--r--ui/qt/widgets/byte_view_text.cpp5
-rw-r--r--ui/qt/widgets/capture_filter_combo.cpp2
-rw-r--r--ui/qt/widgets/capture_filter_edit.cpp4
-rw-r--r--ui/qt/widgets/compression_group_box.cpp69
-rw-r--r--ui/qt/widgets/compression_group_box.h41
-rw-r--r--ui/qt/widgets/copy_from_profile_button.h1
-rw-r--r--ui/qt/widgets/display_filter_combo.cpp89
-rw-r--r--ui/qt/widgets/display_filter_combo.h7
-rw-r--r--ui/qt/widgets/display_filter_edit.cpp73
-rw-r--r--ui/qt/widgets/dissector_syntax_line_edit.cpp15
-rw-r--r--ui/qt/widgets/dissector_syntax_line_edit.h7
-rw-r--r--ui/qt/widgets/field_filter_edit.cpp6
-rw-r--r--ui/qt/widgets/filter_expression_toolbar.cpp34
-rw-r--r--ui/qt/widgets/filter_expression_toolbar.h2
-rw-r--r--ui/qt/widgets/follow_stream_text.cpp118
-rw-r--r--ui/qt/widgets/follow_stream_text.h18
-rw-r--r--ui/qt/widgets/label_stack.cpp4
-rw-r--r--ui/qt/widgets/label_stack.h3
-rw-r--r--ui/qt/widgets/path_selection_edit.cpp12
-rw-r--r--ui/qt/widgets/profile_tree_view.cpp63
-rw-r--r--ui/qt/widgets/profile_tree_view.h13
-rw-r--r--ui/qt/widgets/qcp_axis_ticker_elided.cpp74
-rw-r--r--ui/qt/widgets/qcp_axis_ticker_elided.h38
-rw-r--r--ui/qt/widgets/qcp_axis_ticker_si.cpp74
-rw-r--r--ui/qt/widgets/qcp_axis_ticker_si.h42
-rw-r--r--ui/qt/widgets/qcp_string_legend_item.cpp46
-rw-r--r--ui/qt/widgets/qcp_string_legend_item.h35
-rw-r--r--ui/qt/widgets/resize_header_view.cpp45
-rw-r--r--ui/qt/widgets/resize_header_view.h31
-rw-r--r--ui/qt/widgets/resolved_addresses_view.cpp261
-rw-r--r--ui/qt/widgets/resolved_addresses_view.h50
-rw-r--r--ui/qt/widgets/rowmove_tree_view.cpp98
-rw-r--r--ui/qt/widgets/rowmove_tree_view.h35
-rw-r--r--ui/qt/widgets/rtp_audio_graph.cpp2
-rw-r--r--ui/qt/widgets/splash_overlay.h2
-rw-r--r--ui/qt/widgets/syntax_line_edit.cpp30
-rw-r--r--ui/qt/widgets/traffic_tab.cpp77
-rw-r--r--ui/qt/widgets/traffic_tab.h14
-rw-r--r--ui/qt/widgets/traffic_tree.cpp56
-rw-r--r--ui/qt/widgets/traffic_tree.h2
-rw-r--r--ui/qt/widgets/traffic_types_list.cpp42
-rw-r--r--ui/qt/widgets/traffic_types_list.h4
-rw-r--r--ui/qt/widgets/wireless_timeline.cpp78
-rw-r--r--ui/qt/widgets/wireless_timeline.h14
-rw-r--r--ui/qt/widgets/wireshark_file_dialog.cpp15
-rw-r--r--ui/qt/widgets/wireshark_file_dialog.h9
-rw-r--r--ui/qt/wireless_frame.cpp23
-rw-r--r--ui/qt/wireshark_application.cpp2
-rw-r--r--ui/qt/wireshark_de.ts929
-rw-r--r--ui/qt/wireshark_dialog.cpp4
-rw-r--r--ui/qt/wireshark_dialog.h21
-rw-r--r--ui/qt/wireshark_en.ts821
-rw-r--r--ui/qt/wireshark_es.ts959
-rw-r--r--ui/qt/wireshark_fr.ts973
-rw-r--r--ui/qt/wireshark_it.ts947
-rw-r--r--ui/qt/wireshark_ja_JP.ts907
-rw-r--r--ui/qt/wireshark_ko.ts917
-rw-r--r--ui/qt/wireshark_main_window.cpp664
-rw-r--r--ui/qt/wireshark_main_window.h28
-rw-r--r--ui/qt/wireshark_main_window.ui55
-rw-r--r--ui/qt/wireshark_main_window_slots.cpp480
-rw-r--r--ui/qt/wireshark_pl.ts1327
-rw-r--r--ui/qt/wireshark_ru.ts1342
-rw-r--r--ui/qt/wireshark_sv.ts1001
-rw-r--r--ui/qt/wireshark_tr_TR.ts929
-rw-r--r--ui/qt/wireshark_uk.ts973
-rw-r--r--ui/qt/wireshark_zh_CN.ts897
-rw-r--r--ui/qt/wlan_statistics_dialog.cpp6
362 files changed, 20290 insertions, 7599 deletions
diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt
index 6a1aab9a..3308d6f2 100644
--- a/ui/qt/CMakeLists.txt
+++ b/ui/qt/CMakeLists.txt
@@ -22,6 +22,7 @@ set(WIRESHARK_WIDGET_HEADERS
widgets/capture_filter_combo.h
widgets/capture_filter_edit.h
widgets/clickable_label.h
+ widgets/compression_group_box.h
widgets/copy_from_profile_button.h
widgets/detachable_tabwidget.h
widgets/display_filter_combo.h
@@ -45,7 +46,13 @@ set(WIRESHARK_WIDGET_HEADERS
widgets/path_selection_edit.h
widgets/pref_module_view.h
widgets/profile_tree_view.h
+ widgets/qcp_axis_ticker_elided.h
+ widgets/qcp_axis_ticker_si.h
+ widgets/qcp_string_legend_item.h
widgets/range_syntax_lineedit.h
+ widgets/resize_header_view.h
+ widgets/resolved_addresses_view.h
+ widgets/rowmove_tree_view.h
widgets/rtp_audio_graph.h
widgets/splash_overlay.h
widgets/stock_icon_tool_button.h
@@ -73,6 +80,7 @@ set(WIRESHARK_UTILS_HEADERS
utils/field_information.h
utils/frame_information.h
utils/idata_printable.h
+ utils/profile_switcher.h
utils/proto_node.h
utils/qt_ui_utils.h
utils/rtp_audio_file.h
@@ -140,6 +148,7 @@ set(WIRESHARK_QT_HEADERS
bluetooth_devices_dialog.h
bluetooth_hci_summary_dialog.h
byte_view_tab.h
+ capture_comment_dialog.h
capture_file_dialog.h
capture_file_properties_dialog.h
capture_file.h
@@ -171,7 +180,6 @@ set(WIRESHARK_QT_HEADERS
file_set_dialog.h
filter_action.h
filter_dialog.h
- filter_dialog.h
filter_expression_frame.h
firewall_rules_dialog.h
follow_stream_action.h
@@ -189,6 +197,7 @@ set(WIRESHARK_QT_HEADERS
interface_toolbar_reader.h
interface_toolbar.h
io_console_dialog.h
+ io_graph_action.h
io_graph_dialog.h
layout_preferences_frame.h
lbm_lbtrm_transport_dialog.h
@@ -282,6 +291,7 @@ set(WIRESHARK_WIDGET_SRCS
widgets/capture_filter_combo.cpp
widgets/capture_filter_edit.cpp
widgets/clickable_label.cpp
+ widgets/compression_group_box.cpp
widgets/copy_from_profile_button.cpp
widgets/detachable_tabwidget.cpp
widgets/display_filter_combo.cpp
@@ -305,7 +315,13 @@ set(WIRESHARK_WIDGET_SRCS
widgets/path_selection_edit.cpp
widgets/pref_module_view.cpp
widgets/profile_tree_view.cpp
+ widgets/qcp_axis_ticker_elided.cpp
+ widgets/qcp_axis_ticker_si.cpp
+ widgets/qcp_string_legend_item.cpp
widgets/range_syntax_lineedit.cpp
+ widgets/resize_header_view.cpp
+ widgets/resolved_addresses_view.cpp
+ widgets/rowmove_tree_view.cpp
widgets/rtp_audio_graph.cpp
widgets/splash_overlay.cpp
widgets/stock_icon_tool_button.cpp
@@ -332,6 +348,7 @@ set(WIRESHARK_UTILS_SRCS
utils/data_printer.cpp
utils/field_information.cpp
utils/frame_information.cpp
+ utils/profile_switcher.cpp
utils/proto_node.cpp
utils/qt_ui_utils.cpp
utils/rtp_audio_file.cpp
@@ -394,6 +411,7 @@ set(WIRESHARK_QT_SRC
bluetooth_devices_dialog.cpp
bluetooth_hci_summary_dialog.cpp
byte_view_tab.cpp
+ capture_comment_dialog.cpp
capture_file_dialog.cpp
capture_file_properties_dialog.cpp
capture_file.cpp
@@ -439,6 +457,7 @@ set(WIRESHARK_QT_SRC
interface_toolbar_reader.cpp
interface_toolbar.cpp
io_console_dialog.cpp
+ io_graph_action.cpp
layout_preferences_frame.cpp
lbm_lbtrm_transport_dialog.cpp
lbm_lbtru_transport_dialog.cpp
@@ -558,6 +577,7 @@ set(WIRESHARK_QT_UI
bluetooth_device_dialog.ui
bluetooth_devices_dialog.ui
bluetooth_hci_summary_dialog.ui
+ capture_comment_dialog.ui
capture_file_properties_dialog.ui
capture_info_dialog.ui
capture_options_dialog.ui
@@ -799,6 +819,9 @@ if(USE_qt6)
if(Qt6Multimedia_FOUND)
target_link_libraries(qtui PUBLIC Qt6::Multimedia)
endif()
+ if(Qt6DBus_FOUND)
+ target_link_libraries(qtui PUBLIC Qt6::DBus)
+ endif()
endif()
target_include_directories(qtui
@@ -810,6 +833,7 @@ target_include_directories(qtui
${QT5_INCLUDE_DIRS}
${GCRYPT_INCLUDE_DIRS}
${MINIZIP_INCLUDE_DIRS}
+ ${MINIZIPNG_INCLUDE_DIRS}
${PCAP_INCLUDE_DIRS}
${SPEEXDSP_INCLUDE_DIRS}
${WINSPARKLE_INCLUDE_DIRS}
diff --git a/ui/qt/about_dialog.cpp b/ui/qt/about_dialog.cpp
index 01513030..ea111228 100644
--- a/ui/qt/about_dialog.cpp
+++ b/ui/qt/about_dialog.cpp
@@ -29,16 +29,12 @@
#include <epan/wslua/init_wslua.h>
#endif
-#include "ui/alert_box.h"
#include "ui/util.h"
-#include "ui/help_url.h"
-#include <wsutil/utf8_entities.h>
-#include "file.h"
-#include "wsutil/file_util.h"
-#include "wsutil/tempfile.h"
+#include "wsutil/filesystem.h"
#include "wsutil/plugins.h"
#include "wsutil/version_info.h"
+
#include "ui/capture_globals.h"
#include "extcap.h"
@@ -100,7 +96,33 @@ QStringList AuthorListModel::headerColumns() const
return QStringList() << tr("Name") << tr("Email");
}
+#ifdef HAVE_PLUGINS
static void plugins_add_description(const char *name, const char *version,
+ uint32_t flags, const char *filename,
+ void *user_data)
+{
+ QList<QStringList> *plugin_data = (QList<QStringList> *)user_data;
+ QStringList plugin_types;
+ if (flags & WS_PLUGIN_DESC_DISSECTOR)
+ plugin_types << "dissector";
+ if (flags & WS_PLUGIN_DESC_FILE_TYPE)
+ plugin_types << "file type";
+ if (flags & WS_PLUGIN_DESC_CODEC)
+ plugin_types << "codec";
+ if (flags & WS_PLUGIN_DESC_EPAN)
+ plugin_types << "epan";
+ if (flags & WS_PLUGIN_DESC_TAP_LISTENER)
+ plugin_types << "tap listener";
+ if (flags & WS_PLUGIN_DESC_DFILTER)
+ plugin_types << "dfilter";
+ if (plugin_types.empty())
+ plugin_types << "unknown";
+ QStringList plugin_row = QStringList() << name << version << plugin_types.join(", ") << filename;
+ *plugin_data << plugin_row;
+}
+#endif
+
+static void other_plugins_add_description(const char *name, const char *version,
const char *types, const char *filename,
void *user_data)
{
@@ -109,7 +131,7 @@ static void plugins_add_description(const char *name, const char *version,
*plugin_data << plugin_row;
}
-PluginListModel::PluginListModel(QObject * parent) : AStringListListModel(parent)
+PluginListModel::PluginListModel(QObject *parent) : AStringListListModel(parent)
{
QList<QStringList> plugin_data;
#ifdef HAVE_PLUGINS
@@ -117,10 +139,10 @@ PluginListModel::PluginListModel(QObject * parent) : AStringListListModel(parent
#endif
#ifdef HAVE_LUA
- wslua_plugins_get_descriptions(plugins_add_description, &plugin_data);
+ wslua_plugins_get_descriptions(other_plugins_add_description, &plugin_data);
#endif
- extcap_get_descriptions(plugins_add_description, &plugin_data);
+ extcap_get_descriptions(other_plugins_add_description, &plugin_data);
typeNames_ << QString("");
foreach(QStringList row, plugin_data)
@@ -179,35 +201,36 @@ FolderListModel::FolderListModel(QObject * parent):
AStringListListModel(parent)
{
/* "file open" */
- appendRow(QStringList() << tr("\"File\" dialogs") << get_open_dialog_initial_dir() << tr("capture files"));
+ appendRow(QStringList() << tr("\"File\" dialog location") << get_open_dialog_initial_dir() << tr("Capture files"));
/* temp */
- appendRow(QStringList() << tr("Temp") << (global_capture_opts.temp_dir && global_capture_opts.temp_dir[0] ? global_capture_opts.temp_dir : g_get_tmp_dir()) << tr("untitled capture files"));
+ appendRow(QStringList() << tr("Temp") << (global_capture_opts.temp_dir && global_capture_opts.temp_dir[0] ? global_capture_opts.temp_dir : g_get_tmp_dir())
+ << tr("Untitled capture files"));
/* pers conf */
appendRow(QStringList() << tr("Personal configuration")
- << gchar_free_to_qstring(get_persconffile_path("", FALSE))
- << tr("dfilters, preferences, ethers, …"));
+ << gchar_free_to_qstring(get_persconffile_path("", false))
+ << tr("Preferences, profiles, manuf, …"));
/* global conf */
QString dirPath = get_datafile_dir();
if (! dirPath.isEmpty()) {
appendRow (QStringList() << tr("Global configuration") << dirPath
- << tr("dfilters, preferences, manuf, …"));
+ << tr("Preferences, profiles, manuf, …"));
}
/* system */
appendRow(QStringList() << tr("System") << get_systemfile_dir() << tr("ethers, ipxnets"));
/* program */
- appendRow(QStringList() << tr("Program") << get_progfile_dir() << tr("program files"));
+ appendRow(QStringList() << tr("Program") << get_progfile_dir() << tr("Program files"));
#ifdef HAVE_PLUGINS
/* pers plugins */
- appendRow(QStringList() << tr("Personal Plugins") << get_plugins_pers_dir_with_version() << tr("binary plugins"));
+ appendRow(QStringList() << tr("Personal Plugins") << get_plugins_pers_dir_with_version() << tr("Binary plugins"));
/* global plugins */
- appendRow(QStringList() << tr("Global Plugins") << get_plugins_dir_with_version() << tr("binary plugins"));
+ appendRow(QStringList() << tr("Global Plugins") << get_plugins_dir_with_version() << tr("Binary plugins"));
#endif
#ifdef HAVE_LUA
@@ -219,12 +242,12 @@ FolderListModel::FolderListModel(QObject * parent):
#endif
/* Extcap */
- appendRow(QStringList() << tr("Personal Extcap path") << QString(get_extcap_pers_dir()) << tr("external capture (extcap) plugins"));
- appendRow(QStringList() << tr("Global Extcap path") << QString(get_extcap_dir()) << tr("external capture (extcap) plugins"));
+ appendRow(QStringList() << tr("Personal Extcap path") << QString(get_extcap_pers_dir()) << tr("External capture (extcap) plugins"));
+ appendRow(QStringList() << tr("Global Extcap path") << QString(get_extcap_dir()) << tr("External capture (extcap) plugins"));
#ifdef HAVE_MAXMINDDB
/* MaxMind DB */
- QStringList maxMindDbPaths = QString(maxmind_db_get_paths()).split(G_SEARCHPATH_SEPARATOR_S);
+ QStringList maxMindDbPaths = gchar_free_to_qstring(maxmind_db_get_paths()).split(G_SEARCHPATH_SEPARATOR_S);
foreach(QString path, maxMindDbPaths)
appendRow(QStringList() << tr("MaxMind DB path") << path.trimmed() << tr("MaxMind DB database search path"));
#endif
@@ -263,17 +286,10 @@ AboutDialog::AboutDialog(QWidget *parent) :
QFile f_acknowledgements;
QFile f_license;
- AuthorListModel * authorModel = new AuthorListModel(this);
- AStringListListSortFilterProxyModel * proxyAuthorModel = new AStringListListSortFilterProxyModel(this);
- proxyAuthorModel->setSourceModel(authorModel);
- proxyAuthorModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
- proxyAuthorModel->setColumnToFilter(0);
- proxyAuthorModel->setColumnToFilter(1);
- ui->tblAuthors->setModel(proxyAuthorModel);
- ui->tblAuthors->setRootIsDecorated(false);
- ui->tblAuthors->setContextMenuPolicy(Qt::CustomContextMenu);
- connect(ui->tblAuthors, &QTreeView::customContextMenuRequested, this, &AboutDialog::handleCopyMenu);
- connect(ui->searchAuthors, &QLineEdit::textChanged, proxyAuthorModel, &AStringListListSortFilterProxyModel::setFilter);
+ if (!is_packet_configuration_namespace()) {
+ setWindowTitle(tr("About Logray"));
+ ui->tabWidget->setTabText(ui->tabWidget->indexOf(ui->tab_wireshark), tr("Logray"));
+ }
/* Wireshark tab */
updateWiresharkText();
@@ -286,11 +302,27 @@ AboutDialog::AboutDialog(QWidget *parent) :
ui->label_logo->setPixmap(QPixmap(":/about/wssplash_dev.png"));
#endif
+ /* Authors */
+ AuthorListModel * authorModel = new AuthorListModel(this);
+ AStringListListSortFilterProxyModel * authorProxyModel = new AStringListListSortFilterProxyModel(this);
+ authorProxyModel->setSourceModel(authorModel);
+ authorProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
+ authorProxyModel->setColumnToFilter(0);
+ authorProxyModel->setColumnToFilter(1);
+ ui->tblAuthors->setModel(authorProxyModel);
+ ui->tblAuthors->setRootIsDecorated(false);
+ ui->tblAuthors->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(ui->tblAuthors, &QTreeView::customContextMenuRequested, this, &AboutDialog::handleCopyMenu);
+ connect(ui->searchAuthors, &QLineEdit::textChanged, authorProxyModel, &AStringListListSortFilterProxyModel::setFilter);
+
/* Folders */
FolderListModel * folderModel = new FolderListModel(this);
AStringListListSortFilterProxyModel * folderProxyModel = new AStringListListSortFilterProxyModel(this);
folderProxyModel->setSourceModel(folderModel);
+ folderProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
+ folderProxyModel->setColumnToFilter(0);
folderProxyModel->setColumnToFilter(1);
+ folderProxyModel->setColumnToFilter(2);
folderProxyModel->setFilterType(AStringListListSortFilterProxyModel::FilterByStart);
AStringListListUrlProxyModel * folderDisplayModel = new AStringListListUrlProxyModel(this);
folderDisplayModel->setSourceModel(folderProxyModel);
@@ -306,13 +338,16 @@ AboutDialog::AboutDialog(QWidget *parent) :
connect(ui->searchFolders, &QLineEdit::textChanged, folderProxyModel, &AStringListListSortFilterProxyModel::setFilter);
connect(ui->tblFolders, &QTreeView::doubleClicked, this, &AboutDialog::urlDoubleClicked);
-
/* Plugins */
ui->label_no_plugins->hide();
PluginListModel * pluginModel = new PluginListModel(this);
AStringListListSortFilterProxyModel * pluginFilterModel = new AStringListListSortFilterProxyModel(this);
pluginFilterModel->setSourceModel(pluginModel);
+ pluginFilterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
pluginFilterModel->setColumnToFilter(0);
+ pluginFilterModel->setColumnToFilter(1);
+ pluginFilterModel->setColumnToFilter(2);
+ pluginFilterModel->setColumnToFilter(3);
AStringListListSortFilterProxyModel * pluginTypeModel = new AStringListListSortFilterProxyModel(this);
pluginTypeModel->setSourceModel(pluginFilterModel);
pluginTypeModel->setColumnToFilter(2);
@@ -344,6 +379,7 @@ AboutDialog::AboutDialog(QWidget *parent) :
AStringListListSortFilterProxyModel * shortcutProxyModel = new AStringListListSortFilterProxyModel(this);
shortcutProxyModel->setSourceModel(shortcutModel);
shortcutProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
+ shortcutProxyModel->setColumnToFilter(0);
shortcutProxyModel->setColumnToFilter(1);
shortcutProxyModel->setColumnToFilter(2);
ui->tblShortcuts->setModel(shortcutProxyModel);
@@ -438,7 +474,7 @@ void AboutDialog::showEvent(QShowEvent * event)
void AboutDialog::updateWiresharkText()
{
- QString vcs_version_info_str = get_ws_vcs_version_info();
+ QString vcs_version_info_str = is_packet_configuration_namespace() ? get_ws_vcs_version_info() : get_lr_vcs_version_info();
QString copyright_info_str = get_copyright_info();
QString license_info_str = get_license_info();
QString comp_info_str = gstring_free_to_qbytearray(get_compiled_version_info(gather_wireshark_qt_compiled_info));
diff --git a/ui/qt/about_dialog.ui b/ui/qt/about_dialog.ui
index 4b515de0..bb6de142 100644
--- a/ui/qt/about_dialog.ui
+++ b/ui/qt/about_dialog.ui
@@ -157,7 +157,7 @@
<item>
<widget class="QLineEdit" name="searchFolders">
<property name="placeholderText">
- <string>Filter by path</string>
+ <string>Search Folders</string>
</property>
</widget>
</item>
diff --git a/ui/qt/accordion_frame.cpp b/ui/qt/accordion_frame.cpp
index 8f8cc430..bc1a77d5 100644
--- a/ui/qt/accordion_frame.cpp
+++ b/ui/qt/accordion_frame.cpp
@@ -8,7 +8,6 @@
*/
#include "config.h"
-#include <glib.h>
#include "accordion_frame.h"
@@ -104,4 +103,4 @@ void AccordionFrame::updateStyleSheet()
#endif
setStyleSheet(style_sheet);
-} \ No newline at end of file
+}
diff --git a/ui/qt/address_editor_frame.cpp b/ui/qt/address_editor_frame.cpp
index fb044418..034ac27b 100644
--- a/ui/qt/address_editor_frame.cpp
+++ b/ui/qt/address_editor_frame.cpp
@@ -9,8 +9,6 @@
#include "config.h"
-#include <glib.h>
-
#include "file.h"
#include "frame_tvbuff.h"
@@ -55,8 +53,9 @@ AddressEditorFrame::~AddressEditorFrame()
QString AddressEditorFrame::addressToString(const FieldInformation& finfo)
{
address addr;
- ws_in4_addr ipv4;
- const ws_in6_addr* ipv6;
+ QString addr_str;
+ const ipv4_addr_and_mask *ipv4;
+ const ipv6_addr_and_prefix *ipv6;
if (!finfo.isValid()) {
return QString();
@@ -69,18 +68,24 @@ QString AddressEditorFrame::addressToString(const FieldInformation& finfo)
// proto_item_fill_display_label, but that gives us
// the currently resolved version, if resolution is
// available and enabled. We want the unresolved string.
- ipv4 = fvalue_get_uinteger(finfo.fieldInfo()->value);
- set_address(&addr, AT_IPv4, 4, &ipv4);
- return gchar_free_to_qstring(address_to_str(NULL, &addr));
+ ipv4 = fvalue_get_ipv4(finfo.fieldInfo()->value);
+ set_address_ipv4(&addr, ipv4);
+ addr_str = gchar_free_to_qstring(address_to_str(NULL, &addr));
+ free_address(&addr);
+ break;
case FT_IPv6:
ipv6 = fvalue_get_ipv6(finfo.fieldInfo()->value);
- set_address(&addr, AT_IPv6, sizeof(ws_in6_addr), ipv6);
- return gchar_free_to_qstring(address_to_str(NULL, &addr));
+ set_address_ipv6(&addr, ipv6);
+ addr_str = gchar_free_to_qstring(address_to_str(NULL, &addr));
+ free_address(&addr);
+ break;
default:
- return QString();
+ addr_str = QString();
}
+ return addr_str;
}
+// NOLINTNEXTLINE(misc-no-recursion)
void AddressEditorFrame::addAddresses(const ProtoNode& node, QStringList& addresses)
{
QString addrString = addressToString(FieldInformation(&node));
@@ -89,6 +94,7 @@ void AddressEditorFrame::addAddresses(const ProtoNode& node, QStringList& addres
}
ProtoNode::ChildIterator kids = node.children();
while (kids.element().isValid()) {
+ // We recurse here, but we're limited by tree depth checks in epan
addAddresses(kids.element(), addresses);
kids.next();
}
@@ -119,13 +125,13 @@ void AddressEditorFrame::editAddresses(CaptureFile &cf, int column)
// have one in cap_file_->edt->tree as we have a current frame), but
// this is only a single frame that's previously been dissected so
// the performance hit is slight anyway.
- epan_dissect_init(&edt, cap_file_->epan, TRUE, TRUE);
+ epan_dissect_init(&edt, cap_file_->epan, true, true);
col_custom_prime_edt(&edt, &cap_file_->cinfo);
epan_dissect_run(&edt, cap_file_->cd_t, &cap_file_->rec,
frame_tvbuff_new_buffer(&cap_file_->provider, cap_file_->current_frame, &cap_file_->buf),
cap_file_->current_frame, &cap_file_->cinfo);
- epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
+ epan_dissect_fill_in_columns(&edt, true, true);
addAddresses(ProtoNode(edt.tree), addresses);
diff --git a/ui/qt/bluetooth_att_server_attributes_dialog.cpp b/ui/qt/bluetooth_att_server_attributes_dialog.cpp
index 00330b3c..8191d495 100644
--- a/ui/qt/bluetooth_att_server_attributes_dialog.cpp
+++ b/ui/qt/bluetooth_att_server_attributes_dialog.cpp
@@ -52,6 +52,24 @@ btatt_handle_tap_reset(void *tapinfo_ptr)
tapinfo->tap_reset(tapinfo);
}
+static QTreeWidgetItem *
+item_with_handle_get(QTreeWidget *tableTree, uint16_t handle)
+{
+ QTreeWidgetItemIterator i_item(tableTree);
+
+ while (*i_item) {
+ QTreeWidgetItem *item = static_cast<QTreeWidgetItem*>(*i_item);
+
+ if (item->data(1, Qt::UserRole).value<uint32_t>() == handle) {
+ return item;
+ }
+
+ ++i_item;
+ }
+
+ return NULL;
+}
+
BluetoothAttServerAttributesDialog::BluetoothAttServerAttributesDialog(QWidget &parent, CaptureFile &cf) :
WiresharkDialog(parent, cf),
ui(new Ui::BluetoothAttServerAttributesDialog)
@@ -98,9 +116,9 @@ BluetoothAttServerAttributesDialog::~BluetoothAttServerAttributesDialog()
void BluetoothAttServerAttributesDialog::captureFileClosed()
{
- ui->interfaceComboBox->setEnabled(FALSE);
- ui->deviceComboBox->setEnabled(FALSE);
- ui->removeDuplicatesCheckBox->setEnabled(FALSE);
+ ui->interfaceComboBox->setEnabled(false);
+ ui->deviceComboBox->setEnabled(false);
+ ui->removeDuplicatesCheckBox->setEnabled(false);
WiresharkDialog::captureFileClosed();
}
@@ -170,11 +188,11 @@ void BluetoothAttServerAttributesDialog::on_actionMark_Unmark_Row_triggered()
QBrush fg;
QBrush bg;
- bool is_marked = TRUE;
+ bool is_marked = true;
for (int i = 0; i < ui->tableTreeWidget->columnCount(); i += 1) {
if (current_item->background(i) != QBrush(ColorUtils::fromColorT(&prefs.gui_marked_bg)))
- is_marked = FALSE;
+ is_marked = false;
}
if (is_marked) {
@@ -245,7 +263,7 @@ tap_packet_status BluetoothAttServerAttributesDialog::tapPacket(void *tapinfo_pt
QString handle;
QString uuid;
QString uuid_name;
- gchar *addr = NULL;
+ char *addr = NULL;
if (dialog->file_closed_)
return TAP_PACKET_DONT_REDRAW;
@@ -254,10 +272,11 @@ tap_packet_status BluetoothAttServerAttributesDialog::tapPacket(void *tapinfo_pt
return TAP_PACKET_DONT_REDRAW;
if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID) {
- gchar *interface;
+ char *interface;
const char *interface_name;
- interface_name = epan_get_interface_name(pinfo->epan, pinfo->rec->rec_header.packet_header.interface_id);
+ unsigned section_number = pinfo->rec->presence_flags & WTAP_HAS_SECTION_NUMBER ? pinfo->rec->section_number : 0;
+ interface_name = epan_get_interface_name(pinfo->epan, pinfo->rec->rec_header.packet_header.interface_id, section_number);
interface = wmem_strdup_printf(pinfo->pool, "%u: %s", pinfo->rec->rec_header.packet_header.interface_id, interface_name);
if (dialog->ui->interfaceComboBox->findText(interface) == -1)
@@ -286,24 +305,48 @@ tap_packet_status BluetoothAttServerAttributesDialog::tapPacket(void *tapinfo_pt
uuid_name = QString(print_bluetooth_uuid(pinfo->pool, &tap_handles->uuid));
if (dialog->ui->removeDuplicatesCheckBox->checkState() == Qt::Checked) {
- QTreeWidgetItemIterator i_item(dialog->ui->tableTreeWidget);
-
- while (*i_item) {
- QTreeWidgetItem *item = static_cast<QTreeWidgetItem*>(*i_item);
+ QTreeWidgetItem *item = item_with_handle_get(dialog->ui->tableTreeWidget,
+ tap_handles->handle);
+ if (item) {
if (item->text(column_number_handle) == handle &&
item->text(column_number_uuid) == uuid &&
item->text(column_number_uuid_name) == uuid_name)
return TAP_PACKET_REDRAW;
- ++i_item;
}
}
- QTreeWidgetItem *item = new QTreeWidgetItem(dialog->ui->tableTreeWidget);
- item->setText(column_number_handle, handle);
- item->setText(column_number_uuid, uuid);
- item->setText(column_number_uuid_name, uuid_name);
- item->setData(0, Qt::UserRole, QVariant::fromValue(pinfo->num));
+ QTreeWidgetItem *parent = NULL;
+
+ if (tap_handles->attribute_type == ATTRIBUTE_TYPE_SERVICE) {
+ /* Service declarations are the top level items */
+ parent = dialog->ui->tableTreeWidget->invisibleRootItem();
+ } else if ((tap_handles->uuid.bt_uuid == UUID_GATT_INCLUDE_DECLARATION) ||
+ (tap_handles->uuid.bt_uuid == UUID_GATT_CHARACTERISTIC_DECLARATION)) {
+ /* Characteristic and include declarations are part of services. */
+ parent = item_with_handle_get(dialog->ui->tableTreeWidget,
+ tap_handles->service_handle);
+ } else {
+ /* Each characteristic may have several attributes. */
+ parent = item_with_handle_get(dialog->ui->tableTreeWidget,
+ tap_handles->char_decl_handle);
+ }
+
+ if (parent) {
+ QTreeWidgetItem *item = new QTreeWidgetItem(parent);
+
+ item->setText(column_number_handle, handle);
+ item->setText(column_number_uuid, uuid);
+ item->setText(column_number_uuid_name, uuid_name);
+ item->setData(0, Qt::UserRole, QVariant::fromValue(pinfo->num));
+ item->setData(1, Qt::UserRole, QVariant::fromValue(tap_handles->handle));
+
+ parent->setExpanded(true);
+ } else {
+ /* Do not insert items without a known parent into the tree.
+ * The parent will likely be found later.
+ */
+ }
for (int i = 0; i < dialog->ui->tableTreeWidget->columnCount(); i++) {
dialog->ui->tableTreeWidget->resizeColumnToContents(i);
@@ -336,7 +379,7 @@ void BluetoothAttServerAttributesDialog::on_tableTreeWidget_itemActivated(QTreeW
if (file_closed_)
return;
- guint32 frame_number = item->data(0, Qt::UserRole).value<guint32>();
+ uint32_t frame_number = item->data(0, Qt::UserRole).value<uint32_t>();
emit goToPacket(frame_number);
}
diff --git a/ui/qt/bluetooth_att_server_attributes_dialog.h b/ui/qt/bluetooth_att_server_attributes_dialog.h
index 2d2a4f88..b377d9cc 100644
--- a/ui/qt/bluetooth_att_server_attributes_dialog.h
+++ b/ui/qt/bluetooth_att_server_attributes_dialog.h
@@ -12,8 +12,6 @@
#include <config.h>
-#include <glib.h>
-
#include "wireshark_dialog.h"
#include "cfile.h"
diff --git a/ui/qt/bluetooth_att_server_attributes_dialog.ui b/ui/qt/bluetooth_att_server_attributes_dialog.ui
index ba67973f..a51d3864 100644
--- a/ui/qt/bluetooth_att_server_attributes_dialog.ui
+++ b/ui/qt/bluetooth_att_server_attributes_dialog.ui
@@ -35,7 +35,7 @@
<bool>false</bool>
</property>
<property name="itemsExpandable">
- <bool>false</bool>
+ <bool>true</bool>
</property>
<property name="sortingEnabled">
<bool>true</bool>
diff --git a/ui/qt/bluetooth_device_dialog.cpp b/ui/qt/bluetooth_device_dialog.cpp
index 6e679b8a..d9729c5b 100644
--- a/ui/qt/bluetooth_device_dialog.cpp
+++ b/ui/qt/bluetooth_device_dialog.cpp
@@ -100,7 +100,7 @@ bluetooth_devices_tap(void *data)
}
-BluetoothDeviceDialog::BluetoothDeviceDialog(QWidget &parent, CaptureFile &cf, QString bdAddr, QString name, guint32 interface_id, guint32 adapter_id, gboolean is_local) :
+BluetoothDeviceDialog::BluetoothDeviceDialog(QWidget &parent, CaptureFile &cf, QString bdAddr, QString name, uint32_t interface_id, uint32_t adapter_id, bool is_local) :
WiresharkDialog(parent, cf),
ui(new Ui::BluetoothDeviceDialog)
{
@@ -234,7 +234,7 @@ void BluetoothDeviceDialog::on_actionMark_Unmark_Row_triggered()
{
QBrush fg;
QBrush bg;
- bool is_marked = TRUE;
+ bool is_marked = true;
QTableWidgetItem *current_item = ui->tableWidget->currentItem();
if (!current_item)
@@ -243,7 +243,7 @@ void BluetoothDeviceDialog::on_actionMark_Unmark_Row_triggered()
for (int i = 0; i < ui->tableWidget->columnCount(); i += 1) {
QTableWidgetItem *item = ui->tableWidget->item(current_item->row(), i);
if (item->background() != QBrush(ColorUtils::fromColorT(&prefs.gui_marked_bg)))
- is_marked = FALSE;
+ is_marked = false;
}
if (is_marked) {
@@ -339,7 +339,7 @@ void BluetoothDeviceDialog::tapReset(void *tapinfo_ptr)
*tapinfo->changes = 0;
}
-void BluetoothDeviceDialog::updateChanges(QTableWidget *tableWidget, QString value, const int row, guint *changes, packet_info *pinfo)
+void BluetoothDeviceDialog::updateChanges(QTableWidget *tableWidget, QString value, const int row, unsigned *changes, packet_info *pinfo)
{
QTableWidgetItem *item = tableWidget->item(row, column_number_value);
bluetooth_item_data_t *item_data = VariantPointer<bluetooth_item_data_t>::asPtr(item->data(Qt::UserRole));
@@ -379,7 +379,7 @@ tap_packet_status BluetoothDeviceDialog::tapPacket(void *tapinfo_ptr, packet_inf
bluetooth_device_tap_t *tap_device = static_cast<bluetooth_device_tap_t *>(const_cast<void *>(data));
QString bd_addr;
QString bd_addr_oui;
- const gchar *manuf;
+ const char *manuf;
QTableWidget *tableWidget;
QTableWidgetItem *item;
QString field;
diff --git a/ui/qt/bluetooth_device_dialog.h b/ui/qt/bluetooth_device_dialog.h
index 7ae37bce..a0b408f0 100644
--- a/ui/qt/bluetooth_device_dialog.h
+++ b/ui/qt/bluetooth_device_dialog.h
@@ -12,8 +12,6 @@
#include "config.h"
-#include <glib.h>
-
#include "wireshark_dialog.h"
#include "cfile.h"
@@ -32,18 +30,18 @@ typedef struct _bluetooth_device_tapinfo_t {
tap_reset_cb tap_reset;
tap_packet_cb tap_packet;
QString bdAddr;
- guint32 interface_id;
- guint32 adapter_id;
- gboolean is_local;
+ uint32_t interface_id;
+ uint32_t adapter_id;
+ bool is_local;
void *ui;
- guint *changes;
+ unsigned *changes;
} bluetooth_device_tapinfo_t;
typedef struct _bluetooth_item_data_t {
- guint32 interface_id;
- guint32 adapter_id;
- guint32 frame_number;
- gint changes;
+ uint32_t interface_id;
+ uint32_t adapter_id;
+ uint32_t frame_number;
+ int changes;
} bluetooth_item_data_t;
namespace Ui {
@@ -55,7 +53,7 @@ class BluetoothDeviceDialog : public WiresharkDialog
Q_OBJECT
public:
- explicit BluetoothDeviceDialog(QWidget &parent, CaptureFile &cf, QString bdAddr, QString name, guint32 interface_id, guint32 adapter_id, gboolean is_local);
+ explicit BluetoothDeviceDialog(QWidget &parent, CaptureFile &cf, QString bdAddr, QString name, uint32_t interface_id, uint32_t adapter_id, bool is_local);
~BluetoothDeviceDialog();
public slots:
@@ -77,11 +75,11 @@ private:
bluetooth_device_tapinfo_t tapinfo_;
QMenu context_menu_;
- guint changes_;
+ unsigned changes_;
static void tapReset(void *tapinfo_ptr);
static tap_packet_status tapPacket(void *tapinfo_ptr, packet_info *pinfo, epan_dissect_t *, const void *data, tap_flags_t flags);
- static void updateChanges(QTableWidget *tableWidget, QString value, const int row, guint *changes, packet_info *pinfo);
+ static void updateChanges(QTableWidget *tableWidget, QString value, const int row, unsigned *changes, packet_info *pinfo);
static void saveItemData(QTableWidgetItem *item, bluetooth_device_tap_t *tap_device, packet_info *pinfo);
private slots:
diff --git a/ui/qt/bluetooth_devices_dialog.cpp b/ui/qt/bluetooth_devices_dialog.cpp
index 87d77772..0772b3d7 100644
--- a/ui/qt/bluetooth_devices_dialog.cpp
+++ b/ui/qt/bluetooth_devices_dialog.cpp
@@ -112,8 +112,8 @@ BluetoothDevicesDialog::~BluetoothDevicesDialog()
void BluetoothDevicesDialog::captureFileClosed()
{
- ui->interfaceComboBox->setEnabled(FALSE);
- ui->showInformationStepsCheckBox->setEnabled(FALSE);
+ ui->interfaceComboBox->setEnabled(false);
+ ui->showInformationStepsCheckBox->setEnabled(false);
WiresharkDialog::captureFileClosed();
}
@@ -187,11 +187,11 @@ void BluetoothDevicesDialog::on_actionMark_Unmark_Row_triggered()
{
QBrush fg;
QBrush bg;
- bool is_marked = TRUE;
+ bool is_marked = true;
for (int i = 0; i < ui->tableTreeWidget->columnCount(); i += 1) {
if (ui->tableTreeWidget->currentItem()->background(i) != QBrush(ColorUtils::fromColorT(&prefs.gui_marked_bg)))
- is_marked = FALSE;
+ is_marked = false;
}
if (is_marked) {
@@ -260,7 +260,7 @@ tap_packet_status BluetoothDevicesDialog::tapPacket(void *tapinfo_ptr, packet_in
bluetooth_device_tap_t *tap_device = static_cast<bluetooth_device_tap_t *>(const_cast<void *>(data));
QString bd_addr;
QString bd_addr_oui;
- const gchar *manuf;
+ const char *manuf;
QTreeWidgetItem *item = NULL;
if (dialog->file_closed_)
@@ -270,10 +270,11 @@ tap_packet_status BluetoothDevicesDialog::tapPacket(void *tapinfo_ptr, packet_in
return TAP_PACKET_DONT_REDRAW;
if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID) {
- gchar *interface;
+ char *interface;
const char *interface_name;
- interface_name = epan_get_interface_name(pinfo->epan, pinfo->rec->rec_header.packet_header.interface_id);
+ unsigned section_number = pinfo->rec->presence_flags & WTAP_HAS_SECTION_NUMBER ? pinfo->rec->section_number : 0;
+ interface_name = epan_get_interface_name(pinfo->epan, pinfo->rec->rec_header.packet_header.interface_id, section_number);
interface = wmem_strdup_printf(pinfo->pool, "%u: %s", pinfo->rec->rec_header.packet_header.interface_id, interface_name);
if (dialog->ui->interfaceComboBox->findText(interface) == -1)
diff --git a/ui/qt/bluetooth_devices_dialog.h b/ui/qt/bluetooth_devices_dialog.h
index cf78d9a0..d26039d7 100644
--- a/ui/qt/bluetooth_devices_dialog.h
+++ b/ui/qt/bluetooth_devices_dialog.h
@@ -12,8 +12,6 @@
#include "config.h"
-#include <glib.h>
-
#include "wireshark_dialog.h"
#include "cfile.h"
#include "packet_list.h"
diff --git a/ui/qt/bluetooth_hci_summary_dialog.cpp b/ui/qt/bluetooth_hci_summary_dialog.cpp
index 15d2df5e..c4e59283 100644
--- a/ui/qt/bluetooth_hci_summary_dialog.cpp
+++ b/ui/qt/bluetooth_hci_summary_dialog.cpp
@@ -157,8 +157,8 @@ void BluetoothHciSummaryDialog::captureFileClosing()
void BluetoothHciSummaryDialog::captureFileClosed()
{
- ui->interfaceComboBox->setEnabled(FALSE);
- ui->adapterComboBox->setEnabled(FALSE);
+ ui->interfaceComboBox->setEnabled(false);
+ ui->adapterComboBox->setEnabled(false);
WiresharkDialog::captureFileClosed();
}
@@ -232,11 +232,11 @@ void BluetoothHciSummaryDialog::on_actionMark_Unmark_Row_triggered()
{
QBrush fg;
QBrush bg;
- bool is_marked = TRUE;
+ bool is_marked = true;
for (int i = 0; i < ui->tableTreeWidget->columnCount(); i += 1) {
if (ui->tableTreeWidget->currentItem()->background(i) != QBrush(ColorUtils::fromColorT(&prefs.gui_marked_bg)))
- is_marked = FALSE;
+ is_marked = false;
}
if (is_marked) {
@@ -360,10 +360,11 @@ tap_packet_status BluetoothHciSummaryDialog::tapPacket(void *tapinfo_ptr, packet
name = tr("Unknown");
if (pinfo->rec->presence_flags & WTAP_HAS_INTERFACE_ID) {
- gchar *interface;
+ char *interface;
const char *interface_name;
- interface_name = epan_get_interface_name(pinfo->epan, pinfo->rec->rec_header.packet_header.interface_id);
+ unsigned section_number = pinfo->rec->presence_flags & WTAP_HAS_SECTION_NUMBER ? pinfo->rec->section_number : 0;
+ interface_name = epan_get_interface_name(pinfo->epan, pinfo->rec->rec_header.packet_header.interface_id, section_number);
interface = wmem_strdup_printf(pinfo->pool, "%u: %s", pinfo->rec->rec_header.packet_header.interface_id, interface_name);
if (dialog->ui->interfaceComboBox->findText(interface) == -1)
diff --git a/ui/qt/bluetooth_hci_summary_dialog.h b/ui/qt/bluetooth_hci_summary_dialog.h
index 8bba405e..61796640 100644
--- a/ui/qt/bluetooth_hci_summary_dialog.h
+++ b/ui/qt/bluetooth_hci_summary_dialog.h
@@ -12,8 +12,6 @@
#include "config.h"
-#include <glib.h>
-
#include "wireshark_dialog.h"
#include "cfile.h"
#include "packet_list.h"
diff --git a/ui/qt/byte_view_tab.cpp b/ui/qt/byte_view_tab.cpp
index cf23c24c..6cb8add7 100644
--- a/ui/qt/byte_view_tab.cpp
+++ b/ui/qt/byte_view_tab.cpp
@@ -308,7 +308,7 @@ void ByteViewTab::selectedFieldChanged(FieldInformation *selected)
if (cap_file_->search_in_progress && (cap_file_->hex || (cap_file_->string && cap_file_->packet_data))) {
// In the hex view, only highlight the target bytes or string. The entire
// field can then be displayed by clicking on any of the bytes in the field.
- f_start = cap_file_->search_pos - cap_file_->search_len + 1;
+ f_start = (int)cap_file_->search_pos;
f_length = (int) cap_file_->search_len;
} else {
f_start = selected->position().start;
diff --git a/ui/qt/capture_comment_dialog.cpp b/ui/qt/capture_comment_dialog.cpp
new file mode 100644
index 00000000..8bea4ca4
--- /dev/null
+++ b/ui/qt/capture_comment_dialog.cpp
@@ -0,0 +1,252 @@
+/* packet_comment_dialog.cpp
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "capture_comment_dialog.h"
+#include <ui_capture_comment_dialog.h>
+
+#include "file.h"
+
+#include "ui/simple_dialog.h"
+#include "ui/qt/utils/qt_ui_utils.h"
+#include "main_application.h"
+
+#include <QTabBar>
+#include <QPushButton>
+#include <QPlainTextEdit>
+
+class CaptureCommentTabWidget : public QTabWidget
+{
+ Q_OBJECT
+public:
+ CaptureCommentTabWidget(QWidget *parent = nullptr) : QTabWidget(parent)
+ {
+
+ setTabsClosable(true);
+ setMovable(true);
+ connect(this, &QTabWidget::tabCloseRequested, this, &CaptureCommentTabWidget::closeTab);
+ connect(tabBar(), &QTabBar::tabMoved, this, &CaptureCommentTabWidget::setTabTitles);
+ }
+ int addTab(QWidget *page);
+ void tabRemoved(int index) override;
+ void closeTab(int index);
+ void setReadOnly(bool ro);
+ char** getCommentsText();
+
+private:
+ void setTabTitles(int from, int to);
+};
+
+int CaptureCommentTabWidget::addTab(QWidget *page)
+{
+ return QTabWidget::addTab(page, tr("Comment %1").arg(count() + 1));
+}
+
+void CaptureCommentTabWidget::closeTab(int index)
+{
+ QPlainTextEdit *te;
+ te = qobject_cast<QPlainTextEdit*>(widget(index));
+ if (te != nullptr) {
+ removeTab(index);
+ delete te;
+ }
+}
+
+void CaptureCommentTabWidget::setReadOnly(bool ro)
+{
+ QPlainTextEdit *commentTextEdit;
+ for (int index = 0; index < count(); index++) {
+ commentTextEdit = qobject_cast<QPlainTextEdit*>(widget(index));
+ if (commentTextEdit != nullptr) {
+ commentTextEdit->setReadOnly(ro);
+ }
+ }
+}
+
+void CaptureCommentTabWidget::tabRemoved(int index)
+{
+ setTabTitles(index, count() - 1);
+}
+
+char** CaptureCommentTabWidget::getCommentsText()
+{
+ /* glib 2.68 and later have g_strv_builder which is slightly
+ * more convenient.
+ */
+ QPlainTextEdit *te;
+ GPtrArray *ptr_array = g_ptr_array_new_full(count() + 1, g_free);
+ for (int index = 0; index < count(); index++) {
+ te = qobject_cast<QPlainTextEdit*>(widget(index));
+ if (te != nullptr) {
+ char *str = qstring_strdup(te->toPlainText());
+
+ /*
+ * Make sure this would fit in a pcapng option.
+ *
+ * XXX - 65535 is the maximum size for an option in pcapng;
+ * what if another capture file format supports larger
+ * comments?
+ */
+ if (strlen(str) > 65535) {
+ /* It doesn't fit. Give up. */
+ g_ptr_array_free(ptr_array, true);
+ return nullptr;
+ }
+ g_ptr_array_add(ptr_array, str);
+ }
+ }
+ g_ptr_array_add(ptr_array, nullptr);
+ return (char**)g_ptr_array_free(ptr_array, false);
+}
+
+void CaptureCommentTabWidget::setTabTitles(int from, int to)
+{
+ if (from < to) {
+ for (; from <= to; from++) {
+ this->setTabText(from, tr("Comment %1").arg(from + 1));
+ }
+ } else {
+ for (; from >= to; from--) {
+ this->setTabText(from, tr("Comment %1").arg(from + 1));
+ }
+ }
+}
+
+CaptureCommentDialog::CaptureCommentDialog(QWidget &parent, CaptureFile &capture_file) :
+ WiresharkDialog(parent, capture_file),
+ ui(new Ui::CaptureCommentDialog)
+{
+
+ ui->setupUi(this);
+ loadGeometry();
+ setWindowSubtitle(tr("Edit Capture Comments"));
+
+ ui->sectionTabWidget->setTabBarAutoHide(true);
+ this->actionAddButton = ui->buttonBox->addButton(tr("Add Comment"), QDialogButtonBox::ActionRole);
+ connect(this->actionAddButton, &QPushButton::clicked, this, &CaptureCommentDialog::addComment);
+
+ connect(this, SIGNAL(captureCommentChanged()),
+ mainApp->mainWindow(), SLOT(updateForUnsavedChanges()));
+ QTimer::singleShot(0, this, SLOT(updateWidgets()));
+}
+
+CaptureCommentDialog::~CaptureCommentDialog()
+{
+ delete ui;
+}
+
+void CaptureCommentDialog::addComment()
+{
+ QPlainTextEdit *commentTextEdit;
+ CaptureCommentTabWidget *currentTW = qobject_cast<CaptureCommentTabWidget*>(ui->sectionTabWidget->currentWidget());
+ if (currentTW != nullptr) {
+ commentTextEdit = new QPlainTextEdit(currentTW);
+
+ currentTW->addTab(commentTextEdit);
+ }
+}
+
+void CaptureCommentDialog::updateWidgets()
+{
+ QPlainTextEdit *commentTextEdit;
+ CaptureCommentTabWidget *shbTW;
+ QPushButton *save_bt = ui->buttonBox->button(QDialogButtonBox::Save);
+
+ if (file_closed_ || !cap_file_.isValid()) {
+ for (int shb = 0; shb < ui->sectionTabWidget->count(); shb++) {
+ shbTW = qobject_cast<CaptureCommentTabWidget*>(ui->sectionTabWidget->widget(shb));
+ shbTW->setReadOnly(true);
+ }
+ if (save_bt) {
+ save_bt->setEnabled(false);
+ }
+ actionAddButton->setEnabled(false);
+ WiresharkDialog::updateWidgets();
+ return;
+ }
+
+ bool enable = wtap_dump_can_write(cap_file_.capFile()->linktypes, WTAP_COMMENT_PER_SECTION);
+ save_bt->setEnabled(enable);
+ actionAddButton->setEnabled(enable);
+
+ unsigned num_shbs = wtap_file_get_num_shbs(cap_file_.capFile()->provider.wth);
+ for (unsigned shb_idx = 0; shb_idx < num_shbs; shb_idx++) {
+ shbTW = qobject_cast<CaptureCommentTabWidget*>(ui->sectionTabWidget->widget(shb_idx));
+ if (shbTW == nullptr) {
+ shbTW = new CaptureCommentTabWidget(ui->sectionTabWidget);
+ ui->sectionTabWidget->addTab(shbTW, tr("Section %1").arg(shb_idx + 1));
+ }
+ wtap_block_t shb = wtap_file_get_shb(cap_file_.capFile()->provider.wth, shb_idx);
+ unsigned num_comments = wtap_block_count_option(shb, OPT_COMMENT);
+ char *shb_comment;
+ for (unsigned index = 0; index < num_comments; index++) {
+ commentTextEdit = qobject_cast<QPlainTextEdit*>(shbTW->widget(index));
+ if (commentTextEdit == nullptr) {
+ commentTextEdit = new QPlainTextEdit(shbTW);
+ shbTW->addTab(commentTextEdit);
+ }
+ if (wtap_block_get_nth_string_option_value(shb, OPT_COMMENT, index,
+ &shb_comment) == WTAP_OPTTYPE_SUCCESS) {
+ commentTextEdit->setPlainText(shb_comment);
+ } else {
+ // XXX: Should we warn about this failure?
+ commentTextEdit->setPlainText("");
+ }
+ commentTextEdit->setReadOnly(!enable);
+ }
+ for (unsigned index = shbTW->count(); index > num_comments; index--) {
+ shbTW->closeTab(index - 1);
+ }
+ }
+
+ WiresharkDialog::updateWidgets();
+}
+
+void CaptureCommentDialog::on_buttonBox_helpRequested()
+{
+// mainApp->helpTopicAction(HELP_CAPTURE_COMMENT_DIALOG);
+}
+
+void CaptureCommentDialog::on_buttonBox_accepted()
+{
+ int ret = QDialog::Rejected;
+
+ if (file_closed_ || !cap_file_.capFile()->filename) {
+ done(ret);
+ return;
+ }
+
+ if (wtap_dump_can_write(cap_file_.capFile()->linktypes, WTAP_COMMENT_PER_SECTION))
+ {
+ CaptureCommentTabWidget *current;
+ char** comments_text;
+ for (int shb_idx = 0; shb_idx < ui->sectionTabWidget->count(); shb_idx++) {
+ current = qobject_cast<CaptureCommentTabWidget*>(ui->sectionTabWidget->widget(shb_idx));
+ comments_text = current->getCommentsText();
+ if (comments_text == nullptr) {
+ /* This is the only error we track currently, so it must be
+ * this. Tell the user and give up. */
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ "A comment is too large to save in a capture file.");
+ done(ret);
+ return;
+ }
+ cf_update_section_comments(cap_file_.capFile(), shb_idx, comments_text);
+ emit captureCommentChanged();
+ ret = QDialog::Accepted;
+ }
+ }
+ done(ret);
+}
+
+void CaptureCommentDialog::on_buttonBox_rejected()
+{
+ reject();
+}
+
+#include "capture_comment_dialog.moc"
diff --git a/ui/qt/capture_comment_dialog.h b/ui/qt/capture_comment_dialog.h
new file mode 100644
index 00000000..5e7cb2b3
--- /dev/null
+++ b/ui/qt/capture_comment_dialog.h
@@ -0,0 +1,42 @@
+/** @file
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef CAPTURE_COMMENT_DIALOG_H
+#define CAPTURE_COMMENT_DIALOG_H
+
+#include "wireshark_dialog.h"
+
+namespace Ui {
+class CaptureCommentDialog;
+}
+
+class CaptureCommentDialog : public WiresharkDialog
+{
+ Q_OBJECT
+
+public:
+ explicit CaptureCommentDialog(QWidget &parent, CaptureFile &capture_file);
+ ~CaptureCommentDialog();
+
+signals:
+ void captureCommentChanged();
+
+private slots:
+ void addComment();
+ void updateWidgets();
+ void on_buttonBox_helpRequested();
+ void on_buttonBox_accepted();
+ void on_buttonBox_rejected();
+
+private:
+ QPushButton *actionAddButton;
+ Ui::CaptureCommentDialog *ui;
+};
+
+#endif // CAPTURE_COMMENT_DIALOG_H
diff --git a/ui/qt/capture_comment_dialog.ui b/ui/qt/capture_comment_dialog.ui
new file mode 100644
index 00000000..a30dec03
--- /dev/null
+++ b/ui/qt/capture_comment_dialog.ui
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>CaptureCommentDialog</class>
+ <widget class="QDialog" name="CaptureCommentDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <!--<property name="modal">
+ <bool>true</bool>
+ </property>-->
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTabWidget" name="sectionTabWidget"/>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Save</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+</ui>
diff --git a/ui/qt/capture_event.h b/ui/qt/capture_event.h
index b4db282b..3959ed17 100644
--- a/ui/qt/capture_event.h
+++ b/ui/qt/capture_event.h
@@ -11,6 +11,7 @@
#define CAPTURE_EVENT_H
#include <QEvent>
+#include <QString>
typedef struct _capture_session capture_session;
diff --git a/ui/qt/capture_file.cpp b/ui/qt/capture_file.cpp
index 0fd088b9..5de2c9d4 100644
--- a/ui/qt/capture_file.cpp
+++ b/ui/qt/capture_file.cpp
@@ -85,9 +85,9 @@ CaptureFile::CaptureFile(QObject *parent, capture_file *cap_file) :
file_state_(QString())
{
#ifdef HAVE_LIBPCAP
- capture_callback_add(captureCallback, (gpointer) this);
+ capture_callback_add(captureCallback, (void *) this);
#endif
- cf_callback_add(captureFileCallback, (gpointer) this);
+ cf_callback_add(captureFileCallback, (void *) this);
}
CaptureFile::~CaptureFile()
@@ -239,7 +239,7 @@ capture_file *CaptureFile::globalCapFile()
return &cfile;
}
-gpointer CaptureFile::window()
+void *CaptureFile::window()
{
if (cap_file_) return cap_file_->window;
return NULL;
@@ -250,7 +250,7 @@ void CaptureFile::setCaptureStopFlag(bool stop_flag)
if (cap_file_) cap_file_->stop_flag = stop_flag;
}
-void CaptureFile::captureFileCallback(gint event, gpointer data, gpointer user_data)
+void CaptureFile::captureFileCallback(int event, void *data, void *user_data)
{
CaptureFile *capture_file = static_cast<CaptureFile *>(user_data);
if (!capture_file) return;
@@ -259,7 +259,7 @@ void CaptureFile::captureFileCallback(gint event, gpointer data, gpointer user_d
}
#ifdef HAVE_LIBPCAP
-void CaptureFile::captureCallback(gint event, capture_session *cap_session, gpointer user_data)
+void CaptureFile::captureCallback(int event, capture_session *cap_session, void *user_data)
{
CaptureFile *capture_file = static_cast<CaptureFile *>(user_data);
if (!capture_file) return;
@@ -268,7 +268,7 @@ void CaptureFile::captureCallback(gint event, capture_session *cap_session, gpoi
}
#endif
-void CaptureFile::captureFileEvent(int event, gpointer data)
+void CaptureFile::captureFileEvent(int event, void *data)
{
switch(event) {
case(cf_cb_file_opened):
diff --git a/ui/qt/capture_file.h b/ui/qt/capture_file.h
index 2249f8e0..89be807f 100644
--- a/ui/qt/capture_file.h
+++ b/ui/qt/capture_file.h
@@ -14,8 +14,6 @@
#include <config.h>
-#include <glib.h>
-
#include "cfile.h"
#include "capture_event.h"
@@ -117,7 +115,7 @@ public:
// XXX This shouldn't be needed.
static capture_file *globalCapFile();
- gpointer window();
+ void *window();
signals:
void captureEvent(CaptureEvent);
@@ -146,12 +144,12 @@ public slots:
void setCaptureStopFlag(bool stop_flag = true);
private:
- static void captureFileCallback(gint event, gpointer data, gpointer user_data);
+ static void captureFileCallback(int event, void *data, void *user_data);
#ifdef HAVE_LIBPCAP
- static void captureCallback(gint event, capture_session *cap_session, gpointer user_data);
+ static void captureCallback(int event, capture_session *cap_session, void *user_data);
#endif
- void captureFileEvent(int event, gpointer data);
+ void captureFileEvent(int event, void *data);
void captureSessionEvent(int event, capture_session *cap_session);
const QString &getFileBasename();
diff --git a/ui/qt/capture_file_dialog.cpp b/ui/qt/capture_file_dialog.cpp
index 3e1e6230..884cb3f9 100644
--- a/ui/qt/capture_file_dialog.cpp
+++ b/ui/qt/capture_file_dialog.cpp
@@ -17,12 +17,6 @@
#include "capture_file_dialog.h"
-#ifdef Q_OS_WIN
-#include <windows.h>
-#include "ui/packet_range.h"
-#include "ui/win32/file_dlg_win32.h"
-#else // Q_OS_WIN
-
#include <errno.h>
#include "wsutil/filesystem.h"
#include "wsutil/nstime.h"
@@ -40,12 +34,10 @@
#include <QSortFilterProxyModel>
#include <QSpacerItem>
#include <QVBoxLayout>
-#endif // ! Q_OS_WIN
#include <QPushButton>
#include <QMessageBox>
-#include "epan/prefs.h"
#include <ui/qt/utils/qt_ui_utils.h>
#include <main_application.h>
@@ -55,38 +47,13 @@ static const double HEIGHT_SCALE_FACTOR = 1.4;
CaptureFileDialog::CaptureFileDialog(QWidget *parent, capture_file *cf) :
WiresharkFileDialog(parent),
cap_file_(cf),
-#if !defined(Q_OS_WIN)
display_filter_edit_(NULL),
default_ft_(-1),
save_bt_(NULL),
help_topic_(TOPIC_ACTION_NONE)
-#else
- file_type_(-1)
-#endif
{
- switch (prefs.gui_fileopen_style) {
- case FO_STYLE_LAST_OPENED:
- /* The user has specified that we should start out in the last
- * directory in which we opened a file.
- *
- * The open dialog initial directory will be that directory
- * unless we've never opened a file, in which case it will
- * be the user's personal data file directory.
- */
- setDirectory(mainApp->openDialogInitialDir());
- break;
-
- case FO_STYLE_SPECIFIED:
- /* The user has specified that we should always start out in a
- * specified directory; if they've specified that directory,
- * start out by showing the files in that dir.
- */
- if (prefs.gui_fileopen_dir[0] != '\0')
- setDirectory(prefs.gui_fileopen_dir);
- break;
- }
+ setDirectory(mainApp->openDialogInitialDir());
-#if !defined(Q_OS_WIN)
// Add extra widgets
// https://wiki.qt.io/Qt_project_org_faq#How_can_I_add_widgets_to_my_QFileDialog_instance.3F
setOption(QFileDialog::DontUseNativeDialog, true);
@@ -103,14 +70,10 @@ CaptureFileDialog::CaptureFileDialog(QWidget *parent, capture_file *cf) :
// Left and right boxes for controls and preview
h_box->addLayout(&left_v_box_);
h_box->addLayout(&right_v_box_);
-
-#else // Q_OS_WIN
- merge_type_ = 0;
-#endif // Q_OS_WIN
}
check_savability_t CaptureFileDialog::checkSaveAsWithComments(QWidget *parent, capture_file *cf, int file_type) {
- guint32 comment_types;
+ uint32_t comment_types;
bool all_comment_types_supported = true;
/* What types of comments do we have? */
@@ -191,7 +154,7 @@ check_savability_t CaptureFileDialog::checkSaveAsWithComments(QWidget *parent, c
*/
QList<QAbstractButton *> buttons = msg_dialog.buttons();
for (int i = 0; i < buttons.size(); ++i) {
- QPushButton *button = static_cast<QPushButton *>(buttons.at(i));;
+ QPushButton *button = static_cast<QPushButton *>(buttons.at(i));
button->setAutoDefault(false);
}
@@ -234,7 +197,6 @@ check_savability_t CaptureFileDialog::checkSaveAsWithComments(QWidget *parent, c
}
-#ifndef Q_OS_WIN
void CaptureFileDialog::accept()
{
//
@@ -255,7 +217,6 @@ void CaptureFileDialog::accept()
}
WiresharkFileDialog::accept();
}
-#endif // ! Q_OS_WIN
// You have to use open, merge, saveAs, or exportPackets. We should
@@ -265,98 +226,6 @@ int CaptureFileDialog::exec() {
}
-
-// Windows
-// We use native file dialogs here, rather than the Qt dialog
-#ifdef Q_OS_WIN
-int CaptureFileDialog::selectedFileType() {
- return file_type_;
-}
-
-wtap_compression_type CaptureFileDialog::compressionType() {
- return compression_type_;
-}
-
-int CaptureFileDialog::open(QString &file_name, unsigned int &type, QString &display_filter) {
- QString title_str = mainApp->windowTitleString(tr("Open Capture File"));
- GString *fname = g_string_new(file_name.toUtf8().constData());
- GString *dfilter = g_string_new(display_filter.toUtf8().constData());
- gboolean wof_status;
-
- // XXX Add a widget->HWND routine to qt_ui_utils and use it instead.
- wof_status = win32_open_file((HWND)parentWidget()->effectiveWinId(), title_str.toStdWString().c_str(), fname, &type, dfilter);
- file_name = fname->str;
- display_filter = dfilter->str;
-
- g_string_free(fname, TRUE);
- g_string_free(dfilter, TRUE);
-
- return (int) wof_status;
-}
-
-check_savability_t CaptureFileDialog::saveAs(QString &file_name, bool must_support_all_comments) {
- QString title_str = mainApp->windowTitleString(tr("Save Capture File As"));
- GString *fname = g_string_new(file_name.toUtf8().constData());
- gboolean wsf_status;
-
- wsf_status = win32_save_as_file((HWND)parentWidget()->effectiveWinId(), title_str.toStdWString().c_str(), cap_file_, fname, &file_type_, &compression_type_, must_support_all_comments);
- file_name = fname->str;
-
- g_string_free(fname, TRUE);
-
- if (wsf_status) {
- return checkSaveAsWithComments(parentWidget(), cap_file_, file_type_);
- }
-
- return CANCELLED;
-}
-
-check_savability_t CaptureFileDialog::exportSelectedPackets(QString &file_name, packet_range_t *range, QString selRange) {
- QString title_str = mainApp->windowTitleString(tr("Export Specified Packets"));
- GString *fname = g_string_new(file_name.toUtf8().constData());
- gboolean wespf_status;
-
- if (selRange.length() > 0)
- {
- packet_range_convert_selection_str(range, selRange.toUtf8().constData());
- }
-
- wespf_status = win32_export_specified_packets_file((HWND)parentWidget()->effectiveWinId(), title_str.toStdWString().c_str(), cap_file_, fname, &file_type_, &compression_type_, range);
- file_name = fname->str;
-
- g_string_free(fname, TRUE);
-
- if (wespf_status) {
- return checkSaveAsWithComments(parentWidget(), cap_file_, file_type_);
- }
-
- return CANCELLED;
-}
-
-int CaptureFileDialog::merge(QString &file_name, QString &display_filter) {
- QString title_str = mainApp->windowTitleString(tr("Merge Capture File"));
- GString *fname = g_string_new(file_name.toUtf8().constData());
- GString *dfilter = g_string_new(display_filter.toUtf8().constData());
- gboolean wmf_status;
-
-
- wmf_status = win32_merge_file((HWND)parentWidget()->effectiveWinId(), title_str.toStdWString().c_str(), fname, dfilter, &merge_type_);
- file_name = fname->str;
- display_filter = dfilter->str;
-
- g_string_free(fname, TRUE);
- g_string_free(dfilter, TRUE);
-
- return (int) wmf_status;
-}
-
-int CaptureFileDialog::mergeType() {
- return merge_type_;
-}
-
-#else // ! Q_OS_WIN
-// Not Windows
-// We use the Qt dialogs here
QString CaptureFileDialog::fileExtensionType(int et, bool extension_globs)
{
QString extension_type_name;
@@ -420,7 +289,7 @@ QString CaptureFileDialog::fileType(int ft, QStringList &suffixes)
filter = " (";
- extensions_list = wtap_get_file_extensions_list(ft, TRUE);
+ extensions_list = wtap_get_file_extensions_list(ft, true);
if (extensions_list == NULL) {
/* This file type doesn't have any particular extension
conventionally used for it, so we'll just use a
@@ -438,7 +307,7 @@ QString CaptureFileDialog::fileType(int ft, QStringList &suffixes)
for (GSList *extension = extensions_list; extension != NULL;
extension = g_slist_next(extension)) {
QString suffix((char *)extension->data);
- filter += " *." + suffix;;
+ filter += " *." + suffix;
suffixes << suffix;
}
wtap_free_extensions_list(extensions_list);
@@ -549,23 +418,22 @@ void CaptureFileDialog::fixFilenameExtension()
}
// Fixup the new suffix based on whether we're compressing or not.
- if (compressionType() == WTAP_UNCOMPRESSED) {
- // Not compressing; strip off any compression suffix
- GSList *compression_type_extensions = wtap_get_all_compression_type_extensions_list();
- for (GSList *compression_type_extension = compression_type_extensions;
- compression_type_extension != NULL;
- compression_type_extension = g_slist_next(compression_type_extension)) {
- QString suffix = QString(".") + (char *)compression_type_extension->data;
- if (new_suffix.endsWith(suffix)) {
- //
- // It ends with this compression suffix; chop it off.
- //
- new_suffix.chop(suffix.size());
- break;
- }
+ // Strip off any compression suffix
+ GSList *compression_type_extensions = wtap_get_all_compression_type_extensions_list();
+ for (GSList *compression_type_extension = compression_type_extensions;
+ compression_type_extension != NULL;
+ compression_type_extension = g_slist_next(compression_type_extension)) {
+ QString suffix = QString(".") + (char *)compression_type_extension->data;
+ if (new_suffix.endsWith(suffix)) {
+ //
+ // It ends with this compression suffix; chop it off.
+ //
+ new_suffix.chop(suffix.size());
+ break;
}
- g_slist_free(compression_type_extensions);
- } else {
+ }
+ g_slist_free(compression_type_extensions);
+ if (compressionType() != WTAP_UNCOMPRESSED) {
// Compressing; append the appropriate compression suffix.
QString compressed_file_extension = QString(".") + wtap_compression_type_extension(compressionType());
if (valid_extensions.contains(new_suffix + compressed_file_extension)) {
@@ -634,7 +502,7 @@ int CaptureFileDialog::selectedFileType() {
}
wtap_compression_type CaptureFileDialog::compressionType() {
- return compress_.isChecked() ? WTAP_GZIP_COMPRESSED : WTAP_UNCOMPRESSED;
+ return compress_group_box_.compressionType();
}
void CaptureFileDialog::addDisplayFilterEdit(QString &display_filter) {
@@ -670,15 +538,11 @@ void CaptureFileDialog::addFormatTypeSelector(QVBoxLayout &v_box) {
}
void CaptureFileDialog::addGzipControls(QVBoxLayout &v_box) {
- compress_.setText(tr("Compress with g&zip"));
- if (cap_file_->compression_type == WTAP_GZIP_COMPRESSED &&
- wtap_dump_can_compress(default_ft_)) {
- compress_.setChecked(true);
- } else {
- compress_.setChecked(false);
+ if (wtap_dump_can_compress(default_ft_)) {
+ compress_group_box_.setCompressionType(cap_file_->compression_type);
}
- v_box.addWidget(&compress_, 0, Qt::AlignTop);
- connect(&compress_, &QCheckBox::stateChanged, this, &CaptureFileDialog::fixFilenameExtension);
+ v_box.addWidget(&compress_group_box_, 0, Qt::AlignTop);
+ connect(&compress_group_box_, &CompressionGroupBox::stateChanged, this, &CaptureFileDialog::fixFilenameExtension);
}
@@ -724,7 +588,7 @@ int CaptureFileDialog::open(QString &file_name, unsigned int &type, QString &dis
}
if (WiresharkFileDialog::exec() && selectedFiles().length() > 0) {
- file_name = selectedFiles()[0];
+ file_name = selectedNativePath();
type = open_info_name_to_type(qPrintable(format_type_.currentText()));
display_filter.append(display_filter_edit_->text());
@@ -757,7 +621,7 @@ check_savability_t CaptureFileDialog::saveAs(QString &file_name, bool must_suppo
if (WiresharkFileDialog::exec() && selectedFiles().length() > 0) {
int file_type;
- file_name = selectedFiles()[0];
+ file_name = selectedNativePath();
file_type = selectedFileType();
/* Is the file type bogus? */
if (file_type == WTAP_FILE_TYPE_SUBTYPE_UNKNOWN) {
@@ -807,7 +671,7 @@ check_savability_t CaptureFileDialog::exportSelectedPackets(QString &file_name,
if (WiresharkFileDialog::exec() && selectedFiles().length() > 0) {
int file_type;
- file_name = selectedFiles()[0];
+ file_name = selectedNativePath();
file_type = selectedFileType();
/* Is the file type bogus? */
if (file_type == WTAP_FILE_TYPE_SUBTYPE_UNKNOWN) {
@@ -842,7 +706,7 @@ int CaptureFileDialog::merge(QString &file_name, QString &display_filter) {
resize(width() * WIDTH_SCALE_FACTOR, height() * HEIGHT_SCALE_FACTOR + right_v_box_.minimumSize().height() + display_filter_edit_->minimumSize().height());
if (WiresharkFileDialog::exec() && selectedFiles().length() > 0) {
- file_name.append(selectedFiles()[0]);
+ file_name.append(selectedNativePath());
display_filter.append(display_filter_edit_->text());
return QDialog::Accepted;
@@ -853,9 +717,9 @@ int CaptureFileDialog::merge(QString &file_name, QString &display_filter) {
QStringList CaptureFileDialog::buildFileSaveAsTypeList(bool must_support_all_comments) {
QStringList filters;
- guint32 required_comment_types;
+ uint32_t required_comment_types;
GArray *savable_file_types_subtypes;
- guint i;
+ unsigned i;
type_hash_.clear();
type_suffixes_.clear();
@@ -885,7 +749,7 @@ QStringList CaptureFileDialog::buildFileSaveAsTypeList(bool must_support_all_com
filters << type_name + fileType(ft, type_suffixes_[type_name]);
type_hash_[type_name] = ft;
}
- g_array_free(savable_file_types_subtypes, TRUE);
+ g_array_free(savable_file_types_subtypes, true);
}
return filters;
@@ -909,7 +773,7 @@ void CaptureFileDialog::preview(const QString & path)
{
wtap *wth;
int err;
- gchar *err_info;
+ char *err_info;
ws_file_preview_stats stats;
ws_file_preview_stats_status status;
time_t ti_time;
@@ -933,7 +797,7 @@ void CaptureFileDialog::preview(const QString & path)
return;
}
- wth = wtap_open_offline(path.toUtf8().data(), WTAP_TYPE_AUTO, &err, &err_info, TRUE);
+ wth = wtap_open_offline(path.toUtf8().data(), WTAP_TYPE_AUTO, &err, &err_info, true);
if (wth == NULL) {
if (err == WTAP_ERR_FILE_UNKNOWN_FORMAT) {
preview_format_.setText(tr("unknown file format"));
@@ -952,7 +816,7 @@ void CaptureFileDialog::preview(const QString & path)
preview_format_.setText(QString::fromUtf8(wtap_file_type_subtype_description(wtap_file_type_subtype(wth))));
// Size
- gint64 filesize = wtap_file_size(wth, &err);
+ int64_t filesize = wtap_file_size(wth, &err);
// Finder and Windows Explorer use IEC. What do the various Linux file managers use?
QString size_str(gchar_free_to_qstring(format_size(filesize, FORMAT_SIZE_UNIT_BYTES, FORMAT_SIZE_PREFIX_IEC)));
@@ -963,6 +827,7 @@ void CaptureFileDialog::preview(const QString & path)
g_free(err_info);
preview_size_.setText(tr("%1, error after %Ln data record(s)", "", stats.records)
.arg(size_str));
+ wtap_close(wth);
return;
}
@@ -1032,5 +897,3 @@ void CaptureFileDialog::on_buttonBox_helpRequested()
{
if (help_topic_ != TOPIC_ACTION_NONE) mainApp->helpTopicAction(help_topic_);
}
-
-#endif // ! Q_OS_WIN
diff --git a/ui/qt/capture_file_dialog.h b/ui/qt/capture_file_dialog.h
index 1e22ad8b..2c48100a 100644
--- a/ui/qt/capture_file_dialog.h
+++ b/ui/qt/capture_file_dialog.h
@@ -12,11 +12,10 @@
#include <ui/qt/widgets/wireshark_file_dialog.h>
-#ifndef Q_OS_WIN
#include <ui/qt/widgets/display_filter_edit.h>
+#include <ui/qt/widgets/compression_group_box.h>
#include "packet_range_group_box.h"
#include "ui/help_url.h"
-#endif // Q_OS_WIN
#include <ui/packet_range.h>
@@ -43,14 +42,27 @@ class CaptureFileDialog : public WiresharkFileDialog
//
// You can subclass QFileDialog (which we've done here) and add widgets as
// described at
- // https://web.archive.org/web/20100528190736/http://developer.qt.nokia.com/faq/answer/how_can_i_add_widgets_to_my_qfiledialog_instance
+ //
+ // https://web.archive.org/web/20100528190736/http://developer.qt.nokia.com/faq/answer/how_can_i_add_widgets_to_my_qfiledialog_instance
+ //
// However, Qt's idea of what a file dialog looks like isn't what Microsoft
// and Apple think a file dialog looks like.
//
- // On Windows Vista and later we should probably use IFileOpenDialog. On earlier
- // versions of Windows (including XP) we should use GetOpenFileName, which is
- // what we do in ui/win32/file_dlg_win32.c. macOS we should use NSOpenPanel. On
- // other platforms we should fall back to QFileDialog.
+ // On Windows, we should probably use the Common Item Dialog:
+ //
+ // https://learn.microsoft.com/en-us/windows/win32/shell/common-file-dialog
+ //
+ // We currently use GetOpenFileNam in ui/win32/file_dlg_win32.c.
+ //
+ // On macOS we should use NSOpenPanel and NSSavePanel:
+ //
+ // https://developer.apple.com/documentation/appkit/nsopenpanel?language=objc
+ // https://developer.apple.com/documentation/appkit/nssavepanel?language=objc
+ //
+ // On other platforms we should fall back to QFileDialog (or maybe
+ // KDE's or GTK+/GNOME's file dialog, as appropriate for the desktop
+ // environment being used, if QFileDialog doesn't do so with various
+ // platform plugins).
//
// Yes, that's four implementations of the same window.
//
@@ -62,9 +74,6 @@ class CaptureFileDialog : public WiresharkFileDialog
public:
explicit CaptureFileDialog(QWidget *parent = NULL, capture_file *cf = NULL);
static check_savability_t checkSaveAsWithComments(QWidget *
-#if defined(Q_OS_WIN)
- parent
-#endif // Q_OS_WIN
, capture_file *cf, int file_type);
int mergeType();
@@ -74,7 +83,6 @@ public:
private:
capture_file *cap_file_;
-#if !defined(Q_OS_WIN)
void addMergeControls(QVBoxLayout &v_box);
void addFormatTypeSelector(QVBoxLayout &v_box);
void addDisplayFilterEdit(QString &display_filter);
@@ -110,25 +118,17 @@ private:
int default_ft_;
- QCheckBox compress_;
+ CompressionGroupBox compress_group_box_;
PacketRangeGroupBox packet_range_group_box_;
QPushButton *save_bt_;
topic_action_e help_topic_;
-#else // Q_OS_WIN
- int file_type_;
- int merge_type_;
- wtap_compression_type compression_type_;
-#endif // Q_OS_WIN
-
signals:
public slots:
-#ifndef Q_OS_WIN
void accept() Q_DECL_OVERRIDE;
-#endif
int exec() Q_DECL_OVERRIDE;
int open(QString &file_name, unsigned int &type, QString &display_filter);
check_savability_t saveAs(QString &file_name, bool must_support_comments);
@@ -136,11 +136,9 @@ public slots:
int merge(QString &file_name, QString &display_filter);
private slots:
-#if !defined(Q_OS_WIN)
void fixFilenameExtension();
void preview(const QString & path);
void on_buttonBox_helpRequested();
-#endif // Q_OS_WIN
};
#endif // CAPTURE_FILE_DIALOG_H
diff --git a/ui/qt/capture_file_properties_dialog.cpp b/ui/qt/capture_file_properties_dialog.cpp
index c7705681..9b4458dc 100644
--- a/ui/qt/capture_file_properties_dialog.cpp
+++ b/ui/qt/capture_file_properties_dialog.cpp
@@ -15,12 +15,16 @@
#include "ui/simple_dialog.h"
#include "ui/summary.h"
+#include "wiretap/secrets-types.h"
+
+#include "wsutil/filesystem.h"
#include "wsutil/str_util.h"
#include "wsutil/utf8_entities.h"
#include "wsutil/version_info.h"
#include <ui/qt/utils/qt_ui_utils.h>
#include "main_application.h"
+#include "capture_comment_dialog.h"
#include <QPushButton>
#include <QScrollBar>
@@ -39,10 +43,6 @@ CaptureFilePropertiesDialog::CaptureFilePropertiesDialog(QWidget &parent, Captur
ui->detailsTextEdit->setAcceptRichText(true);
- // make the details box larger than the comments
- ui->splitter->setStretchFactor(0, 6);
- ui->splitter->setStretchFactor(1, 1);
-
QPushButton *button = ui->buttonBox->button(QDialogButtonBox::Reset);
if (button) {
button->setText(tr("Refresh"));
@@ -53,16 +53,14 @@ CaptureFilePropertiesDialog::CaptureFilePropertiesDialog(QWidget &parent, Captur
button->setText(tr("Copy To Clipboard"));
}
- button = ui->buttonBox->button(QDialogButtonBox::Save);
- if (button) {
- button->setText(tr("Save Comments"));
- }
-
button = ui->buttonBox->button(QDialogButtonBox::Close);
if (button) {
button->setDefault(true);
}
+ ui->buttonBox->addButton(ui->actionEditButton, QDialogButtonBox::ActionRole);
+ connect(ui->actionEditButton, &QPushButton::clicked, this, &CaptureFilePropertiesDialog::addCaptureComment);
+
setWindowSubtitle(tr("Capture File Properties"));
QTimer::singleShot(0, this, SLOT(updateWidgets()));
}
@@ -81,34 +79,16 @@ CaptureFilePropertiesDialog::~CaptureFilePropertiesDialog()
void CaptureFilePropertiesDialog::updateWidgets()
{
QPushButton *refresh_bt = ui->buttonBox->button(QDialogButtonBox::Reset);
- QPushButton *save_bt = ui->buttonBox->button(QDialogButtonBox::Save);
if (file_closed_ || !cap_file_.isValid()) {
if (refresh_bt) {
refresh_bt->setEnabled(false);
}
- ui->commentsTextEdit->setReadOnly(true);
- if (save_bt) {
- save_bt->setEnabled(false);
- }
WiresharkDialog::updateWidgets();
return;
}
- bool enable = wtap_dump_can_write(cap_file_.capFile()->linktypes, WTAP_COMMENT_PER_SECTION);
- save_bt->setEnabled(enable);
- ui->commentsTextEdit->setEnabled(enable);
-
fillDetails();
- // XXX - this just handles the first comment in the first section;
- // add support for multiple sections with multiple comments.
- wtap_block_t shb = wtap_file_get_shb(cap_file_.capFile()->provider.wth, 0);
- char *shb_comment;
- if (wtap_block_get_nth_string_option_value(shb, OPT_COMMENT, 0,
- &shb_comment) == WTAP_OPTTYPE_SUCCESS)
- ui->commentsTextEdit->setText(shb_comment);
- else
- ui->commentsTextEdit->setText(NULL);
WiresharkDialog::updateWidgets();
}
@@ -192,7 +172,7 @@ QString CaptureFilePropertiesDialog::summaryToHtml()
QString encaps_str;
if (summary.file_encap_type == WTAP_ENCAP_PER_PACKET) {
- for (guint i = 0; i < summary.packet_encap_types->len; i++)
+ for (unsigned i = 0; i < summary.packet_encap_types->len; i++)
{
encaps_str = QString(wtap_encap_description(g_array_index(summary.packet_encap_types, int, i)));
}
@@ -221,15 +201,23 @@ QString CaptureFilePropertiesDialog::summaryToHtml()
out << table_begin;
// start time
- out << table_row_begin
- << table_vheader_tmpl.arg(tr("First packet"))
- << table_data_tmpl.arg(time_t_to_qstring((time_t)summary.start_time))
+ out << table_row_begin;
+ if (is_packet_configuration_namespace()) {
+ out << table_vheader_tmpl.arg(tr("First packet"));
+ } else {
+ out << table_vheader_tmpl.arg(tr("First event"));
+ }
+ out << table_data_tmpl.arg(time_t_to_qstring((time_t)summary.start_time))
<< table_row_end;
// stop time
- out << table_row_begin
- << table_vheader_tmpl.arg(tr("Last packet"))
- << table_data_tmpl.arg(time_t_to_qstring((time_t)summary.stop_time))
+ out << table_row_begin;
+ if (is_packet_configuration_namespace()) {
+ out << table_vheader_tmpl.arg(tr("Last packet"));
+ } else {
+ out << table_vheader_tmpl.arg(tr("Last event"));
+ }
+ out << table_data_tmpl.arg(time_t_to_qstring((time_t)summary.stop_time))
<< table_row_end;
// elapsed seconds (capture duration)
@@ -257,20 +245,21 @@ QString CaptureFilePropertiesDialog::summaryToHtml()
}
// Information from file sections.
- for (guint section_number = 0;
+ for (unsigned section_number = 0;
section_number < wtap_file_get_num_shbs(cap_file_.capFile()->provider.wth);
section_number++) {
// If we have more than one section, add headers for each section.
if (wtap_file_get_num_shbs(cap_file_.capFile()->provider.wth) > 1)
out << section_tmpl_.arg(QString(tr("Section %1"))
- .arg(section_number));
+ .arg(section_number + 1));
+
+ wtap_block_t shb_inf = wtap_file_get_shb(cap_file_.capFile()->provider.wth, section_number);
// Capture Section
out << section_tmpl_.arg(tr("Capture"));
out << table_begin;
- wtap_block_t shb_inf = wtap_file_get_shb(cap_file_.capFile()->provider.wth, section_number);
char *str;
if (shb_inf != nullptr) {
@@ -317,15 +306,25 @@ QString CaptureFilePropertiesDialog::summaryToHtml()
out << table_begin;
out << table_ul_row_begin
- << table_hheader20_tmpl.arg(tr("Interface"))
- << table_hheader20_tmpl.arg(tr("Dropped packets"))
- << table_hheader20_tmpl.arg(tr("Capture filter"))
- << table_hheader20_tmpl.arg(tr("Link type"))
- << table_hheader20_tmpl.arg(tr("Packet size limit (snaplen)"))
- << table_row_end;
+ << table_hheader20_tmpl.arg(tr("Interface"));
+ if (is_packet_configuration_namespace()) {
+ out << table_hheader20_tmpl.arg(tr("Dropped packets"));
+ } else {
+ out << table_hheader20_tmpl.arg(tr("Dropped events"));
+ }
+ out << table_hheader20_tmpl.arg(tr("Capture filter"))
+ << table_hheader20_tmpl.arg(tr("Link type"));
+ if (is_packet_configuration_namespace()) {
+ out << table_hheader20_tmpl.arg(tr("Packet size limit (snaplen)"));
+ } else {
+ out << table_hheader20_tmpl.arg(tr("Event size limit (snaplen)"));
+ }
+ out << table_row_end;
}
- for (guint i = 0; i < summary.ifaces->len; i++) {
+ // XXX: The mapping of interfaces to different SHBs isn't
+ // handled correctly here or elsewhere
+ for (unsigned i = 0; i < summary.ifaces->len; i++) {
iface_summary_info iface;
iface = g_array_index(summary.ifaces, iface_summary_info, i);
@@ -342,7 +341,7 @@ QString CaptureFilePropertiesDialog::summaryToHtml()
if (iface.drops_known) {
interface_drops = QString("%1 (%2%)").arg(iface.drops).arg(QString::number(
/* MSVC cannot convert from unsigned __int64 to float, so first convert to signed __int64 */
- summary.packet_count ? (100.0 * (gint64)iface.drops)/summary.packet_count : 0, 'f', 1));
+ summary.packet_count ? (100.0 * (int64_t)iface.drops)/summary.packet_count : 0, 'f', 1));
}
/* Capture filter */
@@ -366,6 +365,57 @@ QString CaptureFilePropertiesDialog::summaryToHtml()
if (summary.ifaces->len > 0) {
out << table_end;
}
+
+ unsigned num_comments = wtap_block_count_option(shb_inf, OPT_COMMENT);
+ if (num_comments > 0) {
+ out << section_tmpl_.arg(tr("Comments"));
+ char *shb_comment;
+ for (unsigned i = 0; i < num_comments; i++) {
+ if (wtap_block_get_nth_string_option_value(shb_inf, OPT_COMMENT, i,
+ &shb_comment) == WTAP_OPTTYPE_SUCCESS) {
+ QString section_comment = shb_comment;
+ QString section_comment_html;
+ if (num_comments > 1) {
+ out << tr("Comment %1: ").arg(i+1);
+ }
+
+ QString comment_escaped = html_escape(section_comment).replace('\n', "<br>");
+ out << para_tmpl_.arg(comment_escaped);
+ }
+ }
+ }
+ }
+
+ // Done with the interfaces
+ for (unsigned i = 0; i < summary.ifaces->len; i++) {
+ iface_summary_info iface;
+ iface = g_array_index(summary.ifaces, iface_summary_info, i);
+
+ g_free(iface.descr);
+ g_free(iface.name);
+ g_free(iface.cfilter);
+ }
+ g_array_free(summary.ifaces, true);
+
+ if (wtap_file_get_num_dsbs(cap_file_.capFile()->provider.wth) > 0) {
+ out << section_tmpl_.arg(tr("Decryption Secrets"));
+ out << table_begin;
+ out << table_ul_row_begin
+ << table_hheader20_tmpl.arg(tr("Type"))
+ << table_hheader20_tmpl.arg(tr("Size"))
+ << table_row_end;
+ // XXX: A DSB can have (multiple) comments, we could add that too.
+ for (unsigned section_number = 0;
+ section_number < wtap_file_get_num_dsbs(cap_file_.capFile()->provider.wth);
+ section_number++) {
+ wtap_block_t dsb = wtap_file_get_dsb(cap_file_.capFile()->provider.wth, section_number);
+ wtapng_dsb_mandatory_t *dsb_mand = (wtapng_dsb_mandatory_t*)wtap_block_get_mandatory_data(dsb);
+ out << table_row_begin
+ << table_data_tmpl.arg(secrets_type_description(dsb_mand->secrets_type))
+ << table_data_tmpl.arg(tr("%1 bytes").arg(dsb_mand->secrets_len))
+ << table_row_end;
+ }
+ out << table_end;
}
// Statistics Section
@@ -395,9 +445,13 @@ QString CaptureFilePropertiesDialog::summaryToHtml()
.arg(100.0 * summary.marked_count / summary.packet_count, 1, 'f', 1);
}
- out << table_row_begin
- << table_data_tmpl.arg(tr("Packets"))
- << table_data_tmpl.arg(summary.packet_count)
+ out << table_row_begin;
+ if (is_packet_configuration_namespace()) {
+ out << table_data_tmpl.arg(tr("Packets"));
+ } else {
+ out << table_data_tmpl.arg(tr("Events"));
+ }
+ out << table_data_tmpl.arg(summary.packet_count)
<< table_data_tmpl.arg(displayed_str)
<< table_data_tmpl.arg(marked_str)
<< table_row_end;
@@ -441,17 +495,21 @@ QString CaptureFilePropertiesDialog::summaryToHtml()
// Average packet size
captured_str = displayed_str = marked_str = n_a;
if (summary.packet_count > 0) {
- captured_str = QString::number((guint64) ((double)summary.bytes/summary.packet_count + 0.5));
+ captured_str = QString::number((uint64_t) ((double)summary.bytes/summary.packet_count + 0.5));
}
if (summary.filtered_count > 0) {
- displayed_str = QString::number((guint64) ((double)summary.filtered_bytes/summary.filtered_count + 0.5));
+ displayed_str = QString::number((uint64_t) ((double)summary.filtered_bytes/summary.filtered_count + 0.5));
}
if (summary.marked_count > 0) {
- marked_str = QString::number((guint64) ((double)summary.marked_bytes/summary.marked_count + 0.5));
+ marked_str = QString::number((uint64_t) ((double)summary.marked_bytes/summary.marked_count + 0.5));
}
- out << table_row_begin
- << table_data_tmpl.arg(tr("Average packet size, B"))
- << table_data_tmpl.arg(captured_str)
+ out << table_row_begin;
+ if (is_packet_configuration_namespace()) {
+ out << table_data_tmpl.arg(tr("Average packet size, B"));
+ } else {
+ out << table_data_tmpl.arg(tr("Average event size, B"));
+ }
+ out << table_data_tmpl.arg(captured_str)
<< table_data_tmpl.arg(displayed_str)
<< table_data_tmpl.arg(marked_str)
<< table_row_end;
@@ -533,36 +591,21 @@ void CaptureFilePropertiesDialog::fillDetails()
cursor.insertHtml(summary);
cursor.insertBlock(); // Work around rendering oddity.
- // XXX - this just shows the first comment in the first section;
- // add support for multiple sections with multiple comments.
- wtap_block_t shb = wtap_file_get_shb(cap_file_.capFile()->provider.wth, 0);
- char *shb_comment;
- if (wtap_block_get_nth_string_option_value(shb, OPT_COMMENT, 0,
- &shb_comment) == WTAP_OPTTYPE_SUCCESS) {
- QString section_comment = shb_comment;
- QString section_comment_html;
-
- if (!section_comment.isEmpty()) {
- QString comment_escaped = html_escape(section_comment).replace('\n', "<br>");
- section_comment_html += section_tmpl_.arg(QString(tr("Section Comment")));
- section_comment_html += para_tmpl_.arg(comment_escaped);
-
- cursor.insertBlock();
- cursor.insertHtml(section_comment_html);
- }
- }
-
if (cap_file_.capFile()->packet_comment_count > 0) {
cursor.insertBlock();
- cursor.insertHtml(section_tmpl_.arg(tr("Packet Comments")));
+ if (is_packet_configuration_namespace()) {
+ cursor.insertHtml(section_tmpl_.arg(tr("Packet Comments")));
+ } else {
+ cursor.insertHtml(section_tmpl_.arg(tr("Event Comments")));
+ }
- for (guint32 framenum = 1; framenum <= cap_file_.capFile()->count ; framenum++) {
+ for (uint32_t framenum = 1; framenum <= cap_file_.capFile()->count ; framenum++) {
frame_data *fdata = frame_data_sequence_find(cap_file_.capFile()->provider.frames, framenum);
wtap_block_t pkt_block = cf_get_packet_block(cap_file_.capFile(), fdata);
if (pkt_block) {
- guint n_comments = wtap_block_count_option(pkt_block, OPT_COMMENT);
- for (guint i = 0; i < n_comments; i++) {
+ unsigned n_comments = wtap_block_count_option(pkt_block, OPT_COMMENT);
+ for (unsigned i = 0; i < n_comments; i++) {
char *comment_text;
if (WTAP_OPTTYPE_SUCCESS == wtap_block_get_nth_string_option_value(pkt_block, OPT_COMMENT, i, &comment_text)) {
QString frame_comment_html = tr("<p>Frame %1: ").arg(framenum);
@@ -598,45 +641,31 @@ void CaptureFilePropertiesDialog::changeEvent(QEvent* event)
QDialog::changeEvent(event);
}
-void CaptureFilePropertiesDialog::on_buttonBox_helpRequested()
+void CaptureFilePropertiesDialog::addCaptureComment()
{
- mainApp->helpTopicAction(HELP_STATS_SUMMARY_DIALOG);
+ CaptureCommentDialog* cc_dialog;
+ cc_dialog = new CaptureCommentDialog(*this, cap_file_);
+ connect(cc_dialog, &CaptureCommentDialog::captureCommentChanged, this, &CaptureFilePropertiesDialog::updateWidgets);
+ //cc_dialog->setWindowModality(Qt::ApplicationModal);
+ cc_dialog->setAttribute(Qt::WA_DeleteOnClose);
+ cc_dialog->show();
}
-void CaptureFilePropertiesDialog::on_buttonBox_accepted()
+void CaptureFilePropertiesDialog::on_buttonBox_helpRequested()
{
- if (file_closed_ || !cap_file_.capFile()->filename) {
- return;
- }
-
- if (wtap_dump_can_write(cap_file_.capFile()->linktypes, WTAP_COMMENT_PER_SECTION))
- {
- gchar *str = qstring_strdup(ui->commentsTextEdit->toPlainText());
-
- /*
- * Make sure this would fit in a pcapng option.
- *
- * XXX - 65535 is the maximum size for an option in pcapng;
- * what if another capture file format supports larger
- * comments?
- */
- if (strlen(str) > 65535) {
- /* It doesn't fit. Tell the user and give up. */
- simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
- "That comment is too large to save in a capture file.");
- return;
- }
- cf_update_section_comment(cap_file_.capFile(), str);
- emit captureCommentChanged();
- fillDetails();
- }
+ mainApp->helpTopicAction(HELP_STATS_SUMMARY_DIALOG);
}
void CaptureFilePropertiesDialog::on_buttonBox_clicked(QAbstractButton *button)
{
if (button == ui->buttonBox->button(QDialogButtonBox::Apply)) {
QClipboard *clipboard = QApplication::clipboard();
- QString details = tr("Created by Wireshark %1\n\n").arg(get_ws_vcs_version_info());
+ QString details;
+ if (is_packet_configuration_namespace()) {
+ details = tr("Created by Wireshark %1\n\n").arg(get_ws_vcs_version_info());
+ } else {
+ details = tr("Created by Logray %1\n\n").arg(get_lr_vcs_version_info());
+ }
details.append(ui->detailsTextEdit->toPlainText());
clipboard->setText(details);
} else if (button == ui->buttonBox->button(QDialogButtonBox::Reset)) {
diff --git a/ui/qt/capture_file_properties_dialog.h b/ui/qt/capture_file_properties_dialog.h
index dd1698a6..27b8d86f 100644
--- a/ui/qt/capture_file_properties_dialog.h
+++ b/ui/qt/capture_file_properties_dialog.h
@@ -14,8 +14,6 @@
#include <config.h>
-#include <glib.h>
-
#include <string.h>
#include <time.h>
@@ -62,8 +60,8 @@ private:
private slots:
void updateWidgets();
+ void addCaptureComment();
void on_buttonBox_helpRequested();
- void on_buttonBox_accepted();
void on_buttonBox_clicked(QAbstractButton *button);
void on_buttonBox_rejected();
};
diff --git a/ui/qt/capture_file_properties_dialog.ui b/ui/qt/capture_file_properties_dialog.ui
index bf5cd634..65b28f12 100644
--- a/ui/qt/capture_file_properties_dialog.ui
+++ b/ui/qt/capture_file_properties_dialog.ui
@@ -21,65 +21,38 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
- <widget class="QSplitter" name="splitter">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="opaqueResize">
- <bool>false</bool>
- </property>
- <property name="childrenCollapsible">
- <bool>false</bool>
- </property>
- <widget class="QWidget" name="">
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QLabel" name="detailsLabel">
- <property name="text">
- <string>Details</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QTextEdit" name="detailsTextEdit">
- <property name="readOnly">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="">
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
- <widget class="QLabel" name="commentsLabel">
- <property name="text">
- <string>Capture file comments</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QTextEdit" name="commentsTextEdit">
- <property name="sizeIncrement">
- <size>
- <width>0</width>
- <height>10</height>
- </size>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
+ <widget class="QWidget" name="">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="detailsLabel">
+ <property name="text">
+ <string>Details</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTextEdit" name="detailsTextEdit">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
- <set>QDialogButtonBox::Apply|QDialogButtonBox::Close|QDialogButtonBox::Help|QDialogButtonBox::Reset|QDialogButtonBox::Save</set>
+ <set>QDialogButtonBox::Apply|QDialogButtonBox::Close|QDialogButtonBox::Help|QDialogButtonBox::Reset</set>
</property>
</widget>
</item>
</layout>
+ <widget class="QPushButton" name="actionEditButton">
+ <property name="text">
+ <string>Edit Comments</string>
+ </property>
+ </widget>
</widget>
<resources/>
<connections/>
diff --git a/ui/qt/capture_filter_syntax_worker.cpp b/ui/qt/capture_filter_syntax_worker.cpp
index 89ef981c..0fb6b543 100644
--- a/ui/qt/capture_filter_syntax_worker.cpp
+++ b/ui/qt/capture_filter_syntax_worker.cpp
@@ -10,7 +10,6 @@
#include "config.h"
#ifdef HAVE_LIBPCAP
-#include <glib.h>
#ifdef __MINGW32__
#include <_bsd_types.h>
@@ -50,8 +49,8 @@ static QMutex pcap_compile_mtx_;
void CaptureFilterSyntaxWorker::checkFilter(const QString filter)
{
#ifdef HAVE_LIBPCAP
- QSet<gint> active_dlts;
- QSet<guint> active_extcap;
+ QSet<int> active_dlts;
+ QSet<unsigned> active_extcap;
struct bpf_program fcode;
pcap_t *pd;
int pc_err;
@@ -66,7 +65,7 @@ void CaptureFilterSyntaxWorker::checkFilter(const QString filter)
return;
}
- for (guint if_idx = 0; if_idx < global_capture_opts.all_ifaces->len; if_idx++) {
+ for (unsigned if_idx = 0; if_idx < global_capture_opts.all_ifaces->len; if_idx++) {
interface_t *device;
device = &g_array_index(global_capture_opts.all_ifaces, interface_t, if_idx);
@@ -85,7 +84,7 @@ void CaptureFilterSyntaxWorker::checkFilter(const QString filter)
}
}
- foreach(gint dlt, active_dlts.values()) {
+ foreach(int dlt, active_dlts.values()) {
pcap_compile_mtx_.lock();
pd = pcap_open_dead(dlt, DUMMY_SNAPLENGTH);
if (pd == NULL)
@@ -109,6 +108,7 @@ void CaptureFilterSyntaxWorker::checkFilter(const QString filter)
err_str = pcap_geterr(pd);
} else {
DEBUG_SYNTAX_CHECK("unknown", "known good");
+ pcap_freecode(&fcode);
}
pcap_close(pd);
@@ -118,9 +118,9 @@ void CaptureFilterSyntaxWorker::checkFilter(const QString filter)
}
// If it's already invalid, don't bother to check extcap
if (state != SyntaxLineEdit::Invalid) {
- foreach(guint extcapif, active_extcap.values()) {
+ foreach(unsigned extcapif, active_extcap.values()) {
interface_t *device;
- gchar *error = NULL;
+ char *error = NULL;
device = &g_array_index(global_capture_opts.all_ifaces, interface_t, extcapif);
extcap_filter_status status = extcap_verify_capture_filter(device->name, filter.toUtf8().constData(), &error);
diff --git a/ui/qt/capture_info_dialog.cpp b/ui/qt/capture_info_dialog.cpp
index 5a29652c..e171ba3d 100644
--- a/ui/qt/capture_info_dialog.cpp
+++ b/ui/qt/capture_info_dialog.cpp
@@ -19,7 +19,7 @@
#include "ui/capture.h"
#include "capture_info_dialog.h"
-#include "ui_capture_info_dialog.h"
+#include <ui_capture_info_dialog.h>
#include "main_application.h"
@@ -146,7 +146,7 @@ void CaptureInfoModel::updateInfo()
if (!cap_info_) return;
GHashTableIter iter;
- gpointer key, value;
+ void *key, *value;
samples_++;
other_points_.append(cap_info_->counts->other - last_other_);
diff --git a/ui/qt/capture_options_dialog.cpp b/ui/qt/capture_options_dialog.cpp
index a0aed791..6763f14d 100644
--- a/ui/qt/capture_options_dialog.cpp
+++ b/ui/qt/capture_options_dialog.cpp
@@ -94,10 +94,10 @@ enum
static interface_t *find_device_by_if_name(const QString &interface_name)
{
interface_t *device;
- guint i;
+ unsigned i;
for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
- if (!interface_name.compare(device->display_name) && !device->hidden && device->type != IF_PIPE) {
+ if (!interface_name.compare(device->display_name) && !device->hidden && device->if_info.type != IF_PIPE) {
return device;
}
}
@@ -214,6 +214,7 @@ CaptureOptionsDialog::CaptureOptionsDialog(QWidget *parent) :
#endif
#ifndef SHOW_MONITOR_COLUMN
ui->interfaceTree->setColumnHidden(col_monitor_, true);
+ ui->captureMonitorModeCheckBox->setVisible(false);
#endif
ui->interfaceTree->setItemDelegateForColumn(col_filter_, &interface_item_delegate_);
@@ -222,6 +223,7 @@ CaptureOptionsDialog::CaptureOptionsDialog(QWidget *parent) :
ui->filenameLineEdit->setPlaceholderText(tr("Leave blank to use a temporary file"));
ui->rbCompressionNone->setChecked(true);
+ ui->rbTimeNum->setChecked(true);
ui->tempDirLineEdit->setPlaceholderText(g_get_tmp_dir());
ui->tempDirLineEdit->setText(global_capture_opts.temp_dir);
@@ -246,6 +248,27 @@ CaptureOptionsDialog::CaptureOptionsDialog(QWidget *parent) :
connect(ui->interfaceTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(itemDoubleClicked(QTreeWidgetItem*,int)));
connect(ui->tempDirBrowseButton, SIGNAL(clicked()), this, SLOT(tempDirBrowseButtonClicked()));
+ // Ring buffer minimums (all 1 except # of files)
+ ui->PktSpinBox->setMinimum(1);
+ ui->MBSpinBox->setMinimum(1);
+ ui->SecsSpinBox->setMinimum(1);
+ ui->IntervalSecsSpinBox->setMinimum(1);
+ ui->RbSpinBox->setMinimum(2);
+
+ // Autostop minimums
+ ui->stopPktSpinBox->setMinimum(1);
+ ui->stopFilesSpinBox->setMinimum(1);
+ ui->stopMBSpinBox->setMinimum(1);
+ ui->stopSecsSpinBox->setMinimum(1);
+
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ connect(ui->MBComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CaptureOptionsDialog::MBComboBoxIndexChanged);
+ connect(ui->stopMBComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &CaptureOptionsDialog::stopMBComboBoxIndexChanged);
+#else
+ connect(ui->MBComboBox, &QComboBox::currentIndexChanged, this, &CaptureOptionsDialog::MBComboBoxIndexChanged);
+ connect(ui->stopMBComboBox, &QComboBox::currentIndexChanged, this, &CaptureOptionsDialog::stopMBComboBoxIndexChanged);
+#endif
+
ui->tabWidget->setCurrentIndex(0);
updateWidgets();
@@ -266,14 +289,14 @@ void CaptureOptionsDialog::updateGlobalDeviceSelections()
while (*iter) {
QString device_name = (*iter)->data(col_interface_, Qt::UserRole).value<QString>();
- for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+ for (unsigned i = 0; i < global_capture_opts.all_ifaces->len; i++) {
interface_t *device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
if (device_name.compare(QString().fromUtf8(device->name)) == 0) {
if ((*iter)->isSelected()) {
- device->selected = TRUE;
+ device->selected = true;
global_capture_opts.num_selected++;
} else {
- device->selected = FALSE;
+ device->selected = false;
}
break;
}
@@ -294,7 +317,7 @@ void CaptureOptionsDialog::updateFromGlobalDeviceSelections()
while (*iter) {
QString device_name = (*iter)->data(col_interface_, Qt::UserRole).value<QString>();
- for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+ for (unsigned i = 0; i < global_capture_opts.all_ifaces->len; i++) {
interface_t *device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
if (device_name.compare(QString().fromUtf8(device->name)) == 0) {
if ((bool)device->selected != (*iter)->isSelected()) {
@@ -373,22 +396,27 @@ void CaptureOptionsDialog::on_capturePromModeCheckBox_toggled(bool checked)
}
}
-void CaptureOptionsDialog::browseButtonClicked()
+void CaptureOptionsDialog::on_captureMonitorModeCheckBox_toggled(bool checked)
{
- const char *open_dir = NULL;
-
- switch (prefs.gui_fileopen_style) {
-
- case FO_STYLE_LAST_OPENED:
- open_dir = get_open_dialog_initial_dir();
- break;
+ interface_t *device;
+ prefs.capture_monitor_mode = checked;
+ for (int row = 0; row < ui->interfaceTree->topLevelItemCount(); row++) {
+ InterfaceTreeWidgetItem *ti = dynamic_cast<InterfaceTreeWidgetItem *>(ui->interfaceTree->topLevelItem(row));
+ if (!ti) continue;
- case FO_STYLE_SPECIFIED:
- if (prefs.gui_fileopen_dir[0] != '\0')
- open_dir = prefs.gui_fileopen_dir;
- break;
+ QString device_name = ti->data(col_interface_, Qt::UserRole).toString();
+ device = getDeviceByName(device_name);
+ if (!device) continue;
+ if (device->monitor_mode_supported) {
+ device->monitor_mode_enabled = checked;
+ ti->updateInterfaceColumns(device);
+ }
}
- QString file_name = WiresharkFileDialog::getSaveFileName(this, tr("Specify a Capture File"), open_dir);
+}
+
+void CaptureOptionsDialog::browseButtonClicked()
+{
+ QString file_name = WiresharkFileDialog::getSaveFileName(this, tr("Specify a Capture File"), get_open_dialog_initial_dir());
ui->filenameLineEdit->setText(file_name);
}
@@ -416,15 +444,15 @@ void CaptureOptionsDialog::interfaceItemChanged(QTreeWidgetItem *item, int colum
switch(column) {
case col_pmode_:
- device->pmode = item->checkState(col_pmode_) == Qt::Checked ? TRUE : FALSE;
+ device->pmode = item->checkState(col_pmode_) == Qt::Checked ? true : false;
ti->updateInterfaceColumns(device);
break;
#ifdef SHOW_MONITOR_COLUMN
case col_monitor_:
{
- gboolean monitor_mode = FALSE;
- if (ti->checkState(col_monitor_) == Qt::Checked) monitor_mode = TRUE;
+ bool monitor_mode = false;
+ if (ti->checkState(col_monitor_) == Qt::Checked) monitor_mode = true;
if_capabilities_t *caps;
char *auth_str = NULL;
@@ -444,15 +472,16 @@ void CaptureOptionsDialog::interfaceItemChanged(QTreeWidgetItem *item, int colum
if (caps != Q_NULLPTR) {
for (int i = static_cast<int>(g_list_length(device->links)) - 1; i >= 0; i--) {
- GList* rem = g_list_nth(device->links, static_cast<guint>(i));
+ GList* rem = g_list_nth(device->links, static_cast<unsigned>(i));
device->links = g_list_remove_link(device->links, rem);
g_list_free_1(rem);
}
device->active_dlt = -1;
device->monitor_mode_supported = caps->can_set_rfmon;
- device->monitor_mode_enabled = monitor_mode;
+ device->monitor_mode_enabled = monitor_mode && caps->can_set_rfmon;
+ GList *lt_list = device->monitor_mode_enabled ? caps->data_link_types_rfmon : caps->data_link_types;
- for (GList *lt_entry = caps->data_link_types; lt_entry != Q_NULLPTR; lt_entry = gxx_list_next(lt_entry)) {
+ for (GList *lt_entry = lt_list; lt_entry != Q_NULLPTR; lt_entry = gxx_list_next(lt_entry)) {
link_row *linkr = new link_row();
data_link_info_t *data_link_info = gxx_list_data(data_link_info_t *, lt_entry);
/*
@@ -470,7 +499,7 @@ void CaptureOptionsDialog::interfaceItemChanged(QTreeWidgetItem *item, int colum
}
linkr->name = g_strdup(data_link_info->description);
} else {
- gchar *str;
+ char *str;
/* XXX - should we just omit them? */
str = ws_strdup_printf("%s (not supported)", data_link_info->name);
linkr->dlt = -1;
@@ -483,8 +512,8 @@ void CaptureOptionsDialog::interfaceItemChanged(QTreeWidgetItem *item, int colum
} else {
/* We don't know whether this supports monitor mode or not;
don't ask for monitor mode. */
- device->monitor_mode_enabled = FALSE;
- device->monitor_mode_supported = FALSE;
+ device->monitor_mode_enabled = false;
+ device->monitor_mode_supported = false;
}
ti->updateInterfaceColumns(device);
@@ -565,6 +594,36 @@ void CaptureOptionsDialog::itemDoubleClicked(QTreeWidgetItem *item, int column)
}
}
+void CaptureOptionsDialog::MBComboBoxIndexChanged(int index)
+{
+ switch (index) {
+ case 0: // kilobytes
+ ui->MBSpinBox->setMaximum(2000000000);
+ break;
+ case 1: // megabytes
+ ui->MBSpinBox->setMaximum(2000000);
+ break;
+ case 2: // gigabytes
+ ui->MBSpinBox->setMaximum(2000);
+ break;
+ }
+}
+
+void CaptureOptionsDialog::stopMBComboBoxIndexChanged(int index)
+{
+ switch (index) {
+ case 0: // kilobytes
+ ui->stopMBSpinBox->setMaximum(2000000000);
+ break;
+ case 1: // megabytes
+ ui->stopMBSpinBox->setMaximum(2000000);
+ break;
+ case 2: // gigabytes
+ ui->stopMBSpinBox->setMaximum(2000);
+ break;
+ }
+}
+
void CaptureOptionsDialog::on_gbStopCaptureAuto_toggled(bool checked)
{
global_capture_opts.has_file_interval = checked;
@@ -578,7 +637,7 @@ void CaptureOptionsDialog::on_gbNewFileAuto_toggled(bool checked)
ui->stopMBComboBox->setEnabled(checked?false:true);
ui->gbCompression->setEnabled(checked);
ui->rbCompressionNone->setEnabled(checked);
-#ifdef HAVE_ZLIB
+#if defined(HAVE_ZLIB) || defined(HAVE_ZLIBNG)
ui->rbCompressionGzip->setEnabled(checked);
#else
ui->rbCompressionGzip->setEnabled(false);
@@ -665,6 +724,8 @@ void CaptureOptionsDialog::updateInterfaces()
ui->rbPcap->setChecked(true);
}
ui->capturePromModeCheckBox->setChecked(prefs.capture_prom_mode);
+ ui->captureMonitorModeCheckBox->setChecked(prefs.capture_monitor_mode);
+ ui->captureMonitorModeCheckBox->setEnabled(false);
if (global_capture_opts.saving_to_file) {
ui->filenameLineEdit->setText(QString(global_capture_opts.orig_save_file));
@@ -781,10 +842,10 @@ void CaptureOptionsDialog::updateInterfaces()
ui->interfaceTree->clear();
#ifdef SHOW_BUFFER_COLUMN
- gint buffer;
+ int buffer;
#endif
- gint snaplen;
- gboolean hassnap, pmode;
+ int snaplen;
+ bool hassnap, pmode;
QList<QTreeWidgetItem *> selected_interfaces;
disconnect(ui->interfaceTree, SIGNAL(itemChanged(QTreeWidgetItem*,int)), this, SLOT(interfaceItemChanged(QTreeWidgetItem*,int)));
@@ -792,7 +853,7 @@ void CaptureOptionsDialog::updateInterfaces()
if (global_capture_opts.all_ifaces->len > 0) {
interface_t *device;
- for (guint device_idx = 0; device_idx < global_capture_opts.all_ifaces->len; device_idx++) {
+ for (unsigned device_idx = 0; device_idx < global_capture_opts.all_ifaces->len; device_idx++) {
device = &g_array_index(global_capture_opts.all_ifaces, interface_t, device_idx);
/* Continue if capture device is hidden */
@@ -835,11 +896,11 @@ void CaptureOptionsDialog::updateInterfaces()
if (capture_dev_user_snaplen_find(device->name, &hassnap, &snaplen)) {
/* Default snap length set in preferences */
device->snaplen = snaplen;
- device->has_snaplen = snaplen == WTAP_MAX_PACKET_SIZE_STANDARD ? FALSE : hassnap;
+ device->has_snaplen = snaplen == WTAP_MAX_PACKET_SIZE_STANDARD ? false : hassnap;
} else {
/* No preferences set yet, use default values */
device->snaplen = WTAP_MAX_PACKET_SIZE_STANDARD;
- device->has_snaplen = FALSE;
+ device->has_snaplen = false;
}
#ifdef SHOW_BUFFER_COLUMN
@@ -850,6 +911,11 @@ void CaptureOptionsDialog::updateInterfaces()
device->buffer = DEFAULT_CAPTURE_BUFFER_SIZE;
}
#endif
+#ifdef SHOW_MONITOR_COLUMN
+ if (device->monitor_mode_supported) {
+ ui->captureMonitorModeCheckBox->setEnabled(true);
+ }
+#endif
ti->updateInterfaceColumns(device);
if (device->selected) {
@@ -921,14 +987,14 @@ void CaptureOptionsDialog::updateStatistics(void)
disconnect(ui->interfaceTree, SIGNAL(itemChanged(QTreeWidgetItem*,int)), this, SLOT(interfaceItemChanged(QTreeWidgetItem*,int)));
for (int row = 0; row < ui->interfaceTree->topLevelItemCount(); row++) {
- for (guint if_idx = 0; if_idx < global_capture_opts.all_ifaces->len; if_idx++) {
+ for (unsigned if_idx = 0; if_idx < global_capture_opts.all_ifaces->len; if_idx++) {
QTreeWidgetItem *ti = ui->interfaceTree->topLevelItem(row);
if (!ti) {
continue;
}
device = &g_array_index(global_capture_opts.all_ifaces, interface_t, if_idx);
QString device_name = ti->text(col_interface_);
- if (device_name.compare(device->display_name) || device->hidden || device->type == IF_PIPE) {
+ if (device_name.compare(device->display_name) || device->hidden || device->if_info.type == IF_PIPE) {
continue;
}
QList<int> points = ti->data(col_traffic_, Qt::UserRole).value<QList<int> >();
@@ -942,13 +1008,17 @@ void CaptureOptionsDialog::updateStatistics(void)
void CaptureOptionsDialog::on_compileBPF_clicked()
{
- QStringList interfaces;
+ QList<InterfaceFilter> interfaces;
foreach (QTreeWidgetItem *ti, ui->interfaceTree->selectedItems()) {
- interfaces.append(ti->text(col_interface_));
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ interfaces.emplaceBack(ti->text(col_interface_), ti->text(col_filter_));
+#else
+ interfaces.append(InterfaceFilter(ti->text(col_interface_), ti->text(col_filter_)));
+#endif
}
QString filter = ui->captureFilterComboBox->currentText();
- CompiledFilterOutput *cfo = new CompiledFilterOutput(this, interfaces, filter);
+ CompiledFilterOutput *cfo = new CompiledFilterOutput(this, interfaces);
cfo->show();
}
@@ -1033,17 +1103,17 @@ bool CaptureOptionsDialog::saveOptionsToPreferences()
global_capture_opts.autostop_filesize = ui->MBSpinBox->value();
int index = ui->MBComboBox->currentIndex();
switch (index) {
- case 1: if (global_capture_opts.autostop_filesize > 2000) {
+ case 1: if (global_capture_opts.autostop_filesize > 2000000) {
QMessageBox::warning(this, tr("Error"),
- tr("Multiple files: Requested filesize too large. The filesize cannot be greater than 2 GiB."));
+ tr("Multiple files: Requested filesize too large. The filesize cannot be greater than 2 TB."));
return false;
} else {
global_capture_opts.autostop_filesize *= 1000;
}
break;
- case 2: if (global_capture_opts.autostop_filesize > 2) {
+ case 2: if (global_capture_opts.autostop_filesize > 2000) {
QMessageBox::warning(this, tr("Error"),
- tr("Multiple files: Requested filesize too large. The filesize cannot be greater than 2 GiB."));
+ tr("Multiple files: Requested filesize too large. The filesize cannot be greater than 2 TB."));
return false;
} else {
global_capture_opts.autostop_filesize *= 1000000;
@@ -1072,17 +1142,17 @@ bool CaptureOptionsDialog::saveOptionsToPreferences()
global_capture_opts.autostop_filesize = ui->stopMBSpinBox->value();
int index = ui->stopMBComboBox->currentIndex();
switch (index) {
- case 1: if (global_capture_opts.autostop_filesize > 2000) {
+ case 1: if (global_capture_opts.autostop_filesize > 2000000) {
QMessageBox::warning(this, tr("Error"),
- tr("Multiple files: Requested filesize too large. The filesize cannot be greater than 2 GiB."));
+ tr("Multiple files: Requested filesize too large. The filesize cannot be greater than 2 TB."));
return false;
} else {
global_capture_opts.autostop_filesize *= 1000;
}
break;
- case 2: if (global_capture_opts.autostop_filesize > 2) {
+ case 2: if (global_capture_opts.autostop_filesize > 2000) {
QMessageBox::warning(this, tr("Error"),
- tr("Multiple files: Requested filesize too large. The filesize cannot be greater than 2 GiB."));
+ tr("Multiple files: Requested filesize too large. The filesize cannot be greater than 2 TB."));
return false;
} else {
global_capture_opts.autostop_filesize *= 1000000;
@@ -1185,7 +1255,7 @@ bool CaptureOptionsDialog::saveOptionsToPreferences()
QTreeWidgetItem *ti = ui->interfaceTree->topLevelItem(row);
QString device_name = ti->data(col_interface_, Qt::UserRole).toString();
device = getDeviceByName(device_name);
- if (!device || device->pmode == -1) {
+ if (!device || !device->pmode) {
continue;
}
pmode_list << QString("%1(%2)").arg(device->name).arg(device->pmode);
@@ -1248,6 +1318,14 @@ bool CaptureOptionsDialog::saveOptionsToPreferences()
global_capture_opts.compress_type = NULL;
}
+ if (ui->rbTimeNum->isChecked() ) {
+ global_capture_opts.has_nametimenum = true;
+ } else if (ui->rbNumTime->isChecked() ) {
+ global_capture_opts.has_nametimenum = false;
+ } else {
+ global_capture_opts.has_nametimenum = false;
+ }
+
prefs_main_write();
return true;
}
@@ -1293,7 +1371,7 @@ void CaptureOptionsDialog::changeEvent(QEvent* event)
interface_t *CaptureOptionsDialog::getDeviceByName(const QString device_name)
{
- for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+ for (unsigned i = 0; i < global_capture_opts.all_ifaces->len; i++) {
interface_t *device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
if (device_name.compare(QString().fromUtf8(device->name)) == 0) {
return device;
@@ -1328,6 +1406,13 @@ QVariant InterfaceTreeWidgetItem::data(int column, int role) const
return QVariant::fromValue(points);
}
+ if (column == col_snaplen_ && role == Qt::DisplayRole) {
+ QVariant data = QTreeWidgetItem::data(column, role);
+ if (data.toInt() == WTAP_MAX_PACKET_SIZE_STANDARD || data.toInt() == 0) {
+ return InterfaceTreeDelegate::tr("default");
+ }
+ return data;
+ }
return QTreeWidgetItem::data(column, role);
}
@@ -1366,9 +1451,9 @@ QWidget* InterfaceTreeDelegate::createEditor(QWidget *parent, const QStyleOption
{
QWidget *w = NULL;
#ifdef SHOW_BUFFER_COLUMN
- gint buffer = DEFAULT_CAPTURE_BUFFER_SIZE;
+ int buffer = DEFAULT_CAPTURE_BUFFER_SIZE;
#endif
- guint snap = WTAP_MAX_PACKET_SIZE_STANDARD;
+ unsigned snap = WTAP_MAX_PACKET_SIZE_STANDARD;
GList *links = NULL;
if (idx.column() > 1 && idx.data().toString().compare(UTF8_EM_DASH)) {
@@ -1419,9 +1504,10 @@ QWidget* InterfaceTreeDelegate::createEditor(QWidget *parent, const QStyleOption
case col_snaplen_:
{
QSpinBox *sb = new QSpinBox(parent);
- sb->setRange(1, WTAP_MAX_PACKET_SIZE_STANDARD);
+ sb->setRange(0, WTAP_MAX_PACKET_SIZE_STANDARD);
sb->setValue(snap);
sb->setWrapping(true);
+ sb->setSpecialValueText(tr("default"));
connect(sb, SIGNAL(valueChanged(int)), this, SLOT(snapshotLengthChanged(int)));
w = (QWidget*) sb;
break;
@@ -1505,7 +1591,7 @@ void InterfaceTreeDelegate::snapshotLengthChanged(int value)
if (!device) {
return;
}
- if (value != WTAP_MAX_PACKET_SIZE_STANDARD) {
+ if (value != WTAP_MAX_PACKET_SIZE_STANDARD && value != 0) {
device->has_snaplen = true;
device->snaplen = value;
} else {
diff --git a/ui/qt/capture_options_dialog.h b/ui/qt/capture_options_dialog.h
index e9eea761..cc57467e 100644
--- a/ui/qt/capture_options_dialog.h
+++ b/ui/qt/capture_options_dialog.h
@@ -70,6 +70,7 @@ protected:
private slots:
void on_capturePromModeCheckBox_toggled(bool checked);
+ void on_captureMonitorModeCheckBox_toggled(bool checked);
void on_gbStopCaptureAuto_toggled(bool checked);
void on_cbUpdatePacketsRT_toggled(bool checked);
void on_cbAutoScroll_toggled(bool checked);
@@ -94,6 +95,8 @@ private slots:
void itemDoubleClicked(QTreeWidgetItem *item, int column);
void changeEvent(QEvent* event);
void tempDirBrowseButtonClicked();
+ void MBComboBoxIndexChanged(int index);
+ void stopMBComboBoxIndexChanged(int index);
signals:
void startCapture();
diff --git a/ui/qt/capture_options_dialog.ui b/ui/qt/capture_options_dialog.ui
index 2ace9a95..c9eba3b6 100644
--- a/ui/qt/capture_options_dialog.ui
+++ b/ui/qt/capture_options_dialog.ui
@@ -98,6 +98,16 @@
</widget>
</item>
<item>
+ <widget class="QCheckBox" name="captureMonitorModeCheckBox">
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for some more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string>Enable monitor mode on all 802.11 interfaces</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@@ -321,12 +331,6 @@
<property name="buttonSymbols">
<enum>QAbstractSpinBox::PlusMinus</enum>
</property>
- <property name="minimum">
- <number>1</number>
- </property>
- <property name="maximum">
- <number>1000000</number>
- </property>
<property name="value">
<number>1</number>
</property>
@@ -375,9 +379,6 @@
<property name="buttonSymbols">
<enum>QAbstractSpinBox::PlusMinus</enum>
</property>
- <property name="minimum">
- <number>1</number>
- </property>
<property name="maximum">
<number>1000000</number>
</property>
@@ -431,9 +432,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</stri
<property name="buttonSymbols">
<enum>QAbstractSpinBox::PlusMinus</enum>
</property>
- <property name="minimum">
- <number>1</number>
- </property>
<property name="maximum">
<number>1000000</number>
</property>
@@ -473,7 +471,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</stri
<property name="title">
<string>compression</string>
</property>
- <layout class="QVBoxLayout" name="verticalLayout_5">
+ <layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QRadioButton" name="rbCompressionNone">
<property name="text">
@@ -497,6 +495,44 @@ For example, use 1 hour to have a new file created every hour on the hour.</stri
</layout>
</widget>
</item>
+ <item row="5" column="1" colspan="2">
+ <widget class="QGroupBox" name="nameTemplateGB">
+ <property name="title">
+ <string>File infix pattern</string>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;In multiple file mode, the date and time and file index number are inserted between filename template and any suffix. Select their order.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <item>
+ <widget class="QRadioButton" name="rbTimeNum">
+ <property name="text">
+ <string>YYYYmmDDHHMMSS_NNNNN</string>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Date and time before the file index number. This causes files to sort in creation time order, and keeps files from the same batch closely ordered.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">nameTimeNumBG</string>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="rbNumTime">
+ <property name="text">
+ <string>NNNNN_YYYYmmDDHHMMSS</string>
+ </property>
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;File index number before the date and time. This is the historic Wireshark ordering.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">nameTimeNumBG</string>
+ </attribute>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
<item row="0" column="3" rowspan="4">
<spacer name="horizontalSpacer_8">
<property name="orientation">
@@ -530,9 +566,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</stri
<property name="wrapping">
<bool>true</bool>
</property>
- <property name="minimum">
- <number>2</number>
- </property>
<property name="maximum">
<number>65535</number>
</property>
@@ -782,7 +815,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</stri
</sizepolicy>
</property>
<property name="toolTip">
- <string>Stop capturing after the specified number of packets have been captured.</string>
+ <string>Stop capturing after the specified number of files have been created.</string>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::PlusMinus</enum>
@@ -820,9 +853,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</stri
<property name="buttonSymbols">
<enum>QAbstractSpinBox::PlusMinus</enum>
</property>
- <property name="maximum">
- <number>2147483647</number>
- </property>
<property name="value">
<number>1</number>
</property>
@@ -972,5 +1002,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</stri
<connections/>
<buttongroups>
<buttongroup name="buttonGroup"/>
+ <buttongroup name="nameTimeNumBG"/>
</buttongroups>
</ui>
diff --git a/ui/qt/capture_preferences_frame.cpp b/ui/qt/capture_preferences_frame.cpp
index 361eb656..b20bfbed 100644
--- a/ui/qt/capture_preferences_frame.cpp
+++ b/ui/qt/capture_preferences_frame.cpp
@@ -36,6 +36,7 @@ CapturePreferencesFrame::CapturePreferencesFrame(QWidget *parent) :
pref_device_ = prefFromPrefPtr(&prefs.capture_device);
pref_prom_mode_ = prefFromPrefPtr(&prefs.capture_prom_mode);
+ pref_monitor_mode_ = prefFromPrefPtr(&prefs.capture_monitor_mode);
pref_pcap_ng_ = prefFromPrefPtr(&prefs.capture_pcap_ng);
pref_real_time_ = prefFromPrefPtr(&prefs.capture_real_time);
pref_update_interval_ = prefFromPrefPtr(&prefs.capture_update_interval);
@@ -71,7 +72,7 @@ void CapturePreferencesFrame::updateWidgets()
}
ui->defaultInterfaceComboBox->clear();
if ((global_capture_opts.all_ifaces->len == 0) &&
- (prefs_get_bool_value(pref_no_interface_load_, pref_stashed) == FALSE)) {
+ (prefs_get_bool_value(pref_no_interface_load_, pref_stashed) == false)) {
/*
* No interfaces - try refreshing the local interfaces, to
* see whether any have showed up (or privileges have changed
@@ -79,7 +80,7 @@ void CapturePreferencesFrame::updateWidgets()
*/
mainApp->refreshLocalInterfaces();
}
- for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+ for (unsigned i = 0; i < global_capture_opts.all_ifaces->len; i++) {
device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
/* Continue if capture device is hidden */
@@ -122,6 +123,7 @@ void CapturePreferencesFrame::updateWidgets()
}
ui->capturePromModeCheckBox->setChecked(prefs_get_bool_value(pref_prom_mode_, pref_stashed));
+ ui->captureMonitorModeCheckBox->setChecked(prefs_get_bool_value(pref_monitor_mode_, pref_stashed));
ui->capturePcapNgCheckBox->setChecked(prefs_get_bool_value(pref_pcap_ng_, pref_stashed));
ui->captureRealTimeCheckBox->setChecked(prefs_get_bool_value(pref_real_time_, pref_stashed));
ui->captureUpdateIntervalLineEdit->setText(QString::number(prefs_get_uint_value_real(pref_update_interval_, pref_stashed)));
@@ -142,6 +144,11 @@ void CapturePreferencesFrame::on_capturePromModeCheckBox_toggled(bool checked)
prefs_set_bool_value(pref_prom_mode_, checked, pref_stashed);
}
+void CapturePreferencesFrame::on_captureMonitorModeCheckBox_toggled(bool checked)
+{
+ prefs_set_bool_value(pref_monitor_mode_, checked, pref_stashed);
+}
+
void CapturePreferencesFrame::on_capturePcapNgCheckBox_toggled(bool checked)
{
prefs_set_bool_value(pref_pcap_ng_, checked, pref_stashed);
diff --git a/ui/qt/capture_preferences_frame.h b/ui/qt/capture_preferences_frame.h
index 33cf29b8..35e3b495 100644
--- a/ui/qt/capture_preferences_frame.h
+++ b/ui/qt/capture_preferences_frame.h
@@ -32,6 +32,7 @@ protected:
private slots:
void on_defaultInterfaceComboBox_editTextChanged(const QString &new_iface);
void on_capturePromModeCheckBox_toggled(bool checked);
+ void on_captureMonitorModeCheckBox_toggled(bool checked);
void on_capturePcapNgCheckBox_toggled(bool checked);
void on_captureRealTimeCheckBox_toggled(bool checked);
void on_captureUpdateIntervalLineEdit_textChanged(const QString &new_str);
@@ -43,6 +44,7 @@ private:
pref_t *pref_device_;
pref_t *pref_prom_mode_;
+ pref_t *pref_monitor_mode_;
pref_t *pref_pcap_ng_;
pref_t *pref_real_time_;
pref_t *pref_update_interval_;
diff --git a/ui/qt/capture_preferences_frame.ui b/ui/qt/capture_preferences_frame.ui
index b5a0b4b8..c0a76efd 100644
--- a/ui/qt/capture_preferences_frame.ui
+++ b/ui/qt/capture_preferences_frame.ui
@@ -68,6 +68,16 @@
</widget>
</item>
<item>
+ <widget class="QCheckBox" name="captureMonitorModeCheckBox">
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string>Capture packets in monitor mode on 802.11 devices</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QCheckBox" name="capturePcapNgCheckBox">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Capture packets in the next-generation capture file format.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
diff --git a/ui/qt/coloring_rules_dialog.cpp b/ui/qt/coloring_rules_dialog.cpp
index 20eb72b2..c33013b6 100644
--- a/ui/qt/coloring_rules_dialog.cpp
+++ b/ui/qt/coloring_rules_dialog.cpp
@@ -96,7 +96,7 @@ ColoringRulesDialog::ColoringRulesDialog(QWidget *parent, QString add_filter) :
ui->buttonBox->addButton(copy_button, QDialogButtonBox::ActionRole);
connect(copy_button, &CopyFromProfileButton::copyProfile, this, &ColoringRulesDialog::copyFromProfile);
- QString abs_path = gchar_free_to_qstring(get_persconffile_path(COLORFILTERS_FILE_NAME, TRUE));
+ QString abs_path = gchar_free_to_qstring(get_persconffile_path(COLORFILTERS_FILE_NAME, true));
if (file_exists(abs_path.toUtf8().constData())) {
ui->pathLabel->setText(abs_path);
ui->pathLabel->setUrl(QUrl::fromLocalFile(abs_path).toString());
@@ -229,7 +229,7 @@ void ColoringRulesDialog::updateHint(QModelIndex idx)
if (errors_.count() > 0) {
//take the list of QModelIndexes and sort them so first color rule error is displayed
- //This isn't the most efficent algorithm, but the list shouldn't be large to matter
+ //This isn't the most efficient algorithm, but the list shouldn't be large to matter
QList<QModelIndex> keys = errors_.keys();
//list is not guaranteed to be sorted, so force it
@@ -315,7 +315,7 @@ void ColoringRulesDialog::changeColor(bool foreground)
if (!current.isValid())
return;
- QColorDialog *color_dlg = new QColorDialog();
+ QColorDialog *color_dlg = new QColorDialog(this);
color_dlg->setCurrentColor(colorRuleModel_.data(current, foreground ? Qt::ForegroundRole : Qt::BackgroundRole).toString());
connect(color_dlg, &QColorDialog::colorSelected, std::bind(&ColoringRulesDialog::colorChanged, this, foreground, std::placeholders::_1));
diff --git a/ui/qt/column_editor_frame.cpp b/ui/qt/column_editor_frame.cpp
index ea527b9a..4525ea2c 100644
--- a/ui/qt/column_editor_frame.cpp
+++ b/ui/qt/column_editor_frame.cpp
@@ -9,8 +9,6 @@
#include "config.h"
-#include <glib.h>
-
#include <epan/column.h>
#include <epan/prefs.h>
#include <ui/recent.h>
@@ -25,6 +23,7 @@
#include <QPushButton>
#include <QComboBox>
#include <QKeyEvent>
+#include <QAbstractItemView>
ColumnEditorFrame::ColumnEditorFrame(QWidget *parent) :
AccordionFrame(parent),
@@ -43,10 +42,32 @@ ColumnEditorFrame::ColumnEditorFrame(QWidget *parent) :
ui->typeComboBox->addItem(col_format_desc(i), QVariant(i));
}
+ // We want a behavior where the occurrenceLineEdit and type line edit
+ // will shrink, but where they won't expand past their needed space.
+ // Setting a stretch factor will make them expand (ignoring their
+ // SizePolicy) unless we also set the maximum width to their size hints.
+ //
+ ui->horizontalLayout->setStretchFactor(ui->titleLineEdit, 2);
+ ui->horizontalLayout->setStretchFactor(ui->occurrenceLineEdit, 1);
+ ui->occurrenceLineEdit->setMaximumWidth(ui->occurrenceLineEdit->sizeHint().width());
+ // On Windows, this is necessary to make the popup be the width of the
+ // longest item, instead of the width matching the combobox and using
+ // ellipses. (Linux has the popup wider by default.)
+ ui->typeComboBox->view()->setMinimumWidth(ui->typeComboBox->sizeHint().width());
+ // This lets the typeComboBox shrink a bit if the width is very small.
+ ui->typeComboBox->setMinimumContentsLength(20);
+
connect(ui->fieldsNameLineEdit, &FieldFilterEdit::textChanged,
ui->fieldsNameLineEdit, &FieldFilterEdit::checkCustomColumn);
connect(ui->fieldsNameLineEdit, &FieldFilterEdit::textChanged,
this, &ColumnEditorFrame::checkCanResolve);
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ connect(ui->typeComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
+ &ColumnEditorFrame::typeChanged);
+#else
+ connect(ui->typeComboBox, &QComboBox::currentIndexChanged, this,
+ &ColumnEditorFrame::typeChanged);
+#endif
}
ColumnEditorFrame::~ColumnEditorFrame()
@@ -82,6 +103,34 @@ void ColumnEditorFrame::setFields(int index)
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(ok);
}
+void ColumnEditorFrame::typeChanged(int index)
+{
+ // The fieldsNameLineEdit and occurrenceLineEdit are only relevant if the
+ // typeComboBox is COL_CUSTOM. The text for "Custom" is small. So when
+ // COL_CUSTOM is selected, shrink the size of the typeComboBox to what is
+ // necessary for "Custom" and give extra space to the fieldsNameLineEdit.
+ // For any other column type, do the reverse.
+ if (index == COL_CUSTOM) {
+ int width = fontMetrics().boundingRect(ui->typeComboBox->currentText()).width();
+ if (!ui->typeComboBox->itemIcon(index).isNull()) {
+ width += ui->typeComboBox->iconSize().width() + 4;
+ }
+ QStyleOptionComboBox opt;
+ opt.initFrom(ui->typeComboBox);
+ QSize sh(width, ui->typeComboBox->height());
+ width = ui->typeComboBox->style()->sizeFromContents(QStyle::CT_ComboBox, &opt, sh, ui->typeComboBox).width();
+ ui->typeComboBox->setMaximumWidth(width);
+ ui->fieldsNameLineEdit->setMaximumWidth(16777215); // Default (no) maximum
+ ui->horizontalLayout->setStretchFactor(ui->typeComboBox, 1);
+ ui->horizontalLayout->setStretchFactor(ui->fieldsNameLineEdit, 4);
+ } else {
+ ui->typeComboBox->setMaximumWidth(ui->typeComboBox->sizeHint().width());
+ ui->fieldsNameLineEdit->setMaximumWidth(ui->fieldsNameLineEdit->sizeHint().width());
+ ui->horizontalLayout->setStretchFactor(ui->typeComboBox, 2);
+ ui->horizontalLayout->setStretchFactor(ui->fieldsNameLineEdit, 1);
+ }
+}
+
void ColumnEditorFrame::editColumn(int column)
{
cur_column_ = column;
@@ -146,12 +195,8 @@ void ColumnEditorFrame::on_buttonBox_accepted()
set_column_title(cur_column_, col_str.constData());
set_column_format(cur_column_, ui->typeComboBox->currentIndex());
if (ui->typeComboBox->currentIndex() == COL_CUSTOM) {
- gint width = recent_get_column_width(cur_column_);
- gchar xalign = recent_get_column_xalign(cur_column_);
col_str = ui->fieldsNameLineEdit->text().toUtf8();
set_column_custom_fields(cur_column_, col_str.constData());
- recent_set_column_width(cur_column_, width);
- recent_set_column_xalign(cur_column_, xalign);
if (!ui->occurrenceLineEdit->text().isEmpty()) {
set_column_custom_occurrence(cur_column_, ui->occurrenceLineEdit->text().toInt());
}
diff --git a/ui/qt/column_editor_frame.h b/ui/qt/column_editor_frame.h
index 3778fb0d..6bd18cbb 100644
--- a/ui/qt/column_editor_frame.h
+++ b/ui/qt/column_editor_frame.h
@@ -47,6 +47,7 @@ private:
QString saved_fields_;
QString saved_occurrence_;
void setFields(int index);
+ void typeChanged(int index);
};
#endif // COLUMN_EDITOR_FRAME_H
diff --git a/ui/qt/column_editor_frame.ui b/ui/qt/column_editor_frame.ui
index 682be2bc..781b2d9b 100644
--- a/ui/qt/column_editor_frame.ui
+++ b/ui/qt/column_editor_frame.ui
@@ -19,7 +19,7 @@
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
- <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,1,0,0,0,0,0,2,0,0,0,0,0">
+ <layout class="QHBoxLayout" name="horizontalLayout">
<property name="topMargin">
<number>0</number>
</property>
@@ -43,7 +43,7 @@
</property>
<property name="sizeHint" stdset="0">
<size>
- <width>20</width>
+ <width>10</width>
<height>5</height>
</size>
</property>
@@ -66,7 +66,7 @@
</property>
<property name="sizeHint" stdset="0">
<size>
- <width>20</width>
+ <width>10</width>
<height>5</height>
</size>
</property>
@@ -89,7 +89,7 @@
</property>
<property name="sizeHint" stdset="0">
<size>
- <width>20</width>
+ <width>10</width>
<height>5</height>
</size>
</property>
@@ -125,7 +125,7 @@
</property>
<property name="sizeHint" stdset="0">
<size>
- <width>20</width>
+ <width>10</width>
<height>5</height>
</size>
</property>
diff --git a/ui/qt/column_preferences_frame.cpp b/ui/qt/column_preferences_frame.cpp
index 961e2737..3bfd8bdb 100644
--- a/ui/qt/column_preferences_frame.cpp
+++ b/ui/qt/column_preferences_frame.cpp
@@ -9,8 +9,6 @@
#include "config.h"
-#include <glib.h>
-
#include <epan/column.h>
#include <epan/prefs.h>
#include <epan/proto.h>
diff --git a/ui/qt/compiled_filter_output.cpp b/ui/qt/compiled_filter_output.cpp
index 1db9c899..7e7d778e 100644
--- a/ui/qt/compiled_filter_output.cpp
+++ b/ui/qt/compiled_filter_output.cpp
@@ -28,10 +28,9 @@
#include <QClipboard>
#include <QPushButton>
-CompiledFilterOutput::CompiledFilterOutput(QWidget *parent, QStringList &intList, QString &compile_filter) :
+CompiledFilterOutput::CompiledFilterOutput(QWidget *parent, QList<InterfaceFilter> &intList) :
GeometryStateDialog(parent),
intList_(intList),
- compile_filter_(compile_filter),
ui(new Ui::CompiledFilterOutput)
{
ui->setupUi(this);
@@ -47,8 +46,7 @@ CompiledFilterOutput::CompiledFilterOutput(QWidget *parent, QStringList &intList
close_bt->setDefault(true);
interface_list_ = ui->interfaceList;
- pcap_compile_mtx = g_new(GMutex,1);
- g_mutex_init(pcap_compile_mtx);
+ g_mutex_init(&pcap_compile_mtx_);
#ifdef HAVE_LIBPCAP
compileFilter();
#endif
@@ -64,6 +62,7 @@ CompiledFilterOutput::~CompiledFilterOutput()
parentWidget()->activateWindow();
}
delete ui;
+ g_mutex_clear(&pcap_compile_mtx_);
}
#ifdef HAVE_LIBPCAP
@@ -71,21 +70,21 @@ void CompiledFilterOutput::compileFilter()
{
struct bpf_program fcode;
- foreach (QString interfaces, intList_) {
- for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+ foreach (InterfaceFilter current, intList_) {
+ for (unsigned i = 0; i < global_capture_opts.all_ifaces->len; i++) {
interface_t *device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
- if (interfaces.compare(device->display_name)) {
+ if (current.interface.compare(device->display_name)) {
continue;
} else {
pcap_t *pd = pcap_open_dead(device->active_dlt, WTAP_MAX_PACKET_SIZE_STANDARD);
if (pd == NULL)
break;
- g_mutex_lock(pcap_compile_mtx);
- if (pcap_compile(pd, &fcode, compile_filter_.toUtf8().data(), 1, 0) < 0) {
- compile_results.insert(interfaces, QString(pcap_geterr(pd)));
- g_mutex_unlock(pcap_compile_mtx);
- ui->interfaceList->addItem(new QListWidgetItem(QIcon(":expert/expert_error.png"),interfaces));
+ g_mutex_lock(&pcap_compile_mtx_);
+ if (pcap_compile(pd, &fcode, current.filter.toUtf8().data(), 1, 0) < 0) {
+ compile_results.insert(current.interface, QString(pcap_geterr(pd)));
+ g_mutex_unlock(&pcap_compile_mtx_);
+ ui->interfaceList->addItem(new QListWidgetItem(QIcon(":expert/expert_error.png"), current.interface));
} else {
GString *bpf_code_dump = g_string_new("");
struct bpf_insn *insn = fcode.bf_insns;
@@ -94,11 +93,13 @@ void CompiledFilterOutput::compileFilter()
g_string_append(bpf_code_dump, bpf_image(insn, ii));
g_string_append(bpf_code_dump, "\n");
}
- g_mutex_unlock(pcap_compile_mtx);
- compile_results.insert(interfaces, QString(bpf_code_dump->str));
+ g_mutex_unlock(&pcap_compile_mtx_);
+ compile_results.insert(current.interface, QString(bpf_code_dump->str));
g_string_free(bpf_code_dump, TRUE);
- ui->interfaceList->addItem(new QListWidgetItem(interfaces));
+ ui->interfaceList->addItem(new QListWidgetItem(current.interface));
+ pcap_freecode(&fcode);
}
+ pcap_close(pd);
break;
}
}
diff --git a/ui/qt/compiled_filter_output.h b/ui/qt/compiled_filter_output.h
index a94fc4f0..d87c7c29 100644
--- a/ui/qt/compiled_filter_output.h
+++ b/ui/qt/compiled_filter_output.h
@@ -19,6 +19,13 @@
#include <glib.h>
+struct InterfaceFilter {
+ InterfaceFilter(QString intf, QString filt) : interface(intf), filter(filt) {}
+
+ QString interface;
+ QString filter;
+};
+
namespace Ui {
class CompiledFilterOutput;
}
@@ -28,10 +35,9 @@ class CompiledFilterOutput : public GeometryStateDialog
Q_OBJECT
private:
- QStringList intList_;
- QString &compile_filter_;
+ QList<InterfaceFilter> intList_;
Ui::CompiledFilterOutput *ui;
- GMutex *pcap_compile_mtx;
+ GMutex pcap_compile_mtx_;
QHash<QString, QString> compile_results;
QListWidget *interface_list_;
QPushButton *copy_bt_;
@@ -40,7 +46,7 @@ private:
#endif
public:
- explicit CompiledFilterOutput(QWidget *parent = 0, QStringList &intList = *new QStringList(), QString &filter = *new QString());
+ explicit CompiledFilterOutput(QWidget *parent = 0, QList<InterfaceFilter> &intList = *new QList<InterfaceFilter>());
~CompiledFilterOutput();
diff --git a/ui/qt/conversation_colorize_action.cpp b/ui/qt/conversation_colorize_action.cpp
index 9518e1ee..cb358472 100644
--- a/ui/qt/conversation_colorize_action.cpp
+++ b/ui/qt/conversation_colorize_action.cpp
@@ -11,8 +11,6 @@
#include <config.h>
-#include <glib.h>
-
#include "epan/conversation_filter.h"
#include <QMenu>
diff --git a/ui/qt/conversation_dialog.cpp b/ui/qt/conversation_dialog.cpp
index bad3d6d2..cd69e434 100644
--- a/ui/qt/conversation_dialog.cpp
+++ b/ui/qt/conversation_dialog.cpp
@@ -71,7 +71,7 @@ ConversationDialog::ConversationDialog(QWidget &parent, CaptureFile &cf) :
{
trafficList()->setProtocolInfo(table_name_, &(recent.conversation_tabs));
- trafficTab()->setProtocolInfo(table_name_, trafficList(), &(recent.conversation_tabs_columns), &createModel);
+ trafficTab()->setProtocolInfo(table_name_, trafficList(), &(recent.conversation_tabs), &(recent.conversation_tabs_columns), &createModel);
trafficTab()->setDelegate(&createDelegate);
trafficTab()->setDelegate(&createDelegate);
trafficTab()->setFilter(cf.displayFilter());
@@ -148,6 +148,9 @@ void ConversationDialog::graphTcp()
void ConversationDialog::tabChanged(int)
{
+ // By default we'll open the last known opened tab from the Profile
+ GList *selected_tab = NULL;
+
bool follow = false;
bool graph = false;
@@ -155,6 +158,19 @@ void ConversationDialog::tabChanged(int)
QVariant proto_id = trafficTab()->currentItemData(ATapDataModel::PROTO_ID);
if (!proto_id.isNull()) {
follow = (get_follow_by_proto_id(proto_id.toInt()) != nullptr);
+
+ for (GList * endTab = recent.conversation_tabs; endTab; endTab = endTab->next) {
+ int protoId = proto_get_id_by_short_name((const char *)endTab->data);
+ if ((protoId > -1) && (protoId==proto_id.toInt())) {
+ selected_tab = endTab;
+ }
+ }
+
+ // Move the selected tab to the head
+ if (selected_tab != nullptr) {
+ recent.conversation_tabs = g_list_remove_link(recent.conversation_tabs, selected_tab);
+ recent.conversation_tabs = g_list_prepend(recent.conversation_tabs, selected_tab->data);
+ }
}
int endpointType = trafficTab()->currentItemData(ATapDataModel::ENDPOINT_DATATYPE).toInt();
switch(endpointType) {
diff --git a/ui/qt/conversation_dialog.h b/ui/qt/conversation_dialog.h
index 5ad058ac..e54b67f4 100644
--- a/ui/qt/conversation_dialog.h
+++ b/ui/qt/conversation_dialog.h
@@ -28,7 +28,7 @@ protected:
void captureFileClosing();
signals:
- void openFollowStreamDialog(int proto_id, guint stream_num, guint sub_stream_num);
+ void openFollowStreamDialog(int proto_id, unsigned stream_num, unsigned sub_stream_num);
private:
QPushButton *follow_bt_;
diff --git a/ui/qt/conversation_hash_tables_dialog.cpp b/ui/qt/conversation_hash_tables_dialog.cpp
index cc699dae..f7f4fc74 100644
--- a/ui/qt/conversation_hash_tables_dialog.cpp
+++ b/ui/qt/conversation_hash_tables_dialog.cpp
@@ -12,8 +12,6 @@
#include "config.h"
-#include <glib.h>
-
#include <epan/conversation.h>
#include <epan/conversation_debug.h>
@@ -21,7 +19,7 @@
#include "main_application.h"
static void
-fill_named_table(gpointer key, gpointer value _U_, gpointer user_data)
+fill_named_table(void *key, void *value _U_, void *user_data)
{
const conversation_element_t *elements = static_cast<const conversation_element_t *>(key);
QString* html_table = static_cast<QString *>(user_data);
@@ -38,6 +36,8 @@ fill_named_table(gpointer key, gpointer value _U_, gpointer user_data)
int uint_count = 1;
int uint64_count = 1;
int int_count = 1;
+ int int64_count = 1;
+ int blob_count = 1;
for (const conversation_element_t *cur_el = elements; ; cur_el++) {
QString title;
switch (cur_el->type) {
@@ -59,6 +59,12 @@ fill_named_table(gpointer key, gpointer value _U_, gpointer user_data)
case CE_INT:
title = QString("Int %1").arg(int_count++);
break;
+ case CE_INT64:
+ title = QString("Int64 %1").arg(int64_count++);
+ break;
+ case CE_BLOB:
+ title = QString("Blob %1").arg(blob_count++);
+ break;
case CE_CONVERSATION_TYPE:
html_table->append(QString("<th>Endpoint</th>"));
goto title_done;
@@ -93,6 +99,12 @@ title_done:
case CE_INT:
val = QString::number(cur_el->int_val);
break;
+ case CE_INT64:
+ val = QString::number(cur_el->int64_val);
+ break;
+ case CE_BLOB:
+ val = QString(QByteArray::fromRawData((const char *)cur_el->blob.val, (int)cur_el->blob.len).toHex());
+ break;
case CE_CONVERSATION_TYPE:
html_table->append(QString("<td>%1</td>").arg(QString::number(cur_el->conversation_type_val)));
goto val_done;
diff --git a/ui/qt/decode_as_dialog.cpp b/ui/qt/decode_as_dialog.cpp
index edc6ccc7..c45fae2e 100644
--- a/ui/qt/decode_as_dialog.cpp
+++ b/ui/qt/decode_as_dialog.cpp
@@ -65,7 +65,7 @@ DecodeAsDialog::DecodeAsDialog(QWidget *parent, capture_file *cf, bool create_ne
setWindowTitle(mainApp->windowTitleString(tr("Decode As…")));
- QString abs_path = gchar_free_to_qstring(get_persconffile_path(DECODE_AS_ENTRIES_FILE_NAME, TRUE));
+ QString abs_path = gchar_free_to_qstring(get_persconffile_path(DECODE_AS_ENTRIES_FILE_NAME, true));
if (file_exists(abs_path.toUtf8().constData())) {
ui->pathLabel->setText(abs_path);
ui->pathLabel->setUrl(QUrl::fromLocalFile(abs_path).toString());
@@ -137,7 +137,7 @@ void DecodeAsDialog::on_decodeAsTreeView_currentItemChanged(const QModelIndex &c
void DecodeAsDialog::copyFromProfile(QString filename)
{
- const gchar *err = NULL;
+ const char *err = NULL;
if (!model_->copyFromProfile(filename, &err)) {
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Error while loading %s: %s", filename.toUtf8().constData(), err);
@@ -213,7 +213,7 @@ void DecodeAsDialog::on_buttonBox_clicked(QAbstractButton *button)
break;
case QDialogButtonBox::Save:
{
- gchar* err = NULL;
+ char* err = NULL;
applyChanges();
if (save_decode_as_entries(&err) < 0) {
diff --git a/ui/qt/decode_as_dialog.h b/ui/qt/decode_as_dialog.h
index 8765489a..73d664d3 100644
--- a/ui/qt/decode_as_dialog.h
+++ b/ui/qt/decode_as_dialog.h
@@ -12,8 +12,6 @@
#include <config.h>
-#include <glib.h>
-
#include "cfile.h"
#include <ui/qt/models/decode_as_model.h>
#include <ui/qt/models/decode_as_delegate.h>
diff --git a/ui/qt/display_filter_expression_dialog.cpp b/ui/qt/display_filter_expression_dialog.cpp
index e071d0ab..d192ec4f 100644
--- a/ui/qt/display_filter_expression_dialog.cpp
+++ b/ui/qt/display_filter_expression_dialog.cpp
@@ -316,9 +316,9 @@ void DisplayFilterExpressionDialog::updateWidgets()
void DisplayFilterExpressionDialog::fillEnumBooleanValues(const true_false_string *tfs)
{
- QListWidgetItem *eli = new QListWidgetItem(tfs_get_string(TRUE, tfs), ui->enumListWidget);
+ QListWidgetItem *eli = new QListWidgetItem(tfs_get_string(true, tfs), ui->enumListWidget);
eli->setData(Qt::UserRole, QString("1"));
- eli = new QListWidgetItem(tfs_get_string(FALSE, tfs), ui->enumListWidget);
+ eli = new QListWidgetItem(tfs_get_string(false, tfs), ui->enumListWidget);
eli->setData(Qt::UserRole, QString("0"));
}
diff --git a/ui/qt/endpoint_dialog.cpp b/ui/qt/endpoint_dialog.cpp
index 38a30be2..d3fd98d0 100644
--- a/ui/qt/endpoint_dialog.cpp
+++ b/ui/qt/endpoint_dialog.cpp
@@ -69,7 +69,7 @@ EndpointDialog::EndpointDialog(QWidget &parent, CaptureFile &cf) :
{
trafficList()->setProtocolInfo(table_name_, &(recent.endpoint_tabs));
- trafficTab()->setProtocolInfo(table_name_, trafficList(), &(recent.endpoint_tabs_columns), &createModel);
+ trafficTab()->setProtocolInfo(table_name_, trafficList(), &(recent.endpoint_tabs), &(recent.endpoint_tabs_columns), &createModel);
trafficTab()->setFilter(cf.displayFilter());
connect(trafficTab(), &TrafficTab::filterAction, this, &EndpointDialog::filterAction);
@@ -111,6 +111,29 @@ void EndpointDialog::tabChanged(int idx)
Q_UNUSED(idx);
#endif
+
+ // By default we'll open the last known opened tab from the Profile
+ GList *selected_tab = NULL;
+
+ if (!file_closed_) {
+ QVariant proto_id = trafficTab()->currentItemData(ATapDataModel::PROTO_ID);
+ if (!proto_id.isNull()) {
+
+ for (GList * endTab = recent.endpoint_tabs; endTab; endTab = endTab->next) {
+ int protoId = proto_get_id_by_short_name((const char *)endTab->data);
+ if ((protoId > -1) && (protoId==proto_id.toInt())) {
+ selected_tab = endTab;
+ }
+ }
+
+ // Move the selected tab to the head
+ if (selected_tab != nullptr) {
+ recent.endpoint_tabs = g_list_remove_link(recent.endpoint_tabs, selected_tab);
+ recent.endpoint_tabs = g_list_prepend(recent.endpoint_tabs, selected_tab->data);
+ }
+ }
+ }
+
TrafficTableDialog::currentTabChanged();
}
diff --git a/ui/qt/expert_info_dialog.h b/ui/qt/expert_info_dialog.h
index 1494ffb4..38eb8f09 100644
--- a/ui/qt/expert_info_dialog.h
+++ b/ui/qt/expert_info_dialog.h
@@ -12,8 +12,6 @@
#include <config.h>
-#include <glib.h>
-
#include "filter_action.h"
#include "wireshark_dialog.h"
#include <ui/qt/models/expert_info_model.h>
diff --git a/ui/qt/export_dissection_dialog.cpp b/ui/qt/export_dissection_dialog.cpp
index 7f2664ec..3a51bfd4 100644
--- a/ui/qt/export_dissection_dialog.cpp
+++ b/ui/qt/export_dissection_dialog.cpp
@@ -9,12 +9,6 @@
#include "export_dissection_dialog.h"
-#ifdef Q_OS_WIN
-#include <windows.h>
-#include "ui/packet_range.h"
-#include "ui/win32/file_dlg_win32.h"
-#else // Q_OS_WIN
-
#include "ui/alert_box.h"
#include "ui/help_url.h"
#include "ui/util.h"
@@ -28,12 +22,9 @@
#include <QDialogButtonBox>
#include <QGridLayout>
#include <QPushButton>
-#endif // Q_OS_WIN
-#include <epan/prefs.h>
#include "main_application.h"
-#if !defined(Q_OS_WIN)
static const QStringList export_extensions = QStringList()
<< ""
<< "txt"
@@ -44,45 +35,16 @@ static const QStringList export_extensions = QStringList()
<< "c"
<< "json";
-#endif
-
ExportDissectionDialog::ExportDissectionDialog(QWidget *parent, capture_file *cap_file, export_type_e export_type, QString selRange):
WiresharkFileDialog(parent),
export_type_(export_type),
cap_file_(cap_file)
-#if !defined(Q_OS_WIN)
, save_bt_(NULL)
-#else
- , sel_range_(selRange)
-#endif /* Q_OS_WIN */
{
setWindowTitle(mainApp->windowTitleString(tr("Export Packet Dissections")));
- switch (prefs.gui_fileopen_style) {
-
- case FO_STYLE_LAST_OPENED:
- /* The user has specified that we should start out in the last directory
- * we looked in. If we've already opened a file, use its containing
- * directory, if we could determine it, as the directory, otherwise
- * use the "last opened" directory saved in the preferences file if
- * there was one.
- */
- setDirectory(mainApp->openDialogInitialDir());
- break;
-
- case FO_STYLE_SPECIFIED:
- /* The user has specified that we should always start out in a
- * specified directory; if they've specified that directory,
- * start out by showing the files in that dir.
- */
- if (prefs.gui_fileopen_dir[0] != '\0')
- setDirectory(prefs.gui_fileopen_dir);
- break;
- }
+ setDirectory(mainApp->openDialogInitialDir());
-#if !defined(Q_OS_WIN)
- // Add extra widgets
- // https://wiki.qt.io/Qt_project_org_faq#How_can_I_add_widgets_to_my_QFileDialog_instance.3F
setOption(QFileDialog::DontUseNativeDialog, true);
QDialogButtonBox *button_box = findChild<QDialogButtonBox *>();
QGridLayout *fd_grid = qobject_cast<QGridLayout*>(layout());
@@ -119,7 +81,7 @@ ExportDissectionDialog::ExportDissectionDialog(QWidget *parent, capture_file *ca
/* Init the export range */
packet_range_init(&print_args_.range, cap_file_);
/* Default to displayed packets */
- print_args_.range.process_filtered = TRUE;
+ print_args_.range.process_filtered = true;
packet_range_group_box_.initRange(&print_args_.range, selRange);
h_box->addWidget(&packet_range_group_box_);
@@ -128,64 +90,62 @@ ExportDissectionDialog::ExportDissectionDialog(QWidget *parent, capture_file *ca
if (button_box) {
button_box->addButton(QDialogButtonBox::Help);
- connect(button_box, SIGNAL(helpRequested()), this, SLOT(on_buttonBox_helpRequested()));
+ connect(button_box, &QDialogButtonBox::helpRequested, this, &ExportDissectionDialog::on_buttonBox_helpRequested);
save_bt_ = button_box->button(QDialogButtonBox::Save);
}
if (save_bt_) {
- connect(&packet_range_group_box_, SIGNAL(validityChanged(bool)),
- this, SLOT(checkValidity()));
- connect(&packet_format_group_box_, SIGNAL(formatChanged()),
- this, SLOT(checkValidity()));
+ connect(&packet_range_group_box_, &PacketRangeGroupBox::validityChanged,
+ this, &ExportDissectionDialog::checkValidity);
+ connect(&packet_format_group_box_, &PacketFormatGroupBox::formatChanged,
+ this, &ExportDissectionDialog::checkValidity);
+ save_bt_->installEventFilter(this);
}
- connect(this, SIGNAL(filterSelected(QString)), this, SLOT(exportTypeChanged(QString)));
+ connect(this, &ExportDissectionDialog::filterSelected, this, &ExportDissectionDialog::exportTypeChanged);
// Grow the dialog to account for the extra widgets.
resize(width(), height() + (packet_range_group_box_.height() * 2 / 3));
- connect(this, SIGNAL(filesSelected(QStringList)), this, SLOT(dialogAccepted(QStringList)));
-#else // Q_OS_WIN
-#endif // Q_OS_WIN
+ connect(this, &ExportDissectionDialog::filesSelected, this, &ExportDissectionDialog::dialogAccepted);
}
ExportDissectionDialog::~ExportDissectionDialog()
{
-#if !defined(Q_OS_WIN)
g_free(print_args_.file);
packet_range_cleanup(&print_args_.range);
-#endif
}
void ExportDissectionDialog::show()
{
-#if !defined(Q_OS_WIN)
if (cap_file_) {
WiresharkFileDialog::show();
}
-#else // Q_OS_WIN
- win32_export_file((HWND)parentWidget()->effectiveWinId(), windowTitle().toStdWString().c_str(), cap_file_, export_type_, sel_range_.toStdString().c_str());
-#endif // Q_OS_WIN
}
-#ifndef Q_OS_WIN
void ExportDissectionDialog::dialogAccepted(const QStringList &selected)
{
if (selected.length() > 0) {
+ /* writing might take a while, so hide ourselves so the user
+ * can't click on anything here (this dialog will be closed
+ * and deleted once this function is done), but can access
+ * the ProgressDialog in the main window to cancel the export.
+ */
+ hide();
cf_print_status_t status;
- QString file_name = selected[0];
+ QString file_name = QDir::toNativeSeparators(selected[0]);
/* Fill in our print (and export) args */
print_args_.file = qstring_strdup(file_name);
print_args_.format = PR_FMT_TEXT;
- print_args_.to_file = TRUE;
+ print_args_.to_file = true;
print_args_.cmd = NULL;
- print_args_.print_summary = TRUE;
- print_args_.print_col_headings = TRUE;
+ print_args_.print_summary = true;
+ print_args_.print_col_headings = true;
print_args_.print_dissections = print_dissections_as_displayed;
- print_args_.print_hex = FALSE;
- print_args_.print_formfeed = FALSE;
+ print_args_.print_hex = false;
+ print_args_.print_formfeed = false;
switch (export_type_) {
case export_type_text: /* Text */
@@ -202,12 +162,12 @@ void ExportDissectionDialog::dialogAccepted(const QStringList &selected)
}
print_args_.print_hex = packet_format_group_box_.bytesEnabled();
print_args_.hexdump_options = packet_format_group_box_.getHexdumpOptions();
- print_args_.stream = print_stream_text_new(TRUE, print_args_.file);
+ print_args_.stream = print_stream_text_new(true, print_args_.file);
if (print_args_.stream == NULL) {
- open_failure_alert_box(print_args_.file, errno, TRUE);
+ open_failure_alert_box(print_args_.file, errno, true);
return;
}
- status = cf_print_packets(cap_file_, &print_args_, TRUE);
+ status = cf_print_packets(cap_file_, &print_args_, true);
break;
case export_type_csv: /* CSV */
status = cf_write_csv_packets(cap_file_, &print_args_);
@@ -232,14 +192,14 @@ void ExportDissectionDialog::dialogAccepted(const QStringList &selected)
case CF_PRINT_OK:
break;
case CF_PRINT_OPEN_ERROR:
- open_failure_alert_box(print_args_.file, errno, TRUE);
+ open_failure_alert_box(print_args_.file, errno, true);
break;
case CF_PRINT_WRITE_ERROR:
write_failure_alert_box(print_args_.file, errno);
break;
}
- gchar *dirname;
+ char *dirname;
/* Save the directory name for future file dialogs. */
dirname = get_dirname(print_args_.file); /* Overwrites file_name data */
set_last_open_dir(dirname);
@@ -260,28 +220,55 @@ void ExportDissectionDialog::exportTypeChanged(QString name_filter)
setDefaultSuffix(export_extensions[export_type_]);
}
-void ExportDissectionDialog::checkValidity()
+bool ExportDissectionDialog::isValid()
{
- bool enable = true;
+ bool valid = true;
- if (!save_bt_) return;
-
- if (!packet_range_group_box_.isValid()) enable = false;
+ if (!packet_range_group_box_.isValid()) valid = false;
if (export_type_ == export_type_text) {
if (! packet_format_group_box_.summaryEnabled() &&
! packet_format_group_box_.detailsEnabled() &&
! packet_format_group_box_.bytesEnabled())
{
- enable = false;
+ valid = false;
}
}
- save_bt_->setEnabled(enable);
+ return valid;
+}
+
+void ExportDissectionDialog::checkValidity()
+{
+ if (!save_bt_) return;
+
+ save_bt_->setEnabled(isValid());
}
void ExportDissectionDialog::on_buttonBox_helpRequested()
{
mainApp->helpTopicAction(HELP_EXPORT_FILE_DIALOG);
}
-#endif // Q_OS_WIN
+
+bool ExportDissectionDialog::eventFilter(QObject *obj, QEvent *event)
+{
+ // The QFileDialogPrivate will enable the Ok (Open/Save) button when
+ // anything is typed or selected. We can't catch that beforehand, so
+ // watch for the enable status change and re-disable it if the
+ // group boxes are invalid.
+ // We could do extra work (here and elsewhere) not to disable the button
+ // if what's selected in the dialog is a directory, but even with save_bt_
+ // disabled clicking on the directory still opens it.
+ if (event->type() == QEvent::EnabledChange) {
+ QPushButton *button = qobject_cast<QPushButton *>(obj);
+ if (button && button == save_bt_) {
+ // The button is already changed by the time we get this event.
+ if (button->isEnabled() && !isValid()) {
+ button->setEnabled(false);
+ return true;
+ }
+ }
+ }
+
+ return QObject::eventFilter(obj, event);
+}
diff --git a/ui/qt/export_dissection_dialog.h b/ui/qt/export_dissection_dialog.h
index 6d794918..47cb8ac8 100644
--- a/ui/qt/export_dissection_dialog.h
+++ b/ui/qt/export_dissection_dialog.h
@@ -12,18 +12,14 @@
#include <config.h>
-#include <glib.h>
-
#include "file.h"
#include "epan/print.h"
#include "ui/file_dialog.h"
#include <ui/qt/widgets/wireshark_file_dialog.h>
-#ifndef Q_OS_WIN
#include "packet_range_group_box.h"
#include "packet_format_group_box.h"
-#endif // Q_OS_WIN
#include <QMap>
@@ -38,18 +34,18 @@ public:
public slots:
void show();
+protected:
+ bool eventFilter(QObject *obj, QEvent *event) override;
+
private slots:
-#ifndef Q_OS_WIN
void dialogAccepted(const QStringList &selected);
void exportTypeChanged(QString name_filter);
void checkValidity();
void on_buttonBox_helpRequested();
-#endif // Q_OS_WIN
private:
export_type_e export_type_;
capture_file *cap_file_;
-#ifndef Q_OS_WIN
print_args_t print_args_;
QMap<QString, export_type_e> export_type_map_;
@@ -58,9 +54,8 @@ private:
PacketFormatGroupBox packet_format_group_box_;
QPushButton *save_bt_;
-#else
- QString sel_range_;
-#endif // Q_OS_WIN
+
+ bool isValid();
};
#endif // EXPORT_DISSECTION_DIALOG_H
diff --git a/ui/qt/export_object_action.cpp b/ui/qt/export_object_action.cpp
index bccf84ff..84626647 100644
--- a/ui/qt/export_object_action.cpp
+++ b/ui/qt/export_object_action.cpp
@@ -9,7 +9,6 @@
#include <config.h>
-#include <glib.h>
#include <epan/packet_info.h>
#include <epan/proto_data.h>
#include <epan/packet.h>
diff --git a/ui/qt/export_object_action.h b/ui/qt/export_object_action.h
index e4cc4cc5..7e6f0656 100644
--- a/ui/qt/export_object_action.h
+++ b/ui/qt/export_object_action.h
@@ -12,7 +12,6 @@
#include "config.h"
-#include <glib.h>
#include <epan/packet_info.h>
#include <epan/export_object.h>
diff --git a/ui/qt/export_pdu_dialog.cpp b/ui/qt/export_pdu_dialog.cpp
index 09709e18..27b77842 100644
--- a/ui/qt/export_pdu_dialog.cpp
+++ b/ui/qt/export_pdu_dialog.cpp
@@ -19,6 +19,8 @@
#include "ui/export_pdu_ui_utils.h"
#include "ui/capture_globals.h"
+#include "main_application.h"
+
ExportPDUDialog::ExportPDUDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::ExportPDUDialog)
@@ -27,12 +29,15 @@ ExportPDUDialog::ExportPDUDialog(QWidget *parent) :
ui->setupUi(this);
+ setWindowTitle(mainApp->windowTitleString(tr("Export PDUs")));
+
for (tap_name_list = get_export_pdu_tap_list(); tap_name_list; tap_name_list = g_slist_next(tap_name_list)) {
if (export_pdu_tap_get_encap((const char*)tap_name_list->data) == WTAP_ENCAP_WIRESHARK_UPPER_PDU) {
ui->comboBox->addItem((const char*)(tap_name_list->data));
}
}
}
+
void ExportPDUDialog::on_buttonBox_accepted()
{
const QByteArray& filter = ui->displayFilterLineEdit->text().toUtf8();
@@ -40,6 +45,12 @@ void ExportPDUDialog::on_buttonBox_accepted()
do_export_pdu(filter.constData(), global_capture_opts.temp_dir, tap_name.constData());
}
+
+void ExportPDUDialog::on_buttonBox_helpRequested()
+{
+ mainApp->helpTopicAction(HELP_EXPORT_PDUS_DIALOG);
+}
+
ExportPDUDialog::~ExportPDUDialog()
{
delete ui;
diff --git a/ui/qt/export_pdu_dialog.h b/ui/qt/export_pdu_dialog.h
index e76399a9..48d76f71 100644
--- a/ui/qt/export_pdu_dialog.h
+++ b/ui/qt/export_pdu_dialog.h
@@ -30,6 +30,7 @@ private:
private slots:
void on_buttonBox_accepted();
+ void on_buttonBox_helpRequested();
};
#endif // EXPORT_PDU_DIALOG_H
diff --git a/ui/qt/export_pdu_dialog.ui b/ui/qt/export_pdu_dialog.ui
index 2a0fae81..6127ba8b 100644
--- a/ui/qt/export_pdu_dialog.ui
+++ b/ui/qt/export_pdu_dialog.ui
@@ -26,7 +26,7 @@
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Help</set>
</property>
</widget>
<widget class="QWidget" name="layoutWidget">
@@ -75,32 +75,12 @@
<signal>accepted()</signal>
<receiver>ExportPDUDialog</receiver>
<slot>accept()</slot>
- <hints>
- <hint type="sourcelabel">
- <x>248</x>
- <y>254</y>
- </hint>
- <hint type="destinationlabel">
- <x>157</x>
- <y>274</y>
- </hint>
- </hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ExportPDUDialog</receiver>
<slot>reject()</slot>
- <hints>
- <hint type="sourcelabel">
- <x>316</x>
- <y>260</y>
- </hint>
- <hint type="destinationlabel">
- <x>286</x>
- <y>274</y>
- </hint>
- </hints>
</connection>
</connections>
</ui>
diff --git a/ui/qt/extcap_argument.cpp b/ui/qt/extcap_argument.cpp
index 0a965a79..84cbf906 100644
--- a/ui/qt/extcap_argument.cpp
+++ b/ui/qt/extcap_argument.cpp
@@ -38,6 +38,7 @@
#include <epan/prefs-int.h>
#include <wsutil/wslog.h>
#include <ui/qt/utils/color_utils.h>
+#include <ui/qt/utils/qt_ui_utils.h>
#include <extcap_parser.h>
#include <extcap_argument_file.h>
@@ -105,7 +106,7 @@ QString ExtArgTimestamp::prefValue()
bool ExtArgTimestamp::isSetDefaultValueSupported()
{
- return TRUE;
+ return true;
}
void ExtArgTimestamp::setDefaultValue()
@@ -230,7 +231,7 @@ QString ExtArgSelector::value()
bool ExtArgSelector::isSetDefaultValueSupported()
{
- return TRUE;
+ return true;
}
void ExtArgSelector::setDefaultValue()
@@ -313,6 +314,11 @@ void ExtArgEditSelector::setDefaultValue()
ExtArgRadio::ExtArgRadio(extcap_arg * argument, QObject * parent) :
ExtcapArgument(argument, parent), selectorGroup(0), callStrings(0) {}
+ExtArgRadio::~ExtArgRadio() {
+ if (callStrings != nullptr)
+ delete callStrings;
+}
+
QWidget * ExtArgRadio::createEditor(QWidget * parent)
{
int count = 0;
@@ -394,7 +400,7 @@ bool ExtArgRadio::isValid()
bool ExtArgRadio::isSetDefaultValueSupported()
{
- return TRUE;
+ return true;
}
void ExtArgRadio::setDefaultValue()
@@ -497,7 +503,7 @@ bool ExtArgBool::defaultBool()
if (_argument)
{
- if (extcap_complex_get_bool(_argument->default_complex) == (gboolean)TRUE)
+ if (extcap_complex_get_bool(_argument->default_complex) == true)
result = true;
}
@@ -511,7 +517,7 @@ QString ExtArgBool::defaultValue()
bool ExtArgBool::isSetDefaultValueSupported()
{
- return TRUE;
+ return true;
}
void ExtArgBool::setDefaultValue()
@@ -618,7 +624,7 @@ bool ExtArgText::isValid()
bool ExtArgText::isSetDefaultValueSupported()
{
- return TRUE;
+ return true;
}
void ExtArgText::setDefaultValue()
@@ -654,14 +660,14 @@ QWidget * ExtArgNumber::createEditor(QWidget * parent)
val = extcap_complex_get_int(_argument->range_start);
else if (_argument->arg_type == EXTCAP_ARG_UNSIGNED)
{
- guint tmp = extcap_complex_get_uint(_argument->range_start);
- if (tmp > G_MAXINT)
+ unsigned tmp = extcap_complex_get_uint(_argument->range_start);
+ if (tmp > INT_MAX)
{
ws_log(LOG_DOMAIN_CAPTURE, LOG_LEVEL_DEBUG, "Defined value for range_start of %s exceeds valid integer range", _argument->call);
- val = G_MAXINT;
+ val = INT_MAX;
}
else
- val = (gint)tmp;
+ val = (int)tmp;
}
textValidator->setBottom(val);
@@ -679,14 +685,14 @@ QWidget * ExtArgNumber::createEditor(QWidget * parent)
val = extcap_complex_get_int(_argument->range_end);
else if (_argument->arg_type == EXTCAP_ARG_UNSIGNED)
{
- guint tmp = extcap_complex_get_uint(_argument->range_end);
- if (tmp > G_MAXINT)
+ unsigned tmp = extcap_complex_get_uint(_argument->range_end);
+ if (tmp > INT_MAX)
{
ws_log(LOG_DOMAIN_CAPTURE, LOG_LEVEL_DEBUG, "Defined value for range_end of %s exceeds valid integer range", _argument->call);
- val = G_MAXINT;
+ val = INT_MAX;
}
else
- val = (gint)tmp;
+ val = (int)tmp;
}
textValidator->setTop(val);
@@ -807,7 +813,7 @@ ExtcapValueList ExtcapArgument::loadValues(QString parent)
QString call = QString().fromUtf8(v->call);
ExtcapValue element = ExtcapValue(display, call,
- v->enabled == (gboolean)TRUE, v->is_default == (gboolean)TRUE);
+ v->enabled == true, v->is_default == true);
if (!call.isEmpty())
element.setChildren(this->loadValues(call));
@@ -839,6 +845,7 @@ bool ExtcapArgument::reloadValues()
}
ExtcapArgument::~ExtcapArgument() {
+ extcap_free_arg(_argument);
}
QWidget * ExtcapArgument::createLabel(QWidget * parent)
@@ -907,9 +914,9 @@ QString ExtcapArgument::defaultValue()
{
if (_argument != 0 && _argument->default_complex != 0)
{
- gchar * str = extcap_get_complex_as_string(_argument->default_complex);
- if (str != 0)
- return QString(str);
+ char * str = extcap_get_complex_as_string(_argument->default_complex);
+ if (str != nullptr)
+ return gchar_free_to_qstring(str);
}
return QString();
}
@@ -946,7 +953,7 @@ bool ExtcapArgument::isRequired()
if (_argument != NULL)
return _argument->is_required;
- return FALSE;
+ return false;
}
bool ExtcapArgument::reload()
@@ -962,7 +969,7 @@ bool ExtcapArgument::fileExists()
if (_argument != NULL)
return _argument->fileexists;
- return FALSE;
+ return false;
}
bool ExtcapArgument::isDefault()
@@ -1027,7 +1034,7 @@ void ExtcapArgument::onBoolChanged(bool)
bool ExtcapArgument::isSetDefaultValueSupported()
{
- return FALSE;
+ return false;
}
void ExtcapArgument::setDefaultValue()
diff --git a/ui/qt/extcap_argument.h b/ui/qt/extcap_argument.h
index 2efa4e42..d9e852d7 100644
--- a/ui/qt/extcap_argument.h
+++ b/ui/qt/extcap_argument.h
@@ -211,6 +211,7 @@ class ExtArgRadio : public ExtcapArgument
public:
ExtArgRadio(extcap_arg * argument, QObject *parent = Q_NULLPTR);
+ virtual ~ExtArgRadio();
virtual QWidget * createEditor(QWidget * parent);
virtual QString value();
diff --git a/ui/qt/extcap_argument_multiselect.cpp b/ui/qt/extcap_argument_multiselect.cpp
index 6f816b98..4eb2e4d5 100644
--- a/ui/qt/extcap_argument_multiselect.cpp
+++ b/ui/qt/extcap_argument_multiselect.cpp
@@ -212,7 +212,7 @@ QString ExtArgMultiSelect::defaultValue()
bool ExtArgMultiSelect::isSetDefaultValueSupported()
{
- return TRUE;
+ return true;
}
void ExtArgMultiSelect::setDefaultValue()
diff --git a/ui/qt/extcap_options_dialog.cpp b/ui/qt/extcap_options_dialog.cpp
index 52c360c0..014a949a 100644
--- a/ui/qt/extcap_options_dialog.cpp
+++ b/ui/qt/extcap_options_dialog.cpp
@@ -9,8 +9,6 @@
#include <config.h>
-#include <glib.h>
-
#include <extcap_options_dialog.h>
#include <ui_extcap_options_dialog.h>
@@ -59,8 +57,7 @@ ExtcapOptionsDialog::ExtcapOptionsDialog(bool startCaptureOnClose, QWidget *pare
ui(new Ui::ExtcapOptionsDialog),
device_name(""),
device_idx(0),
- defaultValueIcon_(StockIcon("x-reset")),
- start_capture_on_close_(startCaptureOnClose)
+ defaultValueIcon_(StockIcon("x-reset"))
{
ui->setupUi(this);
@@ -68,10 +65,11 @@ ExtcapOptionsDialog::ExtcapOptionsDialog(bool startCaptureOnClose, QWidget *pare
ui->checkSaveOnStart->setCheckState(prefs.extcap_save_on_start ? Qt::Checked : Qt::Unchecked);
+ ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Start"));
if (startCaptureOnClose) {
- ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Start"));
- } else {
- ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Save"));
+ // This dialog was spawned because the user wanted to start a capture
+ // immediately but a mandatory parameter was not configured.
+ ui->buttonBox->button(QDialogButtonBox::Save)->hide();
}
}
@@ -80,7 +78,7 @@ ExtcapOptionsDialog * ExtcapOptionsDialog::createForDevice(QString &dev_name, bo
interface_t *device;
ExtcapOptionsDialog * resultDialog = NULL;
bool dev_found = false;
- guint if_idx;
+ unsigned if_idx;
if (dev_name.length() == 0)
return NULL;
@@ -118,26 +116,6 @@ ExtcapOptionsDialog::~ExtcapOptionsDialog()
delete ui;
}
-void ExtcapOptionsDialog::on_buttonBox_accepted()
-{
- if (saveOptionToCaptureInfo()) {
- /* Starting a new capture with those values */
- prefs.extcap_save_on_start = ui->checkSaveOnStart->checkState() == Qt::Checked;
-
- /* If the button says "Save" instead of "Start", unconditionally
- * save. XXX - Why not have both buttons? (#19199)
- *
- * XXX - If extcap_save_on_start is the only preference that has
- * changed, or if it changed from true to false, we should write
- * out a new preference file with its new value, but don't.
- */
- if (prefs.extcap_save_on_start || !start_capture_on_close_)
- storeValues();
-
- accept();
- }
-}
-
void ExtcapOptionsDialog::anyValueChanged()
{
bool allowStart = true;
@@ -241,7 +219,7 @@ void ExtcapOptionsDialog::loadArguments()
extcapArguments << optional;
/* argument items are now owned by ExtcapArgument. Only free the lists */
- extcap_free_if_configuration(arguments, FALSE);
+ extcap_free_if_configuration(arguments, false);
}
void ExtcapOptionsDialog::updateWidgets()
@@ -403,12 +381,6 @@ void ExtcapOptionsDialog::updateWidgets()
}
}
-// Not sure why we have to do this manually.
-void ExtcapOptionsDialog::on_buttonBox_rejected()
-{
- reject();
-}
-
void ExtcapOptionsDialog::on_buttonBox_helpRequested()
{
interface_t *device;
@@ -474,8 +446,8 @@ bool ExtcapOptionsDialog::saveOptionToCaptureInfo()
continue;
}
- gchar * call_string = qstring_strdup(call);
- gchar * value_string = NULL;
+ char * call_string = qstring_strdup(call);
+ char * value_string = NULL;
if (value.length() > 0)
value_string = qstring_strdup(value);
@@ -491,8 +463,41 @@ bool ExtcapOptionsDialog::saveOptionToCaptureInfo()
void ExtcapOptionsDialog::on_buttonBox_clicked(QAbstractButton *button)
{
/* Only the save button has the ActionRole */
- if (ui->buttonBox->buttonRole(button) == QDialogButtonBox::ResetRole)
+ switch (ui->buttonBox->buttonRole(button)) {
+ case QDialogButtonBox::ResetRole:
resetValues();
+ break;
+ case QDialogButtonBox::RejectRole:
+ case QDialogButtonBox::DestructiveRole:
+ /* entries are only saved if saveOptionToCaptureInfo() is called,
+ * so do nothing. */
+ reject();
+ break;
+ case QDialogButtonBox::AcceptRole:
+ if (saveOptionToCaptureInfo()) {
+ /* Starting a new capture with those values */
+ prefs.extcap_save_on_start = ui->checkSaveOnStart->checkState() == Qt::Checked;
+
+ /* XXX - If extcap_save_on_start is the only preference that has
+ * changed, or if it changed from true to false, we should write
+ * out a new preference file with its new value, but don't.
+ */
+ if (ui->buttonBox->standardButton(button) == QDialogButtonBox::Save) {
+ storeValues();
+ /* Reject the dialog, because we don't want to start a capture. */
+ reject();
+ } else {
+ /* Start */
+ if (prefs.extcap_save_on_start) {
+ storeValues();
+ }
+ accept();
+ }
+ }
+ break;
+ default:
+ break;
+ }
}
void ExtcapOptionsDialog::resetValues()
@@ -549,14 +554,14 @@ void ExtcapOptionsDialog::resetValues()
}
- /* Values are stored when dialog is commited, just check validity*/
+ /* Values are stored when dialog is committed, just check validity */
anyValueChanged();
}
}
GHashTable *ExtcapOptionsDialog::getArgumentSettings(bool useCallsAsKey, bool includeEmptyValues)
{
- GHashTable * entries = g_hash_table_new(g_str_hash, g_str_equal);
+ GHashTable * entries = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
ExtcapArgumentList::const_iterator iter;
QString value;
@@ -615,7 +620,7 @@ GHashTable *ExtcapOptionsDialog::getArgumentSettings(bool useCallsAsKey, bool in
if ((key.length() > 0) && (includeEmptyValues || isBoolflag || value.length() > 0) )
{
- gchar * val = qstring_strdup(value);
+ char * val = qstring_strdup(value);
g_hash_table_insert(entries, qstring_strdup(key), val);
}
@@ -634,6 +639,8 @@ void ExtcapOptionsDialog::storeValues()
mainApp->emitAppSignal(MainApplication::PreferencesChanged);
}
+
+ g_hash_table_unref(entries);
}
ExtcapValueList ExtcapOptionsDialog::loadValuesFor(int argNum, QString argumentName, QString parent)
@@ -673,7 +680,7 @@ ExtcapValueList ExtcapOptionsDialog::loadValuesFor(int argNum, QString argumentN
QString call = QString().fromUtf8(v->call);
ExtcapValue element = ExtcapValue(display, call,
- v->enabled == (gboolean)TRUE, v->is_default == (gboolean)TRUE);
+ v->enabled == true, v->is_default == true);
#if 0
/* TODO: Disabled due to wrong parent handling. It leads to an infinite loop for now. To implement this properly, other things
diff --git a/ui/qt/extcap_options_dialog.h b/ui/qt/extcap_options_dialog.h
index bb1d8e89..ddf82165 100644
--- a/ui/qt/extcap_options_dialog.h
+++ b/ui/qt/extcap_options_dialog.h
@@ -40,8 +40,6 @@ public:
ExtcapValueList loadValuesFor(int argNum, QString call, QString parent = "");
private Q_SLOTS:
- void on_buttonBox_accepted();
- void on_buttonBox_rejected();
void on_buttonBox_clicked(QAbstractButton *button);
void on_buttonBox_helpRequested();
void updateWidgets();
@@ -52,9 +50,8 @@ private:
Ui::ExtcapOptionsDialog *ui;
QString device_name;
- guint device_idx;
+ unsigned device_idx;
QIcon defaultValueIcon_;
- bool start_capture_on_close_;
ExtcapArgumentList extcapArguments;
diff --git a/ui/qt/extcap_options_dialog.ui b/ui/qt/extcap_options_dialog.ui
index 337a0c9d..1c6f0d7b 100644
--- a/ui/qt/extcap_options_dialog.ui
+++ b/ui/qt/extcap_options_dialog.ui
@@ -40,7 +40,7 @@
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
- <set>QDialogButtonBox::Close|QDialogButtonBox::Help|QDialogButtonBox::Ok|QDialogButtonBox::RestoreDefaults</set>
+ <set>QDialogButtonBox::Discard|QDialogButtonBox::Help|QDialogButtonBox::Ok|QDialogButtonBox::Save|QDialogButtonBox::RestoreDefaults</set>
</property>
</widget>
</item>
diff --git a/ui/qt/file_set_dialog.cpp b/ui/qt/file_set_dialog.cpp
index 70f38914..0cb2d232 100644
--- a/ui/qt/file_set_dialog.cpp
+++ b/ui/qt/file_set_dialog.cpp
@@ -9,8 +9,6 @@
#include "config.h"
-#include <glib.h>
-
#include "file.h"
#include "fileset.h"
diff --git a/ui/qt/file_set_dialog.h b/ui/qt/file_set_dialog.h
index d4158898..defdeda6 100644
--- a/ui/qt/file_set_dialog.h
+++ b/ui/qt/file_set_dialog.h
@@ -12,8 +12,6 @@
#include <config.h>
-#include <glib.h>
-
#include "file.h"
#include "fileset.h"
diff --git a/ui/qt/filter_action.cpp b/ui/qt/filter_action.cpp
index f8b7732f..3a54cf67 100644
--- a/ui/qt/filter_action.cpp
+++ b/ui/qt/filter_action.cpp
@@ -66,25 +66,18 @@ const QString FilterAction::actionName(Action action) {
switch (action) {
case ActionApply:
return QObject::tr("Apply as Filter");
- break;
case ActionPrepare:
return QObject::tr("Prepare as Filter");
- break;
case ActionFind:
return QObject::tr("Find");
- break;
case ActionColorize:
return QObject::tr("Colorize");
- break;
case ActionWebLookup:
return QObject::tr("Look Up");
- break;
case ActionCopy:
return QObject::tr("Copy");
- break;
default:
return QObject::tr("UNKNOWN");
- break;
}
}
@@ -118,25 +111,18 @@ const QString FilterAction::actionTypeName(ActionType type) {
switch (type) {
case ActionTypePlain:
return QObject::tr("Selected");
- break;
case ActionTypeNot:
return QObject::tr("Not Selected");
- break;
case ActionTypeAnd:
return QObject::tr("…and Selected");
- break;
case ActionTypeOr:
return QObject::tr("…or Selected");
- break;
case ActionTypeAndNot:
return QObject::tr("…and not Selected");
- break;
case ActionTypeOrNot:
return QObject::tr("…or not Selected");
- break;
default:
return QObject::tr("UNKNOWN");
- break;
}
}
@@ -160,34 +146,24 @@ const QString FilterAction::actionDirectionName(ActionDirection direction) {
switch (direction) {
case ActionDirectionAToFromB:
return QObject::tr("A " UTF8_LEFT_RIGHT_ARROW " B");
- break;
case ActionDirectionAToB:
return QObject::tr("A " UTF8_RIGHTWARDS_ARROW " B");
- break;
case ActionDirectionAFromB:
return QObject::tr("B " UTF8_RIGHTWARDS_ARROW " A");
- break;
case ActionDirectionAToFromAny:
return QObject::tr("A " UTF8_LEFT_RIGHT_ARROW " Any");
- break;
case ActionDirectionAToAny:
return QObject::tr("A " UTF8_RIGHTWARDS_ARROW " Any");
- break;
case ActionDirectionAFromAny:
return QObject::tr("Any " UTF8_RIGHTWARDS_ARROW " A");
- break;
case ActionDirectionAnyToFromB:
return QObject::tr("Any " UTF8_LEFT_RIGHT_ARROW " B");
- break;
case ActionDirectionAnyToB:
return QObject::tr("Any " UTF8_RIGHTWARDS_ARROW " B");
- break;
case ActionDirectionAnyFromB:
return QObject::tr("B " UTF8_RIGHTWARDS_ARROW " Any");
- break;
default:
return QObject::tr("UNKNOWN");
- break;
}
}
diff --git a/ui/qt/filter_dialog.cpp b/ui/qt/filter_dialog.cpp
index 1ed86b87..e1617611 100644
--- a/ui/qt/filter_dialog.cpp
+++ b/ui/qt/filter_dialog.cpp
@@ -9,8 +9,6 @@
#include <config.h>
-#include <glib.h>
-
#include <wsutil/filter_files.h>
#include <wsutil/filesystem.h>
@@ -59,18 +57,29 @@ FilterDialog::FilterDialog(QWidget *parent, FilterType filter_type, QString new_
ui->filterTreeView->setAcceptDrops(true);
ui->filterTreeView->setDropIndicatorShown(true);
- const gchar * filename = NULL;
+ const char * filename = NULL;
QString newFilterText;
- if (filter_type == CaptureFilter) {
- setWindowTitle(mainApp->windowTitleString(tr("Capture Filters")));
- filename = CFILTER_FILE_NAME;
- newFilterText = tr("New capture filter");
- model_ = new FilterListModel(FilterListModel::Capture, this);
- } else {
- setWindowTitle(mainApp->windowTitleString(tr("Display Filters")));
- filename = DFILTER_FILE_NAME;
- newFilterText = tr("New display filter");
- model_ = new FilterListModel(FilterListModel::Display, this);
+ switch (filter_type) {
+ case CaptureFilter:
+ setWindowTitle(mainApp->windowTitleString(tr("Capture Filters")));
+ filename = CFILTER_FILE_NAME;
+ newFilterText = tr("New capture filter");
+ model_ = new FilterListModel(FilterListModel::Capture, this);
+ break;
+ case DisplayFilter:
+ setWindowTitle(mainApp->windowTitleString(tr("Display Filters")));
+ filename = DFILTER_FILE_NAME;
+ newFilterText = tr("New display filter");
+ model_ = new FilterListModel(FilterListModel::Display, this);
+ break;
+ case DisplayMacro:
+ setWindowTitle(mainApp->windowTitleString(tr("Display Filter Macros")));
+ filename = DMACROS_FILE_NAME;
+ newFilterText = tr("New macro");
+ model_ = new FilterListModel(FilterListModel::DisplayMacro, this);
+ break;
+ default:
+ ws_assert_not_reached();
}
if (new_filter_.length() > 0)
@@ -84,7 +93,7 @@ FilterDialog::FilterDialog(QWidget *parent, FilterType filter_type, QString new_
connect(ui->filterTreeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &FilterDialog::selectionChanged);
- QString abs_path = gchar_free_to_qstring(get_persconffile_path(filename, TRUE));
+ QString abs_path = gchar_free_to_qstring(get_persconffile_path(filename, true));
if (file_exists(abs_path.toUtf8().constData())) {
ui->pathLabel->setText(abs_path);
ui->pathLabel->setUrl(QUrl::fromLocalFile(abs_path).toString());
@@ -129,14 +138,24 @@ void FilterDialog::on_newToolButton_clicked()
QString name;
QString filter;
- if (filter_type_ == CaptureFilter) {
- //: This text is automatically filled in when a new filter is created
- name = tr("New capture filter");
- filter = "ip host host.example.com";
- } else {
- //: This text is automatically filled in when a new filter is created
- name = tr("New display filter");
- filter = "ip.host == host.example.com";
+ switch (filter_type_) {
+ case CaptureFilter:
+ //: This text is automatically filled in when a new filter is created
+ name = tr("New capture filter");
+ filter = "ip host host.example.com";
+ break;
+ case DisplayFilter:
+ //: This text is automatically filled in when a new filter is created
+ name = tr("New display filter");
+ filter = "ip.host == host.example.com";
+ break;
+ case DisplayMacro:
+ //: This text is automatically filled in when a new filter is created
+ name = "eq_example_com";
+ filter = "$1 == host.example.com";
+ break;
+ default:
+ ws_assert_not_reached();
}
addFilter(name, filter, true);
@@ -172,19 +191,43 @@ void FilterDialog::on_buttonBox_accepted()
{
model_->saveList();
- if (filter_type_ == CaptureFilter) {
- mainApp->emitAppSignal(MainApplication::CaptureFilterListChanged);
- } else {
- mainApp->emitAppSignal(MainApplication::DisplayFilterListChanged);
+ switch (filter_type_) {
+ case CaptureFilter:
+ mainApp->emitAppSignal(MainApplication::CaptureFilterListChanged);
+ break;
+ case DisplayFilter:
+ mainApp->emitAppSignal(MainApplication::DisplayFilterListChanged);
+ break;
+ case DisplayMacro:
+ mainApp->reloadDisplayFilterMacros();
+ // The function above emits MainApplication::FieldsChanged, which
+ // takes care of invalidating the current display filter text if
+ // it no longer compiles.
+ // XXX - What if the current display filter means something
+ // different now? Should we force a refilter (not redissection,
+ // the dissection shouldn't have changed) with the current display
+ // filter, or wait for the user to refilter?
+ // The UAT based display macro system did not refilter.
+ break;
+ default:
+ ws_assert_not_reached();
}
}
void FilterDialog::on_buttonBox_helpRequested()
{
- if (filter_type_ == CaptureFilter) {
- mainApp->helpTopicAction(HELP_CAPTURE_FILTERS_DIALOG);
- } else {
- mainApp->helpTopicAction(HELP_DISPLAY_FILTERS_DIALOG);
+ switch (filter_type_) {
+ case CaptureFilter:
+ mainApp->helpTopicAction(HELP_CAPTURE_FILTERS_DIALOG);
+ break;
+ case DisplayFilter:
+ mainApp->helpTopicAction(HELP_DISPLAY_FILTERS_DIALOG);
+ break;
+ case DisplayMacro:
+ mainApp->helpTopicAction(HELP_DISPLAY_MACRO_DIALOG);
+ break;
+ default:
+ ws_assert_not_reached();
}
}
@@ -204,17 +247,26 @@ QWidget *FilterTreeDelegate::createEditor(QWidget *parent, const QStyleOptionVie
if (index.column() != FilterListModel::ColumnExpression) {
w = QStyledItemDelegate::createEditor(parent, option, index);
}
- else
- {
- if (filter_type_ == FilterDialog::CaptureFilter) {
- w = new CaptureFilterEdit(parent, true);
- } else {
- w = new DisplayFilterEdit(parent, DisplayFilterToEnter);
- }
+ else if (filter_type_ == FilterDialog::CaptureFilter) {
+ w = new CaptureFilterEdit(parent, true);
+ }
+ else if (filter_type_ == FilterDialog::DisplayFilter) {
+ w = new DisplayFilterEdit(parent, DisplayFilterToEnter);
+ }
+ else {
+ w = QStyledItemDelegate::createEditor(parent, option, index);
}
- if (qobject_cast<QLineEdit *>(w) && index.column() == FilterListModel::ColumnName)
- qobject_cast<QLineEdit *>(w)->setValidator(new FilterValidator());
+ if (qobject_cast<QLineEdit *>(w)) {
+ if (index.column() == FilterListModel::ColumnName) {
+ if (filter_type_ == FilterDialog::DisplayMacro) {
+ qobject_cast<QLineEdit *>(w)->setValidator(new MacroNameValidator());
+ }
+ else {
+ qobject_cast<QLineEdit *>(w)->setValidator(new FilterValidator());
+ }
+ }
+ }
return w;
}
@@ -244,3 +296,17 @@ QValidator::State FilterValidator::validate(QString & input, int & /*pos*/) cons
return QValidator::Acceptable;
}
+
+QValidator::State MacroNameValidator::validate(QString &input, int & /*pos*/) const
+{
+ if (input.length() <= 0)
+ return QValidator::Intermediate;
+
+ for (QChar ch: input) {
+ if (!ch.isLetterOrNumber() && ch != '_') {
+ return QValidator::Invalid;
+ }
+ }
+
+ return QValidator::Acceptable;
+}
diff --git a/ui/qt/filter_dialog.h b/ui/qt/filter_dialog.h
index 34b3a156..90d2f1b2 100644
--- a/ui/qt/filter_dialog.h
+++ b/ui/qt/filter_dialog.h
@@ -29,7 +29,7 @@ class FilterDialog : public GeometryStateDialog
Q_OBJECT
public:
- enum FilterType { CaptureFilter, DisplayFilter };
+ enum FilterType { CaptureFilter, DisplayFilter, DisplayMacro };
explicit FilterDialog(QWidget *parent = 0, FilterType filter_type = CaptureFilter, const QString new_filter = QString());
~FilterDialog();
@@ -81,4 +81,10 @@ public:
virtual QValidator::State validate(QString & input, int & pos) const override;
};
+class MacroNameValidator : public QValidator
+{
+public:
+ virtual QValidator::State validate(QString & input, int & pos) const override;
+};
+
#endif // FILTER_DIALOG_H
diff --git a/ui/qt/filter_expression_frame.cpp b/ui/qt/filter_expression_frame.cpp
index 38975977..dd40b3fa 100644
--- a/ui/qt/filter_expression_frame.cpp
+++ b/ui/qt/filter_expression_frame.cpp
@@ -144,7 +144,7 @@ void FilterExpressionFrame::on_buttonBox_accepted()
}
else
{
- filter_expression_new(label_ba.constData(), expr_ba.constData(), comment_ba.constData(), TRUE);
+ filter_expression_new(label_ba.constData(), expr_ba.constData(), comment_ba.constData(), true);
}
save_migrated_uat("Display expressions", &prefs.filter_expressions_old);
diff --git a/ui/qt/firewall_rules_dialog.cpp b/ui/qt/firewall_rules_dialog.cpp
index a74355e1..e36e4235 100644
--- a/ui/qt/firewall_rules_dialog.cpp
+++ b/ui/qt/firewall_rules_dialog.cpp
@@ -127,15 +127,15 @@ void FirewallRulesDialog::updateWidgets()
}
#define ADDR_BUF_LEN 200
-void FirewallRulesDialog::addRule(QString description, syntax_func rule_func, address *addr, guint32 port)
+void FirewallRulesDialog::addRule(QString description, syntax_func rule_func, address *addr, uint32_t port)
{
if (!rule_func) return;
char addr_buf[ADDR_BUF_LEN];
QString comment_pfx = firewall_product_comment_prefix(prod_);
GString *rule_str = g_string_new("");
- gboolean inbound = ui->inboundCheckBox->isChecked();
- gboolean deny = ui->denyCheckBox->isChecked();
+ bool inbound = ui->inboundCheckBox->isChecked();
+ bool deny = ui->denyCheckBox->isChecked();
address_to_str_buf(addr, addr_buf, ADDR_BUF_LEN);
rule_func(rule_str, addr_buf, port, ptype_, inbound, deny);
diff --git a/ui/qt/firewall_rules_dialog.h b/ui/qt/firewall_rules_dialog.h
index e14456f4..9d298048 100644
--- a/ui/qt/firewall_rules_dialog.h
+++ b/ui/qt/firewall_rules_dialog.h
@@ -20,7 +20,7 @@ class FirewallRulesDialog;
class QAbstractButton;
-typedef void (*syntax_func)(GString *rtxt, gchar *addr, guint32 port, port_type ptype, gboolean inbound, gboolean deny);
+typedef void (*syntax_func)(GString *rtxt, char *addr, uint32_t port, port_type ptype, bool inbound, bool deny);
class FirewallRulesDialog : public WiresharkDialog
{
@@ -50,11 +50,11 @@ private:
address net_src_;
address net_dst_;
port_type ptype_;
- guint32 src_port_;
- guint32 dst_port_;
+ uint32_t src_port_;
+ uint32_t dst_port_;
void updateWidgets();
- void addRule(QString description, syntax_func rule_func, address *addr, guint32 port);
+ void addRule(QString description, syntax_func rule_func, address *addr, uint32_t port);
};
#endif // FIREWALL_RULES_DIALOG_H
diff --git a/ui/qt/follow_stream_action.cpp b/ui/qt/follow_stream_action.cpp
index c9a946a1..0be2d561 100644
--- a/ui/qt/follow_stream_action.cpp
+++ b/ui/qt/follow_stream_action.cpp
@@ -9,7 +9,6 @@
#include <config.h>
-#include <glib.h>
#include <epan/packet_info.h>
#include <epan/proto_data.h>
#include <epan/packet.h>
diff --git a/ui/qt/follow_stream_action.h b/ui/qt/follow_stream_action.h
index 8c7c58e3..5357bae4 100644
--- a/ui/qt/follow_stream_action.h
+++ b/ui/qt/follow_stream_action.h
@@ -12,7 +12,6 @@
#include "config.h"
-#include <glib.h>
#include <epan/packet_info.h>
#include <epan/follow.h>
diff --git a/ui/qt/follow_stream_dialog.cpp b/ui/qt/follow_stream_dialog.cpp
index dbae1604..532d37f5 100644
--- a/ui/qt/follow_stream_dialog.cpp
+++ b/ui/qt/follow_stream_dialog.cpp
@@ -29,6 +29,7 @@
#include "wsutil/file_util.h"
#include "wsutil/str_util.h"
+#include "wsutil/filesystem.h"
#include "ws_symbol_export.h"
@@ -53,8 +54,6 @@
// - Instead of calling QMessageBox, display the error message in the text
// box and disable the appropriate controls.
// - Add a progress bar and connect captureCaptureUpdateContinue to it
-// - User's Guide documents the "Raw" type as "same as ASCII, but saving binary
-// data". However it currently displays hex-encoded data.
// Matches SplashOverlay.
static int info_update_freq_ = 100;
@@ -63,7 +62,7 @@ static int info_update_freq_ = 100;
static QMutex loop_break_mutex;
// Indicates that a Follow Stream is currently running
-static gboolean isReadRunning;
+static bool isReadRunning;
Q_DECLARE_METATYPE(bytes_show_type)
@@ -72,7 +71,6 @@ FollowStreamDialog::FollowStreamDialog(QWidget &parent, CaptureFile &cf, int pro
ui(new Ui::FollowStreamDialog),
b_find_(NULL),
follower_(NULL),
- truncated_(false),
client_buffer_count_(0),
server_buffer_count_(0),
client_packet_count_(0),
@@ -101,6 +99,8 @@ FollowStreamDialog::FollowStreamDialog(QWidget &parent, CaptureFile &cf, int pro
follow_info_.show_stream = BOTH_HOSTS;
follow_info_.substream_id = SUBSTREAM_UNUSED;
+ nstime_set_zero(&last_ts_);
+
ui->teStreamContent->installEventFilter(this);
connect(ui->leFind, SIGNAL(useRegexFind(bool)), this, SLOT(useRegexFind(bool)));
@@ -118,27 +118,46 @@ FollowStreamDialog::FollowStreamDialog(QWidget &parent, CaptureFile &cf, int pro
cbcs->setCurrentIndex(cbcs->findData(recent.gui_follow_show));
cbcs->blockSignals(false);
+ ui->deltaComboBox->setCurrentIndex(recent.gui_follow_delta);
+
b_filter_out_ = ui->buttonBox->addButton(tr("Filter Out This Stream"), QDialogButtonBox::ActionRole);
- connect(b_filter_out_, SIGNAL(clicked()), this, SLOT(filterOut()));
+ connect(b_filter_out_, &QPushButton::clicked, this, &FollowStreamDialog::filterOut);
b_print_ = ui->buttonBox->addButton(tr("Print"), QDialogButtonBox::ActionRole);
- connect(b_print_, SIGNAL(clicked()), this, SLOT(printStream()));
+ connect(b_print_, &QPushButton::clicked, this, &FollowStreamDialog::printStream);
b_save_ = ui->buttonBox->addButton(tr("Save as…"), QDialogButtonBox::ActionRole);
- connect(b_save_, SIGNAL(clicked()), this, SLOT(saveAs()));
+ connect(b_save_, &QPushButton::clicked, this, &FollowStreamDialog::saveAs);
b_back_ = ui->buttonBox->addButton(tr("Back"), QDialogButtonBox::ActionRole);
- connect(b_back_, SIGNAL(clicked()), this, SLOT(backButton()));
+ connect(b_back_, &QPushButton::clicked, this, &FollowStreamDialog::backButton);
ProgressFrame::addToButtonBox(ui->buttonBox, &parent);
- connect(ui->buttonBox, SIGNAL(helpRequested()), this, SLOT(helpButton()));
- connect(ui->teStreamContent, SIGNAL(mouseMovedToTextCursorPosition(int)),
- this, SLOT(fillHintLabel(int)));
- connect(ui->teStreamContent, SIGNAL(mouseClickedOnTextCursorPosition(int)),
- this, SLOT(goToPacketForTextPos(int)));
+ connect(ui->cbDirections, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
+ this, &FollowStreamDialog::cbDirectionsCurrentIndexChanged);
+ connect(ui->cbCharset, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
+ this, &FollowStreamDialog::cbCharsetCurrentIndexChanged);
+ connect(ui->deltaComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
+ this, &FollowStreamDialog::deltaComboBoxCurrentIndexChanged);
+
+ connect(ui->streamNumberSpinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
+ this, &FollowStreamDialog::streamNumberSpinBoxValueChanged);
+ connect(ui->subStreamNumberSpinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
+ this, &FollowStreamDialog::subStreamNumberSpinBoxValueChanged);
+
+ connect(ui->buttonBox, &QDialogButtonBox::helpRequested, this, &FollowStreamDialog::helpButton);
+ connect(ui->teStreamContent, &FollowStreamText::mouseMovedToPacket,
+ this, &FollowStreamDialog::fillHintLabel);
+ connect(ui->teStreamContent, &FollowStreamText::mouseClickedOnPacket,
+ this, &FollowStreamDialog::goToPacketForTextPos);
+
+ connect(ui->bFind, &QPushButton::clicked, this, &FollowStreamDialog::bFindClicked);
+ connect(ui->leFind, &FindLineEdit::returnPressed, this, &FollowStreamDialog::leFindReturnPressed);
+
+ connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &FollowStreamDialog::buttonBoxRejected);
- fillHintLabel(-1);
+ fillHintLabel();
}
FollowStreamDialog::~FollowStreamDialog()
@@ -169,29 +188,37 @@ void FollowStreamDialog::printStream()
#endif
}
-void FollowStreamDialog::fillHintLabel(int text_pos)
+void FollowStreamDialog::fillHintLabel(int pkt)
{
QString hint;
- int pkt = -1;
- if (text_pos >= 0) {
- QMap<int, guint32>::iterator it = text_pos_to_packet_.upperBound(text_pos);
- if (it != text_pos_to_packet_.end()) {
- pkt = it.value();
+ bool is_logray = strcmp(get_configuration_namespace(), "Logray") == 0;
+
+ if (is_logray) {
+ if (pkt > 0) {
+ hint = QString(tr("Event %1. ")).arg(pkt);
}
- }
- if (pkt > 0) {
- hint = QString(tr("Packet %1. ")).arg(pkt);
- }
+ hint += tr("%Ln <span style=\"color: %1; background-color:%2\">reads</span>, ", "", client_packet_count_)
+ .arg(ColorUtils::fromColorT(prefs.st_client_fg).name(),
+ ColorUtils::fromColorT(prefs.st_client_bg).name())
+ + tr("%Ln <span style=\"color: %1; background-color:%2\">writes</span>, ", "", server_packet_count_)
+ .arg(ColorUtils::fromColorT(prefs.st_server_fg).name(),
+ ColorUtils::fromColorT(prefs.st_server_bg).name())
+ + tr("%Ln turn(s).", "", turns_);
+ } else {
+ if (pkt > 0) {
+ hint = QString(tr("Packet %1. ")).arg(pkt);
+ }
- hint += tr("%Ln <span style=\"color: %1; background-color:%2\">client</span> pkt(s), ", "", client_packet_count_)
- .arg(ColorUtils::fromColorT(prefs.st_client_fg).name())
- .arg(ColorUtils::fromColorT(prefs.st_client_bg).name())
- + tr("%Ln <span style=\"color: %1; background-color:%2\">server</span> pkt(s), ", "", server_packet_count_)
- .arg(ColorUtils::fromColorT(prefs.st_server_fg).name())
- .arg(ColorUtils::fromColorT(prefs.st_server_bg).name())
- + tr("%Ln turn(s).", "", turns_);
+ hint += tr("%Ln <span style=\"color: %1; background-color:%2\">client</span> pkt(s), ", "", client_packet_count_)
+ .arg(ColorUtils::fromColorT(prefs.st_client_fg).name(),
+ ColorUtils::fromColorT(prefs.st_client_bg).name())
+ + tr("%Ln <span style=\"color: %1; background-color:%2\">server</span> pkt(s), ", "", server_packet_count_)
+ .arg(ColorUtils::fromColorT(prefs.st_server_fg).name(),
+ ColorUtils::fromColorT(prefs.st_server_bg).name())
+ + tr("%Ln turn(s).", "", turns_);
+ }
if (pkt > 0) {
hint.append(QString(tr(" Click to select.")));
@@ -202,20 +229,12 @@ void FollowStreamDialog::fillHintLabel(int text_pos)
ui->hintLabel->setText(hint);
}
-void FollowStreamDialog::goToPacketForTextPos(int text_pos)
+void FollowStreamDialog::goToPacketForTextPos(int pkt)
{
- int pkt = -1;
if (file_closed_) {
return;
}
- if (text_pos >= 0) {
- QMap<int, guint32>::iterator it = text_pos_to_packet_.upperBound(text_pos);
- if (it != text_pos_to_packet_.end()) {
- pkt = it.value();
- }
- }
-
if (pkt > 0) {
emit goToPacket(pkt);
}
@@ -255,20 +274,40 @@ void FollowStreamDialog::useRegexFind(bool use_regex)
ui->lFind->setText(tr("Find:"));
}
+// This only calls itself with go_back false, so never recurses more than once.
+// NOLINTNEXTLINE(misc-no-recursion)
void FollowStreamDialog::findText(bool go_back)
{
if (ui->leFind->text().isEmpty()) return;
bool found;
+
+ QTextDocument::FindFlags options;
+ if (ui->caseCheckBox->isChecked()) {
+ options |= QTextDocument::FindCaseSensitively;
+ }
if (use_regex_find_) {
#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
+ // https://bugreports.qt.io/browse/QTBUG-88721
+ // QPlainTextEdit::find() searches case-insensitively unless
+ // QTextDocument::FindCaseSensitively is explicitly given.
+ // This *does* apply to QRegularExpression (overriding
+ // CaseInsensitiveOption), but not QRegExp.
+ //
+ // QRegularExpression and QRegExp do not support Perl's /i, but
+ // the former at least does support the mode modifiers (?i) and
+ // (?-i), which can override QTextDocument::FindCaseSensitively.
+ //
+ // To make matters worse, while the QTextDocument::find() documentation
+ // is correct, QPlainTextEdit::find() claims that QRegularExpression
+ // works like QRegExp, which is incorrect.
QRegularExpression regex(ui->leFind->text(), QRegularExpression::UseUnicodePropertiesOption);
#else
- QRegExp regex(ui->leFind->text());
+ QRegExp regex(ui->leFind->text(), (options & QTextDocument::FindCaseSensitively) ? Qt::CaseSensitive : Qt::CaseInsensitive);
#endif
- found = ui->teStreamContent->find(regex);
+ found = ui->teStreamContent->find(regex, options);
} else {
- found = ui->teStreamContent->find(ui->leFind->text());
+ found = ui->teStreamContent->find(ui->leFind->text(), options);
}
if (found) {
@@ -288,15 +327,17 @@ void FollowStreamDialog::saveAs()
QFile file(file_name);
if (!file.open(QIODevice::WriteOnly)) {
- open_failure_alert_box(file_name.toUtf8().constData(), errno, TRUE);
+ open_failure_alert_box(file_name.toUtf8().constData(), errno, true);
return;
}
+ // XXX: What if truncated_ is true? We should save the entire stream.
// Unconditionally save data as UTF-8 (even if data is decoded otherwise).
QByteArray bytes = ui->teStreamContent->toPlainText().toUtf8();
if (recent.gui_follow_show == SHOW_RAW) {
// The "Raw" format is currently displayed as hex data and needs to be
- // converted to binary data.
+ // converted to binary data. fromHex() skips over non hex characters
+ // including line breaks, which is what we want.
bytes = QByteArray::fromHex(bytes);
}
@@ -337,12 +378,12 @@ void FollowStreamDialog::close()
// previous_filter if 'Close' (passed in follow() method)
// filter_out_filter_ if 'Filter Out This Stream' (built by appending !current_stream to previous_filter)
// leave filter alone if window closed. (current stream)
- emit updateFilter(output_filter_, TRUE);
+ emit updateFilter(output_filter_, true);
WiresharkDialog::close();
}
-void FollowStreamDialog::on_cbDirections_currentIndexChanged(int idx)
+void FollowStreamDialog::cbDirectionsCurrentIndexChanged(int idx)
{
switch(idx)
{
@@ -362,24 +403,43 @@ void FollowStreamDialog::on_cbDirections_currentIndexChanged(int idx)
readStream();
}
-void FollowStreamDialog::on_cbCharset_currentIndexChanged(int idx)
+void FollowStreamDialog::cbCharsetCurrentIndexChanged(int idx)
{
if (idx < 0) return;
recent.gui_follow_show = ui->cbCharset->currentData().value<bytes_show_type>();
+
+ switch (recent.gui_follow_show) {
+ case SHOW_EBCDIC:
+ case SHOW_ASCII:
+ case SHOW_CODEC:
+ ui->deltaComboBox->setEnabled(true);
+ break;
+ default:
+ ui->deltaComboBox->setEnabled(false);
+ }
+
+ readStream();
+}
+
+void FollowStreamDialog::deltaComboBoxCurrentIndexChanged(int idx)
+{
+ if (idx < 0) return;
+ recent.gui_follow_delta = static_cast<follow_delta_type>(ui->deltaComboBox->currentIndex());
+
readStream();
}
-void FollowStreamDialog::on_bFind_clicked()
+void FollowStreamDialog::bFindClicked()
{
findText();
}
-void FollowStreamDialog::on_leFind_returnPressed()
+void FollowStreamDialog::leFindReturnPressed()
{
findText();
}
-void FollowStreamDialog::on_streamNumberSpinBox_valueChanged(int stream_num)
+void FollowStreamDialog::streamNumberSpinBoxValueChanged(int stream_num)
{
if (file_closed_) return;
@@ -388,7 +448,7 @@ void FollowStreamDialog::on_streamNumberSpinBox_valueChanged(int stream_num)
sub_stream_num = ui->subStreamNumberSpinBox->value();
ui->subStreamNumberSpinBox->blockSignals(false);
- gboolean ok;
+ bool ok;
if (ui->subStreamNumberSpinBox->isVisible()) {
/* We need to find a suitable sub stream for the new stream */
follow_sub_stream_id_func sub_stream_func;
@@ -399,7 +459,7 @@ void FollowStreamDialog::on_streamNumberSpinBox_valueChanged(int stream_num)
return;
}
- guint sub_stream_num_new = static_cast<guint>(sub_stream_num);
+ unsigned sub_stream_num_new = static_cast<unsigned>(sub_stream_num);
if (sub_stream_num < 0) {
// Stream ID 0 should always exist as it is used for control messages.
// XXX: That is only guaranteed for HTTP2. For example, in QUIC,
@@ -411,14 +471,14 @@ void FollowStreamDialog::on_streamNumberSpinBox_valueChanged(int stream_num)
// follow? Right now the substream spinbox is left active and
// the user can change the value to no effect.
sub_stream_num_new = 0;
- ok = TRUE;
+ ok = true;
} else {
- ok = sub_stream_func(static_cast<guint>(stream_num), sub_stream_num_new, FALSE, &sub_stream_num_new);
+ ok = sub_stream_func(static_cast<unsigned>(stream_num), sub_stream_num_new, false, &sub_stream_num_new);
if (!ok) {
- ok = sub_stream_func(static_cast<guint>(stream_num), sub_stream_num_new, TRUE, &sub_stream_num_new);
+ ok = sub_stream_func(static_cast<unsigned>(stream_num), sub_stream_num_new, true, &sub_stream_num_new);
}
}
- sub_stream_num = static_cast<gint>(sub_stream_num_new);
+ sub_stream_num = static_cast<int>(sub_stream_num_new);
} else {
/* XXX: For HTTP and TLS, we use the TCP stream index, and really should
* return false if the TCP stream doesn't have HTTP or TLS. (Or we could
@@ -434,7 +494,7 @@ void FollowStreamDialog::on_streamNumberSpinBox_valueChanged(int stream_num)
}
-void FollowStreamDialog::on_subStreamNumberSpinBox_valueChanged(int sub_stream_num)
+void FollowStreamDialog::subStreamNumberSpinBoxValueChanged(int sub_stream_num)
{
if (file_closed_) return;
@@ -451,20 +511,20 @@ void FollowStreamDialog::on_subStreamNumberSpinBox_valueChanged(int sub_stream_n
return;
}
- guint sub_stream_num_new = static_cast<guint>(sub_stream_num);
- gboolean ok;
+ unsigned sub_stream_num_new = static_cast<unsigned>(sub_stream_num);
+ bool ok;
/* previous_sub_stream_num_ is a hack to track which buttons was pressed without event handling */
if (sub_stream_num < 0) {
// Stream ID 0 should always exist as it is used for control messages.
// XXX: That is only guaranteed for HTTP2, see above.
sub_stream_num_new = 0;
- ok = TRUE;
+ ok = true;
} else if (previous_sub_stream_num_ < sub_stream_num) {
- ok = sub_stream_func(static_cast<guint>(stream_num), sub_stream_num_new, FALSE, &sub_stream_num_new);
+ ok = sub_stream_func(static_cast<unsigned>(stream_num), sub_stream_num_new, false, &sub_stream_num_new);
} else {
- ok = sub_stream_func(static_cast<guint>(stream_num), sub_stream_num_new, TRUE, &sub_stream_num_new);
+ ok = sub_stream_func(static_cast<unsigned>(stream_num), sub_stream_num_new, true, &sub_stream_num_new);
}
- sub_stream_num = static_cast<gint>(sub_stream_num_new);
+ sub_stream_num = static_cast<int>(sub_stream_num_new);
if (ok) {
follow(previous_filter_, true, stream_num, sub_stream_num);
@@ -472,7 +532,7 @@ void FollowStreamDialog::on_subStreamNumberSpinBox_valueChanged(int sub_stream_n
}
}
-void FollowStreamDialog::on_buttonBox_rejected()
+void FollowStreamDialog::buttonBoxRejected()
{
// Ignore the close button if FollowStreamDialog::close() is running.
if (terminating_)
@@ -490,60 +550,34 @@ void FollowStreamDialog::removeStreamControls()
ui->subStreamNumberSpinBox->setVisible(false);
}
-void FollowStreamDialog::resetStream()
+void FollowStreamDialog::resetStream(void *tap_data)
{
- GList *cur;
- follow_record_t *follow_record;
-
- filter_out_filter_.clear();
- text_pos_to_packet_.clear();
- if (!data_out_filename_.isEmpty()) {
- ws_unlink(data_out_filename_.toUtf8().constData());
- }
- for (cur = follow_info_.payload; cur; cur = gxx_list_next(cur)) {
- follow_record = gxx_list_data(follow_record_t *, cur);
- if (follow_record->data) {
- g_byte_array_free(follow_record->data, TRUE);
- }
- g_free(follow_record);
- }
- g_list_free(follow_info_.payload);
-
- //Only TCP stream uses fragments
- for (cur = follow_info_.fragments[0]; cur; cur = gxx_list_next(cur)) {
- follow_record = gxx_list_data(follow_record_t *, cur);
- if (follow_record->data) {
- g_byte_array_free(follow_record->data, TRUE);
- }
- g_free(follow_record);
- }
- follow_info_.fragments[0] = Q_NULLPTR;
- for (cur = follow_info_.fragments[1]; cur; cur = gxx_list_next(cur)) {
- follow_record = gxx_list_data(follow_record_t *, cur);
- if (follow_record->data) {
- g_byte_array_free(follow_record->data, TRUE);
- }
- g_free(follow_record);
- }
- follow_info_.fragments[1] = Q_NULLPTR;
+ follow_info_t *follow_info = static_cast<follow_info_t*>(tap_data);
+ follow_reset_stream(follow_info);
+ // If we ever draw the text while tapping (instead of only after
+ // the tap finishes), reset the GUI here too.
+}
- free_address(&follow_info_.client_ip);
- free_address(&follow_info_.server_ip);
- follow_info_.payload = Q_NULLPTR;
- follow_info_.client_port = 0;
+void FollowStreamDialog::resetStream()
+{
+ FollowStreamDialog::resetStream(&follow_info_);
}
-frs_return_t
-FollowStreamDialog::readStream()
+void FollowStreamDialog::readStream()
{
// interrupt any reading already running
loop_break_mutex.lock();
- isReadRunning = FALSE;
+ isReadRunning = false;
loop_break_mutex.unlock();
+ double scroll_ratio = 0.0;
+ int doc_length = ui->teStreamContent->verticalScrollBar()->maximum() + ui->teStreamContent->verticalScrollBar()->pageStep();
+ if (doc_length > 0) {
+ scroll_ratio = static_cast<double>(ui->teStreamContent->verticalScrollBar()->value()) / doc_length;
+ }
+
ui->teStreamContent->clear();
- text_pos_to_packet_.clear();
switch (recent.gui_follow_show) {
case SHOW_CARRAY:
@@ -561,9 +595,6 @@ FollowStreamDialog::readStream()
ui->teStreamContent->setWordWrapMode(QTextOption::WrapAnywhere);
}
- truncated_ = false;
- frs_return_t ret;
-
client_buffer_count_ = 0;
server_buffer_count_ = 0;
client_packet_count_ = 0;
@@ -571,16 +602,16 @@ FollowStreamDialog::readStream()
last_packet_ = 0;
turns_ = 0;
- if (follower_) {
- ret = readFollowStream();
- } else {
- ret = (frs_return_t)0;
+ if (!follower_) {
ws_assert_not_reached();
}
+ readFollowStream();
+
ui->teStreamContent->moveCursor(QTextCursor::Start);
- return ret;
+ doc_length = ui->teStreamContent->verticalScrollBar()->maximum() + ui->teStreamContent->verticalScrollBar()->pageStep();
+ ui->teStreamContent->verticalScrollBar()->setValue(doc_length * scroll_ratio);
}
void
@@ -589,49 +620,9 @@ FollowStreamDialog::followStream()
readStream();
}
-const int FollowStreamDialog::max_document_length_ = 500 * 1000 * 1000; // Just a guess
-void FollowStreamDialog::addText(QString text, gboolean is_from_server, guint32 packet_num, gboolean colorize)
+void FollowStreamDialog::addText(QString text, bool is_from_server, uint32_t packet_num, bool colorize)
{
- if (truncated_) {
- return;
- }
-
- int char_count = ui->teStreamContent->document()->characterCount();
- if (char_count + text.length() > max_document_length_) {
- text.truncate(max_document_length_ - char_count);
- truncated_ = true;
- }
-
- setUpdatesEnabled(false);
- int cur_pos = ui->teStreamContent->verticalScrollBar()->value();
- ui->teStreamContent->moveCursor(QTextCursor::End);
-
- QTextCharFormat tcf = ui->teStreamContent->currentCharFormat();
- if (!colorize) {
- tcf.setBackground(palette().window().color());
- tcf.setForeground(palette().windowText().color());
- } else if (is_from_server) {
- tcf.setForeground(ColorUtils::fromColorT(prefs.st_server_fg));
- tcf.setBackground(ColorUtils::fromColorT(prefs.st_server_bg));
- } else {
- tcf.setForeground(ColorUtils::fromColorT(prefs.st_client_fg));
- tcf.setBackground(ColorUtils::fromColorT(prefs.st_client_bg));
- }
- ui->teStreamContent->setCurrentCharFormat(tcf);
-
- ui->teStreamContent->insertPlainText(text);
- text_pos_to_packet_[ui->teStreamContent->textCursor().anchor()] = packet_num;
-
- if (truncated_) {
- tcf = ui->teStreamContent->currentCharFormat();
- tcf.setBackground(palette().window().color());
- tcf.setForeground(palette().windowText().color());
- ui->teStreamContent->insertPlainText("\n" + tr("[Stream output truncated]"));
- ui->teStreamContent->moveCursor(QTextCursor::End);
- } else {
- ui->teStreamContent->verticalScrollBar()->setValue(cur_pos);
- }
- setUpdatesEnabled(true);
+ ui->teStreamContent->addText(std::move(text), is_from_server, packet_num, colorize);
}
// The following keyboard shortcuts should work (although
@@ -682,33 +673,64 @@ void FollowStreamDialog::keyPressEvent(QKeyEvent *event)
QDialog::keyPressEvent(event);
}
-static inline void sanitize_buffer(char *buffer, size_t nchars) {
- for (size_t i = 0; i < nchars; i++) {
- if (buffer[i] == '\n' || buffer[i] == '\r' || buffer[i] == '\t')
+// Replaces non printable ASCII characters in the QByteArray with .
+// Causes buffer to detach/deep copy *only* if a character has to be
+// replaced.
+static inline void sanitize_buffer(QByteArray &buffer, size_t nchars) {
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ for (int i = 0; i < (int)nchars; i++) {
+#else
+ for (qsizetype i = 0; i < (qsizetype)nchars; i++) {
+#endif
+ if (buffer.at(i) == '\n' || buffer.at(i) == '\r' || buffer.at(i) == '\t')
continue;
- if (! g_ascii_isprint((guchar)buffer[i])) {
+ if (! g_ascii_isprint((unsigned char)buffer.at(i))) {
buffer[i] = '.';
}
}
}
-frs_return_t
-FollowStreamDialog::showBuffer(char *buffer, size_t nchars, gboolean is_from_server, guint32 packet_num,
- nstime_t abs_ts, guint32 *global_pos)
+void FollowStreamDialog::showBuffer(QByteArray &buffer, size_t nchars, bool is_from_server, uint32_t packet_num,
+ nstime_t abs_ts, uint32_t *global_pos)
{
- gchar initbuf[256];
- guint32 current_pos;
- static const gchar hexchars[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
+ char initbuf[256];
+ uint32_t current_pos;
+ static const char hexchars[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
+ bool show_delta = false;
+
+ if (last_packet_ == 0) {
+ last_from_server_ = is_from_server;
+ } else {
+ if (recent.gui_follow_delta == FOLLOW_DELTA_ALL ||
+ (recent.gui_follow_delta == FOLLOW_DELTA_TURN && last_from_server_ != is_from_server)) {
+ show_delta = true;
+ }
+ }
+
+ double delta = 0.0;
+ if (!nstime_is_zero(&abs_ts)) {
+ // packet-tcp.c and possibly other dissectors can return a zero abs_ts when
+ // a fragment is missing.
+ nstime_t delta_ts;
+ nstime_delta(&delta_ts, &abs_ts, &last_ts_);
+ delta = nstime_to_sec(&delta_ts);
+ last_ts_ = abs_ts;
+ }
switch (recent.gui_follow_show) {
case SHOW_EBCDIC:
{
/* If our native arch is ASCII, call: */
- EBCDIC_to_ASCII((guint8*)buffer, (guint) nchars);
+ EBCDIC_to_ASCII((uint8_t*)buffer.data(), (unsigned) nchars);
+ if (show_delta) {
+ ui->teStreamContent->addDeltaTime(delta);
+ }
+ if (show_delta || last_from_server_ != is_from_server) {
+ addText("\n", is_from_server, packet_num);
+ }
sanitize_buffer(buffer, nchars);
- QByteArray ba = QByteArray(buffer, (int)nchars);
- addText(ba, is_from_server, packet_num);
+ addText(buffer, is_from_server, packet_num);
break;
}
@@ -717,32 +739,41 @@ FollowStreamDialog::showBuffer(char *buffer, size_t nchars, gboolean is_from_ser
/* If our native arch is EBCDIC, call:
* ASCII_TO_EBCDIC(buffer, nchars);
*/
+ if (show_delta) {
+ ui->teStreamContent->addDeltaTime(delta);
+ }
+ if (show_delta || last_from_server_ != is_from_server) {
+ addText("\n", is_from_server, packet_num);
+ }
sanitize_buffer(buffer, nchars);
- QByteArray ba = QByteArray(buffer, (int)nchars);
- addText(ba, is_from_server, packet_num);
+ addText(buffer, is_from_server, packet_num);
break;
}
case SHOW_CODEC:
{
+ if (show_delta) {
+ ui->teStreamContent->addDeltaTime(delta);
+ }
+ if (show_delta || last_from_server_ != is_from_server) {
+ addText("\n", is_from_server, packet_num);
+ }
// This assumes that multibyte characters don't span packets in the
// stream. To handle that case properly (which might occur with fixed
// block sizes, e.g. transferring over TFTP, we would need to create
// two stateful QTextDecoders, one for each direction, presumably in
// on_cbCharset_currentIndexChanged()
QTextCodec *codec = QTextCodec::codecForName(ui->cbCharset->currentText().toUtf8());
- QByteArray ba = QByteArray(buffer, (int)nchars);
- QString decoded = codec->toUnicode(ba);
- addText(decoded, is_from_server, packet_num);
+ addText(codec->toUnicode(buffer), is_from_server, packet_num);
break;
}
case SHOW_HEXDUMP:
current_pos = 0;
while (current_pos < nchars) {
- gchar hexbuf[256];
+ char hexbuf[256];
int i;
- gchar *cur = hexbuf, *ascii_start;
+ char *cur = hexbuf, *ascii_start;
/* is_from_server indentation : put 4 spaces at the
* beginning of the string */
@@ -756,9 +787,9 @@ FollowStreamDialog::showBuffer(char *buffer, size_t nchars, gboolean is_from_ser
ascii_start = cur + 49 + 2;
for (i = 0; i < 16 && current_pos + i < nchars; i++) {
*cur++ =
- hexchars[(buffer[current_pos + i] & 0xf0) >> 4];
+ hexchars[(buffer.at(current_pos + i) & 0xf0) >> 4];
*cur++ =
- hexchars[buffer[current_pos + i] & 0x0f];
+ hexchars[buffer.at(current_pos + i) & 0x0f];
*cur++ = ' ';
if (i == 7)
*cur++ = ' ';
@@ -770,8 +801,8 @@ FollowStreamDialog::showBuffer(char *buffer, size_t nchars, gboolean is_from_ser
/* Now dump bytes as text */
for (i = 0; i < 16 && current_pos + i < nchars; i++) {
*cur++ =
- (g_ascii_isprint((guchar)buffer[current_pos + i]) ?
- buffer[current_pos + i] : '.');
+ (g_ascii_isprint((unsigned char)buffer.at(current_pos + i)) ?
+ buffer.at(current_pos + i) : '.');
if (i == 7) {
*cur++ = ' ';
}
@@ -794,7 +825,7 @@ FollowStreamDialog::showBuffer(char *buffer, size_t nchars, gboolean is_from_ser
addText(initbuf, is_from_server, packet_num);
while (current_pos < nchars) {
- gchar hexbuf[256];
+ char hexbuf[256];
int i, cur;
cur = 0;
@@ -803,9 +834,9 @@ FollowStreamDialog::showBuffer(char *buffer, size_t nchars, gboolean is_from_ser
hexbuf[cur++] = '0';
hexbuf[cur++] = 'x';
hexbuf[cur++] =
- hexchars[(buffer[current_pos + i] & 0xf0) >> 4];
+ hexchars[(buffer.at(current_pos + i) & 0xf0) >> 4];
hexbuf[cur++] =
- hexchars[buffer[current_pos + i] & 0x0f];
+ hexchars[buffer.at(current_pos + i) & 0x0f];
/* Delimit array entries with a comma */
if (current_pos + i + 1 < nchars)
@@ -849,15 +880,13 @@ FollowStreamDialog::showBuffer(char *buffer, size_t nchars, gboolean is_from_ser
" - peer: 0\n"
" host: %1\n"
" port: %2\n")
- .arg(hostname0)
- .arg(port0), false, 0);
+ .arg(hostname0, port0), false, 0);
addText(QString(
" - peer: 1\n"
" host: %1\n"
" port: %2\n")
- .arg(hostname1)
- .arg(port1), true, 0);
+ .arg(hostname1, port1), true, 0);
wmem_free(NULL, port0);
wmem_free(NULL, port1);
@@ -879,7 +908,7 @@ FollowStreamDialog::showBuffer(char *buffer, size_t nchars, gboolean is_from_ser
}
while (current_pos < nchars) {
int len = current_pos + base64_raw_len < nchars ? base64_raw_len : (int) nchars - current_pos;
- QByteArray base64_data(&buffer[current_pos], len);
+ QByteArray base64_data(&buffer.constData()[current_pos], len);
/* XXX: GCC 12.1 has a bogus stringop-overread warning using the Qt
* conversions from QByteArray to QString at -O2 and higher due to
@@ -896,15 +925,13 @@ DIAG_ON(stringop-overread)
current_pos += len;
(*global_pos) += len;
}
- addText(yaml_text, is_from_server, packet_num);
+ addText(std::move(yaml_text), is_from_server, packet_num);
break;
}
case SHOW_RAW:
{
- QByteArray ba = QByteArray(buffer, (int)nchars).toHex();
- ba += '\n';
- addText(ba, is_from_server, packet_num);
+ addText(buffer.toHex() + '\n', is_from_server, packet_num);
break;
}
@@ -915,10 +942,6 @@ DIAG_ON(stringop-overread)
ws_assert_not_reached();
}
- if (last_packet_ == 0) {
- last_from_server_ = is_from_server;
- }
-
if (packet_num != last_packet_) {
last_packet_ = packet_num;
if (is_from_server) {
@@ -931,11 +954,9 @@ DIAG_ON(stringop-overread)
turns_++;
}
}
-
- return FRS_OK;
}
-bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index, guint stream_num, guint sub_stream_num)
+bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index, unsigned stream_num, unsigned sub_stream_num)
{
QString follow_filter;
const char *hostname0 = NULL, *hostname1 = NULL;
@@ -943,12 +964,10 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index,
QString server_to_client_string;
QString client_to_server_string;
QString both_directions_string;
- gboolean is_follower = FALSE;
+ bool is_follower = false;
int stream_count;
follow_stream_count_func stream_count_func = NULL;
- resetStream();
-
if (file_closed_)
{
QMessageBox::warning(this, tr("No capture file."), tr("Please make sure you have a capture file opened."));
@@ -969,8 +988,6 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index,
}
}
- follow_reset_stream(&follow_info_);
-
/* Create a new filter that matches all packets in the TCP stream,
and set the display filter entry accordingly */
if (use_stream_index) {
@@ -993,7 +1010,7 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index,
/* append the negation */
if (!previous_filter.isEmpty()) {
filter_out_filter_ = QString("%1 and !(%2)")
- .arg(previous_filter).arg(follow_filter);
+ .arg(previous_filter, follow_filter);
}
else
{
@@ -1005,7 +1022,8 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index,
/* data will be passed via tap callback*/
if (!registerTapListener(get_follow_tap_string(follower_), &follow_info_,
follow_filter.toUtf8().constData(),
- 0, NULL, get_follow_tap_handler(follower_), NULL)) {
+ 0, FollowStreamDialog::resetStream,
+ get_follow_tap_handler(follower_), NULL)) {
return false;
}
@@ -1026,9 +1044,9 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index,
follow_sub_stream_id_func sub_stream_func;
sub_stream_func = get_follow_sub_stream_id_func(follower_);
if (sub_stream_func != NULL) {
- guint substream_max_id = 0;
- sub_stream_func(static_cast<guint>(stream_num), G_MAXINT32, TRUE, &substream_max_id);
- stream_count = static_cast<gint>(substream_max_id);
+ unsigned substream_max_id = 0;
+ sub_stream_func(static_cast<unsigned>(stream_num), INT32_MAX, true, &substream_max_id);
+ stream_count = static_cast<int>(substream_max_id);
ui->subStreamNumberSpinBox->blockSignals(true);
ui->subStreamNumberSpinBox->setEnabled(true);
ui->subStreamNumberSpinBox->setMaximum(stream_count);
@@ -1054,43 +1072,83 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index,
/* Run the display filter so it goes in effect - even if it's the
same as the previous display filter. */
- emit updateFilter(follow_filter, TRUE);
+ /* XXX: This forces a cf_filter_packets() - but if a rescan (or something else
+ * that sets cf->read_lock) is in progress, this will queue the filter
+ * and return immediately. It will also cause a rescan in progress to
+ * stop and restart with the new filter. That also applies to this rescan;
+ * changing the main display filter (from the main window, or from, e.g.
+ * another FollowStreamDialog) will cause this to restart and reset the
+ * tap.
+ *
+ * Other tapping dialogs call cf_retap_packets (which retaps but doesn't
+ * set the main display filter, freeze the packet list, etc.), which
+ * has somewhat different behavior when another dialog tries to retap,
+ * but also results in the taps being reset mid tap.
+ *
+ * Either way, we should be event driven and listening for CaptureEvents
+ * instead of drawing after this returns. (Or like other taps, draw
+ * periodically in a callback, provided that can be done without causing
+ * issues with changing the Decode As type.)
+ */
+ emit updateFilter(follow_filter, true);
removeTapListeners();
- hostname0 = address_to_name(&follow_info_.client_ip);
- hostname1 = address_to_name(&follow_info_.server_ip);
-
- port0 = get_follow_port_to_display(follower_)(NULL, follow_info_.client_port);
- port1 = get_follow_port_to_display(follower_)(NULL, follow_info_.server_port);
-
- server_to_client_string =
- QString("%1:%2 %3 %4:%5 (%6)")
- .arg(hostname0).arg(port0)
- .arg(UTF8_RIGHTWARDS_ARROW)
- .arg(hostname1).arg(port1)
- .arg(gchar_free_to_qstring(format_size(
- follow_info_.bytes_written[0],
- FORMAT_SIZE_UNIT_BYTES, FORMAT_SIZE_PREFIX_SI)));
-
- client_to_server_string =
- QString("%1:%2 %3 %4:%5 (%6)")
- .arg(hostname1).arg(port1)
- .arg(UTF8_RIGHTWARDS_ARROW)
- .arg(hostname0).arg(port0)
- .arg(gchar_free_to_qstring(format_size(
- follow_info_.bytes_written[1],
- FORMAT_SIZE_UNIT_BYTES, FORMAT_SIZE_PREFIX_SI)));
-
- wmem_free(NULL, port0);
- wmem_free(NULL, port1);
-
- both_directions_string = tr("Entire conversation (%1)")
- .arg(gchar_free_to_qstring(format_size(
- follow_info_.bytes_written[0] + follow_info_.bytes_written[1],
- FORMAT_SIZE_UNIT_BYTES, FORMAT_SIZE_PREFIX_SI)));
- setWindowSubtitle(tr("Follow %1 Stream (%2)").arg(proto_get_protocol_short_name(find_protocol_by_id(get_follow_proto_id(follower_))))
- .arg(follow_filter));
+ bool is_logray = strcmp(get_configuration_namespace(), "Logray") == 0;
+
+ if (is_logray) {
+ server_to_client_string =
+ tr("Read activity(%6)")
+ .arg(gchar_free_to_qstring(format_size(
+ follow_info_.bytes_written[0],
+ FORMAT_SIZE_UNIT_BYTES, FORMAT_SIZE_PREFIX_SI)));
+
+ client_to_server_string =
+ tr("Write activity(%6)")
+ .arg(gchar_free_to_qstring(format_size(
+ follow_info_.bytes_written[1],
+ FORMAT_SIZE_UNIT_BYTES, FORMAT_SIZE_PREFIX_SI)));
+
+ both_directions_string = tr("Entire I/O activity (%1)")
+ .arg(gchar_free_to_qstring(format_size(
+ follow_info_.bytes_written[0] + follow_info_.bytes_written[1],
+ FORMAT_SIZE_UNIT_BYTES, FORMAT_SIZE_PREFIX_SI)));
+ } else {
+ hostname0 = address_to_name(&follow_info_.client_ip);
+ hostname1 = address_to_name(&follow_info_.server_ip);
+
+ port0 = get_follow_port_to_display(follower_)(NULL, follow_info_.client_port);
+ port1 = get_follow_port_to_display(follower_)(NULL, follow_info_.server_port);
+
+ server_to_client_string =
+ QString("%1:%2 %3 %4:%5 (%6)")
+ .arg(hostname0, port0)
+ .arg(UTF8_RIGHTWARDS_ARROW)
+ .arg(hostname1, port1)
+ .arg(gchar_free_to_qstring(format_size(
+ follow_info_.bytes_written[0],
+ FORMAT_SIZE_UNIT_BYTES, FORMAT_SIZE_PREFIX_SI)));
+
+ client_to_server_string =
+ QString("%1:%2 %3 %4:%5 (%6)")
+ .arg(hostname1, port1)
+ .arg(UTF8_RIGHTWARDS_ARROW)
+ .arg(hostname0, port0)
+ .arg(gchar_free_to_qstring(format_size(
+ follow_info_.bytes_written[1],
+ FORMAT_SIZE_UNIT_BYTES, FORMAT_SIZE_PREFIX_SI)));
+
+ wmem_free(NULL, port0);
+ wmem_free(NULL, port1);
+
+ both_directions_string = tr("Entire conversation (%1)")
+ .arg(gchar_free_to_qstring(format_size(
+ follow_info_.bytes_written[0] + follow_info_.bytes_written[1],
+ FORMAT_SIZE_UNIT_BYTES, FORMAT_SIZE_PREFIX_SI)));
+ }
+
+ setWindowSubtitle(tr("Follow %1 Stream (%2)").arg(proto_get_protocol_short_name(find_protocol_by_id(get_follow_proto_id(follower_))),
+ follow_filter));
ui->cbDirections->blockSignals(true);
ui->cbDirections->clear();
@@ -1100,13 +1158,13 @@ bool FollowStreamDialog::follow(QString previous_filter, bool use_stream_index,
ui->cbDirections->blockSignals(false);
followStream();
- fillHintLabel(-1);
+ fillHintLabel();
updateWidgets(false);
endRetapPackets();
if (prefs.restore_filter_after_following_stream) {
- emit updateFilter(previous_filter_, TRUE);
+ emit updateFilter(previous_filter_, true);
}
return true;
@@ -1120,74 +1178,53 @@ void FollowStreamDialog::captureFileClosed()
WiresharkDialog::captureFileClosed();
}
-/*
- * XXX - the routine pointed to by "print_line_fcn_p" doesn't get handed lines,
- * it gets handed bufferfuls. That's fine for "follow_write_raw()"
- * and "follow_add_to_gtk_text()", but, as "follow_print_text()" calls
- * the "print_line()" routine from "print.c", and as that routine might
- * genuinely expect to be handed a line (if, for example, it's using
- * some OS or desktop environment's printing API, and that API expects
- * to be handed lines), "follow_print_text()" should probably accumulate
- * lines in a buffer and hand them "print_line()". (If there's a
- * complete line in a buffer - i.e., there's nothing of the line in
- * the previous buffer or the next buffer - it can just hand that to
- * "print_line()" after filtering out non-printables, as an
- * optimization.)
- *
- * This might or might not be the reason why C arrays display
- * correctly but get extra blank lines very other line when printed.
- */
-frs_return_t
-FollowStreamDialog::readFollowStream()
+void FollowStreamDialog::readFollowStream()
{
- guint32 global_client_pos = 0, global_server_pos = 0;
- guint32 *global_pos;
- gboolean skip;
+ uint32_t global_client_pos = 0, global_server_pos = 0;
+ uint32_t *global_pos;
+ bool skip;
GList* cur;
- frs_return_t frs_return;
follow_record_t *follow_record;
QElapsedTimer elapsed_timer;
+ QByteArray buffer;
elapsed_timer.start();
loop_break_mutex.lock();
- isReadRunning = TRUE;
+ isReadRunning = true;
loop_break_mutex.unlock();
for (cur = g_list_last(follow_info_.payload); cur; cur = g_list_previous(cur)) {
if (dialogClosed() || !isReadRunning) break;
follow_record = (follow_record_t *)cur->data;
- skip = FALSE;
+ skip = false;
if (!follow_record->is_server) {
global_pos = &global_client_pos;
if (follow_info_.show_stream == FROM_SERVER) {
- skip = TRUE;
+ skip = true;
}
} else {
global_pos = &global_server_pos;
if (follow_info_.show_stream == FROM_CLIENT) {
- skip = TRUE;
+ skip = true;
}
}
- QByteArray buffer;
if (!skip) {
- // We want a deep copy.
- buffer.clear();
- buffer.append((const char *) follow_record->data->data,
- follow_record->data->len);
- frs_return = showBuffer(
- buffer.data(),
- follow_record->data->len,
- follow_record->is_server,
- follow_record->packet_num,
- follow_record->abs_ts,
- global_pos);
- if (frs_return == FRS_PRINT_ERROR)
- return frs_return;
+ // This will only detach / deep copy if the buffer data is
+ // modified. Try to avoid doing that as much as possible
+ // (and avoid new memory allocations that have to be freed).
+ buffer.setRawData((char*)follow_record->data->data, follow_record->data->len);
+ showBuffer(
+ buffer,
+ follow_record->data->len,
+ follow_record->is_server,
+ follow_record->packet_num,
+ follow_record->abs_ts,
+ global_pos);
if (elapsed_timer.elapsed() > info_update_freq_) {
- fillHintLabel(ui->teStreamContent->textCursor().position());
+ fillHintLabel(ui->teStreamContent->currentPacket());
mainApp->processEvents();
elapsed_timer.start();
}
@@ -1195,8 +1232,7 @@ FollowStreamDialog::readFollowStream()
}
loop_break_mutex.lock();
- isReadRunning = FALSE;
+ isReadRunning = false;
loop_break_mutex.unlock();
-
- return FRS_OK;
}
+
diff --git a/ui/qt/follow_stream_dialog.h b/ui/qt/follow_stream_dialog.h
index e56023de..859c0534 100644
--- a/ui/qt/follow_stream_dialog.h
+++ b/ui/qt/follow_stream_dialog.h
@@ -12,8 +12,6 @@
#include <config.h>
-#include <glib.h>
-
#include <stdio.h>
#ifdef HAVE_UNISTD_H
@@ -44,7 +42,7 @@ public:
~FollowStreamDialog();
void addCodecs(const QMap<QString, QTextCodec *> &codecMap);
- bool follow(QString previous_filter = QString(), bool use_stream_index = false, guint stream_num = 0, guint sub_stream_num = 0);
+ bool follow(QString previous_filter = QString(), bool use_stream_index = false, unsigned stream_num = 0, unsigned sub_stream_num = 0);
protected:
bool eventFilter(QObject *obj, QEvent *event);
@@ -52,10 +50,11 @@ protected:
void captureFileClosed();
private slots:
- void on_cbCharset_currentIndexChanged(int idx);
- void on_cbDirections_currentIndexChanged(int idx);
- void on_bFind_clicked();
- void on_leFind_returnPressed();
+ void cbCharsetCurrentIndexChanged(int idx);
+ void deltaComboBoxCurrentIndexChanged(int idx);
+ void cbDirectionsCurrentIndexChanged(int idx);
+ void bFindClicked();
+ void leFindReturnPressed();
void helpButton();
void backButton();
@@ -65,33 +64,33 @@ private slots:
void findText(bool go_back = true);
void saveAs();
void printStream();
- void fillHintLabel(int text_pos);
- void goToPacketForTextPos(int text_pos);
+ void fillHintLabel(int pkt = 0);
+ void goToPacketForTextPos(int pkt = 0);
- void on_streamNumberSpinBox_valueChanged(int stream_num);
- void on_subStreamNumberSpinBox_valueChanged(int sub_stream_num);
+ void streamNumberSpinBoxValueChanged(int stream_num);
+ void subStreamNumberSpinBoxValueChanged(int sub_stream_num);
- void on_buttonBox_rejected();
+ void buttonBoxRejected();
signals:
void updateFilter(QString filter, bool force);
void goToPacket(int packet_num);
private:
+ // Callback for register_tap_listener
+ static void resetStream(void *tapData);
+
void removeStreamControls();
void resetStream(void);
void updateWidgets(bool follow_in_progress);
void updateWidgets() { updateWidgets(false); } // Needed for WiresharkDialog?
- frs_return_t
- showBuffer(char *buffer, size_t nchars, gboolean is_from_server,
- guint32 packet_num, nstime_t abs_ts, guint32 *global_pos);
-
- frs_return_t readStream();
- frs_return_t readFollowStream();
- frs_return_t readSslStream();
+ void showBuffer(QByteArray &buffer, size_t nchars, bool is_from_server,
+ uint32_t packet_num, nstime_t abs_ts, uint32_t *global_pos);
+ void readStream();
+ void readFollowStream();
void followStream();
- void addText(QString text, gboolean is_from_server, guint32 packet_num, gboolean colorize = true);
+ void addText(QString text, bool is_from_server, uint32_t packet_num, bool colorize = true);
Ui::FollowStreamDialog *ui;
@@ -103,9 +102,6 @@ private:
follow_info_t follow_info_;
register_follow_t* follower_;
- QString data_out_filename_;
- static const int max_document_length_;
- bool truncated_;
QString previous_filter_;
QString filter_out_filter_;
QString output_filter_;
@@ -113,10 +109,10 @@ private:
int server_buffer_count_;
int client_packet_count_;
int server_packet_count_;
- guint32 last_packet_;
- gboolean last_from_server_;
+ uint32_t last_packet_;
+ bool last_from_server_;
+ nstime_t last_ts_;
int turns_;
- QMap<int,guint32> text_pos_to_packet_;
bool use_regex_find_;
diff --git a/ui/qt/follow_stream_dialog.ui b/ui/qt/follow_stream_dialog.ui
index 3b4a76a4..dc77586e 100644
--- a/ui/qt/follow_stream_dialog.ui
+++ b/ui/qt/follow_stream_dialog.ui
@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
- <width>609</width>
+ <width>750</width>
<height>600</height>
</rect>
</property>
@@ -41,7 +41,7 @@
</widget>
</item>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0,0,1,0,0,0,0">
+ <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0,0,0,0,1,0,0,0,0">
<item>
<widget class="QComboBox" name="cbDirections">
<property name="sizeAdjustPolicy">
@@ -50,7 +50,7 @@
</widget>
</item>
<item>
- <spacer name="horizontalSpacer">
+ <spacer name="charsetSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@@ -65,7 +65,7 @@
<item>
<widget class="QLabel" name="label">
<property name="text">
- <string>Show data as</string>
+ <string>Show as</string>
</property>
</widget>
</item>
@@ -77,6 +77,38 @@
</widget>
</item>
<item>
+ <spacer name="deltaSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QComboBox" name="deltaComboBox">
+ <item>
+ <property name="text">
+ <string>No delta times</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Turn delta times</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>All delta times</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
<spacer name="streamNumberSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@@ -124,6 +156,13 @@
<widget class="FindLineEdit" name="leFind"/>
</item>
<item>
+ <widget class="QCheckBox" name="caseCheckBox">
+ <property name="text">
+ <string>Case sensitive</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QPushButton" name="bFind">
<property name="text">
<string>Find &amp;Next</string>
diff --git a/ui/qt/font_color_preferences_frame.cpp b/ui/qt/font_color_preferences_frame.cpp
index 0a09e0f4..ceb94c31 100644
--- a/ui/qt/font_color_preferences_frame.cpp
+++ b/ui/qt/font_color_preferences_frame.cpp
@@ -15,6 +15,7 @@
#include <ui_font_color_preferences_frame.h>
#include <ui/qt/utils/color_utils.h>
#include "main_application.h"
+#include "wsutil/array.h"
#include <functional>
#include <QFontDialog>
@@ -28,7 +29,7 @@ static const char *font_pangrams_[] = {
QT_TRANSLATE_NOOP("FontColorPreferencesFrame", "Example GIF query packets have jumbo window sizes"),
QT_TRANSLATE_NOOP("FontColorPreferencesFrame", "Lazy badgers move unique waxy jellyfish packets")
};
-const int num_font_pangrams_ = (sizeof font_pangrams_ / sizeof font_pangrams_[0]);
+const int num_font_pangrams_ = array_length(font_pangrams_);
FontColorPreferencesFrame::FontColorPreferencesFrame(QWidget *parent) :
QFrame(parent),
@@ -78,7 +79,7 @@ void FontColorPreferencesFrame::showEvent(QShowEvent *)
void FontColorPreferencesFrame::updateWidgets()
{
- gint colorstyle;
+ int colorstyle;
QColor foreground;
QColor background1;
QColor background2;
diff --git a/ui/qt/funnel_statistics.cpp b/ui/qt/funnel_statistics.cpp
index f5ed6745..943c354b 100644
--- a/ui/qt/funnel_statistics.cpp
+++ b/ui/qt/funnel_statistics.cpp
@@ -9,8 +9,6 @@
#include "config.h"
-#include <glib.h>
-
#include "epan/color_filters.h"
#include "file.h"
@@ -43,23 +41,23 @@
extern "C" {
static struct _funnel_text_window_t* text_window_new(funnel_ops_id_t *ops_id, const char* title);
-static void string_dialog_new(funnel_ops_id_t *ops_id, const gchar* title, const gchar** field_names, const gchar** field_values, funnel_dlg_cb_t dialog_cb, void* dialog_cb_data, funnel_dlg_cb_data_free_t dialog_cb_data_free);
+static void string_dialog_new(funnel_ops_id_t *ops_id, const char* title, const char** field_names, const char** field_values, funnel_dlg_cb_t dialog_cb, void* dialog_cb_data, funnel_dlg_cb_data_free_t dialog_cb_data_free);
static void funnel_statistics_retap_packets(funnel_ops_id_t *ops_id);
static void funnel_statistics_copy_to_clipboard(GString *text);
-static const gchar *funnel_statistics_get_filter(funnel_ops_id_t *ops_id);
+static const char *funnel_statistics_get_filter(funnel_ops_id_t *ops_id);
static void funnel_statistics_set_filter(funnel_ops_id_t *ops_id, const char* filter_string);
-static gchar* funnel_statistics_get_color_filter_slot(guint8 filter_num);
-static void funnel_statistics_set_color_filter_slot(guint8 filter_num, const gchar* filter_string);
-static gboolean funnel_statistics_open_file(funnel_ops_id_t *ops_id, const char* fname, const char* filter, char**);
+static char* funnel_statistics_get_color_filter_slot(uint8_t filter_num);
+static void funnel_statistics_set_color_filter_slot(uint8_t filter_num, const char* filter_string);
+static bool funnel_statistics_open_file(funnel_ops_id_t *ops_id, const char* fname, const char* filter, char**);
static void funnel_statistics_reload_packets(funnel_ops_id_t *ops_id);
static void funnel_statistics_redissect_packets(funnel_ops_id_t *ops_id);
static void funnel_statistics_reload_lua_plugins(funnel_ops_id_t *ops_id);
static void funnel_statistics_apply_filter(funnel_ops_id_t *ops_id);
-static gboolean browser_open_url(const gchar *url);
-static void browser_open_data_file(const gchar *filename);
-static struct progdlg *progress_window_new(funnel_ops_id_t *ops_id, const gchar* title, const gchar* task, gboolean terminate_is_stop, gboolean *stop_flag);
-static void progress_window_update(struct progdlg *progress_dialog, float percentage, const gchar* status);
+static bool browser_open_url(const char *url);
+static void browser_open_data_file(const char *filename);
+static struct progdlg *progress_window_new(funnel_ops_id_t *ops_id, const char* title, const char* task, bool terminate_is_stop, bool *stop_flag);
+static void progress_window_update(struct progdlg *progress_dialog, float percentage, const char* status);
static void progress_window_destroy(struct progdlg *progress_dialog);
}
@@ -67,14 +65,14 @@ FunnelAction::FunnelAction(QObject *parent) :
QAction(parent),
callback_(nullptr),
callback_data_(NULL),
- retap_(FALSE),
+ retap_(false),
packetCallback_(nullptr),
packetData_(NULL)
{
}
-FunnelAction::FunnelAction(QString title, funnel_menu_callback callback, gpointer callback_data, gboolean retap, QObject *parent = nullptr) :
+FunnelAction::FunnelAction(QString title, funnel_menu_callback callback, void *callback_data, bool retap, QObject *parent = nullptr) :
QAction(parent),
title_(title),
callback_(callback),
@@ -89,7 +87,7 @@ FunnelAction::FunnelAction(QString title, funnel_menu_callback callback, gpointe
packetRequiredFields_ = QSet<QString>();
}
-FunnelAction::FunnelAction(QString title, funnel_packet_menu_callback callback, gpointer callback_data, gboolean retap, const char *packet_required_fields, QObject *parent = nullptr) :
+FunnelAction::FunnelAction(QString title, funnel_packet_menu_callback callback, void *callback_data, bool retap, const char *packet_required_fields, QObject *parent = nullptr) :
QAction(parent),
title_(title),
callback_data_(callback_data),
@@ -248,7 +246,7 @@ void FunnelConsoleAction::triggerCallback() {
static QHash<int, QList<FunnelAction *> > funnel_actions_;
const QString FunnelStatistics::action_name_ = "FunnelStatisticsAction";
-static gboolean menus_registered = FALSE;
+static bool menus_registered;
struct _funnel_ops_id_t {
FunnelStatistics *funnel_statistics;
@@ -313,7 +311,7 @@ void FunnelStatistics::retapPackets()
capture_file_.retapPackets();
}
-struct progdlg *FunnelStatistics::progressDialogNew(const gchar *task_title, const gchar *item_title, gboolean terminate_is_stop, gboolean *stop_flag)
+struct progdlg *FunnelStatistics::progressDialogNew(const char *task_title, const char *item_title, bool terminate_is_stop, bool *stop_flag)
{
return create_progress_dlg(parent(), task_title, item_title, terminate_is_stop, stop_flag);
}
@@ -373,7 +371,7 @@ struct _funnel_text_window_t* text_window_new(funnel_ops_id_t *ops_id, const cha
return FunnelTextDialog::textWindowNew(qobject_cast<QWidget *>(ops_id->funnel_statistics->parent()), title);
}
-void string_dialog_new(funnel_ops_id_t *ops_id, const gchar* title, const gchar** field_names, const gchar** field_values, funnel_dlg_cb_t dialog_cb, void* dialog_cb_data, funnel_dlg_cb_data_free_t dialog_cb_data_free)
+void string_dialog_new(funnel_ops_id_t *ops_id, const char* title, const char** field_names, const char** field_values, funnel_dlg_cb_t dialog_cb, void* dialog_cb_data, funnel_dlg_cb_data_free_t dialog_cb_data_free)
{
QList<QPair<QString, QString>> field_list;
for (int i = 0; field_names[i]; i++) {
@@ -398,7 +396,7 @@ void funnel_statistics_copy_to_clipboard(GString *text) {
mainApp->clipboard()->setText(text->str);
}
-const gchar *funnel_statistics_get_filter(funnel_ops_id_t *ops_id) {
+const char *funnel_statistics_get_filter(funnel_ops_id_t *ops_id) {
if (!ops_id || !ops_id->funnel_statistics) return nullptr;
return ops_id->funnel_statistics->displayFilter();
@@ -410,28 +408,28 @@ void funnel_statistics_set_filter(funnel_ops_id_t *ops_id, const char* filter_st
ops_id->funnel_statistics->emitSetDisplayFilter(filter_string);
}
-gchar* funnel_statistics_get_color_filter_slot(guint8 filter_num) {
+char* funnel_statistics_get_color_filter_slot(uint8_t filter_num) {
return color_filters_get_tmp(filter_num);
}
-void funnel_statistics_set_color_filter_slot(guint8 filter_num, const gchar* filter_string) {
- gchar *err_msg = nullptr;
- if (!color_filters_set_tmp(filter_num, filter_string, FALSE, &err_msg)) {
+void funnel_statistics_set_color_filter_slot(uint8_t filter_num, const char* filter_string) {
+ char *err_msg = nullptr;
+ if (!color_filters_set_tmp(filter_num, filter_string, false, &err_msg)) {
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
g_free(err_msg);
}
}
-gboolean funnel_statistics_open_file(funnel_ops_id_t *ops_id, const char* fname, const char* filter, char**) {
+bool funnel_statistics_open_file(funnel_ops_id_t *ops_id, const char* fname, const char* filter, char**) {
// XXX We need to return a proper error value. We should probably move
// MainWindow::openCaptureFile to CaptureFile and add error handling
// there.
- if (!ops_id || !ops_id->funnel_statistics) return FALSE;
+ if (!ops_id || !ops_id->funnel_statistics) return false;
QString cf_name(fname);
QString cf_filter(filter);
ops_id->funnel_statistics->emitOpenCaptureFile(cf_name, cf_filter);
- return TRUE;
+ return true;
}
void funnel_statistics_reload_packets(funnel_ops_id_t *ops_id) {
@@ -458,21 +456,21 @@ void funnel_statistics_apply_filter(funnel_ops_id_t *ops_id) {
ops_id->funnel_statistics->emitApplyDisplayFilter();
}
-gboolean browser_open_url(const gchar *url) {
- return QDesktopServices::openUrl(QUrl(url)) ? TRUE : FALSE;
+bool browser_open_url(const char *url) {
+ return QDesktopServices::openUrl(QUrl(url)) ? true : false;
}
-void browser_open_data_file(const gchar *filename) {
+void browser_open_data_file(const char *filename) {
QDesktopServices::openUrl(QUrl::fromLocalFile(filename));
}
-struct progdlg *progress_window_new(funnel_ops_id_t *ops_id, const gchar* task_title, const gchar* item_title, gboolean terminate_is_stop, gboolean *stop_flag) {
+struct progdlg *progress_window_new(funnel_ops_id_t *ops_id, const char* task_title, const char* item_title, bool terminate_is_stop, bool *stop_flag) {
if (!ops_id || !ops_id->funnel_statistics) return nullptr;
return ops_id->funnel_statistics->progressDialogNew(task_title, item_title, terminate_is_stop, stop_flag);
}
-void progress_window_update(struct progdlg *progress_dialog, float percentage, const gchar* status) {
+void progress_window_update(struct progdlg *progress_dialog, float percentage, const char* status) {
update_progress_dlg(progress_dialog, percentage, status);
}
@@ -487,8 +485,8 @@ void register_tap_listener_qt_funnel(void);
static void register_menu_cb(const char *name,
register_stat_group_t group,
funnel_menu_callback callback,
- gpointer callback_data,
- gboolean retap)
+ void *callback_data,
+ bool retap)
{
FunnelAction *funnel_action = new FunnelAction(name, callback, callback_data, retap, mainApp);
if (menus_registered) {
@@ -519,8 +517,8 @@ static void register_menu_cb(const char *name,
static void register_packet_menu_cb(const char *name,
const char *required_fields,
funnel_packet_menu_callback callback,
- gpointer callback_data,
- gboolean retap)
+ void *callback_data,
+ bool retap)
{
FunnelAction *funnel_action = new FunnelAction(name, callback, callback_data, retap, required_fields, mainApp);
MainWindow * mainwindow = qobject_cast<MainWindow *>(mainApp->mainWindow());
@@ -552,7 +550,7 @@ register_tap_listener_qt_funnel(void)
{
funnel_register_all_menus(register_menu_cb);
funnel_statistics_load_console_menus();
- menus_registered = TRUE;
+ menus_registered = true;
}
void
@@ -566,9 +564,9 @@ funnel_statistics_reload_menus(void)
/**
* Returns whether the packet menus have been modified since they were last registered
*
- * @return TRUE if the packet menus were modified since the last registration
+ * @return true if the packet menus were modified since the last registration
*/
-gboolean
+bool
funnel_statistics_packet_menus_modified(void)
{
return funnel_packet_menus_modified();
diff --git a/ui/qt/funnel_statistics.h b/ui/qt/funnel_statistics.h
index 65b36ab8..b6ed12f7 100644
--- a/ui/qt/funnel_statistics.h
+++ b/ui/qt/funnel_statistics.h
@@ -26,7 +26,7 @@ struct progdlg;
/**
* Signature of function that can be called from a custom packet menu entry
*/
-typedef void (* funnel_packet_menu_callback)(gpointer, GPtrArray*);
+typedef void (* funnel_packet_menu_callback)(void *, GPtrArray*);
class FunnelStatistics : public QObject
{
@@ -35,7 +35,7 @@ public:
explicit FunnelStatistics(QObject *parent, CaptureFile &cf);
~FunnelStatistics();
void retapPackets();
- struct progdlg *progressDialogNew(const gchar *task_title, const gchar *item_title, gboolean terminate_is_stop, gboolean *stop_flag);
+ struct progdlg *progressDialogNew(const char *task_title, const char *item_title, bool terminate_is_stop, bool *stop_flag);
const char *displayFilter();
void emitSetDisplayFilter(const QString filter);
void reloadPackets();
@@ -68,8 +68,8 @@ class FunnelAction : public QAction
Q_OBJECT
public:
FunnelAction(QObject *parent = nullptr);
- FunnelAction(QString title, funnel_menu_callback callback, gpointer callback_data, gboolean retap, QObject *parent);
- FunnelAction(QString title, funnel_packet_menu_callback callback, gpointer callback_data, gboolean retap, const char *packet_required_fields, QObject *parent);
+ FunnelAction(QString title, funnel_menu_callback callback, void *callback_data, bool retap, QObject *parent);
+ FunnelAction(QString title, funnel_packet_menu_callback callback, void *callback_data, bool retap, const char *packet_required_fields, QObject *parent);
~FunnelAction();
funnel_menu_callback callback() const;
QString title() const;
@@ -89,8 +89,8 @@ private:
QString title_;
QString packetSubmenu_;
funnel_menu_callback callback_;
- gpointer callback_data_;
- gboolean retap_;
+ void *callback_data_;
+ bool retap_;
funnel_packet_menu_callback packetCallback_;
GPtrArray* packetData_;
QSet<QString> packetRequiredFields_;
@@ -120,7 +120,7 @@ extern "C" {
void funnel_statistics_reload_menus(void);
void funnel_statistics_load_packet_menus(void);
void funnel_statistics_load_console_menus(void);
- gboolean funnel_statistics_packet_menus_modified(void);
+ bool funnel_statistics_packet_menus_modified(void);
} // extern "C"
#endif // FUNNELSTATISTICS_H
diff --git a/ui/qt/funnel_string_dialog.cpp b/ui/qt/funnel_string_dialog.cpp
index de52e73f..c8cffe09 100644
--- a/ui/qt/funnel_string_dialog.cpp
+++ b/ui/qt/funnel_string_dialog.cpp
@@ -81,7 +81,7 @@ void FunnelStringDialog::on_buttonBox_accepted()
}
g_ptr_array_add(returns, NULL);
- gchar **user_input = (gchar **)g_ptr_array_free(returns, FALSE);
+ char **user_input = (char **)g_ptr_array_free(returns, false);
dialog_cb_(user_input, dialog_cb_data_);
}
diff --git a/ui/qt/funnel_string_dialog.h b/ui/qt/funnel_string_dialog.h
index bd4f3d35..2ac277aa 100644
--- a/ui/qt/funnel_string_dialog.h
+++ b/ui/qt/funnel_string_dialog.h
@@ -10,8 +10,6 @@
#ifndef FUNNEL_STRING_DIALOG_H
#define FUNNEL_STRING_DIALOG_H
-#include <glib.h>
-
#include "epan/funnel.h"
#include <QDialog>
diff --git a/ui/qt/funnel_text_dialog.cpp b/ui/qt/funnel_text_dialog.cpp
index 84bbb941..15043926 100644
--- a/ui/qt/funnel_text_dialog.cpp
+++ b/ui/qt/funnel_text_dialog.cpp
@@ -57,17 +57,17 @@ void FunnelTextDialog::reject()
close_cb_(close_cb_data_);
}
- QHash<QObject *, funnel_bt_t*>::iterator i;
- for (i = text_button_to_funnel_button_.begin(); i != text_button_to_funnel_button_.end(); ++i) {
- funnel_bt_t *funnel_button = i.value();
- if (funnel_button->free_data_fcn) {
- funnel_button->free_data_fcn(funnel_button->data);
- }
- if (funnel_button->free_fcn) {
- funnel_button->free_fcn(funnel_button);
+ for (const auto& button : ui->buttonBox->buttons()) {
+ funnel_bt_t *funnel_button = text_button_to_funnel_button_.take(qobject_cast<QObject*>(button));
+ if (funnel_button != nullptr) {
+ if (funnel_button->free_data_fcn) {
+ funnel_button->free_data_fcn(funnel_button->data);
+ }
+ if (funnel_button->free_fcn) {
+ funnel_button->free_fcn(funnel_button);
+ }
}
}
- text_button_to_funnel_button_.clear();
disconnect();
deleteLater();
@@ -113,7 +113,7 @@ void FunnelTextDialog::setCloseCallback(text_win_close_cb_t close_cb, void *clos
close_cb_data_ = close_cb_data;
}
-void FunnelTextDialog::setTextEditable(gboolean editable)
+void FunnelTextDialog::setTextEditable(bool editable)
{
ui->textEdit->setReadOnly(!editable);
}
@@ -214,7 +214,7 @@ void text_window_set_close_cb(funnel_text_window_t *ftw, text_win_close_cb_t clo
}
}
-void text_window_set_editable(funnel_text_window_t *ftw, gboolean editable)
+void text_window_set_editable(funnel_text_window_t *ftw, bool editable)
{
if (ftw) {
ftw->funnel_text_dialog->setTextEditable(editable);
diff --git a/ui/qt/funnel_text_dialog.h b/ui/qt/funnel_text_dialog.h
index 84a313c9..19476dd3 100644
--- a/ui/qt/funnel_text_dialog.h
+++ b/ui/qt/funnel_text_dialog.h
@@ -10,8 +10,6 @@
#ifndef FUNNEL_TEXT_DIALOG_H
#define FUNNEL_TEXT_DIALOG_H
-#include <glib.h>
-
#include "epan/funnel.h"
#include "geometry_state_dialog.h"
@@ -44,7 +42,7 @@ public:
void clearText();
const char *getText();
void setCloseCallback(text_win_close_cb_t close_cb, void* close_cb_data);
- void setTextEditable(gboolean editable);
+ void setTextEditable(bool editable);
void addButton(funnel_bt_t *button_cb, QString label);
private slots:
@@ -66,7 +64,7 @@ void text_window_prepend(funnel_text_window_t* ftw, const char* text);
void text_window_clear(funnel_text_window_t *ftw);
const char *text_window_get_text(funnel_text_window_t* ftw);
void text_window_set_close_cb(funnel_text_window_t *ftw, text_win_close_cb_t close_cb, void* close_cb_data);
-void text_window_set_editable(funnel_text_window_t* ftw, gboolean editable);
+void text_window_set_editable(funnel_text_window_t* ftw, bool editable);
void text_window_destroy(funnel_text_window_t* ftw);
void text_window_add_button(funnel_text_window_t* ftw, funnel_bt_t* funnel_button, const char* label);
}
diff --git a/ui/qt/geometry_state_dialog.cpp b/ui/qt/geometry_state_dialog.cpp
index ca6d3980..28a746ee 100644
--- a/ui/qt/geometry_state_dialog.cpp
+++ b/ui/qt/geometry_state_dialog.cpp
@@ -14,7 +14,8 @@
GeometryStateDialog::~GeometryStateDialog()
{
- saveGeometry();
+ saveWindowGeometry();
+ saveSplitterState();
}
void GeometryStateDialog::loadGeometry(int width, int height, const QString &dialog_name)
@@ -23,24 +24,30 @@ void GeometryStateDialog::loadGeometry(int width, int height, const QString &dia
dialog_name_ = dialog_name.isEmpty() ? objectName() : dialog_name;
if (!dialog_name_.isEmpty() && window_geom_load(dialog_name_.toUtf8().constData(), &geom)) {
- QRect recent_geom(geom.x, geom.y, geom.width, geom.height);
+ if (geom.qt_geom == nullptr || !restoreGeometry(QByteArray::fromHex(geom.qt_geom))) {
+ // restoreGeometry didn't work, fallback to older (but other
+ // toolkit compatible?) less-accurate method. (restoreGeometry
+ // is supposed to take care of things like making sure the window
+ // is on screen, setting the non-maximized size if maximized, etc.)
+ QRect recent_geom(geom.x, geom.y, geom.width, geom.height);
- // Check if the dialog is visible on any screen
- if (rect_on_screen(recent_geom)) {
- move(recent_geom.topLeft());
- resize(recent_geom.size());
- } else {
- // Not visible, move within a reasonable area and try size only
- recent_geom.moveTopLeft(QPoint(50, 50));
+ // Check if the dialog is visible on any screen
if (rect_on_screen(recent_geom)) {
+ move(recent_geom.topLeft());
resize(recent_geom.size());
- } else if (width > 0 && height > 0) {
- // We're not visible on any screens, use defaults
- resize(width, height);
+ } else {
+ // Not visible, move within a reasonable area and try size only
+ recent_geom.moveTopLeft(QPoint(50, 50));
+ if (rect_on_screen(recent_geom)) {
+ resize(recent_geom.size());
+ } else if (width > 0 && height > 0) {
+ // We're not visible on any screens, use defaults
+ resize(width, height);
+ }
+ }
+ if (geom.maximized) {
+ showFullScreen();
}
- }
- if (geom.maximized) {
- showFullScreen();
}
} else if (width > 0 && height > 0) {
// No saved geometry found, use defaults
@@ -48,7 +55,34 @@ void GeometryStateDialog::loadGeometry(int width, int height, const QString &dia
}
}
-void GeometryStateDialog::saveGeometry()
+#ifndef Q_OS_MAC
+void GeometryStateDialog::setWindowModality(Qt::WindowModality modality)
+{
+ if (modality != windowModality()) {
+ if (modality == Qt::NonModal) {
+ setParent(nullptr, windowFlags());
+ } else {
+ setParent(parent_, windowFlags());
+ }
+ }
+ QDialog::setWindowModality(modality);
+}
+#endif
+
+void GeometryStateDialog::loadSplitterState(QSplitter *splitter)
+{
+ if (splitter == nullptr) {
+ splitter = findChild<QSplitter *>();
+ }
+ if (splitter != nullptr) {
+ const char* splitter_state = window_splitter_load(dialog_name_.toUtf8().constData());
+ if (splitter_state != nullptr) {
+ splitter->restoreState(QByteArray::fromHex(splitter_state));
+ }
+ }
+}
+
+void GeometryStateDialog::saveWindowGeometry()
{
if (dialog_name_.isEmpty())
return;
@@ -56,14 +90,27 @@ void GeometryStateDialog::saveGeometry()
window_geometry_t geom;
geom.key = NULL;
- geom.set_pos = TRUE;
+ geom.set_pos = true;
geom.x = pos().x();
geom.y = pos().y();
- geom.set_size = TRUE;
+ geom.set_size = true;
geom.width = size().width();
geom.height = size().height();
- geom.set_maximized = TRUE;
+ geom.set_maximized = true;
+ // XXX: maximized and fullScreen are different window states; we've been
+ // using the maximized key for fullScreen ever since this was added.
geom.maximized = isFullScreen();
+ geom.qt_geom = g_strdup(saveGeometry().toHex().constData());
window_geom_save(dialog_name_.toUtf8().constData(), &geom);
}
+
+void GeometryStateDialog::saveSplitterState(const QSplitter *splitter)
+{
+ if (splitter == nullptr) {
+ splitter = findChild<QSplitter *>();
+ }
+ if (splitter != nullptr) {
+ window_splitter_save(dialog_name_.toUtf8().constData(), splitter->saveState().toHex().constData());
+ }
+}
diff --git a/ui/qt/geometry_state_dialog.h b/ui/qt/geometry_state_dialog.h
index 613fad8a..15f0af63 100644
--- a/ui/qt/geometry_state_dialog.h
+++ b/ui/qt/geometry_state_dialog.h
@@ -11,6 +11,7 @@
#define GEOMETRY_STATE_DIALOG_H
#include <QDialog>
+#include <QSplitter>
class GeometryStateDialog : public QDialog
{
@@ -44,24 +45,51 @@ public:
//
// Additionally, maximized, parent-less dialogs can close to a black screen
// on macOS: https://gitlab.com/wireshark/wireshark/-/issues/12544
+// (aka https://bugreports.qt.io/browse/QTBUG-46701 ), which claims to
+// be fixed in Qt 6.2.0
//
// Pass in the parent on macOS and NULL elsewhere so that we have an
// independent window that un-maximizes correctly.
+//
+// Pass Qt::Window as the flags that we have minimize and maximize buttons, as
+// this class is for dialogs where we want to remember user-set geometry.
+// (We're still at the mercy of the platform and Qt, e.g. recent GNOME defaults
+// to not having min or max buttons, instead requiring right-clicking on the
+// menu title bar to perform the minimize or maximize actions. We can't do
+// anything about that, though users can.)
+//
+// However, we want modal dialogs to always be on top of their parent.
+// On Linux with Mutter (and maybe some other window managers), an orphan
+// ApplicationModal dialog is not always on top, and it's confusing if a
+// modal dialog is behind other windows it blocks (Issue #19099). On Windows,
+// a modal orphan dialog is always on top, but setting the parent adds effects
+// like causing the modal dialog to shake if the blocked parent is clicked.
+// So when setting the dialog modal, set the parent if we haven't yet.
#ifdef Q_OS_MAC
- explicit GeometryStateDialog(QWidget *parent, Qt::WindowFlags f = Qt::WindowFlags()) : QDialog(parent, f) {}
+ explicit GeometryStateDialog(QWidget *parent, Qt::WindowFlags f = Qt::Window) : QDialog(parent, f) {}
#else
- explicit GeometryStateDialog(QWidget *, Qt::WindowFlags f = Qt::WindowFlags()) : QDialog(NULL, f) {}
+ explicit GeometryStateDialog(QWidget *parent, Qt::WindowFlags f = Qt::Window) : QDialog(NULL, f), parent_(parent) {}
#endif
~GeometryStateDialog();
+#ifndef Q_OS_MAC
+public:
+ void setWindowModality(Qt::WindowModality windowModality);
+#endif
+
protected:
void loadGeometry(int width = 0, int height = 0, const QString &dialog_name = QString());
+ void loadSplitterState(QSplitter *splitter = nullptr);
private:
- void saveGeometry();
+ void saveWindowGeometry();
+ void saveSplitterState(const QSplitter *splitter = nullptr);
QString dialog_name_;
+#ifndef Q_OS_MAC
+ QWidget *parent_;
+#endif
};
#endif // GEOMETRY_STATE_DIALOG_H
diff --git a/ui/qt/glib_mainloop_on_qeventloop.cpp b/ui/qt/glib_mainloop_on_qeventloop.cpp
index f715bbc7..c92901b5 100644
--- a/ui/qt/glib_mainloop_on_qeventloop.cpp
+++ b/ui/qt/glib_mainloop_on_qeventloop.cpp
@@ -5,6 +5,8 @@
* SPDX-License-Identifier: GPL-2.0-or-later
*/
+#include <glib.h>
+
#include <QTimer>
#include "glib_mainloop_on_qeventloop.h"
@@ -24,7 +26,7 @@ GLibPoller::~GLibPoller()
void GLibPoller::run()
{
- gint timeout;
+ int timeout;
mutex_.lock();
while (!isInterruptionRequested())
diff --git a/ui/qt/glib_mainloop_on_qeventloop.h b/ui/qt/glib_mainloop_on_qeventloop.h
index 9f66c681..9a641e04 100644
--- a/ui/qt/glib_mainloop_on_qeventloop.h
+++ b/ui/qt/glib_mainloop_on_qeventloop.h
@@ -11,7 +11,6 @@
#include <QThread>
#include <QMutex>
#include <QWaitCondition>
-#include <glib.h>
class GLibPoller : public QThread
{
@@ -26,9 +25,9 @@ protected:
QMutex mutex_;
QWaitCondition dispatched_;
GMainContext *ctx_;
- gint priority_;
+ int priority_;
GPollFD *fds_;
- gint allocated_fds_, nfds_;
+ int allocated_fds_, nfds_;
signals:
void polled(void);
diff --git a/ui/qt/gsm_map_summary_dialog.cpp b/ui/qt/gsm_map_summary_dialog.cpp
index 3652c7c7..acdcd48b 100644
--- a/ui/qt/gsm_map_summary_dialog.cpp
+++ b/ui/qt/gsm_map_summary_dialog.cpp
@@ -16,8 +16,6 @@
#include "config.h"
-#include <glib.h>
-
#include "ui/summary.h"
#include <epan/packet.h>
diff --git a/ui/qt/iax2_analysis_dialog.cpp b/ui/qt/iax2_analysis_dialog.cpp
index 7e3fb82e..dfac2ee7 100644
--- a/ui/qt/iax2_analysis_dialog.cpp
+++ b/ui/qt/iax2_analysis_dialog.cpp
@@ -134,7 +134,7 @@ public:
}
}
- guint32 frameNum() { return frame_num_; }
+ uint32_t frameNum() { return frame_num_; }
bool frameStatus() { return ok_; }
QList<QVariant> rowData() {
@@ -153,19 +153,14 @@ public:
switch (treeWidget()->sortColumn()) {
case (packet_col_):
return frame_num_ < other_row->frame_num_;
- break;
case (delta_col_):
return delta_ < other_row->delta_;
- break;
case (jitter_col_):
return jitter_ < other_row->jitter_;
- break;
case (bandwidth_col_):
return bandwidth_ < other_row->bandwidth_;
- break;
case (length_col_):
return pkt_len_ < other_row->pkt_len_;
- break;
default:
break;
}
@@ -174,9 +169,9 @@ public:
return QTreeWidgetItem::operator <(other);
}
private:
- guint32 frame_num_;
- guint32 pkt_len_;
- guint32 flags_;
+ uint32_t frame_num_;
+ uint32_t pkt_len_;
+ uint32_t flags_;
double delta_;
double jitter_;
double bandwidth_;
@@ -228,6 +223,9 @@ Iax2AnalysisDialog::Iax2AnalysisDialog(QWidget &parent, CaptureFile &cf) :
this, SLOT(graphClicked(QMouseEvent*)));
graph_ctx_menu_.addAction(ui->actionSaveGraph);
+ ui->streamGraph->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(ui->streamGraph, &QCustomPlot::customContextMenuRequested, this,
+ &Iax2AnalysisDialog::showGraphMenu);
QStringList header_labels;
for (int i = 0; i < ui->forwardTreeWidget->columnCount(); i++) {
@@ -289,9 +287,9 @@ Iax2AnalysisDialog::Iax2AnalysisDialog(QWidget &parent, CaptureFile &cf) :
#if 0
/* Only accept Voice or MiniPacket packets */
- const gchar filter_text[] = "iax2.call && (ip || ipv6)";
+ const char filter_text[] = "iax2.call && (ip || ipv6)";
#else
- const gchar filter_text[] = "iax2 && (ip || ipv6)";
+ const char filter_text[] = "iax2 && (ip || ipv6)";
#endif
dfilter_t *sfcode;
df_error_t *df_err;
@@ -318,7 +316,7 @@ Iax2AnalysisDialog::Iax2AnalysisDialog(QWidget &parent, CaptureFile &cf) :
epan_dissect_t edt;
- epan_dissect_init(&edt, cap_file_.capFile()->epan, TRUE, FALSE);
+ epan_dissect_init(&edt, cap_file_.capFile()->epan, true, false);
epan_dissect_prime_with_dfilter(&edt, sfcode);
epan_dissect_run(&edt, cap_file_.capFile()->cd_t, &cap_file_.capFile()->rec,
frame_tvbuff_new_buffer(&cap_file_.capFile()->provider, fdata, &cap_file_.capFile()->buf),
@@ -337,10 +335,10 @@ Iax2AnalysisDialog::Iax2AnalysisDialog(QWidget &parent, CaptureFile &cf) :
dfilter_free(sfcode);
/* ok, it is a IAX2 frame, so let's get the ip and port values */
- rtpstream_id_copy_pinfo(&(edt.pi),&(fwd_id_),FALSE);
+ rtpstream_id_copy_pinfo(&(edt.pi),&(fwd_id_),false);
/* assume the inverse ip/port combination for the reverse direction */
- rtpstream_id_copy_pinfo(&(edt.pi),&(rev_id_),TRUE);
+ rtpstream_id_copy_pinfo(&(edt.pi),&(rev_id_),true);
epan_dissect_cleanup(&edt);
@@ -652,8 +650,8 @@ void Iax2AnalysisDialog::resetStatistics()
memset(&fwd_statinfo_, 0, sizeof(fwd_statinfo_));
memset(&rev_statinfo_, 0, sizeof(rev_statinfo_));
- fwd_statinfo_.first_packet = TRUE;
- rev_statinfo_.first_packet = TRUE;
+ fwd_statinfo_.first_packet = true;
+ rev_statinfo_.first_packet = true;
fwd_statinfo_.reg_pt = PT_UNDEFINED;
rev_statinfo_.reg_pt = PT_UNDEFINED;
@@ -703,17 +701,17 @@ void Iax2AnalysisDialog::addPacket(bool forward, packet_info *pinfo, const struc
}
// iax2_analysis.c:rtp_packet_save_payload
-const guint8 silence_pcmu_ = 0xff;
-const guint8 silence_pcma_ = 0x55;
+const uint8_t silence_pcmu_ = 0xff;
+const uint8_t silence_pcma_ = 0x55;
void Iax2AnalysisDialog::savePayload(QTemporaryFile *tmpfile, packet_info *pinfo, const struct _iax2_info_t *iax2info)
{
/* Is this the first packet we got in this direction? */
// if (statinfo->flags & STAT_FLAG_FIRST) {
// if (saveinfo->fp == NULL) {
-// saveinfo->saved = FALSE;
+// saveinfo->saved = false;
// saveinfo->error_type = TAP_RTP_FILE_OPEN_ERROR;
// } else {
-// saveinfo->saved = TRUE;
+// saveinfo->saved = true;
// }
// }
@@ -896,9 +894,9 @@ void Iax2AnalysisDialog::saveAudio(Iax2AnalysisDialog::StreamDirection direction
}
QFile save_file(file_path);
- gint16 sample;
- guint8 pd[4];
- gboolean stop_flag = FALSE;
+ int16_t sample;
+ uint8_t pd[4];
+ bool stop_flag = false;
qint64 nchars;
save_file.open(QIODevice::WriteOnly);
@@ -1009,16 +1007,16 @@ void Iax2AnalysisDialog::saveAudio(Iax2AnalysisDialog::StreamDirection direction
case dir_both_:
{
char f_rawvalue, r_rawvalue;
- guint32 f_write_silence = 0;
- guint32 r_write_silence = 0;
+ uint32_t f_write_silence = 0;
+ uint32_t r_write_silence = 0;
/* since conversation in one way can start later than in the other one,
* we have to write some silence information for one channel */
if (fwd_statinfo_.start_time > rev_statinfo_.start_time) {
- f_write_silence = (guint32)
+ f_write_silence = (uint32_t)
((fwd_statinfo_.start_time - rev_statinfo_.start_time)
* (8000/1000));
} else if (fwd_statinfo_.start_time < rev_statinfo_.start_time) {
- r_write_silence = (guint32)
+ r_write_silence = (uint32_t)
((rev_statinfo_.start_time - fwd_statinfo_.start_time)
* (8000/1000));
}
@@ -1222,16 +1220,14 @@ bool Iax2AnalysisDialog::eventFilter(QObject *, QEvent *event)
return false;
}
-void Iax2AnalysisDialog::graphClicked(QMouseEvent *event)
+void Iax2AnalysisDialog::showGraphMenu(const QPoint &pos)
+{
+ graph_ctx_menu_.popup(ui->streamGraph->mapToGlobal(pos));
+}
+
+void Iax2AnalysisDialog::graphClicked(QMouseEvent *)
{
updateWidgets();
- if (event->button() == Qt::RightButton) {
-#if QT_VERSION >= QT_VERSION_CHECK(6, 0 ,0)
- graph_ctx_menu_.popup(event->globalPosition().toPoint());
-#else
- graph_ctx_menu_.popup(event->globalPos());
-#endif
- }
}
void Iax2AnalysisDialog::showStreamMenu(QPoint pos)
diff --git a/ui/qt/iax2_analysis_dialog.h b/ui/qt/iax2_analysis_dialog.h
index c6daedd0..b1d40331 100644
--- a/ui/qt/iax2_analysis_dialog.h
+++ b/ui/qt/iax2_analysis_dialog.h
@@ -17,8 +17,6 @@
#include <config.h>
-#include <glib.h>
-
#include <epan/address.h>
#include "ui/tap-iax2-analysis.h"
@@ -74,6 +72,7 @@ private slots:
void on_actionSaveGraph_triggered();
void on_buttonBox_helpRequested();
void showStreamMenu(QPoint pos);
+ void showGraphMenu(const QPoint &pos);
void graphClicked(QMouseEvent *event);
private:
@@ -120,8 +119,8 @@ private:
void saveCsv(StreamDirection direction);
#if 0
- guint32 processNode(proto_node *ptree_node, header_field_info *hfinformation, const gchar* proto_field, bool *ok);
- guint32 getIntFromProtoTree(proto_tree *protocol_tree, const gchar *proto_name, const gchar *proto_field, bool *ok);
+ uint32_t processNode(proto_node *ptree_node, header_field_info *hfinformation, const char* proto_field, bool *ok);
+ uint32_t getIntFromProtoTree(proto_tree *protocol_tree, const char *proto_name, const char *proto_field, bool *ok);
#endif
bool eventFilter(QObject*, QEvent* event);
diff --git a/ui/qt/import_text_dialog.cpp b/ui/qt/import_text_dialog.cpp
index 0916c417..17c1734d 100644
--- a/ui/qt/import_text_dialog.cpp
+++ b/ui/qt/import_text_dialog.cpp
@@ -14,8 +14,6 @@
#include "wiretap/wtap.h"
#include "wiretap/pcap-encap.h"
-#include <epan/prefs.h>
-
#include "ui/text_import_scanner.h"
#include "ui/util.h"
#include "ui/alert_box.h"
@@ -26,8 +24,8 @@
#include "wsutil/file_util.h"
#include "wsutil/inet_addr.h"
#include "wsutil/time_util.h"
-#include "wsutil/tempfile.h"
#include "wsutil/filesystem.h"
+#include <wsutil/array.h>
#include <ui_import_text_dialog.h>
#include "main_application.h"
@@ -127,7 +125,7 @@ ImportTextDialog::ImportTextDialog(QWidget *parent) :
{"Plain bin", ENCODING_PLAIN_BIN},
{"Base 64", ENCODING_BASE64}
};
- for (i = 0; i < (int) (sizeof(encodings) / sizeof(encodings[0])); ++i) {
+ for (i = 0; i < (int)array_length(encodings); ++i) {
ti_ui_->dataEncodingComboBox->addItem(encodings[i].name, QVariant(encodings[i].id));
}
@@ -185,7 +183,7 @@ ImportTextDialog::~ImportTextDialog()
void ImportTextDialog::loadSettingsFile()
{
- QFileInfo fileInfo(gchar_free_to_qstring(get_profile_dir(get_profile_name(), FALSE)), QString(SETTINGS_FILE));
+ QFileInfo fileInfo(gchar_free_to_qstring(get_profile_dir(get_profile_name(), false)), QString(SETTINGS_FILE));
QFile loadFile(fileInfo.filePath());
if (!fileInfo.exists() || !fileInfo.isFile()) {
@@ -202,7 +200,7 @@ void ImportTextDialog::loadSettingsFile()
void ImportTextDialog::saveSettingsFile()
{
- QFileInfo fileInfo(gchar_free_to_qstring(get_profile_dir(get_profile_name(), FALSE)), QString(SETTINGS_FILE));
+ QFileInfo fileInfo(gchar_free_to_qstring(get_profile_dir(get_profile_name(), false)), QString(SETTINGS_FILE));
QFile saveFile(fileInfo.filePath());
if (fileInfo.exists() && !fileInfo.isFile()) {
@@ -407,7 +405,7 @@ int ImportTextDialog::exec() {
char* tmp;
GError* gerror = NULL;
int err;
- gchar *err_info;
+ char *err_info;
wtap_dump_params params;
int file_type_subtype;
QString interface_name;
@@ -427,10 +425,12 @@ int ImportTextDialog::exec() {
import_info_.import_text_filename = qstring_strdup(ti_ui_->textFileLineEdit->text());
import_info_.timestamp_format = qstring_strdup(ti_ui_->timestampFormatLineEdit->text());
if (strlen(import_info_.timestamp_format) == 0) {
- g_free((gpointer) import_info_.timestamp_format);
+ g_free((void *) import_info_.timestamp_format);
import_info_.timestamp_format = NULL;
}
+ mainApp->setLastOpenDirFromFilename(QString(import_info_.import_text_filename));
+
switch (import_info_.mode) {
default: /* should never happen */
setResult(QDialog::Rejected);
@@ -438,7 +438,7 @@ int ImportTextDialog::exec() {
case TEXT_IMPORT_HEXDUMP:
import_info_.hexdump.import_text_FILE = ws_fopen(import_info_.import_text_filename, "rb");
if (!import_info_.hexdump.import_text_FILE) {
- open_failure_alert_box(import_info_.import_text_filename, errno, FALSE);
+ open_failure_alert_box(import_info_.import_text_filename, errno, false);
setResult(QDialog::Rejected);
goto cleanup_mode;
}
@@ -452,7 +452,7 @@ int ImportTextDialog::exec() {
case TEXT_IMPORT_REGEX:
import_info_.regex.import_text_GMappedFile = g_mapped_file_new(import_info_.import_text_filename, true, &gerror);
if (gerror) {
- open_failure_alert_box(import_info_.import_text_filename, gerror->code, FALSE);
+ open_failure_alert_box(import_info_.import_text_filename, gerror->code, false);
g_error_free(gerror);
setResult(QDialog::Rejected);
goto cleanup_mode;
@@ -539,7 +539,7 @@ int ImportTextDialog::exec() {
wtap_free_idb_info(params.idb_inf);
wtap_dump_params_cleanup(&params);
g_free(tmp);
- g_free((gpointer) import_info_.payload);
+ g_free((void *) import_info_.payload);
switch (import_info_.mode) {
case TEXT_IMPORT_HEXDUMP:
fclose(import_info_.hexdump.import_text_FILE);
@@ -547,13 +547,13 @@ int ImportTextDialog::exec() {
case TEXT_IMPORT_REGEX:
g_mapped_file_unref(import_info_.regex.import_text_GMappedFile);
g_regex_unref((GRegex*) import_info_.regex.format);
- g_free((gpointer) import_info_.regex.in_indication);
- g_free((gpointer) import_info_.regex.out_indication);
+ g_free((void *) import_info_.regex.in_indication);
+ g_free((void *) import_info_.regex.out_indication);
break;
}
cleanup_mode:
- g_free((gpointer) import_info_.import_text_filename);
- g_free((gpointer) import_info_.timestamp_format);
+ g_free((void *) import_info_.import_text_filename);
+ g_free((void *) import_info_.timestamp_format);
return result();
}
@@ -606,26 +606,7 @@ void ImportTextDialog::on_textFileBrowseButton_clicked()
if (ti_ui_->textFileLineEdit->text().length() > 0) {
open_dir = ti_ui_->textFileLineEdit->text();
} else {
- switch (prefs.gui_fileopen_style) {
-
- case FO_STYLE_LAST_OPENED:
- /* The user has specified that we should start out in the last directory
- we looked in. If we've already opened a file, use its containing
- directory, if we could determine it, as the directory, otherwise
- use the "last opened" directory saved in the preferences file if
- there was one. */
- /* This is now the default behaviour in file_selection_new() */
- open_dir = get_open_dialog_initial_dir();
- break;
-
- case FO_STYLE_SPECIFIED:
- /* The user has specified that we should always start out in a
- specified directory; if they've specified that directory,
- start out by showing the files in that dir. */
- if (prefs.gui_fileopen_dir[0] != '\0')
- open_dir = prefs.gui_fileopen_dir;
- break;
- }
+ open_dir = get_open_dialog_initial_dir();
}
QString file_name = WiresharkFileDialog::getOpenFileName(this, mainApp->windowTitleString(tr("Import Text File")), open_dir);
@@ -637,7 +618,7 @@ bool ImportTextDialog::checkDateTimeFormat(const QString &time_format)
/* nonstandard is f for fractions of seconds */
const QString valid_code = "aAbBcdDFfHIjmMpsSTUwWxXyYzZ%";
int idx = 0;
- int ret = false;
+ bool ret = false;
/* XXX: Temporary(?) hack to allow ISO format time, a checkbox is
* probably better */
@@ -742,7 +723,7 @@ void ImportTextDialog::on_asciiIdentificationCheckBox_toggled(bool checked)
void ImportTextDialog::on_regexTextEdit_textChanged()
{
- gchar* regex_gchar_p = qstring_strdup(ti_ui_->regexTextEdit->toPlainText());;
+ char* regex_gchar_p = qstring_strdup(ti_ui_->regexTextEdit->toPlainText());
GError* gerror = NULL;
/* TODO: Use GLib's c++ interface or enable C++ int to enum casting
* because the flags are declared as enum, so we can't pass 0 like
@@ -953,7 +934,7 @@ void ImportTextDialog::on_ipVersionComboBox_currentIndexChanged(int index)
on_destinationAddressLineEdit_textChanged(ti_ui_->destinationAddressLineEdit->text());
}
-void ImportTextDialog::check_line_edit(SyntaxLineEdit *le, bool &ok_enabled, const QString &num_str, int base, guint max_val, bool is_short, guint *val_ptr) {
+void ImportTextDialog::check_line_edit(SyntaxLineEdit *le, bool &ok_enabled, const QString &num_str, int base, unsigned max_val, bool is_short, unsigned *val_ptr) {
bool conv_ok;
SyntaxLineEdit::SyntaxState syntax_state = SyntaxLineEdit::Empty;
@@ -967,7 +948,7 @@ void ImportTextDialog::check_line_edit(SyntaxLineEdit *le, bool &ok_enabled, con
if (is_short) {
*val_ptr = num_str.toUShort(&conv_ok, base);
} else {
- *val_ptr = (guint)num_str.toULong(&conv_ok, base);
+ *val_ptr = (unsigned)num_str.toULong(&conv_ok, base);
}
if (conv_ok && *val_ptr <= max_val) {
syntax_state = SyntaxLineEdit::Valid;
diff --git a/ui/qt/import_text_dialog.h b/ui/qt/import_text_dialog.h
index ac9537d9..d2fe13cb 100644
--- a/ui/qt/import_text_dialog.h
+++ b/ui/qt/import_text_dialog.h
@@ -14,8 +14,6 @@
#include <stdio.h>
-#include <glib.h>
-
#include "ui/text_import.h"
#include <ui/qt/widgets/syntax_line_edit.h>
@@ -44,7 +42,7 @@ private:
/* regex fields */
void enableFieldWidgets(bool enable_direction_input = true, bool enable_time_input = true);
- void check_line_edit(SyntaxLineEdit *le, bool &ok_enable, const QString &num_str, int base, guint max_val, bool is_short, guint *val_ptr);
+ void check_line_edit(SyntaxLineEdit *le, bool &ok_enable, const QString &num_str, int base, unsigned max_val, bool is_short, unsigned *val_ptr);
void checkAddress(SyntaxLineEdit *le, bool &ok_enable, const QString &addr_str, ws_in4_addr *val_ptr);
void checkIPv6Address(SyntaxLineEdit *le, bool &ok_enable, const QString &addr_str, ws_in6_addr *val_ptr);
bool checkDateTimeFormat(const QString &time_format);
diff --git a/ui/qt/interface_frame.cpp b/ui/qt/interface_frame.cpp
index b1f34b22..ba2d42e0 100644
--- a/ui/qt/interface_frame.cpp
+++ b/ui/qt/interface_frame.cpp
@@ -32,6 +32,7 @@
#include <ui/recent.h>
#include "capture_opts.h"
#include "ui/capture_globals.h"
+#include <ui/iface_lists.h>
#include <wsutil/utf8_entities.h>
#include <QDesktopServices>
@@ -41,6 +42,8 @@
#include <QLabel>
#include <QPushButton>
#include <QUrl>
+#include <QMutex>
+#include <QDebug>
#include <epan/prefs.h>
@@ -51,6 +54,8 @@ const int stat_update_interval_ = 1000; // ms
#endif
const char *no_capture_link = "#no_capture";
+static QMutex scan_mutex;
+
InterfaceFrame::InterfaceFrame(QWidget * parent)
: QFrame(parent),
ui(new Ui::InterfaceFrame)
@@ -205,6 +210,27 @@ void InterfaceFrame::showEvent(QShowEvent *) {
#endif // HAVE_LIBPCAP
}
+#ifdef HAVE_LIBPCAP
+void InterfaceFrame::scanLocalInterfaces(GList *filter_list)
+{
+ GList *if_list = NULL;
+ if (scan_mutex.tryLock()) {
+ if (isVisible()) {
+ source_model_.stopStatistic();
+ if_stat_cache_t * stat_cache = capture_interface_stat_start(&global_capture_opts, &if_list);
+ source_model_.setCache(stat_cache);
+ }
+ mainApp->setInterfaceList(if_list);
+ free_interface_list(if_list);
+ scan_local_interfaces_filtered(filter_list, main_window_update);
+ mainApp->emitAppSignal(MainApplication::LocalInterfacesChanged);
+ scan_mutex.unlock();
+ } else {
+ qDebug() << "scan mutex locked, can't scan interfaces";
+ }
+}
+#endif // HAVE_LIBPCAP
+
void InterfaceFrame::actionButton_toggled(bool checked)
{
QVariant ifType = sender()->property(BTN_IFTYPE_PROPERTY);
@@ -422,7 +448,7 @@ void InterfaceFrame::on_interfaceTree_doubleClicked(const QModelIndex &index)
interfaces << device_name;
/* We trust the string here. If this interface is really extcap, the string is
- * being checked immediatly before the dialog is being generated */
+ * being checked immediately before the dialog is being generated */
if (extcap_string.length() > 0)
{
/* this checks if configuration is required and not yet provided or saved via prefs */
@@ -454,7 +480,7 @@ void InterfaceFrame::on_interfaceTree_clicked(const QModelIndex &index)
QString extcap_string = source_model_.getColumnContent(realIndex.row(), IFTREE_COL_EXTCAP_PATH).toString();
/* We trust the string here. If this interface is really extcap, the string is
- * being checked immediatly before the dialog is being generated */
+ * being checked immediately before the dialog is being generated */
if (extcap_string.length() > 0)
{
/* this checks if configuration is required and not yet provided or saved via prefs */
@@ -534,7 +560,7 @@ void InterfaceFrame::showContextMenu(QPoint pos)
void InterfaceFrame::on_warningLabel_linkActivated(const QString &link)
{
if (link.compare(no_capture_link) == 0) {
- recent.sys_warn_if_no_capture = FALSE;
+ recent.sys_warn_if_no_capture = false;
resetInterfaceTreeDisplay();
} else {
QDesktopServices::openUrl(QUrl(link));
diff --git a/ui/qt/interface_frame.h b/ui/qt/interface_frame.h
index f36ce945..211350e7 100644
--- a/ui/qt/interface_frame.h
+++ b/ui/qt/interface_frame.h
@@ -15,8 +15,6 @@
#include <config.h>
-#include <glib.h>
-
#include <ui/qt/models/info_proxy_model.h>
#include <ui/qt/models/interface_tree_model.h>
#include <ui/qt/models/interface_sort_filter_model.h>
@@ -52,6 +50,9 @@ Q_SIGNALS:
void typeSelectionChanged();
public slots:
+#ifdef HAVE_LIBPCAP
+ void scanLocalInterfaces(GList *filter_list = nullptr);
+#endif
void updateSelectedInterfaces();
void interfaceListChanged();
void toggleHiddenInterfaces();
diff --git a/ui/qt/interface_toolbar.cpp b/ui/qt/interface_toolbar.cpp
index be2cde66..e4472d8c 100644
--- a/ui/qt/interface_toolbar.cpp
+++ b/ui/qt/interface_toolbar.cpp
@@ -79,7 +79,7 @@ InterfaceToolbar::InterfaceToolbar(QWidget *parent, const iface_toolbar *toolbar
// Fill inn interfaces list and initialize default interface values
for (GList *walker = toolbar->ifnames; walker; walker = walker->next)
{
- QString ifname((gchar *)walker->data);
+ QString ifname((char *)walker->data);
interface_[ifname].reader_thread = NULL;
interface_[ifname].out_fd = -1;
}
@@ -193,14 +193,14 @@ QWidget *InterfaceToolbar::createCheckbox(iface_toolbar_control *control)
QWidget *InterfaceToolbar::createButton(iface_toolbar_control *control)
{
- QPushButton *button = new QPushButton(QString().fromUtf8((gchar *)control->display));
+ QPushButton *button = new QPushButton(QString().fromUtf8((char *)control->display));
button->setMaximumHeight(27);
button->setToolTip(QString().fromUtf8(control->tooltip));
switch (control->ctrl_role)
{
case INTERFACE_ROLE_CONTROL:
- setDefaultValue(control->num, (gchar *)control->display);
+ setDefaultValue(control->num, (char *)control->display);
connect(button, SIGNAL(clicked()), this, SLOT(onControlButtonClicked()));
break;
@@ -242,13 +242,13 @@ QWidget *InterfaceToolbar::createSelector(iface_toolbar_control *control)
for (GList *walker = control->values; walker; walker = walker->next)
{
iface_toolbar_value *val = (iface_toolbar_value *)walker->data;
- QString value = QString().fromUtf8((gchar *)val->value);
+ QString value = QString().fromUtf8((char *)val->value);
if (value.isEmpty())
{
// Invalid value
continue;
}
- QString display = QString().fromUtf8((gchar *)val->display);
+ QString display = QString().fromUtf8((char *)val->display);
QByteArray interface_value;
interface_value.append(value.toUtf8());
@@ -746,7 +746,7 @@ void InterfaceToolbar::startCapture(GArray *ifaces)
QString first_capturing_ifname;
bool selected_found = false;
- for (guint i = 0; i < ifaces->len; i++)
+ for (unsigned i = 0; i < ifaces->len; i++)
{
interface_options *interface_opts = &g_array_index(ifaces, interface_options, i);
QString ifname(interface_opts->name);
@@ -774,7 +774,7 @@ void InterfaceToolbar::startCapture(GArray *ifaces)
// The control out pipe will close when both out_fd and extcap_control_out_h are closed.
HANDLE duplicate_out_handle = INVALID_HANDLE_VALUE;
if (!DuplicateHandle(GetCurrentProcess(), interface_opts->extcap_control_out_h,
- GetCurrentProcess(), &duplicate_out_handle, 0, TRUE, DUPLICATE_SAME_ACCESS))
+ GetCurrentProcess(), &duplicate_out_handle, 0, true, DUPLICATE_SAME_ACCESS))
{
simple_dialog_async(ESD_TYPE_ERROR, ESD_BTN_OK,
"Failed to duplicate extcap control out handle: %s\n.",
@@ -962,7 +962,7 @@ void InterfaceToolbar::interfaceListChanged()
ui->interfacesComboBox->blockSignals(true);
ui->interfacesComboBox->clear();
- for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++)
+ for (unsigned i = 0; i < global_capture_opts.all_ifaces->len; i++)
{
interface_t *device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
if (device->hidden)
diff --git a/ui/qt/interface_toolbar.h b/ui/qt/interface_toolbar.h
index f9879fa2..fc20c197 100644
--- a/ui/qt/interface_toolbar.h
+++ b/ui/qt/interface_toolbar.h
@@ -10,8 +10,6 @@
#ifndef INTERFACE_TOOLBAR_H
#define INTERFACE_TOOLBAR_H
-#include <glib.h>
-
#include "ui/iface_toolbar.h"
#include "funnel_text_dialog.h"
#include "interface_toolbar_reader.h"
diff --git a/ui/qt/interface_toolbar_reader.cpp b/ui/qt/interface_toolbar_reader.cpp
index d12f7472..6b5c1f1a 100644
--- a/ui/qt/interface_toolbar_reader.cpp
+++ b/ui/qt/interface_toolbar_reader.cpp
@@ -34,7 +34,7 @@ int InterfaceToolbarReader::async_pipe_read(void *data, int nbyte)
int bytes_read = -1;
overlap.Pointer = 0;
- overlap.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ overlap.hEvent = CreateEvent(NULL, true, false, NULL);
if (overlap.hEvent == NULL)
{
// CreateEvent failed with error code GetLastError()
@@ -54,7 +54,7 @@ int InterfaceToolbarReader::async_pipe_read(void *data, int nbyte)
if (WaitForSingleObject(overlap.hEvent, INFINITE) == WAIT_OBJECT_0)
{
// The wait operation has completed.
- success = GetOverlappedResult(control_in_, &overlap, &nof_bytes_read, FALSE);
+ success = GetOverlappedResult(control_in_, &overlap, &nof_bytes_read, false);
if (success && nof_bytes_read != 0)
{
diff --git a/ui/qt/io_console_dialog.cpp b/ui/qt/io_console_dialog.cpp
index 92d4c542..600a544b 100644
--- a/ui/qt/io_console_dialog.cpp
+++ b/ui/qt/io_console_dialog.cpp
@@ -44,6 +44,7 @@ IOConsoleDialog::IOConsoleDialog(QWidget &parent,
title = QString("Console");
loadGeometry(0, 0, title);
+ loadSplitterState(ui->splitter);
setWindowTitle(mainApp->windowTitleString(title));
QPushButton *eval_button = ui->buttonBox->addButton(tr("Evaluate"), QDialogButtonBox::ActionRole);
diff --git a/ui/qt/io_graph_action.cpp b/ui/qt/io_graph_action.cpp
new file mode 100644
index 00000000..777f87b1
--- /dev/null
+++ b/ui/qt/io_graph_action.cpp
@@ -0,0 +1,134 @@
+/* @file
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "io_graph_action.h"
+
+#include <ui/qt/main_application.h>
+#include <ui/qt/main_window.h>
+#include <ui/qt/io_graph_dialog.h>
+#include <ui/qt/utils/field_information.h>
+
+#include <ui/io_graph_item.h>
+
+#include <wsutil/filesystem.h>
+
+#include <QMenu>
+
+IOGraphAction::IOGraphAction(QObject *parent, io_graph_item_unit_t unit, QString field) :
+ QAction(parent),
+ unit_(unit),
+ field_(field)
+{
+ setText(unitName(unit));
+ connect(this, &QAction::triggered, [&](){ emit openIOGraphDialog(unit_, field_); });
+}
+
+const QString IOGraphAction::unitName(io_graph_item_unit_t unit) {
+ switch (unit) {
+ case IOG_ITEM_UNIT_PACKETS:
+ if (is_packet_configuration_namespace()) {
+ return QObject::tr("PACKETS");
+ }
+ return QObject::tr("EVENTS");
+ case IOG_ITEM_UNIT_BYTES:
+ return QObject::tr("BYTES");
+ case IOG_ITEM_UNIT_BITS:
+ return QObject::tr("BITS");
+ case IOG_ITEM_UNIT_CALC_FRAMES:
+ return QObject::tr("COUNT FRAMES");
+ case IOG_ITEM_UNIT_CALC_FIELDS:
+ return QObject::tr("COUNT FIELDS");
+ case IOG_ITEM_UNIT_CALC_SUM:
+ return QObject::tr("SUM");
+ case IOG_ITEM_UNIT_CALC_MAX:
+ return QObject::tr("MAX");
+ case IOG_ITEM_UNIT_CALC_MIN:
+ return QObject::tr("MIN");
+ case IOG_ITEM_UNIT_CALC_AVERAGE:
+ return QObject::tr("AVERAGE");
+ case IOG_ITEM_UNIT_CALC_THROUGHPUT:
+ return QObject::tr("THROUGHPUT");
+ case IOG_ITEM_UNIT_CALC_LOAD:
+ return QObject::tr("LOAD");
+ default:
+ return QObject::tr("UNKNOWN");
+ }
+}
+
+QList<io_graph_item_unit_t> IOGraphAction::unitTypes(const FieldInformation::HeaderInfo& headerinfo)
+{
+ static const QList<io_graph_item_unit_t> simple_types_ = QList<io_graph_item_unit_t>()
+ << IOG_ITEM_UNIT_CALC_FRAMES
+ << IOG_ITEM_UNIT_CALC_FIELDS;
+
+ static const QList<io_graph_item_unit_t> number_types_ = QList<io_graph_item_unit_t>()
+ << IOG_ITEM_UNIT_CALC_SUM
+ << IOG_ITEM_UNIT_CALC_FRAMES
+ << IOG_ITEM_UNIT_CALC_FIELDS
+ << IOG_ITEM_UNIT_CALC_MAX
+ << IOG_ITEM_UNIT_CALC_MIN
+ << IOG_ITEM_UNIT_CALC_THROUGHPUT
+ << IOG_ITEM_UNIT_CALC_AVERAGE;
+
+ static const QList<io_graph_item_unit_t> time_types_ = QList<io_graph_item_unit_t>(number_types_)
+ << IOG_ITEM_UNIT_CALC_LOAD;
+
+ switch (headerinfo.type) {
+ case FT_UINT8:
+ case FT_UINT16:
+ case FT_UINT24:
+ case FT_UINT32:
+ case FT_UINT64:
+ case FT_INT8:
+ case FT_INT16:
+ case FT_INT24:
+ case FT_INT32:
+ case FT_INT64:
+ case FT_FLOAT:
+ case FT_DOUBLE:
+ return number_types_;
+ case FT_RELATIVE_TIME:
+ return time_types_;
+ default:
+ return simple_types_;
+ }
+}
+
+QMenu * IOGraphAction::createMenu(const FieldInformation::HeaderInfo& headerinfo, QWidget * parent)
+{
+ MainWindow *mw(nullptr);
+ if (mainApp)
+ {
+ QWidget * mainWin = mainApp->mainWindow();
+ if (qobject_cast<MainWindow *>(mainWin)) {
+ mw = qobject_cast<MainWindow *>(mainWin);
+ }
+ }
+
+ QString title("I/O Graph");
+ QMenu * submenu = new QMenu(title, parent);
+
+ int one_em = submenu->fontMetrics().height();
+ QString prep_text = QString("%1: %2").arg(title).arg(headerinfo.abbreviation);
+ prep_text = submenu->fontMetrics().elidedText(prep_text, Qt::ElideRight, one_em * 40);
+ QAction * comment = submenu->addAction(prep_text);
+ comment->setEnabled(false);
+ submenu->addSeparator();
+
+ IOGraphAction *graphAction;
+ for (const auto &unit : IOGraphAction::unitTypes(headerinfo)) {
+ graphAction = new IOGraphAction(submenu, unit, headerinfo.abbreviation);
+ if (mw) {
+ connect(graphAction, &IOGraphAction::openIOGraphDialog, mw, &MainWindow::showIOGraphDialog);
+ }
+ submenu->addAction(graphAction);
+ }
+
+ return submenu;
+}
diff --git a/ui/qt/io_graph_action.h b/ui/qt/io_graph_action.h
new file mode 100644
index 00000000..290f1880
--- /dev/null
+++ b/ui/qt/io_graph_action.h
@@ -0,0 +1,47 @@
+/** @file
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef IO_GRAPH_ACTION_H
+#define IO_GRAPH_ACTION_H
+
+#include <ui/qt/utils/field_information.h>
+#include <ui/io_graph_item.h>
+
+#include <QAction>
+
+class IOGraphAction : public QAction
+{
+ Q_OBJECT
+public:
+ explicit IOGraphAction(QObject *parent, io_graph_item_unit_t unit = IOG_ITEM_UNIT_PACKETS, QString field = QString());
+ explicit IOGraphAction(QObject *parent);
+
+ io_graph_item_unit_t unit() const { return unit_; }
+
+ QString valueField() const { return field_; }
+
+ static const QString unitName(io_graph_item_unit_t unit);
+
+ static QList<io_graph_item_unit_t> unitTypes(const FieldInformation::HeaderInfo& headerinfo);
+ static QMenu * createMenu(const FieldInformation::HeaderInfo& headerinfo, QWidget * parent);
+
+signals:
+ void openIOGraphDialog(io_graph_item_unit_t, QString);
+
+public slots:
+
+private:
+ io_graph_item_unit_t unit_;
+ QString field_;
+
+private slots:
+
+};
+
+#endif // IO_GRAPH_ACTION_H
diff --git a/ui/qt/io_graph_dialog.cpp b/ui/qt/io_graph_dialog.cpp
index 002b98f9..8e7821a4 100644
--- a/ui/qt/io_graph_dialog.cpp
+++ b/ui/qt/io_graph_dialog.cpp
@@ -7,13 +7,14 @@
* SPDX-License-Identifier: GPL-2.0-or-later
*/
+#define WS_LOG_DOMAIN LOG_DOMAIN_QTUI
#include "io_graph_dialog.h"
#include <ui_io_graph_dialog.h>
#include "file.h"
+#include "locale.h"
#include <epan/stat_tap_ui.h>
-#include "epan/stats_tree_priv.h"
#include "epan/uat-int.h"
#include <wsutil/utf8_entities.h>
@@ -25,11 +26,16 @@
#include <ui/qt/utils/color_utils.h>
#include <ui/qt/widgets/qcustomplot.h>
+#include <ui/qt/widgets/qcp_string_legend_item.h>
+#include <ui/qt/widgets/qcp_axis_ticker_si.h>
#include "progress_frame.h"
#include "main_application.h"
+#include <ui/qt/main_window.h>
#include <wsutil/filesystem.h>
#include <wsutil/report_message.h>
+#include <wsutil/nstime.h>
+#include <wsutil/to_str.h>
#include <ui/qt/utils/tango_colors.h> //provides some default colors
#include <ui/qt/widgets/copy_from_profile_button.h>
@@ -47,6 +53,8 @@
#include <QTimer>
#include <QVariant>
+#include <new> // std::bad_alloc
+
// Bugs and uncertainties:
// - Regular (non-stacked) bar graphs are drawn on top of each other on the Z axis.
// The QCP forum suggests drawing them side by side:
@@ -54,15 +62,30 @@
// - We retap and redraw more than we should.
// - Smoothing doesn't seem to match GTK+
// - Closing the color picker on macOS sends the dialog to the background.
-// - The color picker triggers https://bugreports.qt.io/browse/QTBUG-58699.
+// - X-axis time buckets are based on the file relative time, even in
+// Time of Day / absolute time mode. (See io_graph_item.c/get_io_graph_index)
+// Changing this would mean retapping when switching to ToD mode, though.
// To do:
// - Use scroll bars?
-// - Scroll during live captures
+// https://www.qcustomplot.com/index.php/tutorials/specialcases/scrollbar
+// - Scroll during live captures (currently the graph auto rescales instead)
// - Set ticks per pixel (e.g. pressing "2" sets 2 tpp).
// - Explicitly handle missing values, e.g. via NAN.
// - Add a "show missing" or "show zero" option to the UAT?
// It would add yet another graph configuration column.
+// - Increase max number of items (or make configurable)
+// - Dark Mode support, e.g.
+// https://www.qcustomplot.com/index.php/demos/barchartdemo
+// - Multiple y-axes?
+// https://www.qcustomplot.com/index.php/demos/multiaxisdemo
+// https://www.qcustomplot.com/index.php/tutorials/specialcases/axistags
+
+// Scale factor to convert the units the interval is stored in to seconds.
+// Must match what get_io_graph_index() in io_graph_item expects.
+// Increase this in order to make smaller intervals possible.
+const int SCALE = 1000000;
+const double SCALE_F = (double)SCALE;
const qreal graph_line_width_ = 1.0;
@@ -77,15 +100,15 @@ const int stat_update_interval_ = 200; // ms
// Saved graph settings
typedef struct _io_graph_settings_t {
- gboolean enabled;
+ bool enabled;
char* name;
char* dfilter;
- guint color;
- guint32 style;
- guint32 yaxis;
+ unsigned color;
+ uint32_t style;
+ uint32_t yaxis;
char* yfield;
- guint32 sma_period;
- guint32 y_axis_factor;
+ uint32_t sma_period;
+ uint32_t y_axis_factor;
} io_graph_settings_t;
static const value_string graph_style_vs[] = {
@@ -105,7 +128,7 @@ static const value_string graph_style_vs[] = {
{ 0, NULL }
};
-static const value_string y_axis_vs[] = {
+static const value_string y_axis_packet_vs[] = {
{ IOG_ITEM_UNIT_PACKETS, "Packets" },
{ IOG_ITEM_UNIT_BYTES, "Bytes" },
{ IOG_ITEM_UNIT_BITS, "Bits" },
@@ -115,10 +138,25 @@ static const value_string y_axis_vs[] = {
{ IOG_ITEM_UNIT_CALC_MAX, "MAX(Y Field)" },
{ IOG_ITEM_UNIT_CALC_MIN, "MIN(Y Field)" },
{ IOG_ITEM_UNIT_CALC_AVERAGE, "AVG(Y Field)" },
+ { IOG_ITEM_UNIT_CALC_THROUGHPUT, "THROUGHPUT(Y Field)" },
{ IOG_ITEM_UNIT_CALC_LOAD, "LOAD(Y Field)" },
{ 0, NULL }
};
+static const value_string y_axis_event_vs[] = {
+ { IOG_ITEM_UNIT_PACKETS, "Events" },
+ y_axis_packet_vs[1],
+ y_axis_packet_vs[2],
+ y_axis_packet_vs[3],
+ y_axis_packet_vs[4],
+ y_axis_packet_vs[5],
+ y_axis_packet_vs[6],
+ y_axis_packet_vs[7],
+ y_axis_packet_vs[8],
+ y_axis_packet_vs[9],
+ { 0, NULL }
+};
+
static const value_string moving_avg_vs[] = {
{ 0, "None" },
{ 10, "10 interval SMA" },
@@ -131,24 +169,31 @@ static const value_string moving_avg_vs[] = {
{ 0, NULL }
};
-static io_graph_settings_t *iog_settings_ = NULL;
-static guint num_io_graphs_ = 0;
-static uat_t *iog_uat_ = NULL;
+static io_graph_settings_t *iog_settings_;
+static unsigned num_io_graphs_;
+static uat_t *iog_uat_;
+// XXX - Multiple UatModels with the same uat can crash if one is
+// edited, because the underlying uat_t* data changes but the
+// record_errors and dirty_records lists do not.
+static QPointer<UatModel> static_uat_model_;
// y_axis_factor was added in 3.6. Provide backward compatibility.
static const char *iog_uat_defaults_[] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "1"
};
+static char *decimal_point;
+
extern "C" {
-//Allow the enable/disable field to be a checkbox, but for backwards compatibility,
-//the strings have to be "Enabled"/"Disabled", not "TRUE"/"FALSE"
+//Allow the enable/disable field to be a checkbox, but for backwards
+//compatibility with pre-2.6 versions, the strings are "Enabled"/"Disabled",
+//not "true"/"false". (Pre-4.4 versions require "true" to be all-caps.)
#define UAT_BOOL_ENABLE_CB_DEF(basename,field_name,rec_t) \
-static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, guint len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
+static void basename ## _ ## field_name ## _set_cb(void* rec, const char* buf, unsigned len, const void* UNUSED_PARAMETER(u1), const void* UNUSED_PARAMETER(u2)) {\
char* tmp_str = g_strndup(buf,len); \
- if ((g_strcmp0(tmp_str, "Enabled") == 0) || \
- (g_strcmp0(tmp_str, "TRUE") == 0)) \
+ if (tmp_str && ((g_strcmp0(tmp_str, "Enabled") == 0) || \
+ (g_ascii_strcasecmp(tmp_str, "true") == 0))) \
((rec_t*)rec)->field_name = 1; \
else \
((rec_t*)rec)->field_name = 0; \
@@ -157,32 +202,33 @@ static void basename ## _ ## field_name ## _tostr_cb(void* rec, char** out_ptr,
*out_ptr = ws_strdup_printf("%s",((rec_t*)rec)->field_name ? "Enabled" : "Disabled"); \
*out_len = (unsigned)strlen(*out_ptr); }
-static bool uat_fld_chk_enable(void* u1 _U_, const char* strptr, guint len, const void* u2 _U_, const void* u3 _U_, char** err)
+static bool uat_fld_chk_enable(void* u1 _U_, const char* strptr, unsigned len, const void* u2 _U_, const void* u3 _U_, char** err)
{
char* str = g_strndup(strptr,len);
- if ((g_strcmp0(str, "Enabled") == 0) ||
+ if (str &&
+ ((g_strcmp0(str, "Enabled") == 0) ||
(g_strcmp0(str, "Disabled") == 0) ||
- (g_strcmp0(str, "TRUE") == 0) || //just for UAT functionality
- (g_strcmp0(str, "FALSE") == 0)) {
+ (g_ascii_strcasecmp(str, "true") == 0) || //just for UAT functionality
+ (g_ascii_strcasecmp(str, "false") == 0))) {
*err = NULL;
g_free(str);
- return TRUE;
+ return true;
}
//User should never see this unless they are manually modifying UAT
*err = ws_strdup_printf("invalid value: %s (must be Enabled or Disabled)", str);
g_free(str);
- return FALSE;
+ return false;
}
#define UAT_FLD_BOOL_ENABLE(basename,field_name,title,desc) \
{#field_name, title, PT_TXTMOD_BOOL,{uat_fld_chk_enable,basename ## _ ## field_name ## _set_cb,basename ## _ ## field_name ## _tostr_cb},{0,0,0},0,desc,FLDFILL}
//"Custom" handler for sma_period enumeration for backwards compatibility
-static void io_graph_sma_period_set_cb(void* rec, const char* buf, guint len, const void* vs, const void* u2 _U_)
+static void io_graph_sma_period_set_cb(void* rec, const char* buf, unsigned len, const void* vs, const void* u2 _U_)
{
- guint i;
+ unsigned i;
char* str = g_strndup(buf,len);
const char* cstr;
((io_graph_settings_t*)rec)->sma_period = 0;
@@ -202,7 +248,7 @@ static void io_graph_sma_period_set_cb(void* rec, const char* buf, guint len, co
for (i=0; (cstr = ((const value_string*)vs)[i].strptr) ;i++) {
if (g_str_equal(cstr,str)) {
- ((io_graph_settings_t*)rec)->sma_period = (guint32)((const value_string*)vs)[i].value;
+ ((io_graph_settings_t*)rec)->sma_period = (uint32_t)((const value_string*)vs)[i].value;
g_free(str);
return;
}
@@ -212,7 +258,7 @@ static void io_graph_sma_period_set_cb(void* rec, const char* buf, guint len, co
//Duplicated because macro covers both functions
static void io_graph_sma_period_tostr_cb(void* rec, char** out_ptr, unsigned* out_len, const void* vs, const void* u2 _U_)
{
- guint i;
+ unsigned i;
for (i=0;((const value_string*)vs)[i].strptr;i++) {
if (((const value_string*)vs)[i].value == ((io_graph_settings_t*)rec)->sma_period) {
*out_ptr = g_strdup(((const value_string*)vs)[i].strptr);
@@ -224,9 +270,9 @@ static void io_graph_sma_period_tostr_cb(void* rec, char** out_ptr, unsigned* ou
*out_len = (unsigned)strlen("None");
}
-static bool sma_period_chk_enum(void* u1 _U_, const char* strptr, guint len, const void* v, const void* u3 _U_, char** err) {
+static bool sma_period_chk_enum(void* u1 _U_, const char* strptr, unsigned len, const void* v, const void* u3 _U_, char** err) {
char *str = g_strndup(strptr,len);
- guint i;
+ unsigned i;
const value_string* vs = (const value_string *)v;
//Original UAT had just raw numbers and not enumerated values with "interval SMA"
@@ -246,13 +292,13 @@ static bool sma_period_chk_enum(void* u1 _U_, const char* strptr, guint len, con
if (g_strcmp0(vs[i].strptr,str) == 0) {
*err = NULL;
g_free(str);
- return TRUE;
+ return true;
}
}
*err = ws_strdup_printf("invalid value: %s",str);
g_free(str);
- return FALSE;
+ return false;
}
#define UAT_FLD_SMA_PERIOD(basename,field_name,title,enum,desc) \
@@ -263,18 +309,33 @@ UAT_BOOL_ENABLE_CB_DEF(io_graph, enabled, io_graph_settings_t)
UAT_CSTRING_CB_DEF(io_graph, name, io_graph_settings_t)
UAT_DISPLAY_FILTER_CB_DEF(io_graph, dfilter, io_graph_settings_t)
UAT_COLOR_CB_DEF(io_graph, color, io_graph_settings_t)
-UAT_VS_DEF(io_graph, style, io_graph_settings_t, guint32, 0, "Line")
-UAT_VS_DEF(io_graph, yaxis, io_graph_settings_t, guint32, 0, "Packets")
+UAT_VS_DEF(io_graph, style, io_graph_settings_t, uint32_t, 0, "Line")
+// XXX Need to use "Events" where appropriate.
+UAT_VS_DEF(io_graph, yaxis, io_graph_settings_t, uint32_t, 0, "Packets")
UAT_PROTO_FIELD_CB_DEF(io_graph, yfield, io_graph_settings_t)
UAT_DEC_CB_DEF(io_graph, y_axis_factor, io_graph_settings_t)
-static uat_field_t io_graph_fields[] = {
+static uat_field_t io_graph_packet_fields[] = {
+ UAT_FLD_BOOL_ENABLE(io_graph, enabled, "Enabled", "Graph visibility"),
+ UAT_FLD_CSTRING(io_graph, name, "Graph Name", "The name of the graph"),
+ UAT_FLD_DISPLAY_FILTER(io_graph, dfilter, "Display Filter", "Graph packets matching this display filter"),
+ UAT_FLD_COLOR(io_graph, color, "Color", "Graph color (#RRGGBB)"),
+ UAT_FLD_VS(io_graph, style, "Style", graph_style_vs, "Graph style (Line, Bars, etc.)"),
+ UAT_FLD_VS(io_graph, yaxis, "Y Axis", y_axis_packet_vs, "Y Axis units"),
+ UAT_FLD_PROTO_FIELD(io_graph, yfield, "Y Field", "Apply calculations to this field"),
+ UAT_FLD_SMA_PERIOD(io_graph, sma_period, "SMA Period", moving_avg_vs, "Simple moving average period"),
+ UAT_FLD_DEC(io_graph, y_axis_factor, "Y Axis Factor", "Y Axis Factor"),
+
+ UAT_END_FIELDS
+};
+
+static uat_field_t io_graph_event_fields[] = {
UAT_FLD_BOOL_ENABLE(io_graph, enabled, "Enabled", "Graph visibility"),
UAT_FLD_CSTRING(io_graph, name, "Graph Name", "The name of the graph"),
UAT_FLD_DISPLAY_FILTER(io_graph, dfilter, "Display Filter", "Graph packets matching this display filter"),
UAT_FLD_COLOR(io_graph, color, "Color", "Graph color (#RRGGBB)"),
UAT_FLD_VS(io_graph, style, "Style", graph_style_vs, "Graph style (Line, Bars, etc.)"),
- UAT_FLD_VS(io_graph, yaxis, "Y Axis", y_axis_vs, "Y Axis units"),
+ UAT_FLD_VS(io_graph, yaxis, "Y Axis", y_axis_event_vs, "Y Axis units"),
UAT_FLD_PROTO_FIELD(io_graph, yfield, "Y Field", "Apply calculations to this field"),
UAT_FLD_SMA_PERIOD(io_graph, sma_period, "SMA Period", moving_avg_vs, "Simple moving average period"),
UAT_FLD_DEC(io_graph, y_axis_factor, "Y Axis Factor", "Y Axis Factor"),
@@ -306,16 +367,25 @@ static void io_graph_free_cb(void* p) {
g_free(iogs->yfield);
}
+// If the uat changes outside the model, e.g. when changing profiles,
+// we need to tell the UatModel.
+static void io_graph_post_update_cb() {
+ if (static_uat_model_) {
+ static_uat_model_->reloadUat();
+ }
+}
+
} // extern "C"
-IOGraphDialog::IOGraphDialog(QWidget &parent, CaptureFile &cf, QString displayFilter) :
+IOGraphDialog::IOGraphDialog(QWidget &parent, CaptureFile &cf, QString displayFilter,
+ io_graph_item_unit_t value_units, QString yfield) :
WiresharkDialog(parent, cf),
ui(new Ui::IOGraphDialog),
uat_model_(nullptr),
uat_delegate_(nullptr),
base_graph_(nullptr),
tracer_(nullptr),
- start_time_(0.0),
+ start_time_(NSTIME_INIT_ZERO),
mouse_drags_(true),
rubber_band_(nullptr),
stat_timer_(nullptr),
@@ -355,15 +425,17 @@ IOGraphDialog::IOGraphDialog(QWidget &parent, CaptureFile &cf, QString displayFi
QPushButton *copy_bt = ui->buttonBox->addButton(tr("Copy"), QDialogButtonBox::ActionRole);
connect (copy_bt, SIGNAL(clicked()), this, SLOT(copyAsCsvClicked()));
- CopyFromProfileButton * copy_button = new CopyFromProfileButton(this, "io_graphs", tr("Copy graphs from another profile."));
- ui->buttonBox->addButton(copy_button, QDialogButtonBox::ActionRole);
- connect(copy_button, &CopyFromProfileButton::copyProfile, this, &IOGraphDialog::copyFromProfile);
+ copy_profile_bt_ = new CopyFromProfileButton(this, "io_graphs", tr("Copy graphs from another profile."));
+ ui->buttonBox->addButton(copy_profile_bt_, QDialogButtonBox::ActionRole);
+ connect(copy_profile_bt_, &CopyFromProfileButton::copyProfile, this, &IOGraphDialog::copyFromProfile);
QPushButton *close_bt = ui->buttonBox->button(QDialogButtonBox::Close);
if (close_bt) {
close_bt->setDefault(true);
}
+ connect(ui->buttonBox, &QDialogButtonBox::clicked, this, &IOGraphDialog::buttonBoxClicked);
+
ui->automaticUpdateCheckBox->setChecked(prefs.gui_io_graph_automatic_update ? true : false);
ui->enableLegendCheckBox->setChecked(prefs.gui_io_graph_enable_legend ? true : false);
@@ -373,22 +445,38 @@ IOGraphDialog::IOGraphDialog(QWidget &parent, CaptureFile &cf, QString displayFi
stat_timer_->start(stat_update_interval_);
// Intervals (ms)
- ui->intervalComboBox->addItem(tr("1 ms"), 1);
- ui->intervalComboBox->addItem(tr("2 ms"), 2);
- ui->intervalComboBox->addItem(tr("5 ms"), 5);
- ui->intervalComboBox->addItem(tr("10 ms"), 10);
- ui->intervalComboBox->addItem(tr("20 ms"), 20);
- ui->intervalComboBox->addItem(tr("50 ms"), 50);
- ui->intervalComboBox->addItem(tr("100 ms"), 100);
- ui->intervalComboBox->addItem(tr("200 ms"), 200);
- ui->intervalComboBox->addItem(tr("500 ms"), 500);
- ui->intervalComboBox->addItem(tr("1 sec"), 1000);
- ui->intervalComboBox->addItem(tr("2 sec"), 2000);
- ui->intervalComboBox->addItem(tr("5 sec"), 5000);
- ui->intervalComboBox->addItem(tr("10 sec"), 10000);
- ui->intervalComboBox->addItem(tr("1 min"), 60000);
- ui->intervalComboBox->addItem(tr("10 min"), 600000);
- ui->intervalComboBox->setCurrentIndex(9);
+ // #6441 asks for arbitrary values. We could probably do that with
+ // a QSpinBox, e.g. using QAbstractSpinBox::AdaptiveDecimalStepType
+ // or similar (it only exists starting in Qt 5.12) and suffix(),
+ // or something fancier with valueFromText() and textFromValue() to
+ // convert to and from SI prefixes.
+ ui->intervalComboBox->addItem(tr("1 μs"), SCALE / 1000000);
+ ui->intervalComboBox->addItem(tr("2 μs"), SCALE / 500000);
+ ui->intervalComboBox->addItem(tr("5 μs"), SCALE / 200000);
+ ui->intervalComboBox->addItem(tr("10 μs"), SCALE / 100000);
+ ui->intervalComboBox->addItem(tr("20 μs"), SCALE / 50000);
+ ui->intervalComboBox->addItem(tr("50 μs"), SCALE / 20000);
+ ui->intervalComboBox->addItem(tr("100 μs"), SCALE / 10000);
+ ui->intervalComboBox->addItem(tr("200 μs"), SCALE / 5000);
+ ui->intervalComboBox->addItem(tr("500 μs"), SCALE / 2000);
+ ui->intervalComboBox->addItem(tr("1 ms"), SCALE / 1000);
+ ui->intervalComboBox->addItem(tr("2 ms"), SCALE / 500);
+ ui->intervalComboBox->addItem(tr("5 ms"), SCALE / 200);
+ ui->intervalComboBox->addItem(tr("10 ms"), SCALE / 100);
+ ui->intervalComboBox->addItem(tr("20 ms"), SCALE / 50);
+ ui->intervalComboBox->addItem(tr("50 ms"), SCALE / 20);
+ ui->intervalComboBox->addItem(tr("100 ms"), SCALE / 10);
+ ui->intervalComboBox->addItem(tr("200 ms"), SCALE / 5);
+ ui->intervalComboBox->addItem(tr("500 ms"), SCALE / 2);
+ ui->intervalComboBox->addItem(tr("1 sec"), SCALE);
+ ui->intervalComboBox->addItem(tr("2 sec"), SCALE * 2);
+ ui->intervalComboBox->addItem(tr("5 sec"), SCALE * 5);
+ ui->intervalComboBox->addItem(tr("10 sec"), SCALE * 10);
+ ui->intervalComboBox->addItem(tr("1 min"), SCALE * 60);
+ ui->intervalComboBox->addItem(tr("2 min"), SCALE * 120);
+ ui->intervalComboBox->addItem(tr("5 min"), SCALE * 300);
+ ui->intervalComboBox->addItem(tr("10 min"), SCALE * 600);
+ ui->intervalComboBox->setCurrentIndex(18);
ui->todCheckBox->setChecked(false);
iop->xAxis->setTicker(number_ticker_);
@@ -419,6 +507,9 @@ IOGraphDialog::IOGraphDialog(QWidget &parent, CaptureFile &cf, QString displayFi
ctx_menu_.addAction(ui->actionCrosshairs);
set_action_shortcuts_visible_in_context_menu(ctx_menu_.actions());
+ iop->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(iop, &QCustomPlot::customContextMenuRequested, this, &IOGraphDialog::showContextMenu);
+
iop->xAxis->setLabel(tr("Time (s)"));
iop->setMouseTracking(true);
@@ -433,22 +524,23 @@ IOGraphDialog::IOGraphDialog(QWidget &parent, CaptureFile &cf, QString displayFi
loadProfileGraphs();
bool filterExists = false;
- QString graph_name = is_packet_configuration_namespace() ? tr("Filtered packets") : tr("Filtered events");
if (uat_model_->rowCount() > 0) {
for (int i = 0; i < uat_model_->rowCount(); i++) {
createIOGraph(i);
- if (ioGraphs_.at(i)->filter().compare(displayFilter) == 0)
+ IOGraph *iog = ioGraphs_.at(i);
+ if (iog->filter().compare(displayFilter) == 0 &&
+ iog->valueUnitField().compare(yfield) == 0 &&
+ iog->valueUnits() == value_units) {
filterExists = true;
+ }
}
- if (! filterExists && displayFilter.length() > 0)
- addGraph(true, graph_name, displayFilter, ColorUtils::graphColor(uat_model_->rowCount()),
- IOGraph::psLine, IOG_ITEM_UNIT_PACKETS, QString(), DEFAULT_MOVING_AVERAGE, DEFAULT_Y_AXIS_FACTOR);
} else {
addDefaultGraph(true, 0);
addDefaultGraph(true, 1);
- if (displayFilter.length() > 0)
- addGraph(true, graph_name, displayFilter, ColorUtils::graphColor(uat_model_->rowCount()),
- IOGraph::psLine, IOG_ITEM_UNIT_PACKETS, QString(), DEFAULT_MOVING_AVERAGE, DEFAULT_Y_AXIS_FACTOR);
+ }
+
+ if (! filterExists && (!displayFilter.isEmpty() || !yfield.isEmpty())) {
+ addGraph(true, displayFilter, value_units, yfield);
}
toggleTracerStyle(true);
@@ -460,14 +552,23 @@ IOGraphDialog::IOGraphDialog(QWidget &parent, CaptureFile &cf, QString displayFi
ui->splitter->setStretchFactor(0, 95);
ui->splitter->setStretchFactor(1, 5);
+ loadSplitterState(ui->splitter);
//XXX - resize columns?
+ //ui->graphUat->header()->resizeSections(QHeaderView::ResizeToContents);
ProgressFrame::addToButtonBox(ui->buttonBox, &parent);
connect(iop, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(graphClicked(QMouseEvent*)));
connect(iop, SIGNAL(mouseMove(QMouseEvent*)), this, SLOT(mouseMoved(QMouseEvent*)));
connect(iop, SIGNAL(mouseRelease(QMouseEvent*)), this, SLOT(mouseReleased(QMouseEvent*)));
+
+ connect(iop, &QCustomPlot::beforeReplot, this, &IOGraphDialog::updateLegend);
+
+ MainWindow *main_window = qobject_cast<MainWindow *>(mainApp->mainWindow());
+ if (main_window != nullptr) {
+ connect(main_window, &MainWindow::framesSelected, this, &IOGraphDialog::selectedFrameChanged);
+ }
}
IOGraphDialog::~IOGraphDialog()
@@ -482,15 +583,18 @@ IOGraphDialog::~IOGraphDialog()
void IOGraphDialog::copyFromProfile(QString filename)
{
- guint orig_data_len = iog_uat_->raw_data->len;
+ if (uat_model_ == nullptr)
+ return;
- gchar *err = NULL;
+ char *err = NULL;
+ // uat_load appends rows to the current UAT, using filename.
+ // We should let the UatModel handle it, and have the UatModel
+ // call beginInsertRows() and endInsertRows(), so that we can
+ // just add the new rows instead of resetting the information.
if (uat_load(iog_uat_, filename.toUtf8().constData(), &err)) {
- iog_uat_->changed = TRUE;
- uat_model_->reloadUat();
- for (guint i = orig_data_len; i < iog_uat_->raw_data->len; i++) {
- createIOGraph(i);
- }
+ iog_uat_->changed = true;
+ // uat_load calls the post update cb, which reloads the Uat.
+ //uat_model_->reloadUat();
} else {
report_failure("Error while loading %s: %s", iog_uat_->name, err);
g_free(err);
@@ -499,6 +603,8 @@ void IOGraphDialog::copyFromProfile(QString filename)
void IOGraphDialog::addGraph(bool checked, QString name, QString dfilter, QRgb color_idx, IOGraph::PlotStyles style, io_graph_item_unit_t value_units, QString yfield, int moving_average, int y_axis_factor)
{
+ if (uat_model_ == nullptr)
+ return;
QVariantList newRowData;
newRowData.append(checked ? Qt::Checked : Qt::Unchecked);
@@ -507,12 +613,12 @@ void IOGraphDialog::addGraph(bool checked, QString name, QString dfilter, QRgb c
newRowData.append(QColor(color_idx));
newRowData.append(val_to_str_const(style, graph_style_vs, "None"));
if (is_packet_configuration_namespace()) {
- newRowData.append(val_to_str_const(value_units, y_axis_vs, "Packets"));
+ newRowData.append(val_to_str_const(value_units, y_axis_packet_vs, "Packets"));
} else {
- newRowData.append(val_to_str_const(value_units, y_axis_vs, "Events"));
+ newRowData.append(val_to_str_const(value_units, y_axis_event_vs, "Events"));
}
newRowData.append(yfield);
- newRowData.append(val_to_str_const((guint32) moving_average, moving_avg_vs, "None"));
+ newRowData.append(val_to_str_const((uint32_t) moving_average, moving_avg_vs, "None"));
newRowData.append(y_axis_factor);
QModelIndex newIndex = uat_model_->appendEntry(newRowData);
@@ -522,11 +628,36 @@ void IOGraphDialog::addGraph(bool checked, QString name, QString dfilter, QRgb c
return;
}
ui->graphUat->setCurrentIndex(newIndex);
- createIOGraph(newIndex.row());
+}
+
+void IOGraphDialog::addGraph(bool checked, QString dfilter, io_graph_item_unit_t value_units, QString yfield)
+{
+ if (uat_model_ == nullptr)
+ return;
+
+ QString graph_name;
+ if (yfield.isEmpty()) {
+ if (!dfilter.isEmpty()) {
+ graph_name = is_packet_configuration_namespace() ? tr("Filtered packets") : tr("Filtered events");
+ } else {
+ graph_name = is_packet_configuration_namespace() ? tr("All packets") : tr("All events");
+ }
+ } else {
+ if (is_packet_configuration_namespace()) {
+ graph_name = QString(val_to_str_const(value_units, y_axis_packet_vs, "Unknown")).replace("Y Field", yfield);
+ } else {
+ graph_name = QString(val_to_str_const(value_units, y_axis_event_vs, "Unknown")).replace("Y Field", yfield);
+ }
+ }
+ addGraph(checked, std::move(graph_name), dfilter, ColorUtils::graphColor(uat_model_->rowCount()),
+ IOGraph::psLine, value_units, yfield, DEFAULT_MOVING_AVERAGE, DEFAULT_Y_AXIS_FACTOR);
}
void IOGraphDialog::addGraph(bool copy_from_current)
{
+ if (uat_model_ == nullptr)
+ return;
+
const QModelIndex &current = ui->graphUat->currentIndex();
if (copy_from_current && !current.isValid())
return;
@@ -540,8 +671,6 @@ void IOGraphDialog::addGraph(bool copy_from_current)
qDebug() << "Failed to add a new record";
return;
}
- createIOGraph(copyIdx.row());
-
ui->graphUat->setCurrentIndex(copyIdx);
} else {
addDefaultGraph(false);
@@ -553,22 +682,19 @@ void IOGraphDialog::addGraph(bool copy_from_current)
void IOGraphDialog::createIOGraph(int currentRow)
{
- // XXX - Should IOGraph have it's own list that has to sync with UAT?
- ioGraphs_.append(new IOGraph(ui->ioPlot));
+ // XXX - Should IOGraph have its own list that has to sync with UAT?
+ ioGraphs_.insert(currentRow, new IOGraph(ui->ioPlot));
IOGraph* iog = ioGraphs_[currentRow];
- connect(this, SIGNAL(recalcGraphData(capture_file *, bool)), iog, SLOT(recalcGraphData(capture_file *, bool)));
- connect(this, SIGNAL(reloadValueUnitFields()), iog, SLOT(reloadValueUnitField()));
- connect(&cap_file_, SIGNAL(captureEvent(CaptureEvent)),
- iog, SLOT(captureEvent(CaptureEvent)));
- connect(iog, SIGNAL(requestRetap()), this, SLOT(scheduleRetap()));
- connect(iog, SIGNAL(requestRecalc()), this, SLOT(scheduleRecalc()));
- connect(iog, SIGNAL(requestReplot()), this, SLOT(scheduleReplot()));
+ connect(this, &IOGraphDialog::recalcGraphData, iog, &IOGraph::recalcGraphData);
+ connect(this, &IOGraphDialog::reloadValueUnitFields, iog, &IOGraph::reloadValueUnitField);
+ connect(&cap_file_, &CaptureFile::captureEvent, iog, &IOGraph::captureEvent);
+ connect(iog, &IOGraph::requestRetap, this, [=]() { scheduleRetap(); });
+ connect(iog, &IOGraph::requestRecalc, this, [=]() { scheduleRecalc(); });
+ connect(iog, &IOGraph::requestReplot, this, [=]() { scheduleReplot(); });
syncGraphSettings(currentRow);
- if (iog->visible()) {
- scheduleRetap();
- }
+ iog->setNeedRetap(true);
}
void IOGraphDialog::addDefaultGraph(bool enabled, int idx)
@@ -591,7 +717,7 @@ void IOGraphDialog::addDefaultGraph(bool enabled, int idx)
IOGraph::psLine, IOG_ITEM_UNIT_PACKETS, QString(), DEFAULT_MOVING_AVERAGE, DEFAULT_Y_AXIS_FACTOR);
break;
default:
- addGraph(enabled, tr("Access Denied"), "ct.error == \"AccessDenied\"", ColorUtils::graphColor(4), // 4 = red
+ addGraph(enabled, tr("All Execs"), "evt.type == \"execve\"", ColorUtils::graphColor(4), // 4 = red
IOGraph::psDot, IOG_ITEM_UNIT_PACKETS, QString(), DEFAULT_MOVING_AVERAGE, DEFAULT_Y_AXIS_FACTOR);
break;
}
@@ -613,11 +739,10 @@ void IOGraphDialog::syncGraphSettings(int row)
{
IOGraph *iog = ioGraphs_.value(row, Q_NULLPTR);
- if (!uat_model_->index(row, colEnabled).isValid() || !iog)
+ if (!uat_model_ || !uat_model_->index(row, colEnabled).isValid() || !iog)
return;
bool visible = graphIsEnabled(row);
- bool retap = !iog->visible() && visible;
QString data_str;
iog->setName(uat_model_->data(uat_model_->index(row, colName)).toString());
@@ -625,7 +750,11 @@ void IOGraphDialog::syncGraphSettings(int row)
/* plot style depend on the value unit, so set it first. */
data_str = uat_model_->data(uat_model_->index(row, colYAxis)).toString();
- iog->setValueUnits((int) str_to_val(qUtf8Printable(data_str), y_axis_vs, IOG_ITEM_UNIT_PACKETS));
+ if (is_packet_configuration_namespace()) {
+ iog->setValueUnits((int) str_to_val(qUtf8Printable(data_str), y_axis_packet_vs, IOG_ITEM_UNIT_PACKETS));
+ } else {
+ iog->setValueUnits((int) str_to_val(qUtf8Printable(data_str), y_axis_event_vs, IOG_ITEM_UNIT_PACKETS));
+ }
iog->setValueUnitField(uat_model_->data(uat_model_->index(row, colYField)).toString());
iog->setColor(uat_model_->data(uat_model_->index(row, colColor), Qt::DecorationRole).value<QColor>().rgb());
@@ -642,7 +771,6 @@ void IOGraphDialog::syncGraphSettings(int row)
if (!iog->configError().isEmpty()) {
hint_err_ = iog->configError();
visible = false;
- retap = false;
} else {
hint_err_.clear();
}
@@ -650,18 +778,18 @@ void IOGraphDialog::syncGraphSettings(int row)
iog->setVisible(visible);
getGraphInfo();
- mouseMoved(NULL); // Update hint
- updateLegend();
+ updateHint();
if (visible) {
- if (retap) {
- scheduleRetap();
- } else {
- scheduleReplot();
- }
+ scheduleReplot();
}
}
+qsizetype IOGraphDialog::graphCount() const
+{
+ return uat_model_ ? uat_model_->rowCount() : ioGraphs_.size();
+}
+
void IOGraphDialog::updateWidgets()
{
WiresharkDialog::updateWidgets();
@@ -671,9 +799,6 @@ void IOGraphDialog::scheduleReplot(bool now)
{
need_replot_ = true;
if (now) updateStatistics();
- // A plot finished, force an update of the legend now in case a time unit
- // was involved (which might append "(ms)" to the label).
- updateLegend();
}
void IOGraphDialog::scheduleRecalc(bool now)
@@ -693,6 +818,27 @@ void IOGraphDialog::reloadFields()
emit reloadValueUnitFields();
}
+void IOGraphDialog::captureFileClosing()
+{
+ // The other buttons will be disabled when the model is set to null.
+ ui->newToolButton->setEnabled(false);
+ ui->intervalComboBox->setEnabled(false);
+ copy_profile_bt_->setEnabled(false);
+ if (uat_model_) {
+ applyChanges();
+ disconnect(uat_model_, nullptr, this, nullptr);
+ }
+ // It would be nice to keep the information in the UAT about the graphs
+ // visible in a read-only state after closing, but if the view is just
+ // disabled, updating the model from elsewhere (e.g., other dialogs)
+ // will still change it, so we'd need to copy the information into
+ // a new model.
+ uat_model_ = nullptr;
+ ui->graphUat->setModel(nullptr);
+ ui->graphUat->setVisible(false);
+ WiresharkDialog::captureFileClosing();
+}
+
void IOGraphDialog::keyPressEvent(QKeyEvent *event)
{
int pan_pixels = event->modifiers() & Qt::ShiftModifier ? 1 : 10;
@@ -764,19 +910,25 @@ void IOGraphDialog::keyPressEvent(QKeyEvent *event)
QDialog::keyPressEvent(event);
}
-void IOGraphDialog::reject()
+void IOGraphDialog::applyChanges()
{
- if (!uat_model_)
+ if (!static_uat_model_)
return;
// Changes to the I/O Graphs settings are always saved,
// there is no possibility for "rejection".
QString error;
- if (uat_model_->applyChanges(error)) {
+ if (static_uat_model_->applyChanges(error)) {
if (!error.isEmpty()) {
report_failure("%s", qPrintable(error));
}
}
+}
+
+void IOGraphDialog::reject()
+{
+ if (uat_model_)
+ applyChanges();
QDialog::reject();
}
@@ -881,12 +1033,12 @@ void IOGraphDialog::toggleTracerStyle(bool force_default)
IOGraph *IOGraphDialog::currentActiveGraph() const
{
QModelIndex index = ui->graphUat->currentIndex();
- if (index.isValid()) {
+ if (index.isValid() && graphIsEnabled(index.row())) {
return ioGraphs_.value(index.row(), NULL);
}
//if no currently selected item, go with first item enabled
- for (int row = 0; row < uat_model_->rowCount(); row++)
+ for (int row = 0; row < graphCount(); row++)
{
if (graphIsEnabled(row)) {
return ioGraphs_.value(row, NULL);
@@ -898,8 +1050,13 @@ IOGraph *IOGraphDialog::currentActiveGraph() const
bool IOGraphDialog::graphIsEnabled(int row) const
{
- Qt::CheckState state = static_cast<Qt::CheckState>(uat_model_->data(uat_model_->index(row, colEnabled), Qt::CheckStateRole).toInt());
- return state == Qt::Checked;
+ if (uat_model_) {
+ Qt::CheckState state = static_cast<Qt::CheckState>(uat_model_->data(uat_model_->index(row, colEnabled), Qt::CheckStateRole).toInt());
+ return state == Qt::Checked;
+ } else {
+ IOGraph* iog = ioGraphs_.value(row, nullptr);
+ return (iog && iog->visible());
+ }
}
// Scan through our graphs and gather information.
@@ -909,7 +1066,7 @@ void IOGraphDialog::getGraphInfo()
{
base_graph_ = NULL;
QCPBars *prev_bars = NULL;
- start_time_ = 0.0;
+ nstime_set_zero(&start_time_);
tracer_->setGraph(NULL);
IOGraph *selectedGraph = currentActiveGraph();
@@ -931,9 +1088,9 @@ void IOGraphDialog::getGraphInfo()
prev_bars = bars;
}
if (iog->visible() && iog->maxInterval() >= 0) {
- double iog_start = iog->startOffset();
- if (start_time_ == 0.0 || iog_start < start_time_) {
- start_time_ = iog_start;
+ nstime_t iog_start = iog->startTime();
+ if (nstime_is_zero(&start_time_) || nstime_cmp(&iog_start, &start_time_) < 0) {
+ nstime_copy(&start_time_, &iog_start);
}
}
@@ -946,9 +1103,78 @@ void IOGraphDialog::getGraphInfo()
}
}
+void IOGraphDialog::updateHint()
+{
+ QCustomPlot *iop = ui->ioPlot;
+ QString hint;
+
+ // XXX: ElidedLabel doesn't support rich text / HTML, we
+ // used to bold this error
+ if (!hint_err_.isEmpty()) {
+ hint += QString("%1 ").arg(hint_err_);
+ }
+ if (mouse_drags_) {
+ double ts = 0;
+ packet_num_ = 0;
+ int interval_packet = -1;
+
+ if (tracer_->graph()) {
+ ts = tracer_->position->key();
+ if (IOGraph *iog = currentActiveGraph()) {
+ interval_packet = iog->packetFromTime(ts - nstime_to_sec(&start_time_));
+ }
+ }
+
+ if (interval_packet < 0) {
+ hint += tr("Hover over the graph for details.");
+ } else {
+ QString msg = is_packet_configuration_namespace() ? tr("No packets in interval") : tr("No events in interval");
+ QString val;
+ if (interval_packet > 0) {
+ packet_num_ = (uint32_t) interval_packet;
+ if (is_packet_configuration_namespace()) {
+ msg = QString("%1 %2")
+ .arg(!file_closed_ ? tr("Click to select packet") : tr("Packet"))
+ .arg(packet_num_);
+ } else {
+ msg = QString("%1 %2")
+ .arg(!file_closed_ ? tr("Click to select event") : tr("Event"))
+ .arg(packet_num_);
+ }
+ val = " = " + QString::number(tracer_->position->value(), 'g', 4);
+ }
+ // XXX - If Time of Day is selected, should we use ISO 8601
+ // timestamps or something similar here instead of epoch time?
+ hint += tr("%1 (%2s%3).")
+ .arg(msg)
+ .arg(QString::number(ts, 'f', precision_))
+ .arg(val);
+ }
+ iop->replot(QCustomPlot::rpQueuedReplot);
+ } else {
+ if (rubber_band_ && rubber_band_->isVisible()) {
+ QRectF zoom_ranges = getZoomRanges(rubber_band_->geometry());
+ if (zoom_ranges.width() > 0.0 && zoom_ranges.height() > 0.0) {
+ hint += tr("Release to zoom, x = %1 to %2, y = %3 to %4")
+ .arg(zoom_ranges.x())
+ .arg(zoom_ranges.x() + zoom_ranges.width())
+ .arg(zoom_ranges.y())
+ .arg(zoom_ranges.y() + zoom_ranges.height());
+ } else {
+ hint += tr("Unable to select range.");
+ }
+ } else {
+ hint += tr("Click to select a portion of the graph.");
+ }
+ }
+
+ ui->hintLabel->setText(hint);
+}
+
void IOGraphDialog::updateLegend()
{
QCustomPlot *iop = ui->ioPlot;
+ QSet<format_size_units_e> format_units_set;
QSet<QString> vu_label_set;
QString intervalText = ui->intervalComboBox->itemText(ui->intervalComboBox->currentIndex());
@@ -956,49 +1182,60 @@ void IOGraphDialog::updateLegend()
iop->yAxis->setLabel(QString());
// Find unique labels
- if (uat_model_ != NULL) {
- for (int row = 0; row < uat_model_->rowCount(); row++) {
- IOGraph *iog = ioGraphs_.value(row, Q_NULLPTR);
- if (graphIsEnabled(row) && iog) {
- QString label(iog->valueUnitLabel());
- if (!iog->scaledValueUnit().isEmpty()) {
- label += " (" + iog->scaledValueUnit() + ")";
- }
- vu_label_set.insert(label);
- }
+ for (int row = 0; row < graphCount(); row++) {
+ IOGraph *iog = ioGraphs_.value(row, Q_NULLPTR);
+ if (graphIsEnabled(row) && iog) {
+ QString label(iog->valueUnitLabel());
+ vu_label_set.insert(label);
+ format_units_set.insert(iog->formatUnits());
}
}
// Nothing.
if (vu_label_set.size() < 1) {
+ iop->legend->layer()->replot();
return;
}
+ format_size_units_e format_units = FORMAT_SIZE_UNIT_NONE;
+ if (format_units_set.size() == 1) {
+ format_units = format_units_set.values().constFirst();
+ }
+
+ QSharedPointer<QCPAxisTickerSi> si_ticker = qSharedPointerDynamicCast<QCPAxisTickerSi>(iop->yAxis->ticker());
+ if (format_units != FORMAT_SIZE_UNIT_NONE) {
+ if (si_ticker) {
+ si_ticker->setUnit(format_units);
+ } else {
+ iop->yAxis->setTicker(QSharedPointer<QCPAxisTickerSi>(new QCPAxisTickerSi(format_units, QString(), ui->logCheckBox->isChecked())));
+ }
+ } else {
+ if (si_ticker) {
+ if (ui->logCheckBox->isChecked()) {
+ iop->yAxis->setTicker(QSharedPointer<QCPAxisTickerLog>(new QCPAxisTickerLog));
+ } else {
+ iop->yAxis->setTicker(QSharedPointer<QCPAxisTicker>(new QCPAxisTicker));
+ }
+ }
+ }
+
// All the same. Use the Y Axis label.
if (vu_label_set.size() == 1) {
- iop->yAxis->setLabel(vu_label_set.values()[0] + "/" + intervalText);
- return;
+ iop->yAxis->setLabel(vu_label_set.values().constFirst() + "/" + intervalText);
}
- // Differing labels. Create a legend with a Title label at top.
+ // Create a legend with a Title label at top.
// Legend Title thanks to: https://www.qcustomplot.com/index.php/support/forum/443
- QCPTextElement* legendTitle = qobject_cast<QCPTextElement*>(iop->legend->elementAt(0));
- if (legendTitle == NULL) {
- legendTitle = new QCPTextElement(iop, QString(""));
- iop->legend->insertRow(0);
- iop->legend->addElement(0, 0, legendTitle);
- }
- legendTitle->setText(QString(intervalText + " Intervals "));
-
- if (uat_model_ != NULL) {
- for (int row = 0; row < uat_model_->rowCount(); row++) {
- IOGraph *iog = ioGraphs_.value(row, Q_NULLPTR);
- if (iog) {
- if (graphIsEnabled(row)) {
- iog->addToLegend();
- } else {
- iog->removeFromLegend();
- }
+ iop->legend->clearItems();
+ QCPStringLegendItem *legendTitle = new QCPStringLegendItem(iop->legend, QString(tr("%1 Intervals ").arg(intervalText)));
+ iop->legend->insertRow(0);
+ iop->legend->addElement(0, 0, legendTitle);
+
+ for (int row = 0; row < graphCount(); row++) {
+ IOGraph *iog = ioGraphs_.value(row, Q_NULLPTR);
+ if (iog) {
+ if (graphIsEnabled(row)) {
+ iog->addToLegend();
}
}
}
@@ -1037,19 +1274,37 @@ QRectF IOGraphDialog::getZoomRanges(QRect zoom_rect)
return zoom_ranges;
}
+void IOGraphDialog::showContextMenu(const QPoint &pos)
+{
+ if (ui->ioPlot->legend->selectTest(pos, false) >= 0) {
+ QMenu *menu = new QMenu(this);
+ menu->setAttribute(Qt::WA_DeleteOnClose);
+#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
+ menu->addAction(tr("Move to top left"), this, &IOGraphDialog::moveLegend)->setData((Qt::AlignTop|Qt::AlignLeft).toInt());
+ menu->addAction(tr("Move to top center"), this, &IOGraphDialog::moveLegend)->setData((Qt::AlignTop|Qt::AlignHCenter).toInt());
+ menu->addAction(tr("Move to top right"), this, &IOGraphDialog::moveLegend)->setData((Qt::AlignTop|Qt::AlignRight).toInt());
+ menu->addAction(tr("Move to bottom left"), this, &IOGraphDialog::moveLegend)->setData((Qt::AlignBottom|Qt::AlignLeft).toInt());
+ menu->addAction(tr("Move to bottom center"), this, &IOGraphDialog::moveLegend)->setData((Qt::AlignBottom|Qt::AlignHCenter).toInt());
+ menu->addAction(tr("Move to bottom right"), this, &IOGraphDialog::moveLegend)->setData((Qt::AlignBottom|Qt::AlignRight).toInt());
+#else
+ menu->addAction(tr("Move to top left"), this, &IOGraphDialog::moveLegend)->setData(static_cast<Qt::Alignment::Int>(Qt::AlignTop|Qt::AlignLeft));
+ menu->addAction(tr("Move to top center"), this, &IOGraphDialog::moveLegend)->setData(static_cast<Qt::Alignment::Int>(Qt::AlignTop|Qt::AlignHCenter));
+ menu->addAction(tr("Move to top right"), this, &IOGraphDialog::moveLegend)->setData(static_cast<Qt::Alignment::Int>(Qt::AlignTop|Qt::AlignRight));
+ menu->addAction(tr("Move to bottom left"), this, &IOGraphDialog::moveLegend)->setData(static_cast<Qt::Alignment::Int>(Qt::AlignBottom|Qt::AlignLeft));
+ menu->addAction(tr("Move to bottom center"), this, &IOGraphDialog::moveLegend)->setData(static_cast<Qt::Alignment::Int>(Qt::AlignBottom|Qt::AlignHCenter));
+ menu->addAction(tr("Move to bottom right"), this, &IOGraphDialog::moveLegend)->setData(static_cast<Qt::Alignment::Int>(Qt::AlignBottom|Qt::AlignRight));
+#endif
+ menu->popup(ui->ioPlot->mapToGlobal(pos));
+ } else {
+ ctx_menu_.popup(ui->ioPlot->mapToGlobal(pos));
+ }
+}
+
void IOGraphDialog::graphClicked(QMouseEvent *event)
{
QCustomPlot *iop = ui->ioPlot;
- if (event->button() == Qt::RightButton) {
- // XXX We should find some way to get ioPlot to handle a
- // contextMenuEvent instead.
-#if QT_VERSION >= QT_VERSION_CHECK(6, 0 ,0)
- ctx_menu_.popup(event->globalPosition().toPoint());
-#else
- ctx_menu_.popup(event->globalPos());
-#endif
- } else if (mouse_drags_) {
+ if (mouse_drags_) {
if (iop->axisRect()->rect().contains(event->pos())) {
iop->setCursor(QCursor(Qt::ClosedHandCursor));
}
@@ -1068,87 +1323,35 @@ void IOGraphDialog::graphClicked(QMouseEvent *event)
void IOGraphDialog::mouseMoved(QMouseEvent *event)
{
QCustomPlot *iop = ui->ioPlot;
- QString hint;
Qt::CursorShape shape = Qt::ArrowCursor;
- // XXX: ElidedLabel doesn't support rich text / HTML, we
- // used to bold this error
- if (!hint_err_.isEmpty()) {
- hint += QString("%1 ").arg(hint_err_);
- }
- if (event) {
- if (event->buttons().testFlag(Qt::LeftButton)) {
- if (mouse_drags_) {
- shape = Qt::ClosedHandCursor;
- } else {
- shape = Qt::CrossCursor;
- }
- } else if (iop->axisRect()->rect().contains(event->pos())) {
- if (mouse_drags_) {
- shape = Qt::OpenHandCursor;
- } else {
- shape = Qt::CrossCursor;
- }
+ if (event->buttons().testFlag(Qt::LeftButton)) {
+ if (mouse_drags_) {
+ shape = Qt::ClosedHandCursor;
+ } else {
+ shape = Qt::CrossCursor;
+ }
+ } else if (iop->axisRect()->rect().contains(event->pos())) {
+ if (mouse_drags_) {
+ shape = Qt::OpenHandCursor;
+ } else {
+ shape = Qt::CrossCursor;
}
- iop->setCursor(QCursor(shape));
}
+ iop->setCursor(QCursor(shape));
if (mouse_drags_) {
- double ts = 0;
- packet_num_ = 0;
- int interval_packet = -1;
-
- if (event && tracer_->graph()) {
+ if (tracer_->graph()) {
tracer_->setGraphKey(iop->xAxis->pixelToCoord(event->pos().x()));
- ts = tracer_->position->key();
- if (IOGraph *iog = currentActiveGraph()) {
- interval_packet = iog->packetFromTime(ts - start_time_);
- }
}
- if (interval_packet < 0) {
- hint += tr("Hover over the graph for details.");
- } else {
- QString msg = is_packet_configuration_namespace() ? tr("No packets in interval") : tr("No events in interval");
- QString val;
- if (interval_packet > 0) {
- packet_num_ = (guint32) interval_packet;
- if (is_packet_configuration_namespace()) {
- msg = QString("%1 %2")
- .arg(!file_closed_ ? tr("Click to select packet") : tr("Packet"))
- .arg(packet_num_);
- } else {
- msg = QString("%1 %2")
- .arg(!file_closed_ ? tr("Click to select event") : tr("Event"))
- .arg(packet_num_);
- }
- val = " = " + QString::number(tracer_->position->value(), 'g', 4);
- }
- hint += tr("%1 (%2s%3).")
- .arg(msg)
- .arg(QString::number(ts, 'g', 4))
- .arg(val);
- }
- iop->replot();
} else {
- if (event && rubber_band_ && rubber_band_->isVisible()) {
+ if (rubber_band_ && rubber_band_->isVisible()) {
rubber_band_->setGeometry(QRect(rb_origin_, event->pos()).normalized());
- QRectF zoom_ranges = getZoomRanges(QRect(rb_origin_, event->pos()));
- if (zoom_ranges.width() > 0.0 && zoom_ranges.height() > 0.0) {
- hint += tr("Release to zoom, x = %1 to %2, y = %3 to %4")
- .arg(zoom_ranges.x())
- .arg(zoom_ranges.x() + zoom_ranges.width())
- .arg(zoom_ranges.y())
- .arg(zoom_ranges.y() + zoom_ranges.height());
- } else {
- hint += tr("Unable to select range.");
- }
- } else {
- hint += tr("Click to select a portion of the graph.");
}
}
- ui->hintLabel->setText(hint);
+ updateHint();
}
void IOGraphDialog::mouseReleased(QMouseEvent *event)
@@ -1172,51 +1375,99 @@ void IOGraphDialog::mouseReleased(QMouseEvent *event)
}
}
+void IOGraphDialog::moveLegend()
+{
+ if (QAction *contextAction = qobject_cast<QAction*>(sender())) {
+ if (contextAction->data().canConvert<Qt::Alignment::Int>()) {
+#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
+ ui->ioPlot->axisRect()->insetLayout()->setInsetAlignment(0, Qt::Alignment::fromInt(contextAction->data().value<Qt::Alignment::Int>()));
+#else
+ ui->ioPlot->axisRect()->insetLayout()->setInsetAlignment(0, static_cast<Qt::Alignment>(contextAction->data().value<Qt::Alignment::Int>()));
+#endif
+ ui->ioPlot->replot();
+ }
+ }
+}
+
void IOGraphDialog::resetAxes()
{
QCustomPlot *iop = ui->ioPlot;
- QCPRange x_range = iop->xAxis->scaleType() == QCPAxis::stLogarithmic ?
- iop->xAxis->range().sanitizedForLogScale() : iop->xAxis->range();
-
double pixel_pad = 10.0; // per side
iop->rescaleAxes(true);
+ QCPRange x_range = iop->xAxis->scaleType() == QCPAxis::stLogarithmic ?
+ iop->xAxis->range().sanitizedForLogScale() : iop->xAxis->range();
double axis_pixels = iop->xAxis->axisRect()->width();
iop->xAxis->scaleRange((axis_pixels + (pixel_pad * 2)) / axis_pixels, x_range.center());
+ QCPRange y_range = iop->yAxis->scaleType() == QCPAxis::stLogarithmic ?
+ iop->yAxis->range().sanitizedForLogScale() : iop->yAxis->range();
axis_pixels = iop->yAxis->axisRect()->height();
- iop->yAxis->scaleRange((axis_pixels + (pixel_pad * 2)) / axis_pixels, iop->yAxis->range().center());
+ iop->yAxis->scaleRange((axis_pixels + (pixel_pad * 2)) / axis_pixels, y_range.center());
auto_axes_ = true;
iop->replot();
}
+void IOGraphDialog::selectedFrameChanged(QList<int> frames)
+{
+ if (frames.count() == 1 && cap_file_.isValid() && !file_closed_ && tracer_->graph() && cap_file_.packetInfo() != nullptr) {
+ packet_info *pinfo = cap_file_.packetInfo();
+ if (pinfo->num != packet_num_) {
+ // This prevents being triggered by the IOG's own GoToPacketAction,
+ // although that is mostly harmless.
+ int interval = ui->intervalComboBox->itemData(ui->intervalComboBox->currentIndex()).toInt();
+
+ /*
+ * setGraphKey (with Interpolation false, as it is by default)
+ * finds the nearest point to the key. Our buckets are derived
+ * from rounding down (XXX - which is appropriate for relative
+ * time but less so when absolute time of day is selected.)
+ * We could call get_io_graph_index() and then multiply to get
+ * the exact ts for the bucket, but it's fewer math operations
+ * operations simply to subtract half the interval.
+ * XXX - Getting the exact value would be superior if we wished
+ * to avoid doing anything in the case that the tracer is
+ * already pointing at the correct bucket. (Is the hint always
+ * correct in that case?)
+ */
+#if 0
+ int64_t idx = get_io_graph_index(pinfo, interval);
+ double ts = (double)idx * interval / SCALE_F + nstime_to_sec(&start_time);
+#endif
+ double key = nstime_to_sec(&pinfo->rel_ts) - (interval / (2 * SCALE_F)) + nstime_to_sec(&start_time_);
+ tracer_->setGraphKey(key);
+ ui->ioPlot->replot();
+ updateHint();
+ }
+ }
+}
+
void IOGraphDialog::updateStatistics()
{
if (!isVisible()) return;
- if (need_retap_ && !file_closed_ && prefs.gui_io_graph_automatic_update) {
+ /* XXX - If we're currently retapping, what we really want to do is
+ * abort the current tap and start over. process_specified_records()
+ * in file.c doesn't let us do that, because it doesn't know whether
+ * it's holding cf->read_lock for something that could be restarted
+ * (like tapping or dissection) or something that needs to run to
+ * completion (saving, printing.)
+ *
+ * So we wait and see if we're no longer tapping the next check.
+ */
+ if (need_retap_ && !file_closed_ && !retapDepth() && prefs.gui_io_graph_automatic_update) {
need_retap_ = false;
- cap_file_.retapPackets();
+ QTimer::singleShot(0, &cap_file_, &CaptureFile::retapPackets);
// The user might have closed the window while tapping, which means
// we might no longer exist.
} else {
if (need_recalc_ && !file_closed_ && prefs.gui_io_graph_automatic_update) {
need_recalc_ = false;
need_replot_ = true;
- int enabled_graphs = 0;
- if (uat_model_ != NULL) {
- for (int row = 0; row < uat_model_->rowCount(); row++) {
- if (graphIsEnabled(row)) {
- ++enabled_graphs;
- }
- }
- }
- // With multiple visible graphs, disable Y scaling to avoid
- // multiple, distinct units.
- emit recalcGraphData(cap_file_.capFile(), enabled_graphs == 1);
+ emit recalcGraphData(cap_file_.capFile());
if (!tracer_->graph()) {
if (base_graph_ && base_graph_->data()->size() > 0) {
tracer_->setGraph(base_graph_);
@@ -1239,11 +1490,15 @@ void IOGraphDialog::updateStatistics()
void IOGraphDialog::loadProfileGraphs()
{
if (iog_uat_ == NULL) {
+ uat_field_t *io_graph_fields = io_graph_packet_fields;
+ if (!is_packet_configuration_namespace()) {
+ io_graph_fields = io_graph_event_fields;
+ }
iog_uat_ = uat_new("I/O Graphs",
sizeof(io_graph_settings_t),
"io_graphs",
- TRUE,
+ true,
&iog_settings_,
&num_io_graphs_,
0, /* doesn't affect anything that requires a GUI update */
@@ -1251,7 +1506,7 @@ void IOGraphDialog::loadProfileGraphs()
io_graph_copy_cb,
NULL,
io_graph_free_cb,
- NULL,
+ io_graph_post_update_cb,
NULL,
io_graph_fields);
@@ -1263,16 +1518,26 @@ void IOGraphDialog::loadProfileGraphs()
g_free(err);
uat_clear(iog_uat_);
}
+
+ static_uat_model_ = new UatModel(mainApp, iog_uat_);
+ connect(mainApp, &MainApplication::profileChanging, IOGraphDialog::applyChanges);
}
- uat_model_ = new UatModel(NULL, iog_uat_);
- uat_delegate_ = new UatDelegate;
+ uat_model_ = static_uat_model_;
+ uat_delegate_ = new UatDelegate(ui->graphUat);
ui->graphUat->setModel(uat_model_);
ui->graphUat->setItemDelegate(uat_delegate_);
+ ui->graphUat->setSelectionMode(QAbstractItemView::ContiguousSelection);
+
+ ui->graphUat->setHeader(new ResizeHeaderView(Qt::Horizontal, ui->graphUat));
- connect(uat_model_, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
- this, SLOT(modelDataChanged(QModelIndex)));
- connect(uat_model_, SIGNAL(modelReset()), this, SLOT(modelRowsReset()));
+ connect(uat_model_, &UatModel::dataChanged, this, &IOGraphDialog::modelDataChanged);
+ connect(uat_model_, &UatModel::modelReset, this, &IOGraphDialog::modelRowsReset);
+ connect(uat_model_, &UatModel::rowsInserted, this, &IOGraphDialog::modelRowsInserted);
+ connect(uat_model_, &UatModel::rowsRemoved, this, &IOGraphDialog::modelRowsRemoved);
+ connect(uat_model_, &UatModel::rowsMoved, this, &IOGraphDialog::modelRowsMoved);
+
+ connect(ui->graphUat->selectionModel(), &QItemSelectionModel::selectionChanged, this, &IOGraphDialog::graphUatSelectionChanged);
}
// Slots
@@ -1282,6 +1547,22 @@ void IOGraphDialog::on_intervalComboBox_currentIndexChanged(int)
int interval = ui->intervalComboBox->itemData(ui->intervalComboBox->currentIndex()).toInt();
bool need_retap = false;
+ precision_ = ceil(log10(SCALE_F / interval));
+ if (precision_ < 0) {
+ precision_ = 0;
+ }
+
+ // XXX - This is the default QCP date time format, but adding fractional
+ // seconds when our interval is small. Should we make it something else,
+ // like ISO 8601 (but still with a line break between time and date)?
+ // Note this is local time, with no time zone offset displayed. Should
+ // it be in UTC? (call setDateTimeSpec())
+ if (precision_) {
+ datetime_ticker_->setDateTimeFormat("hh:mm:ss.z\ndd.MM.yy");
+ } else {
+ datetime_ticker_->setDateTimeFormat("hh:mm:ss\ndd.MM.yy");
+ }
+
if (uat_model_ != NULL) {
for (int row = 0; row < uat_model_->rowCount(); row++) {
IOGraph *iog = ioGraphs_.value(row, NULL);
@@ -1289,6 +1570,8 @@ void IOGraphDialog::on_intervalComboBox_currentIndexChanged(int)
iog->setInterval(interval);
if (iog->visible()) {
need_retap = true;
+ } else {
+ iog->setNeedRetap(true);
}
}
}
@@ -1297,13 +1580,12 @@ void IOGraphDialog::on_intervalComboBox_currentIndexChanged(int)
if (need_retap) {
scheduleRetap(true);
}
-
- updateLegend();
}
void IOGraphDialog::on_todCheckBox_toggled(bool checked)
{
- double orig_start = start_time_;
+ nstime_t orig_start;
+ nstime_copy(&orig_start, &start_time_);
bool orig_auto = auto_axes_;
if (checked) {
@@ -1315,46 +1597,135 @@ void IOGraphDialog::on_todCheckBox_toggled(bool checked)
scheduleRecalc(true);
auto_axes_ = orig_auto;
getGraphInfo();
- ui->ioPlot->xAxis->moveRange(start_time_ - orig_start);
- mouseMoved(NULL); // Update hint
+ nstime_delta(&orig_start, &start_time_, &orig_start);
+ ui->ioPlot->xAxis->moveRange(nstime_to_sec(&orig_start));
+ updateHint();
}
void IOGraphDialog::modelRowsReset()
{
+ foreach(IOGraph* iog, ioGraphs_) {
+ delete iog;
+ }
+ ioGraphs_.clear();
+
+ for (int i = 0; i < uat_model_->rowCount(); i++) {
+ createIOGraph(i);
+ }
ui->deleteToolButton->setEnabled(false);
ui->copyToolButton->setEnabled(false);
ui->clearToolButton->setEnabled(uat_model_->rowCount() != 0);
}
-void IOGraphDialog::on_graphUat_currentItemChanged(const QModelIndex &current, const QModelIndex&)
+void IOGraphDialog::modelRowsInserted(const QModelIndex &, int first, int last)
{
- if (current.isValid()) {
+ // first to last is inclusive
+ for (int i = first; i <= last; i++) {
+ createIOGraph(i);
+ }
+}
+
+void IOGraphDialog::modelRowsRemoved(const QModelIndex &, int first, int last)
+{
+ // first to last is inclusive
+ for (int i = last; i >= first; i--) {
+ IOGraph *iog = ioGraphs_.takeAt(i);
+ delete iog;
+ }
+}
+
+void IOGraphDialog::modelRowsMoved(const QModelIndex &source, int sourceStart, int sourceEnd, const QModelIndex &dest, int destinationRow)
+{
+ // The source and destination parent are always the same for UatModel.
+ ws_assert(source == dest);
+ // Either destinationRow < sourceStart, or destinationRow > sourceEnd.
+ // When moving rows down the same parent, the rows are placed _before_
+ // destinationRow, otherwise it's the row to which items are moved.
+ if (destinationRow < sourceStart) {
+ for (int i = 0; i <= sourceEnd - sourceStart; i++) {
+ // When moving up the same parent, moving an earlier
+ // item doesn't change the row.
+ ioGraphs_.move(sourceStart + i, destinationRow + i);
+ }
+ } else {
+ for (int i = 0; i <= sourceEnd - sourceStart; i++) {
+ // When moving down the same parent, moving an earlier
+ // item means the next items move up (so all the moved
+ // rows are always at sourceStart.)
+ ioGraphs_.move(sourceStart, destinationRow - 1);
+ }
+ }
+
+ // setting a QCPLayerable to its current layer moves it to the end
+ // as though it were the last added. Do that for all the plottables
+ // starting with the first one that changed, so that the graphs appear
+ // as though they were added in the current order.
+ // (moveToLayer() is the same thing but with a parameter to prepend
+ // instead, which would be faster if we're in the top half of the
+ // list, except that's a protected function. There's no function
+ // to swap layerables in a layer.)
+ IOGraph *iog;
+ for (int row = qMin(sourceStart, destinationRow); row < uat_model_->rowCount(); row++) {
+ iog = ioGraphs_.at(row);
+ if (iog->graph()) {
+ iog->graph()->setLayer(iog->graph()->layer());
+ } else if (iog->bars()) {
+ iog->bars()->setLayer(iog->bars()->layer());
+ }
+ }
+ ui->ioPlot->replot();
+}
+
+void IOGraphDialog::graphUatSelectionChanged(const QItemSelection&, const QItemSelection&)
+{
+ QModelIndexList selectedRows = ui->graphUat->selectionModel()->selectedRows();
+ qsizetype num_selected = selectedRows.size();
+ if (num_selected > 0) {
+ std::sort(selectedRows.begin(), selectedRows.end());
ui->deleteToolButton->setEnabled(true);
ui->copyToolButton->setEnabled(true);
- ui->clearToolButton->setEnabled(true);
- ui->moveUpwardsToolButton->setEnabled(true);
- ui->moveDownwardsToolButton->setEnabled(true);
+ ui->moveUpwardsToolButton->setEnabled(selectedRows.first().row() > 0);
+ ui->moveDownwardsToolButton->setEnabled(selectedRows.last().row() < uat_model_->rowCount() - 1);
} else {
ui->deleteToolButton->setEnabled(false);
ui->copyToolButton->setEnabled(false);
- ui->clearToolButton->setEnabled(false);
ui->moveUpwardsToolButton->setEnabled(false);
ui->moveDownwardsToolButton->setEnabled(false);
}
}
-void IOGraphDialog::modelDataChanged(const QModelIndex &index)
+void IOGraphDialog::on_graphUat_currentItemChanged(const QModelIndex &current, const QModelIndex&)
+{
+ if (current.isValid()) {
+ ui->clearToolButton->setEnabled(true);
+ if (graphIsEnabled(current.row())) {
+ // Try to set the tracer to the new current graph.
+ // If it's not enabled, don't try to switch from the
+ // old graph to the one in the first row.
+ getGraphInfo();
+ }
+ } else {
+ ui->clearToolButton->setEnabled(false);
+ }
+}
+
+void IOGraphDialog::modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &)
{
bool recalc = false;
- switch (index.column())
- {
- case colYAxis:
- case colSMAPeriod:
- recalc = true;
+ for (int col = topLeft.column(); col <= bottomRight.column(); col++) {
+ switch (col)
+ {
+ case colYAxis:
+ case colSMAPeriod:
+ case colYAxisFactor:
+ recalc = true;
+ }
}
- syncGraphSettings(index.row());
+ for (int row = topLeft.row(); row <= bottomRight.row(); row++) {
+ syncGraphSettings(row);
+ }
if (recalc) {
scheduleRecalc(true);
@@ -1363,11 +1734,6 @@ void IOGraphDialog::modelDataChanged(const QModelIndex &index)
}
}
-void IOGraphDialog::on_resetButton_clicked()
-{
- resetAxes();
-}
-
void IOGraphDialog::on_newToolButton_clicked()
{
addGraph();
@@ -1375,70 +1741,95 @@ void IOGraphDialog::on_newToolButton_clicked()
void IOGraphDialog::on_deleteToolButton_clicked()
{
- const QModelIndex &current = ui->graphUat->currentIndex();
- if (uat_model_ && current.isValid()) {
- delete ioGraphs_[current.row()];
- ioGraphs_.remove(current.row());
+ if (uat_model_ == nullptr) {
+ return;
+ }
- if (!uat_model_->removeRows(current.row(), 1)) {
- qDebug() << "Failed to remove row";
+ for (const auto &range : ui->graphUat->selectionModel()->selection()) {
+ // Each QItemSelectionRange is contiguous
+ if (!range.isEmpty()) {
+ if (!uat_model_->removeRows(range.top(), range.bottom() - range.top() + 1)) {
+ qDebug() << "Failed to remove rows" << range.top() << "to" << range.bottom();
+ }
}
}
// We should probably be smarter about this.
hint_err_.clear();
- mouseMoved(NULL);
+ updateHint();
}
void IOGraphDialog::on_copyToolButton_clicked()
{
- addGraph(true);
+ if (uat_model_ == nullptr) {
+ return;
+ }
+
+ QModelIndexList selectedRows = ui->graphUat->selectionModel()->selectedRows();
+ if (selectedRows.size() > 0) {
+ std::sort(selectedRows.begin(), selectedRows.end());
+
+ QModelIndex copyIdx;
+
+ for (const auto &idx : selectedRows) {
+ copyIdx = uat_model_->copyRow(idx);
+ if (!copyIdx.isValid())
+ {
+ qDebug() << "Failed to copy row" << idx.row();
+ }
+ }
+ ui->graphUat->setCurrentIndex(copyIdx);
+ }
}
void IOGraphDialog::on_clearToolButton_clicked()
{
if (uat_model_) {
- foreach(IOGraph* iog, ioGraphs_) {
- delete iog;
- }
- ioGraphs_.clear();
uat_model_->clearAll();
}
hint_err_.clear();
- mouseMoved(NULL);
+ updateHint();
}
void IOGraphDialog::on_moveUpwardsToolButton_clicked()
{
- const QModelIndex& current = ui->graphUat->currentIndex();
- if (uat_model_ && current.isValid()) {
-
- int current_row = current.row();
- if (current_row > 0){
- // Swap current row with the one above
- IOGraph* temp = ioGraphs_[current_row - 1];
- ioGraphs_[current_row - 1] = ioGraphs_[current_row];
- ioGraphs_[current_row] = temp;
+ if (uat_model_ == nullptr) {
+ return;
+ }
- uat_model_->moveRow(current_row, current_row - 1);
+ for (const auto &range : ui->graphUat->selectionModel()->selection()) {
+ // Each QItemSelectionRange is contiguous
+ if (!range.isEmpty() && range.top() > 0) {
+ // Swap range of rows with the row above the top
+ if (! uat_model_->moveRows(QModelIndex(), range.top(), range.bottom() - range.top() + 1, QModelIndex(), range.top() - 1)) {
+ qDebug() << "Failed to move up rows" << range.top() << "to" << range.bottom();
+ }
+ // Our moveRows implementation calls begin/endMoveRows(), so
+ // range.top() already has the new row number.
+ ui->moveUpwardsToolButton->setEnabled(range.top() > 0);
+ ui->moveDownwardsToolButton->setEnabled(true);
}
}
}
void IOGraphDialog::on_moveDownwardsToolButton_clicked()
{
- const QModelIndex& current = ui->graphUat->currentIndex();
- if (uat_model_ && current.isValid()) {
-
- int current_row = current.row();
- if (current_row < uat_model_->rowCount() - 1) {
- // Swap current row with the one below
- IOGraph* temp = ioGraphs_[current_row + 1];
- ioGraphs_[current_row + 1] = ioGraphs_[current_row];
- ioGraphs_[current_row] = temp;
+ if (uat_model_ == nullptr) {
+ return;
+ }
- uat_model_->moveRow(current_row, current_row + 1);
+ for (const auto &range : ui->graphUat->selectionModel()->selection()) {
+ // Each QItemSelectionRange is contiguous
+ if (!range.isEmpty() && range.bottom() + 1 < uat_model_->rowCount()) {
+ // Swap range of rows with the row below the top
+ if (! uat_model_->moveRows(QModelIndex(), range.top(), range.bottom() - range.top() + 1, QModelIndex(), range.bottom() + 1)) {
+ qDebug() << "Failed to move down rows" << range.top() << "to" << range.bottom();
+ }
+ // Our moveRows implementation calls begin/endMoveRows, so
+ // range.bottom() already has the new row number.
+ ui->moveUpwardsToolButton->setEnabled(true);
+ ui->moveDownwardsToolButton->setEnabled(range.bottom() < uat_model_->rowCount() - 1);
}
}
}
@@ -1461,14 +1852,28 @@ void IOGraphDialog::on_zoomRadioButton_toggled(bool checked)
void IOGraphDialog::on_logCheckBox_toggled(bool checked)
{
QCustomPlot *iop = ui->ioPlot;
+ QSharedPointer<QCPAxisTickerSi> si_ticker = qSharedPointerDynamicCast<QCPAxisTickerSi>(iop->yAxis->ticker());
+ if (si_ticker != nullptr) {
+ si_ticker->setLog(checked);
+ }
- iop->yAxis->setScaleType(checked ? QCPAxis::stLogarithmic : QCPAxis::stLinear);
+ if (checked) {
+ iop->yAxis->setScaleType(QCPAxis::stLogarithmic);
+ if (si_ticker == nullptr) {
+ iop->yAxis->setTicker(QSharedPointer<QCPAxisTickerLog>(new QCPAxisTickerLog));
+ }
+ } else {
+ iop->yAxis->setScaleType(QCPAxis::stLinear);
+ if (si_ticker == nullptr) {
+ iop->yAxis->setTicker(QSharedPointer<QCPAxisTicker>(new QCPAxisTicker));
+ }
+ }
iop->replot();
}
void IOGraphDialog::on_automaticUpdateCheckBox_toggled(bool checked)
{
- prefs.gui_io_graph_automatic_update = checked ? TRUE : FALSE;
+ prefs.gui_io_graph_automatic_update = checked ? true : false;
prefs_main_write();
@@ -1480,16 +1885,16 @@ void IOGraphDialog::on_automaticUpdateCheckBox_toggled(bool checked)
void IOGraphDialog::on_enableLegendCheckBox_toggled(bool checked)
{
- prefs.gui_io_graph_enable_legend = checked ? TRUE : FALSE;
+ prefs.gui_io_graph_enable_legend = checked ? true : false;
prefs_main_write();
- updateLegend();
+ ui->ioPlot->legend->layer()->replot();
}
void IOGraphDialog::on_actionReset_triggered()
{
- on_resetButton_clicked();
+ resetAxes();
}
void IOGraphDialog::on_actionZoomIn_triggered()
@@ -1585,7 +1990,7 @@ void IOGraphDialog::on_actionToggleTimeOrigin_triggered()
void IOGraphDialog::on_actionCrosshairs_triggered()
{
-
+ toggleTracerStyle();
}
void IOGraphDialog::on_buttonBox_helpRequested()
@@ -1638,6 +2043,17 @@ void IOGraphDialog::on_buttonBox_accepted()
}
}
+void IOGraphDialog::buttonBoxClicked(QAbstractButton *button)
+{
+ switch (ui->buttonBox->buttonRole(button)) {
+ case QDialogButtonBox::ResetRole:
+ resetAxes();
+ break;
+ default:
+ break;
+ }
+}
+
void IOGraphDialog::makeCsv(QTextStream &stream) const
{
QList<IOGraph *> activeGraphs;
@@ -1646,25 +2062,47 @@ void IOGraphDialog::makeCsv(QTextStream &stream) const
int max_interval = 0;
stream << "\"Interval start\"";
- if (uat_model_ != NULL) {
- for (int row = 0; row < uat_model_->rowCount(); row++) {
- if (graphIsEnabled(row) && ioGraphs_[row] != NULL) {
- activeGraphs.append(ioGraphs_[row]);
- if (max_interval < ioGraphs_[row]->maxInterval()) {
- max_interval = ioGraphs_[row]->maxInterval();
- }
- QString name = ioGraphs_[row]->name().toUtf8();
- name = QString("\"%1\"").arg(name.replace("\"", "\"\"")); // RFC 4180
- stream << "," << name;
+ for (int row = 0; row < graphCount(); row++) {
+ if (graphIsEnabled(row) && ioGraphs_[row] != NULL) {
+ activeGraphs.append(ioGraphs_[row]);
+ if (max_interval < ioGraphs_[row]->maxInterval()) {
+ max_interval = ioGraphs_[row]->maxInterval();
}
+ QString name = ioGraphs_[row]->name().toUtf8();
+ name = QString("\"%1\"").arg(name.replace("\"", "\"\"")); // RFC 4180
+ stream << "," << name;
}
}
stream << '\n';
for (int interval = 0; interval <= max_interval; interval++) {
- double interval_start = (double)interval * ((double)ui_interval / 1000.0);
- stream << interval_start;
+ int64_t interval_start = (int64_t)interval * ui_interval;
+ if (qSharedPointerDynamicCast<QCPAxisTickerDateTime>(ui->ioPlot->xAxis->ticker()) != nullptr) {
+ nstime_t interval_time = NSTIME_INIT_SECS_USECS((time_t)(interval_start / SCALE), (int)(interval_start % SCALE));
+
+ nstime_add(&interval_time, &start_time_);
+
+ static char time_string_buf[39];
+
+ if (decimal_point == nullptr) {
+ decimal_point = g_strdup(localeconv()->decimal_point);
+ }
+ // Should we convert to UTC for output, even if the graph axis has
+ // local time?
+ // The question of what precision to use is somewhat tricky.
+ // The buckets are aligned to the relative time start, not to
+ // absolute time, so the timestamp precision should be used instead
+ // of the bucket precision. We can save the precision of the
+ // start time timestamp for each graph, but we don't necessarily
+ // have a guarantee that all timestamps in the file have the same
+ // precision. Possibly nstime_t should store precision, cf. #15579
+ format_nstime_as_iso8601(time_string_buf, sizeof time_string_buf, &interval_time, decimal_point, true, 9); // precision_);
+
+ stream << time_string_buf;
+ } else {
+ stream << (double)interval_start / SCALE_F;
+ }
foreach (IOGraph *iog, activeGraphs) {
double value = 0.0;
if (interval <= iog->maxInterval()) {
@@ -1698,11 +2136,14 @@ bool IOGraphDialog::saveCsv(const QString &file_name) const
IOGraph::IOGraph(QCustomPlot *parent) :
parent_(parent),
+ tap_registered_(true),
visible_(false),
graph_(NULL),
bars_(NULL),
val_units_(IOG_ITEM_UNIT_FIRST),
hf_index_(-1),
+ interval_(0),
+ start_time_(NSTIME_INIT_ZERO),
cur_idx_(-1)
{
Q_ASSERT(parent_ != NULL);
@@ -1723,11 +2164,12 @@ IOGraph::IOGraph(QCustomPlot *parent) :
// error_string->str);
// config_err_ = error_string->str;
g_string_free(error_string, TRUE);
+ tap_registered_ = false;
}
}
IOGraph::~IOGraph() {
- remove_tap_listener(this);
+ removeTapListener();
if (graph_) {
parent_->removeGraph(graph_);
}
@@ -1736,9 +2178,17 @@ IOGraph::~IOGraph() {
}
}
+void IOGraph::removeTapListener()
+{
+ if (tap_registered_) {
+ remove_tap_listener(this);
+ tap_registered_ = false;
+ }
+}
+
// Construct a full filter string from the display filter and value unit / Y axis.
-// Check for errors and sets config_err_ if any are found.
-void IOGraph::setFilter(const QString &filter)
+// Check for errors and sets config_err_ and returns false if any are found.
+bool IOGraph::setFilter(const QString &filter)
{
GString *error_string;
QString full_filter(filter.trimmed());
@@ -1756,7 +2206,7 @@ void IOGraph::setFilter(const QString &filter)
config_err_ = QString::fromUtf8(df_err->msg);
df_error_free(&df_err);
filter_ = full_filter;
- return;
+ return false;
}
}
@@ -1765,7 +2215,7 @@ void IOGraph::setFilter(const QString &filter)
if (error_string) {
config_err_ = error_string->str;
g_string_free(error_string, TRUE);
- return;
+ return false;
}
// Make sure vu_field_ survives edt tree pruning by adding it to our filter
@@ -1778,17 +2228,36 @@ void IOGraph::setFilter(const QString &filter)
}
}
- error_string = set_tap_dfilter(this, full_filter.toUtf8().constData());
- if (error_string) {
- config_err_ = error_string->str;
- g_string_free(error_string, TRUE);
- return;
- } else {
- if (filter_.compare(filter) && visible_) {
- emit requestRetap();
+ if (full_filter_.compare(full_filter)) {
+ error_string = set_tap_dfilter(this, full_filter.toUtf8().constData());
+ if (error_string) {
+ config_err_ = error_string->str;
+ g_string_free(error_string, TRUE);
+ return false;
}
+
filter_ = filter;
+ full_filter_ = full_filter;
+ /* If we changed the tap filter the graph is visible, we need to
+ * retap.
+ * Note that setting the tap dfilter will mark the tap as needing a
+ * redraw, which will cause a recalculation (via tapDraw) via the
+ * (fairly long) main application timer.
+ */
+ /* XXX - When changing from an advanced graph to one that doesn't
+ * use the field, we don't actually need to retap if filter and
+ * full_filter produce the same results. (We do have to retap
+ * regardless if changing _to_ an advanced graph, because the
+ * extra fields in the io_graph_item_t aren't filled in from the
+ * edt for the basic graph.)
+ * Checking that in full generality would require more optimization
+ * in the dfilter engine plus functions to compare filters, but
+ * we could test the simple case where filter and vu_field are
+ * the same string.
+ */
+ setNeedRetap(true);
}
+ return true;
}
void IOGraph::applyCurrentColor()
@@ -1796,7 +2265,15 @@ void IOGraph::applyCurrentColor()
if (graph_) {
graph_->setPen(QPen(color_, graph_line_width_));
} else if (bars_) {
- bars_->setPen(QPen(QBrush(ColorUtils::graphColor(0)), graph_line_width_)); // ...or omit it altogether?
+ bars_->setPen(QPen(color_.color().darker(110), graph_line_width_));
+ // ...or omit it altogether?
+ // bars_->setPen(QPen(color_);
+ // XXX - We should do something like
+ // bars_->setPen(QPen(ColorUtils::alphaBlend(color_, palette().windowText(), 0.65));
+ // to get a darker outline in light mode and a lighter outline in dark
+ // mode, but we don't yet respect dark mode in IOGraph (or anything
+ // that uses QCustomPlot) - see link below for how to set QCP colors:
+ // https://www.qcustomplot.com/index.php/demos/barchartdemo
bars_->setBrush(color_);
}
}
@@ -1812,7 +2289,28 @@ void IOGraph::setVisible(bool visible)
bars_->setVisible(visible_);
}
if (old_visibility != visible_) {
- emit requestReplot();
+ if (visible_ && need_retap_) {
+ need_retap_ = false;
+ emit requestRetap();
+ } else {
+ // XXX - If the number of enabled graphs changed to or from 1, we
+ // need to recalculate to possibly change the rescaling. (This is
+ // why QCP recommends doing scaling in the axis ticker instead.)
+ // If we can't determine the number of enabled graphs here, always
+ // request a recalculation instead of a replot. (At least until we
+ // change the scaling to be done in the ticker.)
+ //emit requestReplot();
+ emit requestRecalc();
+ }
+ }
+}
+
+void IOGraph::setNeedRetap(bool retap)
+{
+ if (visible_ && retap) {
+ emit requestRetap();
+ } else {
+ need_retap_ = retap;
}
}
@@ -1827,7 +2325,7 @@ void IOGraph::setName(const QString &name)
}
}
-QRgb IOGraph::color()
+QRgb IOGraph::color() const
{
return color_.color().rgb();
}
@@ -1840,14 +2338,24 @@ void IOGraph::setColor(const QRgb color)
void IOGraph::setPlotStyle(int style)
{
+ bool recalc = false;
+ bool shows_zero = showsZero();
+
// Switch plottable if needed
switch (style) {
case psBar:
case psStackedBar:
if (graph_) {
bars_ = new QCPBars(parent_->xAxis, parent_->yAxis);
+ // default widthType is wtPlotCoords. Scale with the interval
+ // size to prevent overlap. (Multiply this by a factor to have
+ // a gap between bars; the QCustomPlot default is 0.75.)
+ if (interval_) {
+ bars_->setWidth(interval_ / SCALE_F);
+ }
parent_->removeGraph(graph_);
graph_ = NULL;
+ recalc = true;
}
break;
default:
@@ -1855,6 +2363,7 @@ void IOGraph::setPlotStyle(int style)
graph_ = parent_->addGraph(parent_->xAxis, parent_->yAxis);
parent_->removePlottable(bars_);
bars_ = NULL;
+ recalc = true;
}
break;
}
@@ -1930,13 +2439,26 @@ void IOGraph::setPlotStyle(int style)
break;
}
+ if (shows_zero != showsZero()) {
+ // recalculate if whether zero is added changed
+ recalc = true;
+ }
+
setName(name_);
applyCurrentColor();
+
+ if (recalc) {
+ // switching the plottable requires recalculation to add the data
+ emit requestRecalc();
+ }
}
-const QString IOGraph::valueUnitLabel()
+QString IOGraph::valueUnitLabel() const
{
- return val_to_str_const(val_units_, y_axis_vs, "Unknown");
+ if (is_packet_configuration_namespace()) {
+ return val_to_str_const(val_units_, y_axis_packet_vs, "Unknown");
+ }
+ return val_to_str_const(val_units_, y_axis_event_vs, "Unknown");
}
void IOGraph::setValueUnits(int val_units)
@@ -1946,9 +2468,21 @@ void IOGraph::setValueUnits(int val_units)
val_units_ = (io_graph_item_unit_t)val_units;
if (old_val_units != val_units) {
- setFilter(filter_); // Check config & prime vu field
- if (val_units < IOG_ITEM_UNIT_CALC_SUM) {
- emit requestRecalc();
+ // If val_units changed, switching between a type that doesn't
+ // use the vu_field/hfi/edt to one of the advanced graphs that
+ // does requires a retap. setFilter will handle that, because
+ // the full filter strings will be different.
+ if (setFilter(filter_)) { // Check config & prime vu field
+ if (val_units == IOG_ITEM_UNIT_CALC_LOAD ||
+ old_val_units == IOG_ITEM_UNIT_CALC_LOAD) {
+ // LOAD graphs fill in the io_graph_item_t differently
+ // than other advanced graphs, so we have to retap even
+ // if the filter is the same. (update_io_graph_item could
+ // instead calculate and store LOAD information for any
+ // advanced graph type, but the tradeoff might not be
+ // worth it.)
+ setNeedRetap(true);
+ }
}
}
}
@@ -1967,6 +2501,8 @@ void IOGraph::setValueUnitField(const QString &vu_field)
}
if (old_hf_index != hf_index_) {
+ // If the field changed, and val_units is a type that uses it,
+ // we need to retap. setFilter will handle that.
setFilter(filter_); // Check config & prime vu field
}
}
@@ -1993,25 +2529,44 @@ bool IOGraph::removeFromLegend()
return false;
}
-double IOGraph::startOffset()
+// This returns what graph key offset corresponds with relative time 0.0,
+// i.e. when absolute times are used the difference between abs_ts and
+// rel_ts of the first tapped packet. Generally the same for all graphs
+// that are displayed and have some data, unless they're on the opposite
+// sides of time references.
+// XXX - If the graph spans a time reference, it's not clear how we want
+// to switch from relative to absolute times.
+double IOGraph::startOffset() const
{
- if (graph_ && qSharedPointerDynamicCast<QCPAxisTickerDateTime>(graph_->keyAxis()->ticker()) && graph_->data()->size() > 0) {
- return graph_->data()->at(0)->key;
+ if (graph_ && qSharedPointerDynamicCast<QCPAxisTickerDateTime>(graph_->keyAxis()->ticker())) {
+ return nstime_to_sec(&start_time_);
}
- if (bars_ && qSharedPointerDynamicCast<QCPAxisTickerDateTime>(bars_->keyAxis()->ticker()) && bars_->data()->size() > 0) {
- return bars_->data()->at(0)->key;
+ if (bars_ && qSharedPointerDynamicCast<QCPAxisTickerDateTime>(bars_->keyAxis()->ticker())) {
+ return nstime_to_sec(&start_time_);
}
return 0.0;
}
-int IOGraph::packetFromTime(double ts)
+nstime_t IOGraph::startTime() const
{
- int idx = ts * 1000 / interval_;
- if (idx >= 0 && idx < (int) cur_idx_) {
+ if (graph_ && qSharedPointerDynamicCast<QCPAxisTickerDateTime>(graph_->keyAxis()->ticker())) {
+ return start_time_;
+ }
+ if (bars_ && qSharedPointerDynamicCast<QCPAxisTickerDateTime>(bars_->keyAxis()->ticker())) {
+ return start_time_;
+ }
+ return nstime_t(NSTIME_INIT_ZERO);
+}
+
+int IOGraph::packetFromTime(double ts) const
+{
+ int idx = ts * SCALE_F / interval_;
+ if (idx >= 0 && idx <= cur_idx_) {
switch (val_units_) {
case IOG_ITEM_UNIT_CALC_MAX:
+ return items_[idx].max_frame_in_invl;
case IOG_ITEM_UNIT_CALC_MIN:
- return items_[idx].extreme_frame_in_invl;
+ return items_[idx].min_frame_in_invl;
default:
return items_[idx].last_frame_in_invl;
}
@@ -2022,31 +2577,30 @@ int IOGraph::packetFromTime(double ts)
void IOGraph::clearAllData()
{
cur_idx_ = -1;
- reset_io_graph_items(items_, max_io_items_);
+ if (items_.size()) {
+ reset_io_graph_items(&items_[0], items_.size(), hf_index_);
+ }
if (graph_) {
graph_->data()->clear();
}
if (bars_) {
bars_->data()->clear();
}
- start_time_ = 0.0;
+ nstime_set_zero(&start_time_);
}
-void IOGraph::recalcGraphData(capture_file *cap_file, bool enable_scaling)
+void IOGraph::recalcGraphData(capture_file *cap_file)
{
/* Moving average variables */
unsigned int mavg_in_average_count = 0, mavg_left = 0;
unsigned int mavg_to_remove = 0, mavg_to_add = 0;
double mavg_cumulated = 0;
- QCPAxis *x_axis = nullptr;
if (graph_) {
graph_->data()->clear();
- x_axis = graph_->keyAxis();
}
if (bars_) {
bars_->data()->clear();
- x_axis = bars_->keyAxis();
}
if (moving_avg_period_ > 0 && cur_idx_ >= 0) {
@@ -2054,7 +2608,7 @@ void IOGraph::recalcGraphData(capture_file *cap_file, bool enable_scaling)
* just to make sure average on leftmost and rightmost displayed
* values is as reliable as possible
*/
- guint64 warmup_interval = 0;
+ uint64_t warmup_interval = 0;
// for (; warmup_interval < first_interval; warmup_interval += interval_) {
// mavg_cumulated += get_it_value(io, i, (int)warmup_interval/interval_);
@@ -2064,8 +2618,8 @@ void IOGraph::recalcGraphData(capture_file *cap_file, bool enable_scaling)
mavg_cumulated += getItemValue((int)warmup_interval/interval_, cap_file);
mavg_in_average_count++;
for (warmup_interval = interval_;
- ((warmup_interval < (0 + (moving_avg_period_ / 2) * (guint64)interval_)) &&
- (warmup_interval <= (cur_idx_ * (guint64)interval_)));
+ ((warmup_interval < (0 + (moving_avg_period_ / 2) * (uint64_t)interval_)) &&
+ (warmup_interval <= (cur_idx_ * (uint64_t)interval_)));
warmup_interval += interval_) {
mavg_cumulated += getItemValue((int)warmup_interval / interval_, cap_file);
@@ -2074,11 +2628,9 @@ void IOGraph::recalcGraphData(capture_file *cap_file, bool enable_scaling)
mavg_to_add = (unsigned int)warmup_interval;
}
+ double ts_offset = startOffset();
for (int i = 0; i <= cur_idx_; i++) {
- double ts = (double) i * interval_ / 1000;
- if (x_axis && qSharedPointerDynamicCast<QCPAxisTickerDateTime>(x_axis->ticker())) {
- ts += start_time_;
- }
+ double ts = (double) i * interval_ / SCALE_F + ts_offset;
double val = getItemValue(i, cap_file);
if (moving_avg_period_ > 0) {
@@ -2112,73 +2664,46 @@ void IOGraph::recalcGraphData(capture_file *cap_file, bool enable_scaling)
bars_->addData(ts, val);
}
}
-// qDebug() << "=rgd i" << i << ts << val;
- }
-
- // attempt to rescale time values to specific units
- if (enable_scaling) {
- calculateScaledValueUnit();
- } else {
- scaled_value_unit_.clear();
}
emit requestReplot();
}
-void IOGraph::calculateScaledValueUnit()
+format_size_units_e IOGraph::formatUnits() const
{
- // Reset unit and recalculate if needed.
- scaled_value_unit_.clear();
-
- // If there is no field, scaling is not possible.
- if (hf_index_ < 0) {
- return;
- }
-
switch (val_units_) {
+ case IOG_ITEM_UNIT_PACKETS:
+ case IOG_ITEM_UNIT_CALC_FRAMES:
+ if (is_packet_configuration_namespace()) {
+ return FORMAT_SIZE_UNIT_PACKETS;
+ }
+ return FORMAT_SIZE_UNIT_EVENTS;
+ case IOG_ITEM_UNIT_BYTES:
+ return FORMAT_SIZE_UNIT_BYTES;
+ case IOG_ITEM_UNIT_BITS:
+ return FORMAT_SIZE_UNIT_BITS;
+ case IOG_ITEM_UNIT_CALC_LOAD:
+ return FORMAT_SIZE_UNIT_ERLANGS;
+ case IOG_ITEM_UNIT_CALC_FIELDS:
+ return FORMAT_SIZE_UNIT_FIELDS;
case IOG_ITEM_UNIT_CALC_SUM:
case IOG_ITEM_UNIT_CALC_MAX:
case IOG_ITEM_UNIT_CALC_MIN:
case IOG_ITEM_UNIT_CALC_AVERAGE:
// Unit is not yet known, continue detecting it.
- break;
- default:
- // Unit is Packets, Bytes, Bits, etc.
- return;
- }
-
- if (proto_registrar_get_ftype(hf_index_) == FT_RELATIVE_TIME) {
- // find maximum absolute value and scale accordingly
- double maxValue = 0;
- if (graph_) {
- maxValue = maxValueFromGraphData(*graph_->data());
- } else if (bars_) {
- maxValue = maxValueFromGraphData(*bars_->data());
- }
- // If the maximum value is zero, then either we have no data or
- // everything is zero, do not scale the unit in this case.
- if (maxValue == 0) {
- return;
- }
-
- // XXX GTK+ always uses "ms" for log scale, should we do that too?
- int value_multiplier;
- if (maxValue >= 1.0) {
- scaled_value_unit_ = "s";
- value_multiplier = 1;
- } else if (maxValue >= 0.001) {
- scaled_value_unit_ = "ms";
- value_multiplier = 1000;
- } else {
- scaled_value_unit_ = "us";
- value_multiplier = 1000000;
- }
-
- if (graph_) {
- scaleGraphData(*graph_->data(), value_multiplier);
- } else if (bars_) {
- scaleGraphData(*bars_->data(), value_multiplier);
+ if (hf_index_ > 0) {
+ if (proto_registrar_get_ftype(hf_index_) == FT_RELATIVE_TIME) {
+ return FORMAT_SIZE_UNIT_SECONDS;
+ }
+ // Could we look if it's BASE_UNIT_STRING and use that?
+ // One complication is that prefixes shouldn't be combined,
+ // and some unit strings are already prefixed units.
}
+ return FORMAT_SIZE_UNIT_NONE;
+ case IOG_ITEM_UNIT_CALC_THROUGHPUT:
+ return FORMAT_SIZE_UNIT_BITS_S;
+ default:
+ return FORMAT_SIZE_UNIT_NONE;
}
}
@@ -2211,7 +2736,7 @@ void IOGraph::captureEvent(CaptureEvent e)
if ((e.captureContext() == CaptureEvent::File) &&
(e.eventType() == CaptureEvent::Closing))
{
- remove_tap_listener(this);
+ removeTapListener();
}
}
@@ -2222,6 +2747,38 @@ void IOGraph::reloadValueUnitField()
}
}
+// returns true if the current plot style shows zero values,
+// false if null values are omitted.
+bool IOGraph::showsZero() const
+{
+ switch (val_units_) {
+ case IOG_ITEM_UNIT_PACKETS:
+ case IOG_ITEM_UNIT_BYTES:
+ case IOG_ITEM_UNIT_BITS:
+ case IOG_ITEM_UNIT_CALC_FRAMES:
+ case IOG_ITEM_UNIT_CALC_FIELDS:
+ if (graph_ && graph_->lineStyle() == QCPGraph::lsNone) {
+ return false;
+ }
+ else {
+ return true;
+ }
+ case IOG_ITEM_UNIT_CALC_SUM:
+ case IOG_ITEM_UNIT_CALC_MAX:
+ case IOG_ITEM_UNIT_CALC_MIN:
+ case IOG_ITEM_UNIT_CALC_AVERAGE:
+ case IOG_ITEM_UNIT_CALC_LOAD:
+ case IOG_ITEM_UNIT_CALC_THROUGHPUT:
+ // These are not the same sort of "omitted zeros" as above,
+ // but changing val_units_ always results in a recalculation
+ // so it doesn't matter (see modelDataChanged)
+ return false;
+
+ default:
+ return true;
+ }
+}
+
// Check if a packet is available at the given interval (idx).
bool IOGraph::hasItemToShow(int idx, double value) const
{
@@ -2237,7 +2794,7 @@ bool IOGraph::hasItemToShow(int idx, double value) const
case IOG_ITEM_UNIT_BITS:
case IOG_ITEM_UNIT_CALC_FRAMES:
case IOG_ITEM_UNIT_CALC_FIELDS:
- if(value == 0.0 && (graph_ && graph_->scatterStyle().shape() != QCPScatterStyle::ssNone)) {
+ if (value == 0.0 && (graph_ && graph_->lineStyle() == QCPGraph::lsNone)) {
result = false;
}
else {
@@ -2250,6 +2807,7 @@ bool IOGraph::hasItemToShow(int idx, double value) const
case IOG_ITEM_UNIT_CALC_MIN:
case IOG_ITEM_UNIT_CALC_AVERAGE:
case IOG_ITEM_UNIT_CALC_LOAD:
+ case IOG_ITEM_UNIT_CALC_THROUGHPUT:
if (item->fields) {
result = true;
}
@@ -2266,6 +2824,9 @@ bool IOGraph::hasItemToShow(int idx, double value) const
void IOGraph::setInterval(int interval)
{
interval_ = interval;
+ if (bars_) {
+ bars_->setWidth(interval_ / SCALE_F);
+ }
}
// Get the value at the given interval (idx) for the current value unit.
@@ -2273,7 +2834,7 @@ double IOGraph::getItemValue(int idx, const capture_file *cap_file) const
{
ws_assert(idx < max_io_items_);
- return get_io_graph_item(items_, val_units_, idx, hf_index_, cap_file, interval_, cur_idx_);
+ return get_io_graph_item(&items_[0], val_units_, idx, hf_index_, cap_file, interval_, cur_idx_);
}
// "tap_reset" callback for register_tap_listener
@@ -2294,27 +2855,60 @@ tap_packet_status IOGraph::tapPacket(void *iog_ptr, packet_info *pinfo, epan_dis
return TAP_PACKET_DONT_REDRAW;
}
- int idx = get_io_graph_index(pinfo, iog->interval_);
+ int64_t tmp_idx = get_io_graph_index(pinfo, iog->interval_);
bool recalc = false;
/* some sanity checks */
- if ((idx < 0) || (idx >= max_io_items_)) {
- iog->cur_idx_ = max_io_items_ - 1;
+ if ((tmp_idx < 0) || (tmp_idx >= max_io_items_)) {
+ iog->cur_idx_ = (int)iog->items_.size() - 1;
return TAP_PACKET_DONT_REDRAW;
}
+ int idx = (int)tmp_idx;
+ /* If the graph isn't visible, don't do the work or redraw, but mark
+ * the graph in need of a retap if it is ever enabled. The alternative
+ * is to do the work, but clear pending retaps when the taps are reset
+ * (which indicates something else triggered a retap.) The tradeoff would
+ * be more calculation and memory usage when a graph is disabled in
+ * exchange for fewer scenarios that involve retaps when toggling the
+ * enabled/disabled taps.
+ */
+ if (!iog->visible()) {
+ if (idx > iog->cur_idx_) {
+ iog->need_retap_ = true;
+ }
+ return TAP_PACKET_DONT_REDRAW;
+ }
+
+ if ((size_t)idx >= iog->items_.size()) {
+ const size_t old_size = iog->items_.size();
+ size_t new_size;
+ if (old_size == 0) {
+ new_size = 1024;
+ } else {
+ new_size = MIN((old_size * 3) / 2, max_io_items_);
+ }
+ new_size = MAX(new_size, (size_t)idx + 1);
+ try {
+ iog->items_.resize(new_size);
+ } catch (std::bad_alloc&) {
+ // std::vector.resize() has strong exception safety
+ ws_warning("Failed memory allocation!");
+ return TAP_PACKET_DONT_REDRAW;
+ }
+ // resize zero-initializes new items, which is what we want
+ //reset_io_graph_items(&iog->items_[old_size], new_size - old_size);
+ }
+
/* update num_items */
if (idx > iog->cur_idx_) {
- iog->cur_idx_ = (guint32) idx;
+ iog->cur_idx_ = idx;
recalc = true;
}
/* set start time */
- if (iog->start_time_ == 0.0) {
- nstime_t start_nstime;
- nstime_set_zero(&start_nstime);
- nstime_delta(&start_nstime, &pinfo->abs_ts, &pinfo->rel_ts);
- iog->start_time_ = nstime_to_sec(&start_nstime);
+ if (nstime_is_zero(&iog->start_time_)) {
+ nstime_delta(&iog->start_time_, &pinfo->abs_ts, &pinfo->rel_ts);
}
epan_dissect_t *adv_edt = NULL;
@@ -2323,7 +2917,7 @@ tap_packet_status IOGraph::tapPacket(void *iog_ptr, packet_info *pinfo, epan_dis
adv_edt = edt;
}
- if (!update_io_graph_item(iog->items_, idx, pinfo, adv_edt, iog->hf_index_, iog->val_units_, iog->interval_)) {
+ if (!update_io_graph_item(&iog->items_[0], idx, pinfo, adv_edt, iog->hf_index_, iog->val_units_, iog->interval_)) {
return TAP_PACKET_DONT_REDRAW;
}
diff --git a/ui/qt/io_graph_dialog.h b/ui/qt/io_graph_dialog.h
index f0bd4cdf..736ec93d 100644
--- a/ui/qt/io_graph_dialog.h
+++ b/ui/qt/io_graph_dialog.h
@@ -12,8 +12,6 @@
#include <config.h>
-#include <glib.h>
-
#include "epan/epan_dissect.h"
#include "epan/prefs.h"
#include "ui/preference_utils.h"
@@ -25,12 +23,20 @@
#include <ui/qt/models/uat_model.h>
#include <ui/qt/models/uat_delegate.h>
+#include <wsutil/str_util.h>
+
+#include <QPointer>
#include <QIcon>
#include <QMenu>
#include <QTextStream>
+#include <QItemSelection>
+
+#include <vector>
class QRubberBand;
class QTimer;
+class QAbstractButton;
+class CopyFromProfileButton;
class QCPBars;
class QCPGraph;
@@ -39,8 +45,16 @@ class QCustomPlot;
class QCPAxisTicker;
class QCPAxisTickerDateTime;
-// GTK+ sets this to 100000 (NUM_IO_ITEMS)
-const int max_io_items_ = 250000;
+// GTK+ set this to 100000 (NUM_IO_ITEMS) before raising it to unlimited
+// in commit 524583298beb671f43e972476693866754d38a38.
+// This is the maximum index returned from get_io_graph_index that will
+// be added to the graph. Thus, for a minimum interval size of 1 μs no
+// more than 33.55 s.
+// Each io_graph_item_t is 88 bytes on a system with 64 bit time_t, so
+// the max size we'll attempt to allocate for the array of items is 2.75 GiB
+// (plus a tiny amount extra for the std::vector bookkeeping.)
+// 2^25 = 16777216
+const int max_io_items_ = 1 << 25;
// XXX - Move to its own file?
class IOGraph : public QObject {
@@ -51,33 +65,37 @@ public:
explicit IOGraph(QCustomPlot *parent);
~IOGraph();
- const QString configError() { return config_err_; }
- const QString name() { return name_; }
+ QString configError() const { return config_err_; }
+ QString name() const { return name_; }
void setName(const QString &name);
- const QString filter() { return filter_; }
- void setFilter(const QString &filter);
+ QString filter() const { return filter_; }
+ bool setFilter(const QString &filter);
void applyCurrentColor();
- bool visible() { return visible_; }
+ bool visible() const { return visible_; }
void setVisible(bool visible);
- QRgb color();
+ bool needRetap() const { return need_retap_; }
+ void setNeedRetap(bool retap);
+ QRgb color() const;
void setColor(const QRgb color);
void setPlotStyle(int style);
- const QString valueUnitLabel();
+ QString valueUnitLabel() const;
+ format_size_units_e formatUnits() const;
+ io_graph_item_unit_t valueUnits() const { return val_units_; }
void setValueUnits(int val_units);
- const QString valueUnitField() { return vu_field_; }
+ QString valueUnitField() const { return vu_field_; }
void setValueUnitField(const QString &vu_field);
- unsigned int movingAveragePeriod() { return moving_avg_period_; }
+ unsigned int movingAveragePeriod() const { return moving_avg_period_; }
void setInterval(int interval);
bool addToLegend();
bool removeFromLegend();
- QCPGraph *graph() { return graph_; }
- QCPBars *bars() { return bars_; }
- double startOffset();
- int packetFromTime(double ts);
+ QCPGraph *graph() const { return graph_; }
+ QCPBars *bars() const { return bars_; }
+ double startOffset() const;
+ nstime_t startTime() const;
+ int packetFromTime(double ts) const;
bool hasItemToShow(int idx, double value) const;
double getItemValue(int idx, const capture_file *cap_file) const;
int maxInterval () const { return cur_idx_; }
- QString scaledValueUnit() const { return scaled_value_unit_; }
void clearAllData();
@@ -85,7 +103,7 @@ public:
unsigned int y_axis_factor_;
public slots:
- void recalcGraphData(capture_file *cap_file, bool enable_scaling);
+ void recalcGraphData(capture_file *cap_file);
void captureEvent(CaptureEvent e);
void reloadValueUnitField();
@@ -100,28 +118,33 @@ private:
static tap_packet_status tapPacket(void *iog_ptr, packet_info *pinfo, epan_dissect_t *edt, const void *data, tap_flags_t flags);
static void tapDraw(void *iog_ptr);
- void calculateScaledValueUnit();
+ void removeTapListener();
+
+ bool showsZero() const;
+
template<class DataMap> double maxValueFromGraphData(const DataMap &map);
template<class DataMap> void scaleGraphData(DataMap &map, int scalar);
QCustomPlot *parent_;
QString config_err_;
QString name_;
+ bool tap_registered_;
bool visible_;
+ bool need_retap_;
QCPGraph *graph_;
QCPBars *bars_;
QString filter_;
+ QString full_filter_; // Includes vu_field_ if used
QBrush color_;
io_graph_item_unit_t val_units_;
QString vu_field_;
int hf_index_;
int interval_;
- double start_time_;
- QString scaled_value_unit_;
+ nstime_t start_time_;
// Cached data. We should be able to change the Y axis without retapping as
// much as is feasible.
- io_graph_item_t items_[max_io_items_];
+ std::vector<io_graph_item_t> items_;
int cur_idx_;
};
@@ -134,40 +157,50 @@ class IOGraphDialog : public WiresharkDialog
Q_OBJECT
public:
- explicit IOGraphDialog(QWidget &parent, CaptureFile &cf, QString displayFilter = QString());
+ explicit IOGraphDialog(QWidget &parent, CaptureFile &cf, QString displayFilter = QString(), io_graph_item_unit_t value_units = IOG_ITEM_UNIT_PACKETS, QString yfield = QString());
~IOGraphDialog();
enum UatColumns { colEnabled = 0, colName, colDFilter, colColor, colStyle, colYAxis, colYField, colSMAPeriod, colYAxisFactor, colMaxNum};
void addGraph(bool checked, QString name, QString dfilter, QRgb color_idx, IOGraph::PlotStyles style,
io_graph_item_unit_t value_units, QString yfield, int moving_average, int yaxisfactor);
+ void addGraph(bool checked, QString dfilter, io_graph_item_unit_t value_units, QString yfield);
void addGraph(bool copy_from_current = false);
void addDefaultGraph(bool enabled, int idx = 0);
void syncGraphSettings(int row);
+ qsizetype graphCount() const;
public slots:
void scheduleReplot(bool now = false);
void scheduleRecalc(bool now = false);
void scheduleRetap(bool now = false);
- void modelRowsReset();
void reloadFields();
protected:
+ void captureFileClosing();
void keyPressEvent(QKeyEvent *event);
void reject();
+protected slots:
+ void modelDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles);
+ void modelRowsReset();
+ void modelRowsInserted(const QModelIndex &parent, int first, int last);
+ void modelRowsRemoved(const QModelIndex &parent, int first, int last);
+ void modelRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow);
+
signals:
void goToPacket(int packet_num);
- void recalcGraphData(capture_file *cap_file, bool enable_scaling);
+ void recalcGraphData(capture_file *cap_file);
void intervalChanged(int interval);
void reloadValueUnitFields();
private:
Ui::IOGraphDialog *ui;
+ CopyFromProfileButton *copy_profile_bt_;
//Model and delegate were chosen over UatFrame because add/remove/copy
//buttons would need realignment (UatFrame has its own)
- UatModel *uat_model_;
+ QPointer<UatModel> uat_model_;
UatDelegate *uat_delegate_;
// XXX - This needs to stay synced with UAT index
@@ -176,8 +209,8 @@ private:
QString hint_err_;
QCPGraph *base_graph_;
QCPItemTracer *tracer_;
- guint32 packet_num_;
- double start_time_;
+ uint32_t packet_num_;
+ nstime_t start_time_;
bool mouse_drags_;
QRubberBand *rubber_band_;
QPoint rb_origin_;
@@ -187,6 +220,7 @@ private:
bool need_recalc_; // Medium weight: recalculate values, then replot
bool need_retap_; // Heavy weight: re-read packet data
bool auto_axes_;
+ int precision_;
QSharedPointer<QCPAxisTicker> number_ticker_;
QSharedPointer<QCPAxisTickerDateTime> datetime_ticker_;
@@ -199,6 +233,7 @@ private:
void panAxes(int x_pixels, int y_pixels);
void toggleTracerStyle(bool force_default = false);
void getGraphInfo();
+ void updateHint();
void updateLegend();
QRectF getZoomRanges(QRect zoom_rect);
void createIOGraph(int currentRow);
@@ -209,22 +244,26 @@ private:
bool graphIsEnabled(int row) const;
private slots:
+ static void applyChanges();
+
void copyFromProfile(QString filename);
void updateWidgets();
+ void showContextMenu(const QPoint &pos);
void graphClicked(QMouseEvent *event);
void mouseMoved(QMouseEvent *event);
void mouseReleased(QMouseEvent *event);
+ void selectedFrameChanged(QList<int> frames);
+ void moveLegend();
void resetAxes();
void updateStatistics(void);
void copyAsCsvClicked();
+ void graphUatSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
void on_intervalComboBox_currentIndexChanged(int index);
void on_todCheckBox_toggled(bool checked);
- void modelDataChanged(const QModelIndex &index);
void on_graphUat_currentItemChanged(const QModelIndex &current, const QModelIndex &previous);
- void on_resetButton_clicked();
void on_logCheckBox_toggled(bool checked);
void on_automaticUpdateCheckBox_toggled(bool checked);
void on_enableLegendCheckBox_toggled(bool checked);
@@ -257,6 +296,7 @@ private slots:
void on_actionCrosshairs_triggered();
void on_buttonBox_helpRequested();
void on_buttonBox_accepted();
+ void buttonBoxClicked(QAbstractButton *button);
};
#endif // IO_GRAPH_DIALOG_H
diff --git a/ui/qt/io_graph_dialog.ui b/ui/qt/io_graph_dialog.ui
index 91f071ee..25cc41c7 100644
--- a/ui/qt/io_graph_dialog.ui
+++ b/ui/qt/io_graph_dialog.ui
@@ -72,7 +72,7 @@
</item>
</layout>
</widget>
- <widget class="TabnavTreeView" name="graphUat">
+ <widget class="RowMoveTreeView" name="graphUat">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
@@ -97,14 +97,14 @@
<item>
<widget class="StockIconToolButton" name="deleteToolButton">
<property name="toolTip">
- <string>Remove this graph.</string>
+ <string>Remove the selected graph(s).</string>
</property>
</widget>
</item>
<item>
<widget class="StockIconToolButton" name="copyToolButton">
<property name="toolTip">
- <string>Duplicate this graph.</string>
+ <string>Duplicate the selected graph(s).</string>
</property>
<property name="text">
<string/>
@@ -112,32 +112,32 @@
</widget>
</item>
<item>
- <widget class="StockIconToolButton" name="clearToolButton">
+ <widget class="StockIconToolButton" name="moveUpwardsToolButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
- <string>Clear all graphs.</string>
+ <string>Move the selected graph(s) upwards.</string>
</property>
</widget>
</item>
<item>
- <widget class="StockIconToolButton" name="moveUpwardsToolButton">
+ <widget class="StockIconToolButton" name="moveDownwardsToolButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
- <string>Move this graph upwards.</string>
+ <string>Move the selected graph(s) downwards.</string>
</property>
</widget>
</item>
<item>
- <widget class="StockIconToolButton" name="moveDownwardsToolButton">
+ <widget class="StockIconToolButton" name="clearToolButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
- <string>Move this graph downwards.</string>
+ <string>Clear all graphs.</string>
</property>
</widget>
</item>
@@ -290,26 +290,6 @@
</property>
</widget>
</item>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="resetButton">
- <property name="text">
- <string>Reset</string>
- </property>
- </widget>
- </item>
</layout>
</item>
<item>
@@ -318,7 +298,7 @@
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
- <set>QDialogButtonBox::Close|QDialogButtonBox::Help|QDialogButtonBox::Save</set>
+ <set>QDialogButtonBox::Close|QDialogButtonBox::Help|QDialogButtonBox::Save|QDialogButtonBox::Reset</set>
</property>
</widget>
</item>
@@ -540,9 +520,14 @@
<header>widgets/elided_label.h</header>
</customwidget>
<customwidget>
- <class>TabnavTreeView</class>
+ <class>RowMoveTreeView</class>
<extends>QTreeView</extends>
- <header>widgets/tabnav_tree_view.h</header>
+ <header>widgets/rowmove_tree_view.h</header>
+ </customwidget>
+ <customwidget>
+ <class>ResizeHeaderView</class>
+ <extends>QHeaderView</extends>
+ <header>widgets/resize_header_view.h</header>
</customwidget>
<customwidget>
<class>StockIconToolButton</class>
@@ -555,6 +540,11 @@
<header>widgets/qcustomplot.h</header>
<container>1</container>
</customwidget>
+ <customwidget>
+ <class>QCPStringLegendItem</class>
+ <extends>QCPAbstractLegendItem</extends>
+ <header>widgets/qcp_string_legend_item.h</header>
+ </customwidget>
</customwidgets>
<resources/>
<connections>
diff --git a/ui/qt/layout_preferences_frame.cpp b/ui/qt/layout_preferences_frame.cpp
index 07b97c57..693ef228 100644
--- a/ui/qt/layout_preferences_frame.cpp
+++ b/ui/qt/layout_preferences_frame.cpp
@@ -358,22 +358,22 @@ void LayoutPreferencesFrame::on_restoreButtonBox_clicked(QAbstractButton *)
void LayoutPreferencesFrame::on_packetListSeparatorCheckBox_toggled(bool checked)
{
- prefs_set_bool_value(pref_packet_list_separator_, (gboolean) checked, pref_stashed);
+ prefs_set_bool_value(pref_packet_list_separator_, (bool) checked, pref_stashed);
}
void LayoutPreferencesFrame::on_packetListHeaderShowColumnDefinition_toggled(bool checked)
{
- prefs_set_bool_value(pref_packet_header_column_definition_, (gboolean) checked, pref_stashed);
+ prefs_set_bool_value(pref_packet_header_column_definition_, (bool) checked, pref_stashed);
}
void LayoutPreferencesFrame::on_packetListHoverStyleCheckbox_toggled(bool checked)
{
- prefs_set_bool_value(pref_packet_list_hover_style_, (gboolean) checked, pref_stashed);
+ prefs_set_bool_value(pref_packet_list_hover_style_, (bool) checked, pref_stashed);
}
void LayoutPreferencesFrame::on_packetListAllowSorting_toggled(bool checked)
{
- prefs_set_bool_value(pref_packet_list_sorting_, (gboolean) checked, pref_stashed);
+ prefs_set_bool_value(pref_packet_list_sorting_, (bool) checked, pref_stashed);
}
void LayoutPreferencesFrame::on_packetListCachedRowsLineEdit_textEdited(const QString &new_str)
@@ -387,10 +387,10 @@ void LayoutPreferencesFrame::on_packetListCachedRowsLineEdit_textEdited(const QS
void LayoutPreferencesFrame::on_statusBarShowSelectedPacketCheckBox_toggled(bool checked)
{
- prefs_set_bool_value(pref_show_selected_packet_, (gboolean) checked, pref_stashed);
+ prefs_set_bool_value(pref_show_selected_packet_, (bool) checked, pref_stashed);
}
void LayoutPreferencesFrame::on_statusBarShowFileLoadTimeCheckBox_toggled(bool checked)
{
- prefs_set_bool_value(pref_show_file_load_time_, (gboolean) checked, pref_stashed);
+ prefs_set_bool_value(pref_show_file_load_time_, (bool) checked, pref_stashed);
}
diff --git a/ui/qt/lbm_lbtrm_transport_dialog.cpp b/ui/qt/lbm_lbtrm_transport_dialog.cpp
index 9391183e..9f8b9301 100644
--- a/ui/qt/lbm_lbtrm_transport_dialog.cpp
+++ b/ui/qt/lbm_lbtrm_transport_dialog.cpp
@@ -69,7 +69,7 @@ namespace
static const double OneGigabit = OneMegabit * OneKilobit;
}
-static QString format_rate(const nstime_t & elapsed, guint64 bytes)
+static QString format_rate(const nstime_t & elapsed, uint64_t bytes)
{
QString result;
double elapsed_sec;
@@ -143,15 +143,15 @@ static QString format_rate(const nstime_t & elapsed, guint64 bytes)
class LBMLBTRMFrameEntry : public QTreeWidgetItem
{
public:
- LBMLBTRMFrameEntry(guint32 frame);
+ LBMLBTRMFrameEntry(uint32_t frame);
virtual ~LBMLBTRMFrameEntry(void) { }
- guint32 getFrame(void) { return (m_frame); }
+ uint32_t getFrame(void) { return (m_frame); }
private:
- guint32 m_frame;
+ uint32_t m_frame;
};
-LBMLBTRMFrameEntry::LBMLBTRMFrameEntry(guint32 frame) :
+LBMLBTRMFrameEntry::LBMLBTRMFrameEntry(uint32_t frame) :
QTreeWidgetItem(),
m_frame(frame)
{
@@ -160,25 +160,25 @@ LBMLBTRMFrameEntry::LBMLBTRMFrameEntry(guint32 frame) :
setText(Detail_Frame_Column, QString("%1").arg(m_frame));
}
-typedef QMap<guint32, LBMLBTRMFrameEntry *> LBMLBTRMFrameMap;
-typedef QMap<guint32, LBMLBTRMFrameEntry *>::iterator LBMLBTRMFrameMapIterator;
+typedef QMap<uint32_t, LBMLBTRMFrameEntry *> LBMLBTRMFrameMap;
+typedef QMap<uint32_t, LBMLBTRMFrameEntry *>::iterator LBMLBTRMFrameMapIterator;
// A SQN (SeQuence Number) entry
class LBMLBTRMSQNEntry : public QTreeWidgetItem
{
public:
- LBMLBTRMSQNEntry(guint32 sqn);
+ LBMLBTRMSQNEntry(uint32_t sqn);
virtual ~LBMLBTRMSQNEntry(void);
- void processFrame(guint32 frame);
+ void processFrame(uint32_t frame);
private:
LBMLBTRMSQNEntry(void);
- guint32 m_sqn;
- guint32 m_count;
+ uint32_t m_sqn;
+ uint32_t m_count;
LBMLBTRMFrameMap m_frames;
};
-LBMLBTRMSQNEntry::LBMLBTRMSQNEntry(guint32 sqn) :
+LBMLBTRMSQNEntry::LBMLBTRMSQNEntry(uint32_t sqn) :
QTreeWidgetItem(),
m_sqn(sqn),
m_count(0),
@@ -200,7 +200,7 @@ LBMLBTRMSQNEntry::~LBMLBTRMSQNEntry(void)
m_frames.clear();
}
-void LBMLBTRMSQNEntry::processFrame(guint32 frame)
+void LBMLBTRMSQNEntry::processFrame(uint32_t frame)
{
LBMLBTRMFrameMapIterator it;
@@ -221,19 +221,19 @@ void LBMLBTRMSQNEntry::processFrame(guint32 frame)
class LBMLBTRMNCFReasonEntry : public QTreeWidgetItem
{
public:
- LBMLBTRMNCFReasonEntry(guint8 reason);
+ LBMLBTRMNCFReasonEntry(uint8_t reason);
virtual ~LBMLBTRMNCFReasonEntry(void);
- void processFrame(guint32 frame);
+ void processFrame(uint32_t frame);
private:
LBMLBTRMNCFReasonEntry(void);
- guint8 m_reason;
+ uint8_t m_reason;
QString m_reason_string;
- guint32 m_count;
+ uint32_t m_count;
LBMLBTRMFrameMap m_frames;
};
-LBMLBTRMNCFReasonEntry::LBMLBTRMNCFReasonEntry(guint8 reason) :
+LBMLBTRMNCFReasonEntry::LBMLBTRMNCFReasonEntry(uint8_t reason) :
QTreeWidgetItem(),
m_reason(reason),
m_reason_string(),
@@ -273,7 +273,7 @@ LBMLBTRMNCFReasonEntry::~LBMLBTRMNCFReasonEntry(void)
m_frames.clear();
}
-void LBMLBTRMNCFReasonEntry::processFrame(guint32 frame)
+void LBMLBTRMNCFReasonEntry::processFrame(uint32_t frame)
{
LBMLBTRMFrameMapIterator it;
@@ -290,25 +290,25 @@ void LBMLBTRMNCFReasonEntry::processFrame(guint32 frame)
setTextAlignment(Detail_Count_Column, Qt::AlignRight);
}
-typedef QMap<guint32, LBMLBTRMNCFReasonEntry *> LBMLBTRMNCFReasonMap;
-typedef QMap<guint32, LBMLBTRMNCFReasonEntry *>::iterator LBMLBTRMNCFReasonMapIterator;
+typedef QMap<uint32_t, LBMLBTRMNCFReasonEntry *> LBMLBTRMNCFReasonMap;
+typedef QMap<uint32_t, LBMLBTRMNCFReasonEntry *>::iterator LBMLBTRMNCFReasonMapIterator;
// An NCF SQN entry
class LBMLBTRMNCFSQNEntry : public QTreeWidgetItem
{
public:
- LBMLBTRMNCFSQNEntry(guint32 sqn);
+ LBMLBTRMNCFSQNEntry(uint32_t sqn);
virtual ~LBMLBTRMNCFSQNEntry(void);
- void processFrame(guint8 reason, guint32 frame);
+ void processFrame(uint8_t reason, uint32_t frame);
private:
LBMLBTRMNCFSQNEntry(void);
- guint32 m_sqn;
- guint32 m_count;
+ uint32_t m_sqn;
+ uint32_t m_count;
LBMLBTRMNCFReasonMap m_reasons;
};
-LBMLBTRMNCFSQNEntry::LBMLBTRMNCFSQNEntry(guint32 sqn) :
+LBMLBTRMNCFSQNEntry::LBMLBTRMNCFSQNEntry(uint32_t sqn) :
QTreeWidgetItem(),
m_sqn(sqn),
m_count(0),
@@ -330,7 +330,7 @@ LBMLBTRMNCFSQNEntry::~LBMLBTRMNCFSQNEntry(void)
m_reasons.clear();
}
-void LBMLBTRMNCFSQNEntry::processFrame(guint8 reason, guint32 frame)
+void LBMLBTRMNCFSQNEntry::processFrame(uint8_t reason, uint32_t frame)
{
LBMLBTRMNCFReasonMapIterator it;
LBMLBTRMNCFReasonEntry * entry = NULL;
@@ -353,10 +353,10 @@ void LBMLBTRMNCFSQNEntry::processFrame(guint8 reason, guint32 frame)
entry->processFrame(frame);
}
-typedef QMap<guint32, LBMLBTRMSQNEntry *> LBMLBTRMSQNMap;
-typedef QMap<guint32, LBMLBTRMSQNEntry *>::iterator LBMLBTRMSQNMapIterator;
-typedef QMap<guint32, LBMLBTRMNCFSQNEntry *> LBMLBTRMNCFSQNMap;
-typedef QMap<guint32, LBMLBTRMNCFSQNEntry *>::iterator LBMLBTRMNCFSQNMapIterator;
+typedef QMap<uint32_t, LBMLBTRMSQNEntry *> LBMLBTRMSQNMap;
+typedef QMap<uint32_t, LBMLBTRMSQNEntry *>::iterator LBMLBTRMSQNMapIterator;
+typedef QMap<uint32_t, LBMLBTRMNCFSQNEntry *> LBMLBTRMNCFSQNMap;
+typedef QMap<uint32_t, LBMLBTRMNCFSQNEntry *>::iterator LBMLBTRMNCFSQNMapIterator;
// A source transport entry
class LBMLBTRMSourceTransportEntry : public QTreeWidgetItem
@@ -373,15 +373,15 @@ class LBMLBTRMSourceTransportEntry : public QTreeWidgetItem
private:
void fillItem(void);
- guint64 m_data_frames;
- guint64 m_data_bytes;
- guint64 m_rx_data_frames;
- guint64 m_rx_data_bytes;
- guint64 m_ncf_frames;
- guint64 m_ncf_count;
- guint64 m_ncf_bytes;
- guint64 m_sm_frames;
- guint64 m_sm_bytes;
+ uint64_t m_data_frames;
+ uint64_t m_data_bytes;
+ uint64_t m_rx_data_frames;
+ uint64_t m_rx_data_bytes;
+ uint64_t m_ncf_frames;
+ uint64_t m_ncf_count;
+ uint64_t m_ncf_bytes;
+ uint64_t m_sm_frames;
+ uint64_t m_sm_bytes;
nstime_t m_first_frame_timestamp;
bool m_first_frame_timestamp_valid;
nstime_t m_last_frame_timestamp;
@@ -502,13 +502,13 @@ void LBMLBTRMSourceTransportEntry::processPacket(const packet_info * pinfo, cons
}
else if (tap_info->type == LBTRM_PACKET_TYPE_NCF)
{
- guint16 idx;
+ uint16_t idx;
LBMLBTRMNCFSQNMapIterator it;
LBMLBTRMNCFSQNEntry * sqn = NULL;
m_ncf_frames++;
m_ncf_bytes += pinfo->fd->pkt_len;
- m_ncf_count += (guint64)tap_info->num_sqns;
+ m_ncf_count += (uint64_t)tap_info->num_sqns;
for (idx = 0; idx < tap_info->num_sqns; idx++)
{
it = m_ncf_sqns.find(tap_info->sqns[idx]);
@@ -612,15 +612,15 @@ class LBMLBTRMSourceEntry : public QTreeWidgetItem
void fillItem(void);
QString m_address;
QString m_transport;
- guint64 m_data_frames;
- guint64 m_data_bytes;
- guint64 m_rx_data_frames;
- guint64 m_rx_data_bytes;
- guint64 m_ncf_frames;
- guint64 m_ncf_count;
- guint64 m_ncf_bytes;
- guint64 m_sm_frames;
- guint64 m_sm_bytes;
+ uint64_t m_data_frames;
+ uint64_t m_data_bytes;
+ uint64_t m_rx_data_frames;
+ uint64_t m_rx_data_bytes;
+ uint64_t m_ncf_frames;
+ uint64_t m_ncf_count;
+ uint64_t m_ncf_bytes;
+ uint64_t m_sm_frames;
+ uint64_t m_sm_bytes;
nstime_t m_first_frame_timestamp;
bool m_first_frame_timestamp_valid;
nstime_t m_last_frame_timestamp;
@@ -783,9 +783,9 @@ class LBMLBTRMReceiverTransportEntry : public QTreeWidgetItem
private:
void fillItem(void);
QString m_transport;
- guint64 m_nak_frames;
- guint64 m_nak_count;
- guint64 m_nak_bytes;
+ uint64_t m_nak_frames;
+ uint64_t m_nak_count;
+ uint64_t m_nak_bytes;
nstime_t m_first_frame_timestamp;
bool m_first_frame_timestamp_valid;
nstime_t m_last_frame_timestamp;
@@ -839,7 +839,7 @@ void LBMLBTRMReceiverTransportEntry::processPacket(const packet_info * pinfo, co
}
if (tap_info->type == LBTRM_PACKET_TYPE_NAK)
{
- guint16 idx;
+ uint16_t idx;
LBMLBTRMSQNEntry * sqn = NULL;
LBMLBTRMSQNMapIterator it;
@@ -899,9 +899,9 @@ class LBMLBTRMReceiverEntry : public QTreeWidgetItem
void fillItem(void);
QString m_address;
QString m_transport;
- guint64 m_nak_frames;
- guint64 m_nak_count;
- guint64 m_nak_bytes;
+ uint64_t m_nak_frames;
+ uint64_t m_nak_count;
+ uint64_t m_nak_bytes;
nstime_t m_first_frame_timestamp;
bool m_first_frame_timestamp_valid;
nstime_t m_last_frame_timestamp;
diff --git a/ui/qt/lbm_lbtrm_transport_dialog.h b/ui/qt/lbm_lbtrm_transport_dialog.h
index 2e31dc50..5e6b66be 100644
--- a/ui/qt/lbm_lbtrm_transport_dialog.h
+++ b/ui/qt/lbm_lbtrm_transport_dialog.h
@@ -14,8 +14,6 @@
#include <config.h>
-#include <glib.h>
-
#include "cfile.h"
#include <epan/packet_info.h>
#include <epan/tap.h>
diff --git a/ui/qt/lbm_lbtru_transport_dialog.cpp b/ui/qt/lbm_lbtru_transport_dialog.cpp
index 529d7776..cc98c3d5 100644
--- a/ui/qt/lbm_lbtru_transport_dialog.cpp
+++ b/ui/qt/lbm_lbtru_transport_dialog.cpp
@@ -87,7 +87,7 @@ namespace
static const double OneGigabit = OneMegabit * OneKilobit;
}
-static QString format_rate(const nstime_t & elapsed, guint64 bytes)
+static QString format_rate(const nstime_t & elapsed, uint64_t bytes)
{
QString result;
double elapsed_sec;
@@ -161,15 +161,15 @@ static QString format_rate(const nstime_t & elapsed, guint64 bytes)
class LBMLBTRUFrameEntry : public QTreeWidgetItem
{
public:
- LBMLBTRUFrameEntry(guint32 frame);
+ LBMLBTRUFrameEntry(uint32_t frame);
virtual ~LBMLBTRUFrameEntry(void) { }
- guint32 getFrame(void) { return (m_frame); }
+ uint32_t getFrame(void) { return (m_frame); }
private:
- guint32 m_frame;
+ uint32_t m_frame;
};
-LBMLBTRUFrameEntry::LBMLBTRUFrameEntry(guint32 frame) :
+LBMLBTRUFrameEntry::LBMLBTRUFrameEntry(uint32_t frame) :
QTreeWidgetItem(),
m_frame(frame)
{
@@ -178,25 +178,25 @@ LBMLBTRUFrameEntry::LBMLBTRUFrameEntry(guint32 frame) :
setText(Detail_Frame_Column, QString("%1").arg(m_frame));
}
-typedef QMap<guint32, LBMLBTRUFrameEntry *> LBMLBTRUFrameMap;
-typedef QMap<guint32, LBMLBTRUFrameEntry *>::iterator LBMLBTRUFrameMapIterator;
+typedef QMap<uint32_t, LBMLBTRUFrameEntry *> LBMLBTRUFrameMap;
+typedef QMap<uint32_t, LBMLBTRUFrameEntry *>::iterator LBMLBTRUFrameMapIterator;
// An SQN (SeQuence Number) entry
class LBMLBTRUSQNEntry : public QTreeWidgetItem
{
public:
- LBMLBTRUSQNEntry(guint32 sqn);
+ LBMLBTRUSQNEntry(uint32_t sqn);
virtual ~LBMLBTRUSQNEntry(void);
- void processFrame(guint32 frame);
+ void processFrame(uint32_t frame);
private:
LBMLBTRUSQNEntry(void);
- guint32 m_sqn;
- guint32 m_count;
+ uint32_t m_sqn;
+ uint32_t m_count;
LBMLBTRUFrameMap m_frames;
};
-LBMLBTRUSQNEntry::LBMLBTRUSQNEntry(guint32 sqn) :
+LBMLBTRUSQNEntry::LBMLBTRUSQNEntry(uint32_t sqn) :
QTreeWidgetItem(),
m_sqn(sqn),
m_count(0),
@@ -218,7 +218,7 @@ LBMLBTRUSQNEntry::~LBMLBTRUSQNEntry(void)
m_frames.clear();
}
-void LBMLBTRUSQNEntry::processFrame(guint32 frame)
+void LBMLBTRUSQNEntry::processFrame(uint32_t frame)
{
LBMLBTRUFrameMapIterator it;
@@ -239,18 +239,18 @@ void LBMLBTRUSQNEntry::processFrame(guint32 frame)
class LBMLBTRUNCFReasonEntry : public QTreeWidgetItem
{
public:
- LBMLBTRUNCFReasonEntry(guint8 reason);
+ LBMLBTRUNCFReasonEntry(uint8_t reason);
virtual ~LBMLBTRUNCFReasonEntry(void);
- void processFrame(guint32 frame);
+ void processFrame(uint32_t frame);
private:
LBMLBTRUNCFReasonEntry(void);
- guint8 m_reason;
- guint32 m_count;
+ uint8_t m_reason;
+ uint32_t m_count;
LBMLBTRUFrameMap m_frames;
};
-LBMLBTRUNCFReasonEntry::LBMLBTRUNCFReasonEntry(guint8 reason) :
+LBMLBTRUNCFReasonEntry::LBMLBTRUNCFReasonEntry(uint8_t reason) :
QTreeWidgetItem(),
m_reason(reason),
m_count(0),
@@ -288,7 +288,7 @@ LBMLBTRUNCFReasonEntry::~LBMLBTRUNCFReasonEntry(void)
m_frames.clear();
}
-void LBMLBTRUNCFReasonEntry::processFrame(guint32 frame)
+void LBMLBTRUNCFReasonEntry::processFrame(uint32_t frame)
{
LBMLBTRUFrameMapIterator it;
@@ -305,25 +305,25 @@ void LBMLBTRUNCFReasonEntry::processFrame(guint32 frame)
setTextAlignment(Detail_Count_Column, Qt::AlignRight);
}
-typedef QMap<guint8, LBMLBTRUNCFReasonEntry *> LBMLBTRUNCFReasonMap;
-typedef QMap<guint8, LBMLBTRUNCFReasonEntry *>::iterator LBMLBTRUNCFReasonMapIterator;
+typedef QMap<uint8_t, LBMLBTRUNCFReasonEntry *> LBMLBTRUNCFReasonMap;
+typedef QMap<uint8_t, LBMLBTRUNCFReasonEntry *>::iterator LBMLBTRUNCFReasonMapIterator;
// An NCF SQN entry
class LBMLBTRUNCFSQNEntry : public QTreeWidgetItem
{
public:
- LBMLBTRUNCFSQNEntry(guint32 sqn);
+ LBMLBTRUNCFSQNEntry(uint32_t sqn);
virtual ~LBMLBTRUNCFSQNEntry(void);
- void processFrame(guint8 reason, guint32 frame);
+ void processFrame(uint8_t reason, uint32_t frame);
private:
LBMLBTRUNCFSQNEntry(void);
- guint32 m_sqn;
- guint32 m_count;
+ uint32_t m_sqn;
+ uint32_t m_count;
LBMLBTRUNCFReasonMap m_reasons;
};
-LBMLBTRUNCFSQNEntry::LBMLBTRUNCFSQNEntry(guint32 sqn) :
+LBMLBTRUNCFSQNEntry::LBMLBTRUNCFSQNEntry(uint32_t sqn) :
QTreeWidgetItem(),
m_sqn(sqn),
m_count(0),
@@ -345,7 +345,7 @@ LBMLBTRUNCFSQNEntry::~LBMLBTRUNCFSQNEntry(void)
m_reasons.clear();
}
-void LBMLBTRUNCFSQNEntry::processFrame(guint8 reason, guint32 frame)
+void LBMLBTRUNCFSQNEntry::processFrame(uint8_t reason, uint32_t frame)
{
LBMLBTRUNCFReasonMapIterator it;
LBMLBTRUNCFReasonEntry * entry = NULL;
@@ -372,19 +372,19 @@ void LBMLBTRUNCFSQNEntry::processFrame(guint8 reason, guint32 frame)
class LBMLBTRURSTReasonEntry : public QTreeWidgetItem
{
public:
- LBMLBTRURSTReasonEntry(guint32 reason);
+ LBMLBTRURSTReasonEntry(uint32_t reason);
virtual ~LBMLBTRURSTReasonEntry(void);
- void processFrame(guint32 frame);
+ void processFrame(uint32_t frame);
private:
LBMLBTRURSTReasonEntry(void);
- guint32 m_reason;
+ uint32_t m_reason;
QString m_reason_string;
- guint32 m_count;
+ uint32_t m_count;
LBMLBTRUFrameMap m_frames;
};
-LBMLBTRURSTReasonEntry::LBMLBTRURSTReasonEntry(guint32 reason) :
+LBMLBTRURSTReasonEntry::LBMLBTRURSTReasonEntry(uint32_t reason) :
QTreeWidgetItem(),
m_reason(reason),
m_reason_string(),
@@ -416,7 +416,7 @@ LBMLBTRURSTReasonEntry::~LBMLBTRURSTReasonEntry(void)
m_frames.clear();
}
-void LBMLBTRURSTReasonEntry::processFrame(guint32 frame)
+void LBMLBTRURSTReasonEntry::processFrame(uint32_t frame)
{
LBMLBTRUFrameMapIterator it;
@@ -437,19 +437,19 @@ void LBMLBTRURSTReasonEntry::processFrame(guint32 frame)
class LBMLBTRUCREQRequestEntry : public QTreeWidgetItem
{
public:
- LBMLBTRUCREQRequestEntry(guint32 request);
+ LBMLBTRUCREQRequestEntry(uint32_t request);
virtual ~LBMLBTRUCREQRequestEntry(void);
- void processFrame(guint32 frame);
+ void processFrame(uint32_t frame);
private:
LBMLBTRUCREQRequestEntry(void);
- guint32 m_request;
+ uint32_t m_request;
QString m_request_string;
- guint32 m_count;
+ uint32_t m_count;
LBMLBTRUFrameMap m_frames;
};
-LBMLBTRUCREQRequestEntry::LBMLBTRUCREQRequestEntry(guint32 request) :
+LBMLBTRUCREQRequestEntry::LBMLBTRUCREQRequestEntry(uint32_t request) :
QTreeWidgetItem(),
m_request(request),
m_request_string(),
@@ -481,7 +481,7 @@ LBMLBTRUCREQRequestEntry::~LBMLBTRUCREQRequestEntry(void)
m_frames.clear();
}
-void LBMLBTRUCREQRequestEntry::processFrame(guint32 frame)
+void LBMLBTRUCREQRequestEntry::processFrame(uint32_t frame)
{
LBMLBTRUFrameMapIterator it;
@@ -498,14 +498,14 @@ void LBMLBTRUCREQRequestEntry::processFrame(guint32 frame)
setTextAlignment(Detail_Count_Column, Qt::AlignRight);
}
-typedef QMap<guint32, LBMLBTRUSQNEntry *> LBMLBTRUSQNMap;
-typedef QMap<guint32, LBMLBTRUSQNEntry *>::iterator LBMLBTRUSQNMapIterator;
-typedef QMap<guint32, LBMLBTRUNCFSQNEntry *> LBMLBTRUNCFSQNMap;
-typedef QMap<guint32, LBMLBTRUNCFSQNEntry *>::iterator LBMLBTRUNCFSQNMapIterator;
-typedef QMap<guint32, LBMLBTRURSTReasonEntry *> LBMLBTRURSTReasonMap;
-typedef QMap<guint32, LBMLBTRURSTReasonEntry *>::iterator LBMLBTRURSTReasonMapIterator;
-typedef QMap<guint32, LBMLBTRUCREQRequestEntry *> LBMLBTRUCREQRequestMap;
-typedef QMap<guint32, LBMLBTRUCREQRequestEntry *>::iterator LBMLBTRUCREQRequestMapIterator;
+typedef QMap<uint32_t, LBMLBTRUSQNEntry *> LBMLBTRUSQNMap;
+typedef QMap<uint32_t, LBMLBTRUSQNEntry *>::iterator LBMLBTRUSQNMapIterator;
+typedef QMap<uint32_t, LBMLBTRUNCFSQNEntry *> LBMLBTRUNCFSQNMap;
+typedef QMap<uint32_t, LBMLBTRUNCFSQNEntry *>::iterator LBMLBTRUNCFSQNMapIterator;
+typedef QMap<uint32_t, LBMLBTRURSTReasonEntry *> LBMLBTRURSTReasonMap;
+typedef QMap<uint32_t, LBMLBTRURSTReasonEntry *>::iterator LBMLBTRURSTReasonMapIterator;
+typedef QMap<uint32_t, LBMLBTRUCREQRequestEntry *> LBMLBTRUCREQRequestMap;
+typedef QMap<uint32_t, LBMLBTRUCREQRequestEntry *>::iterator LBMLBTRUCREQRequestMapIterator;
// A source transport entry
class LBMLBTRUSourceTransportEntry : public QTreeWidgetItem
@@ -522,17 +522,17 @@ class LBMLBTRUSourceTransportEntry : public QTreeWidgetItem
private:
void fillItem(void);
- guint64 m_data_frames;
- guint64 m_data_bytes;
- guint64 m_rx_data_frames;
- guint64 m_rx_data_bytes;
- guint64 m_ncf_frames;
- guint64 m_ncf_count;
- guint64 m_ncf_bytes;
- guint64 m_sm_frames;
- guint64 m_sm_bytes;
- guint64 m_rst_frames;
- guint64 m_rst_bytes;
+ uint64_t m_data_frames;
+ uint64_t m_data_bytes;
+ uint64_t m_rx_data_frames;
+ uint64_t m_rx_data_bytes;
+ uint64_t m_ncf_frames;
+ uint64_t m_ncf_count;
+ uint64_t m_ncf_bytes;
+ uint64_t m_sm_frames;
+ uint64_t m_sm_bytes;
+ uint64_t m_rst_frames;
+ uint64_t m_rst_bytes;
nstime_t m_first_frame_timestamp;
bool m_first_frame_timestamp_valid;
nstime_t m_last_frame_timestamp;
@@ -664,13 +664,13 @@ void LBMLBTRUSourceTransportEntry::processPacket(const packet_info * pinfo, cons
}
else if (tap_info->type == LBTRU_PACKET_TYPE_NCF)
{
- guint16 idx;
+ uint16_t idx;
LBMLBTRUNCFSQNMapIterator it;
LBMLBTRUNCFSQNEntry * sqn = NULL;
m_ncf_frames++;
m_ncf_bytes += pinfo->fd->pkt_len;
- m_ncf_count += (guint64)tap_info->num_sqns;
+ m_ncf_count += (uint64_t)tap_info->num_sqns;
for (idx = 0; idx < tap_info->num_sqns; idx++)
{
it = m_ncf_sqns.find(tap_info->sqns[idx]);
@@ -801,17 +801,17 @@ class LBMLBTRUSourceEntry : public QTreeWidgetItem
void fillItem(void);
QString m_address;
QString m_transport;
- guint64 m_data_frames;
- guint64 m_data_bytes;
- guint64 m_rx_data_frames;
- guint64 m_rx_data_bytes;
- guint64 m_ncf_frames;
- guint64 m_ncf_count;
- guint64 m_ncf_bytes;
- guint64 m_sm_frames;
- guint64 m_sm_bytes;
- guint64 m_rst_frames;
- guint64 m_rst_bytes;
+ uint64_t m_data_frames;
+ uint64_t m_data_bytes;
+ uint64_t m_rx_data_frames;
+ uint64_t m_rx_data_bytes;
+ uint64_t m_ncf_frames;
+ uint64_t m_ncf_count;
+ uint64_t m_ncf_bytes;
+ uint64_t m_sm_frames;
+ uint64_t m_sm_bytes;
+ uint64_t m_rst_frames;
+ uint64_t m_rst_bytes;
nstime_t m_first_frame_timestamp;
bool m_first_frame_timestamp_valid;
nstime_t m_last_frame_timestamp;
@@ -988,13 +988,13 @@ class LBMLBTRUReceiverTransportEntry : public QTreeWidgetItem
private:
void fillItem(void);
QString m_transport;
- guint64 m_nak_frames;
- guint64 m_nak_count;
- guint64 m_nak_bytes;
- guint64 m_ack_frames;
- guint64 m_ack_bytes;
- guint64 m_creq_frames;
- guint64 m_creq_bytes;
+ uint64_t m_nak_frames;
+ uint64_t m_nak_count;
+ uint64_t m_nak_bytes;
+ uint64_t m_ack_frames;
+ uint64_t m_ack_bytes;
+ uint64_t m_creq_frames;
+ uint64_t m_creq_bytes;
nstime_t m_first_frame_timestamp;
bool m_first_frame_timestamp_valid;
nstime_t m_last_frame_timestamp;
@@ -1070,7 +1070,7 @@ void LBMLBTRUReceiverTransportEntry::processPacket(const packet_info * pinfo, co
{
case LBTRU_PACKET_TYPE_NAK:
{
- guint16 idx;
+ uint16_t idx;
LBMLBTRUSQNEntry * sqn = NULL;
LBMLBTRUSQNMapIterator it;
@@ -1135,7 +1135,6 @@ void LBMLBTRUReceiverTransportEntry::processPacket(const packet_info * pinfo, co
break;
default:
return;
- break;
}
fillItem();
}
@@ -1194,13 +1193,13 @@ class LBMLBTRUReceiverEntry : public QTreeWidgetItem
void fillItem(void);
QString m_address;
QString m_transport;
- guint64 m_nak_frames;
- guint64 m_nak_count;
- guint64 m_nak_bytes;
- guint64 m_ack_frames;
- guint64 m_ack_bytes;
- guint64 m_creq_frames;
- guint64 m_creq_bytes;
+ uint64_t m_nak_frames;
+ uint64_t m_nak_count;
+ uint64_t m_nak_bytes;
+ uint64_t m_ack_frames;
+ uint64_t m_ack_bytes;
+ uint64_t m_creq_frames;
+ uint64_t m_creq_bytes;
nstime_t m_first_frame_timestamp;
bool m_first_frame_timestamp_valid;
nstime_t m_last_frame_timestamp;
diff --git a/ui/qt/lbm_lbtru_transport_dialog.h b/ui/qt/lbm_lbtru_transport_dialog.h
index 56590102..b606fe84 100644
--- a/ui/qt/lbm_lbtru_transport_dialog.h
+++ b/ui/qt/lbm_lbtru_transport_dialog.h
@@ -14,8 +14,6 @@
#include <config.h>
-#include <glib.h>
-
#include "cfile.h"
#include <epan/packet_info.h>
#include <epan/tap.h>
diff --git a/ui/qt/lbm_stream_dialog.cpp b/ui/qt/lbm_stream_dialog.cpp
index 65ddcc47..8988240b 100644
--- a/ui/qt/lbm_stream_dialog.cpp
+++ b/ui/qt/lbm_stream_dialog.cpp
@@ -44,9 +44,9 @@ namespace
class LBMSubstreamEntry
{
public:
- LBMSubstreamEntry(guint64 channel, guint32 substream_id, const address * source_address, guint16 source_port, const address * destination_address, guint16 destination_port);
+ LBMSubstreamEntry(uint64_t channel, uint32_t substream_id, const address * source_address, uint16_t source_port, const address * destination_address, uint16_t destination_port);
~LBMSubstreamEntry(void);
- void processPacket(guint32 frame, guint32 bytes);
+ void processPacket(uint32_t frame, uint32_t bytes);
void setItem(QTreeWidgetItem * item);
QTreeWidgetItem * getItem(void)
{
@@ -54,22 +54,22 @@ class LBMSubstreamEntry
}
private:
- void fillItem(gboolean update_only = TRUE);
- guint64 m_channel;
- guint32 m_substream_id;
+ void fillItem(bool update_only = true);
+ uint64_t m_channel;
+ uint32_t m_substream_id;
QString m_endpoint_a;
QString m_endpoint_b;
- guint32 m_first_frame;
- guint32 m_flast_frame;
- guint32 m_messages;
- guint32 m_bytes;
+ uint32_t m_first_frame;
+ uint32_t m_flast_frame;
+ uint32_t m_messages;
+ uint32_t m_bytes;
QTreeWidgetItem * m_item;
};
-LBMSubstreamEntry::LBMSubstreamEntry(guint64 channel, guint32 substream_id, const address * source_address, guint16 source_port, const address * destination_address, guint16 destination_port) :
+LBMSubstreamEntry::LBMSubstreamEntry(uint64_t channel, uint32_t substream_id, const address * source_address, uint16_t source_port, const address * destination_address, uint16_t destination_port) :
m_channel(channel),
m_substream_id(substream_id),
- m_first_frame((guint32)(~0)),
+ m_first_frame((uint32_t)(~0)),
m_flast_frame(0),
m_messages(0),
m_bytes(0),
@@ -87,7 +87,7 @@ LBMSubstreamEntry::~LBMSubstreamEntry(void)
{
}
-void LBMSubstreamEntry::processPacket(guint32 frame, guint32 bytes)
+void LBMSubstreamEntry::processPacket(uint32_t frame, uint32_t bytes)
{
if (m_first_frame > frame)
{
@@ -105,12 +105,12 @@ void LBMSubstreamEntry::processPacket(guint32 frame, guint32 bytes)
void LBMSubstreamEntry::setItem(QTreeWidgetItem * item)
{
m_item = item;
- fillItem(FALSE);
+ fillItem(false);
}
-void LBMSubstreamEntry::fillItem(gboolean update_only)
+void LBMSubstreamEntry::fillItem(bool update_only)
{
- if (update_only == FALSE)
+ if (update_only == false)
{
m_item->setText(Stream_Column, QString("%1.%2").arg(m_channel).arg(m_substream_id));
m_item->setText(EndpointA_Column, m_endpoint_a);
@@ -122,13 +122,13 @@ void LBMSubstreamEntry::fillItem(gboolean update_only)
m_item->setText(LastFrame_Column, QString("%1").arg(m_flast_frame));
}
-typedef QMap<guint32, LBMSubstreamEntry *> LBMSubstreamMap;
-typedef QMap<guint32, LBMSubstreamEntry *>::iterator LBMSubstreamMapIterator;
+typedef QMap<uint32_t, LBMSubstreamEntry *> LBMSubstreamMap;
+typedef QMap<uint32_t, LBMSubstreamEntry *>::iterator LBMSubstreamMapIterator;
class LBMStreamEntry
{
public:
- LBMStreamEntry(const packet_info * pinfo, guint64 channel, const lbm_uim_stream_endpoint_t * endpoint_a, const lbm_uim_stream_endpoint_t * endpoint_b);
+ LBMStreamEntry(const packet_info * pinfo, uint64_t channel, const lbm_uim_stream_endpoint_t * endpoint_a, const lbm_uim_stream_endpoint_t * endpoint_b);
~LBMStreamEntry(void);
void processPacket(const packet_info * pinfo, const lbm_uim_stream_tap_info_t * stream_info);
void setItem(QTreeWidgetItem * item);
@@ -138,22 +138,22 @@ class LBMStreamEntry
}
private:
- void fillItem(gboolean update_only = TRUE);
+ void fillItem(bool update_only = true);
QString formatEndpoint(const packet_info * pinfo, const lbm_uim_stream_endpoint_t * endpoint);
- guint64 m_channel;
+ uint64_t m_channel;
QString m_endpoint_a;
QString m_endpoint_b;
- guint32 m_first_frame;
- guint32 m_flast_frame;
- guint32 m_messages;
- guint32 m_bytes;
+ uint32_t m_first_frame;
+ uint32_t m_flast_frame;
+ uint32_t m_messages;
+ uint32_t m_bytes;
QTreeWidgetItem * m_item;
LBMSubstreamMap m_substreams;
};
-LBMStreamEntry::LBMStreamEntry(const packet_info * pinfo, guint64 channel, const lbm_uim_stream_endpoint_t * endpoint_a, const lbm_uim_stream_endpoint_t * endpoint_b) :
+LBMStreamEntry::LBMStreamEntry(const packet_info * pinfo, uint64_t channel, const lbm_uim_stream_endpoint_t * endpoint_a, const lbm_uim_stream_endpoint_t * endpoint_b) :
m_channel(channel),
- m_first_frame((guint32)(~0)),
+ m_first_frame((uint32_t)(~0)),
m_flast_frame(0),
m_messages(0),
m_bytes(0),
@@ -228,12 +228,12 @@ void LBMStreamEntry::processPacket(const packet_info * pinfo, const lbm_uim_stre
void LBMStreamEntry::setItem(QTreeWidgetItem * item)
{
m_item = item;
- fillItem(FALSE);
+ fillItem(false);
}
-void LBMStreamEntry::fillItem(gboolean update_only)
+void LBMStreamEntry::fillItem(bool update_only)
{
- if (update_only == FALSE)
+ if (update_only == false)
{
m_item->setData(Stream_Column, Qt::DisplayRole, QVariant((qulonglong)m_channel));
m_item->setText(EndpointA_Column, m_endpoint_a);
@@ -245,8 +245,8 @@ void LBMStreamEntry::fillItem(gboolean update_only)
m_item->setText(LastFrame_Column, QString("%1").arg(m_flast_frame));
}
-typedef QMap<guint64, LBMStreamEntry *> LBMStreamMap;
-typedef QMap<guint64, LBMStreamEntry *>::iterator LBMStreamMapIterator;
+typedef QMap<uint64_t, LBMStreamEntry *> LBMStreamMap;
+typedef QMap<uint64_t, LBMStreamEntry *>::iterator LBMStreamMapIterator;
class LBMStreamDialogInfo
{
diff --git a/ui/qt/lbm_stream_dialog.h b/ui/qt/lbm_stream_dialog.h
index 0bc75d29..0efc141d 100644
--- a/ui/qt/lbm_stream_dialog.h
+++ b/ui/qt/lbm_stream_dialog.h
@@ -14,8 +14,6 @@
#include <config.h>
-#include <glib.h>
-
#include "cfile.h"
#include <epan/packet_info.h>
#include <epan/tap.h>
diff --git a/ui/qt/lte_mac_statistics_dialog.cpp b/ui/qt/lte_mac_statistics_dialog.cpp
index 691128ea..7646caf3 100644
--- a/ui/qt/lte_mac_statistics_dialog.cpp
+++ b/ui/qt/lte_mac_statistics_dialog.cpp
@@ -25,6 +25,7 @@
// Whole-UE headings.
enum {
+ col_rat_,
col_rnti_,
col_type_,
col_ueid_,
@@ -56,7 +57,7 @@ enum {
// Calculate and return a bandwidth figure, in Mbs
static double calculate_bw(const nstime_t *start_time, const nstime_t *stop_time,
- guint32 bytes)
+ uint32_t bytes)
{
// Can only calculate bandwidth if have time delta
if (memcmp(start_time, stop_time, sizeof(nstime_t)) != 0) {
@@ -83,13 +84,14 @@ static double calculate_bw(const nstime_t *start_time, const nstime_t *stop_time
class MacULDLTreeWidgetItem : public QTreeWidgetItem
{
public:
- MacULDLTreeWidgetItem(QTreeWidgetItem *parent, unsigned ueid, unsigned rnti, int row_type) :
+ MacULDLTreeWidgetItem(QTreeWidgetItem *parent, unsigned ueid, unsigned rnti, unsigned rat, int row_type) :
QTreeWidgetItem (parent, row_type),
ueid_(ueid),
- rnti_(rnti)
+ rnti_(rnti),
+ rat_(rat)
{
// Init values held for all lcids to 0.
- for (int n=0; n < MAC_LTE_DATA_LCID_COUNT_MAX; n++) {
+ for (int n=0; n < MAC_3GPP_DATA_LCID_COUNT_MAX; n++) {
lcids[n] = 0;
}
@@ -124,43 +126,62 @@ public:
// Show current value of counter for each LCID.
// N.B. fields that are set as % using percent_bar_delegate.h
// for UE headings don't display here...
- for (int n=0; n < MAC_LTE_DATA_LCID_COUNT_MAX; n++) {
+ for (int n=0; n < MAC_3GPP_DATA_LCID_COUNT_MAX; n++) {
setText(col_type_+n, QString::number((uint)lcids[n]));
}
}
// Increase value held for lcid by given value.
- void updateLCID(guint8 lcid, guint value)
+ void updateLCID(uint8_t lcid, unsigned value)
{
lcids[lcid] += value;
}
// Generate expression for this UE and direction, also filter for SRs and RACH if indicated.
- const QString filterExpression(bool showSR, bool showRACH) {
+ const QString filterExpression(bool showSR, bool showRACH)
+ {
int direction = (type() == mac_dlsch_packet_count_row_type) ||
(type() == mac_dlsch_byte_count_row_type);
QString filter_expr;
if (showSR) {
- filter_expr = QString("(mac-lte.sr-req and mac-lte.ueid == %1) or (").arg(ueid_);
+ // Only applies to LTE.
+ if (rat_ == MAC_RAT_LTE) {
+ filter_expr = QString("(mac-lte.sr-req and mac-lte.ueid == %1) or (").arg(ueid_);
+ }
}
if (showRACH) {
- filter_expr += QString("(mac-lte.rar or (mac-lte.preamble-sent and mac-lte.ueid == %1)) or (").arg(ueid_);
+ if (rat_ == MAC_RAT_LTE) {
+ filter_expr += QString("(mac-lte.rar or (mac-lte.preamble-sent and mac-lte.ueid == %1)) or (").arg(ueid_);
+ }
+ else {
+ filter_expr += QString("mac-nr.rar or ");
+ }
}
// Main expression matching this UE and direction
- filter_expr += QString("mac-lte.ueid==%1 && mac-lte.rnti==%2 && mac-lte.direction==%3").
- arg(ueid_).arg(rnti_).arg(direction);
+ if (rat_ == MAC_RAT_LTE) {
+ filter_expr += QString("mac-lte.ueid==%1 && mac-lte.rnti==%2 && mac-lte.direction==%3").
+ arg(ueid_).arg(rnti_).arg(direction);
+ }
+ else {
+ filter_expr += QString("mac-nr.ueid==%1 && mac-nr.rnti==%2 && mac-nr.direction==%3").
+ arg(ueid_).arg(rnti_).arg(direction);
+ }
// Close () if open because of SR
if (showSR) {
- filter_expr += QString(")");
+ if (rat_ == MAC_RAT_LTE) {
+ filter_expr += QString(")");
+ }
}
// Close () if open because of RACH
if (showRACH) {
- filter_expr += QString(")");
+ if (rat_ == MAC_RAT_LTE) {
+ filter_expr += QString(")");
+ }
}
return filter_expr;
@@ -176,7 +197,8 @@ public:
private:
unsigned ueid_;
unsigned rnti_;
- int lcids[MAC_LTE_DATA_LCID_COUNT_MAX]; /* 0 to 10 and 32 to 38 */
+ unsigned rat_;
+ int lcids[MAC_3GPP_DATA_LCID_COUNT_MAX]; /* For LTE, mapped to 0 to 10 and 32 to 38 */
};
@@ -185,7 +207,7 @@ private:
class MacUETreeWidgetItem : public QTreeWidgetItem
{
public:
- MacUETreeWidgetItem(QTreeWidget *parent, const mac_lte_tap_info *mlt_info) :
+ MacUETreeWidgetItem(QTreeWidget *parent, const mac_3gpp_tap_info *mlt_info) :
QTreeWidgetItem (parent, mac_whole_ue_row_type_),
rnti_(0),
type_(0),
@@ -203,9 +225,13 @@ public:
dl_retx_(0)
{
// Set fixed fields.
- rnti_ = mlt_info->rnti;
- type_ = mlt_info->rntiType;
- ueid_ = mlt_info->ueid;
+ rnti_ = mlt_info->rnti;
+ type_ = mlt_info->rntiType;
+ ueid_ = mlt_info->ueid;
+ rat_ = mlt_info->rat;
+ setText(col_rat_, (mlt_info->rat == MAC_RAT_LTE) ?
+ QObject::tr("LTE") :
+ QObject::tr("NR"));
setText(col_rnti_, QString::number(rnti_));
setText(col_type_, type_ == C_RNTI ? QObject::tr("C-RNTI") : QObject::tr("SPS-RNTI"));
setText(col_ueid_, QString::number(ueid_));
@@ -215,14 +241,15 @@ public:
}
// Does this tap-info match this existing UE item?
- bool isMatch(const mac_lte_tap_info *mlt_info) {
+ bool isMatch(const mac_3gpp_tap_info *mlt_info) {
return ((rnti_ == mlt_info->rnti) &&
(type_ == mlt_info->rntiType) &&
- (ueid_ == mlt_info->ueid));
+ (ueid_ == mlt_info->ueid) &&
+ (rat_ == mlt_info->rat));
}
// Update this UE according to the tap info
- void update(const mac_lte_tap_info *mlt_info) {
+ void update(const mac_3gpp_tap_info *mlt_info) {
// Uplink.
if (mlt_info->direction == DIRECTION_UPLINK) {
@@ -239,9 +266,9 @@ public:
// Update time range
if (ul_frames_ == 0) {
- ul_time_start_ = mlt_info->mac_lte_time;
+ ul_time_start_ = mlt_info->mac_time;
}
- ul_time_stop_ = mlt_info->mac_lte_time;
+ ul_time_stop_ = mlt_info->mac_time;
ul_frames_++;
@@ -251,7 +278,7 @@ public:
// N.B. Not going to support predefined data in Qt version..
if (!mlt_info->isPredefinedData) {
- for (int n=0; n < MAC_LTE_DATA_LCID_COUNT_MAX; n++) {
+ for (int n=0; n < MAC_3GPP_DATA_LCID_COUNT_MAX; n++) {
// Update UL child items
ul_frames_item_->updateLCID(n, mlt_info->sdus_for_lcid[n]);
ul_bytes_item_->updateLCID(n, mlt_info->bytes_for_lcid[n]);
@@ -283,9 +310,9 @@ public:
// Update time range
if (dl_frames_ == 0) {
- dl_time_start_ = mlt_info->mac_lte_time;
+ dl_time_start_ = mlt_info->mac_time;
}
- dl_time_stop_ = mlt_info->mac_lte_time;
+ dl_time_stop_ = mlt_info->mac_time;
dl_frames_++;
@@ -295,7 +322,7 @@ public:
// N.B. Not going to support predefined data in Qt version..
if (!mlt_info->isPredefinedData) {
- for (int n=0; n < MAC_LTE_DATA_LCID_COUNT_MAX; n++) {
+ for (int n=0; n < MAC_3GPP_DATA_LCID_COUNT_MAX; n++) {
// Update DL child items
dl_frames_item_->updateLCID(n, mlt_info->sdus_for_lcid[n]);
dl_bytes_item_->updateLCID(n, mlt_info->bytes_for_lcid[n]);
@@ -308,10 +335,10 @@ public:
void addDetails() {
// Add UL/DL packet and byte counts.
- ul_frames_item_ = new MacULDLTreeWidgetItem(this, ueid_, rnti_, mac_ulsch_packet_count_row_type);
- ul_bytes_item_ = new MacULDLTreeWidgetItem(this, ueid_, rnti_, mac_ulsch_byte_count_row_type);
- dl_frames_item_ = new MacULDLTreeWidgetItem(this, ueid_, rnti_, mac_dlsch_packet_count_row_type);
- dl_bytes_item_ = new MacULDLTreeWidgetItem(this, ueid_, rnti_, mac_dlsch_byte_count_row_type);
+ ul_frames_item_ = new MacULDLTreeWidgetItem(this, ueid_, rnti_, rat_, mac_ulsch_packet_count_row_type);
+ ul_bytes_item_ = new MacULDLTreeWidgetItem(this, ueid_, rnti_, rat_, mac_ulsch_byte_count_row_type);
+ dl_frames_item_ = new MacULDLTreeWidgetItem(this, ueid_, rnti_, rat_, mac_dlsch_packet_count_row_type);
+ dl_bytes_item_ = new MacULDLTreeWidgetItem(this, ueid_, rnti_, rat_, mac_dlsch_byte_count_row_type);
setExpanded(false);
}
@@ -382,23 +409,39 @@ public:
QString filter_expr;
if (showSR) {
- filter_expr = QString("(mac-lte.sr-req and mac-lte.ueid == %1) or (").arg(ueid_);
+ if (rat_ == MAC_RAT_LTE) {
+ filter_expr = QString("(mac-lte.sr-req and mac-lte.ueid == %1) or (").arg(ueid_);
+ }
}
if (showRACH) {
- filter_expr += QString("(mac-lte.rar or (mac-lte.preamble-sent and mac-lte.ueid == %1)) or (").arg(ueid_);
+ if (rat_ == MAC_RAT_LTE) {
+ filter_expr += QString("(mac-lte.rar or (mac-lte.preamble-sent and mac-lte.ueid == %1)) or (").arg(ueid_);
+ }
+ else {
+ filter_expr += QString("mac-nr.rar or ");
+ }
}
// Main expression matching this UE
- filter_expr += QString("mac-lte.ueid==%1 && mac-lte.rnti==%2").arg(ueid_).arg(rnti_);
+ if (rat_ == MAC_RAT_LTE) {
+ filter_expr += QString("mac-lte.ueid==%1 && mac-lte.rnti==%2").arg(ueid_).arg(rnti_);
+ }
+ else {
+ filter_expr += QString("mac-nr.ueid==%1 && mac-nr.rnti==%2").arg(ueid_).arg(rnti_);
+ }
// Close () if open because of SR
if (showSR) {
- filter_expr += QString(")");
+ if (rat_ == MAC_RAT_LTE) {
+ filter_expr += QString(")");
+ }
}
// Close () if open because of RACH
if (showRACH) {
- filter_expr += QString(")");
+ if (rat_ == MAC_RAT_LTE) {
+ filter_expr += QString(")");
+ }
}
return filter_expr;
@@ -432,6 +475,7 @@ public:
private:
// Unchanging (key) fields.
+ uint8_t rat_;
unsigned rnti_;
unsigned type_;
unsigned ueid_;
@@ -467,7 +511,7 @@ private:
// Label headings. Show according to which type of tree item is currently selected.
static const QStringList mac_whole_ue_row_labels = QStringList()
- << QObject::tr("RNTI") << QObject::tr("Type") << QObject::tr("UEId")
+ << QObject::tr("RAT") << QObject::tr("RNTI") << QObject::tr("Type") << QObject::tr("UEId")
<< QObject::tr("UL Frames") << QObject::tr("UL Bytes") << QObject::tr("UL MB/s")
<< QObject::tr("UL Padding %") << QObject::tr("UL Re TX")
<< QObject::tr("DL Frames") << QObject::tr("DL Bytes") << QObject::tr("DL MB/s")
@@ -477,7 +521,7 @@ static const QStringList mac_whole_ue_row_labels = QStringList()
<< QObject::tr("") << QObject::tr("") << QObject::tr("") << QObject::tr("") << QObject::tr("");
static const QStringList mac_channel_counts_labels = QStringList()
- << QObject::tr("") << QObject::tr("CCCH")
+ << QObject::tr("") << QObject::tr("") << QObject::tr("CCCH")
<< QObject::tr("LCID 1") << QObject::tr("LCID 2") << QObject::tr("LCID 3")
<< QObject::tr("LCID 4") << QObject::tr("LCID 5") << QObject::tr("LCID 6")
<< QObject::tr("LCID 7") << QObject::tr("LCID 8") << QObject::tr("LCID 9")
@@ -495,7 +539,7 @@ LteMacStatisticsDialog::LteMacStatisticsDialog(QWidget &parent, CaptureFile &cf,
TapParameterDialog(parent, cf, HELP_STATS_LTE_MAC_TRAFFIC_DIALOG),
commonStatsCurrent_(false)
{
- setWindowSubtitle(tr("LTE Mac Statistics"));
+ setWindowSubtitle(tr("LTE/NR Mac Statistics"));
loadGeometry(parent.width() * 1, parent.height() * 3 / 4, "LTEMacStatisticsDialog");
clearCommonStats();
@@ -617,7 +661,7 @@ LteMacStatisticsDialog::~LteMacStatisticsDialog()
}
// Update system/common counters, and redraw if changed.
-void LteMacStatisticsDialog::updateCommonStats(const mac_lte_tap_info *tap_info)
+void LteMacStatisticsDialog::updateCommonStats(const mac_3gpp_tap_info *tap_info)
{
commonStats_.all_frames++;
@@ -719,11 +763,11 @@ void LteMacStatisticsDialog::tapReset(void *ws_dlg_ptr)
//---------------------------------------------------------------------------------------
// Process tap info from a new packet.
// Returns TAP_PACKET_REDRAW if a redraw is needed, TAP_PACKET_DONT_REDRAW otherwise.
-tap_packet_status LteMacStatisticsDialog::tapPacket(void *ws_dlg_ptr, struct _packet_info *, epan_dissect *, const void *mac_lte_tap_info_ptr, tap_flags_t)
+tap_packet_status LteMacStatisticsDialog::tapPacket(void *ws_dlg_ptr, struct _packet_info *, epan_dissect *, const void *mac_3gpp_tap_info_ptr, tap_flags_t)
{
// Look up dialog and tap info.
LteMacStatisticsDialog *ws_dlg = static_cast<LteMacStatisticsDialog *>(ws_dlg_ptr);
- const mac_lte_tap_info *mlt_info = (const mac_lte_tap_info *) mac_lte_tap_info_ptr;
+ const mac_3gpp_tap_info *mlt_info = (const mac_3gpp_tap_info *)mac_3gpp_tap_info_ptr;
if (!ws_dlg || !mlt_info) {
return TAP_PACKET_DONT_REDRAW;
}
@@ -799,7 +843,7 @@ void LteMacStatisticsDialog::tapDraw(void *ws_dlg_ptr)
ws_dlg->drawCommonStats();
// Update title
- ws_dlg->setWindowSubtitle(QString("LTE Mac Statistics (%1 UEs, %2 frames)").
+ ws_dlg->setWindowSubtitle(QString("3GPP Mac Statistics (%1 UEs, %2 frames)").
arg(ws_dlg->statsTreeWidget()->topLevelItemCount()).arg(ws_dlg->getFrameCount()));
}
@@ -825,7 +869,7 @@ const QString LteMacStatisticsDialog::filterExpression()
void LteMacStatisticsDialog::fillTree()
{
- if (!registerTapListener("mac-lte",
+ if (!registerTapListener("mac-3gpp",
this,
displayFilter_.toLatin1().data(),
TL_REQUIRES_NOTHING,
@@ -910,12 +954,12 @@ lte_mac_statistics_init(const char *args, void*) {
}
static stat_tap_ui lte_mac_statistics_ui = {
- REGISTER_STAT_GROUP_TELEPHONY_LTE,
+ REGISTER_TELEPHONY_GROUP_3GPP_UU,
QT_TRANSLATE_NOOP("LteMacStatisticsDialog", "MAC Statistics"),
- "mac-lte,stat",
+ "mac-3gpp,stat", // cli_string
lte_mac_statistics_init,
- 0,
- NULL
+ 0, // nparams
+ NULL // params
};
extern "C" {
diff --git a/ui/qt/lte_mac_statistics_dialog.h b/ui/qt/lte_mac_statistics_dialog.h
index 411d0614..c3ea692d 100644
--- a/ui/qt/lte_mac_statistics_dialog.h
+++ b/ui/qt/lte_mac_statistics_dialog.h
@@ -18,20 +18,20 @@
#include <ui/qt/models/percent_bar_delegate.h>
// Common channel stats
-typedef struct mac_lte_common_stats {
- guint32 all_frames;
- guint32 mib_frames;
- guint32 sib_frames;
- guint32 sib_bytes;
- guint32 pch_frames;
- guint32 pch_bytes;
- guint32 pch_paging_ids;
- guint32 rar_frames;
- guint32 rar_entries;
-
- guint16 max_ul_ues_in_tti;
- guint16 max_dl_ues_in_tti;
-} mac_lte_common_stats;
+typedef struct mac_3gpp_common_stats {
+ uint32_t all_frames;
+ uint32_t mib_frames;
+ uint32_t sib_frames;
+ uint32_t sib_bytes;
+ uint32_t pch_frames;
+ uint32_t pch_bytes;
+ uint32_t pch_paging_ids;
+ uint32_t rar_frames;
+ uint32_t rar_entries;
+
+ uint16_t max_ul_ues_in_tti;
+ uint16_t max_dl_ues_in_tti;
+} mac_3gpp_common_stats;
class LteMacStatisticsDialog : public TapParameterDialog
@@ -55,15 +55,15 @@ private:
// Callbacks for register_tap_listener
static void tapReset(void *ws_dlg_ptr);
- static tap_packet_status tapPacket(void *ws_dlg_ptr, struct _packet_info *, struct epan_dissect *, const void *mac_lte_tap_info_ptr, tap_flags_t flags);
+ static tap_packet_status tapPacket(void *ws_dlg_ptr, struct _packet_info *, struct epan_dissect *, const void *mac_3gpp_tap_info_ptr, tap_flags_t flags);
static void tapDraw(void *ws_dlg_ptr);
virtual const QString filterExpression();
// Common stats.
- mac_lte_common_stats commonStats_;
+ mac_3gpp_common_stats commonStats_;
bool commonStatsCurrent_; // Set when changes have not yet been drawn
- void updateCommonStats(const struct mac_lte_tap_info *mlt_info);
+ void updateCommonStats(const struct mac_3gpp_tap_info *mlt_info);
void drawCommonStats();
void clearCommonStats();
diff --git a/ui/qt/lte_rlc_graph_dialog.cpp b/ui/qt/lte_rlc_graph_dialog.cpp
index f1ac2b46..6158c21b 100644
--- a/ui/qt/lte_rlc_graph_dialog.cpp
+++ b/ui/qt/lte_rlc_graph_dialog.cpp
@@ -31,6 +31,8 @@
#include "ui/qt/widgets/wireshark_file_dialog.h"
#include <epan/dissectors/packet-rlc-lte.h>
+#include <epan/dissectors/packet-rlc-3gpp-common.h>
+
#include <ui/tap-rlc-graph.h>
@@ -62,7 +64,7 @@ LteRlcGraphDialog::LteRlcGraphDialog(QWidget &parent, CaptureFile &cf, bool chan
rp->xAxis->setLabel(tr("Time"));
rp->yAxis->setLabel(tr("Sequence Number"));
- // TODO: couldn't work out how to tell rp->xAxis not to label fractions of a SN...
+ // TODO: couldn't work out how to tell rp->yAxis not to label fractions of a SN...
ui->dragRadioButton->setChecked(mouse_drags_);
@@ -95,6 +97,9 @@ LteRlcGraphDialog::LteRlcGraphDialog(QWidget &parent, CaptureFile &cf, bool chan
ctx_menu_->addAction(ui->actionSwitchDirection);
set_action_shortcuts_visible_in_context_menu(ctx_menu_->actions());
+ rp->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(rp, &QCustomPlot::customContextMenuRequested, this, &LteRlcGraphDialog::showContextMenu);
+
// Zero out this struct.
memset(&graph_, 0, sizeof(graph_));
@@ -111,15 +116,16 @@ LteRlcGraphDialog::~LteRlcGraphDialog()
}
// Set the channel information that this graph should show.
-void LteRlcGraphDialog::setChannelInfo(guint16 ueid, guint8 rlcMode,
- guint16 channelType, guint16 channelId, guint8 direction,
+void LteRlcGraphDialog::setChannelInfo(uint8_t rat, uint16_t ueid, uint8_t rlcMode,
+ uint16_t channelType, uint16_t channelId, uint8_t direction,
bool maybe_empty)
{
+ graph_.rat = rat;
graph_.ueid = ueid;
graph_.rlcMode = rlcMode;
graph_.channelType = channelType;
graph_.channelId = channelId;
- graph_.channelSet = TRUE;
+ graph_.channelSet = true;
graph_.direction = direction;
completeGraph(maybe_empty);
@@ -135,7 +141,8 @@ void LteRlcGraphDialog::completeGraph(bool may_be_empty)
// Set window title here.
if (graph_.channelSet) {
- QString dlg_title = tr("LTE RLC Graph (UE=%1 chan=%2%3 %4 - %5)")
+ QString dlg_title = tr("%1 RLC Graph (UE=%2 chan=%3%4 %5 - %6)")
+ .arg((graph_.rat == RLC_RAT_LTE) ? "LTE" : "NR")
.arg(graph_.ueid)
.arg((graph_.channelType == CHANNEL_TYPE_SRB) ? "SRB" : "DRB")
.arg(graph_.channelId)
@@ -144,7 +151,7 @@ void LteRlcGraphDialog::completeGraph(bool may_be_empty)
setWindowTitle(dlg_title);
}
else {
- setWindowTitle(tr("LTE RLC Graph - no channel selected"));
+ setWindowTitle(tr("3GPP RLC Graph - no channel selected"));
}
// Set colours/styles for each of the traces on the graph.
@@ -186,7 +193,8 @@ void LteRlcGraphDialog::completeGraph(bool may_be_empty)
// See if the given segment matches the channel this graph is plotting.
bool LteRlcGraphDialog::compareHeaders(rlc_segment *seg)
{
- return compare_rlc_headers(graph_.ueid, graph_.channelType,
+ return compare_rlc_headers(graph_.rat, seg->rat,
+ graph_.ueid, graph_.channelType,
graph_.channelId, graph_.rlcMode, graph_.direction,
seg->ueid, seg->channelType,
seg->channelId, seg->rlcMode, seg->direction,
@@ -230,13 +238,13 @@ void LteRlcGraphDialog::fillGraph()
return;
}
- tracer_->setGraph(NULL);
-
base_graph_->setLineStyle(QCPGraph::lsNone); // dot
reseg_graph_->setLineStyle(QCPGraph::lsNone); // dot
acks_graph_->setLineStyle(QCPGraph::lsStepLeft); // to get step effect...
nacks_graph_->setLineStyle(QCPGraph::lsNone); // dot, but bigger.
+ tracer_->setGraph(NULL);
+
// Will show all graphs with data we find.
for (int i = 0; i < sp->graphCount(); i++) {
sp->graph(i)->data()->clear();
@@ -252,14 +260,13 @@ void LteRlcGraphDialog::fillGraph()
// NACKs are shown bigger than others.
nacks_graph_->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDisc, pkt_point_size_*2));
- // Map timestamps -> segments in first pass.
+ // Map timestamps -> segments (time_stamp_map_) in first pass.
time_stamp_map_.clear();
for (struct rlc_segment *seg = graph_.segments; seg != NULL; seg = seg->next) {
if (!compareHeaders(seg)) {
continue;
}
double ts = seg->rel_secs + seg->rel_usecs / 1000000.0;
-
time_stamp_map_.insert(ts, seg);
}
@@ -268,12 +275,23 @@ void LteRlcGraphDialog::fillGraph()
reseg_seq_time, reseg_seq,
acks_time, acks,
nacks_time, nacks;
+
+ uint32_t last_ackSN = uint32_t(-1); // start with invalid value
+ uint32_t maxSN = 0;
+
+ // Note the max possible SN
+ if (graph_.segments) {
+ maxSN = (1 << graph_.segments->sequenceNumberLength);
+ }
+
+ // Run through the segments to get data
for (struct rlc_segment *seg = graph_.segments; seg != NULL; seg = seg->next) {
double ts = seg->rel_secs + (seg->rel_usecs / 1000000.0);
if (compareHeaders(seg)) {
if (!seg->isControlPDU) {
- // Data
+ // Data PDUs
if (seg->isResegmented) {
+ // LTE only
reseg_seq_time.append(ts);
reseg_seq.append(seg->SN);
}
@@ -283,22 +301,31 @@ void LteRlcGraphDialog::fillGraph()
}
}
else {
- // Status (ACKs/NACKs)
- acks_time.append(ts);
- acks.append(seg->ACKNo-1);
- for (int n=0; n < seg->noOfNACKs; n++) {
- nacks_time.append(ts);
- nacks.append(seg->NACKs[n]);
+ // Status PDUs
+
+ // Filter out ACKS that are likely caused by MAC retx, so track last ACK
+ if (seg->ACKNo != last_ackSN) {
+ // Status (ACKs/NACKs)
+ acks_time.append(ts);
+ acks.append((seg->ACKNo-1) % maxSN);
+ last_ackSN = seg->ACKNo;
+
+ // Any NACKs
+ for (int n=0; n < seg->noOfNACKs; n++) {
+ nacks_time.append(ts);
+ nacks.append(seg->NACKs[n]);
+ }
}
}
}
}
// Add the data from the graphs.
- base_graph_->setData(seq_time, seq);
- reseg_graph_->setData(reseg_seq_time, reseg_seq);
- acks_graph_->setData(acks_time, acks);
- nacks_graph_->setData(nacks_time, nacks);
+ // N.B. passing true to assume the timestamps are already sorted..
+ base_graph_->setData(seq_time, seq, true);
+ reseg_graph_->setData(reseg_seq_time, reseg_seq, true);
+ acks_graph_->setData(acks_time, acks, true);
+ nacks_graph_->setData(nacks_time, nacks, true);
sp->setEnabled(true);
@@ -533,19 +560,16 @@ QRectF LteRlcGraphDialog::getZoomRanges(QRect zoom_rect)
return zoom_ranges;
}
+void LteRlcGraphDialog::showContextMenu(const QPoint &pos)
+{
+ ctx_menu_->popup(ui->rlcPlot->mapToGlobal(pos));
+}
+
void LteRlcGraphDialog::graphClicked(QMouseEvent *event)
{
QCustomPlot *rp = ui->rlcPlot;
- if (event->button() == Qt::RightButton) {
- // XXX We should find some way to get rlcPlot to handle a
- // contextMenuEvent instead.
-#if QT_VERSION >= QT_VERSION_CHECK(6, 0 ,0)
- ctx_menu_->popup(event->globalPosition().toPoint());
-#else
- ctx_menu_->popup(event->globalPos());
-#endif
- } else if (mouse_drags_) {
+ if (mouse_drags_) {
if (rp->axisRect()->rect().contains(event->pos())) {
rp->setCursor(QCursor(Qt::ClosedHandCursor));
}
@@ -675,21 +699,21 @@ void LteRlcGraphDialog::resetAxes()
{
QCustomPlot *rp = ui->rlcPlot;
- QCPRange x_range = rp->xAxis->scaleType() == QCPAxis::stLogarithmic ?
- rp->xAxis->range().sanitizedForLogScale() : rp->xAxis->range();
-
double pixel_pad = 10.0; // per side
rp->rescaleAxes(true);
- base_graph_->rescaleValueAxis(false, true);
+
+ QCPRange x_range = rp->xAxis->range();
double axis_pixels = rp->xAxis->axisRect()->width();
rp->xAxis->scaleRange((axis_pixels + (pixel_pad * 2)) / axis_pixels, x_range.center());
axis_pixels = rp->yAxis->axisRect()->height();
- rp->yAxis->scaleRange((axis_pixels + (pixel_pad * 2)) / axis_pixels, rp->yAxis->range().center());
+ rp->yAxis->scaleRange((axis_pixels + (pixel_pad * 2)) / axis_pixels,
+ rp->yAxis->range().center());
- rp->replot(QCustomPlot::rpQueuedReplot);
+ // N.B. TCP Stream Dialog uses default (rpRefreshHint) - was using QCustomPlot::rpQueuedReplot
+ rp->replot();
}
void LteRlcGraphDialog::on_actionGoToPacket_triggered()
@@ -800,7 +824,8 @@ void LteRlcGraphDialog::on_actionSwitchDirection_triggered()
{
// Channel settings exactly the same, except change direction.
// N.B. do not fail and close if there are no packets in opposite direction.
- setChannelInfo(graph_.ueid,
+ setChannelInfo(graph_.rat,
+ graph_.ueid,
graph_.rlcMode,
graph_.channelType,
graph_.channelId,
diff --git a/ui/qt/lte_rlc_graph_dialog.h b/ui/qt/lte_rlc_graph_dialog.h
index 07661ab2..2b83f0ff 100644
--- a/ui/qt/lte_rlc_graph_dialog.h
+++ b/ui/qt/lte_rlc_graph_dialog.h
@@ -33,8 +33,8 @@ public:
explicit LteRlcGraphDialog(QWidget &parent, CaptureFile &cf, bool channelKnown);
~LteRlcGraphDialog();
- void setChannelInfo(guint16 ueid, guint8 rlcMode,
- guint16 channelType, guint16 channelId, guint8 direction,
+ void setChannelInfo(uint8_t rat, uint16_t ueid, uint8_t rlcMode,
+ uint16_t channelType, uint16_t channelId, uint8_t direction,
bool maybe_empty=false);
signals:
@@ -51,19 +51,19 @@ private:
QPoint rb_origin_;
QMenu *ctx_menu_;
- // Data gleaned directly from tapping packets (shared with gtk impl)
+ // Data gleaned directly from tapping packets
struct rlc_graph graph_;
// Data
- QMultiMap<double, struct rlc_segment *> time_stamp_map_;
+ QMultiMap<double, struct rlc_segment *> time_stamp_map_; // used for mapping clicks back to segment/frame
QMap<double, struct rlc_segment *> sequence_num_map_;
- QCPGraph *base_graph_; // Clickable packets
+ QCPGraph *base_graph_; // Data SNs - clickable packets
QCPGraph *reseg_graph_;
QCPGraph *acks_graph_;
QCPGraph *nacks_graph_;
QCPItemTracer *tracer_;
- guint32 packet_num_;
+ uint32_t packet_num_;
void completeGraph(bool may_be_empty=false);
@@ -82,6 +82,7 @@ private:
void toggleTracerStyle(bool force_default);
private slots:
+ void showContextMenu(const QPoint &pos);
void graphClicked(QMouseEvent *event);
void mouseMoved(QMouseEvent *event);
void mouseReleased(QMouseEvent *event);
diff --git a/ui/qt/lte_rlc_statistics_dialog.cpp b/ui/qt/lte_rlc_statistics_dialog.cpp
index 43b5c81b..77553c96 100644
--- a/ui/qt/lte_rlc_statistics_dialog.cpp
+++ b/ui/qt/lte_rlc_statistics_dialog.cpp
@@ -13,8 +13,6 @@
#include <epan/strutil.h>
#include <epan/tap.h>
-#include <epan/dissectors/packet-rlc-lte.h>
-
#include <QFormLayout>
#include <QTreeWidgetItem>
#include <QPushButton>
@@ -26,6 +24,7 @@
// TODO: have never tested in a live capture.
enum {
+ col_rat_,
col_ueid_,
col_mode_, // channel only
col_priority_, // channel only
@@ -49,7 +48,7 @@ enum {
};
/* Calculate and return a bandwidth figure, in Mbs */
-static double calculate_bw(const nstime_t *start_time, const nstime_t *stop_time, guint32 bytes)
+static double calculate_bw(const nstime_t *start_time, const nstime_t *stop_time, uint32_t bytes)
{
/* Can only calculate bandwidth if have time delta */
if (memcmp(start_time, stop_time, sizeof(nstime_t)) != 0) {
@@ -74,31 +73,31 @@ static double calculate_bw(const nstime_t *start_time, const nstime_t *stop_time
// Stats kept for one channel.
typedef struct rlc_channel_stats {
- guint8 rlcMode;
- guint8 priority;
- guint16 channelType;
- guint16 channelId;
+ uint8_t rlcMode;
+ uint8_t priority;
+ uint16_t channelType;
+ uint16_t channelId;
- guint32 UL_frames;
- guint32 UL_bytes;
+ uint32_t UL_frames;
+ uint32_t UL_bytes;
nstime_t UL_time_start;
nstime_t UL_time_stop;
- gboolean UL_has_data; // i.e. not just ACKs for DL.
+ bool UL_has_data; // i.e. not just ACKs for DL.
- guint32 DL_frames;
- guint32 DL_bytes;
+ uint32_t DL_frames;
+ uint32_t DL_bytes;
nstime_t DL_time_start;
nstime_t DL_time_stop;
- gboolean DL_has_data; // i.e. not just ACKs for UL.
+ bool DL_has_data; // i.e. not just ACKs for UL.
- guint32 UL_acks;
- guint32 UL_nacks;
+ uint32_t UL_acks;
+ uint32_t UL_nacks;
- guint32 DL_acks;
- guint32 DL_nacks;
+ uint32_t DL_acks;
+ uint32_t DL_nacks;
- guint32 UL_missing;
- guint32 DL_missing;
+ uint32_t UL_missing;
+ uint32_t DL_missing;
} rlc_channel_stats;
//-------------------------------------------------------------------
@@ -108,10 +107,12 @@ class RlcChannelTreeWidgetItem : public QTreeWidgetItem
{
public:
RlcChannelTreeWidgetItem(QTreeWidgetItem *parent,
+ uint8_t rat,
unsigned ueid,
unsigned mode,
unsigned channelType, unsigned channelId) :
QTreeWidgetItem(parent, rlc_channel_row_type_),
+ rat_(rat),
ueid_(ueid),
channelType_(channelType),
channelId_(channelId),
@@ -163,7 +164,7 @@ public:
}
// Update UE/channels from tap info.
- void update(const rlc_lte_tap_info *tap_info) {
+ void update(const rlc_3gpp_tap_info *tap_info) {
// Copy these fields into UE stats.
if (tap_info->rlcMode != stats_.rlcMode) {
@@ -183,9 +184,9 @@ public:
if (tap_info->direction == DIRECTION_UPLINK) {
// Update time range.
if (stats_.UL_frames == 0) {
- stats_.UL_time_start = tap_info->rlc_lte_time;
+ stats_.UL_time_start = tap_info->rlc_time;
}
- stats_.UL_time_stop = tap_info->rlc_lte_time;
+ stats_.UL_time_stop = tap_info->rlc_time;
stats_.UL_frames++;
stats_.UL_bytes += tap_info->pduLength;
@@ -195,15 +196,15 @@ public:
stats_.UL_acks++;
}
else {
- stats_.UL_has_data = TRUE;
+ stats_.UL_has_data = true;
}
}
else {
// Update time range.
if (stats_.DL_frames == 0) {
- stats_.DL_time_start = tap_info->rlc_lte_time;
+ stats_.DL_time_start = tap_info->rlc_time;
}
- stats_.DL_time_stop = tap_info->rlc_lte_time;
+ stats_.DL_time_stop = tap_info->rlc_time;
stats_.DL_frames++;
stats_.DL_bytes += tap_info->pduLength;
@@ -213,7 +214,7 @@ public:
stats_.DL_acks++;
}
else {
- stats_.DL_has_data = TRUE;
+ stats_.DL_has_data = true;
}
}
}
@@ -269,47 +270,81 @@ public:
return QTreeWidgetItem::operator< (other);
}
- // Filter expression for channel.
+ // Filter expression for this bearer.
const QString filterExpression(bool showSR, bool showRACH) {
// Create an expression to match with all traffic for this UE.
QString filter_expr;
// Are we taking RLC PDUs from MAC, or not?
if (!recent.gui_rlc_use_pdus_from_mac) {
- filter_expr += QString("not mac-lte and ");
+ if (rat_ == RLC_RAT_LTE) {
+ filter_expr += QString("not mac-lte and ");
+ }
+ else {
+ filter_expr += QString("not mac-nr and ");
+ }
}
else {
- filter_expr += QString("mac-lte and ");
+ if (rat_ == RLC_RAT_LTE) {
+ filter_expr += QString("mac-lte and ");
+ }
+ else {
+ filter_expr += QString("mac-nr and ");
+ }
}
if (showSR) {
- filter_expr += QString("(mac-lte.sr-req and mac-lte.ueid == %1) or (").arg(ueid_);
+ if (rat_ == RLC_RAT_LTE) {
+ filter_expr += QString("(mac-lte.sr-req and mac-lte.ueid == %1) or (").arg(ueid_);
+ }
}
if (showRACH) {
- filter_expr += QString("(mac-lte.rar or (mac-lte.preamble-sent and mac-lte.ueid == %1)) or (").arg(ueid_);
+ if (rat_ == RLC_RAT_LTE) {
+ filter_expr += QString("(mac-lte.rar or (mac-lte.preamble-sent and mac-lte.ueid == %1)) or (").arg(ueid_);
+ }
+ else {
+ filter_expr += QString("(mac-nr.rar or ");
+ }
}
// Main part of expression.
- filter_expr += QString("rlc-lte.ueid==%1 and rlc-lte.channel-type == %2").
- arg(ueid_).arg(channelType_);
+ if (rat_ == RLC_RAT_LTE) {
+ filter_expr += QString("rlc-lte.ueid==%1 and rlc-lte.channel-type == %2").
+ arg(ueid_).arg(channelType_);
+ }
+ else {
+ filter_expr += QString("rlc-nr.ueid==%1 and rlc-nr.bearer-type == %2").
+ arg(ueid_).arg(channelType_);
+ }
+ // Channel/bearer Id
if ((channelType_ == CHANNEL_TYPE_SRB) || (channelType_ == CHANNEL_TYPE_DRB)) {
- filter_expr += QString(" and rlc-lte.channel-id == %1").arg(channelId_);
+ if (rat_ == RLC_RAT_LTE) {
+ filter_expr += QString(" and rlc-lte.channel-id == %1").arg(channelId_);
+ }
+ else {
+ filter_expr += QString(" and rlc-nr.bearer-id == %1").arg(channelId_);
+ }
}
// Close () if open because of SR
if (showSR) {
- filter_expr += QString(")");
+ if (rat_ == RLC_RAT_LTE) {
+ filter_expr += QString(")");
+ }
}
// Close () if open because of RACH
if (showRACH) {
- filter_expr += QString(")");
+ if (rat_ == RLC_RAT_LTE) {
+ filter_expr += QString(")");
+ }
}
return filter_expr;
}
// Accessors (queried for launching graph)
+ uint8_t get_rat() const { return rat_; }
unsigned get_ueid() const { return ueid_; }
unsigned get_channelType() const { return channelType_; }
unsigned get_channelId() const { return channelId_; }
@@ -325,10 +360,11 @@ public:
}
private:
+ uint8_t rat_;
unsigned ueid_;
unsigned channelType_;
unsigned channelId_;
- unsigned mode_;
+ unsigned mode_; // RLC mode for this bearer
unsigned priority_;
unsigned channelRank() const
@@ -353,21 +389,21 @@ private:
// Stats for one UE. TODO: private to class?
typedef struct rlc_ue_stats {
- guint32 UL_frames;
- guint32 UL_total_bytes;
+ uint32_t UL_frames;
+ uint32_t UL_total_bytes;
nstime_t UL_time_start;
nstime_t UL_time_stop;
- guint32 UL_total_acks;
- guint32 UL_total_nacks;
- guint32 UL_total_missing;
+ uint32_t UL_total_acks;
+ uint32_t UL_total_nacks;
+ uint32_t UL_total_missing;
- guint32 DL_frames;
- guint32 DL_total_bytes;
+ uint32_t DL_frames;
+ uint32_t DL_total_bytes;
nstime_t DL_time_start;
nstime_t DL_time_stop;
- guint32 DL_total_acks;
- guint32 DL_total_nacks;
- guint32 DL_total_missing;
+ uint32_t DL_total_acks;
+ uint32_t DL_total_nacks;
+ uint32_t DL_total_missing;
} rlc_ue_stats;
@@ -377,11 +413,17 @@ typedef struct rlc_ue_stats {
class RlcUeTreeWidgetItem : public QTreeWidgetItem
{
public:
- RlcUeTreeWidgetItem(QTreeWidget *parent, const rlc_lte_tap_info *rlt_info) :
+ RlcUeTreeWidgetItem(QTreeWidget *parent, const rlc_3gpp_tap_info *rlt_info) :
QTreeWidgetItem (parent, rlc_ue_row_type_),
ueid_(0)
{
ueid_ = rlt_info->ueid;
+ rat_ = rlt_info->rat;
+
+ // Version matches UE number
+ setText(col_rat_, (rat_ == RLC_RAT_LTE) ?
+ QObject::tr("LTE") :
+ QObject::tr("NR"));
setText(col_ueid_, QString::number(ueid_));
// We create RlcChannelTreeWidgetItems when first data on new channel is seen.
@@ -398,20 +440,14 @@ public:
}
// Does UE match?
- bool isMatch(const rlc_lte_tap_info *rlt_info) {
- return ueid_ == rlt_info->ueid;
+ bool isMatch(const rlc_3gpp_tap_info *rlt_info)
+ {
+ return (rat_ == rlt_info->rat) && (ueid_ == rlt_info->ueid);
}
// Update UE/channels from tap info.
- void update(const rlc_lte_tap_info *tap_info) {
-
- // Are we ignoring RLC frames that were found in MAC frames, or only those
- // that were logged separately?
- if ((!recent.gui_rlc_use_pdus_from_mac && tap_info->loggedInMACFrame) ||
- (recent.gui_rlc_use_pdus_from_mac && !tap_info->loggedInMACFrame)) {
- return;
- }
-
+ void update(const rlc_3gpp_tap_info *tap_info)
+ {
// TODO: update title with number of UEs and frames like MAC does?
// N.B. not really expecting to see common stats - ignoring them.
@@ -430,9 +466,9 @@ public:
if (tap_info->direction == DIRECTION_UPLINK) {
// Update time range.
if (stats_.UL_frames == 0) {
- stats_.UL_time_start = tap_info->rlc_lte_time;
+ stats_.UL_time_start = tap_info->rlc_time;
}
- stats_.UL_time_stop = tap_info->rlc_lte_time;
+ stats_.UL_time_stop = tap_info->rlc_time;
stats_.UL_frames++;
stats_.UL_total_bytes += tap_info->pduLength;
@@ -448,9 +484,9 @@ public:
else {
// Update time range.
if (stats_.DL_frames == 0) {
- stats_.DL_time_start = tap_info->rlc_lte_time;
+ stats_.DL_time_start = tap_info->rlc_time;
}
- stats_.DL_time_stop = tap_info->rlc_lte_time;
+ stats_.DL_time_stop = tap_info->rlc_time;
stats_.DL_frames++;
stats_.DL_total_bytes += tap_info->pduLength;
@@ -472,7 +508,7 @@ public:
channel_item = CCCH_stats_;
if (channel_item == NULL) {
channel_item = CCCH_stats_ =
- new RlcChannelTreeWidgetItem(this, tap_info->ueid, RLC_TM_MODE,
+ new RlcChannelTreeWidgetItem(this, tap_info->rat, tap_info->ueid, RLC_TM_MODE,
tap_info->channelType, tap_info->channelId);
}
break;
@@ -481,7 +517,7 @@ public:
channel_item = srb_stats_[tap_info->channelId-1];
if (channel_item == NULL) {
channel_item = srb_stats_[tap_info->channelId-1] =
- new RlcChannelTreeWidgetItem(this, tap_info->ueid, RLC_AM_MODE,
+ new RlcChannelTreeWidgetItem(this, tap_info->rat, tap_info->ueid, RLC_AM_MODE,
tap_info->channelType, tap_info->channelId);
}
break;
@@ -490,7 +526,7 @@ public:
channel_item = drb_stats_[tap_info->channelId-1];
if (channel_item == NULL) {
channel_item = drb_stats_[tap_info->channelId-1] =
- new RlcChannelTreeWidgetItem(this, tap_info->ueid, tap_info->rlcMode,
+ new RlcChannelTreeWidgetItem(this, tap_info->rat, tap_info->ueid, tap_info->rlcMode,
tap_info->channelType, tap_info->channelId);
}
break;
@@ -505,7 +541,8 @@ public:
}
// Draw UE entry
- void draw() {
+ void draw()
+ {
// Fixed fields only drawn once from constructor so don't redraw here.
/* Calculate bandwidths. */
@@ -516,6 +553,8 @@ public:
&stats_.DL_time_stop,
stats_.DL_total_bytes);
+ setText(col_rat_, (rat_ == RLC_RAT_LTE) ? QString("LTE") : QString("NR"));
+
// Uplink.
setText(col_ul_frames_, QString::number(stats_.UL_frames));
setText(col_ul_bytes_, QString::number(stats_.UL_total_bytes));
@@ -564,35 +603,63 @@ public:
}
// Filter expression for UE.
- const QString filterExpression(bool showSR, bool showRACH) {
+ const QString filterExpression(bool showSR, bool showRACH)
+ {
// Create an expression to match with all traffic for this UE.
QString filter_expr;
// Are we taking RLC PDUs from MAC, or not?
if (!recent.gui_rlc_use_pdus_from_mac) {
- filter_expr += QString("not mac-lte and ");
+ if (rat_ == RLC_RAT_LTE) {
+ filter_expr += QString("not mac-lte and ");
+ }
+ else {
+ filter_expr += QString("not mac-nr and ");
+ }
}
else {
- filter_expr += QString("mac-lte and ");
+ if (rat_ == RLC_RAT_LTE) {
+ filter_expr += QString("mac-lte and ");
+ }
+ else {
+ filter_expr += QString("mac-nr and ");
+ }
}
if (showSR) {
- filter_expr += QString("(mac-lte.sr-req and mac-lte.ueid == %1) or (").arg(ueid_);
+ if (rat_ == RLC_RAT_LTE) {
+ filter_expr += QString("(mac-lte.sr-req and mac-lte.ueid == %1) or (").arg(ueid_);
+ }
}
if (showRACH) {
- filter_expr += QString("(mac-lte.rar or (mac-lte.preamble-sent and mac-lte.ueid == %1)) or (").arg(ueid_);
+ if (rat_ == RLC_RAT_LTE) {
+ filter_expr += QString("(mac-lte.rar or (mac-lte.preamble-sent and mac-lte.ueid == %1)) or (").arg(ueid_);
+ }
+ else {
+ filter_expr += QString("mac-nr.rar or ");
+ }
}
- filter_expr += QString("rlc-lte.ueid==%1").arg(ueid_);
+ // Must match UE
+ if (rat_ == RLC_RAT_LTE) {
+ filter_expr += QString("rlc-lte.ueid==%1").arg(ueid_);
+ }
+ else {
+ filter_expr += QString("rlc-nr.ueid==%1").arg(ueid_);
+ }
// Close () if open because of SR
if (showSR) {
- filter_expr += QString(")");
+ if (rat_ == RLC_RAT_LTE) {
+ filter_expr += QString(")");
+ }
}
// Close () if open because of RACH
if (showRACH) {
- filter_expr += QString(")");
+ if (rat_ == RLC_RAT_LTE) {
+ filter_expr += QString(")");
+ }
}
return filter_expr;
@@ -623,6 +690,7 @@ public:
}
private:
+ uint8_t rat_;
unsigned ueid_;
rlc_ue_stats stats_;
@@ -633,15 +701,16 @@ private:
};
-// Only the first 3 columns headings differ between UE and channel rows.
-
-static const QString ue_col_0_title_ = QObject::tr("UE Id");
-static const QString ue_col_1_title_ = QObject::tr("");
+// Only the first 4 columns headings differ between UE and channel rows.
+static const QString ue_col_0_title_ = QObject::tr("RAT");
+static const QString ue_col_1_title_ = QObject::tr("UE Id");
static const QString ue_col_2_title_ = QObject::tr("");
+static const QString ue_col_3_title_ = QObject::tr("");
-static const QString channel_col_0_title_ = QObject::tr("Name");
-static const QString channel_col_1_title_ = QObject::tr("Mode");
-static const QString channel_col_2_title_ = QObject::tr("Priority");
+static const QString channel_col_0_title_ = QObject::tr("");
+static const QString channel_col_1_title_ = QObject::tr("Name");
+static const QString channel_col_2_title_ = QObject::tr("Mode");
+static const QString channel_col_3_title_ = QObject::tr("Priority");
@@ -650,11 +719,11 @@ static const QString channel_col_2_title_ = QObject::tr("Priority");
// Constructor.
LteRlcStatisticsDialog::LteRlcStatisticsDialog(QWidget &parent, CaptureFile &cf, const char *filter) :
- TapParameterDialog(parent, cf, HELP_STATS_LTE_MAC_TRAFFIC_DIALOG),
+ TapParameterDialog(parent, cf, HELP_STATS_LTE_RLC_TRAFFIC_DIALOG),
cf_(cf),
packet_count_(0)
{
- setWindowSubtitle(tr("LTE RLC Statistics"));
+ setWindowSubtitle(tr("3GPP RLC Statistics"));
loadGeometry((parent.width() * 5) / 5, (parent.height() * 3) / 4, "LTERLCStatisticsDialog");
// Create a grid for filtering-related widgetsto also appear in layout.
@@ -692,7 +761,7 @@ LteRlcStatisticsDialog::LteRlcStatisticsDialog(QWidget &parent, CaptureFile &cf,
filter_controls_grid->addWidget(useRLCFramesFromMacCheckBox_);
QStringList header_labels = QStringList()
- << "" << "" << ""
+ << "" << "" << "" << ""
<< tr("UL Frames") << tr("UL Bytes") << tr("UL MB/s")
<< tr("UL ACKs") << tr("UL NACKs") << tr("UL Missing")
<< tr("DL Frames") << tr("DL Bytes") << tr("DL MB/s")
@@ -705,6 +774,9 @@ LteRlcStatisticsDialog::LteRlcStatisticsDialog(QWidget &parent, CaptureFile &cf,
// resizeColumnToContents doesn't work well here, so set sizes manually.
for (int col = 0; col < statsTreeWidget()->columnCount() - 1; col++) {
switch (col) {
+ case col_rat_:
+ statsTreeWidget()->setColumnWidth(col, one_em * 3);
+ break;
case col_ueid_:
statsTreeWidget()->setColumnWidth(col, one_em * 7);
break;
@@ -770,24 +842,33 @@ void LteRlcStatisticsDialog::tapReset(void *ws_dlg_ptr)
// Process the tap info from a dissected RLC PDU.
// Returns TAP_PACKET_REDRAW if a redraw is needed, TAP_PACKET_DONT_REDRAW otherwise.
-tap_packet_status LteRlcStatisticsDialog::tapPacket(void *ws_dlg_ptr, struct _packet_info *, epan_dissect *, const void *rlc_lte_tap_info_ptr, tap_flags_t)
+tap_packet_status LteRlcStatisticsDialog::tapPacket(void *ws_dlg_ptr, struct _packet_info *, epan_dissect *, const void *rlc_3gpp_tap_info_ptr, tap_flags_t)
{
// Look up dialog.
LteRlcStatisticsDialog *ws_dlg = static_cast<LteRlcStatisticsDialog *>(ws_dlg_ptr);
- const rlc_lte_tap_info *rlt_info = (const rlc_lte_tap_info *) rlc_lte_tap_info_ptr;
+ const rlc_3gpp_tap_info *rlt_info = (const rlc_3gpp_tap_info *) rlc_3gpp_tap_info_ptr;
if (!ws_dlg || !rlt_info) {
return TAP_PACKET_DONT_REDRAW;
}
+ // Are we ignoring RLC frames that were found in MAC frames, or only those
+ // that were logged separately?
+ if ((!recent.gui_rlc_use_pdus_from_mac && rlt_info->loggedInMACFrame) ||
+ (recent.gui_rlc_use_pdus_from_mac && !rlt_info->loggedInMACFrame)) {
+ return TAP_PACKET_DONT_REDRAW;
+ }
+
ws_dlg->incFrameCount();
- // Look for this UE (TODO: avoid linear search if have lots of UEs in capture...)
+ // Look for this UE (TODO: avoid linear search if have lots of UEs in capture?)
RlcUeTreeWidgetItem *ue_ti = NULL;
for (int i = 0; i < ws_dlg->statsTreeWidget()->topLevelItemCount(); i++) {
QTreeWidgetItem *ti = ws_dlg->statsTreeWidget()->topLevelItem(i);
if (ti->type() != rlc_ue_row_type_) continue;
+ // Get UE object for this entry
RlcUeTreeWidgetItem *cur_ru_ti = static_cast<RlcUeTreeWidgetItem*>(ti);
+ // Does it match this tap?
if (cur_ru_ti->isMatch(rlt_info)) {
ue_ti = cur_ru_ti;
break;
@@ -842,6 +923,7 @@ void LteRlcStatisticsDialog::useRLCFramesFromMacCheckBoxToggled(bool state)
fillTree();
}
+// Return a filter expression for currently selected UE or bearer row
const QString LteRlcStatisticsDialog::filterExpression()
{
QString filter_expr;
@@ -864,7 +946,7 @@ const QString LteRlcStatisticsDialog::filterExpression()
void LteRlcStatisticsDialog::fillTree()
{
- if (!registerTapListener("rlc-lte",
+ if (!registerTapListener("rlc-3gpp",
this,
displayFilter_.toLatin1().data(),
TL_REQUIRES_NOTHING,
@@ -904,14 +986,16 @@ void LteRlcStatisticsDialog::updateHeaderLabels()
statsTreeWidget()->selectedItems()[0]->type() == rlc_channel_row_type_) {
// UE column headings.
- statsTreeWidget()->headerItem()->setText(col_ueid_, channel_col_0_title_);
- statsTreeWidget()->headerItem()->setText(col_mode_, channel_col_1_title_);
- statsTreeWidget()->headerItem()->setText(col_priority_, channel_col_2_title_);
+ statsTreeWidget()->headerItem()->setText(col_rat_, channel_col_0_title_);
+ statsTreeWidget()->headerItem()->setText(col_ueid_, channel_col_1_title_);
+ statsTreeWidget()->headerItem()->setText(col_mode_, channel_col_2_title_);
+ statsTreeWidget()->headerItem()->setText(col_priority_, channel_col_3_title_);
} else {
// Channel column headings.
- statsTreeWidget()->headerItem()->setText(col_ueid_, ue_col_0_title_);
- statsTreeWidget()->headerItem()->setText(col_mode_, ue_col_1_title_);
- statsTreeWidget()->headerItem()->setText(col_priority_, ue_col_2_title_);
+ statsTreeWidget()->headerItem()->setText(col_rat_, ue_col_0_title_);
+ statsTreeWidget()->headerItem()->setText(col_ueid_, ue_col_1_title_);
+ statsTreeWidget()->headerItem()->setText(col_mode_, ue_col_2_title_);
+ statsTreeWidget()->headerItem()->setText(col_priority_, ue_col_3_title_);
}
}
@@ -925,11 +1009,15 @@ void LteRlcStatisticsDialog::captureFileClosing()
// Launch a UL graph for the currently-selected channel.
void LteRlcStatisticsDialog::launchULGraphButtonClicked()
{
- if (statsTreeWidget()->selectedItems().count() > 0 && statsTreeWidget()->selectedItems()[0]->type() == rlc_channel_row_type_) {
+ if (statsTreeWidget()->selectedItems().count() > 0 &&
+ statsTreeWidget()->selectedItems()[0]->type() == rlc_channel_row_type_) {
+
// Get the channel item.
QTreeWidgetItem *ti = statsTreeWidget()->selectedItems()[0];
RlcChannelTreeWidgetItem *rc_ti = static_cast<RlcChannelTreeWidgetItem*>(ti);
+ // Launch the graph.
emit launchRLCGraph(true,
+ rc_ti->get_rat(),
rc_ti->get_ueid(),
rc_ti->get_mode(),
rc_ti->get_channelType(),
@@ -946,6 +1034,7 @@ void LteRlcStatisticsDialog::launchDLGraphButtonClicked()
QTreeWidgetItem *ti = statsTreeWidget()->selectedItems()[0];
RlcChannelTreeWidgetItem *rc_ti = static_cast<RlcChannelTreeWidgetItem*>(ti);
emit launchRLCGraph(true,
+ rc_ti->get_rat(),
rc_ti->get_ueid(),
rc_ti->get_mode(),
rc_ti->get_channelType(),
@@ -982,7 +1071,8 @@ QList<QVariant> LteRlcStatisticsDialog::treeItemData(QTreeWidgetItem *item) cons
// Stat command + args
static void
-lte_rlc_statistics_init(const char *args, void*) {
+lte_rlc_statistics_init(const char *args, void*)
+{
QStringList args_l = QString(args).split(',');
QByteArray filter;
if (args_l.length() > 2) {
@@ -992,12 +1082,12 @@ lte_rlc_statistics_init(const char *args, void*) {
}
static stat_tap_ui lte_rlc_statistics_ui = {
- REGISTER_STAT_GROUP_TELEPHONY_LTE,
+ REGISTER_TELEPHONY_GROUP_3GPP_UU,
QT_TRANSLATE_NOOP("LteRlcStatisticsDialog", "RLC Statistics"),
- "rlc-lte,stat",
+ "rlc-3gpp,stat", // cli_string
lte_rlc_statistics_init,
- 0,
- NULL
+ 0, // nparams
+ NULL // params
};
extern "C" {
diff --git a/ui/qt/lte_rlc_statistics_dialog.h b/ui/qt/lte_rlc_statistics_dialog.h
index 50e1af92..fc97996e 100644
--- a/ui/qt/lte_rlc_statistics_dialog.h
+++ b/ui/qt/lte_rlc_statistics_dialog.h
@@ -12,6 +12,10 @@
#include "tap_parameter_dialog.h"
+#include <epan/dissectors/packet-rlc-lte.h>
+#include <epan/dissectors/packet-rlc-3gpp-common.h>
+
+
#include <QCheckBox>
class LteRlcStatisticsDialog : public TapParameterDialog
@@ -30,9 +34,11 @@ protected:
signals:
void launchRLCGraph(bool channelKnown,
- guint16 ueid, guint8 rlcMode,
- guint16 channelType, guint16 channelId,
- guint8 direction);
+ uint8_t version,
+ uint16_t ueid,
+ uint8_t rlcMode,
+ uint16_t channelType, uint16_t channelId,
+ uint8_t direction);
private:
// Extra controls needed for this dialog.
diff --git a/ui/qt/main.cpp b/ui/qt/main.cpp
index 582855f2..c7d459b1 100644
--- a/ui/qt/main.cpp
+++ b/ui/qt/main.cpp
@@ -10,8 +10,6 @@
#include <config.h>
#define WS_LOG_DOMAIN LOG_DOMAIN_MAIN
-#include <glib.h>
-
#include <locale.h>
#ifdef _WIN32
@@ -77,6 +75,7 @@
#include "ui/preference_utils.h"
#include "ui/software_update.h"
#include "ui/taps.h"
+#include "ui/profile.h"
#include "ui/qt/conversation_dialog.h"
#include "ui/qt/utils/color_utils.h"
@@ -209,11 +208,27 @@ gather_wireshark_qt_compiled_info(feature_list l)
#endif
gather_caplibs_compile_info(l);
epan_gather_compile_info(l);
+#ifdef HAVE_MINIZIPNG
+ with_feature(l, "Minizip-ng %s", MINIZIPNG_VERSION);
+#else
+#ifdef HAVE_MINIZIP
+ with_feature(l, "Minizip %s", MINIZIP_VERSION);
+#else
+ without_feature(l, "Minizip");
+#endif
+#endif /* HAVE_MINIZIPNG */
#ifdef QT_MULTIMEDIA_LIB
with_feature(l, "QtMultimedia");
#else
without_feature(l, "QtMultimedia");
#endif
+#if !defined(Q_OS_WIN) && !defined(Q_OS_MAC)
+#ifdef QT_DBUS_LIB
+ with_feature(l, "QtDBus");
+#else
+ without_feature(l, "QtDBus");
+#endif
+#endif /* !Q_OS_WIN && !Q_OS_MAC */
const char *update_info = software_update_info();
if (update_info) {
@@ -228,12 +243,6 @@ gather_wireshark_qt_compiled_info(feature_list l)
without_feature(l, "AirPcap");
#endif
#endif /* _WIN32 */
-
-#ifdef HAVE_MINIZIP
- with_feature(l, "Minizip");
-#else
- without_feature(l, "Minizip");
-#endif
}
void
@@ -339,7 +348,7 @@ qt_log_message_handler(QtMsgType type, const QMessageLogContext &context, const
static void
check_and_warn_user_startup()
{
- gchar *cur_user, *cur_group;
+ char *cur_user, *cur_group;
/* Tell the user not to run as root. */
if (running_with_special_privs() && recent.privs_warn_if_elevated) {
@@ -447,16 +456,15 @@ macos_enable_layer_backing(void)
static GList *
capture_opts_get_interface_list(int *err, char **err_str)
{
- /*
- * XXX - should this pass an update callback?
- * We already have a window up by the time we start parsing
- * the majority of the command-line arguments, because
- * we need to do a bunch of initialization work before
- * parsing those arguments, and we want to let the user
- * know that we're doing that initialization, given that
- * it can take a while.
- */
- return capture_interface_list(err, err_str, NULL);
+ if (mainApp) {
+ GList *if_list = mainApp->getInterfaceList();
+ if (if_list == NULL) {
+ if_list = capture_interface_list(err, err_str, main_window_update);
+ mainApp->setInterfaceList(if_list);
+ }
+ return if_list;
+ }
+ return capture_interface_list(err, err_str, main_window_update);
}
#endif
@@ -475,15 +483,15 @@ int main(int argc, char *qt_argv[])
char *rf_path;
int rf_open_errno;
#ifdef HAVE_LIBPCAP
- gchar *err_str, *err_str_secondary;;
+ char *err_str, *err_str_secondary;
#else
#ifdef _WIN32
#ifdef HAVE_AIRPCAP
- gchar *err_str;
+ char *err_str;
#endif
#endif
#endif
- gchar *err_msg = NULL;
+ char *err_msg = NULL;
df_error_t *df_err = NULL;
QString dfilter, read_filter;
@@ -491,7 +499,7 @@ int main(int argc, char *qt_argv[])
int caps_queries = 0;
#endif
/* Start time in microseconds */
- guint64 start_time = g_get_monotonic_time();
+ uint64_t start_time = g_get_monotonic_time();
static const struct report_message_routines wireshark_report_routines = {
vfailure_alert_box,
vwarning_alert_box,
@@ -542,7 +550,7 @@ int main(int argc, char *qt_argv[])
/* Initialize log handler early so we can have proper logging during startup. */
ws_log_init("wireshark", vcmdarg_err);
/* For backward compatibility with GLib logging and Wireshark 3.4. */
- ws_log_console_writer_set_use_stdout(TRUE);
+ ws_log_console_writer_set_use_stdout(true);
qInstallMessageHandler(qt_log_message_handler);
@@ -551,7 +559,7 @@ int main(int argc, char *qt_argv[])
#endif
#ifdef DEBUG_STARTUP_TIME
- prefs.gui_console_open = console_open_always;
+ ws_log_console_open = LOG_CONSOLE_OPEN_ALWAYS;
#endif /* DEBUG_STARTUP_TIME */
#if defined(Q_OS_MAC)
@@ -675,7 +683,7 @@ int main(int argc, char *qt_argv[])
g_free (rf_path);
}
- profile_store_persconffiles(TRUE);
+ profile_store_persconffiles(true);
recent_init();
/* Read the profile independent recent file. We have to do this here so we can */
@@ -704,7 +712,7 @@ int main(int argc, char *qt_argv[])
// https://bugreports.qt.io/browse/QTBUG-53022 - The device pixel ratio is pretty much bogus on Windows.
// https://bugreports.qt.io/browse/QTBUG-55510 - Windows have wrong size
//
- // Deprecated in Qt6.
+ // Deprecated in Qt6, which is Per-Monitor DPI Aware V2 by default.
// warning: 'Qt::AA_EnableHighDpiScaling' is deprecated: High-DPI scaling is always enabled.
// This attribute no longer has any effect.
#if defined(Q_OS_WIN) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
@@ -762,8 +770,10 @@ int main(int argc, char *qt_argv[])
GLibMainloopOnQEventLoop::setup(main_w);
// We may not need a queued connection here but it would seem to make sense
// to force the issue.
- main_w->connect(&ws_app, SIGNAL(openCaptureFile(QString,QString,unsigned int)),
- main_w, SLOT(openCaptureFile(QString,QString,unsigned int)));
+ main_w->connect(&ws_app, &WiresharkApplication::openCaptureFile,
+ main_w, [&](QString cf_path, QString display_filter, unsigned int type) {
+ main_w->openCaptureFile(cf_path, display_filter, type);
+ });
main_w->connect(&ws_app, &WiresharkApplication::openCaptureOptions,
main_w, &WiresharkMainWindow::showCaptureOptionsDialog);
@@ -793,7 +803,7 @@ int main(int argc, char *qt_argv[])
* dissection-time handlers for file-type-dependent blocks can
* register using the file type/subtype value for the file type.
*/
- wtap_init(TRUE);
+ wtap_init(true);
splash_update(RA_DISSECTORS, NULL, NULL);
#ifdef DEBUG_STARTUP_TIME
@@ -803,14 +813,14 @@ int main(int argc, char *qt_argv[])
"-G" flag, as the "-G" flag dumps information registered by the
dissectors, and we must do it before we read the preferences, in
case any dissectors register preferences. */
- if (!epan_init(splash_update, NULL, TRUE)) {
+ if (!epan_init(splash_update, NULL, true)) {
SimpleDialog::displayQueuedMessages(main_w);
ret_val = WS_EXIT_INIT_FAILED;
goto clean_exit;
}
#ifdef DEBUG_STARTUP_TIME
/* epan_init resets the preferences */
- prefs.gui_console_open = console_open_always;
+ ws_log_console_open = LOG_CONSOLE_OPEN_ALWAYS;
ws_log(LOG_DOMAIN_MAIN, LOG_LEVEL_INFO, "epan done, elapsed time %" PRIu64 " us \n", g_get_monotonic_time() - start_time);
#endif
@@ -847,11 +857,6 @@ int main(int argc, char *qt_argv[])
in_file_type = open_info_name_to_type(ex_opt_get_next("read_format"));
}
-#ifdef DEBUG_STARTUP_TIME
- ws_log(LOG_DOMAIN_MAIN, LOG_LEVEL_INFO, "Calling extcap_register_preferences, elapsed time %" PRIu64 " us \n", g_get_monotonic_time() - start_time);
-#endif
- splash_update(RA_EXTCAP, NULL, NULL);
- extcap_register_preferences();
splash_update(RA_PREFERENCES, NULL, NULL);
#ifdef DEBUG_STARTUP_TIME
ws_log(LOG_DOMAIN_MAIN, LOG_LEVEL_INFO, "Calling module preferences, elapsed time %" PRIu64 " us \n", g_get_monotonic_time() - start_time);
@@ -864,7 +869,17 @@ int main(int argc, char *qt_argv[])
* line, and store them. We have to do this before applying the
* preferences to the capture options.
*/
- commandline_override_prefs(argc, argv, TRUE);
+ commandline_override_prefs(argc, argv, true);
+
+ /* Register the extcap preferences. We do this after seeing if the
+ * capture_no_extcap preference is set in the configuration file
+ * or command line. This will re-read the extcap specific preferences.
+ */
+#ifdef DEBUG_STARTUP_TIME
+ ws_log(LOG_DOMAIN_MAIN, LOG_LEVEL_INFO, "Calling extcap_register_preferences, elapsed time %" PRIu64 " us \n", g_get_monotonic_time() - start_time);
+#endif
+ splash_update(RA_EXTCAP, NULL, NULL);
+ extcap_register_preferences();
/* Some of the preferences affect the capture options. Apply those
* before getting the other command line arguments, which can also
@@ -875,7 +890,21 @@ int main(int argc, char *qt_argv[])
prefs_to_capture_opts();
/* Now get our remaining args */
- commandline_other_options(argc, argv, TRUE);
+
+ /* XXX: Processing interface options on the command line might retrieve
+ * interface list. We don't yet know if we will need to retrieve the
+ * interface capabilities as well (e.g. are we printing capabilities,
+ * or loading the interface list?) until we parse other options, like
+ * whether we have a capture file.
+ *
+ * We'd prefer to avoid firing up dumpcap twice (once for the list
+ * without the capabilities and once for capabilities), especially
+ * on Windows where that could mean two UAC prompts. However, getting
+ * the interface capabilities is a bit time-consuming so we don't want
+ * to do it if we don't need to.
+ */
+
+ commandline_other_options(argc, argv, true);
/* Convert some command-line parameters to QStrings */
if (global_commandline_info.cf_name != NULL)
@@ -890,17 +919,9 @@ int main(int argc, char *qt_argv[])
timestamp_set_seconds_type (recent.gui_seconds_format);
#ifdef HAVE_LIBPCAP
-#ifdef DEBUG_STARTUP_TIME
- ws_log(LOG_DOMAIN_MAIN, LOG_LEVEL_INFO, "Calling fill_in_local_interfaces, elapsed time %" PRIu64 " us \n", g_get_monotonic_time() - start_time);
-#endif
- splash_update(RA_INTERFACES, NULL, NULL);
-
- if (!global_commandline_info.cf_name && !prefs.capture_no_interface_load)
- fill_in_local_interfaces(main_window_update);
-
- if (global_commandline_info.list_link_layer_types)
+ if (global_commandline_info.list_link_layer_types)
caps_queries |= CAPS_QUERY_LINK_TYPES;
- if (global_commandline_info.list_timestamp_types)
+ if (global_commandline_info.list_timestamp_types)
caps_queries |= CAPS_QUERY_TIMESTAMP_TYPES;
if (global_commandline_info.start_capture || caps_queries) {
@@ -919,27 +940,41 @@ int main(int argc, char *qt_argv[])
* and exit.
*/
if (caps_queries) {
- guint i;
+ unsigned i;
#ifdef _WIN32
create_console();
#endif /* _WIN32 */
/* Get the list of link-layer types for the capture devices. */
ret_val = EXIT_SUCCESS;
+ GList *if_cap_queries = NULL;
+ if_cap_query_t *if_cap_query;
+ GHashTable *capability_hash;
for (i = 0; i < global_capture_opts.ifaces->len; i++) {
interface_options *interface_opts;
- if_capabilities_t *caps;
- char *auth_str = NULL;
interface_opts = &g_array_index(global_capture_opts.ifaces, interface_options, i);
+ if_cap_query = g_new(if_cap_query_t, 1);
+ if_cap_query->name = interface_opts->name;
+ if_cap_query->monitor_mode = interface_opts->monitor_mode;
+ if_cap_query->auth_username = NULL;
+ if_cap_query->auth_password = NULL;
#ifdef HAVE_PCAP_REMOTE
if (interface_opts->auth_type == CAPTURE_AUTH_PWD) {
- auth_str = ws_strdup_printf("%s:%s", interface_opts->auth_username, interface_opts->auth_password);
+ if_cap_query->auth_username = interface_opts->auth_username;
+ if_cap_query->auth_password = interface_opts->auth_password;
}
#endif
- caps = capture_get_if_capabilities(interface_opts->name, interface_opts->monitor_mode,
- auth_str, &err_str, &err_str_secondary, NULL);
- g_free(auth_str);
+ if_cap_queries = g_list_prepend(if_cap_queries, if_cap_query);
+ }
+ if_cap_queries = g_list_reverse(if_cap_queries);
+ capability_hash = capture_get_if_list_capabilities(if_cap_queries, &err_str, &err_str_secondary, NULL);
+ g_list_free_full(if_cap_queries, g_free);
+ for (i = 0; i < global_capture_opts.ifaces->len; i++) {
+ interface_options *interface_opts;
+ if_capabilities_t *caps;
+ interface_opts = &g_array_index(global_capture_opts.ifaces, interface_options, i);
+ caps = static_cast<if_capabilities_t*>(g_hash_table_lookup(capability_hash, interface_opts->name));
if (caps == NULL) {
cmdarg_err("%s%s%s", err_str, err_str_secondary ? "\n" : "", err_str_secondary ? err_str_secondary : "");
g_free(err_str);
@@ -949,7 +984,6 @@ int main(int argc, char *qt_argv[])
}
ret_val = capture_opts_print_if_capabilities(caps, interface_opts,
caps_queries);
- free_if_capabilities(caps);
if (ret_val != EXIT_SUCCESS) {
break;
}
@@ -957,9 +991,19 @@ int main(int argc, char *qt_argv[])
#ifdef _WIN32
destroy_console();
#endif /* _WIN32 */
+ g_hash_table_destroy(capability_hash);
goto clean_exit;
}
+#ifdef DEBUG_STARTUP_TIME
+ ws_log(LOG_DOMAIN_MAIN, LOG_LEVEL_INFO, "Calling fill_in_local_interfaces, elapsed time %" PRIu64 " us \n", g_get_monotonic_time() - start_time);
+#endif
+ splash_update(RA_INTERFACES, NULL, NULL);
+
+ if (!global_commandline_info.cf_name && !prefs.capture_no_interface_load) {
+ wsApp->scanLocalInterfaces(nullptr);
+ }
+
capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
capture_opts_trim_ring_num_files(&global_capture_opts);
#endif /* HAVE_LIBPCAP */
@@ -972,17 +1016,18 @@ int main(int argc, char *qt_argv[])
#endif
splash_update(RA_PREFERENCES_APPLY, NULL, NULL);
prefs_apply_all();
+ wsApp->emitAppSignal(WiresharkApplication::ColorsChanged);
wsApp->emitAppSignal(WiresharkApplication::PreferencesChanged);
#ifdef HAVE_LIBPCAP
if ((global_capture_opts.num_selected == 0) &&
(prefs.capture_device != NULL)) {
- guint i;
+ unsigned i;
interface_t *device;
for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
if (!device->hidden && strcmp(device->display_name, prefs.capture_device) == 0) {
- device->selected = TRUE;
+ device->selected = true;
global_capture_opts.num_selected++;
break;
}
@@ -999,7 +1044,7 @@ int main(int argc, char *qt_argv[])
goto clean_exit;
}
- build_column_format_array(&CaptureFile::globalCapFile()->cinfo, global_commandline_info.prefs_p->num_cols, TRUE);
+ build_column_format_array(&CaptureFile::globalCapFile()->cinfo, global_commandline_info.prefs_p->num_cols, true);
wsApp->emitAppSignal(WiresharkApplication::ColumnsChanged); // We read "recent" widths above.
wsApp->emitAppSignal(WiresharkApplication::RecentPreferencesRead); // Must be emitted after PreferencesChanged.
@@ -1022,7 +1067,7 @@ int main(int argc, char *qt_argv[])
* processEvents() here.
*/
wsApp->allSystemsGo();
- ws_log(LOG_DOMAIN_MAIN, LOG_LEVEL_INFO, "Wireshark is up and ready to go, elapsed time %.3fs", (float) (g_get_monotonic_time() - start_time) / 1000000);
+ ws_info("Wireshark is up and ready to go, elapsed time %.3fs", (float) (g_get_monotonic_time() - start_time) / 1000000);
SimpleDialog::displayQueuedMessages(main_w);
/* User could specify filename, or display filter, or both */
@@ -1043,7 +1088,7 @@ int main(int argc, char *qt_argv[])
if (global_commandline_info.go_to_packet != 0) {
/* Jump to the specified frame number, kept for backward
compatibility. */
- cf_goto_frame(CaptureFile::globalCapFile(), global_commandline_info.go_to_packet);
+ cf_goto_frame(CaptureFile::globalCapFile(), global_commandline_info.go_to_packet, false);
} else if (global_commandline_info.jfilter != NULL) {
dfilter_t *jump_to_filter = NULL;
/* try to compile given filter */
@@ -1069,7 +1114,7 @@ int main(int argc, char *qt_argv[])
if (global_capture_opts.save_file != NULL) {
/* Save the directory name for future file dialogs. */
/* (get_dirname overwrites filename) */
- gchar *s = g_strdup(global_capture_opts.save_file);
+ char *s = g_strdup(global_capture_opts.save_file);
set_last_open_dir(get_dirname(s));
g_free(s);
}
@@ -1079,6 +1124,9 @@ int main(int argc, char *qt_argv[])
/* If no user interfaces were specified on the command line,
copy the list of selected interfaces to the set of interfaces
to use for this capture. */
+ /* XXX: I don't think this can happen, because if start_capture is
+ * true then capture_opts_default_iface_if_necessary() was called
+ */
if (global_capture_opts.ifaces->len == 0)
collect_ifaces(&global_capture_opts);
CaptureFile::globalCapFile()->window = main_w;
@@ -1106,8 +1154,10 @@ int main(int argc, char *qt_argv[])
// loaded when the dialog is shown. Register them here.
profile_register_persconffile("io_graphs");
profile_register_persconffile("import_hexdump.json");
+ profile_register_persconffile("remote_hosts.json");
- profile_store_persconffiles(FALSE);
+ profile_store_persconffiles(false);
+ init_profile_list();
// If the wsApp->exec() event loop exits cleanly, we call
// WiresharkApplication::cleanup().
diff --git a/ui/qt/main_application.cpp b/ui/qt/main_application.cpp
index bc52b6cf..00b65218 100644
--- a/ui/qt/main_application.cpp
+++ b/ui/qt/main_application.cpp
@@ -31,7 +31,9 @@
#include "epan/tap.h"
#include "epan/timestamp.h"
#include "epan/decode_as.h"
+#include "epan/dfilter/dfilter-macro.h"
+#include "ui/commandline.h"
#include "ui/decode_as_utils.h"
#include "ui/preference_utils.h"
#include "ui/iface_lists.h"
@@ -110,7 +112,7 @@
#pragma warning(pop)
#endif
-MainApplication *mainApp = NULL;
+MainApplication *mainApp;
// XXX - Copied from ui/gtk/file_dlg.c
@@ -161,7 +163,7 @@ topic_action(topic_action_e action)
* https://stackoverflow.com/questions/437212/how-do-you-register-a-most-recently-used-list-with-windows-in-preparation-for-win
*/
extern "C" void
-add_menu_recent_capture_file(const gchar *cf_name) {
+add_menu_recent_capture_file(const char *cf_name, bool force) {
QString normalized_cf_name = QString::fromUtf8(cf_name);
QDir cf_path;
@@ -196,7 +198,7 @@ add_menu_recent_capture_file(const gchar *cf_name) {
*/
ri->filename.compare(normalized_cf_name) == 0 ||
#endif
- cnt >= prefs.gui_recent_files_count_max) {
+ (!force && cnt >= prefs.gui_recent_files_count_max)) {
rii.remove();
delete(ri);
cnt--;
@@ -212,12 +214,15 @@ extern "C" void menu_recent_file_write_all(FILE *rf) {
/* we have to iterate backwards through the children's list,
* so we get the latest item last in the file.
*/
- QListIterator<recent_item_status *> rii(recent_captures_);
- rii.toBack();
- while (rii.hasPrevious()) {
- QString cf_name;
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ int i = qMin(recent_captures_.size(), (int)(prefs.gui_recent_files_count_max)) - 1;
+#else
+ qsizetype i = qMin(recent_captures_.size(), (qsizetype)prefs.gui_recent_files_count_max) - 1;
+#endif
+ for (; i >= 0; i--) {
+ recent_item_status *ri = recent_captures_.at(i);
/* get capture filename from the menu item label */
- cf_name = rii.previous()->filename;
+ QString cf_name = ri->filename;
if (!cf_name.isNull()) {
fprintf (rf, RECENT_KEY_CAPTURE_FILE ": %s\n", qUtf8Printable(cf_name));
}
@@ -279,7 +284,7 @@ void MainApplication::colorSchemeChanged() {
void MainApplication::updateTaps()
{
- draw_tap_listeners(FALSE);
+ draw_tap_listeners(false);
}
QDir MainApplication::openDialogInitialDir() {
@@ -288,7 +293,8 @@ QDir MainApplication::openDialogInitialDir() {
void MainApplication::setLastOpenDirFromFilename(const QString file_name)
{
- QString directory = QFileInfo(file_name).absolutePath();
+ /* XXX - Use canonicalPath() instead of absolutePath()? */
+ QString directory = QDir::toNativeSeparators(QFileInfo(file_name).absolutePath());
/* XXX - printable? */
set_last_open_dir(qUtf8Printable(directory));
}
@@ -298,7 +304,7 @@ void MainApplication::helpTopicAction(topic_action_e action)
QString url = gchar_free_to_qstring(topic_action_url(action));
if (!url.isEmpty()) {
- QDesktopServices::openUrl(QUrl(url));
+ QDesktopServices::openUrl(QUrl(QDir::fromNativeSeparators(url)));
}
}
@@ -396,25 +402,21 @@ void MainApplication::setMonospaceFont(const char *font_string) {
int MainApplication::monospaceTextSize(const char *str)
{
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
return QFontMetrics(mono_font_).horizontalAdvance(str);
-#else
- return QFontMetrics(mono_font_).width(str);
-#endif
}
-void MainApplication::setConfigurationProfile(const gchar *profile_name, bool write_recent_file)
+void MainApplication::setConfigurationProfile(const char *profile_name, bool write_recent_file)
{
char *rf_path;
int rf_open_errno;
- gchar *err_msg = NULL;
+ char *err_msg = NULL;
- gboolean prev_capture_no_interface_load;
- gboolean prev_capture_no_extcap;
+ bool prev_capture_no_interface_load;
+ bool prev_capture_no_extcap;
/* First check if profile exists */
- if (!profile_exists(profile_name, FALSE)) {
- if (profile_exists(profile_name, TRUE)) {
+ if (!profile_exists(profile_name, false)) {
+ if (profile_exists(profile_name, true)) {
char *pf_dir_path, *pf_dir_path2, *pf_filename;
/* Copy from global profile */
if (create_persconffile_profile(profile_name, &pf_dir_path) == -1) {
@@ -425,7 +427,7 @@ void MainApplication::setConfigurationProfile(const gchar *profile_name, bool wr
g_free(pf_dir_path);
}
- if (copy_persconffile_profile(profile_name, profile_name, TRUE, &pf_filename,
+ if (copy_persconffile_profile(profile_name, profile_name, true, &pf_filename,
&pf_dir_path, &pf_dir_path2) == -1) {
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
"Can't copy file \"%s\" in directory\n\"%s\" to\n\"%s\":\n%s.",
@@ -452,7 +454,7 @@ void MainApplication::setConfigurationProfile(const gchar *profile_name, bool wr
/* Get the current geometry, before writing it to disk */
emit profileChanging();
- if (write_recent_file && profile_exists(get_profile_name(), FALSE))
+ if (write_recent_file && profile_exists(get_profile_name(), false))
{
/* Write recent file for profile we are leaving, if it still exists */
write_profile_recent();
@@ -465,6 +467,13 @@ void MainApplication::setConfigurationProfile(const gchar *profile_name, bool wr
/* Apply new preferences */
readConfigurationFiles(true);
+ /* Apply command-line preferences */
+ commandline_options_reapply();
+ extcap_register_preferences();
+
+ /* Switching profile requires reloading the macro list. */
+ reloadDisplayFilterMacros();
+
if (!recent_read_profile_static(&rf_path, &rf_open_errno)) {
simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
"Could not open common recent file\n\"%s\": %s.",
@@ -493,6 +502,7 @@ void MainApplication::setConfigurationProfile(const gchar *profile_name, bool wr
emit freezePacketList(true);
emit columnsChanged();
+ emit colorsChanged();
emit preferencesChanged();
emit recentPreferencesRead();
emit filterExpressionsChanged();
@@ -522,7 +532,7 @@ void MainApplication::setConfigurationProfile(const gchar *profile_name, bool wr
void MainApplication::reloadLuaPluginsDelayed()
{
- QTimer::singleShot(0, this, SIGNAL(reloadLuaPlugins()));
+ QTimer::singleShot(0, this, &MainApplication::reloadLuaPlugins);
}
const QIcon &MainApplication::normalIcon()
@@ -646,6 +656,9 @@ MainApplication::MainApplication(int &argc, char **argv) :
is_reloading_lua_(false),
if_notifier_(NULL),
active_captures_(0)
+#ifdef HAVE_LIBPCAP
+ , cached_if_list_(NULL)
+#endif
{
mainApp = this;
@@ -675,15 +688,13 @@ MainApplication::MainApplication(int &argc, char **argv) :
setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
#endif
-#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) && QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
setAttribute(Qt::AA_DisableWindowContextHelpButton);
#endif
// Throw various settings at the wall with the hope that one of them will
// enable context menu shortcuts QTBUG-69452, QTBUG-109590
-#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
setAttribute(Qt::AA_DontShowShortcutsInContextMenus, false);
-#endif
#if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
styleHints()->setShowShortcutsInContextMenus(true);
#endif
@@ -696,7 +707,7 @@ MainApplication::MainApplication(int &argc, char **argv) :
// QFileSystemWatcher should allow us to watch for files being
// removed or renamed. It uses kqueues and EVFILT_VNODE on FreeBSD,
// NetBSD, FSEvents on macOS, inotify on Linux if available, and
- // FindFirstChagneNotification() on Windows. On all other platforms,
+ // FindFirstChangeNotification() on Windows. On all other platforms,
// it just periodically polls, as we're doing now.
//
// For unmounts:
@@ -775,17 +786,17 @@ MainApplication::MainApplication(int &argc, char **argv) :
// I'm not sure what can be done on Linux.
//
recent_timer_.setParent(this);
- connect(&recent_timer_, SIGNAL(timeout()), this, SLOT(refreshRecentCaptures()));
+ connect(&recent_timer_, &QTimer::timeout, this, &MainApplication::refreshRecentCaptures);
recent_timer_.start(2000);
packet_data_timer_.setParent(this);
- connect(&packet_data_timer_, SIGNAL(timeout()), this, SLOT(refreshPacketData()));
+ connect(&packet_data_timer_, &QTimer::timeout, this, &MainApplication::refreshPacketData);
packet_data_timer_.start(1000);
tap_update_timer_.setParent(this);
tap_update_timer_.setInterval(TAP_UPDATE_DEFAULT_INTERVAL);
- connect(this, SIGNAL(appInitialized()), &tap_update_timer_, SLOT(start()));
- connect(&tap_update_timer_, SIGNAL(timeout()), this, SLOT(updateTaps()));
+ connect(this, &MainApplication::appInitialized, &tap_update_timer_, [&]() { tap_update_timer_.start(); });
+ connect(&tap_update_timer_, &QTimer::timeout, this, &MainApplication::updateTaps);
// Application-wide style sheet
QString app_style_sheet = qApp->styleSheet();
@@ -795,7 +806,7 @@ MainApplication::MainApplication(int &argc, char **argv) :
prefs_set_gui_theme_is_dark(ColorUtils::themeIsDark());
#if defined(HAVE_SOFTWARE_UPDATE) && defined(Q_OS_WIN)
- connect(this, SIGNAL(softwareUpdateQuit()), this, SLOT(quit()), Qt::QueuedConnection);
+ connect(this, &MainApplication::softwareUpdateQuit, this, &MainApplication::quit, Qt::QueuedConnection);
#endif
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0) && defined(Q_OS_WIN)
@@ -803,14 +814,16 @@ MainApplication::MainApplication(int &argc, char **argv) :
connect(styleHints(), &QStyleHints::colorSchemeChanged, this, &MainApplication::colorSchemeChanged);
#endif
- connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(cleanup()));
+ connect(qApp, &QApplication::aboutToQuit, this, &MainApplication::cleanup);
}
MainApplication::~MainApplication()
{
mainApp = NULL;
+#ifdef HAVE_LIBPCAP
+ free_interface_list(cached_if_list_);
+#endif
clearDynamicMenuGroupItems();
- free_filter_lists();
}
void MainApplication::registerUpdate(register_action_e action, const char *message)
@@ -857,6 +870,9 @@ void MainApplication::emitAppSignal(AppSignal signal)
case FieldsChanged:
emit fieldsChanged();
break;
+ case ColorsChanged:
+ emit colorsChanged();
+ break;
case FreezePacketList:
emit freezePacketList(false);
break;
@@ -985,7 +1001,7 @@ static void
iface_mon_event_cb(const char *iface, int added, int up)
{
int present = 0;
- guint ifs, j;
+ unsigned ifs, j;
interface_t *device;
interface_options *interface_opts;
@@ -1014,6 +1030,27 @@ iface_mon_event_cb(const char *iface, int added, int up)
/*
* We've been told that there's a new interface or that an old
* interface is gone; reload the local interface list.
+ *
+ * XXX: We also want to reload the local interface list if [what
+ * we can retrieve about] the capabilities of the device have changed.
+ * Ideally we'd update the capabilities of just the one device in
+ * the cache and signal that the list has been updated, instead of
+ * freeing the entire cache and scanning again - but some extcaps
+ * depend on other interfaces being up; e.g. by default androiddump
+ * tries to connect to the loopback interface to look for adb running,
+ * so if the loopback interface changes so does the status of
+ * androiddump.
+ *
+ * On Linux, at least, you can't get the capabilities from a down
+ * interface, but it's still present in all_ifaces - dumpcap returns
+ * it in the list, and we show it so the user can get a status / error
+ * message when trying to capture on it instead of it vanishing.
+ * So if both present and up are true, then we still want to refresh
+ * to update the capabilities and restart the stats.
+ *
+ * We also store the address in all_ifaces and show them to the user,
+ * so we probably should monitor those events as well and update
+ * the interface list appropriately when those change.
*/
mainApp->refreshLocalInterfaces();
}
@@ -1045,21 +1082,23 @@ void MainApplication::refreshLocalInterfaces()
extcap_clear_interfaces();
#ifdef HAVE_LIBPCAP
- /*
- * Reload the local interface list.
- */
- scan_local_interfaces(main_window_update);
-
- /*
- * Now emit a signal to indicate that the list changed, so that all
- * places displaying the list will get updated.
- *
- * XXX - only if it *did* change.
- */
- emit localInterfaceListChanged();
+ emit scanLocalInterfaces(nullptr);
#endif
}
+#ifdef HAVE_LIBPCAP
+GList* MainApplication::getInterfaceList() const
+{
+ return interface_list_copy(cached_if_list_);
+}
+
+void MainApplication::setInterfaceList(GList *if_list)
+{
+ free_interface_list(cached_if_list_);
+ cached_if_list_ = interface_list_copy(if_list);
+}
+#endif
+
void MainApplication::allSystemsGo()
{
QString display_filter = NULL;
@@ -1077,7 +1116,7 @@ void MainApplication::allSystemsGo()
if (err == 0) {
if_notifier_ = new QSocketNotifier(iface_mon_get_sock(),
QSocketNotifier::Read, this);
- connect(if_notifier_, SIGNAL(activated(int)), SLOT(ifChangeEventsAvailable()));
+ connect(if_notifier_, &QSocketNotifier::activated, this, &MainApplication::ifChangeEventsAvailable);
}
#endif
}
@@ -1099,9 +1138,6 @@ _e_prefs *MainApplication::readConfigurationFiles(bool reset)
/* Load libwireshark settings from the current profile. */
prefs_p = epan_load_settings();
- /* Read the capture filter file. */
- read_filter_list(CFILTER_LIST);
-
return prefs_p;
}
@@ -1178,9 +1214,9 @@ void MainApplication::loadLanguage(const QString newLanguage)
switchTranslator(mainApp->translator,
QString("wireshark_%1.qm").arg(localeLanguage), QString(get_datafile_dir()) + QString("/languages"));
if (QFile::exists(QString("%1/wireshark_%3.qm")
- .arg(gchar_free_to_qstring(get_persconffile_path("languages", FALSE))).arg(localeLanguage)))
+ .arg(gchar_free_to_qstring(get_persconffile_path("languages", false))).arg(localeLanguage)))
switchTranslator(mainApp->translator,
- QString("wireshark_%1.qm").arg(localeLanguage), gchar_free_to_qstring(get_persconffile_path("languages", FALSE)));
+ QString("wireshark_%1.qm").arg(localeLanguage), gchar_free_to_qstring(get_persconffile_path("languages", false)));
if (QFile::exists(QString("%1/qt_%2.qm")
.arg(get_datafile_dir()).arg(localeLanguage))) {
switchTranslator(mainApp->translatorQt,
@@ -1381,3 +1417,11 @@ void MainApplication::gotoFrame(int frame)
MainWindow * mw = qobject_cast<MainWindow *>(mainWindow());
mw->gotoFrame(frame);
}
+
+void MainApplication::reloadDisplayFilterMacros()
+{
+ dfilter_macro_reload();
+ // The signal is needed when the display filter grammar changes for
+ // any reason (not just "fields".)
+ mainApp->emitAppSignal(MainApplication::FieldsChanged);
+}
diff --git a/ui/qt/main_application.h b/ui/qt/main_application.h
index dd5b0bab..de7aad0a 100644
--- a/ui/qt/main_application.h
+++ b/ui/qt/main_application.h
@@ -12,8 +12,6 @@
#include <config.h>
-#include <glib.h>
-
#include "wsutil/feature_list.h"
#include "epan/register.h"
@@ -56,6 +54,7 @@ public:
enum AppSignal {
CaptureFilterListChanged,
+ ColorsChanged,
ColumnsChanged,
DisplayFilterListChanged,
FieldsChanged,
@@ -89,6 +88,16 @@ public:
// Emitting app signals (PacketDissectionChanged in particular) from
// dialogs on macOS can be problematic. Dialogs should call queueAppSignal
// instead.
+ // On macOS, nested event loops (e.g., calling a dialog with exec())
+ // that call processEvents (e.g., from PacketDissectionChanged, or
+ // anything with a ProgressFrame) caused issues off and on from 5.3.0
+ // until 5.7.1/5.8.0. It appears to be solved after some false starts:
+ // https://bugreports.qt.io/browse/QTBUG-53947
+ // https://bugreports.qt.io/browse/QTBUG-56746
+ // We also try to avoid exec / additional event loops as much as possible:
+ // e.g., commit f67eccedd9836e6ced1f57ae9889f57a5400a3d7
+ // (note it can show up in unexpected places, e.g. static functions like
+ // WiresharkFileDialog::getOpenFileName())
void queueAppSignal(AppSignal signal) { app_signals_ << signal; }
void emitStatCommandSignal(const QString &menu_path, const char *arg, void *userdata);
void emitTapParameterSignal(const QString cfg_abbr, const QString arg, void *userdata);
@@ -105,6 +114,13 @@ public:
void emitLocalInterfaceEvent(const char *ifname, int added, int up);
virtual void refreshLocalInterfaces();
+#ifdef HAVE_LIBPCAP
+ // This returns a deep copy of the cached interface list that must
+ // be freed with free_interface_list.
+ GList * getInterfaceList() const;
+ // This set the cached interface list to a deep copy of if_list.
+ void setInterfaceList(GList *if_list);
+#endif
struct _e_prefs * readConfigurationFiles(bool reset);
QList<recent_item_status *> recentItems() const;
@@ -116,7 +132,7 @@ public:
const QFont monospaceFont(bool zoomed = false) const;
void setMonospaceFont(const char *font_string);
int monospaceTextSize(const char *str);
- void setConfigurationProfile(const gchar *profile_name, bool write_recent_file = true);
+ void setConfigurationProfile(const char *profile_name, bool write_recent_file = true);
void reloadLuaPluginsDelayed();
bool isInitialized() { return initialized_; }
void setReloadingLua(bool is_reloading) { is_reloading_lua_ = is_reloading; }
@@ -160,6 +176,7 @@ private:
static QString window_title_separator_;
QList<AppSignal> app_signals_;
int active_captures_;
+
#if defined(HAVE_SOFTWARE_UPDATE) && defined(Q_OS_WIN)
bool software_update_ok_;
#endif
@@ -173,10 +190,14 @@ protected:
QIcon normal_icon_;
QIcon capture_icon_;
+#ifdef HAVE_LIBPCAP
+ GList *cached_if_list_;
+#endif
signals:
void appInitialized();
void localInterfaceEvent(const char *ifname, int added, int up);
+ void scanLocalInterfaces(GList *filter_list = nullptr);
void localInterfaceListChanged();
void openCaptureFile(QString cf_path, QString display_filter, unsigned int type);
void openCaptureOptions();
@@ -184,7 +205,7 @@ signals:
void updateRecentCaptureStatus(const QString &filename, qint64 size, bool accessible);
void splashUpdate(register_action_e action, const char *message);
void profileChanging();
- void profileNameChanged(const gchar *profile_name);
+ void profileNameChanged(const char *profile_name);
void freezePacketList(bool changing_profile);
void columnsChanged(); // XXX This recreates the packet list. We might want to rename it accordingly.
@@ -192,6 +213,7 @@ signals:
void displayFilterListChanged();
void filterExpressionsChanged();
void packetDissectionChanged();
+ void colorsChanged();
void preferencesChanged();
void addressResolutionChanged();
void columnDataChanged();
@@ -223,6 +245,8 @@ public slots:
// each dialog that calls queueAppSignal closes.
void flushAppSignals();
+ void reloadDisplayFilterMacros();
+
private slots:
void updateTaps();
diff --git a/ui/qt/main_status_bar.cpp b/ui/qt/main_status_bar.cpp
index a504aa7a..3e5c6e9c 100644
--- a/ui/qt/main_status_bar.cpp
+++ b/ui/qt/main_status_bar.cpp
@@ -9,8 +9,6 @@
#include "config.h"
-#include <glib.h>
-
#include "file.h"
#include <epan/expert.h>
@@ -47,13 +45,13 @@ Q_DECLARE_METATYPE(ProfileDialog::ProfileAction)
// If we ever add support for multiple windows this will need to be replaced.
// See also: main_window.cpp
-static MainStatusBar *cur_main_status_bar_ = NULL;
+static MainStatusBar *cur_main_status_bar_;
/*
* Push a formatted temporary message onto the statusbar.
*/
void
-statusbar_push_temporary_msg(const gchar *msg_format, ...)
+statusbar_push_temporary_msg(const char *msg_format, ...)
{
va_list ap;
QString push_msg;
@@ -133,8 +131,8 @@ MainStatusBar::MainStatusBar(QWidget *parent) :
comment_button_->setToolTip(tr("Open the Capture File Properties dialog"));
comment_button_->setEnabled(false);
- connect(expert_button_, SIGNAL(clicked(bool)), this, SIGNAL(showExpertInfo()));
- connect(comment_button_, SIGNAL(clicked(bool)), this, SIGNAL(editCaptureComment()));
+ connect(expert_button_, &QToolButton::clicked, this, &MainStatusBar::showExpertInfo);
+ connect(comment_button_, &QToolButton::clicked, this, &MainStatusBar::editCaptureComment);
info_progress_hb->setContentsMargins(icon_size / 2, 0, 0, 0);
@@ -167,17 +165,13 @@ MainStatusBar::MainStatusBar(QWidget *parent) :
progress_frame_.enableTaskbarUpdates(true);
#endif
- connect(mainApp, SIGNAL(appInitialized()), splitter, SLOT(show()));
- connect(mainApp, SIGNAL(appInitialized()), this, SLOT(appInitialized()));
- connect(&info_status_, SIGNAL(toggleTemporaryFlash(bool)),
- this, SLOT(toggleBackground(bool)));
- connect(mainApp, SIGNAL(profileNameChanged(const gchar *)),
- this, SLOT(setProfileName()));
- connect(&profile_status_, SIGNAL(clickedAt(QPoint,Qt::MouseButton)),
- this, SLOT(showProfileMenu(QPoint,Qt::MouseButton)));
-
- connect(&progress_frame_, SIGNAL(stopLoading()),
- this, SIGNAL(stopLoading()));
+ connect(mainApp, &MainApplication::appInitialized, splitter, &QSplitter::show);
+ connect(mainApp, &MainApplication::appInitialized, this, &MainStatusBar::appInitialized);
+ connect(&info_status_, &LabelStack::toggleTemporaryFlash, this, &MainStatusBar::toggleBackground);
+ connect(mainApp, &MainApplication::profileNameChanged, this, &MainStatusBar::setProfileName);
+ connect(&profile_status_, &ClickableLabel::clickedAt, this, &MainStatusBar::showProfileMenu);
+
+ connect(&progress_frame_, &ProgressFrame::stopLoading, this, &MainStatusBar::stopLoading);
}
void MainStatusBar::showExpert() {
@@ -235,8 +229,7 @@ void MainStatusBar::setFileName(CaptureFile &cf)
if (cf.isValid()) {
popGenericStatus(STATUS_CTX_FILE);
QString msgtip = QString("%1 (%2)")
- .arg(cf.capFile()->filename)
- .arg(file_size_to_qstring(cf.capFile()->f_datalen));
+ .arg(cf.capFile()->filename, file_size_to_qstring(cf.capFile()->f_datalen));
pushGenericStatus(STATUS_CTX_FILE, cf.fileName(), msgtip);
}
}
@@ -264,8 +257,7 @@ void MainStatusBar::setStatusbarForCaptureFile()
if (cap_file_ && cap_file_->filename && (cap_file_->state != FILE_CLOSED)) {
popGenericStatus(STATUS_CTX_FILE);
QString msgtip = QString("%1 (%2)")
- .arg(cap_file_->filename)
- .arg(file_size_to_qstring(cap_file_->f_datalen));
+ .arg(cap_file_->filename, file_size_to_qstring(cap_file_->f_datalen));
pushGenericStatus(STATUS_CTX_FILE,
gchar_free_to_qstring(cf_get_display_name(cap_file_)), msgtip);
}
@@ -298,7 +290,12 @@ void MainStatusBar::selectedFieldChanged(FieldInformation * finfo)
finfo_length = finfo->position().length + finfo->appendix().length;
if (finfo_length > 0) {
- item_info.append(", " + tr("%Ln byte(s)", "", finfo_length));
+ int finfo_bits = FI_GET_BITS_SIZE(finfo->fieldInfo());
+ if (finfo_bits % 8 == 0) {
+ item_info.append(", " + tr("%Ln byte(s)", "", finfo_length));
+ } else {
+ item_info.append(", " + tr("%Ln bit(s)", "", finfo_bits));
+ }
}
}
@@ -312,16 +309,14 @@ void MainStatusBar::highlightedFieldChanged(FieldInformation * finfo)
if (finfo)
{
FieldInformation::Position pos = finfo->position();
- QString field_str;
if (pos.length < 2) {
- hint = QString(tr("Byte %1")).arg(pos.start);
+ hint = tr("Byte %1").arg(pos.start);
} else {
- hint = QString(tr("Bytes %1-%2")).arg(pos.start).arg(pos.start + pos.length - 1);
+ hint = tr("Bytes %1-%2").arg(pos.start).arg(pos.start + pos.length - 1);
}
hint += QString(": %1 (%2)")
- .arg(finfo->headerInfo().name)
- .arg(finfo->headerInfo().abbreviation);
+ .arg(finfo->headerInfo().name, finfo->headerInfo().abbreviation);
}
pushGenericStatus(STATUS_CTX_BYTE, hint);
@@ -337,9 +332,7 @@ void MainStatusBar::pushGenericStatus(StatusContext status, const QString &messa
if (message.isEmpty() && status != STATUS_CTX_FILE && status != STATUS_CTX_TEMPORARY && status != STATUS_CTX_PROGRESS)
popGenericStatus(status);
else
- stack->pushText(message, status);
-
- stack->setToolTip(messagetip);
+ stack->pushText(message, status, messagetip);
if (status == STATUS_CTX_FILTER || status == STATUS_CTX_FILE)
expertUpdate();
@@ -352,8 +345,6 @@ void MainStatusBar::popGenericStatus(StatusContext status)
if (status == STATUS_CTX_MAIN)
stack = &packet_status_;
- stack->setToolTip(QString());
-
stack->popText(status);
}
@@ -365,7 +356,7 @@ void MainStatusBar::setProfileName()
void MainStatusBar::appInitialized()
{
setProfileName();
- connect(mainApp->mainWindow(), SIGNAL(framesSelected(QList<int>)), this, SLOT(selectedFrameChanged(QList<int>)));
+ connect(qobject_cast<MainWindow *>(mainApp->mainWindow()), &MainWindow::framesSelected, this, &MainStatusBar::selectedFrameChanged);
}
void MainStatusBar::selectedFrameChanged(QList<int>)
@@ -390,48 +381,62 @@ void MainStatusBar::showCaptureStatistics()
}
if (cs_count_ > 0) {
if (prefs.gui_show_selected_packet && rows.count() == 1) {
- packets_str.append(QString(tr("Selected Packet: %1 %2 "))
- .arg(rows.at(0))
- .arg(UTF8_MIDDLE_DOT));
+ if (is_packet_configuration_namespace()) {
+ packets_str.append(tr("Selected Packet: %1 %2 ")
+ .arg(rows.at(0))
+ .arg(UTF8_MIDDLE_DOT));
+ } else {
+ packets_str.append(tr("Selected Event: %1 %2 ")
+ .arg(rows.at(0))
+ .arg(UTF8_MIDDLE_DOT));
+ }
+ }
+ if (is_packet_configuration_namespace()) {
+ packets_str.append(tr("Packets: %1")
+ .arg(cs_count_));
+ } else {
+ packets_str.append(tr("Events: %1")
+ .arg(cs_count_));
+ }
+ if (cap_file_->dfilter) {
+ packets_str.append(tr(" %1 Displayed: %2 (%3%)")
+ .arg(UTF8_MIDDLE_DOT)
+ .arg(cap_file_->displayed_count)
+ .arg((100.0*cap_file_->displayed_count)/cs_count_, 0, 'f', 1));
}
- packets_str.append(QString(tr("Packets: %1 %4 Displayed: %2 (%3%)"))
- .arg(cs_count_)
- .arg(cap_file_->displayed_count)
- .arg((100.0*cap_file_->displayed_count)/cs_count_, 0, 'f', 1)
- .arg(UTF8_MIDDLE_DOT));
if (rows.count() > 1) {
- packets_str.append(QString(tr(" %1 Selected: %2 (%3%)"))
+ packets_str.append(tr(" %1 Selected: %2 (%3%)")
.arg(UTF8_MIDDLE_DOT)
.arg(rows.count())
.arg((100.0*rows.count())/cs_count_, 0, 'f', 1));
}
if (cap_file_->marked_count > 0) {
- packets_str.append(QString(tr(" %1 Marked: %2 (%3%)"))
+ packets_str.append(tr(" %1 Marked: %2 (%3%)")
.arg(UTF8_MIDDLE_DOT)
.arg(cap_file_->marked_count)
.arg((100.0*cap_file_->marked_count)/cs_count_, 0, 'f', 1));
}
if (cap_file_->drops_known) {
- packets_str.append(QString(tr(" %1 Dropped: %2 (%3%)"))
+ packets_str.append(tr(" %1 Dropped: %2 (%3%)")
.arg(UTF8_MIDDLE_DOT)
.arg(cap_file_->drops)
.arg((100.0*cap_file_->drops)/cs_count_, 0, 'f', 1));
}
if (cap_file_->ignored_count > 0) {
- packets_str.append(QString(tr(" %1 Ignored: %2 (%3%)"))
+ packets_str.append(tr(" %1 Ignored: %2 (%3%)")
.arg(UTF8_MIDDLE_DOT)
.arg(cap_file_->ignored_count)
.arg((100.0*cap_file_->ignored_count)/cs_count_, 0, 'f', 1));
}
if (cap_file_->packet_comment_count > 0) {
- packets_str.append(QString(tr(" %1 Comments: %2"))
+ packets_str.append(tr(" %1 Comments: %2")
.arg(UTF8_MIDDLE_DOT)
.arg(cap_file_->packet_comment_count));
}
if (prefs.gui_show_file_load_time && !cap_file_->is_tempfile) {
/* Loading an existing file */
- gulong computed_elapsed = cf_get_computed_elapsed(cap_file_);
- packets_str.append(QString(tr(" %1 Load time: %2:%3.%4"))
+ unsigned long computed_elapsed = cf_get_computed_elapsed(cap_file_);
+ packets_str.append(tr(" %1 Load time: %2:%3.%4")
.arg(UTF8_MIDDLE_DOT)
.arg(computed_elapsed/60000, 2, 10, QLatin1Char('0'))
.arg(computed_elapsed%60000/1000, 2, 10, QLatin1Char('0'))
@@ -440,18 +445,32 @@ void MainStatusBar::showCaptureStatistics()
}
} else if (cs_fixed_ && cs_count_ > 0) {
/* There shouldn't be any rows without a cap_file_ but this is benign */
- if (prefs.gui_show_selected_packet && rows.count() == 1) {
- packets_str.append(QString(tr("Selected Packet: %1 %2 "))
- .arg(rows.at(0))
- .arg(UTF8_MIDDLE_DOT));
+ if (is_packet_configuration_namespace()) {
+ if (prefs.gui_show_selected_packet && rows.count() == 1) {
+ packets_str.append(tr("Selected Packet: %1 %2 ")
+ .arg(rows.at(0))
+ .arg(UTF8_MIDDLE_DOT));
+ }
+ packets_str.append(tr("Packets: %1")
+ .arg(cs_count_));
+ } else {
+ if (prefs.gui_show_selected_packet && rows.count() == 1) {
+ packets_str.append(tr("Selected Event: %1 %2 ")
+ .arg(rows.at(0))
+ .arg(UTF8_MIDDLE_DOT));
+ }
+ packets_str.append(tr("Events: %1")
+ .arg(cs_count_));
}
- packets_str.append(QString(tr("Packets: %1"))
- .arg(cs_count_));
}
#endif // HAVE_LIBPCAP
if (packets_str.isEmpty()) {
- packets_str = tr("No Packets");
+ if (is_packet_configuration_namespace()) {
+ packets_str = tr("No Packets");
+ } else {
+ packets_str = tr("No Events");
+ }
}
popGenericStatus(STATUS_CTX_MAIN);
@@ -580,7 +599,7 @@ void MainStatusBar::showProfileMenu(const QPoint &global_pos, Qt::MouseButton bu
action->setEnabled(enable_edit);
ctx_menu_->addSeparator();
-#ifdef HAVE_MINIZIP
+#if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG)
QMenu * importMenu = new QMenu(tr("Import"), ctx_menu_);
action = importMenu->addAction(tr("From Zip File..."), this, SLOT(manageProfile()));
action->setProperty("dialog_action_", (int)ProfileDialog::ImportZipProfile);
diff --git a/ui/qt/main_status_bar.h b/ui/qt/main_status_bar.h
index 611bc017..c53bc54a 100644
--- a/ui/qt/main_status_bar.h
+++ b/ui/qt/main_status_bar.h
@@ -65,7 +65,7 @@ private:
// Capture statistics
bool cs_fixed_;
- guint32 cs_count_;
+ uint32_t cs_count_;
void showCaptureStatistics();
void setStatusbarForCaptureFile();
diff --git a/ui/qt/main_window.cpp b/ui/qt/main_window.cpp
index 0f54995f..5c96863a 100644
--- a/ui/qt/main_window.cpp
+++ b/ui/qt/main_window.cpp
@@ -9,14 +9,19 @@
#include "config.h"
-#include <glib.h>
-
#include "ui/preference_utils.h"
#include "main_window.h"
+#include "epan/dfilter/dfilter-translator.h"
+
+#include <QClipboard>
+
#include "funnel_statistics.h"
+#include "main_application.h"
#include "packet_list.h"
+#include "utils/profile_switcher.h"
+#include "utils/qt_ui_utils.h"
#include "widgets/display_filter_combo.h"
// Packet Menu actions
@@ -32,7 +37,8 @@ MainWindow::MainWindow(QWidget *parent) :
byte_view_tab_(nullptr),
packet_diagram_(nullptr),
df_combo_box_(nullptr),
- main_status_bar_(nullptr)
+ main_status_bar_(nullptr),
+ profile_switcher_(new ProfileSwitcher())
{
}
@@ -51,7 +57,7 @@ bool MainWindow::hasSelection()
/*
* As hasSelection() is not looking for one single packet
- * selection, but at least 2, this method returns TRUE in
+ * selection, but at least 2, this method returns true in
* this specific case.
*/
bool MainWindow::hasUniqueSelection()
@@ -76,9 +82,9 @@ frame_data* MainWindow::frameDataForRow(int row) const
return Q_NULLPTR;
}
-void MainWindow::insertColumn(QString name, QString abbrev, gint pos)
+void MainWindow::insertColumn(QString name, QString abbrev, int pos)
{
- gint colnr = 0;
+ int colnr = 0;
if (name.length() > 0 && abbrev.length() > 0)
{
colnr = column_prefs_add_custom(COL_CUSTOM, name.toStdString().c_str(), abbrev.toStdString().c_str(), pos);
@@ -115,10 +121,10 @@ void MainWindow::setDisplayFilter(QString filter, FilterAction::Action action, F
*
* @param funnel_action a custom packet menu action
*/
-void MainWindow::appendPacketMenu(QAction* funnel_action)
+void MainWindow::appendPacketMenu(FunnelAction* funnel_action)
{
dynamic_packet_menu_actions.append(funnel_action);
- connect(funnel_action, SIGNAL(triggered(bool)), funnel_action, SLOT(triggerPacketCallback()));
+ connect(funnel_action, &FunnelAction::triggered, funnel_action, &FunnelAction::triggerPacketCallback);
}
/*
@@ -177,7 +183,7 @@ bool MainWindow::addPacketMenus(QMenu * ctx_menu, GPtrArray *finfo_array)
// Build a set of fields present for efficient lookups
QSet<QString> fieldsPresent = QSet<QString>();
- for (guint fieldInfoIndex = 0; fieldInfoIndex < finfo_array->len; fieldInfoIndex++) {
+ for (unsigned fieldInfoIndex = 0; fieldInfoIndex < finfo_array->len; fieldInfoIndex++) {
field_info *fi = (field_info *)g_ptr_array_index (finfo_array, fieldInfoIndex);
fieldsPresent.insert(QString(fi->hfinfo->abbrev));
}
@@ -203,3 +209,67 @@ bool MainWindow::addPacketMenus(QMenu * ctx_menu, GPtrArray *finfo_array)
}
return insertedPacketMenu;
}
+
+const char *MainWindow::translator_ = "translator";
+const char *MainWindow::translated_filter_ = "translated filter";
+
+void MainWindow::addDisplayFilterTranslationActions(QMenu *copy_menu) {
+ if (!copy_menu) {
+ return;
+ }
+
+ char **df_translators = get_dfilter_translator_list();
+
+ if (df_translators == NULL || df_translators[0] == NULL) {
+ return;
+ }
+
+ copy_menu->addSeparator();
+
+ for (size_t idx = 0; df_translators[idx]; idx++) {
+ QString translator = df_translators[idx];
+ QString action_text;
+ if (idx == 0) {
+ action_text = tr("Display filter as %1").arg(translator);
+ } else {
+ action_text = tr(UTF8_HORIZONTAL_ELLIPSIS "as %1").arg(translator);
+ }
+ QAction *xlate_action = copy_menu->addAction(action_text);
+ xlate_action->setProperty(translator_, QVariant::fromValue(translator));
+ xlate_action->setEnabled(false);
+ connect(xlate_action, &QAction::triggered, this, &MainWindow::copyDisplayFilterTranslation);
+ df_translate_actions_ += xlate_action;
+ }
+
+ g_free(df_translators);
+}
+
+void MainWindow::updateDisplayFilterTranslationActions(const QString &df_text)
+{
+ for (QAction *xlate_action : df_translate_actions_) {
+ bool enable = false;
+ QString translated_filter;
+ if (!df_text.isEmpty()) {
+ QString translator = xlate_action->property(translator_).toString();
+ translated_filter = gchar_free_to_qstring((char *)translate_dfilter(qUtf8Printable(translator),
+ qUtf8Printable(df_text)));
+ if (!translated_filter.isEmpty()) {
+ enable = true;
+ }
+ }
+ xlate_action->setEnabled(enable);
+ xlate_action->setProperty(translated_filter_, QVariant::fromValue(translated_filter));
+ }
+}
+
+void MainWindow::copyDisplayFilterTranslation()
+{
+ QAction *xlate_action = qobject_cast<QAction *>(sender());
+ if (!xlate_action) {
+ return;
+ }
+
+ QString translated_filter = xlate_action->property(translated_filter_).toString();
+ mainApp->clipboard()->setText(translated_filter);
+}
+
diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h
index ac5ddcf4..2f78a261 100644
--- a/ui/qt/main_window.h
+++ b/ui/qt/main_window.h
@@ -19,18 +19,23 @@
#include "filter_action.h"
+#include "io_graph_action.h"
#include <QMainWindow>
#include <QSplitter>
+class QMenu;
class QSplitter;
class QStackedWidget;
+
class ByteViewTab;
class DisplayFilterCombo;
class FieldInformation;
+class FunnelAction;
class MainStatusBar;
class PacketDiagram;
class PacketList;
+class ProfileSwitcher;
class ProtoTree;
class WelcomePage;
@@ -45,7 +50,7 @@ public:
bool hasSelection();
bool hasUniqueSelection();
QList<int> selectedRows(bool useFrameNum = false);
- void insertColumn(QString name, QString abbrev, gint pos = -1);
+ void insertColumn(QString name, QString abbrev, int pos = -1);
void gotoFrame(int packet_num);
frame_data* frameDataForRow(int) const;
@@ -53,7 +58,7 @@ public:
MainStatusBar *statusBar();
// Used for managing custom packet menus
- void appendPacketMenu(QAction* funnel_action);
+ void appendPacketMenu(FunnelAction *funnel_action);
QList<QAction*> getPacketMenuActions();
void clearAddedPacketMenus();
bool addPacketMenus(QMenu * ctx_menu, GPtrArray *finfo_array);
@@ -62,6 +67,7 @@ public slots:
void setDisplayFilter(QString filter, FilterAction::Action action, FilterAction::ActionType filterType);
virtual void filterPackets(QString, bool) = 0;
virtual void showPreferencesDialog(QString module_name) = 0;
+ virtual void showIOGraphDialog(io_graph_item_unit_t, QString) = 0;
void layoutPanes();
void applyRecentPaneGeometry();
@@ -96,6 +102,20 @@ protected:
PacketDiagram *packet_diagram_;
DisplayFilterCombo *df_combo_box_;
MainStatusBar *main_status_bar_;
+ ProfileSwitcher *profile_switcher_;
+
+protected slots:
+ void addDisplayFilterTranslationActions(QMenu *copy_menu);
+ void updateDisplayFilterTranslationActions(const QString &df_text);
+
+private:
+ QVector<QAction *> df_translate_actions_;
+
+ static const char *translator_;
+ static const char *translated_filter_;
+
+private slots:
+ void copyDisplayFilterTranslation(void);
signals:
void setCaptureFile(capture_file *cf);
diff --git a/ui/qt/main_window_layout.cpp b/ui/qt/main_window_layout.cpp
index b65b267f..9e2b5a3c 100644
--- a/ui/qt/main_window_layout.cpp
+++ b/ui/qt/main_window_layout.cpp
@@ -88,7 +88,9 @@ void MainWindow::layoutPanes()
packet_list_->setParent(main_stack_);
proto_tree_->setParent(main_stack_);
byte_view_tab_->setParent(main_stack_);
- packet_diagram_->setParent(main_stack_);
+ if (packet_diagram_) {
+ packet_diagram_->setParent(main_stack_);
+ }
empty_pane_.setParent(main_stack_);
extra_split_.setParent(main_stack_);
@@ -163,7 +165,9 @@ void MainWindow::layoutPanes()
packet_list_->setVisible(ms_children.contains(packet_list_) && recent.packet_list_show);
proto_tree_->setVisible(ms_children.contains(proto_tree_) && recent.tree_view_show);
byte_view_tab_->setVisible(ms_children.contains(byte_view_tab_) && recent.byte_view_show);
- packet_diagram_->setVisible(ms_children.contains(packet_diagram_) && recent.packet_diagram_show);
+ if (packet_diagram_) {
+ packet_diagram_->setVisible(ms_children.contains(packet_diagram_) && recent.packet_diagram_show);
+ }
if (frozen) {
packet_list_->thaw(true);
@@ -177,59 +181,65 @@ void MainWindow::layoutPanes()
// - When the profile changes
void MainWindow::applyRecentPaneGeometry()
{
- // XXX This shrinks slightly each time the application is run. For some
- // reason the master_split_ geometry is two pixels shorter when
- // saveWindowGeometry is invoked.
-
- // This is also an awful lot of trouble to go through to reuse the GTK+
- // pane settings. We might want to add gui.geometry_main_master_sizes
- // and gui.geometry_main_extra_sizes and save QSplitter::saveState in
- // each.
-
- // Force a geometry recalculation
- QWidget *cur_w = main_stack_->currentWidget();
- showCapture();
- QRect geom = main_stack_->geometry();
- QList<int> master_sizes = master_split_.sizes();
- QList<int> extra_sizes = extra_split_.sizes();
- main_stack_->setCurrentWidget(cur_w);
-
- int master_last_size = master_split_.orientation() == Qt::Vertical ? geom.height() : geom.width();
- master_last_size -= master_split_.handleWidth() * (master_sizes.length() - 1);
-
- int extra_last_size = extra_split_.orientation() == Qt::Vertical ? geom.height() : geom.width();
- extra_last_size -= extra_split_.handleWidth();
-
- if (recent.gui_geometry_main_upper_pane > 0) {
- master_sizes[0] = recent.gui_geometry_main_upper_pane;
- master_last_size -= recent.gui_geometry_main_upper_pane;
- } else {
- master_sizes[0] = master_last_size / master_sizes.length();
- master_last_size -= master_last_size / master_sizes.length();
- }
-
- if (recent.gui_geometry_main_lower_pane > 0) {
- if (master_sizes.length() > 2) {
- master_sizes[1] = recent.gui_geometry_main_lower_pane;
- master_last_size -= recent.gui_geometry_main_lower_pane;
- } else if (extra_sizes.length() > 0) {
- extra_sizes[0] = recent.gui_geometry_main_lower_pane;
- extra_last_size -= recent.gui_geometry_main_lower_pane;
- extra_sizes.last() = extra_last_size;
+ if (recent.gui_geometry_main_master_split == nullptr ||
+ recent.gui_geometry_main_extra_split == nullptr ||
+ !master_split_.restoreState(QByteArray::fromHex(recent.gui_geometry_main_master_split)) ||
+ !extra_split_.restoreState(QByteArray::fromHex(recent.gui_geometry_main_extra_split))) {
+ // Restoring the splitter states via the savedState didn't work,
+ // so let's fall back to the older method.
+ //
+ // XXX This shrinks slightly each time the application is run. For some
+ // reason the master_split_ geometry is two pixels shorter when
+ // saveWindowGeometry is invoked.
+
+ // This is also an awful lot of trouble to go through to reuse the GTK+
+ // pane settings.
+
+ // Force a geometry recalculation
+ QWidget *cur_w = main_stack_->currentWidget();
+ showCapture();
+ QRect geom = main_stack_->geometry();
+ QList<int> master_sizes = master_split_.sizes();
+ QList<int> extra_sizes = extra_split_.sizes();
+ main_stack_->setCurrentWidget(cur_w);
+
+ int master_last_size = master_split_.orientation() == Qt::Vertical ? geom.height() : geom.width();
+ master_last_size -= master_split_.handleWidth() * (master_sizes.length() - 1);
+
+ int extra_last_size = extra_split_.orientation() == Qt::Vertical ? geom.height() : geom.width();
+ extra_last_size -= extra_split_.handleWidth();
+
+ if (recent.gui_geometry_main_upper_pane > 0) {
+ master_sizes[0] = recent.gui_geometry_main_upper_pane;
+ master_last_size -= recent.gui_geometry_main_upper_pane;
+ } else {
+ master_sizes[0] = master_last_size / master_sizes.length();
+ master_last_size -= master_last_size / master_sizes.length();
}
- } else {
- if (master_sizes.length() > 2) {
- master_sizes[1] = master_last_size / 2;
- master_last_size -= master_last_size / 2;
- } else if (extra_sizes.length() > 0) {
- extra_sizes[0] = extra_last_size / 2;
- extra_last_size -= extra_last_size / 2;
- extra_sizes.last() = extra_last_size;
+
+ if (recent.gui_geometry_main_lower_pane > 0) {
+ if (master_sizes.length() > 2) {
+ master_sizes[1] = recent.gui_geometry_main_lower_pane;
+ master_last_size -= recent.gui_geometry_main_lower_pane;
+ } else if (extra_sizes.length() > 0) {
+ extra_sizes[0] = recent.gui_geometry_main_lower_pane;
+ extra_last_size -= recent.gui_geometry_main_lower_pane;
+ extra_sizes.last() = extra_last_size;
+ }
+ } else {
+ if (master_sizes.length() > 2) {
+ master_sizes[1] = master_last_size / 2;
+ master_last_size -= master_last_size / 2;
+ } else if (extra_sizes.length() > 0) {
+ extra_sizes[0] = extra_last_size / 2;
+ extra_last_size -= extra_last_size / 2;
+ extra_sizes.last() = extra_last_size;
+ }
}
- }
- master_sizes.last() = master_last_size;
+ master_sizes.last() = master_last_size;
- master_split_.setSizes(master_sizes);
- extra_split_.setSizes(extra_sizes);
+ master_split_.setSizes(master_sizes);
+ extra_split_.setSizes(extra_sizes);
+ }
}
diff --git a/ui/qt/main_window_preferences_frame.cpp b/ui/qt/main_window_preferences_frame.cpp
index 9659c928..447540f7 100644
--- a/ui/qt/main_window_preferences_frame.cpp
+++ b/ui/qt/main_window_preferences_frame.cpp
@@ -48,6 +48,7 @@ MainWindowPreferencesFrame::MainWindowPreferencesFrame(QWidget *parent) :
).arg(ui->geometryCheckBox->style()->subElementRect(QStyle::SE_CheckBoxContents, &style_opt).left());
ui->foStyleLastOpenedRadioButton->setStyleSheet(indent_ss);
ui->foStyleSpecifiedRadioButton->setStyleSheet(indent_ss);
+ ui->foStyleCWDRadioButton->setStyleSheet(indent_ss);
ui->maxFilterLineEdit->setStyleSheet(indent_ss);
ui->maxRecentLineEdit->setStyleSheet(indent_ss);
@@ -66,7 +67,7 @@ MainWindowPreferencesFrame::MainWindowPreferencesFrame(QWidget *parent) :
ui->languageComboBox->setItemIcon(0, language_icon);
QString globalLanguagesPath(QString(get_datafile_dir()) + "/languages/");
- QString userLanguagesPath(gchar_free_to_qstring(get_persconffile_path("languages/", FALSE)));
+ QString userLanguagesPath(gchar_free_to_qstring(get_persconffile_path("languages/", false)));
QStringList filenames = QDir(":/i18n/").entryList(QStringList("wireshark_*.qm"));
filenames += QDir(globalLanguagesPath).entryList(QStringList("wireshark_*.qm"));
@@ -114,10 +115,18 @@ void MainWindowPreferencesFrame::updateWidgets()
ui->geometryCheckBox->setChecked(false);
}
- if (prefs_get_enum_value(pref_fileopen_style_, pref_stashed) == FO_STYLE_LAST_OPENED) {
+ switch (prefs_get_enum_value(pref_fileopen_style_, pref_stashed)) {
+
+ case FO_STYLE_LAST_OPENED:
ui->foStyleLastOpenedRadioButton->setChecked(true);
- } else {
+ break;
+ case FO_STYLE_CWD:
+ ui->foStyleCWDRadioButton->setChecked(true);
+ break;
+ case FO_STYLE_SPECIFIED:
+ default:
ui->foStyleSpecifiedRadioButton->setChecked(true);
+ break;
}
ui->foStyleSpecifiedLineEdit->setText(prefs_get_string_value(pref_fileopen_dir_, pref_stashed));
@@ -148,6 +157,13 @@ void MainWindowPreferencesFrame::on_geometryCheckBox_toggled(bool checked)
prefs_set_bool_value(pref_geometry_save_maximized_, checked, pref_stashed);
}
+void MainWindowPreferencesFrame::on_foStyleCWDRadioButton_toggled(bool checked)
+{
+ if (checked) {
+ prefs_set_enum_value(pref_fileopen_style_, FO_STYLE_CWD, pref_stashed);
+ }
+}
+
void MainWindowPreferencesFrame::on_foStyleLastOpenedRadioButton_toggled(bool checked)
{
if (checked) {
diff --git a/ui/qt/main_window_preferences_frame.h b/ui/qt/main_window_preferences_frame.h
index 52d01049..2ba1064d 100644
--- a/ui/qt/main_window_preferences_frame.h
+++ b/ui/qt/main_window_preferences_frame.h
@@ -48,6 +48,7 @@ private:
private slots:
void on_geometryCheckBox_toggled(bool checked);
+ void on_foStyleCWDRadioButton_toggled(bool checked);
void on_foStyleLastOpenedRadioButton_toggled(bool checked);
void on_foStyleSpecifiedRadioButton_toggled(bool checked);
void on_foStyleSpecifiedLineEdit_textEdited(const QString &new_dir);
diff --git a/ui/qt/main_window_preferences_frame.ui b/ui/qt/main_window_preferences_frame.ui
index 745e78b3..6ed803c3 100644
--- a/ui/qt/main_window_preferences_frame.ui
+++ b/ui/qt/main_window_preferences_frame.ui
@@ -84,6 +84,16 @@
</attribute>
</widget>
</item>
+ <item row="2" column="0" colspan="3">
+ <widget class="QRadioButton" name="foStyleCWDRadioButton">
+ <property name="text">
+ <string>The current working directory</string>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">openInButtonGroup</string>
+ </attribute>
+ </widget>
+ </item>
</layout>
</item>
<item>
diff --git a/ui/qt/manage_interfaces_dialog.cpp b/ui/qt/manage_interfaces_dialog.cpp
index a8529e26..ca7a1d9a 100644
--- a/ui/qt/manage_interfaces_dialog.cpp
+++ b/ui/qt/manage_interfaces_dialog.cpp
@@ -23,6 +23,10 @@
#include "ui/qt/remote_settings_dialog.h"
#include "capture/capture-pcap-util.h"
#include "ui/recent.h"
+#include "wsutil/filesystem.h"
+#include <QJsonDocument>
+#include <QJsonArray>
+#include <QJsonObject>
#endif
#include "ui/iface_lists.h"
#include "ui/preference_utils.h"
@@ -72,53 +76,89 @@ enum {
};
#ifdef HAVE_PCAP_REMOTE
-static void populateExistingRemotes(gpointer key, gpointer value, gpointer user_data)
+#define REMOTE_HOSTS_FILE "remote_hosts.json"
+
+void ManageInterfacesDialog::addRemote(const QVariantMap&& remoteHostMap)
{
- ManageInterfacesDialog *dialog = (ManageInterfacesDialog*)user_data;
- const gchar *host = (const gchar *)key;
- struct remote_host *remote_host = (struct remote_host *)value;
remote_options global_remote_opts;
int err;
- gchar *err_str;
+ char* err_str;
global_remote_opts.src_type = CAPTURE_IFREMOTE;
- global_remote_opts.remote_host_opts.remote_host = g_strdup(host);
- global_remote_opts.remote_host_opts.remote_port = g_strdup(remote_host->remote_port);
- global_remote_opts.remote_host_opts.auth_type = remote_host->auth_type;
- global_remote_opts.remote_host_opts.auth_username = g_strdup(remote_host->auth_username);
- global_remote_opts.remote_host_opts.auth_password = g_strdup(remote_host->auth_password);
- global_remote_opts.remote_host_opts.datatx_udp = FALSE;
- global_remote_opts.remote_host_opts.nocap_rpcap = TRUE;
- global_remote_opts.remote_host_opts.nocap_local = FALSE;
+ global_remote_opts.remote_host_opts.remote_host = qstring_strdup(remoteHostMap["host"].toString());
+ global_remote_opts.remote_host_opts.remote_port = qstring_strdup(remoteHostMap["port"].toString());
+ global_remote_opts.remote_host_opts.auth_type = static_cast<capture_auth>(remoteHostMap["auth"].toInt());
+ global_remote_opts.remote_host_opts.auth_username = qstring_strdup(remoteHostMap["username"].toString());
+ global_remote_opts.remote_host_opts.auth_password = qstring_strdup(remoteHostMap["password"].toString());
+ global_remote_opts.remote_host_opts.datatx_udp = false;
+ global_remote_opts.remote_host_opts.nocap_rpcap = true;
+ global_remote_opts.remote_host_opts.nocap_local = false;
#ifdef HAVE_PCAP_SETSAMPLING
global_remote_opts.sampling_method = CAPTURE_SAMP_NONE;
- global_remote_opts.sampling_param = 0;
+ global_remote_opts.sampling_param = 0;
#endif
- GList *rlist = get_remote_interface_list(global_remote_opts.remote_host_opts.remote_host,
- global_remote_opts.remote_host_opts.remote_port,
- global_remote_opts.remote_host_opts.auth_type,
- global_remote_opts.remote_host_opts.auth_username,
- global_remote_opts.remote_host_opts.auth_password,
- &err, &err_str);
+
+ // This doesn't handle CAPTURE_AUTH_PWD because we don't store the password
+ // XXX: Don't these strings get leaked? I think that they're dup'ed again
+ // later. Same for in RemoteCaptureDialog::apply_remote()
+
+ GList* rlist = get_remote_interface_list(global_remote_opts.remote_host_opts.remote_host,
+ global_remote_opts.remote_host_opts.remote_port,
+ global_remote_opts.remote_host_opts.auth_type,
+ global_remote_opts.remote_host_opts.auth_username,
+ global_remote_opts.remote_host_opts.auth_password,
+ &err, &err_str);
+
if (rlist == NULL) {
switch (err) {
case 0:
- QMessageBox::warning(dialog, QObject::tr("Error"), QObject::tr("No remote interfaces found."));
+ QMessageBox::warning(this, QObject::tr("Error"), QObject::tr("No remote interfaces found."));
break;
case CANT_GET_INTERFACE_LIST:
- QMessageBox::critical(dialog, QObject::tr("Error"), err_str);
+ QMessageBox::critical(this, QObject::tr("Error"), err_str);
break;
case DONT_HAVE_PCAP:
- QMessageBox::critical(dialog, QObject::tr("Error"), QObject::tr("PCAP not found"));
+ QMessageBox::critical(this, QObject::tr("Error"), QObject::tr("PCAP not found"));
break;
default:
- QMessageBox::critical(dialog, QObject::tr("Error"), QObject::tr("Unknown error"));
+ QMessageBox::critical(this, QObject::tr("Error"), QObject::tr("Unknown error"));
break;
}
return;
}
+ // XXX: If the connection fails we won't add it, so it won't get saved to
+ // load automatically next time (but will perhaps still be in recent.)
+ // That's mostly a feature not a bug, but we might want support for
+ // currently disabled remote hosts.
+
+ emit remoteAdded(rlist, &global_remote_opts);
+}
+
+void ManageInterfacesDialog::populateExistingRemotes()
+{
+ const char* cfile = REMOTE_HOSTS_FILE;
+
+ /* Try personal config file first */
+ QString fileName = gchar_free_to_qstring(get_persconffile_path(cfile, true));
+
+ if (fileName.isEmpty() || !QFileInfo::exists(fileName)) {
+ return;
+ }
+
+ QFile file(fileName);
+ if (!file.open(QIODevice::ReadOnly)) {
+ return;
+ }
+
+ QJsonDocument document = QJsonDocument::fromJson(file.readAll());
+ if (!document.isArray()) {
+ return;
+ }
+
+ foreach(QJsonValue value, document.array()) {
+ addRemote(value.toObject().toVariantMap());
+ }
- emit dialog->remoteAdded(rlist, &global_remote_opts);
}
#endif /* HAVE_PCAP_REMOTE */
@@ -157,10 +197,13 @@ ManageInterfacesDialog::ManageInterfacesDialog(QWidget *parent) :
proxyModel->setRemoteDisplay(false);
#endif
proxyModel->setFilterByType(false);
+ proxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
ui->localView->setModel(proxyModel);
ui->localView->resizeColumnToContents(proxyModel->mapSourceToColumn(IFTREE_COL_HIDDEN));
ui->localView->resizeColumnToContents(proxyModel->mapSourceToColumn(IFTREE_COL_NAME));
+ ui->localView->header()->setSortIndicator(-1, Qt::AscendingOrder);
+ ui->localView->setSortingEnabled(true);
pipeProxyModel = new InterfaceSortFilterModel(this);
columns.clear();
@@ -176,7 +219,7 @@ ManageInterfacesDialog::ManageInterfacesDialog(QWidget *parent) :
ui->pipeView->setModel(pipeProxyModel);
ui->delPipe->setEnabled(pipeProxyModel->rowCount() > 0);
- ui->pipeView->setItemDelegateForColumn(pipeProxyModel->mapSourceToColumn(IFTREE_COL_PIPE_PATH), new PathSelectionDelegate());
+ ui->pipeView->setItemDelegateForColumn(pipeProxyModel->mapSourceToColumn(IFTREE_COL_PIPE_PATH), new PathSelectionDelegate(this));
connect(ui->pipeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, [=](const QItemSelection &sel, const QItemSelection &) {
ui->delPipe->setEnabled(sel.count() > 0);
});
@@ -200,7 +243,7 @@ ManageInterfacesDialog::ManageInterfacesDialog(QWidget *parent) :
connect(this, SIGNAL(remoteAdded(GList*, remote_options*)), this, SLOT(addRemoteInterfaces(GList*, remote_options*)));
connect(this, SIGNAL(remoteSettingsChanged(interface_t *)), this, SLOT(setRemoteSettings(interface_t *)));
connect(ui->remoteList, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(remoteSelectionChanged(QTreeWidgetItem*, int)));
- recent_remote_host_list_foreach(populateExistingRemotes, this);
+ populateExistingRemotes();
#endif
ui->tabWidget->setCurrentIndex(tab_local_);
@@ -272,8 +315,8 @@ void ManageInterfacesDialog::on_addPipe_clicked()
memset(&device, 0, sizeof(device));
device.name = qstring_strdup(tr("New Pipe"));
device.display_name = g_strdup(device.name);
- device.hidden = FALSE;
- device.selected = TRUE;
+ device.hidden = false;
+ device.selected = true;
device.pmode = global_capture_opts.default_options.promisc_mode;
device.has_snaplen = global_capture_opts.default_options.has_snaplen;
device.snaplen = global_capture_opts.default_options.snaplen;
@@ -319,20 +362,25 @@ void ManageInterfacesDialog::updateRemoteInterfaceList(GList* rlist, remote_opti
GList *if_entry, *lt_entry;
if_info_t *if_info;
char *if_string = NULL;
- gchar *descr, *auth_str;
+ char *descr, *auth_str;
if_capabilities_t *caps;
- gint linktype_count;
+ int linktype_count;
bool monitor_mode, found = false;
GSList *curr_addr;
int ips = 0;
- guint i;
+ unsigned i;
if_addr_t *addr;
data_link_info_t *data_link_info;
GString *ip_str;
link_row *linkr = NULL;
interface_t device;
- guint num_interfaces;
+ unsigned num_interfaces;
+ // Add any (remote) interface in rlist to the global list of all
+ // interfaces.
+ // Most of this is copied from scan_local_interfaces_filtered, but
+ // some of it doesn't make sense for remote interfaces (yet?) - we
+ // can't, for example, control monitor mode.
num_interfaces = global_capture_opts.all_ifaces->len;
for (if_entry = g_list_first(rlist); if_entry != NULL; if_entry = gxx_list_next(if_entry)) {
auth_str = NULL;
@@ -345,12 +393,12 @@ void ManageInterfacesDialog::updateRemoteInterfaceList(GList* rlist, remote_opti
if (device.hidden)
continue;
if (strcmp(device.name, if_info->name) == 0) {
- found = TRUE;
+ found = true;
break;
}
}
if (found) {
- found = FALSE;
+ found = false;
continue;
}
ip_str = g_string_new("");
@@ -430,11 +478,15 @@ void ManageInterfacesDialog::updateRemoteInterfaceList(GList* rlist, remote_opti
linktype_count = 0;
device.links = NULL;
if (caps != NULL) {
+ GList *lt_list = caps->data_link_types;
#ifdef HAVE_PCAP_CREATE
- device.monitor_mode_enabled = monitor_mode;
+ device.monitor_mode_enabled = monitor_mode && caps->can_set_rfmon;
device.monitor_mode_supported = caps->can_set_rfmon;
+ if (device.monitor_mode_enabled) {
+ lt_list = caps->data_link_types_rfmon;
+ }
#endif
- for (lt_entry = caps->data_link_types; lt_entry != NULL; lt_entry = gxx_list_next(lt_entry)) {
+ for (lt_entry = lt_list; lt_entry != NULL; lt_entry = gxx_list_next(lt_entry)) {
data_link_info = gxx_list_data(data_link_info_t *, lt_entry);
linkr = new link_row;
/*
@@ -459,8 +511,8 @@ void ManageInterfacesDialog::updateRemoteInterfaceList(GList* rlist, remote_opti
} /* for link_types */
} else {
#if defined(HAVE_PCAP_CREATE)
- device.monitor_mode_enabled = FALSE;
- device.monitor_mode_supported = FALSE;
+ device.monitor_mode_enabled = false;
+ device.monitor_mode_supported = false;
#endif
device.active_dlt = -1;
}
@@ -468,7 +520,7 @@ void ManageInterfacesDialog::updateRemoteInterfaceList(GList* rlist, remote_opti
device.no_addresses = ips;
device.remote_opts.src_type= roptions->src_type;
if (device.remote_opts.src_type == CAPTURE_IFREMOTE) {
- device.local = FALSE;
+ device.local = false;
}
device.remote_opts.remote_host_opts.remote_host = g_strdup(roptions->remote_host_opts.remote_host);
device.remote_opts.remote_host_opts.remote_port = g_strdup(roptions->remote_host_opts.remote_port);
@@ -482,7 +534,7 @@ void ManageInterfacesDialog::updateRemoteInterfaceList(GList* rlist, remote_opti
device.remote_opts.sampling_method = roptions->sampling_method;
device.remote_opts.sampling_param = roptions->sampling_param;
#endif
- device.selected = TRUE;
+ device.selected = true;
global_capture_opts.num_selected++;
g_array_append_val(global_capture_opts.all_ifaces, device);
g_string_free(ip_str, TRUE);
@@ -500,9 +552,17 @@ void ManageInterfacesDialog::addRemoteInterfaces(GList* rlist, remote_options *r
void ManageInterfacesDialog::remoteAccepted()
{
QTreeWidgetItemIterator it(ui->remoteList);
+ QJsonArray hostArray;
while (*it) {
- for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+ if ((*it)->parent() == nullptr) {
+ QVariant v = (*it)->data(0, Qt::UserRole);
+ if (v.canConvert<QJsonObject>()) {
+ hostArray.append(v.toJsonValue());
+ }
+ }
+
+ for (unsigned i = 0; i < global_capture_opts.all_ifaces->len; i++) {
interface_t *device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
if ((*it)->text(col_r_host_dev_).compare(device->name))
continue;
@@ -510,6 +570,21 @@ void ManageInterfacesDialog::remoteAccepted()
}
++it;
}
+
+ const char* cfile = REMOTE_HOSTS_FILE;
+ /* Try personal config file first */
+ QString fileName = gchar_free_to_qstring(get_persconffile_path(cfile, true));
+
+ if (fileName.isEmpty()) {
+ return;
+ }
+
+ QFile file(fileName);
+ if (!file.open(QIODevice::WriteOnly)) {
+ return;
+ }
+
+ file.write(QJsonDocument(hostArray).toJson(QJsonDocument::Compact));
}
void ManageInterfacesDialog::on_remoteList_currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)
@@ -523,7 +598,7 @@ void ManageInterfacesDialog::on_remoteList_itemClicked(QTreeWidgetItem *item, in
return;
}
- for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+ for (unsigned i = 0; i < global_capture_opts.all_ifaces->len; i++) {
interface_t *device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
if (!device->local) {
if (item->text(col_r_host_dev_).compare(device->name))
@@ -540,7 +615,7 @@ void ManageInterfacesDialog::on_delRemote_clicked()
return;
}
- for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+ for (unsigned i = 0; i < global_capture_opts.all_ifaces->len; i++) {
interface_t *device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
if (item->text(col_r_host_dev_).compare(device->remote_opts.remote_host_opts.remote_host))
continue;
@@ -559,7 +634,7 @@ void ManageInterfacesDialog::on_addRemote_clicked()
void ManageInterfacesDialog::showRemoteInterfaces()
{
- guint i;
+ unsigned i;
interface_t *device;
QTreeWidgetItem * item = nullptr;
@@ -580,6 +655,17 @@ void ManageInterfacesDialog::showRemoteInterfaces()
if (items.count() == 0) {
item = new QTreeWidgetItem(ui->remoteList);
item->setText(col_r_host_dev_, parentName);
+ QJsonObject remote_host{
+ {"host", parentName},
+ {"port", device->remote_opts.remote_host_opts.remote_port},
+ {"auth_type", device->remote_opts.remote_host_opts.auth_type},
+ {"username", device->remote_opts.remote_host_opts.auth_username},
+ // {"password", device->remote_opts.remote_host_opts.auth_password},
+ // We should find some way to store the password in a
+ // credential manager (cf. #17949 for extcap) and
+ // reference it
+ };
+ item->setData(0, Qt::UserRole, remote_host);
item->setExpanded(true);
}
else {
@@ -599,7 +685,7 @@ void ManageInterfacesDialog::showRemoteInterfaces()
void ManageInterfacesDialog::on_remoteSettings_clicked()
{
- guint i = 0;
+ unsigned i = 0;
interface_t *device;
QTreeWidgetItem* item = ui->remoteList->currentItem();
if (!item) {
@@ -622,7 +708,7 @@ void ManageInterfacesDialog::on_remoteSettings_clicked()
void ManageInterfacesDialog::setRemoteSettings(interface_t *iface)
{
- for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+ for (unsigned i = 0; i < global_capture_opts.all_ifaces->len; i++) {
interface_t *device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
if (!device->local) {
if (strcmp(iface->name, device->name)) {
diff --git a/ui/qt/manage_interfaces_dialog.h b/ui/qt/manage_interfaces_dialog.h
index 79e9d0d9..de8db2d4 100644
--- a/ui/qt/manage_interfaces_dialog.h
+++ b/ui/qt/manage_interfaces_dialog.h
@@ -12,7 +12,6 @@
#include <config.h>
-#include <glib.h>
#include "capture_opts.h"
#include <ui/qt/models/interface_tree_cache_model.h>
@@ -48,6 +47,10 @@ private:
InterfaceSortFilterModel * pipeProxyModel;
void showRemoteInterfaces();
+#ifdef HAVE_PCAP_REMOTE
+ void addRemote(const QVariantMap&&);
+ void populateExistingRemotes();
+#endif
signals:
void ifsChanged();
diff --git a/ui/qt/manager/wireshark_preference.cpp b/ui/qt/manager/wireshark_preference.cpp
index cca87c7b..91f8bd20 100644
--- a/ui/qt/manager/wireshark_preference.cpp
+++ b/ui/qt/manager/wireshark_preference.cpp
@@ -80,6 +80,7 @@ public:
};
REGISTER_PREFERENCE_TYPE(PREF_STRING, StringPreference)
REGISTER_PREFERENCE_TYPE(PREF_CUSTOM, StringPreference)
+REGISTER_PREFERENCE_TYPE(PREF_DISSECTOR, StringPreference)
class PasswordPreference : public StringPreference
{
@@ -101,7 +102,6 @@ public:
UIntPreference(QObject * parent = Q_NULLPTR) : StringPreference(parent) {}
};
REGISTER_PREFERENCE_TYPE(PREF_UINT, UIntPreference)
-REGISTER_PREFERENCE_TYPE(PREF_DECODE_AS_UINT, UIntPreference)
class EnumPreference : public WiresharkPreference
{
diff --git a/ui/qt/manuf_dialog.cpp b/ui/qt/manuf_dialog.cpp
index 0c383af3..d7ed9192 100644
--- a/ui/qt/manuf_dialog.cpp
+++ b/ui/qt/manuf_dialog.cpp
@@ -102,9 +102,9 @@ static QByteArray convertMacAddressToByteArray(const QString &bytesString)
{
GByteArray *bytes = g_byte_array_new();
- if (!hex_str_to_bytes(qUtf8Printable(bytesString), bytes, FALSE)
+ if (!hex_str_to_bytes(qUtf8Printable(bytesString), bytes, false)
|| bytes->len == 0 || bytes->len > 6) {
- g_byte_array_free(bytes, TRUE);
+ g_byte_array_free(bytes, true);
return QByteArray();
}
diff --git a/ui/qt/models/astringlist_list_model.cpp b/ui/qt/models/astringlist_list_model.cpp
index a0b5fc38..c3b3ec05 100644
--- a/ui/qt/models/astringlist_list_model.cpp
+++ b/ui/qt/models/astringlist_list_model.cpp
@@ -166,7 +166,6 @@ bool AStringListListSortFilterProxyModel::filterAcceptsRow(int sourceRow, const
break;
case FilterNone:
return true;
- break;
default:
compareFunc = AContainsB;
break;
diff --git a/ui/qt/models/astringlist_list_model.h b/ui/qt/models/astringlist_list_model.h
index 70acc97b..f1e396c8 100644
--- a/ui/qt/models/astringlist_list_model.h
+++ b/ui/qt/models/astringlist_list_model.h
@@ -21,6 +21,7 @@
class AStringListListModel : public QAbstractTableModel
{
+ Q_OBJECT
public:
explicit AStringListListModel(QObject * parent = Q_NULLPTR);
virtual ~AStringListListModel();
diff --git a/ui/qt/models/atap_data_model.cpp b/ui/qt/models/atap_data_model.cpp
index b7ff508d..c3a2f840 100644
--- a/ui/qt/models/atap_data_model.cpp
+++ b/ui/qt/models/atap_data_model.cpp
@@ -7,8 +7,6 @@
* SPDX-License-Identifier: GPL-2.0-or-later
*/
-#include <glib.h>
-
#include <epan/tap.h>
#include <epan/conversation.h>
#include <epan/conversation_table.h>
@@ -90,10 +88,12 @@ bool ATapDataModel::hasGeoIPData()
while (!coordsFound && row < count)
{
QModelIndex idx = index(row, 0);
- if (_type == ATapDataModel::DATAMODEL_ENDPOINT)
- coordsFound = qobject_cast<EndpointDataModel *>(this)->data(idx, ATapDataModel::GEODATA_AVAILABLE).toBool();
- else if (_type == ATapDataModel::DATAMODEL_CONVERSATION)
- coordsFound = qobject_cast<ConversationDataModel *>(this)->data(idx, ATapDataModel::GEODATA_AVAILABLE).toBool();
+ if (!data(idx, ATapDataModel::ROW_IS_FILTERED).toBool()) {
+ if (_type == ATapDataModel::DATAMODEL_ENDPOINT)
+ coordsFound = qobject_cast<EndpointDataModel *>(this)->data(idx, ATapDataModel::GEODATA_AVAILABLE).toBool();
+ else if (_type == ATapDataModel::DATAMODEL_CONVERSATION)
+ coordsFound = qobject_cast<ConversationDataModel *>(this)->data(idx, ATapDataModel::GEODATA_AVAILABLE).toBool();
+ }
row++;
}
@@ -585,6 +585,9 @@ void ConversationDataModel::doDataUpdate()
int ConversationDataModel::columnCount(const QModelIndex &) const
{
+ if(tap()=="tcp")
+ return CONV_TCP_EXT_NUM_COLUMNS;
+
return CONV_NUM_COLUMNS;
}
@@ -630,6 +633,15 @@ QVariant ConversationDataModel::headerData(int section, Qt::Orientation orientat
case CONV_COLUMN_BPS_BA:
return tr("Bits/s B " UTF8_RIGHTWARDS_ARROW " A"); break;
}
+ /* Extended conversations columns, e.g. TCP */
+ if(tap()=="tcp") {
+ switch (section) {
+ case CONV_TCP_EXT_COLUMN_A:
+ return tr("Flows"); break;
+ default :
+ ws_assert_not_reached(); break;
+ }
+ }
} else if (role == Qt::TextAlignmentRole) {
if (section == CONV_COLUMN_SRC_ADDR || section == CONV_COLUMN_DST_ADDR)
return Qt::AlignLeft;
@@ -701,7 +713,10 @@ QVariant ConversationDataModel::data(const QModelIndex &idx, int role) const
return role == Qt::DisplayRole ? formatString((qlonglong)conv_item->tx_bytes + conv_item->rx_bytes) :
QVariant((qlonglong)conv_item->tx_bytes + conv_item->rx_bytes);
case CONV_COLUMN_CONV_ID:
- return (int) conv_item->conv_id;
+ if(conv_item->conv_id!=CONV_ID_UNSET) {
+ return (int) conv_item->conv_id;
+ }
+ break;
case CONV_COLUMN_PACKETS_TOTAL:
{
qlonglong packets = 0;
@@ -722,7 +737,7 @@ QVariant ConversationDataModel::data(const QModelIndex &idx, int role) const
/* Qt guarantees that this roundtrip conversion compares equally,
* so filtering with equality will work as expected.
* XXX: Perhaps the UNFORMATTED_DISPLAYDATA role shoud be split
- * into one used for raw data export and comparisions with each
+ * into one used for raw data export and comparisons with each
* other, and another for comparing with filters?
*/
return role == Qt::DisplayRole ? rounded + "%" : QVariant(rounded.toDouble());
@@ -778,6 +793,18 @@ QVariant ConversationDataModel::data(const QModelIndex &idx, int role) const
case CONV_COLUMN_BPS_BA:
return bpsCalculated ? (role == Qt::DisplayRole ? gchar_free_to_qstring(format_size((int64_t)bps_ba, FORMAT_SIZE_UNIT_BITS_S, FORMAT_SIZE_PREFIX_SI)) : QVariant((qlonglong)bps_ba)): QVariant();
}
+ /* Extended conversations columns, e.g. TCP */
+ if(tap()=="tcp") {
+ switch(idx.column()) {
+ case CONV_TCP_EXT_COLUMN_A:
+ {
+ qlonglong flows = (qlonglong)conv_item->ext_tcp.flows;
+ return role == Qt::DisplayRole ? QString("%L1").arg(flows) : (QVariant)flows; break;
+ }
+ default :
+ ws_assert_not_reached(); break;
+ }
+ }
} else if (role == Qt::ToolTipRole) {
if (idx.column() == CONV_COLUMN_START || idx.column() == CONV_COLUMN_DURATION)
return QObject::tr("Bars show the relative timeline for each conversation.");
@@ -844,7 +871,11 @@ bool ConversationDataModel::showConversationId(int row) const
return false;
conv_item_t *conv_item = (conv_item_t *)&g_array_index(storage_, conv_item_t, row);
- if (conv_item && (conv_item->ctype == CONVERSATION_TCP || conv_item->ctype == CONVERSATION_UDP))
+ if (conv_item && (conv_item->ctype == CONVERSATION_TCP ||
+ conv_item->ctype == CONVERSATION_UDP ||
+ conv_item->ctype == CONVERSATION_IP ||
+ conv_item->ctype == CONVERSATION_IPV6||
+ conv_item->ctype == CONVERSATION_ETH))
return true;
return false;
}
diff --git a/ui/qt/models/atap_data_model.h b/ui/qt/models/atap_data_model.h
index 38bdbd2f..6ba0b325 100644
--- a/ui/qt/models/atap_data_model.h
+++ b/ui/qt/models/atap_data_model.h
@@ -12,8 +12,6 @@
#include "config.h"
-#include "glib.h"
-
#include <epan/tap.h>
#include <epan/conversation.h>
#include <epan/conversation_table.h>
@@ -306,6 +304,12 @@ public:
CONV_INDEX_COLUMN = CONV_NUM_COLUMNS
} conversation_column_type_e;
+ typedef enum {
+ CONV_TCP_EXT_COLUMN_A = CONV_INDEX_COLUMN,
+ CONV_TCP_EXT_NUM_COLUMNS,
+ CONV_TCP_EXT_INDEX_COLUMN = CONV_TCP_EXT_NUM_COLUMNS
+ } conversation_tcp_ext_column_type_e;
+
explicit ConversationDataModel(int protoId, QString filter, QObject *parent = nullptr);
int columnCount(const QModelIndex &parent = QModelIndex()) const;
diff --git a/ui/qt/models/coloring_rules_delegate.cpp b/ui/qt/models/coloring_rules_delegate.cpp
index b86ffa97..58524be1 100644
--- a/ui/qt/models/coloring_rules_delegate.cpp
+++ b/ui/qt/models/coloring_rules_delegate.cpp
@@ -32,7 +32,7 @@ QWidget* ColoringRulesDelegate::createEditor(QWidget *parent, const QStyleOption
return new DisplayFilterEdit(parent);
default:
- Q_ASSERT(FALSE);
+ Q_ASSERT(false);
return 0;
}
diff --git a/ui/qt/models/coloring_rules_model.cpp b/ui/qt/models/coloring_rules_model.cpp
index dced9c37..29bb7dcf 100644
--- a/ui/qt/models/coloring_rules_model.cpp
+++ b/ui/qt/models/coloring_rules_model.cpp
@@ -72,7 +72,7 @@ ColoringRuleItem& ColoringRuleItem::operator=(ColoringRuleItem& rhs)
// Callback for color_filters_clone.
void
-color_filter_add_cb(color_filter_t *colorf, gpointer user_data)
+color_filter_add_cb(color_filter_t *colorf, void *user_data)
{
ColoringRulesModel *model = (ColoringRulesModel*)user_data;
@@ -149,7 +149,7 @@ void ColoringRulesModel::addColor(bool disabled, QString filter, QColor foregrou
bool ColoringRulesModel::importColors(QString filename, QString& err)
{
bool success = true;
- gchar* err_msg = NULL;
+ char* err_msg = NULL;
if (!color_filters_import(filename.toUtf8().constData(), this, &err_msg, color_filter_add_cb)) {
err = gchar_free_to_qstring(err_msg);
success = false;
@@ -162,8 +162,8 @@ bool ColoringRulesModel::exportColors(QString filename, QString& err)
{
GSList *cfl = createColorFilterList();
bool success = true;
- gchar* err_msg = NULL;
- if (!color_filters_export(filename.toUtf8().constData(), cfl, FALSE, &err_msg)) {
+ char* err_msg = NULL;
+ if (!color_filters_export(filename.toUtf8().constData(), cfl, false, &err_msg)) {
err = gchar_free_to_qstring(err_msg);
success = false;
}
@@ -176,7 +176,7 @@ bool ColoringRulesModel::writeColors(QString& err)
{
GSList *cfl = createColorFilterList();
bool success = true;
- gchar* err_msg = NULL;
+ char* err_msg = NULL;
if (!color_filters_apply(conversation_colors_, cfl, &err_msg)) {
err = gchar_free_to_qstring(err_msg);
success = false;
diff --git a/ui/qt/models/coloring_rules_model.h b/ui/qt/models/coloring_rules_model.h
index f51a1a30..0df532ef 100644
--- a/ui/qt/models/coloring_rules_model.h
+++ b/ui/qt/models/coloring_rules_model.h
@@ -14,7 +14,6 @@
#include <config.h>
-#include <glib.h>
#include <epan/color_filters.h>
#include <ui/qt/models/tree_model_helpers.h>
diff --git a/ui/qt/models/column_list_model.cpp b/ui/qt/models/column_list_model.cpp
index a0e5c8ba..7613e487 100644
--- a/ui/qt/models/column_list_model.cpp
+++ b/ui/qt/models/column_list_model.cpp
@@ -13,11 +13,11 @@
#include <ui/qt/widgets/syntax_line_edit.h>
#include <ui/qt/utils/wireshark_mime_data.h>
-#include <glib.h>
#include <epan/column.h>
#include <epan/prefs.h>
#include <epan/proto.h>
#include <ui/preference_utils.h>
+#include <ui/recent.h>
#include <QLineEdit>
#include <QStringList>
@@ -31,6 +31,8 @@ struct ListElement
int type;
int originalType;
int occurrence;
+ int width;
+ char xalign;
bool displayed;
bool resolved;
};
@@ -65,6 +67,22 @@ ColumnTypeDelegate::ColumnTypeDelegate(QObject * parent) :
QStyledItemDelegate(parent)
{}
+QString ColumnTypeDelegate::alignDesc(char xalign)
+{
+ switch (xalign) {
+ case COLUMN_XALIGN_DEFAULT:
+ return QObject::tr("Default");
+ case COLUMN_XALIGN_LEFT:
+ return QObject::tr("Left");
+ case COLUMN_XALIGN_CENTER:
+ return QObject::tr("Center");
+ case COLUMN_XALIGN_RIGHT:
+ return QObject::tr("Right");
+ default:
+ return QObject::tr("Unknown");
+ }
+}
+
QWidget *ColumnTypeDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
@@ -92,13 +110,26 @@ QWidget *ColumnTypeDelegate::createEditor(QWidget *parent,
ff_editor->setText(index.data().toString());
editor = ff_editor;
}
- else if (index.column() == ColumnListModel::COL_OCCURRENCE)
+ else if (index.column() == ColumnListModel::COL_OCCURRENCE ||
+ index.column() == ColumnListModel::COL_WIDTH)
{
SyntaxLineEdit * sl_editor = new SyntaxLineEdit(parent);
connect(sl_editor, &SyntaxLineEdit::textChanged, sl_editor, &SyntaxLineEdit::checkInteger);
sl_editor->setText(index.data().toString());
editor = sl_editor;
}
+ else if (index.column() == ColumnListModel::COL_XALIGN)
+ {
+ QComboBox *cb_editor = new QComboBox(parent);
+
+ cb_editor->addItem(alignDesc(COLUMN_XALIGN_DEFAULT), QVariant(COLUMN_XALIGN_DEFAULT));
+ cb_editor->addItem(alignDesc(COLUMN_XALIGN_LEFT), QVariant(COLUMN_XALIGN_LEFT));
+ cb_editor->addItem(alignDesc(COLUMN_XALIGN_CENTER), QVariant(COLUMN_XALIGN_CENTER));
+ cb_editor->addItem(alignDesc(COLUMN_XALIGN_RIGHT), QVariant(COLUMN_XALIGN_RIGHT));
+ cb_editor->setCurrentIndex(cb_editor->findText(index.data().toString()));
+ cb_editor->setFrame(false);
+ editor = cb_editor;
+ }
if (!editor) {
editor = QStyledItemDelegate::createEditor(parent, option, index);
@@ -111,7 +142,8 @@ void ColumnTypeDelegate::setEditorData(QWidget *editor,
const QModelIndex &index) const
{
QVariant data = index.model()->data(index);
- if (index.column() == ColumnListModel::COL_TYPE)
+ if (index.column() == ColumnListModel::COL_TYPE ||
+ index.column() == ColumnListModel::COL_XALIGN)
{
QComboBox *comboBox = static_cast<QComboBox*>(editor);
comboBox->setCurrentText(data.toString());
@@ -121,7 +153,8 @@ void ColumnTypeDelegate::setEditorData(QWidget *editor,
if (qobject_cast<FieldFilterEdit *>(editor))
qobject_cast<FieldFilterEdit *>(editor)->setText(data.toString());
}
- else if (index.column() == ColumnListModel::COL_OCCURRENCE)
+ else if (index.column() == ColumnListModel::COL_OCCURRENCE ||
+ index.column() == ColumnListModel::COL_WIDTH)
{
if (qobject_cast<SyntaxLineEdit *>(editor))
qobject_cast<SyntaxLineEdit *>(editor)->setText(data.toString());
@@ -136,7 +169,8 @@ void ColumnTypeDelegate::setEditorData(QWidget *editor,
void ColumnTypeDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const
{
- if (index.column() == ColumnListModel::COL_TYPE)
+ if (index.column() == ColumnListModel::COL_TYPE ||
+ index.column() == ColumnListModel::COL_XALIGN)
{
QComboBox *comboBox = static_cast<QComboBox*>(editor);
bool ok = false;
@@ -197,6 +231,22 @@ void ColumnTypeDelegate::setModelData(QWidget *editor, QAbstractItemModel *model
}
}
+ else if (index.column() == ColumnListModel::COL_WIDTH)
+ {
+ SyntaxLineEdit * sle = qobject_cast<SyntaxLineEdit *>(editor);
+ bool ok = false;
+ if (sle)
+ {
+ sle->checkInteger(index.data().toString());
+ if (sle->syntaxState() == SyntaxLineEdit::Valid)
+ ok = true;
+ }
+
+ if (ok)
+ {
+ model->setData(index, sle->text(), Qt::EditRole);
+ }
+ }
else
QStyledItemDelegate::setModelData(editor, model, index);
}
@@ -216,7 +266,7 @@ ColumnListModel::ColumnListModel(QObject * parent):
QVariant ColumnListModel::headerData(int section, Qt::Orientation orientation, int role) const
{
- if (section > ColumnListModel::COL_RESOLVED || orientation != Qt::Horizontal ||
+ if (section > ColumnListModel::COL_XALIGN || orientation != Qt::Horizontal ||
role != Qt::DisplayRole)
return QVariant();
@@ -230,7 +280,7 @@ int ColumnListModel::rowCount(const QModelIndex &/*parent*/) const
int ColumnListModel::columnCount(const QModelIndex &/*parent*/) const
{
- return ColumnListModel::COL_RESOLVED + 1;
+ return ColumnListModel::COL_XALIGN + 1;
}
QString ColumnListModel::headerTitle(int section) const
@@ -249,6 +299,10 @@ QString ColumnListModel::headerTitle(int section) const
return tr("Field Occurrence");
case ColumnListModel::COL_RESOLVED:
return tr("Resolved");
+ case ColumnListModel::COL_WIDTH:
+ return tr("Width");
+ case ColumnListModel::COL_XALIGN:
+ return tr("Alignment");
}
return QString();
@@ -271,6 +325,9 @@ void ColumnListModel::populate()
ne.occurrence = cfmt->custom_occurrence;
ne.resolved = cfmt->resolved;
+ ne.width = recent_get_column_width(nr);
+ ne.xalign = recent_get_column_xalign(nr);
+
nr++;
store_ << ne;
}
@@ -278,7 +335,7 @@ void ColumnListModel::populate()
QVariant ColumnListModel::data(const QModelIndex &index, int role) const
{
- if (! index.isValid() || index.column() >= store_.count())
+ if (! index.isValid() || index.row() >= store_.count())
return QVariant();
ListElement ne = store_.at(index.row());
@@ -298,6 +355,10 @@ QVariant ColumnListModel::data(const QModelIndex &index, int role) const
return ne.customFields;
case ColumnListModel::COL_OCCURRENCE:
return ne.customFields.length() > 0 ? QVariant::fromValue(ne.occurrence) : QVariant();
+ case ColumnListModel::COL_WIDTH:
+ return ne.width;
+ case ColumnListModel::COL_XALIGN:
+ return ColumnTypeDelegate::alignDesc(ne.xalign);
}
}
else if (role == Qt::CheckStateRole)
@@ -452,6 +513,20 @@ bool ColumnListModel::setData(const QModelIndex &index, const QVariant &value, i
{
store_[index.row()].resolved = value.toInt() == Qt::Checked ? true : false;
}
+ else if (index.column() == ColumnListModel::COL_WIDTH)
+ {
+ bool ok = false;
+ int val = value.toInt(&ok);
+ if (ok)
+ store_[index.row()].width = val;
+ }
+ else if (index.column() == ColumnListModel::COL_XALIGN)
+ {
+ bool ok = false;
+ int val = value.toInt(&ok);
+ if (ok)
+ store_[index.row()].xalign = static_cast<char>(val);
+ }
if (change)
emit dataChanged(index, index);
@@ -471,7 +546,7 @@ void ColumnListModel::saveColumns()
cfmt->title = qstring_strdup(elem.title);
cfmt->visible = elem.displayed;
cfmt->fmt = elem.type;
- cfmt->resolved = TRUE;
+ cfmt->resolved = true;
if (cfmt->fmt == COL_CUSTOM)
{
cfmt->custom_fields = qstring_strdup(elem.customFields);
@@ -486,6 +561,16 @@ void ColumnListModel::saveColumns()
column_prefs_remove_link(prefs.col_list);
prefs.col_list = new_col_list;
+
+ recent_free_column_width_info(&recent);
+ for (int row = 0; row < store_.count(); row++)
+ {
+ ListElement elem = store_.at(row);
+
+ recent_insert_column(row);
+ recent_set_column_width(row, elem.width);
+ recent_set_column_xalign(row, elem.xalign);
+ }
}
void ColumnListModel::addEntry()
@@ -499,6 +584,8 @@ void ColumnListModel::addEntry()
elem.occurrence = 0;
elem.customFields = QString();
elem.resolved = true;
+ elem.width = -1;
+ elem.xalign = COLUMN_XALIGN_DEFAULT;
store_ << elem;
endInsertRows();
}
diff --git a/ui/qt/models/column_list_model.h b/ui/qt/models/column_list_model.h
index c4739f96..7f59b91c 100644
--- a/ui/qt/models/column_list_model.h
+++ b/ui/qt/models/column_list_model.h
@@ -35,6 +35,8 @@ class ColumnTypeDelegate : public QStyledItemDelegate
public:
ColumnTypeDelegate(QObject * parent = Q_NULLPTR);
+ static QString alignDesc(char xalign);
+
QWidget * createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
@@ -59,7 +61,9 @@ public:
COL_TYPE,
COL_FIELDS,
COL_OCCURRENCE,
- COL_RESOLVED
+ COL_RESOLVED,
+ COL_WIDTH,
+ COL_XALIGN
};
enum {
diff --git a/ui/qt/models/decode_as_delegate.cpp b/ui/qt/models/decode_as_delegate.cpp
index 3c300a79..c3917928 100644
--- a/ui/qt/models/decode_as_delegate.cpp
+++ b/ui/qt/models/decode_as_delegate.cpp
@@ -46,11 +46,11 @@ void DecodeAsDelegate::cachePacketProtocols()
if (cap_file_ && cap_file_->edt) {
wmem_list_frame_t * protos = wmem_list_head(cap_file_->edt->pi.layers);
- guint8 curr_layer_num = 1;
+ uint8_t curr_layer_num = 1;
while (protos != NULL) {
int proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
- const gchar * proto_name = proto_get_protocol_filter_name(proto_id);
+ const char * proto_name = proto_get_protocol_filter_name(proto_id);
for (GList *cur = decode_as_list; cur; cur = cur->next) {
decode_as_t *entry = (decode_as_t *) cur->data;
if (g_strcmp0(proto_name, entry->name) == 0) {
@@ -95,7 +95,7 @@ void DecodeAsDelegate::collectDAProtocols(QSet<QString>& all_protocols, QList<QS
//correspond to using a combo box
bool DecodeAsDelegate::isSelectorCombo(DecodeAsItem* item) const
{
- const gchar *proto_name = NULL;
+ const char *proto_name = NULL;
foreach(packet_proto_data_t proto, packet_proto_list_)
{
@@ -117,7 +117,7 @@ bool DecodeAsDelegate::isSelectorCombo(DecodeAsItem* item) const
return false;
}
-void DecodeAsDelegate::decodeAddProtocol(const gchar *, const gchar *proto_name, gpointer value, gpointer user_data)
+void DecodeAsDelegate::decodeAddProtocol(const char *, const char *proto_name, void *value, void *user_data)
{
QList<dissector_info_t*>* proto_list = (QList<dissector_info_t*>*)user_data;
@@ -178,10 +178,10 @@ QWidget* DecodeAsDelegate::createEditor(QWidget *parentWidget, const QStyleOptio
case DecodeAsModel::colSelector:
{
QComboBox *cb_editor = NULL;
- const gchar *proto_name = NULL;
+ const char *proto_name = NULL;
bool edt_present = cap_file_ && cap_file_->edt;
- gint8 curr_layer_num_saved = edt_present ? cap_file_->edt->pi.curr_layer_num : 0;
- QList<guint8> proto_layers;
+ int8_t curr_layer_num_saved = edt_present ? cap_file_->edt->pi.curr_layer_num : 0;
+ QList<uint8_t> proto_layers;
foreach(packet_proto_data_t proto, packet_proto_list_)
{
@@ -212,7 +212,7 @@ QWidget* DecodeAsDelegate::createEditor(QWidget *parentWidget, const QStyleOptio
cb_editor->addItem(current_value);
//get the value(s) from the packet
- foreach(guint8 current_layer, proto_layers) {
+ foreach(uint8_t current_layer, proto_layers) {
cap_file_->edt->pi.curr_layer_num = current_layer;
for (uint ni = 0; ni < entry->num_items; ni++) {
if (entry->values[ni].num_values == 1) { // Skip over multi-value ("both") entries
diff --git a/ui/qt/models/decode_as_delegate.h b/ui/qt/models/decode_as_delegate.h
index d0457764..d793a85a 100644
--- a/ui/qt/models/decode_as_delegate.h
+++ b/ui/qt/models/decode_as_delegate.h
@@ -13,7 +13,6 @@
#define DECODE_AS_DELEGATE_H
#include <config.h>
-#include <glib.h>
#include "cfile.h"
@@ -23,9 +22,9 @@
#include <ui/qt/models/decode_as_model.h>
typedef struct _packet_proto_data_t {
- const gchar* proto_name;
- const gchar* table_ui_name;
- guint8 curr_layer_num;
+ const char* proto_name;
+ const char* table_ui_name;
+ uint8_t curr_layer_num;
} packet_proto_data_t;
class DecodeAsDelegate : public QStyledItemDelegate
@@ -51,7 +50,7 @@ private:
void cachePacketProtocols();
bool isSelectorCombo(DecodeAsItem* item) const;
- static void decodeAddProtocol(const gchar *table_name, const gchar *proto_name, gpointer value, gpointer user_data);
+ static void decodeAddProtocol(const char *table_name, const char *proto_name, void *value, void *user_data);
capture_file *cap_file_;
QList<packet_proto_data_t> packet_proto_list_;
diff --git a/ui/qt/models/decode_as_model.cpp b/ui/qt/models/decode_as_model.cpp
index 67e98b75..73253c30 100644
--- a/ui/qt/models/decode_as_model.cpp
+++ b/ui/qt/models/decode_as_model.cpp
@@ -29,7 +29,7 @@
static const char *DEFAULT_TABLE = "tcp.port"; // Arbitrary
static const char *DEFAULT_UI_TABLE = "TCP port"; // Arbitrary
-DecodeAsItem::DecodeAsItem(const char* table_name, gconstpointer selector) :
+DecodeAsItem::DecodeAsItem(const char* table_name, const void *selector) :
tableName_(DEFAULT_TABLE),
tableUIName_(DEFAULT_UI_TABLE),
selectorUint_(0),
@@ -45,7 +45,7 @@ DecodeAsItem::DecodeAsItem(const char* table_name, gconstpointer selector) :
init(table_name, selector);
}
-DecodeAsItem::DecodeAsItem(const decode_as_t *entry, gconstpointer selector) :
+DecodeAsItem::DecodeAsItem(const decode_as_t *entry, const void *selector) :
tableName_(DEFAULT_TABLE),
tableUIName_(DEFAULT_UI_TABLE),
selectorUint_(0),
@@ -65,7 +65,7 @@ DecodeAsItem::~DecodeAsItem()
{
}
-void DecodeAsItem::init(const char* table_name, gconstpointer selector)
+void DecodeAsItem::init(const char* table_name, const void *selector)
{
tableName_ = table_name;
tableUIName_ = get_dissector_table_ui_name(tableName_);
@@ -74,7 +74,7 @@ void DecodeAsItem::init(const char* table_name, gconstpointer selector)
ftenum_t selector_type = get_dissector_table_selector_type(tableName_);
if (FT_IS_STRING(selector_type)) {
if (selector != NULL) {
- default_handle = dissector_get_default_string_handle(tableName_, (const gchar*)selector);
+ default_handle = dissector_get_default_string_handle(tableName_, (const char*)selector);
selectorString_ = QString((const char*)selector);
}
} else if (FT_IS_UINT(selector_type)) {
@@ -241,7 +241,7 @@ QVariant DecodeAsModel::data(const QModelIndex &index, int role) const
if (FT_IS_UINT(selector_type)) {
return entryString(item->tableName(), GUINT_TO_POINTER(item->selectorUint()));
} else if (FT_IS_STRING(selector_type)) {
- return entryString(item->tableName(), (gconstpointer)item->selectorString().toUtf8().constData());
+ return entryString(item->tableName(), (const void *)item->selectorString().toUtf8().constData());
} else if (selector_type == FT_GUID) {
if (item->selectorDCERPC() != NULL) {
return item->selectorDCERPC()->ctx_id;
@@ -410,12 +410,12 @@ bool DecodeAsModel::insertRows(int row, int count, const QModelIndex &/*parent*/
// the fields for the tables not being present at all.
wmem_list_frame_t * protos = wmem_list_tail(cap_file_->edt->pi.layers);
- gint8 curr_layer_num_saved = cap_file_->edt->pi.curr_layer_num;
- guint8 curr_layer_num = wmem_list_count(cap_file_->edt->pi.layers);
+ int8_t curr_layer_num_saved = cap_file_->edt->pi.curr_layer_num;
+ uint8_t curr_layer_num = wmem_list_count(cap_file_->edt->pi.layers);
while (protos != NULL && item == nullptr) {
int proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos));
- const gchar * proto_name = proto_get_protocol_filter_name(proto_id);
+ const char * proto_name = proto_get_protocol_filter_name(proto_id);
for (GList *cur = decode_as_list; cur; cur = cur->next) {
decode_as_t *entry = (decode_as_t *) cur->data;
if (g_strcmp0(proto_name, entry->name) == 0) {
@@ -428,7 +428,7 @@ bool DecodeAsModel::insertRows(int row, int count, const QModelIndex &/*parent*/
// XXX: What if the Decode As table supports multiple
// values, but the first possible one is 0/NULL?
cap_file_->edt->pi.curr_layer_num = curr_layer_num;
- gpointer selector = entry->values[0].build_values[0](&cap_file_->edt->pi);
+ void *selector = entry->values[0].build_values[0](&cap_file_->edt->pi);
// FT_NONE tables don't need a value
if (selector != NULL || selector_type == FT_NONE) {
item = new DecodeAsItem(entry, selector);
@@ -499,7 +499,7 @@ bool DecodeAsModel::copyRow(int dst_row, int src_row)
return true;
}
-prefs_set_pref_e DecodeAsModel::readDecodeAsEntry(gchar *key, const gchar *value, void *private_data, gboolean)
+prefs_set_pref_e DecodeAsModel::readDecodeAsEntry(char *key, const char *value, void *private_data, bool)
{
DecodeAsModel *model = (DecodeAsModel*)private_data;
if (model == NULL)
@@ -510,7 +510,7 @@ prefs_set_pref_e DecodeAsModel::readDecodeAsEntry(gchar *key, const gchar *value
}
/* Parse into table, selector, initial, current */
- gchar **values = g_strsplit_set(value, ",", 4);
+ char **values = g_strsplit_set(value, ",", 4);
DecodeAsItem *item = nullptr;
dissector_table_t dissector_table = find_dissector_table(values[0]);
@@ -546,7 +546,7 @@ prefs_set_pref_e DecodeAsModel::readDecodeAsEntry(gchar *key, const gchar *value
return PREFS_SET_OK;
}
-bool DecodeAsModel::copyFromProfile(QString filename, const gchar **err)
+bool DecodeAsModel::copyFromProfile(QString filename, const char **err)
{
FILE *fp = ws_fopen(filename.toUtf8().constData(), "r");
@@ -564,7 +564,7 @@ bool DecodeAsModel::copyFromProfile(QString filename, const gchar **err)
return true;
}
-QString DecodeAsModel::entryString(const gchar *table_name, gconstpointer value)
+QString DecodeAsModel::entryString(const char *table_name, const void *value)
{
QString entry_str;
ftenum_t selector_type = get_dissector_table_selector_type(table_name);
@@ -654,7 +654,7 @@ void DecodeAsModel::setDissectorHandle(const QModelIndex &index, dissector_handl
item->setDissectorHandle(dissector_handle);
}
-void DecodeAsModel::buildChangedList(const gchar *table_name, ftenum_t, gpointer key, gpointer value, gpointer user_data)
+void DecodeAsModel::buildChangedList(const char *table_name, ftenum_t, void *key, void *value, void *user_data)
{
DecodeAsModel *model = (DecodeAsModel*)user_data;
if (model == NULL)
@@ -669,7 +669,7 @@ void DecodeAsModel::buildChangedList(const gchar *table_name, ftenum_t, gpointer
model->decode_as_items_ << item;
}
-void DecodeAsModel::buildDceRpcChangedList(gpointer data, gpointer user_data)
+void DecodeAsModel::buildDceRpcChangedList(void *data, void *user_data)
{
dissector_table_t sub_dissectors;
guid_key guid_val;
@@ -690,27 +690,36 @@ void DecodeAsModel::buildDceRpcChangedList(gpointer data, gpointer user_data)
model->decode_as_items_ << item;
}
-typedef QPair<const char *, guint32> UintPair;
typedef QPair<const char *, const char *> CharPtrPair;
-void DecodeAsModel::gatherChangedEntries(const gchar *table_name,
- ftenum_t selector_type, gpointer key, gpointer, gpointer user_data)
+void DecodeAsModel::gatherChangedEntries(const char *table_name,
+ ftenum_t selector_type, void *key, void *value, void *user_data)
{
DecodeAsModel *model = qobject_cast<DecodeAsModel*>((DecodeAsModel*)user_data);
if (model == NULL)
return;
+ dissector_handle_t current = dtbl_entry_get_handle((dtbl_entry_t *)value);
+
switch (selector_type) {
case FT_UINT8:
case FT_UINT16:
case FT_UINT24:
case FT_UINT32:
- model->changed_uint_entries_ << UintPair(table_name, GPOINTER_TO_UINT(key));
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ model->changed_uint_entries_.emplaceBack(table_name, GPOINTER_TO_UINT(key), dissector_handle_get_pref_suffix(current));
+#else
+ model->changed_uint_entries_ << UIntEntry(table_name, GPOINTER_TO_UINT(key), dissector_handle_get_pref_suffix(current));
+#endif
break;
case FT_NONE:
//need to reset dissector table, so this needs to be in a changed list,
//might as well be the uint one.
- model->changed_uint_entries_ << UintPair(table_name, 0);
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ model->changed_uint_entries_.emplaceBack(table_name, 0, "");
+#else
+ model->changed_uint_entries_ << UIntEntry(table_name, 0, "");
+#endif
break;
case FT_STRING:
@@ -741,20 +750,20 @@ void DecodeAsModel::applyChanges()
// If dissector_all_tables_remove_changed existed we could call it
// instead.
dissector_all_tables_foreach_changed(gatherChangedEntries, this);
- foreach (UintPair uint_entry, changed_uint_entries_) {
+ foreach (const auto &uint_entry, changed_uint_entries_) {
/* Set "Decode As preferences" to default values */
- sub_dissectors = find_dissector_table(uint_entry.first);
- handle = dissector_get_uint_handle(sub_dissectors, uint_entry.second);
+ sub_dissectors = find_dissector_table(uint_entry.table);
+ handle = dissector_get_uint_handle(sub_dissectors, uint_entry.key);
if (handle != NULL) {
module = prefs_find_module(proto_get_protocol_filter_name(dissector_handle_get_protocol_index(handle)));
- pref_value = prefs_find_preference(module, uint_entry.first);
+ pref_value = prefs_find_preference(module, uint_entry.pref_name);
if (pref_value != NULL) {
module->prefs_changed_flags |= prefs_get_effect_flags(pref_value);
reset_pref(pref_value);
}
}
- dissector_reset_uint(uint_entry.first, uint_entry.second);
+ dissector_reset_uint(uint_entry.table, uint_entry.key);
}
changed_uint_entries_.clear();
foreach (CharPtrPair char_ptr_entry, changed_string_entries_) {
@@ -775,7 +784,7 @@ void DecodeAsModel::applyChanges()
if (!g_strcmp0(decode_as_entry->table_name, item->tableName())) {
ftenum_t selector_type = get_dissector_table_selector_type(item->tableName());
- gconstpointer selector_value;
+ const void * selector_value;
QByteArray byteArray;
switch (selector_type) {
@@ -791,7 +800,7 @@ void DecodeAsModel::applyChanges()
case FT_STRINGZPAD:
case FT_STRINGZTRUNC:
byteArray = item->selectorString().toUtf8();
- selector_value = (gconstpointer) byteArray.constData();
+ selector_value = (const void *) byteArray.constData();
break;
case FT_NONE:
//selector value is ignored, but dissector table needs to happen
@@ -799,7 +808,7 @@ void DecodeAsModel::applyChanges()
break;
case FT_GUID:
if (item->selectorDCERPC() != NULL) {
- selector_value = (gconstpointer)item->selectorDCERPC();
+ selector_value = (const void *)item->selectorDCERPC();
} else {
//TODO: Support normal GUID dissector tables
selector_value = NULL;
@@ -820,7 +829,7 @@ void DecodeAsModel::applyChanges()
pref_value = prefs_find_preference(module, decode_as_entry->table_name);
if (pref_value != NULL) {
module->prefs_changed_flags |= prefs_get_effect_flags(pref_value);
- prefs_remove_decode_as_value(pref_value, item->selectorUint(), TRUE);
+ prefs_remove_decode_as_value(pref_value, item->selectorUint(), true);
}
}
}
@@ -833,10 +842,10 @@ void DecodeAsModel::applyChanges()
if (item->dissectorHandle() != NULL) {
if (FT_IS_UINT(dissector_table_get_type(sub_dissectors))) {
module = prefs_find_module(proto_get_protocol_filter_name(dissector_handle_get_protocol_index(item->dissectorHandle())));
- pref_value = prefs_find_preference(module, decode_as_entry->table_name);
+ pref_value = prefs_find_preference(module, QByteArray(decode_as_entry->table_name).append(dissector_handle_get_pref_suffix(item->dissectorHandle())));
if (pref_value != NULL) {
module->prefs_changed_flags |= prefs_get_effect_flags(pref_value);
- prefs_add_decode_as_value(pref_value, item->selectorUint(), FALSE);
+ prefs_add_decode_as_value(pref_value, item->selectorUint(), false);
}
}
}
diff --git a/ui/qt/models/decode_as_model.h b/ui/qt/models/decode_as_model.h
index cf280965..273827a8 100644
--- a/ui/qt/models/decode_as_model.h
+++ b/ui/qt/models/decode_as_model.h
@@ -13,7 +13,6 @@
#define DECODE_AS_MODEL_H
#include <config.h>
-#include <glib.h>
#include <QAbstractItemModel>
#include <QList>
@@ -27,12 +26,12 @@
class DecodeAsItem
{
public:
- DecodeAsItem(const char *table_name = NULL, gconstpointer selector = NULL);
- DecodeAsItem(const decode_as_t *entry, gconstpointer selector = NULL);
+ DecodeAsItem(const char *table_name = NULL, const void *selector = NULL);
+ DecodeAsItem(const decode_as_t *entry, const void *selector = NULL);
virtual ~DecodeAsItem();
- const gchar* tableName() const { return tableName_; }
- const gchar* tableUIName() const { return tableUIName_; }
+ const char* tableName() const { return tableName_; }
+ const char* tableUIName() const { return tableUIName_; }
uint selectorUint() const { return selectorUint_; }
QString selectorString() const { return selectorString_; }
decode_dcerpc_bind_values_t* selectorDCERPC() const { return selectorDCERPC_; }
@@ -46,10 +45,10 @@ public:
void updateHandles();
private:
- void init(const char *table_name, gconstpointer selector = NULL);
+ void init(const char *table_name, const void *selector = NULL);
- const gchar* tableName_;
- const gchar* tableUIName_;
+ const char* tableName_;
+ const char* tableUIName_;
//save our sanity and not have to worry about memory management
//between (lack of) persistent data in GUI and underlying data
@@ -70,6 +69,15 @@ public:
DecodeAsModel(QObject *parent, capture_file *cf = NULL);
virtual ~DecodeAsModel();
+ struct UIntEntry {
+ QByteArray table;
+ uint32_t key;
+ QByteArray pref_name;
+
+ UIntEntry(const char* t, uint32_t k, const char* pref_suffix) :
+ table(t), key(k), pref_name(t) { pref_name.append(pref_suffix); }
+ };
+
enum DecodeAsColumn {
colTable = 0, // aka "Field" (or dissector table like "TCP Port")
colSelector, // the actual table value (e.g., port number 80)
@@ -95,25 +103,25 @@ public:
bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
void clearAll();
bool copyRow(int dst_row, int src_row);
- bool copyFromProfile(QString filename, const gchar **err);
+ bool copyFromProfile(QString filename, const char **err);
- static QString entryString(const gchar *table_name, gconstpointer value);
+ static QString entryString(const char *table_name, const void *value);
void applyChanges();
protected:
- static void buildChangedList(const gchar *table_name, ftenum_t selector_type,
- gpointer key, gpointer value, gpointer user_data);
- static void buildDceRpcChangedList(gpointer data, gpointer user_data);
- static void gatherChangedEntries(const gchar *table_name, ftenum_t selector_type,
- gpointer key, gpointer value, gpointer user_data);
- static prefs_set_pref_e readDecodeAsEntry(gchar *key, const gchar *value,
- void *user_data, gboolean return_range_errors);
+ static void buildChangedList(const char *table_name, ftenum_t selector_type,
+ void *key, void *value, void *user_data);
+ static void buildDceRpcChangedList(void *data, void *user_data);
+ static void gatherChangedEntries(const char *table_name, ftenum_t selector_type,
+ void *key, void *value, void *user_data);
+ static prefs_set_pref_e readDecodeAsEntry(char *key, const char *value,
+ void *user_data, bool);
private:
capture_file *cap_file_;
QList<DecodeAsItem *> decode_as_items_;
- QList<QPair<const char *, guint32> > changed_uint_entries_;
+ QList<UIntEntry> changed_uint_entries_;
QList<QPair<const char *, const char *> > changed_string_entries_;
};
diff --git a/ui/qt/models/dissector_tables_model.cpp b/ui/qt/models/dissector_tables_model.cpp
index 73c757ec..dcf3dc72 100644
--- a/ui/qt/models/dissector_tables_model.cpp
+++ b/ui/qt/models/dissector_tables_model.cpp
@@ -179,7 +179,7 @@ QVariant DissectorTablesModel::data(const QModelIndex &index, int role) const
return QVariant();
}
-static void gatherProtocolDecodes(const char *, ftenum_t selector_type, gpointer key, gpointer value, gpointer item_ptr)
+static void gatherProtocolDecodes(const char *, ftenum_t selector_type, void *key, void *value, void *item_ptr)
{
DissectorTablesItem* pdl_ptr = (DissectorTablesItem*)item_ptr;
if (pdl_ptr == NULL)
@@ -225,7 +225,7 @@ struct tables_root
DissectorTablesItem* string_table;
};
-static void gatherTableNames(const char *short_name, const char *table_name, gpointer model_ptr)
+static void gatherTableNames(const char *short_name, const char *table_name, void *model_ptr)
{
struct tables_root* tables = (struct tables_root*)model_ptr;
if (model_ptr == NULL)
@@ -262,7 +262,7 @@ static void gatherTableNames(const char *short_name, const char *table_name, gpo
dissector_table_foreach(short_name, gatherProtocolDecodes, dt_ti);
}
-static void gatherHeurProtocolDecodes(const char *, struct heur_dtbl_entry *dtbl_entry, gpointer list_ptr)
+static void gatherHeurProtocolDecodes(const char *, struct heur_dtbl_entry *dtbl_entry, void *list_ptr)
{
DissectorTablesItem* hdl_ptr = (DissectorTablesItem*)list_ptr;
if (hdl_ptr == NULL)
@@ -279,13 +279,18 @@ static void gatherHeurProtocolDecodes(const char *, struct heur_dtbl_entry *dtbl
}
}
-static void gatherHeurTableNames(const char *table_name, heur_dissector_list *list, gpointer heur_tables)
+static void gatherHeurTableNames(const char *table_name, heur_dissector_list *list, void *heur_tables)
{
DissectorTablesItem* table = (DissectorTablesItem*)heur_tables;
if (table == NULL)
return;
- DissectorTablesItem *heur = new DissectorTablesItem(table_name, QString(""), table);
+ QString desc_name = table_name;
+ if (list) {
+ const char *desc = heur_dissector_list_get_description(list);
+ if (desc) desc_name = desc;
+ }
+ DissectorTablesItem *heur = new DissectorTablesItem(desc_name, table_name, table);
table->prependChild(heur);
if (list) {
diff --git a/ui/qt/models/enabled_protocols_model.cpp b/ui/qt/models/enabled_protocols_model.cpp
index ecbc47a9..d923d765 100644
--- a/ui/qt/models/enabled_protocols_model.cpp
+++ b/ui/qt/models/enabled_protocols_model.cpp
@@ -31,7 +31,7 @@ public:
virtual ~ProtocolTreeItem() {}
protected:
- virtual void applyValuePrivate(gboolean value)
+ virtual void applyValuePrivate(bool value)
{
if (! proto_can_toggle_protocol(proto_get_id(proto_))) {
return;
@@ -56,7 +56,7 @@ public:
virtual ~HeuristicTreeItem() {}
protected:
- virtual void applyValuePrivate(gboolean value)
+ virtual void applyValuePrivate(bool value)
{
heuristic_table_->enabled = value;
}
@@ -239,7 +239,6 @@ QVariant EnabledProtocolsModel::data(const QModelIndex &index, int role) const
break;
case DATA_PROTOCOL_TYPE:
return QVariant::fromValue(item->type());
- break;
default:
break;
}
@@ -270,7 +269,7 @@ bool EnabledProtocolsModel::setData(const QModelIndex &index, const QVariant &va
return true;
}
-static void addHeuristicItem(gpointer data, gpointer user_data)
+static void addHeuristicItem(void *data, void *user_data)
{
heur_dtbl_entry_t* heur = (heur_dtbl_entry_t*)data;
ProtocolTreeItem* protocol_item = (ProtocolTreeItem*)user_data;
diff --git a/ui/qt/models/enabled_protocols_model.h b/ui/qt/models/enabled_protocols_model.h
index 23b2c1bb..fe6caeab 100644
--- a/ui/qt/models/enabled_protocols_model.h
+++ b/ui/qt/models/enabled_protocols_model.h
@@ -43,7 +43,7 @@ public:
bool applyValue();
protected:
- virtual void applyValuePrivate(gboolean value) = 0;
+ virtual void applyValuePrivate(bool value) = 0;
QString name_;
QString description_;
diff --git a/ui/qt/models/expert_info_model.cpp b/ui/qt/models/expert_info_model.cpp
index 017dba3d..24204612 100644
--- a/ui/qt/models/expert_info_model.cpp
+++ b/ui/qt/models/expert_info_model.cpp
@@ -118,7 +118,7 @@ ExpertPacketItem* ExpertInfoModel::createRootItem()
{
static const char* rootName = "ROOT";
DIAG_OFF_CAST_AWAY_CONST
- static expert_info_t root_expert = { 0, -1, -1, -1, rootName, (gchar*)rootName, NULL };
+ static expert_info_t root_expert = { 0, -1, -1, -1, rootName, (char*)rootName, NULL };
DIAG_ON_CAST_AWAY_CONST
return new ExpertPacketItem(root_expert, NULL, NULL);
@@ -355,8 +355,8 @@ int ExpertInfoModel::columnCount(const QModelIndex&) const
void ExpertInfoModel::addExpertInfo(const struct expert_info_s& expert_info)
{
- QString groupKey = ExpertPacketItem::groupKey(FALSE, expert_info.severity, expert_info.group, QString(expert_info.protocol), expert_info.hf_index);
- QString summaryKey = ExpertPacketItem::groupKey(TRUE, expert_info.severity, expert_info.group, QString(expert_info.protocol), expert_info.hf_index);
+ QString groupKey = ExpertPacketItem::groupKey(false, expert_info.severity, expert_info.group, QString(expert_info.protocol), expert_info.hf_index);
+ QString summaryKey = ExpertPacketItem::groupKey(true, expert_info.severity, expert_info.group, QString(expert_info.protocol), expert_info.hf_index);
ExpertPacketItem* expert_root = root_->child(groupKey);
if (expert_root == NULL) {
diff --git a/ui/qt/models/export_objects_model.cpp b/ui/qt/models/export_objects_model.cpp
index 3cf9ec63..3546db5c 100644
--- a/ui/qt/models/export_objects_model.cpp
+++ b/ui/qt/models/export_objects_model.cpp
@@ -176,7 +176,7 @@ void ExportObjectModel::saveAllEntries(QString path)
if (entry == NULL)
continue;
- guint count = 0;
+ unsigned count = 0;
QString filename;
do {
diff --git a/ui/qt/models/fileset_entry_model.cpp b/ui/qt/models/fileset_entry_model.cpp
index 8c9f504b..86979e38 100644
--- a/ui/qt/models/fileset_entry_model.cpp
+++ b/ui/qt/models/fileset_entry_model.cpp
@@ -121,14 +121,13 @@ void FilesetEntryModel::clear()
}
QString FilesetEntryModel::nameToDate(const char *name) const {
+ char *date;
QString dn;
- if (!fileset_filename_match_pattern(name))
+ if (fileset_filename_match_pattern(name, NULL, NULL, &date) == FILESET_NO_MATCH)
return NULL;
- dn = name;
- dn.remove(QRegularExpression(".*_"));
- dn.truncate(14);
+ dn = gchar_free_to_qstring(date);
dn.insert(4, '-');
dn.insert(7, '-');
dn.insert(10, ' ');
diff --git a/ui/qt/models/fileset_entry_model.h b/ui/qt/models/fileset_entry_model.h
index aa812b0c..40e6796f 100644
--- a/ui/qt/models/fileset_entry_model.h
+++ b/ui/qt/models/fileset_entry_model.h
@@ -12,8 +12,6 @@
#include <config.h>
-#include <glib.h>
-
#include <fileset.h>
#include <QAbstractItemModel>
diff --git a/ui/qt/models/filter_list_model.cpp b/ui/qt/models/filter_list_model.cpp
index 3ed25839..c257d6af 100644
--- a/ui/qt/models/filter_list_model.cpp
+++ b/ui/qt/models/filter_list_model.cpp
@@ -8,8 +8,6 @@
* SPDX-License-Identifier: GPL-2.0-or-later
*/
-#include <glib.h>
-
#include <wsutil/filesystem.h>
#include <ui/qt/utils/qt_ui_utils.h>
@@ -24,11 +22,6 @@
#include <QMimeData>
/*
- * Old filter file name.
- */
-#define FILTER_FILE_NAME "filters"
-
-/*
* Capture filter file name.
*/
#define CFILTER_FILE_NAME "cfilters"
@@ -38,6 +31,11 @@
*/
#define DFILTER_FILE_NAME "dfilters"
+/*
+ * Display filter macros file name.
+ */
+#define DMACROS_FILE_NAME "dmacros"
+
FilterListModel::FilterListModel(QObject * parent) :
QAbstractListModel(parent),
type_(FilterListModel::Display)
@@ -56,12 +54,17 @@ void FilterListModel::reload()
{
storage.clear();
- const char * cfile = (type_ == FilterListModel::Capture) ? CFILTER_FILE_NAME : DFILTER_FILE_NAME;
+ const char *cfile;
+
+ switch (type_) {
+ case FilterListModel::Capture: cfile = CFILTER_FILE_NAME; break;
+ case FilterListModel::Display: cfile = DFILTER_FILE_NAME; break;
+ case FilterListModel::DisplayMacro: cfile = DMACROS_FILE_NAME; break;
+ default: ws_assert_not_reached();
+ }
/* Try personal config file first */
- QString fileName = gchar_free_to_qstring(get_persconffile_path(cfile, TRUE));
- if (fileName.length() <= 0 || ! QFileInfo::exists(fileName))
- fileName = gchar_free_to_qstring(get_persconffile_path(FILTER_FILE_NAME, TRUE));
+ QString fileName = gchar_free_to_qstring(get_persconffile_path(cfile, true));
if (fileName.length() <= 0 || ! QFileInfo::exists(fileName))
fileName = gchar_free_to_qstring(get_datafile_path(cfile));
if (fileName.length() <= 0 || ! QFileInfo::exists(fileName))
@@ -80,7 +83,7 @@ void FilterListModel::reload()
/* Filter out lines that do not contain content:
* - Starting with # is a comment
* - Does not start with a quoted string
- */
+ */
if (data.startsWith("#") || ! data.trimmed().startsWith("\""))
continue;
@@ -125,10 +128,16 @@ QVariant FilterListModel::headerData(int section, Qt::Orientation orientation, i
{
switch (section) {
case ColumnName:
- return tr("Filter Name");
+ if (type_ == DisplayMacro)
+ return tr("Macro Name");
+ else
+ return tr("Filter Name");
break;
case ColumnExpression:
- return tr("Filter Expression");
+ if (type_ == DisplayMacro)
+ return tr("Macro Expression");
+ else
+ return tr("Filter Expression");
break;
}
}
@@ -230,9 +239,17 @@ void FilterListModel::removeFilter(QModelIndex idx)
void FilterListModel::saveList()
{
- QString filename = (type_ == FilterListModel::Capture) ? CFILTER_FILE_NAME : DFILTER_FILE_NAME;
+ const char *cfile;
+ QString filename;
+
+ switch (type_) {
+ case Capture: cfile = CFILTER_FILE_NAME; break;
+ case Display: cfile = DFILTER_FILE_NAME; break;
+ case DisplayMacro: cfile = DMACROS_FILE_NAME; break;
+ default: ws_assert_not_reached();
+ }
- filename = QString("%1%2%3").arg(ProfileModel::activeProfilePath()).arg("/").arg(filename);
+ filename = QString("%1%2%3").arg(ProfileModel::activeProfilePath()).arg("/").arg(cfile);
QFile file(filename);
if (! file.open(QIODevice::WriteOnly | QIODevice::Text))
diff --git a/ui/qt/models/filter_list_model.h b/ui/qt/models/filter_list_model.h
index 4f528d2f..4611eeb9 100644
--- a/ui/qt/models/filter_list_model.h
+++ b/ui/qt/models/filter_list_model.h
@@ -25,7 +25,8 @@ class FilterListModel : public QAbstractListModel
public:
enum FilterListType {
Display,
- Capture
+ Capture,
+ DisplayMacro,
};
explicit FilterListModel(FilterListType type = FilterListModel::Display, QObject * parent = Q_NULLPTR);
diff --git a/ui/qt/models/info_proxy_model.cpp b/ui/qt/models/info_proxy_model.cpp
index 7b256b9d..e07027c8 100644
--- a/ui/qt/models/info_proxy_model.cpp
+++ b/ui/qt/models/info_proxy_model.cpp
@@ -57,7 +57,6 @@ QVariant InfoProxyModel::data (const QModelIndex &index, int role) const
{
case Qt::DisplayRole:
return infos_.at(ifIdx);
- break;
case Qt::FontRole:
QFont font = QIdentityProxyModel::data(index, Qt::FontRole).value<QFont>();
font.setItalic(true);
diff --git a/ui/qt/models/interface_sort_filter_model.cpp b/ui/qt/models/interface_sort_filter_model.cpp
index 9d9c5dc8..f5d62074 100644
--- a/ui/qt/models/interface_sort_filter_model.cpp
+++ b/ui/qt/models/interface_sort_filter_model.cpp
@@ -12,8 +12,6 @@
#include <ui/qt/models/interface_tree_cache_model.h>
#include <ui/qt/models/interface_sort_filter_model.h>
-#include <glib.h>
-
#include <epan/prefs.h>
#include <ui/preference_utils.h>
#include <ui/qt/utils/qt_ui_utils.h>
@@ -143,10 +141,7 @@ void InterfaceSortFilterModel::resetPreferenceData()
}
}
-#if 0
- // Disabled until bug 13354 is fixed
_filterHidden = ! prefs.gui_interfaces_show_hidden;
-#endif
#ifdef HAVE_PCAP_REMOTE
_remoteDisplay = prefs.gui_interfaces_remote_display;
#endif
@@ -278,15 +273,18 @@ bool InterfaceSortFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex
int type = -1;
bool hidden = false;
- if (dynamic_cast<InterfaceTreeCacheModel*>(sourceModel()) != 0)
+ InterfaceTreeCacheModel* cacheModel = qobject_cast<InterfaceTreeCacheModel*>(sourceModel());
+ InterfaceTreeModel* treeModel = nullptr;
+
+ if (cacheModel != nullptr)
{
- type = ((InterfaceTreeCacheModel *)sourceModel())->getColumnContent(idx, IFTREE_COL_TYPE).toInt();
- hidden = ((InterfaceTreeCacheModel *)sourceModel())->getColumnContent(idx, IFTREE_COL_HIDDEN, Qt::UserRole).toBool();
+ type = cacheModel->getColumnContent(idx, IFTREE_COL_TYPE).toInt();
+ hidden = cacheModel->getColumnContent(idx, IFTREE_COL_HIDDEN, Qt::UserRole).toBool();
}
- else if (dynamic_cast<InterfaceTreeModel*>(sourceModel()) != 0)
+ else if ((treeModel = qobject_cast<InterfaceTreeModel*>(sourceModel())) != nullptr)
{
- type = ((InterfaceTreeModel *)sourceModel())->getColumnContent(idx, IFTREE_COL_TYPE).toInt();
- hidden = ((InterfaceTreeModel *)sourceModel())->getColumnContent(idx, IFTREE_COL_HIDDEN, Qt::UserRole).toBool();
+ type = treeModel->getColumnContent(idx, IFTREE_COL_TYPE).toInt();
+ hidden = treeModel->getColumnContent(idx, IFTREE_COL_HIDDEN, Qt::UserRole).toBool();
}
else
return false;
@@ -294,24 +292,31 @@ bool InterfaceSortFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex
if (hidden && _filterHidden)
return false;
+#ifdef HAVE_PCAP_REMOTE
+ bool isRemote = false;
+ if (cacheModel && cacheModel->isRemote(realIndex)) {
+ isRemote = true;
+ } else if (treeModel && treeModel->isRemote(idx)) {
+ isRemote = true;
+ }
+#endif
+
if (_filterTypes && ! isInterfaceTypeShown(type))
{
#ifdef HAVE_PCAP_REMOTE
- /* Remote interfaces have the if type IF_WIRED, therefore would be filtered, if not explicitly checked here */
- if (type != IF_WIRED || ! ((InterfaceTreeModel *)sourceModel())->isRemote(idx))
+ /* Remote interfaces have the if type IF_WIRED, therefore would be filtered if not explicitly checked here */
+ if (type != IF_WIRED || !isRemote)
#endif
return false;
}
#ifdef HAVE_PCAP_REMOTE
- if (((InterfaceTreeModel *)sourceModel())->isRemote(idx))
- {
- if (! _remoteDisplay)
+ if (isRemote && !_remoteDisplay) {
return false;
}
#endif
-#endif
+#endif /* HAVE_LIBPCAP */
return true;
}
diff --git a/ui/qt/models/interface_sort_filter_model.h b/ui/qt/models/interface_sort_filter_model.h
index 5bf69d9d..e3609a81 100644
--- a/ui/qt/models/interface_sort_filter_model.h
+++ b/ui/qt/models/interface_sort_filter_model.h
@@ -16,8 +16,6 @@
#include <ui/qt/models/interface_tree_model.h>
-#include <glib.h>
-
#include <QSortFilterProxyModel>
class InterfaceSortFilterModel : public QSortFilterProxyModel
diff --git a/ui/qt/models/interface_tree_cache_model.cpp b/ui/qt/models/interface_tree_cache_model.cpp
index 71eda509..6c21d004 100644
--- a/ui/qt/models/interface_tree_cache_model.cpp
+++ b/ui/qt/models/interface_tree_cache_model.cpp
@@ -32,7 +32,7 @@ InterfaceTreeCacheModel::InterfaceTreeCacheModel(QObject *parent) :
sourceModel = new InterfaceTreeModel(parent);
QIdentityProxyModel::setSourceModel(sourceModel);
- storage = new QMap<int, QMap<InterfaceTreeColumns, QVariant> *>();
+ storage = new QMap<int, QSharedPointer<QMap<InterfaceTreeColumns, QVariant> > >();
checkableColumns << IFTREE_COL_HIDDEN << IFTREE_COL_PROMISCUOUSMODE;
#ifdef HAVE_PCAP_CREATE
@@ -67,8 +67,7 @@ void InterfaceTreeCacheModel::reset(int row)
{
if (row < 0)
{
- delete storage;
- storage = new QMap<int, QMap<InterfaceTreeColumns, QVariant> *>();
+ storage->clear();
}
else
{
@@ -90,7 +89,7 @@ void InterfaceTreeCacheModel::saveNewDevices()
interface_t *device = const_cast<interface_t *>(&(*it));
bool useDevice = false;
- QMap<InterfaceTreeColumns, QVariant> * dataField = storage->value(idx, 0);
+ QSharedPointer<QMap<InterfaceTreeColumns, QVariant> > dataField = storage->value(idx, 0);
/* When devices are being added, they are added using generic values. So only devices
* whose data have been changed should be used from here on out. */
if (dataField != 0)
@@ -124,7 +123,6 @@ void InterfaceTreeCacheModel::saveNewDevices()
/* All entries of this new devices have been considered */
storage->remove(idx);
- delete dataField;
}
newDevices.clear();
@@ -140,6 +138,13 @@ void InterfaceTreeCacheModel::save()
/* No devices are hidden until checking "Show" state */
prefStorage[&prefs.capture_devices_hide] = QStringList();
+ /* Some of the columns we only add entries to the QStringList for
+ * interfaces that have a non-default value, so we need to ensure
+ * that we set the pref string to empty if no interface is set.
+ */
+ prefStorage[&prefs.capture_devices_descr] = QStringList();
+ prefStorage[&prefs.capture_devices_monitor_mode] << QStringList();
+
/* Storing new devices first including their changed values */
saveNewDevices();
@@ -152,7 +157,7 @@ void InterfaceTreeCacheModel::save()
continue;
/* Try to load a saved value row for this index */
- QMap<InterfaceTreeColumns, QVariant> * dataField = storage->value(idx, 0);
+ QSharedPointer<QMap<InterfaceTreeColumns, QVariant> > dataField = storage->value(idx, 0);
/* Handle the storing of values for this device here */
if (dataField)
@@ -170,7 +175,8 @@ void InterfaceTreeCacheModel::save()
if (col == IFTREE_COL_HIDDEN)
{
- device->hidden = saveValue.toBool();
+ /* Hidden is de-selection, therefore inverted logic here */
+ device->hidden = (saveValue == Qt::Unchecked);
}
else if (device->if_info.type == IF_EXTCAP)
{
@@ -413,12 +419,12 @@ bool InterfaceTreeCacheModel::setData(const QModelIndex &index, const QVariant &
{
QVariant saveValue = value;
- QMap<InterfaceTreeColumns, QVariant> * dataField = 0;
+ QSharedPointer<QMap<InterfaceTreeColumns, QVariant> > dataField = nullptr;
/* obtain the list of already stored changes for this row. If none exist
* create a new storage row for this entry */
- if ((dataField = storage->value(row, 0)) == 0)
+ if ((dataField = storage->value(row, 0)) == nullptr)
{
- dataField = new QMap<InterfaceTreeColumns, QVariant>();
+ dataField = QSharedPointer<QMap<InterfaceTreeColumns, QVariant> >(new QMap<InterfaceTreeColumns, QVariant>);
storage->insert(row, dataField);
}
@@ -445,8 +451,8 @@ QVariant InterfaceTreeCacheModel::data(const QModelIndex &index, int role) const
if (((role == Qt::DisplayRole || role == Qt::EditRole) && editableColumns.contains(col)) ||
(role == Qt::CheckStateRole && checkableColumns.contains(col)) )
{
- QMap<InterfaceTreeColumns, QVariant> * dataField = 0;
- if ((dataField = storage->value(row, 0)) != 0)
+ QSharedPointer<QMap<InterfaceTreeColumns, QVariant> > dataField = nullptr;
+ if ((dataField = storage->value(row, 0)) != nullptr)
{
if (dataField->contains(col))
{
@@ -485,8 +491,8 @@ QVariant InterfaceTreeCacheModel::data(const QModelIndex &index, int role) const
col == IFTREE_COL_DESCRIPTION)
{
- QMap<InterfaceTreeColumns, QVariant> * dataField = 0;
- if ((dataField = storage->value(row, 0)) != 0 &&
+ QSharedPointer<QMap<InterfaceTreeColumns, QVariant> > dataField = nullptr;
+ if ((dataField = storage->value(row, 0)) != nullptr &&
dataField->contains(IFTREE_COL_PIPE_PATH))
{
return dataField->value(IFTREE_COL_PIPE_PATH, QVariant());
@@ -518,6 +524,17 @@ QVariant InterfaceTreeCacheModel::data(const QModelIndex &index, int role) const
return QVariant();
}
+#ifdef HAVE_PCAP_REMOTE
+bool InterfaceTreeCacheModel::isRemote(const QModelIndex &index) const
+{
+ const interface_t *device = lookup(index);
+ if (device != nullptr && device->remote_opts.src_type == CAPTURE_IFREMOTE) {
+ return true;
+ }
+ return false;
+}
+#endif
+
#ifdef HAVE_LIBPCAP
QModelIndex InterfaceTreeCacheModel::index(int row, int column, const QModelIndex &parent) const
{
diff --git a/ui/qt/models/interface_tree_cache_model.h b/ui/qt/models/interface_tree_cache_model.h
index 9b51c10b..1c33081d 100644
--- a/ui/qt/models/interface_tree_cache_model.h
+++ b/ui/qt/models/interface_tree_cache_model.h
@@ -20,6 +20,8 @@
class InterfaceTreeCacheModel : public QIdentityProxyModel
{
+ Q_OBJECT
+
public:
explicit InterfaceTreeCacheModel(QObject *parent);
~InterfaceTreeCacheModel();
@@ -42,6 +44,10 @@ public:
void deleteDevice(const QModelIndex &index);
#endif
+#ifdef HAVE_PCAP_REMOTE
+ bool isRemote(const QModelIndex &index) const;
+#endif
+
private:
InterfaceTreeModel * sourceModel;
@@ -50,7 +56,7 @@ private:
void saveNewDevices();
#endif
- QMap<int, QMap<InterfaceTreeColumns, QVariant> *> * storage;
+ QMap<int, QSharedPointer<QMap<InterfaceTreeColumns, QVariant> > > * storage;
QList<InterfaceTreeColumns> editableColumns;
QList<InterfaceTreeColumns> checkableColumns;
diff --git a/ui/qt/models/interface_tree_model.cpp b/ui/qt/models/interface_tree_model.cpp
index 547b9010..696937a2 100644
--- a/ui/qt/models/interface_tree_model.cpp
+++ b/ui/qt/models/interface_tree_model.cpp
@@ -136,7 +136,7 @@ QVariant InterfaceTreeModel::data(const QModelIndex &index, int role) const
}
else if (col == IFTREE_COL_DESCRIPTION)
{
- return QString(device->friendly_name);
+ return QString(device->if_info.friendly_name);
}
else if (col == IFTREE_COL_DISPLAY_NAME)
{
@@ -370,7 +370,7 @@ void InterfaceTreeModel::interfaceListChanged()
QVariant InterfaceTreeModel::toolTipForInterface(int idx) const
{
#ifdef HAVE_LIBPCAP
- if (! global_capture_opts.all_ifaces || global_capture_opts.all_ifaces->len <= (guint) idx)
+ if (! global_capture_opts.all_ifaces || global_capture_opts.all_ifaces->len <= (unsigned) idx)
return QVariant();
interface_t *device = &g_array_index(global_capture_opts.all_ifaces, interface_t, idx);
@@ -415,6 +415,12 @@ QVariant InterfaceTreeModel::toolTipForInterface(int idx) const
}
#ifdef HAVE_LIBPCAP
+void InterfaceTreeModel::setCache(if_stat_cache_t *stat_cache)
+{
+ stopStatistic();
+ stat_cache_ = stat_cache;
+}
+
void InterfaceTreeModel::stopStatistic()
{
if (stat_cache_)
@@ -428,7 +434,7 @@ void InterfaceTreeModel::stopStatistic()
void InterfaceTreeModel::updateStatistic(unsigned int idx)
{
#ifdef HAVE_LIBPCAP
- if (! global_capture_opts.all_ifaces || global_capture_opts.all_ifaces->len <= (guint) idx)
+ if (! global_capture_opts.all_ifaces || global_capture_opts.all_ifaces->len <= (unsigned) idx)
return;
interface_t *device = &g_array_index(global_capture_opts.all_ifaces, interface_t, idx);
@@ -439,7 +445,11 @@ void InterfaceTreeModel::updateStatistic(unsigned int idx)
if (!stat_cache_)
{
// Start gathering statistics using dumpcap
- // We crash (on macOS at least) if we try to do this from ::showEvent.
+ //
+ // The stat cache will only properly configure if it has the list
+ // of interfaces in global_capture_opts->all_ifaces.
+ // We crash if we try to do this from InterfaceFrame::showEvent,
+ // because main.cpp calls mainw->show() before capture_opts_init().
stat_cache_ = capture_stat_start(&global_capture_opts);
}
@@ -530,12 +540,12 @@ bool InterfaceTreeModel::updateSelectedDevices(QItemSelection sourceSelection)
{
if (! device->selected)
selectionHasChanged = true;
- device->selected = TRUE;
+ device->selected = true;
global_capture_opts.num_selected++;
} else {
if (device->selected)
selectionHasChanged = true;
- device->selected = FALSE;
+ device->selected = false;
}
}
#else
diff --git a/ui/qt/models/interface_tree_model.h b/ui/qt/models/interface_tree_model.h
index cdf2ac89..747dc2e0 100644
--- a/ui/qt/models/interface_tree_model.h
+++ b/ui/qt/models/interface_tree_model.h
@@ -27,19 +27,28 @@
typedef QList<int> PointList;
+/*
+ * When sorting, QSortFilterProxyModel creates its own mapping instead
+ * of using the QModelIndex mapping with mapToSource to determine which
+ * column in the proxy model maps to which column in the source. Its own
+ * mapping is always done in order; this means that it's easier if all
+ * the Views of this model keep the columns in the same relative order,
+ * but can omit columns. (If you really need to change the order,
+ * QHeaderView::swapSections() can be used.)
+ */
enum InterfaceTreeColumns
{
- IFTREE_COL_EXTCAP,
+ IFTREE_COL_EXTCAP, // InterfaceFrame interfaceTree
IFTREE_COL_EXTCAP_PATH,
- IFTREE_COL_NAME,
- IFTREE_COL_DESCRIPTION,
- IFTREE_COL_DISPLAY_NAME,
- IFTREE_COL_COMMENT,
- IFTREE_COL_HIDDEN,
+ IFTREE_COL_HIDDEN, // ManageInterfaceDialog localView
+ IFTREE_COL_DISPLAY_NAME, // InterfaceFrame interfaceTree
+ IFTREE_COL_DESCRIPTION, // ManageInterfaceDialog localView
+ IFTREE_COL_NAME, // ManageInterfaceDialog localView
+ IFTREE_COL_COMMENT, // ManageInterfaceDialog localView
+ IFTREE_COL_STATS, // InterfaceFrame interfaceTree
IFTREE_COL_DLT,
IFTREE_COL_PROMISCUOUSMODE,
IFTREE_COL_TYPE,
- IFTREE_COL_STATS,
IFTREE_COL_ACTIVE,
IFTREE_COL_SNAPLEN,
#ifdef CAN_SET_CAPTURE_BUFFER_SIZE
@@ -49,7 +58,7 @@ enum InterfaceTreeColumns
IFTREE_COL_MONITOR_MODE,
#endif
IFTREE_COL_CAPTURE_FILTER,
- IFTREE_COL_PIPE_PATH,
+ IFTREE_COL_PIPE_PATH, // ManageInterfaceDialog pipeView
IFTREE_COL_MAX /* is not being displayed, it is the definition for the maximum numbers of columns */
};
@@ -68,6 +77,7 @@ public:
void updateStatistic(unsigned int row);
#ifdef HAVE_LIBPCAP
+ void setCache(if_stat_cache_t *stat_cache);
void stopStatistic();
#endif
diff --git a/ui/qt/models/packet_list_model.cpp b/ui/qt/models/packet_list_model.cpp
index 0ed61d74..9bb81fb5 100644
--- a/ui/qt/models/packet_list_model.cpp
+++ b/ui/qt/models/packet_list_model.cpp
@@ -8,7 +8,6 @@
*/
#include <algorithm>
-#include <glib.h>
#include <cmath>
#include <stdexcept>
@@ -55,7 +54,7 @@ class SortAbort : public std::runtime_error
static PacketListModel * glbl_plist_model = Q_NULLPTR;
static const int reserved_packets_ = 100000;
-guint
+unsigned
packet_list_append(column_info *, frame_data *fdata)
{
if (!glbl_plist_model)
@@ -143,7 +142,7 @@ int PacketListModel::packetNumberToRow(int packet_num) const
return number_to_row_.value(packet_num) - 1;
}
-guint PacketListModel::recreateVisibleRows()
+unsigned PacketListModel::recreateVisibleRows()
{
beginResetModel();
visible_rows_.resize(0);
@@ -155,7 +154,7 @@ guint PacketListModel::recreateVisibleRows()
if (fdata->passed_dfilter || fdata->ref_time) {
visible_rows_ << record;
- if (static_cast<guint32>(number_to_row_.size()) <= fdata->num) {
+ if (static_cast<uint32_t>(number_to_row_.size()) <= fdata->num) {
number_to_row_.resize(fdata->num + 10000);
}
number_to_row_[fdata->num] = static_cast<int>(visible_rows_.count());
@@ -166,7 +165,7 @@ guint PacketListModel::recreateVisibleRows()
endInsertRows();
}
idle_dissection_row_ = 0;
- return static_cast<guint>(visible_rows_.count());
+ return static_cast<unsigned>(visible_rows_.count());
}
void PacketListModel::clear() {
@@ -186,26 +185,74 @@ void PacketListModel::clear() {
void PacketListModel::invalidateAllColumnStrings()
{
+ // https://bugreports.qt.io/browse/QTBUG-58580
+ // https://bugreports.qt.io/browse/QTBUG-124173
+ // https://codereview.qt-project.org/c/qt/qtbase/+/285280
+ //
+ // In Qt 6, QAbstractItemView::dataChanged determines how much of the
+ // viewport rectangle is covered by the changed indices and only updates
+ // that much. Unfortunately, if the number of indices is very large,
+ // computing the union of the intersecting rectangle takes much longer
+ // than unconditionally updating the entire viewport. It increases linearly
+ // with the total number of packets in the list, unlike updating the
+ // viewport, which scales with the size of the viewport but is unaffected
+ // by undisplayed packets.
+ //
+ // In particular, if the data for all of the model is invalidated, we
+ // know we want to update the entire viewport and very much do not
+ // want to waste time calculating the affected area. (This can take
+ // 1 s with 1.4 M packets, 9 s with 12 M packets.)
+ //
+ // Issuing layoutAboutToBeChanged() and layoutChanged() causes the
+ // QTreeView to clear all the information for each of the view items,
+ // but without clearing the current and selected items (unlike
+ // [begin|end]ResetModel.)
+ //
+ // Theoretically this is less efficient because dataChanged() has a list
+ // of what roles changed and the other signals do not; in practice,
+ // neither QTreeView::dataChanged nor QAbstractItemView::dataChanged
+ // actually use the roles parameter, and just reset everything.
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ emit layoutAboutToBeChanged();
+#endif
PacketListRecord::invalidateAllRecords();
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ emit layoutChanged();
+#else
emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1),
QVector<int>() << Qt::DisplayRole);
+#endif
}
void PacketListModel::resetColumns()
{
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ emit layoutAboutToBeChanged();
+#endif
if (cap_file_) {
PacketListRecord::resetColumns(&cap_file_->cinfo);
}
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ emit layoutChanged();
+#else
emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));
+#endif
emit headerDataChanged(Qt::Horizontal, 0, columnCount() - 1);
}
void PacketListModel::resetColorized()
{
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ emit layoutAboutToBeChanged();
+#endif
PacketListRecord::resetColorization();
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ emit layoutChanged();
+#else
emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1),
QVector<int>() << Qt::BackgroundRole << Qt::ForegroundRole);
+#endif
}
void PacketListModel::toggleFrameMark(const QModelIndexList &indeces)
@@ -237,8 +284,11 @@ void PacketListModel::toggleFrameMark(const QModelIndexList &indeces)
}
}
-void PacketListModel::setDisplayedFrameMark(gboolean set)
+void PacketListModel::setDisplayedFrameMark(bool set)
{
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ emit layoutAboutToBeChanged();
+#endif
foreach (PacketListRecord *record, visible_rows_) {
if (set) {
cf_mark_frame(cap_file_, record->frameData());
@@ -246,8 +296,12 @@ void PacketListModel::setDisplayedFrameMark(gboolean set)
cf_unmark_frame(cap_file_, record->frameData());
}
}
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ emit layoutChanged();
+#else
emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1),
QVector<int>() << Qt::BackgroundRole << Qt::ForegroundRole);
+#endif
}
void PacketListModel::toggleFrameIgnore(const QModelIndexList &indeces)
@@ -279,8 +333,11 @@ void PacketListModel::toggleFrameIgnore(const QModelIndexList &indeces)
}
}
-void PacketListModel::setDisplayedFrameIgnore(gboolean set)
+void PacketListModel::setDisplayedFrameIgnore(bool set)
{
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ emit layoutAboutToBeChanged();
+#endif
foreach (PacketListRecord *record, visible_rows_) {
if (set) {
cf_ignore_frame(cap_file_, record->frameData());
@@ -288,8 +345,12 @@ void PacketListModel::setDisplayedFrameIgnore(gboolean set)
cf_unignore_frame(cap_file_, record->frameData());
}
}
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ emit layoutChanged();
+#else
emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1),
QVector<int>() << Qt::BackgroundRole << Qt::ForegroundRole << Qt::DisplayRole);
+#endif
}
void PacketListModel::toggleFrameRefTime(const QModelIndex &rt_index)
@@ -302,6 +363,9 @@ void PacketListModel::toggleFrameRefTime(const QModelIndex &rt_index)
frame_data *fdata = record->frameData();
if (!fdata) return;
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ emit layoutAboutToBeChanged();
+#endif
if (fdata->ref_time) {
fdata->ref_time=0;
cap_file_->ref_time_count--;
@@ -332,7 +396,11 @@ void PacketListModel::unsetAllFrameRefTime()
cap_file_->ref_time_count = 0;
cf_reftime_packets(cap_file_);
PacketListRecord::resetColumns(&cap_file_->cinfo);
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ emit layoutChanged();
+#else
emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));
+#endif
}
void PacketListModel::addFrameComment(const QModelIndexList &indices, const QByteArray &comment)
@@ -378,7 +446,7 @@ void PacketListModel::addFrameComment(const QModelIndexList &indices, const QByt
}
}
-void PacketListModel::setFrameComment(const QModelIndex &index, const QByteArray &comment, guint c_number)
+void PacketListModel::setFrameComment(const QModelIndex &index, const QByteArray &comment, unsigned c_number)
{
int sectionMax = columnCount() - 1;
frame_data *fdata;
@@ -423,10 +491,10 @@ void PacketListModel::deleteFrameComments(const QModelIndexList &indices)
fdata = record->frameData();
wtap_block_t pkt_block = cf_get_packet_block(cap_file_, fdata);
- guint n_comments = wtap_block_count_option(pkt_block, OPT_COMMENT);
+ unsigned n_comments = wtap_block_count_option(pkt_block, OPT_COMMENT);
if (n_comments) {
- for (guint i = 0; i < n_comments; i++) {
+ for (unsigned i = 0; i < n_comments; i++) {
wtap_block_remove_nth_option_instance(pkt_block, OPT_COMMENT, 0);
}
if (!cf_set_modified_block(cap_file_, fdata, pkt_block)) {
@@ -453,10 +521,10 @@ void PacketListModel::deleteAllFrameComments()
foreach (PacketListRecord *record, physical_rows_) {
frame_data *fdata = record->frameData();
wtap_block_t pkt_block = cf_get_packet_block(cap_file_, fdata);
- guint n_comments = wtap_block_count_option(pkt_block, OPT_COMMENT);
+ unsigned n_comments = wtap_block_count_option(pkt_block, OPT_COMMENT);
if (n_comments) {
- for (guint i = 0; i < n_comments; i++) {
+ for (unsigned i = 0; i < n_comments; i++) {
wtap_block_remove_nth_option_instance(pkt_block, OPT_COMMENT, 0);
}
cf_set_modified_block(cap_file_, fdata, pkt_block);
@@ -488,7 +556,7 @@ int PacketListModel::sort_column_is_numeric_;
int PacketListModel::text_sort_column_;
Qt::SortOrder PacketListModel::sort_order_;
capture_file *PacketListModel::sort_cap_file_;
-gboolean PacketListModel::stop_flag_;
+bool PacketListModel::stop_flag_;
ProgressFrame *PacketListModel::progress_frame_;
double PacketListModel::comps_;
double PacketListModel::exp_comps_;
@@ -510,7 +578,7 @@ void PacketListModel::sort(int column, Qt::SortOrder order)
QString col_title = get_column_title(column);
- if (text_sort_column_ >= 0 && (guint)visible_rows_.count() > prefs.gui_packet_list_cached_rows_max) {
+ if (text_sort_column_ >= 0 && (unsigned)visible_rows_.count() > prefs.gui_packet_list_cached_rows_max) {
/* Column not based on frame data but by column text that requires
* dissection, so to sort in a reasonable amount of time the column
* text needs to be cached.
@@ -545,7 +613,7 @@ void PacketListModel::sort(int column, Qt::SortOrder order)
*/
return;
}
- sort_cap_file_->read_lock = TRUE;
+ sort_cap_file_->read_lock = true;
QString busy_msg;
if (!col_title.isEmpty()) {
@@ -553,7 +621,7 @@ void PacketListModel::sort(int column, Qt::SortOrder order)
} else {
busy_msg = tr("Sorting …");
}
- stop_flag_ = FALSE;
+ stop_flag_ = false;
comps_ = 0;
/* XXX: The expected number of comparisons is O(N log N), but this could
* be a pretty significant overestimate of the amount of time it takes,
@@ -603,7 +671,7 @@ void PacketListModel::sort(int column, Qt::SortOrder order)
disconnect(progress_frame_, &ProgressFrame::stopLoading,
this, &PacketListModel::stopSorting);
}
- sort_cap_file_->read_lock = FALSE;
+ sort_cap_file_->read_lock = false;
if (cap_file_->current_frame) {
emit goToPacket(cap_file_->current_frame->num);
@@ -612,11 +680,14 @@ void PacketListModel::sort(int column, Qt::SortOrder order)
void PacketListModel::stopSorting()
{
- stop_flag_ = TRUE;
+ stop_flag_ = true;
}
bool PacketListModel::isNumericColumn(int column)
{
+ /* XXX - Should this and ui/packet_list_utils.c right_justify_column()
+ * be the same list of columns?
+ */
if (column < 0) {
return false;
}
@@ -651,10 +722,19 @@ bool PacketListModel::isNumericColumn(int column)
return false;
}
- guint num_fields = g_slist_length(sort_cap_file_->cinfo.columns[column].col_custom_fields_ids);
- for (guint i = 0; i < num_fields; i++) {
- guint *field_idx = (guint *) g_slist_nth_data(sort_cap_file_->cinfo.columns[column].col_custom_fields_ids, i);
- header_field_info *hfi = proto_registrar_get_nth(*field_idx);
+ unsigned num_fields = g_slist_length(sort_cap_file_->cinfo.columns[column].col_custom_fields_ids);
+ col_custom_t *col_custom;
+ for (unsigned i = 0; i < num_fields; i++) {
+ col_custom = (col_custom_t *) g_slist_nth_data(sort_cap_file_->cinfo.columns[column].col_custom_fields_ids, i);
+ if (col_custom->field_id == 0) {
+ /* XXX - We need some way to check the compiled dfilter's expected
+ * return type. Best would be to use the actual field values return
+ * and sort on those (we could skip expensive string conversions
+ * in the numeric case, see below)
+ */
+ return false;
+ }
+ header_field_info *hfi = proto_registrar_get_nth(col_custom->field_id);
/*
* Reject a field when there is no numeric field type or when:
@@ -755,7 +835,7 @@ double PacketListModel::parseNumericColumn(const QString &val, bool *ok)
{
QByteArray ba = val.toUtf8();
const char *strval = ba.constData();
- gchar *end = NULL;
+ char *end = NULL;
double num = g_ascii_strtod(strval, &end);
*ok = strval != end;
return num;
@@ -802,13 +882,10 @@ QVariant PacketListModel::data(const QModelIndex &d_index, int role) const
switch(recent_get_column_xalign(d_index.column())) {
case COLUMN_XALIGN_RIGHT:
return Qt::AlignRight;
- break;
case COLUMN_XALIGN_CENTER:
return Qt::AlignCenter;
- break;
case COLUMN_XALIGN_LEFT:
return Qt::AlignLeft;
- break;
case COLUMN_XALIGN_DEFAULT:
default:
if (right_justify_column(d_index.column(), cap_file_)) {
@@ -926,6 +1003,12 @@ void PacketListModel::dissectIdle(bool reset)
idle_dissection_timer_->restart();
+ if (!cap_file_ || cap_file_->read_lock) {
+ // File is in use (at worst, being rescanned). Try again later.
+ QTimer::singleShot(idle_dissection_interval_, this, [=]() { dissectIdle(); });
+ return;
+ }
+
int first = idle_dissection_row_;
while (idle_dissection_timer_->elapsed() < idle_dissection_interval_
&& idle_dissection_row_ < physical_rows_.count()) {
@@ -946,7 +1029,7 @@ void PacketListModel::dissectIdle(bool reset)
// XXX Pass in cinfo from packet_list_append so that we can fill in
// line counts?
-gint PacketListModel::appendPacket(frame_data *fdata)
+int PacketListModel::appendPacket(frame_data *fdata)
{
PacketListRecord *record = new PacketListRecord(fdata);
qsizetype pos = -1;
@@ -969,17 +1052,19 @@ gint PacketListModel::appendPacket(frame_data *fdata)
pos = static_cast<int>( visible_rows_.count() + new_visible_rows_.count() ) - 1;
}
- return static_cast<gint>(pos);
+ emit packetAppended(cap_file_, fdata, physical_rows_.size() - 1);
+
+ return static_cast<int>(pos);
}
-frame_data *PacketListModel::getRowFdata(QModelIndex idx)
+frame_data *PacketListModel::getRowFdata(QModelIndex idx) const
{
if (!idx.isValid())
return Q_NULLPTR;
return getRowFdata(idx.row());
}
-frame_data *PacketListModel::getRowFdata(int row) {
+frame_data *PacketListModel::getRowFdata(int row) const {
if (row < 0 || row >= visible_rows_.count())
return NULL;
PacketListRecord *record = visible_rows_[row];
@@ -1002,13 +1087,8 @@ void PacketListModel::ensureRowColorized(int row)
int PacketListModel::visibleIndexOf(frame_data *fdata) const
{
- int row = 0;
- foreach (PacketListRecord *record, visible_rows_) {
- if (record->frameData() == fdata) {
- return row;
- }
- row++;
+ if (fdata == nullptr) {
+ return -1;
}
-
- return -1;
+ return packetNumberToRow(fdata->num);
}
diff --git a/ui/qt/models/packet_list_model.h b/ui/qt/models/packet_list_model.h
index 807d8847..c4a4acf4 100644
--- a/ui/qt/models/packet_list_model.h
+++ b/ui/qt/models/packet_list_model.h
@@ -14,8 +14,6 @@
#include <stdio.h>
-#include <glib.h>
-
#include <epan/packet.h>
#include <QAbstractItemModel>
@@ -46,7 +44,7 @@ public:
const QModelIndex & = QModelIndex()) const;
QModelIndex parent(const QModelIndex &) const;
int packetNumberToRow(int packet_num) const;
- guint recreateVisibleRows();
+ unsigned recreateVisibleRows();
void clear();
int rowCount(const QModelIndex &parent = QModelIndex()) const;
@@ -54,9 +52,9 @@ public:
QVariant data(const QModelIndex &d_index, int role) const;
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
- gint appendPacket(frame_data *fdata);
- frame_data *getRowFdata(QModelIndex idx);
- frame_data *getRowFdata(int row);
+ int appendPacket(frame_data *fdata);
+ frame_data *getRowFdata(QModelIndex idx) const;
+ frame_data *getRowFdata(int row) const;
void ensureRowColorized(int row);
int visibleIndexOf(frame_data *fdata) const;
/**
@@ -69,19 +67,20 @@ public:
void resetColumns();
void resetColorized();
void toggleFrameMark(const QModelIndexList &indeces);
- void setDisplayedFrameMark(gboolean set);
+ void setDisplayedFrameMark(bool set);
void toggleFrameIgnore(const QModelIndexList &indeces);
- void setDisplayedFrameIgnore(gboolean set);
+ void setDisplayedFrameIgnore(bool set);
void toggleFrameRefTime(const QModelIndex &rt_index);
void unsetAllFrameRefTime();
void addFrameComment(const QModelIndexList &indices, const QByteArray &comment);
- void setFrameComment(const QModelIndex &index, const QByteArray &comment, guint c_number);
+ void setFrameComment(const QModelIndex &index, const QByteArray &comment, unsigned c_number);
void deleteFrameComments(const QModelIndexList &indices);
void deleteAllFrameComments();
void setMaximumRowHeight(int height);
signals:
+ void packetAppended(capture_file *cap_file, frame_data *fdata, qsizetype row);
void goToPacket(int);
void maxLineCountChanged(const QModelIndex &ih_index) const;
void itemHeightChanged(const QModelIndex &ih_index);
@@ -113,7 +112,7 @@ private:
static bool recordLessThan(PacketListRecord *r1, PacketListRecord *r2);
static double parseNumericColumn(const QString &val, bool *ok);
- static gboolean stop_flag_;
+ static bool stop_flag_;
static ProgressFrame *progress_frame_;
static double exp_comps_;
static double comps_;
diff --git a/ui/qt/models/packet_list_record.cpp b/ui/qt/models/packet_list_record.cpp
index 9c2c66d1..3cba64d5 100644
--- a/ui/qt/models/packet_list_record.cpp
+++ b/ui/qt/models/packet_list_record.cpp
@@ -24,7 +24,7 @@
#include <QStringList>
-QCache<guint32, QStringList> PacketListRecord::col_text_cache_(500);
+QCache<uint32_t, QStringList> PacketListRecord::col_text_cache_(500);
QMap<int, int> PacketListRecord::cinfo_column_;
unsigned PacketListRecord::rows_color_ver_ = 1;
@@ -112,7 +112,7 @@ void PacketListRecord::dissect(capture_file *cap_file, bool dissect_columns, boo
// packet_list_store.c:packet_list_dissect_and_cache_record
epan_dissect_t edt;
column_info *cinfo = NULL;
- gboolean create_proto_tree;
+ bool create_proto_tree;
wtap_rec rec; /* Record metadata */
Buffer buf; /* Record data */
@@ -144,7 +144,7 @@ void PacketListRecord::dissect(capture_file *cap_file, bool dissect_columns, boo
* error message.
*/
if (dissect_columns) {
- col_fill_in_error(cinfo, fdata_, FALSE, FALSE /* fill_fd_columns */);
+ col_fill_in_error(cinfo, fdata_, false, false /* fill_fd_columns */);
cacheColumnStrings(cinfo);
}
@@ -175,7 +175,7 @@ void PacketListRecord::dissect(capture_file *cap_file, bool dissect_columns, boo
epan_dissect_init(&edt, cap_file->epan,
create_proto_tree,
- FALSE /* proto_tree_visible */);
+ false /* proto_tree_visible */);
/* Re-color when the coloring rules are changed via the UI. */
if (dissect_color) {
@@ -195,7 +195,7 @@ void PacketListRecord::dissect(capture_file *cap_file, bool dissect_columns, boo
if (dissect_columns) {
/* "Stringify" non frame_data vals */
- epan_dissect_fill_in_columns(&edt, FALSE, FALSE /* fill_fd_columns */);
+ epan_dissect_fill_in_columns(&edt, false, false /* fill_fd_columns */);
cacheColumnStrings(cinfo);
}
@@ -204,7 +204,8 @@ void PacketListRecord::dissect(capture_file *cap_file, bool dissect_columns, boo
color_ver_ = rows_color_ver_;
}
- struct conversation * conv = find_conversation_pinfo(&edt.pi, 0);
+ struct conversation * conv = find_conversation_pinfo_ro(&edt.pi, 0);
+
conv_index_ = ! conv ? 0 : conv->conv_index;
epan_dissect_cleanup(&edt);
@@ -214,7 +215,7 @@ void PacketListRecord::dissect(capture_file *cap_file, bool dissect_columns, boo
void PacketListRecord::cacheColumnStrings(column_info *cinfo)
{
- // packet_list_store.c:packet_list_change_record(PacketList *packet_list, PacketListRecord *record, gint col, column_info *cinfo)
+ // packet_list_store.c:packet_list_change_record(PacketList *packet_list, PacketListRecord *record, int col, column_info *cinfo)
if (!cinfo) {
return;
}
@@ -230,7 +231,7 @@ void PacketListRecord::cacheColumnStrings(column_info *cinfo)
QString col_str;
int text_col = cinfo_column_.value(column, -1);
if (text_col < 0) {
- col_fill_in_frame_data(fdata_, cinfo, column, FALSE);
+ col_fill_in_frame_data(fdata_, cinfo, column, false);
}
col_str = QString(get_column_text(cinfo, column));
diff --git a/ui/qt/models/packet_list_record.h b/ui/qt/models/packet_list_record.h
index 47aa5621..7bb582fa 100644
--- a/ui/qt/models/packet_list_record.h
+++ b/ui/qt/models/packet_list_record.h
@@ -12,8 +12,6 @@
#include <config.h>
-#include <glib.h>
-
#include "cfile.h"
#include <epan/column.h>
@@ -60,7 +58,7 @@ public:
private:
/** The column text for some columns */
- static QCache<guint32, QStringList> col_text_cache_;
+ static QCache<uint32_t, QStringList> col_text_cache_;
frame_data *fdata_;
int lines_;
diff --git a/ui/qt/models/pref_delegate.cpp b/ui/qt/models/pref_delegate.cpp
index e33bb13f..313c17dc 100644
--- a/ui/qt/models/pref_delegate.cpp
+++ b/ui/qt/models/pref_delegate.cpp
@@ -66,7 +66,7 @@ void AdvancedPrefDelegate::setEditorData(QWidget *editor, const QModelIndex &ind
return;
}
- Q_ASSERT(FALSE);
+ Q_ASSERT(false);
}
void AdvancedPrefDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
@@ -81,5 +81,5 @@ void AdvancedPrefDelegate::setModelData(QWidget *editor, QAbstractItemModel *mod
return;
}
- Q_ASSERT(FALSE);
+ Q_ASSERT(false);
}
diff --git a/ui/qt/models/pref_models.cpp b/ui/qt/models/pref_models.cpp
index b86230f0..3480a8db 100644
--- a/ui/qt/models/pref_models.cpp
+++ b/ui/qt/models/pref_models.cpp
@@ -23,10 +23,10 @@
#include <QApplication>
// XXX Should we move this to ui/preference_utils?
-static GHashTable * pref_ptr_to_pref_ = NULL;
+static GHashTable * pref_ptr_to_pref_;
pref_t *prefFromPrefPtr(void *pref_ptr)
{
- return (pref_t *)g_hash_table_lookup(pref_ptr_to_pref_, (gpointer) pref_ptr);
+ return (pref_t *)g_hash_table_lookup(pref_ptr_to_pref_, (void *) pref_ptr);
}
static void prefInsertPrefPtr(void * pref_ptr, pref_t * pref)
@@ -34,8 +34,8 @@ static void prefInsertPrefPtr(void * pref_ptr, pref_t * pref)
if (! pref_ptr_to_pref_)
pref_ptr_to_pref_ = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
- gpointer key = (gpointer) pref_ptr;
- gpointer val = (gpointer) pref;
+ void *key = (void *) pref_ptr;
+ void *val = (void *) pref;
/* Already existing entries will be ignored */
if ((void *)g_hash_table_lookup(pref_ptr_to_pref_, key) == NULL)
@@ -47,6 +47,7 @@ PrefsItem::PrefsItem(module_t *module, pref_t *pref, PrefsItem* parent)
pref_(pref),
module_(module),
name_(module->name ? module->name : module->parent->name),
+ help_(QString()),
changed_(false)
{
if (pref_ != NULL) {
@@ -59,9 +60,19 @@ PrefsItem::PrefsItem(const QString name, PrefsItem* parent)
pref_(NULL),
module_(NULL),
name_(name),
+ help_(QString()),
changed_(false)
{
+}
+PrefsItem::PrefsItem(PrefsModel::PrefsModelType type, PrefsItem* parent)
+ : ModelHelperTreeItem<PrefsItem>(parent),
+ pref_(NULL),
+ module_(NULL),
+ name_(PrefsModel::typeToString(type)),
+ help_(PrefsModel::typeToHelp(type)),
+ changed_(false)
+{
}
PrefsItem::~PrefsItem()
@@ -113,6 +124,20 @@ QString PrefsItem::getModuleTitle() const
return QString(module_->title);
}
+QString PrefsItem::getModuleHelp() const
+{
+ if (module_ == nullptr)
+ return help_;
+
+ module_t *pref_module = module_;
+
+ while (pref_module->help == nullptr && pref_module->parent) {
+ pref_module = pref_module->parent;
+ }
+
+ return pref_module->help;
+}
+
void PrefsItem::setChanged(bool changed)
{
changed_ = changed;
@@ -232,8 +257,8 @@ QVariant PrefsModel::data(const QModelIndex &index, int role) const
return QVariant();
}
-static guint
-fill_prefs(module_t *module, gpointer root_ptr)
+static unsigned
+fill_prefs(module_t *module, void *root_ptr)
{
PrefsItem* root_item = static_cast<PrefsItem*>(root_ptr);
@@ -275,32 +300,32 @@ fill_prefs(module_t *module, gpointer root_ptr)
void PrefsModel::populate()
{
- prefs_modules_foreach_submodules(NULL, fill_prefs, (gpointer)root_);
+ prefs_modules_foreach_submodules(NULL, fill_prefs, (void *)root_);
//Add the "specially handled" preferences
PrefsItem *appearance_item, *appearance_subitem, *special_item;
- appearance_item = new PrefsItem(typeToString(PrefsModel::Appearance), root_);
+ appearance_item = new PrefsItem(PrefsModel::Appearance, root_);
root_->prependChild(appearance_item);
- appearance_subitem = new PrefsItem(typeToString(PrefsModel::Layout), appearance_item);
+ appearance_subitem = new PrefsItem(PrefsModel::Layout, appearance_item);
appearance_item->prependChild(appearance_subitem);
- appearance_subitem = new PrefsItem(typeToString(PrefsModel::Columns), appearance_item);
+ appearance_subitem = new PrefsItem(PrefsModel::Columns, appearance_item);
appearance_item->prependChild(appearance_subitem);
- appearance_subitem = new PrefsItem(typeToString(PrefsModel::FontAndColors), appearance_item);
+ appearance_subitem = new PrefsItem(PrefsModel::FontAndColors, appearance_item);
appearance_item->prependChild(appearance_subitem);
- special_item = new PrefsItem(typeToString(PrefsModel::Capture), root_);
+ special_item = new PrefsItem(PrefsModel::Capture, root_);
root_->prependChild(special_item);
- special_item = new PrefsItem(typeToString(PrefsModel::Expert), root_);
+ special_item = new PrefsItem(PrefsModel::Expert, root_);
root_->prependChild(special_item);
- special_item = new PrefsItem(typeToString(PrefsModel::FilterButtons), root_);
+ special_item = new PrefsItem(PrefsModel::FilterButtons, root_);
root_->prependChild(special_item);
#ifdef HAVE_LIBGNUTLS
- special_item = new PrefsItem(typeToString(PrefsModel::RSAKeys), root_);
+ special_item = new PrefsItem(PrefsModel::RSAKeys, root_);
root_->prependChild(special_item);
#endif
- special_item = new PrefsItem(typeToString(PrefsModel::Advanced), root_);
+ special_item = new PrefsItem(PrefsModel::Advanced, root_);
root_->prependChild(special_item);
}
@@ -324,6 +349,44 @@ QString PrefsModel::typeToString(int type)
return typeStr;
}
+QString PrefsModel::typeToHelp(int type)
+{
+ QString helpStr;
+
+ switch(type)
+ {
+ case Appearance:
+ helpStr = QString("ChCustPreferencesSection.html#_appearance");
+ break;
+ case Columns:
+ helpStr = QString("ChCustPreferencesSection.html#_columns");
+ break;
+ case FontAndColors:
+ helpStr = QString("ChCustPreferencesSection.html#_font_and_colors");
+ break;
+ case Layout:
+ helpStr = QString("ChCustPreferencesSection.html#_layout");
+ break;
+ case Capture:
+ helpStr = QString("ChCustPreferencesSection.html#_capture");
+ break;
+ case Expert:
+ helpStr = QString("ChCustPreferencesSection.html#ChCustPrefsExpertSection");
+ break;
+ case FilterButtons:
+ helpStr = QString("ChCustPreferencesSection.html#ChCustFilterButtons");
+ break;
+ case RSAKeys:
+ helpStr = QString("ChCustPreferencesSection.html#ChCustPrefsRSASection");
+ break;
+ case Advanced:
+ helpStr = QString("ChCustPreferencesSection.html#_advanced");
+ break;
+ }
+
+ return helpStr;
+}
+
AdvancedPrefsModel::AdvancedPrefsModel(QObject * parent)
: QSortFilterProxyModel(parent),
filter_(),
@@ -470,11 +533,10 @@ bool AdvancedPrefsModel::setData(const QModelIndex &dataindex, const QVariant &v
item->setChanged(true);
switch (item->getPrefType())
{
- case PREF_DECODE_AS_UINT:
case PREF_UINT:
{
bool ok;
- guint new_val = value.toString().toUInt(&ok, prefs_get_uint_base(item->getPref()));
+ unsigned new_val = value.toString().toUInt(&ok, prefs_get_uint_base(item->getPref()));
if (ok)
prefs_set_uint_value(item->getPref(), new_val, pref_stashed);
@@ -487,6 +549,7 @@ bool AdvancedPrefsModel::setData(const QModelIndex &dataindex, const QVariant &v
prefs_set_enum_value(item->getPref(), value.toInt(), pref_stashed);
break;
case PREF_STRING:
+ case PREF_DISSECTOR:
prefs_set_string_value(item->getPref(), value.toString().toStdString().c_str(), pref_stashed);
break;
case PREF_PASSWORD:
@@ -543,7 +606,7 @@ Qt::ItemFlags AdvancedPrefsModel::flags(const QModelIndex &index) const
Qt::ItemFlags flags = QAbstractItemModel::flags(index);
if (item->getPref() == NULL) {
- /* Base modules aren't changable */
+ /* Base modules aren't changeable */
flags &= ~(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
} else {
flags |= Qt::ItemIsEditable;
@@ -683,6 +746,8 @@ QVariant ModulePrefsModel::data(const QModelIndex &dataindex, int role) const
return sourceModel()->data(modelIndex, role);
case ModuleName:
return item->getModuleName();
+ case ModuleHelp:
+ return item->getModuleHelp();
default:
break;
}
diff --git a/ui/qt/models/pref_models.h b/ui/qt/models/pref_models.h
index 775da0d0..601c7623 100644
--- a/ui/qt/models/pref_models.h
+++ b/ui/qt/models/pref_models.h
@@ -19,32 +19,7 @@
#include <QSortFilterProxyModel>
#include <QTreeView>
-class PrefsItem : public ModelHelperTreeItem<PrefsItem>
-{
-public:
- PrefsItem(module_t *module, pref_t *pref, PrefsItem* parent);
- PrefsItem(const QString name, PrefsItem* parent);
- virtual ~PrefsItem();
-
- QString getName() const {return name_;}
- pref_t* getPref() const {return pref_;}
- int getPrefType() const;
- bool isPrefDefault() const;
- QString getPrefTypeName() const;
- module_t* getModule() const {return module_;}
- QString getModuleName() const;
- QString getModuleTitle() const;
- void setChanged(bool changed = true);
-
-private:
- pref_t *pref_;
- module_t *module_;
- QString name_;
- //set to true if changed during module manipulation
- //Used to determine proper "default" for comparison
- bool changed_;
-};
-
+class PrefsItem;
class PrefsModel : public QAbstractItemModel
{
@@ -83,6 +58,7 @@ public:
int columnCount(const QModelIndex &parent = QModelIndex()) const;
static QString typeToString(int type);
+ static QString typeToHelp(int type);
private:
void populate();
@@ -90,6 +66,35 @@ private:
PrefsItem* root_;
};
+class PrefsItem : public ModelHelperTreeItem<PrefsItem>
+{
+public:
+ PrefsItem(module_t *module, pref_t *pref, PrefsItem* parent);
+ PrefsItem(const QString name, PrefsItem* parent);
+ PrefsItem(PrefsModel::PrefsModelType type, PrefsItem* parent);
+ virtual ~PrefsItem();
+
+ QString getName() const {return name_;}
+ pref_t* getPref() const {return pref_;}
+ int getPrefType() const;
+ bool isPrefDefault() const;
+ QString getPrefTypeName() const;
+ module_t* getModule() const {return module_;}
+ QString getModuleName() const;
+ QString getModuleTitle() const;
+ QString getModuleHelp() const;
+ void setChanged(bool changed = true);
+
+private:
+ pref_t *pref_;
+ module_t *module_;
+ QString name_;
+ QString help_;
+ //set to true if changed during module manipulation
+ //Used to determine proper "default" for comparison
+ bool changed_;
+};
+
class AdvancedPrefsModel : public QSortFilterProxyModel
{
Q_OBJECT
@@ -143,7 +148,8 @@ public:
};
enum ModulePrefsRoles {
- ModuleName = Qt::UserRole + 1
+ ModuleName = Qt::UserRole + 1,
+ ModuleHelp = Qt::UserRole + 2
};
QVariant data(const QModelIndex &index, int role) const;
diff --git a/ui/qt/models/profile_model.cpp b/ui/qt/models/profile_model.cpp
index 206ef389..ecbcef6b 100644
--- a/ui/qt/models/profile_model.cpp
+++ b/ui/qt/models/profile_model.cpp
@@ -11,12 +11,13 @@
#include <errno.h>
-#include "glib.h"
#include "ui/profile.h"
#include "ui/recent.h"
-#include "wsutil/filesystem.h"
#include "epan/prefs.h"
+#include "wsutil/filesystem.h"
+#include "wsutil/utf8_entities.h"
+
#include <ui/qt/models/profile_model.h>
#include <ui/qt/utils/color_utils.h>
@@ -276,6 +277,14 @@ QVariant ProfileModel::dataDisplay(const QModelIndex &index) const
return tr("Global");
else
return tr("Personal");
+ case COL_AUTO_SWITCH_FILTER:
+ {
+ if (prof->is_global) {
+ return QString(UTF8_EM_DASH);
+ }
+ return (QString(prof->auto_switch_filter));
+ }
+
default:
break;
}
@@ -426,7 +435,7 @@ QVariant ProfileModel::dataBackgroundRole(const QModelIndex &index) const
if (prof->status != PROF_STAT_DEFAULT && ! prof->is_global)
{
- /* Highlights errorneous line */
+ /* Highlights erroneous line */
if (checkInvalid(index) || checkIfDeleted(index) || checkDuplicate(index) || ! checkNameValidity(prof->name))
return ColorUtils::fromColorT(&prefs.gui_text_invalid);
@@ -438,6 +447,23 @@ QVariant ProfileModel::dataBackgroundRole(const QModelIndex &index) const
return QVariant();
}
+QVariant ProfileModel::dataForegroundRole(const QModelIndex &index) const
+{
+ if (! index.isValid() || profiles_.count() <= index.row())
+ return QVariant();
+
+ profile_def * prof = guard(index.row());
+ if (! prof) {
+ return QVariant();
+ }
+
+ if (prof->is_global && index.column() == COL_AUTO_SWITCH_FILTER) {
+ return ColorUtils::disabledForeground();
+ }
+
+ return QVariant();
+}
+
QVariant ProfileModel::dataToolTipRole(const QModelIndex &idx) const
{
if (! idx.isValid() || profiles_.count() <= idx.row())
@@ -492,7 +518,7 @@ QVariant ProfileModel::dataPath(const QModelIndex &index) const
{
case PROF_STAT_DEFAULT:
if (!reset_default_)
- return gchar_free_to_qstring(get_persconffile_path("", FALSE));
+ return gchar_free_to_qstring(get_persconffile_path("", false));
else
return tr("Resetting to default");
case PROF_STAT_EXISTS:
@@ -537,7 +563,7 @@ QVariant ProfileModel::dataPath(const QModelIndex &index) const
QString appendix;
/* A global profile is neither deleted or removed, only system provided is allowed as appendix */
- if (profile_exists(prof->reference, TRUE) && prof->from_global)
+ if (profile_exists(prof->reference, true) && prof->from_global)
appendix = tr("system provided");
/* A default model as reference can neither be deleted or renamed, so skip if the reference was one */
else if (! index.data(ProfileModel::DATA_IS_DEFAULT).toBool())
@@ -588,6 +614,8 @@ QVariant ProfileModel::data(const QModelIndex &index, int role) const
return dataFontRole(index);
case Qt::BackgroundRole:
return dataBackgroundRole(index);
+ case Qt::ForegroundRole:
+ return dataForegroundRole(index);
case Qt::ToolTipRole:
return dataToolTipRole(index);
case ProfileModel::DATA_STATUS:
@@ -612,10 +640,6 @@ QVariant ProfileModel::data(const QModelIndex &index, int role) const
}
case ProfileModel::DATA_PATH:
return dataPath(index);
- case ProfileModel::DATA_INDEX_VALUE_IS_URL:
- if (index.column() <= ProfileModel::COL_TYPE)
- return QVariant::fromValue(false);
- return QVariant::fromValue(true);
case ProfileModel::DATA_PATH_IS_NOT_DESCRIPTION:
if (prof->status == PROF_STAT_NEW || prof->status == PROF_STAT_COPY
|| (prof->status == PROF_STAT_DEFAULT && reset_default_)
@@ -641,6 +665,8 @@ QVariant ProfileModel::headerData(int section, Qt::Orientation orientation, int
return tr("Profile");
case COL_TYPE:
return tr("Type");
+ case COL_AUTO_SWITCH_FILTER:
+ return tr("Auto Switch Filter");
default:
break;
}
@@ -654,11 +680,18 @@ Qt::ItemFlags ProfileModel::flags(const QModelIndex &index) const
Qt::ItemFlags fl = QAbstractTableModel::flags(index);
profile_def * prof = guard(index);
- if (! prof)
+ if (! prof) {
return fl;
+ }
- if (index.column() == ProfileModel::COL_NAME && prof->status != PROF_STAT_DEFAULT && ! prof->is_global)
+ if (prof->is_global) {
+ return fl;
+ }
+
+ if ((index.column() == ProfileModel::COL_NAME && prof->status != PROF_STAT_DEFAULT)
+ || (index.column() == ProfileModel::COL_AUTO_SWITCH_FILTER)) {
fl |= Qt::ItemIsEditable;
+ }
return fl;
}
@@ -722,7 +755,7 @@ QModelIndex ProfileModel::addNewProfile(QString name)
cnt++;
}
- add_to_profile_list(newName.toUtf8().constData(), newName.toUtf8().constData(), PROF_STAT_NEW, FALSE, FALSE, FALSE);
+ add_to_profile_list(newName.toUtf8().constData(), newName.toUtf8().constData(), PROF_STAT_NEW, false, false, false);
loadProfiles();
return index(findByName(newName), COL_NAME);
@@ -794,7 +827,7 @@ QModelIndex ProfileModel::duplicateEntry(QModelIndex idx, int new_status)
new_status = PROF_STAT_NEW;
/* add element */
- add_to_profile_list(new_name.toUtf8().constData(), parent.toUtf8().constData(), new_status, FALSE, prof->from_global ? prof->from_global : prof->is_global, FALSE);
+ add_to_profile_list(new_name.toUtf8().constData(), parent.toUtf8().constData(), new_status, false, prof->from_global ? prof->from_global : prof->is_global, false);
/* reload profile list in model */
loadProfiles();
@@ -901,27 +934,41 @@ bool ProfileModel::setData(const QModelIndex &idx, const QVariant &value, int ro
{
last_set_row_ = -1;
- if (role != Qt::EditRole || ! value.isValid() || value.toString().isEmpty())
+ if (role != Qt::EditRole || !value.isValid()) {
return false;
+ }
+
+ if (idx.column() == COL_NAME && value.toString().isEmpty()) {
+ return false;
+ }
QString newValue = value.toString();
profile_def * prof = guard(idx);
- if (! prof || prof->status == PROF_STAT_DEFAULT)
+
+ if (!prof) {
return false;
+ }
last_set_row_ = idx.row();
- QString current(prof->name);
- if (current.compare(newValue) != 0)
- {
- g_free(prof->name);
- prof->name = qstring_strdup(newValue);
+ if (idx.column() == COL_NAME && prof->status != PROF_STAT_DEFAULT) {
+ QString current(prof->name);
+ if (current.compare(newValue) != 0)
+ {
+ g_free(prof->name);
+ prof->name = qstring_strdup(newValue);
- if (prof->reference && g_strcmp0(prof->name, prof->reference) == 0 && ! (prof->status == PROF_STAT_NEW || prof->status == PROF_STAT_COPY)) {
- prof->status = PROF_STAT_EXISTS;
- } else if (prof->status == PROF_STAT_EXISTS) {
- prof->status = PROF_STAT_CHANGED;
+ if (prof->reference && g_strcmp0(prof->name, prof->reference) == 0 && ! (prof->status == PROF_STAT_NEW || prof->status == PROF_STAT_COPY)) {
+ prof->status = PROF_STAT_EXISTS;
+ } else if (prof->status == PROF_STAT_EXISTS) {
+ prof->status = PROF_STAT_CHANGED;
+ }
+ emit itemChanged(idx);
}
+ } else if (idx.column() == COL_AUTO_SWITCH_FILTER) {
+ g_free(prof->auto_switch_filter);
+ prof->auto_switch_filter = qstring_strdup(newValue);
+ prof->prefs_changed = true;
emit itemChanged(idx);
}
@@ -1033,7 +1080,7 @@ QFileInfoList ProfileModel::filterProfilePath(QString path, QFileInfoList ent, b
return result;
}
-#ifdef HAVE_MINIZIP
+#if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG)
QStringList ProfileModel::exportFileList(QModelIndexList items)
{
QStringList result;
@@ -1163,7 +1210,7 @@ int ProfileModel::importProfilesFromDir(QString dirname, int * skippedCnt, bool
if (success)
{
count++;
- add_to_profile_list(fentry.fileName().toUtf8().constData(), fentry.fileName().toUtf8().constData(), PROF_STAT_NEW, FALSE, FALSE, TRUE);
+ add_to_profile_list(fentry.fileName().toUtf8().constData(), fentry.fileName().toUtf8().constData(), PROF_STAT_NEW, false, false, true);
}
else if (! wasEmpty && QFile::exists(profilePath))
{
diff --git a/ui/qt/models/profile_model.h b/ui/qt/models/profile_model.h
index 16febd70..ff054752 100644
--- a/ui/qt/models/profile_model.h
+++ b/ui/qt/models/profile_model.h
@@ -11,7 +11,6 @@
#define PROFILE_MODEL_H
#include "config.h"
-#include "glib.h"
#include <ui/profile.h>
@@ -59,6 +58,7 @@ public:
enum {
COL_NAME,
COL_TYPE,
+ COL_AUTO_SWITCH_FILTER,
_LAST_ENTRY
} columns_;
@@ -69,7 +69,6 @@ public:
DATA_IS_SELECTED,
DATA_PATH,
DATA_PATH_IS_NOT_DESCRIPTION,
- DATA_INDEX_VALUE_IS_URL
} data_values_;
// QAbstractItemModel interface
@@ -101,7 +100,7 @@ public:
bool userProfilesExist() const;
-#ifdef HAVE_MINIZIP
+#if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG)
bool exportProfiles(QString filename, QModelIndexList items, QString * err = Q_NULLPTR);
int importProfilesFromZip(QString filename, int *skippedCnt = Q_NULLPTR, QStringList *result = Q_NULLPTR);
#endif
@@ -142,7 +141,7 @@ private:
int findByNameAndVisibility(QString name, bool isGlobal = false, bool searchReference = false) const;
int findAsReference(QString reference) const;
-#ifdef HAVE_MINIZIP
+#if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG)
static bool acceptFile(QString fileName, int fileSize);
static QString cleanName(QString fileName);
#endif
@@ -150,10 +149,11 @@ private:
QVariant dataDisplay(const QModelIndex & idx) const;
QVariant dataFontRole(const QModelIndex & idx) const;
QVariant dataBackgroundRole(const QModelIndex & idx) const;
+ QVariant dataForegroundRole(const QModelIndex & idx) const;
QVariant dataToolTipRole(const QModelIndex & idx) const;
QVariant dataPath(const QModelIndex & idx) const;
-#ifdef HAVE_MINIZIP
+#if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG)
QStringList exportFileList(QModelIndexList items);
#endif
bool copyTempToProfile(QString tempPath, QString profilePath, bool *wasEmpty = Q_NULLPTR);
diff --git a/ui/qt/models/proto_tree_model.cpp b/ui/qt/models/proto_tree_model.cpp
index 3ededffd..fe6f7f95 100644
--- a/ui/qt/models/proto_tree_model.cpp
+++ b/ui/qt/models/proto_tree_model.cpp
@@ -188,7 +188,8 @@ struct find_hfid_ {
ProtoNode *node;
};
-bool ProtoTreeModel::foreachFindHfid(ProtoNode *node, gpointer find_hfid_ptr)
+// NOLINTNEXTLINE(misc-no-recursion)
+bool ProtoTreeModel::foreachFindHfid(ProtoNode *node, void *find_hfid_ptr)
{
struct find_hfid_ *find_hfid = (struct find_hfid_ *) find_hfid_ptr;
if (PNODE_FINFO(node->protoNode()) && PNODE_FINFO(node->protoNode())->hfinfo->id == find_hfid->hfid) {
@@ -196,6 +197,7 @@ bool ProtoTreeModel::foreachFindHfid(ProtoNode *node, gpointer find_hfid_ptr)
return true;
}
for (int i = 0; i < node->childrenCount(); i++) {
+ // We recurse here, but we're limited by tree depth checks in epan
if (foreachFindHfid(node->child(i), find_hfid)) {
return true;
}
@@ -221,7 +223,8 @@ struct find_field_info_ {
ProtoNode *node;
};
-bool ProtoTreeModel::foreachFindField(ProtoNode *node, gpointer find_finfo_ptr)
+// NOLINTNEXTLINE(misc-no-recursion)
+bool ProtoTreeModel::foreachFindField(ProtoNode *node, void *find_finfo_ptr)
{
struct find_field_info_ *find_finfo = (struct find_field_info_ *) find_finfo_ptr;
if (PNODE_FINFO(node->protoNode()) == find_finfo->fi) {
@@ -229,6 +232,7 @@ bool ProtoTreeModel::foreachFindField(ProtoNode *node, gpointer find_finfo_ptr)
return true;
}
for (int i = 0; i < node->childrenCount(); i++) {
+ // We recurse here, but we're limited by tree depth checks in epan
if (foreachFindField(node->child(i), find_finfo)) {
return true;
}
diff --git a/ui/qt/models/proto_tree_model.h b/ui/qt/models/proto_tree_model.h
index df7cbba8..12d08fc0 100644
--- a/ui/qt/models/proto_tree_model.h
+++ b/ui/qt/models/proto_tree_model.h
@@ -41,8 +41,8 @@ public:
private:
ProtoNode *root_node_;
- static bool foreachFindHfid(ProtoNode *node, gpointer find_hfid_ptr);
- static bool foreachFindField(ProtoNode *node, gpointer find_finfo_ptr);
+ static bool foreachFindHfid(ProtoNode *node, void *find_hfid_ptr);
+ static bool foreachFindField(ProtoNode *node, void *find_finfo_ptr);
};
#endif // PROTO_TREE_MODEL_H
diff --git a/ui/qt/models/related_packet_delegate.cpp b/ui/qt/models/related_packet_delegate.cpp
index 885160f4..bb001adc 100644
--- a/ui/qt/models/related_packet_delegate.cpp
+++ b/ui/qt/models/related_packet_delegate.cpp
@@ -73,7 +73,7 @@ void RelatedPacketDelegate::paint(QPainter *painter, const QStyleOptionViewItem
option_vi.decorationSize.setWidth(em_w);
QStyledItemDelegate::paint(painter, option_vi, index);
- guint32 setup_frame = 0, last_frame = 0;
+ uint32_t setup_frame = 0, last_frame = 0;
if (conv_) {
setup_frame = (int) conv_->setup_frame;
last_frame = (int) conv_->last_frame;
@@ -339,7 +339,7 @@ void RelatedPacketDelegate::clear()
conv_ = NULL;
}
-void RelatedPacketDelegate::setCurrentFrame(guint32 current_frame)
+void RelatedPacketDelegate::setCurrentFrame(uint32_t current_frame)
{
current_frame_ = current_frame;
foreach (ft_framenum_type_t framenum_type, related_frames_) {
diff --git a/ui/qt/models/related_packet_delegate.h b/ui/qt/models/related_packet_delegate.h
index 927129a0..68250119 100644
--- a/ui/qt/models/related_packet_delegate.h
+++ b/ui/qt/models/related_packet_delegate.h
@@ -26,7 +26,7 @@ class RelatedPacketDelegate : public QStyledItemDelegate
public:
RelatedPacketDelegate(QWidget *parent = 0);
void clear();
- void setCurrentFrame(guint32 current_frame);
+ void setCurrentFrame(uint32_t current_frame);
void setConversation(struct conversation *conv);
public slots:
@@ -41,7 +41,7 @@ protected:
private:
QHash<int, ft_framenum_type_t> related_frames_;
struct conversation *conv_;
- guint32 current_frame_;
+ uint32_t current_frame_;
void drawArrow(QPainter *painter, const QPoint tail, const QPoint head, int head_size) const;
void drawChevrons(QPainter *painter, const QPoint tail, const QPoint head, int head_size) const;
diff --git a/ui/qt/models/resolved_addresses_models.cpp b/ui/qt/models/resolved_addresses_models.cpp
index 48dd2f09..25557771 100644
--- a/ui/qt/models/resolved_addresses_models.cpp
+++ b/ui/qt/models/resolved_addresses_models.cpp
@@ -9,8 +9,6 @@
#include <ui/qt/models/resolved_addresses_models.h>
-#include <glib.h>
-
#include "file.h"
#include "epan/addr_resolv.h"
@@ -20,11 +18,11 @@ extern "C"
{
static void
-serv_port_hash_to_qstringlist(gpointer key, gpointer value, gpointer member_ptr)
+serv_port_hash_to_qstringlist(void *key, void *value, void *member_ptr)
{
PortsModel *model = static_cast<PortsModel *>(member_ptr);
serv_port_t *serv_port = (serv_port_t *)value;
- guint port = GPOINTER_TO_UINT(key);
+ unsigned port = GPOINTER_TO_UINT(key);
if (serv_port->tcp_name) {
QStringList entries;
@@ -61,69 +59,73 @@ serv_port_hash_to_qstringlist(gpointer key, gpointer value, gpointer member_ptr)
}
static void
-ipv4_hash_table_resolved_to_list(gpointer, gpointer value, gpointer sl_ptr)
+ipv4_hash_table_resolved_to_list(void *, void *value, void *sl_ptr)
{
QList<QStringList> *hosts = (QList<QStringList> *) sl_ptr;
hashipv4_t *ipv4_hash_table_entry = (hashipv4_t *) value;
- if ((ipv4_hash_table_entry->flags & NAME_RESOLVED)) {
+ if ((ipv4_hash_table_entry->flags & (USED_AND_RESOLVED_MASK)) == USED_AND_RESOLVED_MASK) {
*hosts << (QStringList() << QString(ipv4_hash_table_entry->ip) << QString(ipv4_hash_table_entry->name));
}
}
static void
-ipv6_hash_table_resolved_to_list(gpointer, gpointer value, gpointer sl_ptr)
+ipv6_hash_table_resolved_to_list(void *, void *value, void *sl_ptr)
{
QList<QStringList> *hosts = (QList<QStringList> *) sl_ptr;
hashipv6_t *ipv6_hash_table_entry = (hashipv6_t *) value;
- if ((ipv6_hash_table_entry->flags & NAME_RESOLVED)) {
+ if ((ipv6_hash_table_entry->flags & USED_AND_RESOLVED_MASK) == USED_AND_RESOLVED_MASK) {
*hosts << (QStringList() << QString(ipv6_hash_table_entry->ip6) << QString(ipv6_hash_table_entry->name));
}
}
static void
-eth_hash_to_qstringlist(gpointer, gpointer value, gpointer sl_ptr)
+eth_hash_to_qstringlist(void *, void *value, void *sl_ptr)
{
QList<QStringList> *values = (QList<QStringList> *) sl_ptr;
hashether_t* tp = (hashether_t*)value;
- *values << (QStringList() << QString(get_hash_ether_hexaddr(tp)) << QString(get_hash_ether_resolved_name(tp)));
+ if (get_hash_ether_used(tp)) {
+ *values << (QStringList() << QString(get_hash_ether_hexaddr(tp)) << QString(get_hash_ether_resolved_name(tp)));
+ }
}
static void
-manuf_hash_to_qstringlist(gpointer key, gpointer value, gpointer sl_ptr)
+manuf_hash_to_qstringlist(void *key, void *value, void *sl_ptr)
{
QList<QStringList> *values = (QList<QStringList> *) sl_ptr;
hashmanuf_t *manuf = (hashmanuf_t*)value;
- guint eth_as_guint = GPOINTER_TO_UINT(key);
+ unsigned eth_as_uint = GPOINTER_TO_UINT(key);
- QString entry = QString("%1:%2:%3")
- .arg((eth_as_guint >> 16 & 0xff), 2, 16, QChar('0'))
- .arg((eth_as_guint >> 8 & 0xff), 2, 16, QChar('0'))
- .arg((eth_as_guint & 0xff), 2, 16, QChar('0'));
+ if (get_hash_manuf_used(manuf)) {
+ QString entry = QString("%1:%2:%3")
+ .arg((eth_as_uint >> 16 & 0xff), 2, 16, QChar('0'))
+ .arg((eth_as_uint >> 8 & 0xff), 2, 16, QChar('0'))
+ .arg((eth_as_uint & 0xff), 2, 16, QChar('0'));
- *values << (QStringList() << entry << QString(get_hash_manuf_resolved_name(manuf)));
+ *values << (QStringList() << entry << QString(get_hash_manuf_resolved_name(manuf)));
+ }
}
static void
-wka_hash_to_qstringlist(gpointer key, gpointer value, gpointer sl_ptr)
+wka_hash_to_qstringlist(void *key, void *value, void *sl_ptr)
{
QList<QStringList> *values = (QList<QStringList> *) sl_ptr;
- gchar *name = (gchar *)value;
- guint8 *eth_addr = (guint8*)key;
-
- QString entry = QString("%1:%2:%3:%4:%5:%6")
- .arg(eth_addr[0], 2, 16, QChar('0'))
- .arg(eth_addr[1], 2, 16, QChar('0'))
- .arg(eth_addr[2], 2, 16, QChar('0'))
- .arg(eth_addr[3], 2, 16, QChar('0'))
- .arg(eth_addr[4], 2, 16, QChar('0'))
- .arg(eth_addr[5], 2, 16, QChar('0'));
-
- // We should filter on only those actually resolved, not display
- // everything in wka
- *values << (QStringList() << entry << QString(name));
+ hashwka_t *wkahash = (hashwka_t *)value;
+ uint8_t *eth_addr = (uint8_t*)key;
+
+ if (get_hash_wka_used(wkahash)) {
+ QString entry = QString("%1:%2:%3:%4:%5:%6")
+ .arg(eth_addr[0], 2, 16, QChar('0'))
+ .arg(eth_addr[1], 2, 16, QChar('0'))
+ .arg(eth_addr[2], 2, 16, QChar('0'))
+ .arg(eth_addr[3], 2, 16, QChar('0'))
+ .arg(eth_addr[4], 2, 16, QChar('0'))
+ .arg(eth_addr[5], 2, 16, QChar('0'));
+
+ *values << (QStringList() << entry << QString(get_hash_wka_resolved_name(wkahash)));
+ }
}
}
diff --git a/ui/qt/models/resolved_addresses_models.h b/ui/qt/models/resolved_addresses_models.h
index 32ca1b15..9a26eb6d 100644
--- a/ui/qt/models/resolved_addresses_models.h
+++ b/ui/qt/models/resolved_addresses_models.h
@@ -30,6 +30,13 @@ protected:
};
+enum PortsModelColumns
+{
+ PORTS_COL_NAME,
+ PORTS_COL_PORT,
+ PORTS_COL_PROTOCOL
+};
+
class PortsModel : public AStringListListModel
{
Q_OBJECT
diff --git a/ui/qt/models/sparkline_delegate.cpp b/ui/qt/models/sparkline_delegate.cpp
index 457c8295..121d8226 100644
--- a/ui/qt/models/sparkline_delegate.cpp
+++ b/ui/qt/models/sparkline_delegate.cpp
@@ -20,7 +20,7 @@ void SparkLineDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opt
QList<int> points = qvariant_cast<QList<int> >(index.data(Qt::UserRole));
int max = 1;
// We typically draw a sparkline alongside some text. Size our
- // drawing area based on an Em width. and a bit of eyballing on
+ // drawing area based on an Em width. and a bit of eyeballing on
// Linux, macOS, and Windows.
int em_w = option.fontMetrics.height();
int content_w = option.rect.width() - (em_w / 4);
diff --git a/ui/qt/models/uat_delegate.h b/ui/qt/models/uat_delegate.h
index e57e533d..f9cfa92d 100644
--- a/ui/qt/models/uat_delegate.h
+++ b/ui/qt/models/uat_delegate.h
@@ -15,7 +15,6 @@
#define UAT_DELEGATE_H
#include <config.h>
-#include <glib.h>
#include <epan/uat-int.h>
#include <QStyledItemDelegate>
diff --git a/ui/qt/models/uat_model.cpp b/ui/qt/models/uat_model.cpp
index a841ca8c..24b4423c 100644
--- a/ui/qt/models/uat_model.cpp
+++ b/ui/qt/models/uat_model.cpp
@@ -12,12 +12,23 @@
#include "uat_model.h"
#include <epan/to_str.h>
+#include <ui/qt/utils/qt_ui_utils.h>
+#include <QFont>
#include <QBrush>
#include <QDebug>
+// XXX - The model accesses the uat_t raw data, but if the raw data
+// is changed outside the model, e.g. by another model on the same UAT
+// or by changing configuration profiles, record_errors and dirty_records
+// don't have the proper length, which leads to accessing an illegal list
+// index. The preference dialog and configuration profile dialogs are modal,
+// which reduces the chance of this, but the I/O Graphs using a UAT invites
+// issues.
+
UatModel::UatModel(QObject *parent, epan_uat *uat) :
QAbstractTableModel(parent),
- uat_(0)
+ uat_(0),
+ applying_(false)
{
loadUat(uat);
}
@@ -46,7 +57,14 @@ void UatModel::loadUat(epan_uat * uat)
void UatModel::reloadUat()
{
+ // Avoid unnecessarily resetting the model if we're just making
+ // what's on disk match what we have.
+ if (applying_)
+ return;
+
beginResetModel();
+ record_errors.clear();
+ dirty_records.clear();
loadUat(uat_);
endResetModel();
}
@@ -54,16 +72,22 @@ void UatModel::reloadUat()
bool UatModel::applyChanges(QString &error)
{
if (uat_->changed) {
- gchar *err = NULL;
+ char *err = NULL;
if (!uat_save(uat_, &err)) {
error = QString("Error while saving %1: %2").arg(uat_->name).arg(err);
g_free(err);
}
+ applying_ = true;
+ // XXX - Why does this need to call post_update_cb? post_update_cb
+ // is for when the uat_t is updated, e.g. after loading a file.
+ // Saving makes the information on disk match the table records in
+ // memory, but it shouldn't change the uat_t.
if (uat_->post_update_cb) {
uat_->post_update_cb();
}
+ applying_ = false;
return true;
}
@@ -76,7 +100,7 @@ bool UatModel::revertChanges(QString &error)
// to avoid calling post_update_cb. Calling uat_clear + uat_load is a lazy
// option and might fail (e.g. when the UAT file is removed).
if (uat_->changed) {
- gchar *err = NULL;
+ char *err = NULL;
uat_clear(uat_);
if (!uat_load(uat_, NULL, &err)) {
error = QString("Error while loading %1: %2").arg(uat_->name).arg(err);
@@ -90,17 +114,19 @@ bool UatModel::revertChanges(QString &error)
Qt::ItemFlags UatModel::flags(const QModelIndex &index) const
{
+ Qt::ItemFlags flags = QAbstractTableModel::flags(index);
+ flags |= Qt::ItemIsDropEnabled;
+
if (!index.isValid())
- return Qt::ItemFlags();
+ return flags;
uat_field_t *field = &uat_->fields[index.column()];
- Qt::ItemFlags flags = QAbstractTableModel::flags(index);
if (field->mode == PT_TXTMOD_BOOL)
{
flags |= Qt::ItemIsUserCheckable;
}
- flags |= Qt::ItemIsEditable;
+ flags |= Qt::ItemIsEditable | Qt::ItemIsDragEnabled;
return flags;
}
@@ -114,13 +140,13 @@ QVariant UatModel::data(const QModelIndex &index, int role) const
uat_field_t *field = &uat_->fields[index.column()];
if (role == Qt::DisplayRole || role == Qt::EditRole) {
char *str = NULL;
- guint length = 0;
+ unsigned length = 0;
field->cb.tostr(rec, &str, &length, field->cbdata.tostr, field->fld_data);
switch (field->mode) {
case PT_TXTMOD_HEXBYTES:
{
- char* temp_str = bytes_to_str(NULL, (const guint8 *) str, length);
+ char* temp_str = bytes_to_str(NULL, (const uint8_t *) str, length);
g_free(str);
QString qstr(temp_str);
wmem_free(NULL, temp_str);
@@ -128,24 +154,24 @@ QVariant UatModel::data(const QModelIndex &index, int role) const
}
case PT_TXTMOD_BOOL:
case PT_TXTMOD_COLOR:
+ g_free(str);
return QVariant();
default:
- {
- QString qstr(str);
- g_free(str);
- return qstr;
- }
+ return gchar_free_to_qstring(str);
}
}
if ((role == Qt::CheckStateRole) && (field->mode == PT_TXTMOD_BOOL))
{
char *str = NULL;
- guint length = 0;
+ unsigned length = 0;
enum Qt::CheckState state = Qt::Unchecked;
field->cb.tostr(rec, &str, &length, field->cbdata.tostr, field->fld_data);
- if ((g_strcmp0(str, "TRUE") == 0) ||
- (g_strcmp0(str, "Enabled") == 0))
+ // "Enabled" is for backwards compatibility with pre-UAT IO Graphs:
+ // (Commit 5b3e3ee58748ac1fd9201d2d3facbed1b9b1e800)
+ if (str &&
+ ((g_ascii_strcasecmp(str, "true") == 0) ||
+ (g_strcmp0(str, "Enabled") == 0)))
state = Qt::Checked;
g_free(str);
@@ -166,12 +192,21 @@ QVariant UatModel::data(const QModelIndex &index, int role) const
return QVariant();
}
+ if (role == Qt::FontRole) {
+ if (!g_array_index(uat_->valid_data, bool, index.row())) {
+ QFont font;
+ font.setItalic(!font.italic());
+ return font;
+ }
+ return QVariant();
+ }
+
if ((role == Qt::DecorationRole) && (field->mode == PT_TXTMOD_COLOR)) {
char *str = NULL;
- guint length = 0;
+ unsigned length = 0;
field->cb.tostr(rec, &str, &length, field->cbdata.tostr, field->fld_data);
- return QColor(QString(str));
+ return QColor(gchar_free_to_qstring(str));
}
// expose error message if any.
@@ -259,9 +294,9 @@ QModelIndex UatModel::appendEntry(QVariantList rowData)
data = rowData[col].toString();
} else {
if (rowData[col].toInt() == Qt::Checked) {
- data = QString("TRUE");
+ data = QString("true");
} else {
- data = QString("FALSE");
+ data = QString("false");
}
}
}
@@ -281,7 +316,7 @@ QModelIndex UatModel::appendEntry(QVariantList rowData)
// postponed until the row (in the view) is not selected anymore
checkRow(row);
dirty_records.insert(row, true);
- uat_->changed = TRUE;
+ uat_->changed = true;
emit endInsertRows();
@@ -316,9 +351,9 @@ bool UatModel::setData(const QModelIndex &index, const QVariant &value, int role
field->cb.set(rec, bytes.constData(), (unsigned) bytes.size(), field->cbdata.set, field->fld_data);
} else {
if (value.toInt() == Qt::Checked) {
- field->cb.set(rec, "TRUE", 4, field->cbdata.set, field->fld_data);
+ field->cb.set(rec, "true", 4, field->cbdata.set, field->fld_data);
} else {
- field->cb.set(rec, "FALSE", 5, field->cbdata.set, field->fld_data);
+ field->cb.set(rec, "false", 5, field->cbdata.set, field->fld_data);
}
}
@@ -348,7 +383,7 @@ bool UatModel::setData(const QModelIndex &index, const QVariant &value, int role
}
uat_update_record(uat_, rec, record_errors[row].isEmpty());
dirty_records[row] = true;
- uat_->changed = TRUE;
+ uat_->changed = true;
if (updated_cols.size() > updated_cols.count(index.column())) {
// The validation status for other columns were also affected by
@@ -388,21 +423,24 @@ bool UatModel::insertRows(int row, int count, const QModelIndex &/*parent*/)
// postponed until the row (in the view) is not selected anymore
checkRow(row);
dirty_records.insert(row, true);
- uat_->changed = TRUE;
+ uat_->changed = true;
endInsertRows();
return true;
}
bool UatModel::removeRows(int row, int count, const QModelIndex &/*parent*/)
{
- if (count != 1 || row < 0 || row >= rowCount())
+ if (row < 0 || count < 0 || row + count > rowCount())
return false;
- beginRemoveRows(QModelIndex(), row, row);
- uat_remove_record_idx(uat_, row);
- record_errors.removeAt(row);
- dirty_records.removeAt(row);
- uat_->changed = TRUE;
+ if (count == 0)
+ return true;
+
+ beginRemoveRows(QModelIndex(), row, row + count - 1);
+ uat_remove_record_range(uat_, row, count);
+ record_errors.remove(row, count);
+ dirty_records.remove(row, count);
+ uat_->changed = true;
endRemoveRows();
return true;
}
@@ -416,7 +454,7 @@ void UatModel::clearAll()
uat_clear(uat_);
record_errors.clear();
dirty_records.clear();
- uat_->changed = TRUE;
+ uat_->changed = true;
endResetModel();
}
@@ -448,7 +486,7 @@ QModelIndex UatModel::copyRow(QModelIndex original)
checkRow(newRow);
dirty_records.insert(newRow, true);
- // the UAT record has been created, now it is filled with the infromation
+ // the UAT record has been created, now it is filled with the information
const void *src_record = UAT_INDEX_PTR(uat_, original.row());
void *dst_record = UAT_INDEX_PTR(uat_, newRow);
// insertRows always initializes the record with empty value. Before copying
@@ -462,35 +500,67 @@ QModelIndex UatModel::copyRow(QModelIndex original)
/* According to documentation of uat_copy_cb_t memcpy should be used if uat_->copy_cb is NULL */
memcpy(dst_record, src_record, uat_->record_size);
}
- gboolean src_valid = g_array_index(uat_->valid_data, gboolean, original.row());
+ bool src_valid = g_array_index(uat_->valid_data, bool, original.row());
uat_update_record(uat_, dst_record, src_valid);
record_errors[newRow] = record_errors[original.row()];
dirty_records[newRow] = true;
- uat_->changed = TRUE;
+ uat_->changed = true;
endInsertRows();
return index(newRow, 0, QModelIndex());
}
-bool UatModel::moveRow(int src_row, int dst_row)
+bool UatModel::moveRowPrivate(int src_row, int dst_row)
{
- if (src_row < 0 || src_row >= rowCount() || dst_row < 0 || dst_row >= rowCount())
- return false;
-
- int dst = src_row < dst_row ? dst_row + 1 : dst_row;
+ if (src_row == dst_row)
+ return true;
- beginMoveRows(QModelIndex(), src_row, src_row, QModelIndex(), dst);
uat_move_index(uat_, src_row, dst_row);
record_errors.move(src_row, dst_row);
dirty_records.move(src_row, dst_row);
- uat_->changed = TRUE;
- endMoveRows();
+ uat_->changed = true;
return true;
}
+bool UatModel::moveRow(int src_row, int dst_row)
+{
+ return moveRows(QModelIndex(), src_row, 1, QModelIndex(), dst_row);
+}
+
+bool UatModel::moveRows(const QModelIndex &, int sourceRow, int count, const QModelIndex &, int destinationChild)
+{
+ if (sourceRow < 0 || sourceRow >= rowCount() || destinationChild < 0 || destinationChild >= rowCount() || count < 0)
+ return false;
+
+ if (count == 0)
+ return true;
+
+ // beginMoveRows checks this
+ if (sourceRow <= destinationChild && destinationChild <= sourceRow + count - 1)
+ return false;
+
+ if (destinationChild < sourceRow) {
+ if (!beginMoveRows(QModelIndex(), sourceRow, sourceRow + count - 1, QModelIndex(), destinationChild)) {
+ return false;
+ }
+ for (int i = 0; i < count; i++) {
+ moveRowPrivate(sourceRow + i, destinationChild + i);
+ }
+ } else {
+ if (!beginMoveRows(QModelIndex(), sourceRow, sourceRow + count - 1, QModelIndex(), destinationChild + 1)) {
+ return false;
+ }
+ for (int i = 0; i < count; i++) {
+ moveRowPrivate(sourceRow, destinationChild);
+ }
+ }
+ endMoveRows();
+ return true;
+}
+
bool UatModel::hasErrors() const
{
for (int i = 0; i < rowCount(); i++) {
@@ -513,7 +583,7 @@ bool UatModel::checkField(int row, int col, char **error) const
}
char *str = NULL;
- guint length;
+ unsigned length;
field->cb.tostr(rec, &str, &length, field->cbdata.tostr, field->fld_data);
bool ok = field->cb.chk(rec, str, length, field->cbdata.chk, field->fld_data, error);
@@ -543,3 +613,20 @@ QList<int> UatModel::checkRow(int row)
}
return changed;
}
+
+Qt::DropActions UatModel::supportedDropActions() const
+{
+ return Qt::MoveAction;
+}
+
+bool UatModel::dropMimeData(const QMimeData *, Qt::DropAction, int, int, const QModelIndex &)
+{
+ // We could implement MimeData using uat_fld_tostr (or a new function
+ // that just gives the entire string) although it would be nice for
+ // uat_load_str to be able to load at a specified index, or else have
+ // a function to produce a UAT record from a string. Or we could use
+ // something else. However, for now we really just want internal moves.
+ // Supporting drop actions and rejecting drops still allows our row
+ // moving view's InternalMove to work.
+ return false;
+}
diff --git a/ui/qt/models/uat_model.h b/ui/qt/models/uat_model.h
index 5da647a5..a24c938a 100644
--- a/ui/qt/models/uat_model.h
+++ b/ui/qt/models/uat_model.h
@@ -15,7 +15,6 @@
#define UAT_MODEL_H
#include <config.h>
-#include <glib.h>
#include <QAbstractItemModel>
#include <QList>
@@ -24,6 +23,7 @@
class UatModel : public QAbstractTableModel
{
+ Q_OBJECT
public:
UatModel(QObject *parent, uat_t *uat = 0);
UatModel(QObject *parent, QString tableName);
@@ -43,9 +43,13 @@ public:
QModelIndex appendEntry(QVariantList row);
QModelIndex copyRow(QModelIndex original);
+
bool moveRow(int src_row, int dst_row);
+ bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild);
- bool moveRow(const QModelIndex &sourceParent, int sourceRow, const QModelIndex &destinationParent, int destinationChild);
+ //Drag & drop functionality
+ Qt::DropActions supportedDropActions() const;
+ bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
void reloadUat();
bool hasErrors() const;
@@ -74,9 +78,11 @@ private:
bool checkField(int row, int col, char **error) const;
QList<int> checkRow(int row);
void loadUat(uat_t * uat = 0);
+ bool moveRowPrivate(int src_row, int dst_row);
epan_uat *uat_;
- QList<bool> dirty_records;
- QList<QMap<int, QString> > record_errors;
+ bool applying_;
+ QVector<bool> dirty_records;
+ QVector<QMap<int, QString> > record_errors;
};
#endif // UAT_MODEL_H
diff --git a/ui/qt/models/voip_calls_info_model.cpp b/ui/qt/models/voip_calls_info_model.cpp
index 23ba46f1..2f6d4f18 100644
--- a/ui/qt/models/voip_calls_info_model.cpp
+++ b/ui/qt/models/voip_calls_info_model.cpp
@@ -58,7 +58,7 @@ QVariant VoipCallsInfoModel::data(const QModelIndex &index, int role) const
call_info->protocol_name : voip_protocol_name[call_info->protocol];
case Duration:
{
- guint callDuration = nstime_to_sec(&(call_info->stop_fd->abs_ts)) - nstime_to_sec(&(call_info->start_fd->abs_ts));
+ unsigned callDuration = nstime_to_sec(&(call_info->stop_fd->abs_ts)) - nstime_to_sec(&(call_info->start_fd->abs_ts));
return QString("%1:%2:%3").arg(callDuration / 3600, 2, 10, QChar('0')).arg((callDuration % 3600) / 60, 2, 10, QChar('0')).arg(callDuration % 60, 2, 10, QChar('0'));
}
case Packets:
@@ -82,14 +82,14 @@ QVariant VoipCallsInfoModel::data(const QModelIndex &index, int role) const
case VOIP_H323:
{
h323_calls_info_t *h323_info = (h323_calls_info_t *)call_info->prot_info;
- gboolean flag = FALSE;
+ bool flag = false;
static const QString on_str = tr("On");
static const QString off_str = tr("Off");
if (call_info->call_state == VOIP_CALL_SETUP) {
flag = h323_info->is_faststart_Setup;
} else {
if ((h323_info->is_faststart_Setup) && (h323_info->is_faststart_Proc)) {
- flag = TRUE;
+ flag = true;
}
}
return tr("Tunneling: %1 Fast Start: %2")
@@ -202,7 +202,7 @@ void VoipCallsInfoModel::updateCalls(GQueue *callsinfos)
// Add new rows
cur_call = g_queue_peek_nth_link(callsinfos, rowCount());
- guint extra = g_list_length(cur_call);
+ unsigned extra = g_list_length(cur_call);
if (extra > 0) {
beginInsertRows(QModelIndex(), rowCount(), rowCount() + extra - 1);
while (cur_call && cur_call->data) {
diff --git a/ui/qt/models/voip_calls_info_model.h b/ui/qt/models/voip_calls_info_model.h
index 2f8d4007..afb7ebe3 100644
--- a/ui/qt/models/voip_calls_info_model.h
+++ b/ui/qt/models/voip_calls_info_model.h
@@ -11,7 +11,6 @@
#define VOIP_CALLS_INFO_MODEL_H
#include <config.h>
-#include <glib.h>
#include "ui/voip_calls.h"
#include <ui/qt/utils/variant_pointer.h>
diff --git a/ui/qt/module_preferences_scroll_area.cpp b/ui/qt/module_preferences_scroll_area.cpp
index 56503e0a..d6f4718d 100644
--- a/ui/qt/module_preferences_scroll_area.cpp
+++ b/ui/qt/module_preferences_scroll_area.cpp
@@ -10,6 +10,7 @@
#include "module_preferences_scroll_area.h"
#include <ui_module_preferences_scroll_area.h>
#include <ui/qt/widgets/syntax_line_edit.h>
+#include <ui/qt/widgets/dissector_syntax_line_edit.h>
#include "ui/qt/widgets/wireshark_file_dialog.h"
#include <ui/qt/utils/qt_ui_utils.h>
#include "uat_dialog.h"
@@ -56,8 +57,8 @@ extern "C" {
// Callbacks prefs routines
/* Add a single preference to the QVBoxLayout of a preference page */
-static guint
-pref_show(pref_t *pref, gpointer user_data)
+static unsigned
+pref_show(pref_t *pref, void *user_data)
{
prefSearchData * data = static_cast<prefSearchData *>(user_data);
@@ -73,7 +74,6 @@ pref_show(pref_t *pref, gpointer user_data)
switch (prefs_get_type(pref)) {
case PREF_UINT:
- case PREF_DECODE_AS_UINT:
{
QHBoxLayout *hb = new QHBoxLayout();
QLabel *label = new QLabel(prefs_get_title(pref));
@@ -171,6 +171,21 @@ pref_show(pref_t *pref, gpointer user_data)
vb->addLayout(hb);
break;
}
+ case PREF_DISSECTOR:
+ {
+ QHBoxLayout *hb = new QHBoxLayout();
+ QLabel *label = new QLabel(prefs_get_title(pref));
+ label->setToolTip(tooltip);
+ hb->addWidget(label);
+ QLineEdit *string_le = new DissectorSyntaxLineEdit();
+ string_le->setToolTip(tooltip);
+ string_le->setProperty(pref_prop_, VariantPointer<pref_t>::asQVariant(pref));
+ string_le->setMinimumWidth(string_le->fontMetrics().height() * 20);
+ hb->addWidget(string_le);
+ hb->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ vb->addLayout(hb);
+ break;
+ }
case PREF_DECODE_AS_RANGE:
case PREF_RANGE:
{
@@ -305,7 +320,7 @@ ModulePreferencesScrollArea::ModulePreferencesScrollArea(module_t *module, QWidg
/* Show the preference's description at the top of the page */
QFont font;
- font.setBold(TRUE);
+ font.setBold(true);
QLabel *label = new QLabel(module->description);
label->setFont(font);
ui->verticalLayout->addWidget(label);
@@ -322,9 +337,6 @@ ModulePreferencesScrollArea::ModulePreferencesScrollArea(module_t *module, QWidg
if (!pref) continue;
switch (prefs_get_type(pref)) {
- case PREF_DECODE_AS_UINT:
- connect(le, &QLineEdit::textEdited, this, &ModulePreferencesScrollArea::uintLineEditTextEdited);
- break;
case PREF_UINT:
connect(le, &QLineEdit::textEdited, this, &ModulePreferencesScrollArea::uintLineEditTextEdited);
break;
@@ -333,6 +345,7 @@ ModulePreferencesScrollArea::ModulePreferencesScrollArea(module_t *module, QWidg
case PREF_OPEN_FILENAME:
case PREF_DIRNAME:
case PREF_PASSWORD:
+ case PREF_DISSECTOR:
connect(le, &QLineEdit::textEdited, this, &ModulePreferencesScrollArea::stringLineEditTextEdited);
break;
case PREF_RANGE:
@@ -471,11 +484,27 @@ void ModulePreferencesScrollArea::updateWidgets()
}
if (prefs_get_type(pref) == PREF_PROTO_TCP_SNDAMB_ENUM && !prefs_get_enum_radiobuttons(pref)) {
- MainWindow* topWidget = dynamic_cast<MainWindow*> (mainApp->mainWindow());
- /* Ensure there is one unique or multiple selections. See issue 18642 */
- if (topWidget->hasSelection() || topWidget->hasUniqueSelection()) {
- frame_data * fdata = topWidget->frameDataForRow((topWidget->selectedRows()).at(0));
- enum_cb->setCurrentIndex(fdata->tcp_snd_manual_analysis);
+ if (prefs_get_list_value(pref, pref_stashed) == NULL) {
+ /* We haven't added a list of frames that could have their
+ * analysis changed. Set the current value to whatever the
+ * first selected frame has for its its TCP Sequence Analysis
+ * override.
+ */
+ MainWindow* topWidget = qobject_cast<MainWindow*>(mainApp->mainWindow());
+ /* Ensure there is one unique or multiple selections. See issue 18642 */
+ if (topWidget->hasSelection() || topWidget->hasUniqueSelection()) {
+ frame_data * fdata = topWidget->frameDataForRow((topWidget->selectedRows()).at(0));
+ enum_cb->setCurrentIndex(enum_cb->findData(fdata->tcp_snd_manual_analysis));
+ QList<int> rows = topWidget->selectedRows();
+ foreach (int row, rows) {
+ frame_data * fdata = topWidget->frameDataForRow(row);
+ prefs_add_list_value(pref, fdata, pref_stashed);
+ }
+ }
+ } else {
+ /* The initial value was already set from the selected frames,
+ * use the current value from when the CB was changed. */
+ enum_cb->setCurrentIndex(enum_cb->findData(prefs_get_enum_value(pref, pref_current)));
}
}
}
@@ -640,20 +669,8 @@ void ModulePreferencesScrollArea::enumComboBoxCurrentIndexChanged_PROTO_TCP(int
pref_t *pref = VariantPointer<pref_t>::asPtr(enum_cb->property(pref_prop_));
if (!pref) return;
- MainWindow* topWidget = dynamic_cast<MainWindow*> (mainApp->mainWindow());
-
- // method 1 : apply to one single packet
- /* frame_data * fdata = topWidget->frameDataForRow((topWidget->selectedRows()).at(0));
- fdata->tcp_snd_manual_analysis = enum_cb->itemData(index).toInt();*/
-
- // method 2 : we can leverage the functionality by allowing multiple selections
- QList<int> rows = topWidget->selectedRows();
- foreach (int row, rows) {
- frame_data * fdata = topWidget->frameDataForRow(row);
- fdata->tcp_snd_manual_analysis = enum_cb->itemData(index).toInt();
- }
-
+ // Store the index value in the current value, not the stashed value.
+ // We use the stashed value to store the frame data pointers.
prefs_set_enum_value(pref, enum_cb->itemData(index).toInt(), pref_current);
//prefs_set_enum_value(pref, enum_cb->itemData(index).toInt(), pref_stashed);
- updateWidgets();
}
diff --git a/ui/qt/module_preferences_scroll_area.h b/ui/qt/module_preferences_scroll_area.h
index f3da516b..8123564d 100644
--- a/ui/qt/module_preferences_scroll_area.h
+++ b/ui/qt/module_preferences_scroll_area.h
@@ -12,8 +12,6 @@
#include <config.h>
-#include <glib.h>
-
#include <epan/prefs.h>
#include <epan/prefs-int.h>
diff --git a/ui/qt/mtp3_summary_dialog.cpp b/ui/qt/mtp3_summary_dialog.cpp
index e5460fd9..37fb50dc 100644
--- a/ui/qt/mtp3_summary_dialog.cpp
+++ b/ui/qt/mtp3_summary_dialog.cpp
@@ -16,8 +16,6 @@
#include "config.h"
-#include <glib.h>
-
#include <epan/tap.h>
#include <epan/dissectors/packet-mtp3.h>
diff --git a/ui/qt/multicast_statistics_dialog.cpp b/ui/qt/multicast_statistics_dialog.cpp
index cca74783..30801647 100644
--- a/ui/qt/multicast_statistics_dialog.cpp
+++ b/ui/qt/multicast_statistics_dialog.cpp
@@ -153,9 +153,9 @@ public:
private:
address src_addr_;
- guint16 src_port_;
+ uint16_t src_port_;
address dst_addr_;
- guint16 dst_port_;
+ uint16_t dst_port_;
unsigned num_packets_;
double avg_pps_;
double avg_bw_;
@@ -414,7 +414,7 @@ void MulticastStatisticsDialog::updateMulticastParameters()
param = burst_measurement_interval_le_->text().toUInt(&ok);
if (ok && param > 0 && param <= 1000) {
- mcast_stream_burstint = (guint16) param;
+ mcast_stream_burstint = (uint16_t) param;
}
param = burst_alarm_threshold_le_->text().toInt(&ok);
@@ -456,7 +456,7 @@ void MulticastStatisticsDialog::fillTree()
void MulticastStatisticsDialog::rescan()
{
- gboolean was_registered = tapinfo_->is_registered;
+ bool was_registered = tapinfo_->is_registered;
if (!tapinfo_->is_registered)
register_tap_listener_mcast_stream(tapinfo_);
diff --git a/ui/qt/packet_comment_dialog.h b/ui/qt/packet_comment_dialog.h
index 114e8345..e380953d 100644
--- a/ui/qt/packet_comment_dialog.h
+++ b/ui/qt/packet_comment_dialog.h
@@ -10,8 +10,6 @@
#ifndef PACKET_COMMENT_DIALOG_H
#define PACKET_COMMENT_DIALOG_H
-#include <glib.h>
-
#include "geometry_state_dialog.h"
namespace Ui {
diff --git a/ui/qt/packet_diagram.cpp b/ui/qt/packet_diagram.cpp
index a5bbc106..4d83deb2 100644
--- a/ui/qt/packet_diagram.cpp
+++ b/ui/qt/packet_diagram.cpp
@@ -322,19 +322,11 @@ private:
QFontMetrics fm = QFontMetrics(layout_->regularFont());
painter->setFont(layout_->regularFont());
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
int label_w = fm.horizontalAdvance(label);
-#else
- int label_w = fm.width(label);
-#endif
if (label_w > label_rect.width()) {
painter->setFont(layout_->smallFont());
fm = QFontMetrics(layout_->smallFont());
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
label_w = fm.horizontalAdvance(label);
-#else
- label_w = fm.width(label);
-#endif
if (label_w > label_rect.width()) {
// XXX Use parent+ItemClipsChildrenToShape or setScale instead?
label = fm.elidedText(label, Qt::ElideRight, label_rect.width());
@@ -379,6 +371,8 @@ void PacketDiagram::setRootNode(proto_node *root_node)
// useful in our case because it gives us a cheap way to retain our
// scroll position between packets.
scene()->clear();
+ viewport()->update();
+
selected_field_ = nullptr;
y_pos_ = 0;
@@ -399,7 +393,7 @@ void PacketDiagram::setRootNode(proto_node *root_node)
kids.next();
// Exclude all ("Frame") and nothing
- if (tl_node->finfo->start == 0 && tl_node->finfo->length == (int) tvb_captured_length(cap_file_->edt->tvb)) {
+ if (tl_node == root_node->first_child) {
continue;
}
if (tl_node->finfo->length < 1) {
@@ -475,6 +469,9 @@ void PacketDiagram::contextMenuEvent(QContextMenuEvent *event)
action->setChecked(layout_->showFields());
connect(action, &QAction::toggled, this, &PacketDiagram::showFieldsToggled);
+ action = ctx_menu->addAction(tr("Refresh"));
+ connect(action, &QAction::triggered, this, &PacketDiagram::resetScene);
+
ctx_menu->addSeparator();
action = ctx_menu->addAction(tr("Save Diagram As…"));
@@ -564,11 +561,7 @@ void PacketDiagram::addDiagram(proto_node *tl_node)
qreal y_bottom = y_pos_ + bit_width;
QGraphicsItem *tl_item = scene()->addLine(x, y_bottom, x + diag_w, y_bottom);
QFontMetrics sfm = QFontMetrics(layout_->smallFont());
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
int space_w = sfm.horizontalAdvance(' ');
-#else
- int space_w = sfm.width(' ');
-#endif
#ifdef Q_OS_WIN
// t_item->boundingRect() has a pixel of space on the left on my (gcc)
// Windows VM.
diff --git a/ui/qt/packet_dialog.cpp b/ui/qt/packet_dialog.cpp
index 8bf7a3bf..8c2d0010 100644
--- a/ui/qt/packet_dialog.cpp
+++ b/ui/qt/packet_dialog.cpp
@@ -15,6 +15,7 @@
#include "epan/column.h"
#include "epan/ftypes/ftypes.h"
#include "epan/prefs.h"
+#include "epan/prefs-int.h"
#include "ui/preference_utils.h"
#include "frame_tvbuff.h"
@@ -28,6 +29,8 @@
#include <ui/qt/utils/field_information.h>
#include <QTreeWidgetItemIterator>
+Q_DECLARE_METATYPE(splitter_layout_e)
+
// To do:
// - Copy over experimental packet editing code.
// - Fix ElidedText width.
@@ -41,6 +44,8 @@ PacketDialog::PacketDialog(QWidget &parent, CaptureFile &cf, frame_data *fdata)
ui->setupUi(this);
loadGeometry(parent.width() * 4 / 5, parent.height() * 4 / 5);
ui->hintLabel->setSmallText();
+ ui->prefsLayout->insertSpacing(1, 20);
+ ui->prefsLayout->addStretch();
wtap_rec_init(&rec_);
ws_buffer_init(&buf_, 1514);
@@ -59,13 +64,13 @@ PacketDialog::PacketDialog(QWidget &parent, CaptureFile &cf, frame_data *fdata)
}
/* proto tree, visible. We need a proto tree if there are custom columns */
- epan_dissect_init(&edt_, cap_file_.capFile()->epan, TRUE, TRUE);
+ epan_dissect_init(&edt_, cap_file_.capFile()->epan, true, true);
col_custom_prime_edt(&edt_, &(cap_file_.capFile()->cinfo));
epan_dissect_run(&edt_, cap_file_.capFile()->cd_t, &rec_,
frame_tvbuff_new_buffer(&cap_file_.capFile()->provider, fdata, &buf_),
fdata, &(cap_file_.capFile()->cinfo));
- epan_dissect_fill_in_columns(&edt_, TRUE, TRUE);
+ epan_dissect_fill_in_columns(&edt_, true, true);
proto_tree_ = new ProtoTree(ui->packetSplitter, &edt_);
// Do not call proto_tree_->setCaptureFile, ProtoTree only needs the
@@ -76,7 +81,40 @@ PacketDialog::PacketDialog(QWidget &parent, CaptureFile &cf, frame_data *fdata)
byte_view_tab_->setCaptureFile(cap_file_.capFile());
byte_view_tab_->selectedFrameChanged(QList<int>() << 0);
- ui->packetSplitter->setStretchFactor(1, 0);
+ // We have to load the splitter state after adding the proto tree
+ // and byte view.
+ loadSplitterState(ui->packetSplitter);
+
+ module_t *gui_module = prefs_find_module("gui");
+ if (gui_module != nullptr) {
+ pref_packet_dialog_layout_ = prefs_find_preference(gui_module, "packet_dialog_layout");
+ if (pref_packet_dialog_layout_ != nullptr) {
+ for (const enum_val_t *ev = prefs_get_enumvals(pref_packet_dialog_layout_); ev && ev->description; ev++) {
+ ui->layoutComboBox->addItem(ev->description, QVariant(ev->value));
+ }
+ }
+ }
+ ui->layoutComboBox->setCurrentIndex(ui->layoutComboBox->findData(QVariant(prefs.gui_packet_dialog_layout)));
+ Qt::Orientation pref_orientation = Qt::Vertical;
+ switch(prefs.gui_packet_dialog_layout) {
+ case(layout_vertical):
+ pref_orientation = Qt::Vertical;
+ break;
+ case(layout_horizontal):
+ pref_orientation = Qt::Horizontal;
+ break;
+ }
+
+ if (ui->packetSplitter->orientation() != pref_orientation) {
+ ui->packetSplitter->setOrientation(pref_orientation);
+ // If the orientation is different than the restore one,
+ // reset the sizes to 50-50.
+ QList<int> sizes = ui->packetSplitter->sizes();
+ int totalsize = sizes.at(0) + sizes.at(1);
+ sizes[0] = totalsize / 2;
+ sizes[1] = totalsize / 2;
+ ui->packetSplitter->setSizes(sizes);
+ }
QStringList col_parts;
for (int i = 0; i < cap_file_.capFile()->cinfo.num_cols; ++i) {
@@ -96,6 +134,7 @@ PacketDialog::PacketDialog(QWidget &parent, CaptureFile &cf, frame_data *fdata)
byte_view_tab_->setVisible(false);
}
ui->chkShowByteView->setCheckState(state);
+ ui->layoutComboBox->setEnabled(state);
connect(mainApp, SIGNAL(zoomMonospaceFont(QFont)),
proto_tree_, SLOT(setMonospaceFont(QFont)));
@@ -117,6 +156,11 @@ PacketDialog::PacketDialog(QWidget &parent, CaptureFile &cf, frame_data *fdata)
connect(proto_tree_, SIGNAL(editProtocolPreference(preference*,pref_module*)),
this, SIGNAL(editProtocolPreference(preference*,pref_module*)));
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ connect(ui->layoutComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PacketDialog::layoutChanged);
+#else
+ connect(ui->layoutComboBox, &QComboBox::currentIndexChanged, this, &PacketDialog::layoutChanged, Qt::AutoConnection);
+#endif
connect(ui->chkShowByteView, &QCheckBox::stateChanged, this, &PacketDialog::viewVisibilityStateChanged);
}
@@ -192,7 +236,12 @@ void PacketDialog::setHintTextSelected(FieldInformation* finfo)
finfo_length = finfo->position().length + finfo->appendix().length;
if (finfo_length > 0) {
- hint.append(", " + tr("%Ln byte(s)", "", finfo_length));
+ int finfo_bits = FI_GET_BITS_SIZE(finfo->fieldInfo());
+ if (finfo_bits % 8 == 0) {
+ hint.append(", " + tr("%Ln byte(s)", "", finfo_length));
+ } else {
+ hint.append(", " + tr("%Ln bit(s)", "", finfo_bits));
+ }
}
}
}
@@ -205,7 +254,22 @@ void PacketDialog::setHintTextSelected(FieldInformation* finfo)
void PacketDialog::viewVisibilityStateChanged(int state)
{
byte_view_tab_->setVisible(state == Qt::Checked);
+ ui->layoutComboBox->setEnabled(state == Qt::Checked);
- prefs.gui_packet_details_show_byteview = (state == Qt::Checked ? TRUE : FALSE);
+ prefs.gui_packet_details_show_byteview = (state == Qt::Checked ? true : false);
prefs_main_write();
}
+
+void PacketDialog::layoutChanged(int index _U_)
+{
+ splitter_layout_e layout = ui->layoutComboBox->currentData().value<splitter_layout_e>();
+ switch(layout) {
+ case(layout_vertical):
+ ui->packetSplitter->setOrientation(Qt::Vertical);
+ break;
+ case(layout_horizontal):
+ ui->packetSplitter->setOrientation(Qt::Horizontal);
+ break;
+ }
+ prefs_set_enum_value(pref_packet_dialog_layout_, layout, pref_current);
+}
diff --git a/ui/qt/packet_dialog.h b/ui/qt/packet_dialog.h
index c2119b74..927784f1 100644
--- a/ui/qt/packet_dialog.h
+++ b/ui/qt/packet_dialog.h
@@ -43,6 +43,7 @@ signals:
private slots:
void on_buttonBox_helpRequested();
void viewVisibilityStateChanged(int);
+ void layoutChanged(int);
void setHintText(FieldInformation *);
void setHintTextSelected(FieldInformation*);
@@ -50,6 +51,7 @@ private slots:
private:
Ui::PacketDialog *ui;
+ pref_t *pref_packet_dialog_layout_;
QString col_info_;
ProtoTree *proto_tree_;
ByteViewTab *byte_view_tab_;
diff --git a/ui/qt/packet_dialog.ui b/ui/qt/packet_dialog.ui
index 0473fa12..83442828 100644
--- a/ui/qt/packet_dialog.ui
+++ b/ui/qt/packet_dialog.ui
@@ -35,14 +35,29 @@
</widget>
</item>
<item>
- <widget class="QCheckBox" name="chkShowByteView">
- <property name="text">
- <string>Show packet bytes</string>
- </property>
- <property name="checked">
- <bool>true</bool>
- </property>
- </widget>
+ <layout class="QHBoxLayout" name="prefsLayout">
+ <item>
+ <widget class="QCheckBox" name="chkShowByteView">
+ <property name="text">
+ <string>Show packet bytes</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="layoutLabel">
+ <property name="text">
+ <string>Layout:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="layoutComboBox">
+ </widget>
+ </item>
+ </layout>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
diff --git a/ui/qt/packet_list.cpp b/ui/qt/packet_list.cpp
index a065eacc..896c66fe 100644
--- a/ui/qt/packet_list.cpp
+++ b/ui/qt/packet_list.cpp
@@ -11,8 +11,6 @@
#include "config.h"
-#include <glib.h>
-
#include "file.h"
#include <epan/epan.h>
@@ -36,6 +34,7 @@
#include "ui/util.h"
#include "wiretap/wtap_opttypes.h"
+#include "wsutil/filesystem.h"
#include "wsutil/str_util.h"
#include <wsutil/wslog.h>
@@ -49,6 +48,7 @@
#include "main_application.h"
#include <ui/qt/utils/data_printer.h>
#include <ui/qt/utils/frame_information.h>
+#include <ui/qt/utils/profile_switcher.h>
#include <ui/qt/utils/variant_pointer.h>
#include <ui/qt/models/pref_models.h>
#include <ui/qt/widgets/packet_list_header.h>
@@ -93,7 +93,7 @@
// If we ever add the ability to open multiple capture files we might be
// able to use something like QMap<capture_file *, PacketList *> to match
// capture files against packet lists and models.
-static PacketList *gbl_cur_packet_list = NULL;
+static PacketList *gbl_cur_packet_list;
const int max_comments_to_fetch_ = 20000000; // Arbitrary
const int overlay_update_interval_ = 100; // 250; // Milliseconds.
@@ -102,18 +102,18 @@ const int overlay_update_interval_ = 100; // 250; // Milliseconds.
/*
* Given a frame_data structure, scroll to and select the row in the
* packet list corresponding to that frame. If there is no such
- * row, return FALSE, otherwise return TRUE.
+ * row, return false, otherwise return true.
*/
-gboolean
+bool
packet_list_select_row_from_data(frame_data *fdata_needle)
{
if (! gbl_cur_packet_list || ! gbl_cur_packet_list->model())
- return FALSE;
+ return false;
PacketListModel * model = qobject_cast<PacketListModel *>(gbl_cur_packet_list->model());
if (! model)
- return FALSE;
+ return false;
model->flushVisibleRows();
int row = -1;
@@ -132,10 +132,32 @@ packet_list_select_row_from_data(frame_data *fdata_needle)
gbl_cur_packet_list->selectionModel()->clearSelection();
gbl_cur_packet_list->selectionModel()->setCurrentIndex(model->index(row, 0), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
gbl_cur_packet_list->scrollTo(gbl_cur_packet_list->currentIndex(), PacketList::PositionAtCenter);
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
+}
+
+/*
+ * Given a field_info, select the field (which will scroll to it in
+ * the main ProtoTree, etc.) This is kind of an odd place for it,
+ * but we call this when performing Find Packet in lieu of changing the
+ * selected frame (the function above), because we found a match in the
+ * same frame as the currently selected one.
+ */
+bool
+packet_list_select_finfo(field_info *fi)
+{
+ if (! gbl_cur_packet_list || ! gbl_cur_packet_list->model())
+ return false;
+
+ if (fi) {
+ FieldInformation finfo(fi, gbl_cur_packet_list);
+ emit gbl_cur_packet_list->fieldSelected(&finfo);
+ } else {
+ emit gbl_cur_packet_list->fieldSelected(0);
+ }
+ return true;
}
void
@@ -180,21 +202,21 @@ packet_list_recent_write_all(FILE *rf) {
gbl_cur_packet_list->writeRecent(rf);
}
-gboolean
+bool
packet_list_multi_select_active(void)
{
if (gbl_cur_packet_list) {
return gbl_cur_packet_list->multiSelectActive();
}
- return FALSE;
+ return false;
}
#define MIN_COL_WIDTH_STR "MMMMMM"
PacketList::PacketList(QWidget *parent) :
QTreeView(parent),
- proto_tree_(NULL),
- cap_file_(NULL),
+ proto_tree_(nullptr),
+ cap_file_(nullptr),
ctx_column_(-1),
overlay_timer_id_(0),
create_near_overlay_(true),
@@ -209,7 +231,8 @@ PacketList::PacketList(QWidget *parent) :
frozen_selected_rows_(QModelIndexList()),
cur_history_(-1),
in_history_(false),
- finfo_array(NULL)
+ finfo_array(nullptr),
+ profile_switcher_(nullptr)
{
setItemsExpandable(false);
setRootIsDecorated(false);
@@ -227,9 +250,7 @@ PacketList::PacketList(QWidget *parent) :
connect(packet_list_header_, &PacketListHeader::columnsChanged, this, &PacketList::columnsChanged);
setHeader(packet_list_header_);
-#if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
header()->setFirstSectionMovable(true);
-#endif
setSelectionMode(QAbstractItemView::ExtendedSelection);
@@ -276,10 +297,23 @@ PacketList::~PacketList()
{
if (finfo_array)
{
- g_ptr_array_free(finfo_array, TRUE);
+ g_ptr_array_free(finfo_array, true);
}
}
+void PacketList::scrollTo(const QModelIndex &index, QAbstractItemView::ScrollHint hint)
+{
+ /* QAbstractItemView doesn't have a way to indicate "auto scroll, but
+ * only vertically." So just restore the horizontal scroll value whenever
+ * it scrolls.
+ */
+ setUpdatesEnabled(false);
+ int horizVal = horizontalScrollBar()->value();
+ QTreeView::scrollTo(index, hint);
+ horizontalScrollBar()->setValue(horizVal);
+ setUpdatesEnabled(true);
+}
+
void PacketList::colorsChanged()
{
const QString c_active = "active";
@@ -550,7 +584,6 @@ void PacketList::selectionChanged (const QItemSelection & selected, const QItemS
selection_history_.resize(cur_history_);
selection_history_.append(cap_file_->current_frame->num);
}
- in_history_ = false;
related_packet_delegate_.clear();
@@ -567,7 +600,7 @@ void PacketList::selectionChanged (const QItemSelection & selected, const QItemS
if (cap_file_->edt->tree) {
packet_info *pi = &cap_file_->edt->pi;
related_packet_delegate_.setCurrentFrame(pi->num);
- conversation_t *conv = find_conversation_pinfo(pi, 0);
+ conversation_t *conv = find_conversation_pinfo_ro(pi, 0);
if (conv) {
related_packet_delegate_.setConversation(conv);
}
@@ -581,9 +614,17 @@ void PacketList::selectionChanged (const QItemSelection & selected, const QItemS
// The tree where the target string matched one of the labels was discarded in
// match_protocol_tree() so we have to search again in the latest tree.
fi = cf_find_string_protocol_tree(cap_file_, cap_file_->edt->tree);
- } else if (cap_file_->search_pos != 0) {
+ } else if (cap_file_->search_len != 0) {
// Find the finfo that corresponds to our byte.
- fi = proto_find_field_from_offset(cap_file_->edt->tree, cap_file_->search_pos,
+ // The match can span multiple fields (and a single byte can
+ // match more than one field.) Our behavior is to find the last
+ // field in the tree (so hopefully spanning fewer bytes) that
+ // matches the last byte in the search match.
+ // (regex search can find a zero length match not at the
+ // start of the frame if lookbehind is used, but
+ // proto_find_field_from_offset doesn't match such a field
+ // and it's not clear which field we would want to match.)
+ fi = proto_find_field_from_offset(cap_file_->edt->tree, cap_file_->search_pos + cap_file_->search_len - 1,
cap_file_->edt->tvb);
}
@@ -606,16 +647,16 @@ void PacketList::contextMenuEvent(QContextMenuEvent *event)
if (finfo_array)
{
- g_ptr_array_free(finfo_array, TRUE);
+ g_ptr_array_free(finfo_array, true);
finfo_array = NULL;
}
if (cap_file_ && cap_file_->edt && cap_file_->edt->tree) {
finfo_array = proto_all_finfos(cap_file_->edt->tree);
QList<QString> added_proto_prefs;
- for (guint i = 0; i < finfo_array->len; i++) {
+ for (unsigned i = 0; i < finfo_array->len; i++) {
field_info *fi = (field_info *)g_ptr_array_index (finfo_array, i);
- header_field_info *hfinfo = fi->hfinfo;
+ const header_field_info *hfinfo = fi->hfinfo;
if (prefs_is_registered_protocol(hfinfo->abbrev)) {
if (hfinfo->parent == -1) {
@@ -654,8 +695,8 @@ void PacketList::contextMenuEvent(QContextMenuEvent *event)
ctx_menu->setAttribute(Qt::WA_DeleteOnClose);
// XXX We might want to reimplement setParent() and fill in the context
// menu there.
- ctx_menu->addAction(window()->findChild<QAction *>("actionEditMarkPacket"));
- ctx_menu->addAction(window()->findChild<QAction *>("actionEditIgnorePacket"));
+ ctx_menu->addAction(window()->findChild<QAction *>("actionEditMarkSelected"));
+ ctx_menu->addAction(window()->findChild<QAction *>("actionEditIgnoreSelected"));
ctx_menu->addAction(window()->findChild<QAction *>("actionEditSetTimeReference"));
ctx_menu->addAction(window()->findChild<QAction *>("actionEditTimeShift"));
ctx_menu->addMenu(window()->findChild<QMenu *>("menuPacketComment"));
@@ -728,6 +769,7 @@ void PacketList::contextMenuEvent(QContextMenuEvent *event)
main_menu_item = window()->findChild<QMenu *>("menuEditCopy");
submenu = new QMenu(main_menu_item->title(), ctx_menu);
+ submenu->setToolTipsVisible(true);
ctx_menu->addMenu(submenu);
QAction * action = submenu->addAction(tr("Summary as Text"));
@@ -749,15 +791,16 @@ void PacketList::contextMenuEvent(QContextMenuEvent *event)
copyEntries->setParent(submenu);
frameData->setParent(submenu);
- ctx_menu->addSeparator();
- ctx_menu->addMenu(&proto_prefs_menus_);
- action = ctx_menu->addAction(tr("Decode As…"));
- action->setProperty("create_new", QVariant(true));
- connect(action, &QAction::triggered, this, &PacketList::ctxDecodeAsDialog);
- // "Print" not ported intentionally
- action = window()->findChild<QAction *>("actionViewShowPacketInNewWindow");
- ctx_menu->addAction(action);
-
+ if (is_packet_configuration_namespace()) {
+ ctx_menu->addSeparator();
+ ctx_menu->addMenu(&proto_prefs_menus_);
+ action = ctx_menu->addAction(tr("Decode As…"));
+ action->setProperty("create_new", QVariant(true));
+ connect(action, &QAction::triggered, this, &PacketList::ctxDecodeAsDialog);
+ // "Print" not ported intentionally
+ action = window()->findChild<QAction *>("actionViewShowPacketInNewWindow");
+ ctx_menu->addAction(action);
+ }
// Set menu sensitivity for the current column and set action data.
if (frameData)
@@ -805,9 +848,7 @@ void PacketList::paintEvent(QPaintEvent *event)
void PacketList::mousePressEvent (QMouseEvent *event)
{
- setAutoScroll(false);
QTreeView::mousePressEvent(event);
- setAutoScroll(true);
QModelIndex curIndex = indexAt(event->pos());
mouse_pressed_at_ = curIndex;
@@ -918,23 +959,7 @@ void PacketList::mouseMoveEvent (QMouseEvent *event)
void PacketList::keyPressEvent(QKeyEvent *event)
{
- bool handled = false;
- // If scrolling up/down, want to preserve horizontal scroll extent.
- if (event->key() == Qt::Key_Down || event->key() == Qt::Key_Up ||
- event->key() == Qt::Key_PageDown || event->key() == Qt::Key_PageUp ||
- event->key() == Qt::Key_End || event->key() == Qt::Key_Home )
- {
- // XXX: Why allow jumping to the left if the first column is current?
- if (currentIndex().isValid() && currentIndex().column() > 0) {
- int pos = horizontalScrollBar()->value();
- QTreeView::keyPressEvent(event);
- horizontalScrollBar()->setValue(pos);
- handled = true;
- }
- }
-
- if (!handled)
- QTreeView::keyPressEvent(event);
+ QTreeView::keyPressEvent(event);
if (event->matches(QKeySequence::Copy))
{
@@ -1008,19 +1033,11 @@ void PacketList::setRecentColumnWidth(int col)
const char *long_str = get_column_width_string(fmt, col);
QFontMetrics fm = QFontMetrics(mainApp->monospaceFont());
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
if (long_str) {
col_width = fm.horizontalAdvance(long_str);
} else {
col_width = fm.horizontalAdvance(MIN_COL_WIDTH_STR);
}
-#else
- if (long_str) {
- col_width = fm.width(long_str);
- } else {
- col_width = fm.width(MIN_COL_WIDTH_STR);
- }
-#endif
// Custom delegate padding
if (itemDelegateForColumn(col)) {
QStyleOptionViewItem option;
@@ -1038,6 +1055,8 @@ void PacketList::setRecentColumnWidth(int col)
void PacketList::drawCurrentPacket()
{
+ // XXX - Update for multi-select? If more than one packet is Selected,
+ // this changes it so that only the Current packet is Selected.
QModelIndex current_index = currentIndex();
if (selectionModel() && current_index.isValid()) {
selectionModel()->clearSelection();
@@ -1100,6 +1119,14 @@ bool PacketList::havePreviousHistory(bool update_cur)
return false;
}
+void PacketList::setProfileSwitcher(ProfileSwitcher *profile_switcher)
+{
+ profile_switcher_ = profile_switcher;
+ if (profile_switcher) {
+ connect(packet_list_model_, &PacketListModel::packetAppended, profile_switcher_, &ProfileSwitcher::checkPacket);
+ }
+}
+
frame_data *PacketList::getFDataForRow(int row) const
{
return packet_list_model_->getRowFdata(row);
@@ -1118,7 +1145,7 @@ void PacketList::columnsChanged()
prefs.num_cols = g_list_length(prefs.col_list);
col_cleanup(&cap_file_->cinfo);
- build_column_format_array(&cap_file_->cinfo, prefs.num_cols, FALSE);
+ build_column_format_array(&cap_file_->cinfo, prefs.num_cols, false);
create_far_overlay_ = true;
resetColumns();
applyRecentColumnWidths();
@@ -1131,7 +1158,7 @@ void PacketList::fieldsChanged(capture_file *cf)
{
prefs.num_cols = g_list_length(prefs.col_list);
col_cleanup(&cf->cinfo);
- build_column_format_array(&cf->cinfo, prefs.num_cols, FALSE);
+ build_column_format_array(&cf->cinfo, prefs.num_cols, false);
resetColumns();
}
@@ -1161,9 +1188,6 @@ void PacketList::applyRecentColumnWidths()
void PacketList::preferencesChanged()
{
- // Update color style changes
- colorsChanged();
-
// Related packet delegate
if (prefs.gui_packet_list_show_related) {
setItemDelegateForColumn(0, &related_packet_delegate_);
@@ -1327,8 +1351,8 @@ void PacketList::clear() {
}
void PacketList::writeRecent(FILE *rf) {
- gint col, width, col_fmt;
- gchar xalign;
+ int col, width, col_fmt;
+ char xalign;
fprintf (rf, "%s:\n", RECENT_KEY_COL_WIDTH);
for (col = 0; col < prefs.num_cols; col++) {
@@ -1385,7 +1409,7 @@ QString PacketList::getFilterFromRowAndColumn(QModelIndex idx)
return filter; /* error reading the record */
}
/* proto tree, visible. We need a proto tree if there's custom columns */
- epan_dissect_init(&edt, cap_file_->epan, have_custom_cols(&cap_file_->cinfo), FALSE);
+ epan_dissect_init(&edt, cap_file_->epan, have_custom_cols(&cap_file_->cinfo), false);
col_custom_prime_edt(&edt, &cap_file_->cinfo);
epan_dissect_run(&edt, cap_file_->cd_t, &rec,
@@ -1398,14 +1422,14 @@ QString PacketList::getFilterFromRowAndColumn(QModelIndex idx)
/* We don't need to fill in the custom columns, as we get their
* filters above.
*/
- col_fill_in(&edt.pi, TRUE, TRUE);
+ col_fill_in(&edt.pi, true, true);
if (strlen(cap_file_->cinfo.col_expr.col_expr[column]) != 0 &&
strlen(cap_file_->cinfo.col_expr.col_expr_val[column]) != 0) {
- gboolean is_string_value = FALSE;
+ bool is_string_value = false;
header_field_info *hfi = proto_registrar_get_byname(cap_file_->cinfo.col_expr.col_expr[column]);
- if (hfi && hfi->type == FT_STRING) {
+ if (hfi && FT_IS_STRING(hfi->type)) {
/* Could be an address type such as usb.src which must be quoted. */
- is_string_value = TRUE;
+ is_string_value = true;
}
if (filter.isEmpty()) {
@@ -1436,7 +1460,7 @@ void PacketList::resetColorized()
update();
}
-QString PacketList::getPacketComment(guint c_number)
+QString PacketList::getPacketComment(unsigned c_number)
{
int row = currentIndex().row();
const frame_data *fdata;
@@ -1485,7 +1509,7 @@ void PacketList::addPacketComment(QString new_comment)
}
}
-void PacketList::setPacketComment(guint c_number, QString new_comment)
+void PacketList::setPacketComment(unsigned c_number, QString new_comment)
{
QModelIndex curIndex = currentIndex();
@@ -1511,7 +1535,7 @@ void PacketList::setPacketComment(guint c_number, QString new_comment)
QString PacketList::allPacketComments()
{
- guint32 framenum;
+ uint32_t framenum;
frame_data *fdata;
QString buf_str;
@@ -1523,8 +1547,8 @@ QString PacketList::allPacketComments()
wtap_block_t pkt_block = cf_get_packet_block(cap_file_, fdata);
if (pkt_block) {
- guint n_comments = wtap_block_count_option(pkt_block, OPT_COMMENT);
- for (guint i = 0; i < n_comments; i++) {
+ unsigned n_comments = wtap_block_count_option(pkt_block, OPT_COMMENT);
+ for (unsigned i = 0; i < n_comments; i++) {
char *comment_text;
if (WTAP_OPTTYPE_SUCCESS == wtap_block_get_nth_string_option_value(pkt_block, OPT_COMMENT, i, &comment_text)) {
buf_str.append(QString(tr("Frame %1: %2\n\n")).arg(framenum).arg(comment_text));
@@ -1582,7 +1606,12 @@ void PacketList::setCaptureFile(capture_file *cf)
void PacketList::setMonospaceFont(const QFont &mono_font)
{
setFont(mono_font);
- header()->setFont(mainApp->font());
+}
+
+void PacketList::setRegularFont(const QFont &regular_font)
+{
+ header()->setFont(regular_font);
+ header()->viewport()->setFont(regular_font);
}
void PacketList::goNextPacket(void)
@@ -1642,16 +1671,14 @@ void PacketList::goLastPacket(void) {
scrollViewChanged(false);
}
-// XXX We can jump to the wrong packet if a display filter is applied
void PacketList::goToPacket(int packet, int hf_id)
{
- if (!cf_goto_frame(cap_file_, packet))
+ if (!cf_goto_frame(cap_file_, packet, false))
return;
- int row = packet_list_model_->packetNumberToRow(packet);
- if (row >= 0) {
- selectionModel()->setCurrentIndex(packet_list_model_->index(row, 0), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
- scrollTo(currentIndex(), PositionAtCenter);
+ // cf_goto_frame only returns true if packet_list_select_row_from_data
+ // succeeds, the latter has already selected and scrolled to the frame.
+ if (hf_id > 0) {
proto_tree_->goToHfid(hf_id);
}
@@ -1808,7 +1835,7 @@ void PacketList::sectionResized(int col, int, int new_width)
// visible.
//
// Don't set column width when columns changed or setting column
- // visibility because we may get a sectionReized() from QTreeView
+ // visibility because we may get a sectionResized() from QTreeView
// with values from a old columns layout.
//
// Don't set column width when hiding a column.
@@ -1823,6 +1850,7 @@ void PacketList::sectionResized(int col, int, int new_width)
void PacketList::sectionMoved(int logicalIndex, int oldVisualIndex, int newVisualIndex)
{
GList *new_col_list = NULL;
+ GList *new_recent_col_list = NULL;
QList<int> saved_sizes;
int sort_idx;
@@ -1847,9 +1875,14 @@ void PacketList::sectionMoved(int logicalIndex, int oldVisualIndex, int newVisua
saved_sizes << header()->sectionSize(log_idx);
void *pref_data = g_list_nth_data(prefs.col_list, log_idx);
- if (!pref_data) continue;
+ if (pref_data) {
+ new_col_list = g_list_append(new_col_list, pref_data);
+ }
- new_col_list = g_list_append(new_col_list, pref_data);
+ pref_data = g_list_nth_data(recent.col_width_list, log_idx);
+ if (pref_data) {
+ new_recent_col_list = g_list_append(new_recent_col_list, pref_data);
+ }
}
// Undo move to ensure that the logical indices map to the visual indices,
@@ -1867,6 +1900,8 @@ void PacketList::sectionMoved(int logicalIndex, int oldVisualIndex, int newVisua
g_list_free(prefs.col_list);
prefs.col_list = new_col_list;
+ g_list_free(recent.col_width_list);
+ recent.col_width_list = new_recent_col_list;
thaw(true);
@@ -1986,7 +2021,7 @@ void PacketList::scrollViewChanged(bool at_end)
// out colors.
// Try 3: One packet per vertical scroll bar pixel. This seems to work best
// but has the smallest window.
-// Try 4: Use a multiple of the scroll bar heigh and scale the image down
+// Try 4: Use a multiple of the scroll bar height and scale the image down
// using Qt::SmoothTransformation. This gives us more packets per raster
// line.
diff --git a/ui/qt/packet_list.h b/ui/qt/packet_list.h
index 2b025e25..8667bf5e 100644
--- a/ui/qt/packet_list.h
+++ b/ui/qt/packet_list.h
@@ -24,6 +24,7 @@
class PacketListHeader;
class OverlayScrollBar;
+class ProfileSwitcher;
class QAction;
class QTimerEvent;
@@ -49,6 +50,7 @@ public:
};
Q_ENUM(SummaryCopyType)
+ virtual void scrollTo(const QModelIndex &index, QAbstractItemView::ScrollHint hint = EnsureVisible) override;
QMenu *conversationMenu() { return &conv_menu_; }
QMenu *colorizeMenu() { return &colorize_menu_; }
void setProtoTree(ProtoTree *proto_tree);
@@ -73,9 +75,9 @@ public:
bool contextMenuActive();
QString getFilterFromRowAndColumn(QModelIndex idx);
void resetColorized();
- QString getPacketComment(guint c_number);
+ QString getPacketComment(unsigned c_number);
void addPacketComment(QString new_comment);
- void setPacketComment(guint c_number, QString new_comment);
+ void setPacketComment(unsigned c_number, QString new_comment);
QString allPacketComments();
void deleteCommentsFromPackets();
void deleteAllPacketComments();
@@ -85,6 +87,7 @@ public:
void resetColumns();
bool haveNextHistory(bool update_cur = false);
bool havePreviousHistory(bool update_cur = false);
+ void setProfileSwitcher(ProfileSwitcher *profile_switcher);
frame_data * getFDataForRow(int row) const;
@@ -147,15 +150,15 @@ private:
int cur_history_;
bool in_history_;
GPtrArray *finfo_array; // Packet data from the last selected packet entry
+ ProfileSwitcher *profile_switcher_;
- void setFrameReftime(gboolean set, frame_data *fdata);
+ void setFrameReftime(bool set, frame_data *fdata);
void setColumnVisibility();
int sizeHintForColumn(int column) const override;
void setRecentColumnWidth(int column);
void drawCurrentPacket();
void applyRecentColumnWidths();
void scrollViewChanged(bool at_end);
- void colorsChanged();
QString joinSummaryRow(QStringList col_parts, int row, SummaryCopyType type);
signals:
@@ -172,6 +175,7 @@ signals:
public slots:
void setCaptureFile(capture_file *cf);
void setMonospaceFont(const QFont &mono_font);
+ void setRegularFont(const QFont &regular_font);
void goNextPacket();
void goPreviousPacket();
void goFirstPacket();
@@ -189,6 +193,7 @@ public slots:
void recolorPackets();
void redrawVisiblePackets();
void redrawVisiblePacketsDontSelectCurrent();
+ void colorsChanged();
void columnsChanged();
void fieldsChanged(capture_file *cf);
void preferencesChanged();
diff --git a/ui/qt/packet_range_group_box.cpp b/ui/qt/packet_range_group_box.cpp
index 143da613..068f36a7 100644
--- a/ui/qt/packet_range_group_box.cpp
+++ b/ui/qt/packet_range_group_box.cpp
@@ -113,12 +113,23 @@ void PacketRangeGroupBox::updateCounts() {
pr_ui_->selectedDisplayedLabel->setEnabled(displayed_checked);
if (range_->include_dependents) {
- pr_ui_->selectedCapturedLabel->setText(QString::number(range_->selected_plus_depends_cnt));
- pr_ui_->selectedDisplayedLabel->setText(QString::number(range_->displayed_selected_plus_depends_cnt));
+ label_count = range_->selected_plus_depends_cnt;
} else {
- pr_ui_->selectedCapturedLabel->setText(QString::number(range_->selection_range_cnt));
- pr_ui_->selectedDisplayedLabel->setText(QString::number(range_->displayed_selection_range_cnt));
+ label_count = range_->selection_range_cnt;
}
+ if (range_->remove_ignored) {
+ label_count -= range_->ignored_selection_range_cnt;
+ }
+ pr_ui_->selectedCapturedLabel->setText(QString::number(label_count));
+ if (range_->include_dependents) {
+ label_count = range_->displayed_selected_plus_depends_cnt;
+ } else {
+ label_count = range_->displayed_selection_range_cnt;
+ }
+ if (range_->remove_ignored) {
+ label_count -= range_->displayed_ignored_selection_range_cnt;
+ }
+ pr_ui_->selectedDisplayedLabel->setText(QString::number(label_count));
} else {
if (range_->process == range_process_selected) {
pr_ui_->allButton->setChecked(true);
@@ -396,7 +407,7 @@ void PacketRangeGroupBox::on_rangeButton_toggled(bool checked)
void PacketRangeGroupBox::on_capturedButton_toggled(bool checked)
{
if (checked) {
- if (range_) range_->process_filtered = FALSE;
+ if (range_) range_->process_filtered = false;
updateCounts();
}
}
@@ -404,21 +415,21 @@ void PacketRangeGroupBox::on_capturedButton_toggled(bool checked)
void PacketRangeGroupBox::on_displayedButton_toggled(bool checked)
{
if (checked) {
- if (range_) range_->process_filtered = TRUE;
+ if (range_) range_->process_filtered = true;
updateCounts();
}
}
void PacketRangeGroupBox::on_ignoredCheckBox_toggled(bool checked)
{
- if (range_) range_->remove_ignored = checked ? TRUE : FALSE;
+ if (range_) range_->remove_ignored = checked ? true : false;
updateCounts();
}
void PacketRangeGroupBox::on_dependedCheckBox_toggled(bool checked)
{
if (range_) {
- range_->include_dependents = checked ? TRUE : FALSE;
+ range_->include_dependents = checked ? true : false;
updateCounts();
}
}
diff --git a/ui/qt/packet_range_group_box.h b/ui/qt/packet_range_group_box.h
index 1912d71d..44fb1790 100644
--- a/ui/qt/packet_range_group_box.h
+++ b/ui/qt/packet_range_group_box.h
@@ -12,8 +12,6 @@
#include <config.h>
-#include <glib.h>
-
#include <ui/packet_range.h>
#include <ui/qt/widgets/syntax_line_edit.h>
diff --git a/ui/qt/preference_editor_frame.cpp b/ui/qt/preference_editor_frame.cpp
index 4ebce5c9..eec2571a 100644
--- a/ui/qt/preference_editor_frame.cpp
+++ b/ui/qt/preference_editor_frame.cpp
@@ -9,8 +9,6 @@
#include "config.h"
-#include <glib.h>
-
#include <epan/prefs.h>
#include <epan/prefs-int.h>
#include <epan/decode_as.h>
@@ -49,6 +47,9 @@ PreferenceEditorFrame::PreferenceEditorFrame(QWidget *parent) :
#endif
connect(ui->preferenceBrowseButton, &QPushButton::clicked, this, &PreferenceEditorFrame::browsePushButtonClicked);
+
+ // Disconnect textChanged signal for DissectorSyntaxLineEdit.
+ disconnect(ui->preferenceLineEdit, &DissectorSyntaxLineEdit::textChanged, NULL, NULL);
}
PreferenceEditorFrame::~PreferenceEditorFrame()
@@ -80,14 +81,15 @@ void PreferenceEditorFrame::editPreference(preference *pref, pref_module *module
ui->preferenceLineEdit->clear();
ui->preferenceLineEdit->setSyntaxState(SyntaxLineEdit::Empty);
- disconnect(ui->preferenceLineEdit, 0, 0, 0);
+
+ // Disconnect previous textChanged signal.
+ disconnect(ui->preferenceLineEdit, &SyntaxLineEdit::textChanged, this, NULL);
bool show = false;
bool browse_button = false;
switch (prefs_get_type(pref_)) {
case PREF_UINT:
- case PREF_DECODE_AS_UINT:
connect(ui->preferenceLineEdit, &SyntaxLineEdit::textChanged,
this, &PreferenceEditorFrame::uintLineEditTextEdited);
show = true;
@@ -99,6 +101,7 @@ void PreferenceEditorFrame::editPreference(preference *pref, pref_module *module
// Fallthrough
case PREF_STRING:
case PREF_PASSWORD:
+ case PREF_DISSECTOR:
connect(ui->preferenceLineEdit, &SyntaxLineEdit::textChanged,
this, &PreferenceEditorFrame::stringLineEditTextEdited);
show = true;
@@ -114,6 +117,16 @@ void PreferenceEditorFrame::editPreference(preference *pref, pref_module *module
}
if (show) {
+ // Enable completion only for display filter search.
+ if (prefs_get_type(pref_) == PREF_DISSECTOR) {
+ ui->preferenceLineEdit->allowCompletion(true);
+ ui->preferenceLineEdit->updateDissectorNames();
+ ui->preferenceLineEdit->setDefaultPlaceholderText();
+ } else {
+ ui->preferenceLineEdit->allowCompletion(false);
+ ui->preferenceLineEdit->setPlaceholderText("");
+ }
+
ui->preferenceLineEdit->setText(gchar_free_to_qstring(prefs_pref_to_str(pref_, pref_stashed)).remove(QRegularExpression("\n\t")));
ui->preferenceBrowseButton->setHidden(!browse_button);
animatedShow();
@@ -143,8 +156,15 @@ void PreferenceEditorFrame::uintLineEditTextEdited(const QString &new_str)
void PreferenceEditorFrame::stringLineEditTextEdited(const QString &new_str)
{
+ bool ok = true;
new_str_ = new_str;
- ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
+
+ if (prefs_get_type(pref_) == PREF_DISSECTOR) {
+ ui->preferenceLineEdit->checkDissectorName(new_str_);
+ ok = (ui->preferenceLineEdit->syntaxState() != SyntaxLineEdit::Invalid);
+ }
+
+ ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(ok);
}
void PreferenceEditorFrame::browsePushButtonClicked()
@@ -220,13 +240,13 @@ void PreferenceEditorFrame::on_buttonBox_accepted()
unsigned int apply = 0;
switch(prefs_get_type(pref_)) {
case PREF_UINT:
- case PREF_DECODE_AS_UINT:
apply = prefs_set_uint_value(pref_, new_uint_, pref_stashed);
break;
case PREF_STRING:
case PREF_SAVE_FILENAME:
case PREF_OPEN_FILENAME:
case PREF_DIRNAME:
+ case PREF_DISSECTOR:
apply = prefs_set_string_value(pref_, new_str_.toStdString().c_str(), pref_stashed);
break;
case PREF_PASSWORD:
@@ -245,13 +265,13 @@ void PreferenceEditorFrame::on_buttonBox_accepted()
pref_unstash_data_t unstashed_data;
unstashed_data.module = module_;
- unstashed_data.handle_decode_as = TRUE;
+ unstashed_data.handle_decode_as = true;
pref_unstash(pref_, &unstashed_data);
prefs_apply(module_);
prefs_main_write();
- gchar* err = NULL;
+ char* err = NULL;
if (save_decode_as_entries(&err) < 0)
{
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err);
@@ -280,7 +300,7 @@ void PreferenceEditorFrame::on_buttonBox_rejected()
void PreferenceEditorFrame::keyPressEvent(QKeyEvent *event)
{
- if (event->modifiers() == Qt::NoModifier) {
+ if (pref_ && module_ && (event->modifiers() == Qt::NoModifier)) {
if (event->key() == Qt::Key_Escape) {
on_buttonBox_rejected();
} else if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
diff --git a/ui/qt/preference_editor_frame.ui b/ui/qt/preference_editor_frame.ui
index 6b8900e2..52b11dca 100644
--- a/ui/qt/preference_editor_frame.ui
+++ b/ui/qt/preference_editor_frame.ui
@@ -54,7 +54,7 @@
</widget>
</item>
<item>
- <widget class="SyntaxLineEdit" name="preferenceLineEdit">
+ <widget class="DissectorSyntaxLineEdit" name="preferenceLineEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>1</horstretch>
@@ -106,9 +106,9 @@
<container>1</container>
</customwidget>
<customwidget>
- <class>SyntaxLineEdit</class>
- <extends>QLineEdit</extends>
- <header>widgets/syntax_line_edit.h</header>
+ <class>DissectorSyntaxLineEdit</class>
+ <extends>SyntaxLineEdit</extends>
+ <header>widgets/dissector_syntax_line_edit.h</header>
</customwidget>
</customwidgets>
<resources/>
diff --git a/ui/qt/preferences_dialog.cpp b/ui/qt/preferences_dialog.cpp
index 7f78350c..76a880e2 100644
--- a/ui/qt/preferences_dialog.cpp
+++ b/ui/qt/preferences_dialog.cpp
@@ -22,21 +22,25 @@
#include <ui/simple_dialog.h>
#include <ui/recent.h>
#include <main_window.h>
+#include <extcap.h>
#include <ui/qt/utils/qt_ui_utils.h>
#include "main_application.h"
+#include <QDesktopServices>
+#include <QUrl>
+
extern "C" {
// Callbacks prefs routines
-static guint
-module_prefs_unstash(module_t *module, gpointer data)
+static unsigned
+module_prefs_unstash(module_t *module, void *data)
{
- gboolean *must_redissect_p = static_cast<gboolean *>(data);
+ unsigned int *must_redissect_p = static_cast<unsigned int *>(data);
pref_unstash_data_t unstashed_data;
- unstashed_data.handle_decode_as = TRUE;
+ unstashed_data.handle_decode_as = true;
module->prefs_changed_flags = 0; /* assume none of them changed */
for (GList *pref_l = module->prefs; pref_l && pref_l->data; pref_l = gxx_list_next(pref_l)) {
@@ -60,8 +64,8 @@ module_prefs_unstash(module_t *module, gpointer data)
return 0; /* Keep unstashing. */
}
-static guint
-module_prefs_clean_stash(module_t *module, gpointer)
+static unsigned
+module_prefs_clean_stash(module_t *module, void *)
{
for (GList *pref_l = module->prefs; pref_l && pref_l->data; pref_l = gxx_list_next(pref_l)) {
pref_t *pref = gxx_list_data(pref_t *, pref_l);
@@ -112,6 +116,13 @@ PreferencesDialog::PreferencesDialog(QWidget *parent) :
pd_ui_->splitter->setStretchFactor(0, 1);
pd_ui_->splitter->setStretchFactor(1, 5);
+
+ // The calculations done in showEvent to set the minimum size of the
+ // protocol column mean that if we load the splitter state it will become
+ // impossible to shrink the splitter below the width of the widest protocol
+ // that initially fits, so don't do this unless we change showEvent.
+ //loadSplitterState(pd_ui_->splitter);
+
pd_ui_->prefsView->sortByColumn(ModulePrefsModel::colName, Qt::AscendingOrder);
//Set the Appearance leaf to expanded
@@ -225,7 +236,7 @@ void PreferencesDialog::on_advancedSearchLineEdit_textEdited(const QString &text
* the countdown.
*/
searchLineEditText = text;
- guint gui_debounce_timer = prefs_get_uint_value("gui", "debounce.timer");
+ unsigned gui_debounce_timer = prefs_get_uint_value("gui", "debounce.timer");
searchLineEditTimer->start(gui_debounce_timer);
}
@@ -237,19 +248,25 @@ void PreferencesDialog::on_showChangedValuesCheckBox_toggled(bool checked)
pd_ui_->advancedView->expandAll();
}
-void PreferencesDialog::on_buttonBox_accepted()
+void PreferencesDialog::apply()
{
- gchar* err = NULL;
+ char* err = NULL;
unsigned int redissect_flags = 0;
// XXX - We should validate preferences as the user changes them, not here.
// XXX - We're also too enthusiastic about setting must_redissect.
- prefs_modules_foreach_submodules(NULL, module_prefs_unstash, (gpointer)&redissect_flags);
+ prefs_modules_foreach_submodules(NULL, module_prefs_unstash, (void *)&redissect_flags);
+
+ extcap_register_preferences();
if (redissect_flags & PREF_EFFECT_GUI_LAYOUT) {
// Layout type changed, reset sizes
recent.gui_geometry_main_upper_pane = 0;
recent.gui_geometry_main_lower_pane = 0;
+ g_free(recent.gui_geometry_main_master_split);
+ g_free(recent.gui_geometry_main_extra_split);
+ recent.gui_geometry_main_master_split = NULL;
+ recent.gui_geometry_main_extra_split = NULL;
}
pd_ui_->columnFrame->unstash();
@@ -299,28 +316,41 @@ void PreferencesDialog::on_buttonBox_accepted()
mainApp->setMonospaceFont(prefs.gui_font_name);
+ if (redissect_flags & (PREF_EFFECT_GUI_COLOR)) {
+ mainApp->emitAppSignal(MainApplication::ColorsChanged);
+ }
+
if (redissect_flags & PREF_EFFECT_FIELDS) {
- mainApp->queueAppSignal(MainApplication::FieldsChanged);
+ mainApp->emitAppSignal(MainApplication::FieldsChanged);
}
if (redissect_flags & PREF_EFFECT_DISSECTION) {
// Freeze the packet list early to avoid updating column data before doing a
// full redissection. The packet list will be thawed when redissection is done.
- mainApp->queueAppSignal(MainApplication::FreezePacketList);
+ mainApp->emitAppSignal(MainApplication::FreezePacketList);
/* Redissect all the packets, and re-evaluate the display filter. */
- mainApp->queueAppSignal(MainApplication::PacketDissectionChanged);
+ mainApp->emitAppSignal(MainApplication::PacketDissectionChanged);
+ }
+
+ if (redissect_flags) {
+ mainApp->emitAppSignal(MainApplication::PreferencesChanged);
}
- mainApp->queueAppSignal(MainApplication::PreferencesChanged);
if (redissect_flags & PREF_EFFECT_GUI_LAYOUT) {
- mainApp->queueAppSignal(MainApplication::RecentPreferencesRead);
+ mainApp->emitAppSignal(MainApplication::RecentPreferencesRead);
}
if (prefs.capture_no_extcap != saved_capture_no_extcap_)
mainApp->refreshLocalInterfaces();
}
+void PreferencesDialog::on_buttonBox_accepted()
+{
+ apply();
+ accept();
+}
+
void PreferencesDialog::on_buttonBox_rejected()
{
//handle frames that don't have their own OK/Cancel "buttons"
@@ -329,9 +359,24 @@ void PreferencesDialog::on_buttonBox_rejected()
#ifdef HAVE_LIBGNUTLS
pd_ui_->rsaKeysFrame->rejectChanges();
#endif
+ reject();
+}
+
+void PreferencesDialog::on_buttonBox_clicked(QAbstractButton *button)
+{
+ if (pd_ui_->buttonBox->buttonRole(button) == QDialogButtonBox::ApplyRole) {
+ apply();
+ }
}
void PreferencesDialog::on_buttonBox_helpRequested()
{
- mainApp->helpTopicAction(HELP_PREFERENCES_DIALOG);
+ QString help_page = modulePrefsModel_.data(pd_ui_->prefsView->currentIndex(), ModulePrefsModel::ModuleHelp).toString();
+ if (!help_page.isEmpty()) {
+ QString url = gchar_free_to_qstring(user_guide_url(help_page.toUtf8().constData()));
+ QDesktopServices::openUrl(QUrl(url));
+ } else {
+ // Generic help
+ mainApp->helpTopicAction(HELP_PREFERENCES_DIALOG);
+ }
}
diff --git a/ui/qt/preferences_dialog.h b/ui/qt/preferences_dialog.h
index 51760699..b295aeaa 100644
--- a/ui/qt/preferences_dialog.h
+++ b/ui/qt/preferences_dialog.h
@@ -20,6 +20,7 @@
#include "geometry_state_dialog.h"
class QComboBox;
+class QAbstractButton;
namespace Ui {
class PreferencesDialog;
@@ -44,6 +45,8 @@ protected:
void showEvent(QShowEvent *evt);
private:
+ void apply();
+
Ui::PreferencesDialog *pd_ui_;
QHash<QString, QWidget*> prefs_pane_to_item_;
@@ -52,7 +55,7 @@ private:
AdvancedPrefsModel advancedPrefsModel_;
AdvancedPrefDelegate advancedPrefsDelegate_;
ModulePrefsModel modulePrefsModel_;
- gboolean saved_capture_no_extcap_;
+ bool saved_capture_no_extcap_;
QTimer *searchLineEditTimer;
QString searchLineEditText;
@@ -65,6 +68,7 @@ private slots:
void on_buttonBox_accepted();
void on_buttonBox_rejected();
void on_buttonBox_helpRequested();
+ void on_buttonBox_clicked(QAbstractButton *button);
/**
* Update search results from the advancedSearchLineEdit field
diff --git a/ui/qt/preferences_dialog.ui b/ui/qt/preferences_dialog.ui
index e6c625bb..dc016ae0 100644
--- a/ui/qt/preferences_dialog.ui
+++ b/ui/qt/preferences_dialog.ui
@@ -111,7 +111,7 @@
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok</set>
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Help|QDialogButtonBox::Ok|QDialogButtonBox::Apply</set>
</property>
</widget>
</item>
@@ -168,38 +168,4 @@
</customwidget>
</customwidgets>
<resources/>
- <connections>
- <connection>
- <sender>buttonBox</sender>
- <signal>accepted()</signal>
- <receiver>PreferencesDialog</receiver>
- <slot>accept()</slot>
- <hints>
- <hint type="sourcelabel">
- <x>248</x>
- <y>254</y>
- </hint>
- <hint type="destinationlabel">
- <x>157</x>
- <y>274</y>
- </hint>
- </hints>
- </connection>
- <connection>
- <sender>buttonBox</sender>
- <signal>rejected()</signal>
- <receiver>PreferencesDialog</receiver>
- <slot>reject()</slot>
- <hints>
- <hint type="sourcelabel">
- <x>316</x>
- <y>260</y>
- </hint>
- <hint type="destinationlabel">
- <x>286</x>
- <y>274</y>
- </hint>
- </hints>
- </connection>
- </connections>
</ui>
diff --git a/ui/qt/print_dialog.cpp b/ui/qt/print_dialog.cpp
index 84c2d906..413510b4 100644
--- a/ui/qt/print_dialog.cpp
+++ b/ui/qt/print_dialog.cpp
@@ -32,32 +32,32 @@ extern "C" {
// Page element callbacks
-static gboolean
-print_preamble_pd(print_stream_t *self, gchar *, const char *)
+static bool
+print_preamble_pd(print_stream_t *self, char *, const char *)
{
- if (!self) return FALSE;
+ if (!self) return false;
PrintDialog *print_dlg = static_cast<PrintDialog *>(self->data);
- if (!print_dlg) return FALSE;
+ if (!print_dlg) return false;
return print_dlg->printHeader();
}
-static gboolean
+static bool
print_line_pd(print_stream_t *self, int indent, const char *line)
{
- if (!self) return FALSE;
+ if (!self) return false;
PrintDialog *print_dlg = static_cast<PrintDialog *>(self->data);
- if (!print_dlg) return FALSE;
+ if (!print_dlg) return false;
return print_dlg->printLine(indent, line);
}
-static gboolean
+static bool
new_page_pd(print_stream_t *self)
{
- if (!self) return FALSE;
+ if (!self) return false;
PrintDialog *print_dlg = static_cast<PrintDialog *>(self->data);
- if (!print_dlg) return FALSE;
+ if (!print_dlg) return false;
return print_dlg->printHeader();
}
@@ -73,7 +73,7 @@ PrintDialog::PrintDialog(QWidget *parent, capture_file *cf, QString selRange) :
print_bt_(new QPushButton(tr("&Print…"))),
cap_file_(cf),
page_pos_(0),
- in_preview_(FALSE)
+ in_preview_(false)
{
Q_ASSERT(cf);
@@ -97,7 +97,7 @@ PrintDialog::PrintDialog(QWidget *parent, capture_file *cf, QString selRange) :
/* Init the export range */
packet_range_init(&print_args_.range, cap_file_);
/* Default to displayed packets */
- print_args_.range.process_filtered = TRUE;
+ print_args_.range.process_filtered = true;
stream_ops_.print_preamble = print_preamble_pd;
stream_ops_.print_line = print_line_pd;
@@ -107,7 +107,7 @@ PrintDialog::PrintDialog(QWidget *parent, capture_file *cf, QString selRange) :
stream_.ops = &stream_ops_;
print_args_.stream = &stream_;
- gchar *display_basename = g_filename_display_basename(cap_file_->filename);
+ char *display_basename = g_filename_display_basename(cap_file_->filename);
printer_.setDocName(display_basename);
g_free(display_basename);
@@ -136,9 +136,9 @@ PrintDialog::~PrintDialog()
delete pd_ui_;
}
-gboolean PrintDialog::printHeader()
+bool PrintDialog::printHeader()
{
- if (!cap_file_ || !cap_file_->filename || !cur_printer_ || !cur_painter_) return FALSE;
+ if (!cap_file_ || !cap_file_->filename || !cur_printer_ || !cur_painter_) return false;
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
int page_top = cur_printer_->pageLayout().paintRectPixels(cur_printer_->resolution()).top();
#else
@@ -149,7 +149,7 @@ gboolean PrintDialog::printHeader()
if (in_preview_) {
// When generating a preview, only generate the first page;
// if we're past the first page, stop the printing process.
- return FALSE;
+ return false;
}
// Second and subsequent pages only
cur_printer_->newPage();
@@ -160,21 +160,21 @@ gboolean PrintDialog::printHeader()
QString banner = QString(tr("%1 %2 total packets, %3 shown"))
.arg(cap_file_->filename)
.arg(cap_file_->count)
- .arg(cap_file_->displayed_count);
+ .arg(packet_range_count(&print_args_.range));
cur_painter_->setFont(header_font_);
cur_painter_->drawText(0, page_top, banner);
}
page_pos_ += cur_painter_->fontMetrics().height();
cur_painter_->setFont(packet_font_);
- return TRUE;
+ return true;
}
-gboolean PrintDialog::printLine(int indent, const char *line)
+bool PrintDialog::printLine(int indent, const char *line)
{
QRect out_rect, page_rect;
QString out_line;
- if (!line || !cur_printer_ || !cur_painter_) return FALSE;
+ if (!line || !cur_printer_ || !cur_painter_) return false;
/* Prepare the tabs for printing, depending on tree level */
out_line.fill(' ', indent * 4);
@@ -196,13 +196,13 @@ gboolean PrintDialog::printLine(int indent, const char *line)
if (in_preview_) {
// When generating a preview, only generate the first page;
// if we're past the first page, stop the printing process.
- return FALSE;
+ return false;
}
if (*line == '\0') {
// This is an empty line, so it's a separator; no need to
// waste space printing it at the top of a page, as the
// page break suffices as a separator.
- return TRUE;
+ return true;
}
printHeader();
}
@@ -210,7 +210,7 @@ gboolean PrintDialog::printLine(int indent, const char *line)
out_rect.translate(0, page_pos_);
cur_painter_->drawText(out_rect, Qt::TextWordWrap, out_line);
page_pos_ += out_rect.height();
- return TRUE;
+ return true;
}
// Protected
@@ -287,7 +287,7 @@ void PrintDialog::printPackets(QPrinter *printer, bool in_preview)
// Don't show a progress bar if we're previewing; if it takes a
// significant amount of time to generate a preview of the first
// page, We Have A Real Problem
- cf_print_packets(cap_file_, &print_args_, in_preview ? FALSE : TRUE);
+ cf_print_packets(cap_file_, &print_args_, in_preview ? false : true);
cur_printer_ = NULL;
cur_painter_ = NULL;
painter.end();
diff --git a/ui/qt/print_dialog.h b/ui/qt/print_dialog.h
index 88bda81e..eabb0b08 100644
--- a/ui/qt/print_dialog.h
+++ b/ui/qt/print_dialog.h
@@ -12,8 +12,6 @@
#include <config.h>
-#include <glib.h>
-
#include "file.h"
#include <QDialog>
@@ -33,8 +31,8 @@ public:
explicit PrintDialog(QWidget *parent = 0, capture_file *cf = NULL, QString selRange = QString());
~PrintDialog();
- gboolean printHeader();
- gboolean printLine(int indent, const char *line);
+ bool printHeader();
+ bool printLine(int indent, const char *line);
protected:
virtual void keyPressEvent(QKeyEvent *event) override;
diff --git a/ui/qt/profile_dialog.cpp b/ui/qt/profile_dialog.cpp
index 5b53a2cf..9de24054 100644
--- a/ui/qt/profile_dialog.cpp
+++ b/ui/qt/profile_dialog.cpp
@@ -8,11 +8,8 @@
*/
#include "config.h"
-#include <glib.h>
#include "wsutil/filesystem.h"
-#include "wsutil/utf8_entities.h"
-#include "epan/prefs.h"
#include <ui/qt/utils/qt_ui_utils.h>
@@ -27,6 +24,7 @@
#include "main_application.h"
#include <ui/qt/utils/color_utils.h>
#include <ui/qt/simple_dialog.h>
+#include <ui/qt/widgets/wireshark_file_dialog.h>
#include <QBrush>
#include <QDir>
@@ -37,7 +35,6 @@
#include <QUrl>
#include <QComboBox>
#include <QLineEdit>
-#include <QFileDialog>
#include <QStandardPaths>
#include <QKeyEvent>
#include <QMenu>
@@ -74,9 +71,16 @@ ProfileDialog::ProfileDialog(QWidget *parent) :
pd_ui_->hintLabel->setAttribute(Qt::WA_MacSmallSize, true);
#endif
+ QString as_tooltip = pd_ui_->autoSwitchLimitLabel->toolTip();
+ pd_ui_->autoSwitchSpinBox->setToolTip(as_tooltip);
+ if (!is_packet_configuration_namespace()) {
+ pd_ui_->autoSwitchLimitLabel->setText(tr("Auto switch event limit"));
+ }
+ pd_ui_->autoSwitchSpinBox->setValue(recent.gui_profile_switch_check_count);
+
import_button_ = pd_ui_->buttonBox->addButton(tr("Import", "noun"), QDialogButtonBox::ActionRole);
-#ifdef HAVE_MINIZIP
+#if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG)
export_button_ = pd_ui_->buttonBox->addButton(tr("Export", "noun"), QDialogButtonBox::ActionRole);
QMenu * importMenu = new QMenu(import_button_);
@@ -112,13 +116,23 @@ ProfileDialog::ProfileDialog(QWidget *parent) :
currentItemChanged();
+ connect(pd_ui_->newToolButton, &StockIconToolButton::clicked, this, &ProfileDialog::newToolButtonClicked);
+ connect(pd_ui_->deleteToolButton, &StockIconToolButton::clicked, this, &ProfileDialog::deleteToolButtonClicked);
+ connect(pd_ui_->copyToolButton, &StockIconToolButton::clicked, this, &ProfileDialog::copyToolButtonClicked);
+ connect(pd_ui_->buttonBox, &QDialogButtonBox::accepted, this, &ProfileDialog::buttonBoxAccepted);
+ connect(pd_ui_->buttonBox, &QDialogButtonBox::rejected, this, &ProfileDialog::buttonBoxRejected);
+ connect(pd_ui_->buttonBox, &QDialogButtonBox::helpRequested, this, &ProfileDialog::buttonBoxHelpRequested);
+
+ pd_ui_->profileTreeView->resizeColumnToContents(ProfileModel::COL_NAME);
+ pd_ui_->profileTreeView->resizeColumnToContents(ProfileModel::COL_TYPE);
+
pd_ui_->profileTreeView->setFocus();
}
ProfileDialog::~ProfileDialog()
{
delete pd_ui_;
- empty_profile_list (TRUE);
+ empty_profile_list (true);
}
void ProfileDialog::keyPressEvent(QKeyEvent *evt)
@@ -149,11 +163,11 @@ int ProfileDialog::execAction(ProfileDialog::ProfileAction profile_action)
ret = exec();
break;
case NewProfile:
- on_newToolButton_clicked();
+ newToolButtonClicked();
ret = exec();
break;
case ImportZipProfile:
-#ifdef HAVE_MINIZIP
+#if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG)
importFromZip();
#endif
break;
@@ -161,12 +175,12 @@ int ProfileDialog::execAction(ProfileDialog::ProfileAction profile_action)
importFromDirectory();
break;
case ExportSingleProfile:
-#ifdef HAVE_MINIZIP
+#if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG)
exportProfiles();
#endif
break;
case ExportAllProfiles:
-#ifdef HAVE_MINIZIP
+#if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG)
exportProfiles(true);
#endif
break;
@@ -249,7 +263,7 @@ void ProfileDialog::updateWidgets()
import_button_->setToolTip(msg);
import_button_->setEnabled(enable_import);
-#ifdef HAVE_MINIZIP
+#if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG)
bool contains_user = false;
bool enable_export = false;
@@ -294,7 +308,7 @@ void ProfileDialog::updateWidgets()
msg = tr("%Ln Selected Personal Profile(s)...", "", user_profiles);
pd_ui_->hintLabel->setText(msg);
-#ifdef HAVE_MINIZIP
+#if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG)
export_selected_entry_->setText(msg);
#endif
}
@@ -314,7 +328,7 @@ void ProfileDialog::updateWidgets()
}
pd_ui_->copyToolButton->setEnabled(true);
-#ifdef HAVE_MINIZIP
+#if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG)
export_selected_entry_->setText(msg);
#endif
}
@@ -365,9 +379,6 @@ void ProfileDialog::updateWidgets()
pd_ui_->hintLabel->setUrl(hintUrl);
- /* ensure the name column is resized to it's content */
- pd_ui_->profileTreeView->resizeColumnToContents(ProfileModel::COL_NAME);
-
pd_ui_->deleteToolButton->setEnabled(enable_del);
ok_button_->setEnabled(enable_ok);
}
@@ -377,7 +388,7 @@ void ProfileDialog::currentItemChanged(const QModelIndex &, const QModelIndex &)
updateWidgets();
}
-void ProfileDialog::on_newToolButton_clicked()
+void ProfileDialog::newToolButtonClicked()
{
pd_ui_->lineProfileFilter->setText("");
pd_ui_->cmbProfileTypes->setCurrentIndex(ProfileSortModel::AllProfiles);
@@ -395,7 +406,7 @@ void ProfileDialog::on_newToolButton_clicked()
updateWidgets();
}
-void ProfileDialog::on_deleteToolButton_clicked()
+void ProfileDialog::deleteToolButtonClicked()
{
QModelIndexList profiles = selectedProfiles();
if (profiles.count() <= 0)
@@ -417,7 +428,7 @@ void ProfileDialog::on_deleteToolButton_clicked()
updateWidgets();
}
-void ProfileDialog::on_copyToolButton_clicked()
+void ProfileDialog::copyToolButtonClicked()
{
QModelIndexList profiles = selectedProfiles();
if (profiles.count() > 1)
@@ -444,11 +455,13 @@ void ProfileDialog::on_copyToolButton_clicked()
updateWidgets();
}
-void ProfileDialog::on_buttonBox_accepted()
+void ProfileDialog::buttonBoxAccepted()
{
bool write_recent = true;
bool item_data_removed = false;
+ recent.gui_profile_switch_check_count = pd_ui_->autoSwitchSpinBox->value();
+
QModelIndex index = sort_model_->mapToSource(pd_ui_->profileTreeView->currentIndex());
pd_ui_->buttonBox->setFocus();
@@ -483,7 +496,7 @@ void ProfileDialog::on_buttonBox_accepted()
write_profile_recent();
}
- gchar * err_msg = Q_NULLPTR;
+ char * err_msg = Q_NULLPTR;
if ((err_msg = apply_profile_changes()) != Q_NULLPTR) {
QMessageBox::critical(this, tr("Profile Error"),
err_msg,
@@ -512,22 +525,22 @@ void ProfileDialog::on_buttonBox_accepted()
if (profileName.length() > 0 && model_->findByName(profileName) >= 0) {
// The new profile exists, change.
- mainApp->setConfigurationProfile (profileName.toUtf8().constData(), FALSE);
+ mainApp->setConfigurationProfile (profileName.toUtf8().constData(), false);
} else if (!model_->activeProfile().isValid()) {
// The new profile does not exist, and the previous profile has
// been deleted. Change to the default profile.
- mainApp->setConfigurationProfile (Q_NULLPTR, FALSE);
+ mainApp->setConfigurationProfile (Q_NULLPTR, false);
}
}
-void ProfileDialog::on_buttonBox_rejected()
+void ProfileDialog::buttonBoxRejected()
{
QString msg;
if (! model_->clearImported(&msg))
QMessageBox::critical(this, tr("Error"), msg);
}
-void ProfileDialog::on_buttonBox_helpRequested()
+void ProfileDialog::buttonBoxHelpRequested()
{
mainApp->helpTopicAction(HELP_CONFIG_PROFILES_DIALOG);
}
@@ -558,14 +571,12 @@ void ProfileDialog::filterChanged(const QString &text)
else if (qobject_cast<QLineEdit *>(sender()))
sort_model_->setFilterString(text);
- pd_ui_->profileTreeView->resizeColumnToContents(ProfileModel::COL_NAME);
-
QModelIndex active = sort_model_->mapFromSource(model_->activeProfile());
if (active.isValid())
pd_ui_->profileTreeView->setCurrentIndex(active);
}
-#ifdef HAVE_MINIZIP
+#if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG)
void ProfileDialog::exportProfiles(bool exportAllPersonalProfiles)
{
QAction * action = qobject_cast<QAction *>(sender());
@@ -604,7 +615,7 @@ void ProfileDialog::exportProfiles(bool exportAllPersonalProfiles)
return;
}
- QString zipFile = QFileDialog::getSaveFileName(this, tr("Select zip file for export"), openDialogInitialDir(), tr("Zip File (*.zip)"));
+ QString zipFile = WiresharkFileDialog::getSaveFileName(this, tr("Select zip file for export"), openDialogInitialDir(), tr("Zip File (*.zip)"));
if (zipFile.length() > 0)
{
@@ -627,7 +638,7 @@ void ProfileDialog::exportProfiles(bool exportAllPersonalProfiles)
{
QString msg = tr("An error has occurred while exporting profiles");
if (err.length() > 0)
- msg.append(QString("\n\n%1: %3").arg(tr("Error")).arg(err));
+ msg.append(QString("\n\n%1: %2").arg(tr("Error"), err));
QMessageBox::critical(this, tr("Exporting profiles"), msg);
}
}
@@ -635,7 +646,7 @@ void ProfileDialog::exportProfiles(bool exportAllPersonalProfiles)
void ProfileDialog::importFromZip()
{
- QString zipFile = QFileDialog::getOpenFileName(this, tr("Select zip file for import"), openDialogInitialDir(), tr("Zip File (*.zip)"));
+ QString zipFile = WiresharkFileDialog::getOpenFileName(this, tr("Select zip file for import"), openDialogInitialDir(), tr("Zip File (*.zip)"));
QFileInfo fi(zipFile);
if (! fi.exists())
@@ -651,7 +662,7 @@ void ProfileDialog::importFromZip()
void ProfileDialog::importFromDirectory()
{
- QString importDir = QFileDialog::getExistingDirectory(this, tr("Select directory for import"), openDialogInitialDir());
+ QString importDir = WiresharkFileDialog::getExistingDirectory(this, tr("Select directory for import"), openDialogInitialDir());
QFileInfo fi(importDir);
if (! fi.isDir())
@@ -726,11 +737,8 @@ void ProfileDialog::resetTreeView()
selectionChanged();
- if (sort_model_->columnCount() <= 1)
+ if (sort_model_->columnCount() <= 1) {
pd_ui_->profileTreeView->header()->hide();
- else
- {
- pd_ui_->profileTreeView->header()->setStretchLastSection(false);
- pd_ui_->profileTreeView->header()->setSectionResizeMode(ProfileModel::COL_NAME, QHeaderView::Stretch);
}
}
+
diff --git a/ui/qt/profile_dialog.h b/ui/qt/profile_dialog.h
index d42594f0..5ffc69f7 100644
--- a/ui/qt/profile_dialog.h
+++ b/ui/qt/profile_dialog.h
@@ -40,8 +40,8 @@ public:
/**
* @brief Select the profile with the given name.
*
- * If the profile name is empty, the currently selected profile will be choosen instead.
- * If the choosen profile is invalid, the first row will be choosen.
+ * If the profile name is empty, the currently selected profile will be chosen instead.
+ * If the chosen profile is invalid, the first row will be chosen.
*
* @param profile the name of the profile to be selected
*/
@@ -54,7 +54,7 @@ private:
Ui::ProfileDialog *pd_ui_;
QPushButton *ok_button_;
QPushButton *import_button_;
-#ifdef HAVE_MINIZIP
+#if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG)
QPushButton *export_button_;
QAction *export_selected_entry_;
#endif
@@ -68,18 +68,18 @@ private:
private slots:
void currentItemChanged(const QModelIndex & c = QModelIndex(), const QModelIndex & p = QModelIndex());
-#ifdef HAVE_MINIZIP
+#if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG)
void exportProfiles(bool exportAllPersonalProfiles = false);
void importFromZip();
#endif
void importFromDirectory();
- void on_newToolButton_clicked();
- void on_deleteToolButton_clicked();
- void on_copyToolButton_clicked();
- void on_buttonBox_accepted();
- void on_buttonBox_rejected();
- void on_buttonBox_helpRequested();
+ void newToolButtonClicked();
+ void deleteToolButtonClicked();
+ void copyToolButtonClicked();
+ void buttonBoxAccepted();
+ void buttonBoxRejected();
+ void buttonBoxHelpRequested();
void dataChanged(const QModelIndex &);
void filterChanged(const QString &);
diff --git a/ui/qt/profile_dialog.ui b/ui/qt/profile_dialog.ui
index fcc7591f..5f5bdf38 100644
--- a/ui/qt/profile_dialog.ui
+++ b/ui/qt/profile_dialog.ui
@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
- <width>570</width>
+ <width>600</width>
<height>400</height>
</rect>
</property>
@@ -54,7 +54,7 @@
</widget>
</item>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0,0,0">
+ <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0,0,0,0,0,0,0">
<item>
<widget class="StockIconToolButton" name="newToolButton">
<property name="toolTip">
@@ -95,6 +95,42 @@
</widget>
</item>
<item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>5</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="autoSwitchLimitLabel">
+ <property name="toolTip">
+ <string>The number of packets or events to check for automatic profile switching.</string>
+ </property>
+ <property name="text">
+ <string>Auto switch packet limit</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="autoSwitchSpinBox">
+ <property name="buttonSymbols">
+ <enum>QAbstractSpinBox::NoButtons</enum>
+ </property>
+ <property name="maximum">
+ <number>10000000</number>
+ </property>
+ <property name="singleStep">
+ <number>1000</number>
+ </property>
+ </widget>
+ </item>
+ <item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
diff --git a/ui/qt/progress_frame.cpp b/ui/qt/progress_frame.cpp
index 2e40ac80..33306ebc 100644
--- a/ui/qt/progress_frame.cpp
+++ b/ui/qt/progress_frame.cpp
@@ -28,8 +28,8 @@
// - Don't complain so loudly when the user stops a capture.
progdlg_t *
-create_progress_dlg(gpointer top_level_window, const gchar *task_title, const gchar *item_title,
- gboolean terminate_is_stop, gboolean *stop_flag) {
+create_progress_dlg(void *top_level_window, const char *task_title, const char *item_title,
+ bool terminate_is_stop, bool *stop_flag) {
ProgressFrame *pf;
QWidget *main_window;
@@ -57,9 +57,9 @@ create_progress_dlg(gpointer top_level_window, const gchar *task_title, const gc
}
progdlg_t *
-delayed_create_progress_dlg(gpointer top_level_window, const gchar *task_title, const gchar *item_title,
- gboolean terminate_is_stop, gboolean *stop_flag,
- gfloat progress)
+delayed_create_progress_dlg(void *top_level_window, const char *task_title, const char *item_title,
+ bool terminate_is_stop, bool *stop_flag,
+ float progress)
{
progdlg_t *progress_dialog = create_progress_dlg(top_level_window, task_title, item_title, terminate_is_stop, stop_flag);
update_progress_dlg(progress_dialog, progress, item_title);
@@ -70,7 +70,7 @@ delayed_create_progress_dlg(gpointer top_level_window, const gchar *task_title,
* Update the progress information of the progress bar box.
*/
void
-update_progress_dlg(progdlg_t *dlg, gfloat percentage, const gchar *)
+update_progress_dlg(progdlg_t *dlg, float percentage, const char *)
{
if (!dlg) return;
@@ -145,8 +145,8 @@ ProgressFrame::ProgressFrame(QWidget *parent) :
effect_ = new QGraphicsOpacityEffect(this);
animation_ = new QPropertyAnimation(effect_, "opacity", this);
- connect(this, SIGNAL(showRequested(bool,bool,gboolean*)),
- this, SLOT(show(bool,bool,gboolean*)));
+ connect(this, SIGNAL(showRequested(bool,bool,bool*)),
+ this, SLOT(show(bool,bool,bool*)));
hide();
}
@@ -155,17 +155,13 @@ ProgressFrame::~ProgressFrame()
delete ui;
}
-struct progdlg *ProgressFrame::showProgress(const QString &title, bool animate, bool terminate_is_stop, gboolean *stop_flag, int value)
+struct progdlg *ProgressFrame::showProgress(const QString &title, bool animate, bool terminate_is_stop, bool *stop_flag, int value)
{
setMaximumValue(100);
ui->progressBar->setValue(value);
QString elided_title = title;
int max_w = fontMetrics().height() * 20; // em-widths, arbitrary
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
int title_w = fontMetrics().horizontalAdvance(title);
-#else
- int title_w = fontMetrics().width(title);
-#endif
if (title_w > max_w) {
elided_title = fontMetrics().elidedText(title, Qt::ElideRight, max_w);
}
@@ -175,7 +171,7 @@ struct progdlg *ProgressFrame::showProgress(const QString &title, bool animate,
return &progress_dialog_;
}
-progdlg *ProgressFrame::showBusy(bool animate, bool terminate_is_stop, gboolean *stop_flag)
+progdlg *ProgressFrame::showBusy(bool animate, bool terminate_is_stop, bool *stop_flag)
{
setMaximumValue(0);
emit showRequested(animate, terminate_is_stop, stop_flag);
@@ -209,8 +205,8 @@ void ProgressFrame::addToButtonBox(QDialogButtonBox *button_box, QObject *main_w
int one_em = progress_frame->fontMetrics().height();
progress_frame->setMaximumWidth(one_em * 8);
- connect(main_progress_frame, SIGNAL(showRequested(bool,bool,gboolean*)),
- progress_frame, SLOT(show(bool,bool,gboolean*)));
+ connect(main_progress_frame, SIGNAL(showRequested(bool,bool,bool*)),
+ progress_frame, SLOT(show(bool,bool,bool*)));
connect(main_progress_frame, SIGNAL(maximumValueChanged(int)),
progress_frame, SLOT(setMaximumValue(int)));
connect(main_progress_frame, SIGNAL(valueChanged(int)),
@@ -226,12 +222,12 @@ void ProgressFrame::captureFileClosing()
{
// Hide any paired ProgressFrames and disconnect from them.
emit setHidden();
- disconnect(SIGNAL(showRequested(bool,bool,gboolean*)));
+ disconnect(SIGNAL(showRequested(bool,bool,bool*)));
disconnect(SIGNAL(maximumValueChanged(int)));
disconnect(SIGNAL(valueChanged(int)));
- connect(this, SIGNAL(showRequested(bool,bool,gboolean*)),
- this, SLOT(show(bool,bool,gboolean*)));
+ connect(this, SIGNAL(showRequested(bool,bool,bool*)),
+ this, SLOT(show(bool,bool,bool*)));
}
void ProgressFrame::setValue(int value)
@@ -281,7 +277,7 @@ void ProgressFrame::on_stopButton_clicked()
const int show_delay_ = 150; // ms
-void ProgressFrame::show(bool animate, bool terminate_is_stop, gboolean *stop_flag)
+void ProgressFrame::show(bool animate, bool terminate_is_stop, bool *stop_flag)
{
terminate_is_stop_ = terminate_is_stop;
stop_flag_ = stop_flag;
diff --git a/ui/qt/progress_frame.h b/ui/qt/progress_frame.h
index 241afab8..368e519a 100644
--- a/ui/qt/progress_frame.h
+++ b/ui/qt/progress_frame.h
@@ -10,8 +10,6 @@
#ifndef PROGRESS_FRAME_H
#define PROGRESS_FRAME_H
-#include <glib.h>
-
#include <QFrame>
namespace Ui {
@@ -50,13 +48,13 @@ public:
void captureFileClosing();
public slots:
- struct progdlg *showProgress(const QString &title, bool animate, bool terminate_is_stop, gboolean *stop_flag, int value = 0);
- struct progdlg *showBusy(bool animate, bool terminate_is_stop, gboolean *stop_flag);
+ struct progdlg *showProgress(const QString &title, bool animate, bool terminate_is_stop, bool *stop_flag, int value = 0);
+ struct progdlg *showBusy(bool animate, bool terminate_is_stop, bool *stop_flag);
void setValue(int value);
void hide();
signals:
- void showRequested(bool animate, bool terminate_is_stop, gboolean *stop_flag);
+ void showRequested(bool animate, bool terminate_is_stop, bool *stop_flag);
void valueChanged(int value);
void maximumValueChanged(int value);
void setHidden();
@@ -72,7 +70,7 @@ private:
QString message_;
QString status_;
bool terminate_is_stop_;
- gboolean *stop_flag_;
+ bool *stop_flag_;
int show_timer_;
QGraphicsOpacityEffect *effect_;
QPropertyAnimation *animation_;
@@ -84,7 +82,7 @@ private:
private slots:
void on_stopButton_clicked();
- void show(bool animate, bool terminate_is_stop, gboolean *stop_flag);
+ void show(bool animate, bool terminate_is_stop, bool *stop_flag);
void setMaximumValue(int value);
};
diff --git a/ui/qt/proto_tree.cpp b/ui/qt/proto_tree.cpp
index 77af8d22..0db9eaa5 100644
--- a/ui/qt/proto_tree.cpp
+++ b/ui/qt/proto_tree.cpp
@@ -26,6 +26,7 @@
#include <ui/qt/show_packet_bytes_dialog.h>
#include <ui/qt/filter_action.h>
#include <ui/qt/follow_stream_action.h>
+#include <ui/qt/io_graph_action.h>
#include <ui/all_files_wildcard.h>
#include <ui/alert_box.h>
#include <ui/urls.h>
@@ -174,7 +175,7 @@ void ProtoTree::ctxCopySelectedInfo()
case ProtoTree::Value:
{
epan_dissect_t *edt = cap_file_ ? cap_file_->edt : edt_;
- gchar* field_str = get_node_field_value(finfo.fieldInfo(), edt);
+ char* field_str = get_node_field_value(finfo.fieldInfo(), edt);
clip.append(field_str);
g_free(field_str);
}
@@ -216,7 +217,7 @@ void ProtoTree::ctxOpenUrlWiki()
if (ret != QMessageBox::Yes) return;
- url = QString(WS_WIKI_URL("%1")).arg(proto_abbrev);
+ url = QString(WS_WIKI_URL("Protocols/%1")).arg(proto_abbrev);
}
else
{
@@ -334,7 +335,10 @@ void ProtoTree::contextMenuEvent(QContextMenuEvent *event)
ctx_menu->addSeparator();
}
+ ctx_menu->addMenu(IOGraphAction::createMenu(finfo->headerInfo(), ctx_menu));
+
submenu = ctx_menu->addMenu(tr("Copy"));
+ submenu->setToolTipsVisible(true);
submenu->addAction(tr("All Visible Items"), this, SLOT(ctxCopyVisibleItems()));
action = submenu->addAction(tr("All Visible Selected Tree Items"), this, SLOT(ctxCopyVisibleItems()));
action->setProperty("selected_tree", QVariant::fromValue(true));
@@ -356,7 +360,9 @@ void ProtoTree::contextMenuEvent(QContextMenuEvent *event)
action = window()->findChild<QAction *>("actionAnalyzeShowPacketBytes");
ctx_menu->addAction(action);
action = window()->findChild<QAction *>("actionFileExportPacketBytes");
- ctx_menu->addAction(action);
+ if (action) {
+ ctx_menu->addAction(action);
+ }
ctx_menu->addSeparator();
}
@@ -395,12 +401,14 @@ void ProtoTree::contextMenuEvent(QContextMenuEvent *event)
if (! buildForDialog)
{
- QAction *decode_as_ = window()->findChild<QAction *>("actionAnalyzeDecodeAs");
- ctx_menu->addAction(decode_as_);
- decode_as_->setProperty("create_new", QVariant::fromValue(true));
+ QAction *decode_as = window()->findChild<QAction *>("actionAnalyzeDecodeAs");
+ if (decode_as) {
+ ctx_menu->addAction(decode_as);
+ decode_as->setProperty("create_new", QVariant::fromValue(true));
- ctx_menu->addAction(window()->findChild<QAction *>("actionGoGoToLinkedPacket"));
- ctx_menu->addAction(window()->findChild<QAction *>("actionContextShowLinkedPacketInNewWindow"));
+ ctx_menu->addAction(window()->findChild<QAction *>("actionGoGoToLinkedPacket"));
+ ctx_menu->addAction(window()->findChild<QAction *>("actionContextShowLinkedPacketInNewWindow"));
+ }
}
// The "text only" header field will not give preferences for the selected protocol.
@@ -460,7 +468,7 @@ void ProtoTree::setMonospaceFont(const QFont &mono_font)
update();
}
-void ProtoTree::foreachTreeNode(proto_node *node, gpointer proto_tree_ptr)
+void ProtoTree::foreachTreeNode(proto_node *node, void *proto_tree_ptr)
{
ProtoTree *tree_view = static_cast<ProtoTree *>(proto_tree_ptr);
ProtoTreeModel *model = qobject_cast<ProtoTreeModel *>(tree_view->model());
@@ -478,6 +486,7 @@ void ProtoTree::foreachTreeNode(proto_node *node, gpointer proto_tree_ptr)
proto_tree_children_foreach(node, foreachTreeNode, proto_tree_ptr);
}
+// NOLINTNEXTLINE(misc-no-recursion)
void ProtoTree::foreachExpand(const QModelIndex &index = QModelIndex()) {
// Restore expanded state. (Note QModelIndex() refers to the root node)
@@ -490,6 +499,7 @@ void ProtoTree::foreachExpand(const QModelIndex &index = QModelIndex()) {
if (node && node->isValid() && tree_expanded(node->protoNode()->finfo->tree_type)) {
expand(childIndex);
}
+ // We recurse here, but we're limited by tree depth checks in epan
foreachExpand(childIndex);
}
}
@@ -571,7 +581,7 @@ void ProtoTree::syncExpanded(const QModelIndex &index) {
* are thus presumably leaf nodes and cannot be expanded.
*/
if (finfo.treeType() != -1) {
- tree_expanded_set(finfo.treeType(), TRUE);
+ tree_expanded_set(finfo.treeType(), true);
}
}
@@ -584,7 +594,7 @@ void ProtoTree::syncCollapsed(const QModelIndex &index) {
* are thus presumably leaf nodes and cannot be collapsed.
*/
if (finfo.treeType() != -1) {
- tree_expanded_set(finfo.treeType(), FALSE);
+ tree_expanded_set(finfo.treeType(), false);
}
}
@@ -635,7 +645,7 @@ void ProtoTree::collapseSubtrees()
void ProtoTree::expandAll()
{
for (int i = 0; i < num_tree_types; i++) {
- tree_expanded_set(i, TRUE);
+ tree_expanded_set(i, true);
}
QTreeView::expandAll();
updateContentWidth();
@@ -644,7 +654,7 @@ void ProtoTree::expandAll()
void ProtoTree::collapseAll()
{
for (int i = 0; i < num_tree_types; i++) {
- tree_expanded_set(i, FALSE);
+ tree_expanded_set(i, false);
}
QTreeView::collapseAll();
updateContentWidth();
@@ -776,6 +786,7 @@ void ProtoTree::restoreSelectedField()
autoScrollTo(cur_index);
}
+// NOLINTNEXTLINE(misc-no-recursion)
QString ProtoTree::traverseTree(const QModelIndex & travTree, int identLevel) const
{
QString result = "";
@@ -792,6 +803,7 @@ QString ProtoTree::traverseTree(const QModelIndex & travTree, int identLevel) co
int children = proto_tree_model_->rowCount(travTree);
identLevel++;
for (int child = 0; child < children; child++)
+ // We recurse here, but we're limited by tree depth checks in epan
result += traverseTree(proto_tree_model_->index(child, 0, travTree), identLevel);
}
}
diff --git a/ui/qt/proto_tree.h b/ui/qt/proto_tree.h
index 511063e9..ca08668b 100644
--- a/ui/qt/proto_tree.h
+++ b/ui/qt/proto_tree.h
@@ -70,7 +70,7 @@ private:
epan_dissect_t *edt_;
void saveSelectedField(QModelIndex &index);
- static void foreachTreeNode(proto_node *node, gpointer proto_tree_ptr);
+ static void foreachTreeNode(proto_node *node, void *proto_tree_ptr);
void foreachExpand(const QModelIndex &index);
signals:
diff --git a/ui/qt/protocol_hierarchy_dialog.cpp b/ui/qt/protocol_hierarchy_dialog.cpp
index a97f37b7..fefb0b5c 100644
--- a/ui/qt/protocol_hierarchy_dialog.cpp
+++ b/ui/qt/protocol_hierarchy_dialog.cpp
@@ -305,7 +305,7 @@ void ProtocolHierarchyDialog::filterActionTriggered()
emit filterAction(filter_name, fa->action(), fa->actionType());
}
-void ProtocolHierarchyDialog::addTreeNode(GNode *node, gpointer data)
+void ProtocolHierarchyDialog::addTreeNode(GNode *node, void *data)
{
ph_stats_node_t *stats = (ph_stats_node_t *)node->data;
if (!stats) return;
diff --git a/ui/qt/protocol_hierarchy_dialog.h b/ui/qt/protocol_hierarchy_dialog.h
index 08f3dfd2..33191d1e 100644
--- a/ui/qt/protocol_hierarchy_dialog.h
+++ b/ui/qt/protocol_hierarchy_dialog.h
@@ -55,7 +55,7 @@ private:
QSet<QString> used_protos_;
// Callback for g_node_children_foreach
- static void addTreeNode(GNode *node, gpointer data);
+ static void addTreeNode(GNode *node, void *data);
void updateWidgets();
QList<QVariant> protoHierRowData(QTreeWidgetItem *item) const;
};
diff --git a/ui/qt/protocol_preferences_menu.cpp b/ui/qt/protocol_preferences_menu.cpp
index 75c3515c..4beff2fd 100644
--- a/ui/qt/protocol_preferences_menu.cpp
+++ b/ui/qt/protocol_preferences_menu.cpp
@@ -9,8 +9,6 @@
#include "config.h"
-#include <glib.h>
-
#include <epan/prefs.h>
#include <epan/prefs-int.h>
#include <epan/proto.h>
@@ -118,7 +116,7 @@ public:
}
void showUatDialog() {
- UatDialog *uat_dlg = new UatDialog(qobject_cast<QWidget*>(parent()), prefs_get_uat_value(pref_));
+ UatDialog *uat_dlg = new UatDialog(mainApp->mainWindow(), prefs_get_uat_value(pref_));
connect(uat_dlg, SIGNAL(destroyed(QObject*)), mainApp, SLOT(flushAppSignals()));
uat_dlg->setWindowModality(Qt::ApplicationModal);
uat_dlg->setAttribute(Qt::WA_DeleteOnClose);
@@ -154,8 +152,8 @@ private:
extern "C" {
// Preference callback
-static guint
-add_prefs_menu_item(pref_t *pref, gpointer menu_ptr)
+static unsigned
+add_prefs_menu_item(pref_t *pref, void *menu_ptr)
{
ProtocolPreferencesMenu *pp_menu = static_cast<ProtocolPreferencesMenu *>(menu_ptr);
if (!pp_menu) return 1;
@@ -267,9 +265,9 @@ void ProtocolPreferencesMenu::addMenuItem(preference *pref)
case PREF_OPEN_FILENAME:
case PREF_DIRNAME:
case PREF_RANGE:
- case PREF_DECODE_AS_UINT:
case PREF_DECODE_AS_RANGE:
case PREF_PASSWORD:
+ case PREF_DISSECTOR:
{
EditorPreferenceAction *epa = new EditorPreferenceAction(pref, this);
addAction(epa);
diff --git a/ui/qt/remote_capture_dialog.cpp b/ui/qt/remote_capture_dialog.cpp
index dff16527..f9a183b2 100644
--- a/ui/qt/remote_capture_dialog.cpp
+++ b/ui/qt/remote_capture_dialog.cpp
@@ -11,8 +11,8 @@
#include "config.h"
#ifdef HAVE_PCAP_REMOTE
-#include <glib.h>
#include <ui/qt/utils/qt_ui_utils.h>
+#include <ui/qt/utils/variant_pointer.h>
#include "ui/capture_globals.h"
#include "remote_capture_dialog.h"
#include <ui_remote_capture_dialog.h>
@@ -49,7 +49,11 @@ void RemoteCaptureDialog::hostChanged(const QString host)
recent_free_remote_host_list();
ui->hostCombo->clear();
} else {
- struct remote_host *rh = recent_get_remote_host(host.toUtf8().constData());
+ const struct remote_host *rh = nullptr;
+ int index = ui->hostCombo->findText(host);
+ if (index != -1) {
+ rh = VariantPointer<const struct remote_host>::asPtr(ui->hostCombo->itemData(index));
+ }
if (rh) {
ui->portText->setText(QString(rh->remote_port));
if (rh->auth_type == CAPTURE_AUTH_NULL) {
@@ -62,10 +66,11 @@ void RemoteCaptureDialog::hostChanged(const QString host)
}
-static void fillBox(gpointer key, gpointer, gpointer user_data)
+static void fillBox(void *value, void *user_data)
{
QComboBox *cb = (QComboBox *)user_data;
- cb->addItem(QString((gchar*)key));
+ struct remote_host* rh = (struct remote_host*)value;
+ cb->addItem(QString((char*)rh->r_host), VariantPointer<const struct remote_host>::asQVariant(rh));
}
void RemoteCaptureDialog::fillComboBox()
@@ -84,10 +89,13 @@ void RemoteCaptureDialog::fillComboBox()
void RemoteCaptureDialog::apply_remote()
{
int err;
- gchar *err_str;
+ char *err_str;
remote_options global_remote_opts;
QString host = ui->hostCombo->currentText();
+ if (host.isEmpty()) {
+ return;
+ }
global_remote_opts.src_type = CAPTURE_IFREMOTE;
global_remote_opts.remote_host_opts.remote_host = qstring_strdup(host);
QString port = ui->portText->text();
@@ -101,9 +109,9 @@ void RemoteCaptureDialog::apply_remote()
global_remote_opts.remote_host_opts.auth_username = qstring_strdup(user);
QString pw = ui->pwText->text();
global_remote_opts.remote_host_opts.auth_password = qstring_strdup(pw);
- global_remote_opts.remote_host_opts.datatx_udp = FALSE;
- global_remote_opts.remote_host_opts.nocap_rpcap = TRUE;
- global_remote_opts.remote_host_opts.nocap_local = FALSE;
+ global_remote_opts.remote_host_opts.datatx_udp = false;
+ global_remote_opts.remote_host_opts.nocap_rpcap = true;
+ global_remote_opts.remote_host_opts.nocap_local = false;
#ifdef HAVE_PCAP_SETSAMPLING
global_remote_opts.sampling_method = CAPTURE_SAMP_NONE;
global_remote_opts.sampling_param = 0;
@@ -126,24 +134,28 @@ void RemoteCaptureDialog::apply_remote()
QMessageBox::critical(this, tr("Error"), "Unknown error");
return;
}
- if (ui->hostCombo->count() == 0) {
- ui->hostCombo->addItem("");
- ui->hostCombo->addItem(host);
- ui->hostCombo->insertSeparator(2);
- ui->hostCombo->addItem(QString(tr("Clear list")));
- } else {
- ui->hostCombo->insertItem(0, host);
- }
- struct remote_host *rh = recent_get_remote_host(host.toUtf8().constData());
- if (!rh) {
- rh = (struct remote_host *)g_malloc (sizeof (*rh));
- rh->r_host = qstring_strdup(host);
- rh->remote_port = qstring_strdup(port);
- rh->auth_type = global_remote_opts.remote_host_opts.auth_type;
- rh->auth_password = g_strdup("");
- rh->auth_username = g_strdup("");
- recent_add_remote_host(global_remote_opts.remote_host_opts.remote_host, rh);
- }
+
+ // Add the remote host even if it already exists, to update the port and
+ // auth type and move it to the front.
+ struct remote_host* rh;
+ rh = (struct remote_host *)g_malloc (sizeof (*rh));
+ rh->r_host = qstring_strdup(host);
+ rh->remote_port = qstring_strdup(port);
+ rh->auth_type = global_remote_opts.remote_host_opts.auth_type;
+ rh->auth_password = g_strdup("");
+ rh->auth_username = g_strdup("");
+ recent_add_remote_host(global_remote_opts.remote_host_opts.remote_host, rh);
+
+ // We don't need to add the new entry to hostCombo since we only call
+ // this when accepting the dialog.
+
+ // Tell the parent ManageInterfacesDialog we added this.
+ // XXX: If the remote hostname already exists in ManageInterfacesDialog,
+ // this doesn't remove it. Most of the time it won't, but there is the
+ // corner case of a host existing with empty (hence default, 2002) port,
+ // and then adding it a second time explicitly starting port 2002.
+ // Someone could bind rpcapd to multiple ports on the same host for
+ // some reason too, I suppose.
emit remoteAdded(rlist, &global_remote_opts);
}
diff --git a/ui/qt/remote_capture_dialog.h b/ui/qt/remote_capture_dialog.h
index 86ef0740..fee75d89 100644
--- a/ui/qt/remote_capture_dialog.h
+++ b/ui/qt/remote_capture_dialog.h
@@ -14,10 +14,8 @@
#ifdef HAVE_PCAP_REMOTE
#include <QDialog>
-#include <glib.h>
#include "capture_opts.h"
-
namespace Ui {
class RemoteCaptureDialog;
}
diff --git a/ui/qt/resolved_addresses_dialog.cpp b/ui/qt/resolved_addresses_dialog.cpp
index dfe51c84..e4507294 100644
--- a/ui/qt/resolved_addresses_dialog.cpp
+++ b/ui/qt/resolved_addresses_dialog.cpp
@@ -12,8 +12,6 @@
#include "config.h"
-#include <glib.h>
-
#include "file.h"
#include "epan/addr_resolv.h"
@@ -43,6 +41,11 @@ ResolvedAddressesDialog::ResolvedAddressesDialog(QWidget *parent, QString captur
QStringList title_parts = QStringList() << tr("Resolved Addresses");
+ copy_bt_ = ui->buttonBox->addButton(tr("Copy"), QDialogButtonBox::ActionRole);
+
+ save_bt_ = ui->buttonBox->addButton(tr("Save as…"), QDialogButtonBox::ActionRole);
+ connect(save_bt_, &QPushButton::clicked, this, &ResolvedAddressesDialog::saveAs);
+
if (!captureFile.isEmpty()) {
file_name_ = captureFile;
title_parts << file_name_;
@@ -86,7 +89,6 @@ ResolvedAddressesDialog::ResolvedAddressesDialog(QWidget *parent, QString captur
ethTypeModel->setColumnToHide(0);
ui->tblAddresses->setModel(ethTypeModel);
ui->tblAddresses->resizeColumnsToContents();
- ui->tblAddresses->horizontalHeader()->setStretchLastSection(true);
ui->tblAddresses->sortByColumn(1, Qt::AscendingOrder);
ui->cmbDataType->addItems(ethModel->filterValues());
@@ -94,17 +96,19 @@ ResolvedAddressesDialog::ResolvedAddressesDialog(QWidget *parent, QString captur
portTypeModel = new AStringListListSortFilterProxyModel(this);
PortsModel * portModel = new PortsModel(this);
portSortModel->setSourceModel(portModel);
- portSortModel->setColumnAsNumeric(1);
- portSortModel->setColumnsToFilter(QList<int>() << 0 << 1);
+ portSortModel->setColumnAsNumeric(PORTS_COL_PORT);
+ portSortModel->setColumnsToFilter(QList<int>() << PORTS_COL_NAME << PORTS_COL_PROTOCOL);
portSortModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
portTypeModel->setSourceModel(portSortModel);
- portTypeModel->setColumnToFilter(2);
- portTypeModel->setColumnAsNumeric(1);
+ portTypeModel->setColumnToFilter(PORTS_COL_PROTOCOL);
+ portTypeModel->setColumnAsNumeric(PORTS_COL_PORT);
ui->tblPorts->setModel(portTypeModel);
ui->tblPorts->resizeColumnsToContents();
- ui->tblPorts->horizontalHeader()->setStretchLastSection(true);
- ui->tblPorts->sortByColumn(1, Qt::AscendingOrder);
+ ui->tblPorts->sortByColumn(PORTS_COL_PORT, Qt::AscendingOrder);
ui->cmbPortFilterType->addItems(portModel->filterValues());
+
+ tabChanged(ui->tabWidget->currentIndex());
+ connect(ui->tabWidget, &QTabWidget::currentChanged, this, &ResolvedAddressesDialog::tabChanged);
}
ResolvedAddressesDialog::~ResolvedAddressesDialog()
@@ -112,6 +116,27 @@ ResolvedAddressesDialog::~ResolvedAddressesDialog()
delete ui;
}
+void ResolvedAddressesDialog::tabChanged(int index)
+{
+ QWidget *currentTab = ui->tabWidget->widget(index);
+ ResolvedAddressesView *addressView = nullptr;
+ if (currentTab != nullptr) {
+ addressView = currentTab->findChild<ResolvedAddressesView*>();
+ if (addressView != nullptr) {
+ QMenu* oldMenu = copy_bt_->menu();
+ copy_bt_->setMenu(addressView->createCopyMenu(false, copy_bt_));
+ if (oldMenu != nullptr) {
+ delete oldMenu;
+ }
+ }
+ }
+ foreach (QAbstractButton *button, ui->buttonBox->buttons()) {
+ if (ui->buttonBox->buttonRole(button) == QDialogButtonBox::ActionRole) {
+ button->setEnabled(addressView != nullptr);
+ }
+ }
+}
+
void ResolvedAddressesDialog::on_cmbDataType_currentIndexChanged(int index)
{
if (! ethSortModel)
@@ -146,10 +171,10 @@ void ResolvedAddressesDialog::on_cmbPortFilterType_currentIndexChanged(int index
if (index == 0)
{
filter.clear();
- portTypeModel->setFilterType(AStringListListSortFilterProxyModel::FilterNone, 2);
+ portTypeModel->setFilterType(AStringListListSortFilterProxyModel::FilterNone, PORTS_COL_PROTOCOL);
}
else
- portTypeModel->setFilterType(AStringListListSortFilterProxyModel::FilterByEquivalent, 2);
+ portTypeModel->setFilterType(AStringListListSortFilterProxyModel::FilterByEquivalent, PORTS_COL_PROTOCOL);
portTypeModel->setFilter(filter);
}
@@ -202,3 +227,18 @@ void ResolvedAddressesDialog::fillBlocks()
ui->plainTextEdit->moveCursor(QTextCursor::Start);
setUpdatesEnabled(true);
}
+
+void ResolvedAddressesDialog::saveAs()
+{
+ QWidget *currentTab = ui->tabWidget->currentWidget();
+ if (currentTab == nullptr) {
+ return;
+ }
+
+ ResolvedAddressesView *addressView = currentTab->findChild<ResolvedAddressesView*>();
+ if (addressView == nullptr) {
+ return;
+ }
+
+ addressView->saveAs();
+}
diff --git a/ui/qt/resolved_addresses_dialog.h b/ui/qt/resolved_addresses_dialog.h
index dc6a9b64..3ce4698e 100644
--- a/ui/qt/resolved_addresses_dialog.h
+++ b/ui/qt/resolved_addresses_dialog.h
@@ -12,6 +12,8 @@
#include "geometry_state_dialog.h"
+#include <QMenu>
+
#include <wiretap/wtap.h>
class CaptureFile;
@@ -41,6 +43,8 @@ private:
Ui::ResolvedAddressesDialog *ui;
QString file_name_;
QString comment_;
+ QPushButton *copy_bt_;
+ QPushButton *save_bt_;
AStringListListSortFilterProxyModel * ethSortModel;
AStringListListSortFilterProxyModel * ethTypeModel;
@@ -48,6 +52,10 @@ private:
AStringListListSortFilterProxyModel * portTypeModel;
void fillBlocks();
+
+private slots:
+ void tabChanged(int index);
+ void saveAs();
};
#endif // RESOLVED_ADDRESSES_DIALOG_H
diff --git a/ui/qt/resolved_addresses_dialog.ui b/ui/qt/resolved_addresses_dialog.ui
index c77c5cc1..8cbbdc7f 100644
--- a/ui/qt/resolved_addresses_dialog.ui
+++ b/ui/qt/resolved_addresses_dialog.ui
@@ -39,19 +39,7 @@
</layout>
</item>
<item>
- <widget class="QTableView" name="tblAddresses">
- <property name="editTriggers">
- <set>QAbstractItemView::NoEditTriggers</set>
- </property>
- <property name="sortingEnabled">
- <bool>true</bool>
- </property>
- <attribute name="horizontalHeaderShowSortIndicator" stdset="0">
- <bool>true</bool>
- </attribute>
- <attribute name="verticalHeaderVisible">
- <bool>false</bool>
- </attribute>
+ <widget class="ResolvedAddressesView" name="tblAddresses">
</widget>
</item>
</layout>
@@ -76,13 +64,7 @@
</layout>
</item>
<item>
- <widget class="QTableView" name="tblPorts">
- <property name="sortingEnabled">
- <bool>true</bool>
- </property>
- <attribute name="verticalHeaderVisible">
- <bool>false</bool>
- </attribute>
+ <widget class="ResolvedAddressesView" name="tblPorts">
</widget>
</item>
</layout>
@@ -233,6 +215,13 @@
</property>
</action>
</widget>
+ <customwidgets>
+ <customwidget>
+ <class>ResolvedAddressesView</class>
+ <extends>QTableVew</extends>
+ <header>ui/qt/widgets/resolved_addresses_view.h</header>
+ </customwidget>
+ </customwidgets>
<resources/>
<connections>
<connection>
diff --git a/ui/qt/response_time_delay_dialog.cpp b/ui/qt/response_time_delay_dialog.cpp
index f656525e..8943d579 100644
--- a/ui/qt/response_time_delay_dialog.cpp
+++ b/ui/qt/response_time_delay_dialog.cpp
@@ -50,7 +50,7 @@ bool register_response_time_delay_tables(const void *, void *value, void*)
rtd_init,
ResponseTimeDelayDialog::createRtdDialog);
g_free(cfg_abbr);
- return FALSE;
+ return false;
}
enum {
diff --git a/ui/qt/rpc_service_response_time_dialog.cpp b/ui/qt/rpc_service_response_time_dialog.cpp
index 7c7f70b3..fa5caf30 100644
--- a/ui/qt/rpc_service_response_time_dialog.cpp
+++ b/ui/qt/rpc_service_response_time_dialog.cpp
@@ -44,7 +44,7 @@
extern "C" {
static void
-dce_rpc_add_program(gpointer key_ptr, gpointer value_ptr, gpointer rsrtd_ptr)
+dce_rpc_add_program(void *key_ptr, void *value_ptr, void *rsrtd_ptr)
{
RpcServiceResponseTimeDialog *rsrt_dlg = dynamic_cast<RpcServiceResponseTimeDialog *>((RpcServiceResponseTimeDialog *)rsrtd_ptr);
if (!rsrt_dlg) return;
@@ -56,7 +56,7 @@ dce_rpc_add_program(gpointer key_ptr, gpointer value_ptr, gpointer rsrtd_ptr)
}
static void
-dce_rpc_find_versions(gpointer key_ptr, gpointer, gpointer rsrtd_ptr)
+dce_rpc_find_versions(void *key_ptr, void *, void *rsrtd_ptr)
{
RpcServiceResponseTimeDialog *rsrt_dlg = dynamic_cast<RpcServiceResponseTimeDialog *>((RpcServiceResponseTimeDialog *)rsrtd_ptr);
if (!rsrt_dlg) return;
@@ -66,19 +66,19 @@ dce_rpc_find_versions(gpointer key_ptr, gpointer, gpointer rsrtd_ptr)
}
static void
-onc_rpc_add_program(gpointer prog_ptr, gpointer value_ptr, gpointer rsrtd_ptr)
+onc_rpc_add_program(void *prog_ptr, void *value_ptr, void *rsrtd_ptr)
{
RpcServiceResponseTimeDialog *rsrt_dlg = dynamic_cast<RpcServiceResponseTimeDialog *>((RpcServiceResponseTimeDialog *)rsrtd_ptr);
if (!rsrt_dlg) return;
- guint32 program = GPOINTER_TO_UINT(prog_ptr);
+ uint32_t program = GPOINTER_TO_UINT(prog_ptr);
rpc_prog_info_value *value = (rpc_prog_info_value *) value_ptr;
rsrt_dlg->addOncRpcProgram(program, value);
}
static void
-onc_rpc_find_versions(const gchar *, ftenum_t , gpointer rpik_ptr, gpointer, gpointer rsrtd_ptr)
+onc_rpc_find_versions(const char *, ftenum_t , void *rpik_ptr, void *, void *rsrtd_ptr)
{
RpcServiceResponseTimeDialog *rsrt_dlg = dynamic_cast<RpcServiceResponseTimeDialog *>((RpcServiceResponseTimeDialog *)rsrtd_ptr);
if (!rsrt_dlg) return;
@@ -89,7 +89,7 @@ onc_rpc_find_versions(const gchar *, ftenum_t , gpointer rpik_ptr, gpointer, gpo
}
static void
-onc_rpc_count_procedures(const gchar *, ftenum_t , gpointer rpik_ptr, gpointer, gpointer rsrtd_ptr)
+onc_rpc_count_procedures(const char *, ftenum_t , void *rpik_ptr, void *, void *rsrtd_ptr)
{
RpcServiceResponseTimeDialog *rsrt_dlg = dynamic_cast<RpcServiceResponseTimeDialog *>((RpcServiceResponseTimeDialog *)rsrtd_ptr);
if (!rsrt_dlg) return;
@@ -241,12 +241,12 @@ void RpcServiceResponseTimeDialog::addDceRpcProgramVersion(_guid_key *key)
std::sort(versions_.begin(), versions_.end());
}
-void RpcServiceResponseTimeDialog::addOncRpcProgram(guint32 program, _rpc_prog_info_value *value)
+void RpcServiceResponseTimeDialog::addOncRpcProgram(uint32_t program, _rpc_prog_info_value *value)
{
onc_name_to_program_.insert(value->progname, program);
}
-void RpcServiceResponseTimeDialog::addOncRpcProgramVersion(guint32 program, guint32 version)
+void RpcServiceResponseTimeDialog::addOncRpcProgramVersion(uint32_t program, uint32_t version)
{
if (onc_name_to_program_[program_combo_->currentText()] != program) return;
@@ -262,7 +262,7 @@ void RpcServiceResponseTimeDialog::addOncRpcProgramVersion(guint32 program, guin
}
}
-void RpcServiceResponseTimeDialog::updateOncRpcProcedureCount(guint32 program, guint32 version, int procedure)
+void RpcServiceResponseTimeDialog::updateOncRpcProcedureCount(uint32_t program, uint32_t version, int procedure)
{
if (onc_name_to_program_[program_combo_->currentText()] != program) return;
if (version_combo_->itemData(version_combo_->currentIndex()).toUInt() != version) return;
@@ -374,7 +374,7 @@ void RpcServiceResponseTimeDialog::provideParameterData()
{
void *tap_data = NULL;
const QString program_name = program_combo_->currentText();
- guint32 max_procs = 0;
+ uint32_t max_procs = 0;
switch (dlg_type_) {
case DceRpc:
@@ -382,8 +382,8 @@ void RpcServiceResponseTimeDialog::provideParameterData()
if (!dce_name_to_uuid_key_.contains(program_name)) return;
guid_key *dkey = dce_name_to_uuid_key_[program_name];
- guint16 version = (guint16) version_combo_->itemData(version_combo_->currentIndex()).toUInt();
- dcerpc_sub_dissector *procs = dcerpc_get_proto_sub_dissector(&(dkey->guid), version);
+ uint16_t version = (uint16_t) version_combo_->itemData(version_combo_->currentIndex()).toUInt();
+ const dcerpc_sub_dissector *procs = dcerpc_get_proto_sub_dissector(&(dkey->guid), version);
if (!procs) return;
dcerpcstat_tap_data_t *dtap_data = g_new0(dcerpcstat_tap_data_t, 1);
@@ -406,7 +406,7 @@ void RpcServiceResponseTimeDialog::provideParameterData()
rpcstat_tap_data_t *otap_data = g_new0(rpcstat_tap_data_t, 1);
otap_data->program = onc_name_to_program_[program_name];
otap_data->prog = rpc_prog_name(otap_data->program);
- otap_data->version = (guint32) version_combo_->itemData(version_combo_->currentIndex()).toUInt();
+ otap_data->version = (uint32_t) version_combo_->itemData(version_combo_->currentIndex()).toUInt();
onc_rpc_num_procedures_ = -1;
dissector_table_foreach ("rpc.call", onc_rpc_count_procedures, this);
diff --git a/ui/qt/rpc_service_response_time_dialog.h b/ui/qt/rpc_service_response_time_dialog.h
index d8f2ca53..4fa7306a 100644
--- a/ui/qt/rpc_service_response_time_dialog.h
+++ b/ui/qt/rpc_service_response_time_dialog.h
@@ -35,9 +35,9 @@ public:
void addDceRpcProgram(_guid_key *key, struct _dcerpc_uuid_value *value);
void addDceRpcProgramVersion(_guid_key *key);
- void addOncRpcProgram(guint32 program, struct _rpc_prog_info_value *value);
- void addOncRpcProgramVersion(guint32 program, guint32 version);
- void updateOncRpcProcedureCount(guint32 program, guint32 version, int procedure);
+ void addOncRpcProgram(uint32_t program, struct _rpc_prog_info_value *value);
+ void addOncRpcProgramVersion(uint32_t program, uint32_t version);
+ void updateOncRpcProcedureCount(uint32_t program, uint32_t version, int procedure);
void setDceRpcUuidAndVersion(struct _e_guid_t *uuid, int version);
void setOncRpcProgramAndVersion(int program, int version);
@@ -60,7 +60,7 @@ private:
QMap<QString, struct _guid_key *> dce_name_to_uuid_key_;
// ONC-RPC
- QMap<QString, guint32> onc_name_to_program_;
+ QMap<QString, uint32_t> onc_name_to_program_;
int onc_rpc_num_procedures_;
void clearVersionCombo();
diff --git a/ui/qt/rsa_keys_frame.cpp b/ui/qt/rsa_keys_frame.cpp
index c784ab9c..429b3aaa 100644
--- a/ui/qt/rsa_keys_frame.cpp
+++ b/ui/qt/rsa_keys_frame.cpp
@@ -63,10 +63,10 @@ RsaKeysFrame::~RsaKeysFrame()
delete ui;
}
-gboolean RsaKeysFrame::verifyKey(const char *uri, const char *password, gboolean *need_password, QString &error)
+bool RsaKeysFrame::verifyKey(const char *uri, const char *password, bool *need_password, QString &error)
{
char *error_c = NULL;
- gboolean key_ok = secrets_verify_key(qPrintable(uri), qPrintable(password), need_password, &error_c);
+ bool key_ok = secrets_verify_key(qPrintable(uri), qPrintable(password), need_password, &error_c);
error = error_c ? error_c : "";
g_free(error_c);
return key_ok;
@@ -120,7 +120,7 @@ void RsaKeysFrame::on_addItemButton_clicked()
}
// Validate the token, is a PIN needed?
- gboolean key_ok = false, needs_pin = true;
+ bool key_ok = false, needs_pin = true;
QString error;
if (!item.startsWith("pkcs11:")) {
// For keys other than pkcs11, try to verify the key without password.
@@ -168,7 +168,7 @@ void RsaKeysFrame::on_addFileButton_clicked()
// Try to load the key as unencrypted key file. If any errors occur, assume
// an encrypted key file and prompt for a password.
QString password, error;
- gboolean key_ok = secrets_verify_key(qPrintable(file), NULL, NULL, NULL);
+ bool key_ok = secrets_verify_key(qPrintable(file), NULL, NULL, NULL);
while (!key_ok) {
QString msg;
if (!error.isEmpty()) {
diff --git a/ui/qt/rsa_keys_frame.h b/ui/qt/rsa_keys_frame.h
index fae40e2f..c2dbccd2 100644
--- a/ui/qt/rsa_keys_frame.h
+++ b/ui/qt/rsa_keys_frame.h
@@ -40,7 +40,7 @@ private:
UatModel *rsa_keys_model_;
UatModel *pkcs11_libs_model_;
- gboolean verifyKey(const char *uri, const char *password, gboolean *need_password, QString &error);
+ bool verifyKey(const char *uri, const char *password, bool *need_password, QString &error);
void addKey(const QString &uri, const QString &password);
private slots:
diff --git a/ui/qt/rtp_analysis_dialog.cpp b/ui/qt/rtp_analysis_dialog.cpp
index d4eafd6c..9dcb910c 100644
--- a/ui/qt/rtp_analysis_dialog.cpp
+++ b/ui/qt/rtp_analysis_dialog.cpp
@@ -193,22 +193,16 @@ public:
switch (treeWidget()->sortColumn()) {
case (packet_col_):
return frame_num_ < other_row->frame_num_;
- break;
case (sequence_col_):
return sequence_num_ < other_row->sequence_num_;
- break;
case (delta_col_):
return delta_ < other_row->delta_;
- break;
case (jitter_col_):
return jitter_ < other_row->jitter_;
- break;
case (skew_col_):
return skew_ < other_row->skew_;
- break;
case (bandwidth_col_):
return bandwidth_ < other_row->bandwidth_;
- break;
default:
break;
}
@@ -278,6 +272,10 @@ RtpAnalysisDialog::RtpAnalysisDialog(QWidget &parent, CaptureFile &cf) :
graph_ctx_menu_.addAction(ui->actionSaveGraph);
+ ui->streamGraph->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(ui->streamGraph, &QCustomPlot::customContextMenuRequested, this,
+ &RtpAnalysisDialog::showGraphMenu);
+
ui->streamGraph->xAxis->setLabel("Arrival Time");
ui->streamGraph->yAxis->setLabel("Value (ms)");
@@ -967,16 +965,14 @@ bool RtpAnalysisDialog::eventFilter(QObject *, QEvent *event)
return false;
}
-void RtpAnalysisDialog::graphClicked(QMouseEvent *event)
+void RtpAnalysisDialog::showGraphMenu(const QPoint &pos)
+{
+ graph_ctx_menu_.popup(ui->streamGraph->mapToGlobal(pos));
+}
+
+void RtpAnalysisDialog::graphClicked(QMouseEvent*)
{
updateWidgets();
- if (event->button() == Qt::RightButton) {
-#if QT_VERSION >= QT_VERSION_CHECK(6, 0 ,0)
- graph_ctx_menu_.popup(event->globalPosition().toPoint());
-#else
- graph_ctx_menu_.popup(event->globalPos());
-#endif
- }
}
void RtpAnalysisDialog::clearLayout(QLayout *layout)
diff --git a/ui/qt/rtp_analysis_dialog.h b/ui/qt/rtp_analysis_dialog.h
index a7fcfced..b16eccd3 100644
--- a/ui/qt/rtp_analysis_dialog.h
+++ b/ui/qt/rtp_analysis_dialog.h
@@ -12,7 +12,6 @@
#include <config.h>
-#include <glib.h>
#include <mutex>
#include "epan/address.h"
@@ -118,6 +117,7 @@ private slots:
void on_actionSaveGraph_triggered();
void on_buttonBox_helpRequested();
void showStreamMenu(QPoint pos);
+ void showGraphMenu(const QPoint &pos);
void graphClicked(QMouseEvent *event);
void closeTab(int index);
void rowCheckboxChanged(int checked);
@@ -135,7 +135,7 @@ private:
int tab_seq;
QVector<tab_info_t *> tabs_;
- QMultiHash<guint, tab_info_t *> tab_hash_;
+ QMultiHash<unsigned, tab_info_t *> tab_hash_;
QToolButton *player_button_;
diff --git a/ui/qt/rtp_audio_stream.cpp b/ui/qt/rtp_audio_stream.cpp
index 5ceb809f..8950c8df 100644
--- a/ui/qt/rtp_audio_stream.cpp
+++ b/ui/qt/rtp_audio_stream.cpp
@@ -128,7 +128,7 @@ void RtpAudioStream::addRtpPacket(const struct _packet_info *pinfo, const struct
rtp_packet_t *rtp_packet = g_new0(rtp_packet_t, 1);
rtp_packet->info = (struct _rtp_info *) g_memdup2(rtp_info, sizeof(struct _rtp_info));
if (rtp_info->info_all_data_present && (rtp_info->info_payload_len != 0)) {
- rtp_packet->payload_data = (guint8 *) g_memdup2(&(rtp_info->info_data[rtp_info->info_payload_offset]),
+ rtp_packet->payload_data = (uint8_t *) g_memdup2(&(rtp_info->info_data[rtp_info->info_payload_offset]),
rtp_info->info_payload_len);
}
@@ -258,21 +258,21 @@ void RtpAudioStream::decodeAudio(QAudioDeviceInfo out_device)
{
// XXX This is more messy than it should be.
- gint32 resample_buff_bytes = 0x1000;
+ int32_t resample_buff_bytes = 0x1000;
SAMPLE *resample_buff = (SAMPLE *) g_malloc(resample_buff_bytes);
char *write_buff = NULL;
qint64 write_bytes = 0;
unsigned int channels = 0;
unsigned int sample_rate = 0;
- guint32 last_sequence = 0;
- guint32 last_sequence_w = 0; // Last sequence number we wrote data
+ uint32_t last_sequence = 0;
+ uint32_t last_sequence_w = 0; // Last sequence number we wrote data
double rtp_time_prev = 0.0;
double arrive_time_prev = 0.0;
double pack_period = 0.0;
double start_time = 0.0;
double start_rtp_time = 0.0;
- guint64 start_timestamp = 0;
+ uint64_t start_timestamp = 0;
size_t decoded_bytes_prev = 0;
unsigned int audio_resampler_input_rate = 0;
@@ -430,7 +430,7 @@ void RtpAudioStream::decodeAudio(QAudioDeviceInfo out_device)
// Buffer is in SAMPLEs
spx_uint32_t in_len = (spx_uint32_t) (write_bytes / SAMPLE_BYTES);
// Output is audio_out_rate_/sample_rate bigger than input
- spx_uint32_t out_len = (spx_uint32_t) ((guint64)in_len * audio_out_rate_ / sample_rate);
+ spx_uint32_t out_len = (spx_uint32_t) ((uint64_t)in_len * audio_out_rate_ / sample_rate);
resample_buff = resizeBufferIfNeeded(resample_buff, &resample_buff_bytes, out_len * SAMPLE_BYTES);
if (audio_resampler &&
@@ -472,13 +472,13 @@ void RtpAudioStream::decodeAudio(QAudioDeviceInfo out_device)
void RtpAudioStream::decodeVisual()
{
spx_uint32_t read_len = 0;
- gint32 read_buff_bytes = VISUAL_BUFF_BYTES;
+ int32_t read_buff_bytes = VISUAL_BUFF_BYTES;
SAMPLE *read_buff = (SAMPLE *) g_malloc(read_buff_bytes);
- gint32 resample_buff_bytes = VISUAL_BUFF_BYTES;
+ int32_t resample_buff_bytes = VISUAL_BUFF_BYTES;
SAMPLE *resample_buff = (SAMPLE *) g_malloc(resample_buff_bytes);
unsigned int sample_no = 0;
spx_uint32_t out_len;
- guint32 frame_num;
+ uint32_t frame_num;
rtp_frame_type type;
speex_resampler_set_rate(visual_resampler_, audio_out_rate_, visual_sample_rate_);
@@ -486,7 +486,7 @@ void RtpAudioStream::decodeVisual()
// Loop over every frame record
// readFrameSamples() maintains size of buffer for us
while (audio_file_->readFrameSamples(&read_buff_bytes, &read_buff, &read_len, &frame_num, &type)) {
- out_len = (spx_uint32_t)(((guint64)read_len * visual_sample_rate_ ) / audio_out_rate_);
+ out_len = (spx_uint32_t)(((uint64_t)read_len * visual_sample_rate_ ) / audio_out_rate_);
if (type == RTP_FRAME_AUDIO) {
// We resample only audio samples
@@ -538,14 +538,14 @@ const QVector<double> RtpAudioStream::visualTimestamps(bool relative)
// Scale the height of the waveform to global scale (max_sample_val_used_)
// and adjust its Y offset so that they overlap slightly (stack_offset_).
-static const double stack_offset_ = G_MAXINT16 / 3;
+static const double stack_offset_ = INT16_MAX / 3;
const QVector<double> RtpAudioStream::visualSamples(int y_offset)
{
QVector<double> adj_samples;
double scaled_offset = y_offset * stack_offset_;
for (int i = 0; i < visual_samples_.size(); i++) {
if (SAMPLE_NaN != visual_samples_[i]) {
- adj_samples.append(((double)visual_samples_[i] * G_MAXINT16 / max_sample_val_used_) + scaled_offset);
+ adj_samples.append(((double)visual_samples_[i] * INT16_MAX / max_sample_val_used_) + scaled_offset);
} else {
// Convert to break in graph line
adj_samples.append(qQNaN());
@@ -701,8 +701,8 @@ const QString RtpAudioStream::formatDescription(const QAudioFormat &format)
QString RtpAudioStream::getIDAsQString()
{
- gchar *src_addr_str = address_to_display(NULL, &id_.src_addr);
- gchar *dst_addr_str = address_to_display(NULL, &id_.dst_addr);
+ char *src_addr_str = address_to_display(NULL, &id_.src_addr);
+ char *dst_addr_str = address_to_display(NULL, &id_.dst_addr);
QString str = QString("%1:%2 - %3:%4 %5")
.arg(src_addr_str)
.arg(id_.src_port)
@@ -843,7 +843,7 @@ void RtpAudioStream::stopPlaying()
if (audio_output_) {
if (audio_output_->state() == QAudio::StoppedState) {
// Looks like "delayed" QTBUG-6548
- // It may happen that stream is stopped, but no signal emited
+ // It may happen that stream is stopped, but no signal emitted
// Probably triggered by some issue in sound system which is not
// handled by Qt correctly
outputStateChanged(QAudio::StoppedState);
@@ -905,7 +905,7 @@ void RtpAudioStream::delayedStopStream()
audio_output_->stop();
}
-SAMPLE *RtpAudioStream::resizeBufferIfNeeded(SAMPLE *buff, gint32 *buff_bytes, qint64 requested_size)
+SAMPLE *RtpAudioStream::resizeBufferIfNeeded(SAMPLE *buff, int32_t *buff_bytes, qint64 requested_size)
{
if (requested_size > *buff_bytes) {
while ((requested_size > *buff_bytes))
diff --git a/ui/qt/rtp_audio_stream.h b/ui/qt/rtp_audio_stream.h
index 1ddeaacd..e7fd78d5 100644
--- a/ui/qt/rtp_audio_stream.h
+++ b/ui/qt/rtp_audio_stream.h
@@ -14,8 +14,6 @@
#ifdef QT_MULTIMEDIA_LIB
-#include <glib.h>
-
#include <epan/address.h>
#include <ui/rtp_stream.h>
#include <ui/qt/utils/rtp_audio_routing.h>
@@ -154,7 +152,7 @@ public:
void seekPlaying(qint64 samples);
void setStereoRequired(bool stereo_required) { stereo_required_ = stereo_required; }
qint16 getMaxSampleValue() { return max_sample_val_; }
- void setMaxSampleValue(gint16 max_sample_val) { max_sample_val_used_ = max_sample_val; }
+ void setMaxSampleValue(int16_t max_sample_val) { max_sample_val_used_ = max_sample_val; }
void seekSample(qint64 samples);
qint64 readSample(SAMPLE *sample);
qint64 getLeadSilenceSamples() { return prepend_samples_; }
@@ -163,7 +161,7 @@ public:
double getEndOfSilenceTime() { return (double)getEndOfSilenceSample() / (double)playRate(); }
qint64 convertTimeToSamples(double time) { return (qint64)(time * playRate()); }
bool savePayload(QIODevice *file);
- guint getHash() { return rtpstream_id_to_hash(&(id_)); }
+ unsigned getHash() { return rtpstream_id_to_hash(&(id_)); }
rtpstream_id_t *getID() { return &(id_); }
QString getIDAsQString();
rtpstream_info_t *getStreamInfo() { return &rtpstream_; }
@@ -223,7 +221,7 @@ private:
quint32 calculateAudioOutRate(QAudioDeviceInfo out_device, unsigned int sample_rate, unsigned int requested_out_rate);
#endif
void decodeVisual();
- SAMPLE *resizeBufferIfNeeded(SAMPLE *buff, gint32 *buff_bytes, qint64 requested_size);
+ SAMPLE *resizeBufferIfNeeded(SAMPLE *buff, int32_t *buff_bytes, qint64 requested_size);
private slots:
void outputStateChanged(QAudio::State new_state);
diff --git a/ui/qt/rtp_player_dialog.cpp b/ui/qt/rtp_player_dialog.cpp
index 7d0ad62d..889dde2a 100644
--- a/ui/qt/rtp_player_dialog.cpp
+++ b/ui/qt/rtp_player_dialog.cpp
@@ -135,7 +135,6 @@ public:
default:
// Fall back to string comparison
return QTreeWidgetItem::operator <(other);
- break;
}
}
};
@@ -206,7 +205,15 @@ RtpPlayerDialog::RtpPlayerDialog(QWidget &parent, CaptureFile &cf, bool capture_
graph_ctx_menu_->addAction(ui->actionGoToSetupPacketPlot);
set_action_shortcuts_visible_in_context_menu(graph_ctx_menu_->actions());
+ ui->audioPlot->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(ui->audioPlot, &QCustomPlot::customContextMenuRequested, this, &RtpPlayerDialog::showGraphContextMenu);
+
ui->streamTreeWidget->setMouseTracking(true);
+ mouse_update_timer_ = new QTimer(this);
+ mouse_update_timer_->setSingleShot(true);
+ mouse_update_timer_->setInterval(10);
+ connect(mouse_update_timer_, &QTimer::timeout, this, &RtpPlayerDialog::mouseMoveUpdate);
+
connect(ui->streamTreeWidget, &QTreeWidget::itemEntered, this, &RtpPlayerDialog::itemEntered);
connect(ui->audioPlot, &QCustomPlot::mouseMove, this, &RtpPlayerDialog::mouseMovePlot);
@@ -393,13 +400,13 @@ RtpPlayerDialog::~RtpPlayerDialog()
{
std::lock_guard<std::mutex> lock(init_mutex_);
if (pinstance_ != nullptr) {
- cleanupMarkerStream();
for (int row = 0; row < ui->streamTreeWidget->topLevelItemCount(); row++) {
QTreeWidgetItem *ti = ui->streamTreeWidget->topLevelItem(row);
RtpAudioStream *audio_stream = ti->data(stream_data_col_, Qt::UserRole).value<RtpAudioStream*>();
if (audio_stream)
delete audio_stream;
}
+ cleanupMarkerStream();
delete ui;
pinstance_ = nullptr;
}
@@ -533,7 +540,7 @@ void RtpPlayerDialog::createPlot(bool rescale_axes)
bool legend_inserted_silences = false;
bool relative_timestamps = !ui->todCheckBox->isChecked();
int row_count = ui->streamTreeWidget->topLevelItemCount();
- gint16 total_max_sample_value = 1;
+ int16_t total_max_sample_value = 1;
ui->audioPlot->clearGraphs();
@@ -547,7 +554,7 @@ void RtpPlayerDialog::createPlot(bool rescale_axes)
for (int row = 0; row < row_count; row++) {
QTreeWidgetItem *ti = ui->streamTreeWidget->topLevelItem(row);
RtpAudioStream *audio_stream = ti->data(stream_data_col_, Qt::UserRole).value<RtpAudioStream*>();
- gint16 max_sample_value = audio_stream->getMaxSampleValue();
+ int16_t max_sample_value = audio_stream->getMaxSampleValue();
if (max_sample_value > total_max_sample_value) {
total_max_sample_value = max_sample_value;
@@ -673,7 +680,7 @@ void RtpPlayerDialog::fillTappedColumns()
// true just for first stream
bool is_first = true;
- // Get all rows, immutable list. Later changes in rows migth reorder them
+ // Get all rows, immutable list. Later changes in rows might reorder them
QList<QTreeWidgetItem *> items = ui->streamTreeWidget->findItems(
QString("*"), Qt::MatchWrap | Qt::MatchWildcard | Qt::MatchRecursive);
@@ -887,6 +894,8 @@ void RtpPlayerDialog::setMarkers()
void RtpPlayerDialog::showEvent(QShowEvent *)
{
+ // We could use loadSplitterState(ui->splitter) instead of always
+ // resetting the plot size to 75%
QList<int> split_sizes = ui->splitter->sizes();
int tot_size = split_sizes[0] + split_sizes[1];
int plot_size = tot_size * 3 / 4;
@@ -1130,22 +1139,34 @@ void RtpPlayerDialog::itemEntered(QTreeWidgetItem *item, int column _U_)
void RtpPlayerDialog::mouseMovePlot(QMouseEvent *event)
{
+ // The calculations are expensive, so just store the position and
+ // calculate no more than once per some interval. (On Linux the
+ // QMouseEvents can be sent absurdly often, every 25 microseconds!)
+ mouse_pos_ = event->pos();
+ if (!mouse_update_timer_->isActive()) {
+ mouse_update_timer_->start();
+ }
+}
+
+void RtpPlayerDialog::mouseMoveUpdate()
+{
+ // findItemByCoords is expensive (because of calling pointDistance),
+ // and updateHintLabel calls it as well via getHoveredPacket. Some
+ // way to only perform the distance calculations once would be better.
updateHintLabel();
- QTreeWidgetItem *ti = findItemByCoords(event->pos());
+ QTreeWidgetItem *ti = findItemByCoords(mouse_pos_);
handleItemHighlight(ti, true);
}
-void RtpPlayerDialog::graphClicked(QMouseEvent *event)
+void RtpPlayerDialog::showGraphContextMenu(const QPoint &pos)
+{
+ graph_ctx_menu_->popup(ui->audioPlot->mapToGlobal(pos));
+}
+
+void RtpPlayerDialog::graphClicked(QMouseEvent*)
{
updateWidgets();
- if (event->button() == Qt::RightButton) {
-#if QT_VERSION >= QT_VERSION_CHECK(6, 0 ,0)
- graph_ctx_menu_->popup(event->globalPosition().toPoint());
-#else
- graph_ctx_menu_->popup(event->globalPos());
-#endif
- }
}
void RtpPlayerDialog::graphDoubleClicked(QMouseEvent *event)
@@ -1288,7 +1309,9 @@ void RtpPlayerDialog::playFinished(RtpAudioStream *stream, QAudio::Error error)
}
playing_streams_.removeOne(stream);
if (playing_streams_.isEmpty()) {
- marker_stream_->stop();
+ if (marker_stream_) {
+ marker_stream_->stop();
+ }
updateWidgets();
}
}
@@ -1427,7 +1450,7 @@ void RtpPlayerDialog::on_playButton_clicked()
#endif
marker_stream_->start(new AudioSilenceGenerator(marker_stream_));
// It may happen that stream play is finished before all others are started
- // therefore we do not use playing_streams_ there, but separate temporarly
+ // therefore we do not use playing_streams_ there, but separate temporarily
// list. It avoids access element/remove element race condition.
streams_to_start = playing_streams_;
for( int i = 0; i<streams_to_start.count(); ++i ) {
@@ -2280,11 +2303,11 @@ qint64 RtpPlayerDialog::saveAudioHeaderWAV(QFile *save_file, quint32 channels, u
{
uint8_t pd[4];
int64_t nchars;
- gint32 subchunk2Size;
- gint32 data32;
- gint16 data16;
+ int32_t subchunk2Size;
+ int32_t data32;
+ int16_t data16;
- subchunk2Size = sizeof(SAMPLE) * channels * (gint32)samples;
+ subchunk2Size = sizeof(SAMPLE) * channels * (int32_t)samples;
/* http://soundfile.sapp.org/doc/WaveFormat/ */
@@ -2352,14 +2375,14 @@ qint64 RtpPlayerDialog::saveAudioHeaderWAV(QFile *save_file, quint32 channels, u
}
/* WAVE fmt header, BlockAlign */
- data16 = channels * (gint16)sizeof(SAMPLE);
+ data16 = channels * (int16_t)sizeof(SAMPLE);
nchars = save_file->write((const char *)&data16, 2);
if (nchars != 2) {
return -1;
}
/* WAVE fmt header, BitsPerSample */
- data16 = (gint16)sizeof(SAMPLE) * 8;
+ data16 = (int16_t)sizeof(SAMPLE) * 8;
nchars = save_file->write((const char *)&data16, 2);
if (nchars != 2) {
return -1;
@@ -2416,12 +2439,12 @@ bool RtpPlayerDialog::writeAudioStreamsSamples(QFile *out_file, QVector<RtpAudio
if (swap_bytes) {
// same as phton16(), but more clear in compare
// to else branch
- pd[0] = (guint8)(sample >> 8);
- pd[1] = (guint8)(sample >> 0);
+ pd[0] = (uint8_t)(sample >> 8);
+ pd[1] = (uint8_t)(sample >> 0);
} else {
// just copy
- pd[1] = (guint8)(sample >> 8);
- pd[0] = (guint8)(sample >> 0);
+ pd[1] = (uint8_t)(sample >> 8);
+ pd[0] = (uint8_t)(sample >> 0);
}
read = true;
} else {
diff --git a/ui/qt/rtp_player_dialog.h b/ui/qt/rtp_player_dialog.h
index 5fba67db..0180e78f 100644
--- a/ui/qt/rtp_player_dialog.h
+++ b/ui/qt/rtp_player_dialog.h
@@ -12,7 +12,6 @@
#include "config.h"
-#include <glib.h>
#include <mutex>
#include "ui/rtp_stream.h"
@@ -146,6 +145,8 @@ private slots:
void updateWidgets();
void itemEntered(QTreeWidgetItem *item, int column);
void mouseMovePlot(QMouseEvent *event);
+ void mouseMoveUpdate();
+ void showGraphContextMenu(const QPoint &pos);
void graphClicked(QMouseEvent *event);
void graphDoubleClicked(QMouseEvent *event);
void plotClicked(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event);
@@ -245,11 +246,13 @@ private:
QToolButton *analyze_btn_;
QPushButton *prepare_btn_;
QPushButton *export_btn_;
- QMultiHash<guint, RtpAudioStream *> stream_hash_;
+ QMultiHash<unsigned, RtpAudioStream *> stream_hash_;
bool block_redraw_;
int lock_ui_;
bool read_capture_enabled_;
double silence_skipped_time_;
+ QTimer *mouse_update_timer_;
+ QPoint mouse_pos_;
// const QString streamKey(const rtpstream_info_t *rtpstream);
// const QString streamKey(const packet_info *pinfo, const struct _rtp_info *rtpinfo);
diff --git a/ui/qt/rtp_stream_dialog.cpp b/ui/qt/rtp_stream_dialog.cpp
index 6b28a837..3d3a1c70 100644
--- a/ui/qt/rtp_stream_dialog.cpp
+++ b/ui/qt/rtp_stream_dialog.cpp
@@ -269,7 +269,6 @@ public:
rtpstream_info_calc_free(&calc1);
rtpstream_info_calc_free(&calc2);
return ret;
- break;
case min_delta_col_:
return stream_info_->rtp_stats.min_delta < other_rstwi.stream_info_->rtp_stats.min_delta;
case mean_delta_col_:
@@ -290,14 +289,14 @@ public:
return QTreeWidgetItem::operator <(other);
}
- void setTOD(gboolean tod)
+ void setTOD(bool tod)
{
tod_ = tod;
}
private:
rtpstream_info_t *stream_info_;
- gboolean tod_;
+ bool tod_;
};
@@ -586,9 +585,9 @@ void RtpStreamDialog::updateStreams()
// string_list is reverse ordered, so we must add
// just first "to_insert_count" of streams
GList *cur_stream = g_list_first(tapinfo_.strinfo_list);
- guint tap_len = g_list_length(tapinfo_.strinfo_list);
- guint tree_len = static_cast<guint>(ui->streamTreeWidget->topLevelItemCount());
- guint to_insert_count = tap_len - tree_len;
+ unsigned tap_len = g_list_length(tapinfo_.strinfo_list);
+ unsigned tree_len = static_cast<unsigned>(ui->streamTreeWidget->topLevelItemCount());
+ unsigned to_insert_count = tap_len - tree_len;
// Add any missing items
while (cur_stream && cur_stream->data && to_insert_count) {
@@ -797,8 +796,8 @@ void RtpStreamDialog::on_actionExportAsRtpDump_triggered()
save_file, "RTPDump Format (*.rtp)", &extension);
if (file_name.length() > 0) {
- gchar *dest_file = qstring_strdup(file_name);
- gboolean save_ok = rtpstream_save(&tapinfo_, cap_file_.capFile(), stream_info, dest_file);
+ char *dest_file = qstring_strdup(file_name);
+ bool save_ok = rtpstream_save(&tapinfo_, cap_file_.capFile(), stream_info, dest_file);
g_free(dest_file);
// else error dialog?
if (save_ok) {
diff --git a/ui/qt/sctp_all_assocs_dialog.cpp b/ui/qt/sctp_all_assocs_dialog.cpp
index c8208d66..2d04e69f 100644
--- a/ui/qt/sctp_all_assocs_dialog.cpp
+++ b/ui/qt/sctp_all_assocs_dialog.cpp
@@ -49,13 +49,9 @@ void SCTPAllAssocsDialog::fillTable()
int numAssocs;
ui->assocList->setColumnHidden(0, true);
- ui->assocList->setColumnWidth(1, 85);
- ui->assocList->setColumnWidth(2, 85);
- ui->assocList->setColumnWidth(3, 150);
- ui->assocList->setColumnWidth(4, 150);
sctp_assocs = sctp_stat_get_info();
- if (sctp_assocs->is_registered == FALSE) {
+ if (sctp_assocs->is_registered == false) {
register_tap_listener_sctp_stat();
/* (redissect all packets) */
cf_retap_packets(cap_file_);
@@ -63,19 +59,43 @@ void SCTPAllAssocsDialog::fillTable()
numAssocs = 0;
ui->assocList->setRowCount(static_cast<int>(g_list_length(sctp_assocs->assoc_info_list)));
+ /* https://doc.qt.io/qt-6/qtablewidget.html#setItem suggests turning
+ * off sorting before setting several items of a row in a loop.
+ */
+ bool sorting = ui->assocList->isSortingEnabled();
+ if (sorting) {
+ ui->assocList->setSortingEnabled(false);
+ }
list = g_list_first(sctp_assocs->assoc_info_list);
+ QTableWidgetItem *item;
while (list) {
assinfo = gxx_list_data(const sctp_assoc_info_t*, list);
- ui->assocList->setItem(numAssocs, 0, new QTableWidgetItem(QString("%1").arg(assinfo->assoc_id)));
- ui->assocList->setItem(numAssocs, 1, new QTableWidgetItem(QString("%1").arg(assinfo->port1)));
- ui->assocList->setItem(numAssocs, 2, new QTableWidgetItem(QString("%1").arg(assinfo->port2)));
- ui->assocList->setItem(numAssocs, 3, new QTableWidgetItem(QString("%1").arg(assinfo->n_packets)));
- ui->assocList->setItem(numAssocs, 4, new QTableWidgetItem(QString("%1").arg(assinfo->n_data_chunks)));
- ui->assocList->setItem(numAssocs, 5, new QTableWidgetItem(QString("%1").arg(assinfo->n_data_bytes)));
+ item = new QTableWidgetItem();
+ item->setData(Qt::DisplayRole, assinfo->assoc_id);
+ ui->assocList->setItem(numAssocs, 0, item);
+ item = new QTableWidgetItem();
+ item->setData(Qt::DisplayRole, assinfo->port1);
+ ui->assocList->setItem(numAssocs, 1, item);
+ item = new QTableWidgetItem();
+ item->setData(Qt::DisplayRole, assinfo->port2);
+ ui->assocList->setItem(numAssocs, 2, item);
+ item = new QTableWidgetItem();
+ item->setData(Qt::DisplayRole, assinfo->n_packets);
+ ui->assocList->setItem(numAssocs, 3, item);
+ item = new QTableWidgetItem();
+ item->setData(Qt::DisplayRole, assinfo->n_data_chunks);
+ ui->assocList->setItem(numAssocs, 4, item);
+ item = new QTableWidgetItem();
+ item->setData(Qt::DisplayRole, assinfo->n_data_bytes);
+ ui->assocList->setItem(numAssocs, 5, item);
list = gxx_list_next(list);
numAssocs++;
}
+ if (sorting) {
+ ui->assocList->setSortingEnabled(true);
+ }
+ ui->assocList->resizeColumnsToContents();
ui->analyseButton->setEnabled(false);
ui->setFilterButton->setEnabled(false);
connect(ui->assocList, SIGNAL(itemSelectionChanged()), this, SLOT(getSelectedItem()));
diff --git a/ui/qt/sctp_all_assocs_dialog.h b/ui/qt/sctp_all_assocs_dialog.h
index c29c8e9b..93ebf3f9 100644
--- a/ui/qt/sctp_all_assocs_dialog.h
+++ b/ui/qt/sctp_all_assocs_dialog.h
@@ -12,8 +12,6 @@
#include <config.h>
-#include <glib.h>
-
#include <file.h>
#include <epan/dissectors/packet-sctp.h>
@@ -48,7 +46,7 @@ private slots:
private:
Ui::SCTPAllAssocsDialog *ui;
capture_file *cap_file_;
- guint16 selected_assoc_id;
+ uint16_t selected_assoc_id;
signals:
diff --git a/ui/qt/sctp_assoc_analyse_dialog.cpp b/ui/qt/sctp_assoc_analyse_dialog.cpp
index c6b4b11a..89a3d603 100644
--- a/ui/qt/sctp_assoc_analyse_dialog.cpp
+++ b/ui/qt/sctp_assoc_analyse_dialog.cpp
@@ -54,7 +54,7 @@ const sctp_assoc_info_t* SCTPAssocAnalyseDialog::findAssocForPacket(capture_file
bool frame_found = false;
fdata = cf->current_frame;
- if (sctp_stat_get_info()->is_registered == FALSE) {
+ if (sctp_stat_get_info()->is_registered == false) {
register_tap_listener_sctp_stat();
/* (redissect all packets) */
cf_retap_packets(cf);
@@ -65,11 +65,11 @@ const sctp_assoc_info_t* SCTPAssocAnalyseDialog::findAssocForPacket(capture_file
assoc = gxx_list_data(const sctp_assoc_info_t*, list);
framelist = g_list_first(assoc->frame_numbers);
- guint32 fn;
+ uint32_t fn;
while (framelist) {
fn = GPOINTER_TO_UINT(framelist->data);
if (fn == fdata->num) {
- frame_found = TRUE;
+ frame_found = true;
break;
}
framelist = gxx_list_next(framelist);
@@ -89,7 +89,7 @@ const sctp_assoc_info_t* SCTPAssocAnalyseDialog::findAssocForPacket(capture_file
return Q_NULLPTR;
}
-const _sctp_assoc_info* SCTPAssocAnalyseDialog::findAssoc(QWidget *parent, guint16 assoc_id)
+const _sctp_assoc_info* SCTPAssocAnalyseDialog::findAssoc(QWidget *parent, uint16_t assoc_id)
{
const sctp_assoc_info_t* result = get_sctp_assoc_info(assoc_id);
if (result) return result;
diff --git a/ui/qt/sctp_assoc_analyse_dialog.h b/ui/qt/sctp_assoc_analyse_dialog.h
index ec361f4c..335abfbf 100644
--- a/ui/qt/sctp_assoc_analyse_dialog.h
+++ b/ui/qt/sctp_assoc_analyse_dialog.h
@@ -12,8 +12,6 @@
#include <config.h>
-#include <glib.h>
-
#include <file.h>
#include <epan/dissectors/packet-sctp.h>
@@ -44,7 +42,7 @@ public:
void fillTabs(const _sctp_assoc_info* selected_assoc);
static const _sctp_assoc_info* findAssocForPacket(capture_file* cf);
- static const _sctp_assoc_info* findAssoc(QWidget *parent, guint16 assoc_id);
+ static const _sctp_assoc_info* findAssoc(QWidget *parent, uint16_t assoc_id);
public slots:
void setCaptureFile(capture_file *cf) { cap_file_ = cf; }
@@ -63,7 +61,7 @@ private slots:
private:
Ui::SCTPAssocAnalyseDialog *ui;
- guint16 selected_assoc_id;
+ uint16_t selected_assoc_id;
capture_file *cap_file_;
void openGraphDialog(int direction);
void openGraphByteDialog(int direction);
diff --git a/ui/qt/sctp_chunk_statistics_dialog.cpp b/ui/qt/sctp_chunk_statistics_dialog.cpp
index f77c2edd..20098a7b 100644
--- a/ui/qt/sctp_chunk_statistics_dialog.cpp
+++ b/ui/qt/sctp_chunk_statistics_dialog.cpp
@@ -62,7 +62,7 @@ SCTPChunkStatisticsDialog::~SCTPChunkStatisticsDialog()
void SCTPChunkStatisticsDialog::initializeChunkMap()
{
struct chunkTypes temp;
- gchar buf[16];
+ char buf[16];
for (int i = 0; i < 256; i++) {
temp.id = i;
@@ -94,7 +94,7 @@ void SCTPChunkStatisticsDialog::fillTable(bool all, const sctp_assoc_info_t *sel
return;
}
uat_t *uat = prefs_get_uat_value(pref);
- gchar* fname = uat_get_actual_filename(uat,TRUE);
+ char* fname = uat_get_actual_filename(uat,true);
bool init = false;
if (!fname) {
@@ -220,7 +220,7 @@ void SCTPChunkStatisticsDialog::on_pushButton_clicked()
uat_t *uat = prefs_get_uat_value(pref);
- gchar* fname = uat_get_actual_filename(uat,TRUE);
+ char* fname = uat_get_actual_filename(uat,true);
if (!fname) {
return;
@@ -228,7 +228,7 @@ void SCTPChunkStatisticsDialog::on_pushButton_clicked()
fp = ws_fopen(fname,"w");
if (!fp && errno == ENOENT) {
- gchar *pf_dir_path = NULL;
+ char *pf_dir_path = NULL;
if (create_persconffile_dir(&pf_dir_path) != 0) {
g_free (pf_dir_path);
return;
@@ -251,7 +251,7 @@ void SCTPChunkStatisticsDialog::on_pushButton_clicked()
snprintf(str, sizeof str, "\"%d\",\"%s\",\"%s\"\n", tempChunk.id, tempChunk.name, tempChunk.hide==0?"Show":"Hide");
fputs(str, fp);
void *rec = g_malloc0(uat->record_size);
- uat_add_record(uat, rec, TRUE);
+ uat_add_record(uat, rec, true);
if (uat->free_cb) {
uat->free_cb(rec);
}
@@ -287,7 +287,7 @@ void SCTPChunkStatisticsDialog::on_actionHideChunkType_triggered()
void SCTPChunkStatisticsDialog::on_actionChunkTypePreferences_triggered()
{
- gchar* err = NULL;
+ char* err = NULL;
pref_t *pref = prefs_find_preference(prefs_find_module("sctp"),"statistics_chunk_types");
if (!pref) {
diff --git a/ui/qt/sctp_chunk_statistics_dialog.h b/ui/qt/sctp_chunk_statistics_dialog.h
index aa45f752..1c18dad9 100644
--- a/ui/qt/sctp_chunk_statistics_dialog.h
+++ b/ui/qt/sctp_chunk_statistics_dialog.h
@@ -11,7 +11,6 @@
#define SCTP_CHUNK_STATISTICS_DIALOG_H
#include <config.h>
-#include <glib.h>
#include <file.h>
#include <wsutil/file_util.h>
@@ -62,7 +61,7 @@ signals:
private:
Ui::SCTPChunkStatisticsDialog *ui;
- guint16 selected_assoc_id;
+ uint16_t selected_assoc_id;
capture_file *cap_file_;
QMenu ctx_menu_;
QPoint selected_point;
diff --git a/ui/qt/sctp_graph_arwnd_dialog.cpp b/ui/qt/sctp_graph_arwnd_dialog.cpp
index 2734f28a..92c254fe 100644
--- a/ui/qt/sctp_graph_arwnd_dialog.cpp
+++ b/ui/qt/sctp_graph_arwnd_dialog.cpp
@@ -63,8 +63,8 @@ void SCTPGraphArwndDialog::drawArwndGraph(const sctp_assoc_info_t *selected_asso
struct sack_chunk_header *sack_header;
struct nr_sack_chunk_header *nr_sack_header;
tsn_t *tsn;
- guint8 type;
- guint32 arwnd=0;
+ uint8_t type;
+ uint32_t arwnd=0;
if (direction == 1) {
listSACK = g_list_last(selected_assoc->sack1);
@@ -161,7 +161,7 @@ void SCTPGraphArwndDialog::graphClicked(QCPAbstractPlottable* plottable, int, QM
}
}
if (cap_file_ && frame_num > 0) {
- cf_goto_frame(cap_file_, frame_num);
+ cf_goto_frame(cap_file_, frame_num, false);
}
ui->hintLabel->setText(QString(tr("<small><i>Graph %1: a_rwnd=%2 Time=%3 secs </i></small>"))
diff --git a/ui/qt/sctp_graph_arwnd_dialog.h b/ui/qt/sctp_graph_arwnd_dialog.h
index c74d43d3..7c30b84d 100644
--- a/ui/qt/sctp_graph_arwnd_dialog.h
+++ b/ui/qt/sctp_graph_arwnd_dialog.h
@@ -11,7 +11,6 @@
#define SCTP_GRAPH_ARWND_DIALOG_H
#include <config.h>
-#include <glib.h>
#include "cfile.h"
@@ -46,13 +45,13 @@ private slots:
private:
Ui::SCTPGraphArwndDialog *ui;
- guint16 selected_assoc_id;
+ uint16_t selected_assoc_id;
capture_file *cap_file_;
int frame_num;
int direction;
- guint32 startArwnd;
+ uint32_t startArwnd;
QVector<double> xa, ya;
- QVector<guint32> fa;
+ QVector<uint32_t> fa;
// QVector<QString> typeStrings;
void drawGraph(const _sctp_assoc_info *selected_assoc);
diff --git a/ui/qt/sctp_graph_byte_dialog.cpp b/ui/qt/sctp_graph_byte_dialog.cpp
index bd91c088..660a70d1 100644
--- a/ui/qt/sctp_graph_byte_dialog.cpp
+++ b/ui/qt/sctp_graph_byte_dialog.cpp
@@ -61,9 +61,9 @@ void SCTPGraphByteDialog::drawBytesGraph(const sctp_assoc_info_t *selected_assoc
{
GList *listTSN = Q_NULLPTR, *tlist = Q_NULLPTR;
tsn_t *tsn = Q_NULLPTR;
- guint8 type;
- guint32 maxBytes;
- guint64 sumBytes = 0;
+ uint8_t type;
+ uint32_t maxBytes;
+ uint64_t sumBytes = 0;
if (direction == 1) {
maxBytes = selected_assoc->n_data_bytes_ep1;
@@ -77,7 +77,7 @@ void SCTPGraphByteDialog::drawBytesGraph(const sctp_assoc_info_t *selected_assoc
while (listTSN) {
tsn = gxx_list_data(tsn_t*, listTSN);
tlist = g_list_first(tsn->tsns);
- guint16 length;
+ uint16_t length;
while (tlist)
{
type = gxx_list_data(struct chunk_header *, tlist)->type;
@@ -164,7 +164,7 @@ void SCTPGraphByteDialog::graphClicked(QCPAbstractPlottable* plottable, int, QMo
}
}
if (cap_file_ && frame_num > 0) {
- cf_goto_frame(cap_file_, frame_num);
+ cf_goto_frame(cap_file_, frame_num, false);
}
ui->hintLabel->setText(QString(tr("<small><i>Graph %1: Received bytes=%2 Time=%3 secs </i></small>"))
diff --git a/ui/qt/sctp_graph_byte_dialog.h b/ui/qt/sctp_graph_byte_dialog.h
index e6785da9..b331ad9f 100644
--- a/ui/qt/sctp_graph_byte_dialog.h
+++ b/ui/qt/sctp_graph_byte_dialog.h
@@ -11,7 +11,6 @@
#define SCTP_GRAPH_BYTE_DIALOG_H
#include <config.h>
-#include <glib.h>
#include "cfile.h"
@@ -46,12 +45,12 @@ private slots:
private:
Ui::SCTPGraphByteDialog *ui;
- guint16 selected_assoc_id;
+ uint16_t selected_assoc_id;
capture_file *cap_file_;
int frame_num;
int direction;
QVector<double> xb, yb;
- QVector<guint32> fb;
+ QVector<uint32_t> fb;
void drawGraph();
void drawBytesGraph(const _sctp_assoc_info *selected_assoc);
diff --git a/ui/qt/sctp_graph_dialog.cpp b/ui/qt/sctp_graph_dialog.cpp
index a26f0d11..e0e69faf 100644
--- a/ui/qt/sctp_graph_dialog.cpp
+++ b/ui/qt/sctp_graph_dialog.cpp
@@ -67,13 +67,13 @@ void SCTPGraphDialog::drawNRSACKGraph(const sctp_assoc_info_t* selected_assoc)
{
tsn_t *sack = Q_NULLPTR;
GList *list = Q_NULLPTR, *tlist = Q_NULLPTR;
- guint16 gap_start=0, gap_end=0, i, numberOf_gaps, numberOf_nr_gaps;
- guint8 type;
- guint32 tsnumber, j = 0, min_tsn, rel = 0;
+ uint16_t gap_start=0, gap_end=0, i, numberOf_gaps, numberOf_nr_gaps;
+ uint8_t type;
+ uint32_t tsnumber, j = 0, min_tsn, rel = 0;
struct nr_sack_chunk_header *nr_sack_header = Q_NULLPTR;
struct gaps *nr_gap = Q_NULLPTR;
/* This holds the sum of gap acks and nr gap acks */
- guint16 total_gaps = 0;
+ uint16_t total_gaps = 0;
if (direction == 1) {
list = g_list_last(selected_assoc->sack1);
@@ -133,14 +133,14 @@ void SCTPGraphDialog::drawNRSACKGraph(const sctp_assoc_info_t* selected_assoc)
void SCTPGraphDialog::drawSACKGraph(const sctp_assoc_info_t* selected_assoc)
{
GList *listSACK = Q_NULLPTR, *tlist = Q_NULLPTR;
- guint16 gap_start=0, gap_end=0, nr, dup_nr;
+ uint16_t gap_start=0, gap_end=0, nr, dup_nr;
struct sack_chunk_header *sack_header = Q_NULLPTR;
struct gaps *gap = Q_NULLPTR;
tsn_t *tsn = Q_NULLPTR;
- guint8 type;
- guint32 tsnumber=0, rel = 0;
- guint32 minTSN;
- guint32 *dup_list = Q_NULLPTR;
+ uint8_t type;
+ uint32_t tsnumber=0, rel = 0;
+ uint32_t minTSN;
+ uint32_t *dup_list = Q_NULLPTR;
int i, j;
if (direction == 1) {
@@ -262,8 +262,8 @@ void SCTPGraphDialog::drawTSNGraph(const sctp_assoc_info_t* selected_assoc)
{
GList *listTSN = Q_NULLPTR,*tlist = Q_NULLPTR;
tsn_t *tsn = Q_NULLPTR;
- guint8 type;
- guint32 tsnumber=0, rel = 0, minTSN;
+ uint8_t type;
+ uint32_t tsnumber=0, rel = 0, minTSN;
if (direction == 1) {
listTSN = g_list_last(selected_assoc->tsn1);
@@ -321,7 +321,7 @@ void SCTPGraphDialog::drawGraph(const sctp_assoc_info_t* selected_assoc)
if (!selected_assoc) return;
}
- guint32 maxTSN, minTSN;
+ uint32_t maxTSN, minTSN;
if (direction == 1) {
maxTSN = selected_assoc->max_tsn1;
@@ -467,7 +467,7 @@ void SCTPGraphDialog::graphClicked(QCPAbstractPlottable* plottable, int, QMouseE
}
}
if (cap_file_ && frame_num > 0) {
- cf_goto_frame(cap_file_, frame_num);
+ cf_goto_frame(cap_file_, frame_num, false);
}
ui->hintLabel->setText(QString(tr("<small><i>%1: %2 Time: %3 secs </i></small>"))
.arg(plottable->name())
diff --git a/ui/qt/sctp_graph_dialog.h b/ui/qt/sctp_graph_dialog.h
index 28aeccb0..06cfdd94 100644
--- a/ui/qt/sctp_graph_dialog.h
+++ b/ui/qt/sctp_graph_dialog.h
@@ -11,7 +11,6 @@
#define SCTP_GRAPH_DIALOG_H
#include <config.h>
-#include <glib.h>
#include "cfile.h"
@@ -27,47 +26,47 @@ class QCustomPlot;
struct _sctp_assoc_info;
struct chunk_header {
- guint8 type;
- guint8 flags;
- guint16 length;
+ uint8_t type;
+ uint8_t flags;
+ uint16_t length;
};
struct data_chunk_header {
- guint8 type;
- guint8 flags;
- guint16 length;
- guint32 tsn;
- guint16 sid;
- guint16 ssn;
- guint32 ppi;
+ uint8_t type;
+ uint8_t flags;
+ uint16_t length;
+ uint32_t tsn;
+ uint16_t sid;
+ uint16_t ssn;
+ uint32_t ppi;
};
struct gaps {
- guint16 start;
- guint16 end;
+ uint16_t start;
+ uint16_t end;
};
struct sack_chunk_header {
- guint8 type;
- guint8 flags;
- guint16 length;
- guint32 cum_tsn_ack;
- guint32 a_rwnd;
- guint16 nr_of_gaps;
- guint16 nr_of_dups;
+ uint8_t type;
+ uint8_t flags;
+ uint16_t length;
+ uint32_t cum_tsn_ack;
+ uint32_t a_rwnd;
+ uint16_t nr_of_gaps;
+ uint16_t nr_of_dups;
struct gaps gaps[1];
};
struct nr_sack_chunk_header {
- guint8 type;
- guint8 flags;
- guint16 length;
- guint32 cum_tsn_ack;
- guint32 a_rwnd;
- guint16 nr_of_gaps;
- guint16 nr_of_nr_gaps;
- guint16 nr_of_dups;
- guint16 reserved;
+ uint8_t type;
+ uint8_t flags;
+ uint16_t length;
+ uint32_t cum_tsn_ack;
+ uint32_t a_rwnd;
+ uint16_t nr_of_gaps;
+ uint16_t nr_of_nr_gaps;
+ uint16_t nr_of_dups;
+ uint16_t reserved;
struct gaps gaps[1];
};
@@ -102,12 +101,12 @@ private slots:
private:
Ui::SCTPGraphDialog *ui;
- guint16 selected_assoc_id;
+ uint16_t selected_assoc_id;
capture_file *cap_file_;
int frame_num;
int direction;
QVector<double> xt, yt, xs, ys, xg, yg, xd, yd, xn, yn;
- QVector<guint32> ft, fs, fg, fd, fn;
+ QVector<uint32_t> ft, fs, fg, fd, fn;
QVector<QString> typeStrings;
bool relative;
int type;
diff --git a/ui/qt/search_frame.cpp b/ui/qt/search_frame.cpp
index 95a5b8e8..d4a332d8 100644
--- a/ui/qt/search_frame.cpp
+++ b/ui/qt/search_frame.cpp
@@ -16,10 +16,13 @@
#include <epan/proto.h>
#include <epan/strutil.h>
+#include <wsutil/filesystem.h>
#include <wsutil/utf8_entities.h>
#include <wsutil/regex.h>
#include "main_application.h"
+#include "utils/qt_ui_utils.h"
+
#include <QKeyEvent>
#include <QCheckBox>
@@ -56,6 +59,18 @@ SearchFrame::SearchFrame(QWidget *parent) :
}
#endif
+ if (!is_packet_configuration_namespace()) {
+ sf_ui_->searchInComboBox->setItemText(0, tr("Event List"));
+ sf_ui_->searchInComboBox->setItemText(1, tr("Event Details"));
+ sf_ui_->searchInComboBox->setItemText(2, tr("Event Bytes"));
+ sf_ui_->searchInComboBox->setToolTip(tr("<html><head/><body>"
+ "<p>Search the Info column of the event list (summary pane), "
+ "decoded event display labels (tree view pane) or the "
+ "ASCII-converted event data (hex view pane).</p>"
+ "</body></html>"));
+ }
+
+
applyRecentSearchSettings();
updateWidgets();
@@ -80,7 +95,7 @@ void SearchFrame::findNext()
{
if (!cap_file_) return;
- cap_file_->dir = SD_FORWARD;
+ sf_ui_->dirCheckBox->setChecked(false);
if (isHidden()) {
animatedShow();
return;
@@ -92,7 +107,7 @@ void SearchFrame::findPrevious()
{
if (!cap_file_) return;
- cap_file_->dir = SD_BACKWARD;
+ sf_ui_->dirCheckBox->setChecked(true);
if (isHidden()) {
animatedShow();
return;
@@ -104,7 +119,6 @@ void SearchFrame::setFocus()
{
sf_ui_->searchLineEdit->setFocus();
sf_ui_->searchLineEdit->selectAll();
- cap_file_->dir = SD_FORWARD;
}
void SearchFrame::setCaptureFile(capture_file *cf)
@@ -145,6 +159,9 @@ bool SearchFrame::regexCompile()
if (!sf_ui_->caseCheckBox->isChecked()) {
flags |= WS_REGEX_CASELESS;
}
+ if (sf_ui_->dirCheckBox->isChecked()) {
+ flags |= WS_REGEX_ANCHORED;
+ }
if (regex_) {
ws_regex_free(regex_);
@@ -221,6 +238,8 @@ void SearchFrame::applyRecentSearchSettings()
sf_ui_->charEncodingComboBox->setCurrentIndex(char_encoding_idx);
sf_ui_->caseCheckBox->setChecked(recent.gui_search_case_sensitive);
sf_ui_->searchTypeComboBox->setCurrentIndex(search_type_idx);
+ sf_ui_->dirCheckBox->setChecked(recent.gui_search_reverse_dir);
+ sf_ui_->multipleCheckBox->setChecked(recent.gui_search_multiple_occurs);
}
void SearchFrame::updateWidgets()
@@ -235,7 +254,15 @@ void SearchFrame::updateWidgets()
int search_type = sf_ui_->searchTypeComboBox->currentIndex();
sf_ui_->searchInComboBox->setEnabled(search_type == string_search_ || search_type == regex_search_);
sf_ui_->caseCheckBox->setEnabled(search_type == string_search_ || search_type == regex_search_);
- sf_ui_->charEncodingComboBox->setEnabled(search_type == string_search_);
+ // The encoding only is used when searching the raw Packet Bytes
+ // (otherwise all strings have already been converted to UTF-8)
+ sf_ui_->charEncodingComboBox->setEnabled(search_type == string_search_ && sf_ui_->searchInComboBox->currentIndex() == in_bytes_);
+
+ // We can search for multiple matches in the same frame if we're doing
+ // a Proto Tree search or a Frame Bytes search, but not a string/regex
+ // search in the Packet List, or a display filter search (since those
+ // don't highlight what fields / offsets caused the match.)
+ sf_ui_->multipleCheckBox->setEnabled((sf_ui_->searchInComboBox->isEnabled() && sf_ui_->searchInComboBox->currentIndex() != in_packet_list_) || search_type == hex_search_);
switch (search_type) {
case df_search_:
@@ -245,7 +272,7 @@ void SearchFrame::updateWidgets()
if (sf_ui_->searchLineEdit->text().isEmpty()) {
sf_ui_->searchLineEdit->setSyntaxState(SyntaxLineEdit::Invalid);
} else {
- guint8 *bytes;
+ uint8_t *bytes;
size_t nbytes;
bytes = convert_string_to_hex(sf_ui_->searchLineEdit->text().toUtf8().constData(), &nbytes);
if (bytes == nullptr)
@@ -297,6 +324,9 @@ void SearchFrame::on_searchInComboBox_currentIndexChanged(int idx)
default:
break;
}
+
+ // We only search for multiple occurrences in packet list and bytes
+ updateWidgets();
}
void SearchFrame::on_charEncodingComboBox_currentIndexChanged(int idx)
@@ -359,27 +389,39 @@ void SearchFrame::on_searchLineEdit_textChanged(const QString &)
updateWidgets();
}
+void SearchFrame::on_dirCheckBox_toggled(bool checked)
+{
+ recent.gui_search_reverse_dir = checked;
+}
+
+void SearchFrame::on_multipleCheckBox_toggled(bool checked)
+{
+ recent.gui_search_multiple_occurs = checked;
+}
+
void SearchFrame::on_findButton_clicked()
{
- guint8 *bytes = nullptr;
+ uint8_t *bytes = nullptr;
size_t nbytes = 0;
char *string = nullptr;
dfilter_t *dfp = nullptr;
- gboolean found_packet = FALSE;
+ bool found_packet = false;
QString err_string;
if (!cap_file_) {
return;
}
- cap_file_->hex = FALSE;
- cap_file_->string = FALSE;
- cap_file_->case_type = FALSE;
+ cap_file_->hex = false;
+ cap_file_->string = false;
+ cap_file_->case_type = false;
cap_file_->regex = nullptr;
- cap_file_->packet_data = FALSE;
- cap_file_->decode_data = FALSE;
- cap_file_->summary_data = FALSE;
+ cap_file_->packet_data = false;
+ cap_file_->decode_data = false;
+ cap_file_->summary_data = false;
cap_file_->scs_type = SCS_NARROW_AND_WIDE;
+ cap_file_->dir = sf_ui_->dirCheckBox->isChecked() ? SD_BACKWARD : SD_FORWARD;
+ bool multiple_occurrences = sf_ui_->multipleCheckBox->isChecked();
int search_type = sf_ui_->searchTypeComboBox->currentIndex();
switch (search_type) {
@@ -400,7 +442,7 @@ void SearchFrame::on_findButton_clicked()
err_string = tr("That's not a valid hex string.");
goto search_done;
}
- cap_file_->hex = TRUE;
+ cap_file_->hex = true;
break;
case string_search_:
case regex_search_:
@@ -408,8 +450,8 @@ void SearchFrame::on_findButton_clicked()
err_string = tr("You didn't specify any text for which to search.");
goto search_done;
}
- cap_file_->string = TRUE;
- cap_file_->case_type = sf_ui_->caseCheckBox->isChecked() ? FALSE : TRUE;
+ cap_file_->string = true;
+ cap_file_->case_type = sf_ui_->caseCheckBox->isChecked() ? false : true;
cap_file_->regex = (search_type == regex_search_ ? regex_ : nullptr);
switch (sf_ui_->charEncodingComboBox->currentIndex()) {
case narrow_and_wide_chars_:
@@ -434,13 +476,13 @@ void SearchFrame::on_findButton_clicked()
switch (sf_ui_->searchInComboBox->currentIndex()) {
case in_packet_list_:
- cap_file_->summary_data = TRUE;
+ cap_file_->summary_data = true;
break;
case in_proto_tree_:
- cap_file_->decode_data = TRUE;
+ cap_file_->decode_data = true;
break;
case in_bytes_:
- cap_file_->packet_data = TRUE;
+ cap_file_->packet_data = true;
break;
default:
err_string = tr("No valid search area selected. Please report this to the development team.");
@@ -448,13 +490,13 @@ void SearchFrame::on_findButton_clicked()
}
g_free(cap_file_->sfilter);
- cap_file_->sfilter = g_strdup(sf_ui_->searchLineEdit->text().toUtf8().constData());
+ cap_file_->sfilter = qstring_strdup(sf_ui_->searchLineEdit->text());
mainApp->popStatus(MainApplication::FileStatus);
mainApp->pushStatus(MainApplication::FileStatus, tr("Searching for %1…").arg(sf_ui_->searchLineEdit->text()));
if (cap_file_->hex) {
/* Hex value in packet data */
- found_packet = cf_find_packet_data(cap_file_, bytes, nbytes, cap_file_->dir);
+ found_packet = cf_find_packet_data(cap_file_, bytes, nbytes, cap_file_->dir, multiple_occurrences);
g_free(bytes);
if (!found_packet) {
/* We didn't find a packet */
@@ -476,7 +518,7 @@ void SearchFrame::on_findButton_clicked()
}
} else if (cap_file_->decode_data) {
/* String in the protocol tree headings */
- found_packet = cf_find_packet_protocol_tree(cap_file_, string, cap_file_->dir);
+ found_packet = cf_find_packet_protocol_tree(cap_file_, string, cap_file_->dir, multiple_occurrences);
g_free(string);
if (!found_packet) {
err_string = tr("No packet contained that string in its dissected display.");
@@ -484,7 +526,7 @@ void SearchFrame::on_findButton_clicked()
}
} else if (cap_file_->packet_data && string) {
/* String in the ASCII-converted packet data */
- found_packet = cf_find_packet_data(cap_file_, (guint8 *) string, strlen(string), cap_file_->dir);
+ found_packet = cf_find_packet_data(cap_file_, (uint8_t *) string, strlen(string), cap_file_->dir, multiple_occurrences);
g_free(string);
if (!found_packet) {
err_string = tr("No packet contained that string in its converted data.");
diff --git a/ui/qt/search_frame.h b/ui/qt/search_frame.h
index 7ea0946a..52a2a489 100644
--- a/ui/qt/search_frame.h
+++ b/ui/qt/search_frame.h
@@ -56,6 +56,8 @@ private slots:
void on_caseCheckBox_toggled(bool checked);
void on_searchTypeComboBox_currentIndexChanged(int idx);
void on_searchLineEdit_textChanged(const QString &);
+ void on_dirCheckBox_toggled(bool checked);
+ void on_multipleCheckBox_toggled(bool checked);
void on_findButton_clicked();
void on_cancelButton_clicked();
};
diff --git a/ui/qt/search_frame.ui b/ui/qt/search_frame.ui
index c3bb9908..0229d6f9 100644
--- a/ui/qt/search_frame.ui
+++ b/ui/qt/search_frame.ui
@@ -19,7 +19,18 @@
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
- <layout class="QHBoxLayout" name="horizontalLayout" stretch="3,0,0,0,0,0,0,1,0,0">
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="spacing">
+ <number>4</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout" stretch="3,0,0,0,1,0,0">
<property name="topMargin">
<number>0</number>
</property>
@@ -78,114 +89,179 @@
</spacer>
</item>
<item>
- <widget class="QComboBox" name="charEncodingComboBox">
+ <widget class="QComboBox" name="searchTypeComboBox">
<property name="toolTip">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for strings containing narrow (UTF-8 and ASCII) or wide (UTF-16) characters.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5), a plain string (e.g. My String) or a regular expression (e.g. colou?r).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<item>
<property name="text">
- <string>Narrow &amp; Wide</string>
+ <string>Display filter</string>
</property>
</item>
<item>
<property name="text">
- <string>Narrow (UTF-8 / ASCII)</string>
+ <string>Hex value</string>
</property>
</item>
<item>
<property name="text">
- <string>Wide (UTF-16)</string>
+ <string>String</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Regular Expression</string>
</property>
</item>
</widget>
</item>
<item>
- <widget class="QCheckBox" name="caseCheckBox">
+ <widget class="DisplayFilterEdit" name="searchLineEdit">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="findButton">
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>27</height>
+ </size>
+ </property>
<property name="text">
- <string>Case sensitive</string>
+ <string>Find</string>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="cancelButton">
+ <property name="maximumSize">
+ <size>
+ <width>16777215</width>
+ <height>27</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>Cancel</string>
</property>
</widget>
</item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="3,0,0,0,0,0,0,1">
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
<item>
- <spacer name="horizontalSpacer">
+ <spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
<property name="sizeHint" stdset="0">
<size>
- <width>20</width>
- <height>10</height>
+ <width>40</width>
+ <height>20</height>
</size>
</property>
</spacer>
</item>
<item>
- <widget class="QComboBox" name="searchTypeComboBox">
+ <widget class="QLabel" name="optionLabel">
+ <property name="text">
+ <string>&lt;b&gt;Options:&lt;/b&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="charEncodingComboBox">
<property name="toolTip">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5), a plain string (e.g. My String) or a regular expression (e.g. colou?r).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for strings containing narrow (UTF-8 and ASCII) or wide (UTF-16) characters.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<item>
<property name="text">
- <string>Display filter</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Hex value</string>
+ <string>Narrow &amp; Wide</string>
</property>
</item>
<item>
<property name="text">
- <string>String</string>
+ <string>Narrow (UTF-8 / ASCII)</string>
</property>
</item>
<item>
<property name="text">
- <string>Regular Expression</string>
+ <string>Wide (UTF-16)</string>
</property>
</item>
</widget>
</item>
<item>
- <widget class="DisplayFilterEdit" name="searchLineEdit">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>1</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
+ <widget class="QCheckBox" name="caseCheckBox">
+ <property name="text">
+ <string>Case sensitive</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="findButton">
- <property name="maximumSize">
+ <spacer name="horizontalSpacer_5">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
<size>
- <width>16777215</width>
- <height>27</height>
+ <width>20</width>
+ <height>10</height>
</size>
</property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="dirCheckBox">
<property name="text">
- <string>Find</string>
- </property>
- <property name="default">
- <bool>true</bool>
+ <string>Backwards</string>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="cancelButton">
- <property name="maximumSize">
+ <spacer name="horizontalSpacer_6">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
<size>
- <width>16777215</width>
- <height>27</height>
+ <width>20</width>
+ <height>10</height>
</size>
</property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="multipleCheckBox">
+ <property name="toolTip">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for a subsequent occurrence in the current packet before advancing to the next packet.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
<property name="text">
- <string>Cancel</string>
+ <string>Multiple occurrences</string>
</property>
</widget>
</item>
</layout>
+ </item>
+ </layout>
</widget>
<customwidgets>
<customwidget>
diff --git a/ui/qt/sequence_diagram.cpp b/ui/qt/sequence_diagram.cpp
index 4628915b..fd28a1e1 100644
--- a/ui/qt/sequence_diagram.cpp
+++ b/ui/qt/sequence_diagram.cpp
@@ -11,9 +11,11 @@
#include "epan/addr_resolv.h"
#include "epan/sequence_analysis.h"
+#include "epan/column.h"
#include <ui/qt/utils/color_utils.h>
#include <ui/qt/utils/qt_ui_utils.h>
+#include <ui/qt/widgets/qcp_axis_ticker_elided.h>
#include "ui/recent.h"
#include <QFont>
@@ -66,9 +68,12 @@ SequenceDiagram::SequenceDiagram(QCPAxis *keyAxis, QCPAxis *valueAxis, QCPAxis *
axis->setTicker(ticker);
axis->setSubTickPen(no_pen);
axis->setTickPen(no_pen);
- axis->setBasePen(no_pen);
+ axis->setSelectedTickPen(no_pen);
}
+ QSharedPointer<QCPAxisTicker> ticker(new QCPAxisTickerElided(comment_axis_));
+ comment_axis_->setTicker(ticker);
+
value_axis_->grid()->setVisible(false);
key_axis_->setRangeReversed(true);
@@ -82,6 +87,14 @@ SequenceDiagram::SequenceDiagram(QCPAxis *keyAxis, QCPAxis *valueAxis, QCPAxis *
smooth_font_size(comment_font);
comment_axis_->setTickLabelFont(comment_font);
comment_axis_->setSelectedTickLabelFont(QFont(comment_font.family(), comment_font.pointSizeF(), QFont::Bold));
+
+ // By default QCPAxisRect auto resizes, which creates some slight but
+ // noticeable horizontal movement when scrolling vertically. Prevent that.
+ key_axis_->axisRect()->setAutoMargins(QCP::msTop | QCP::msBottom);
+ int time_margin = QFontMetrics(key_axis_->tickLabelFont()).horizontalAdvance(get_column_longest_string(COL_CLS_TIME));
+ int comment_margin = QFontMetrics(comment_font).height() * (max_comment_em_width_ + 1); // Add 1 as using the exact elided width is slightly too narrow
+ key_axis_->axisRect()->setMargins(QMargins(time_margin, 0, comment_margin, 0));
+
// frame_label
// port_src -----------------> port_dst
@@ -127,7 +140,7 @@ int SequenceDiagram::adjacentPacket(bool next)
it = data_->constEnd();
--it;
while (it != data_->constBegin()) {
- guint32 prev_frame = it.value().value->frame_number;
+ uint32_t prev_frame = it.value().value->frame_number;
--it;
if (prev_frame == selected_packet_) {
adjacent_packet = it.value().value->frame_number;
@@ -149,8 +162,6 @@ void SequenceDiagram::setData(_seq_analysis_info *sainfo)
double cur_key = 0.0;
QVector<double> key_ticks, val_ticks;
QVector<QString> key_labels, val_labels, com_labels;
- QFontMetrics com_fm(comment_axis_->tickLabelFont());
- int elide_w = com_fm.height() * max_comment_em_width_;
char* addr_str;
for (GList *cur = g_queue_peek_nth_link(sainfo->items, 0); cur; cur = gxx_list_next(cur)) {
@@ -165,7 +176,7 @@ void SequenceDiagram::setData(_seq_analysis_info *sainfo)
key_ticks.append(cur_key);
key_labels.append(sai->time_str);
- com_labels.append(com_fm.elidedText(sai->comment, Qt::ElideRight, elide_w));
+ com_labels.append(sai->comment);
cur_key++;
}
@@ -211,6 +222,20 @@ _seq_analysis_item *SequenceDiagram::itemForPosY(int ypos)
return NULL;
}
+bool SequenceDiagram::inComment(QPoint pos) const
+{
+ return pos.x() >= (comment_axis_->axisRect()->right()
+ + comment_axis_->padding()
+ + comment_axis_->tickLabelPadding()
+ + comment_axis_->offset());
+}
+
+QString SequenceDiagram::elidedComment(const QString &text) const
+{
+ QSharedPointer<QCPAxisTickerElided> comment_ticker = qSharedPointerCast<QCPAxisTickerElided>(comment_axis_->ticker());
+ return comment_ticker->elidedText(text);
+}
+
double SequenceDiagram::selectTest(const QPointF &pos, bool, QVariant *) const
{
double key_pos = qRound(key_axis_->pixelToCoord(pos.y()));
@@ -327,11 +352,7 @@ void SequenceDiagram::draw(QCPPainter *painter)
double arrow_width = (arrow_end.x() - arrow_start.x()) * dir_mul;
QString arrow_label = cfm.elidedText(sai->frame_label, Qt::ElideRight, arrow_width);
int arrow_label_width = 0;
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
arrow_label_width = cfm.horizontalAdvance(arrow_label);
-#else
- arrow_label_width = cfm.width(arrow_label);
-#endif
QPoint text_pt(comment_start + ((arrow_width - arrow_label_width) / 2),
arrow_start.y() - (en_w / 2));
@@ -344,11 +365,7 @@ void SequenceDiagram::draw(QCPPainter *painter)
QString port_left = QString::number(dir_mul > 0 ? sai->port_src : sai->port_dst);
QString port_right = QString::number(dir_mul > 0 ? sai->port_dst : sai->port_src);
int port_left_width = 0;
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
port_left_width = cfm.horizontalAdvance(port_left);
-#else
- port_left_width = cfm.width(port_left);
-#endif
text_pt = QPoint(left_x - en_w - port_left_width, arrow_start.y() + (en_w / 2));
painter->drawText(text_pt, port_left);
diff --git a/ui/qt/sequence_diagram.h b/ui/qt/sequence_diagram.h
index aa9a377a..a3c1327d 100644
--- a/ui/qt/sequence_diagram.h
+++ b/ui/qt/sequence_diagram.h
@@ -12,8 +12,6 @@
#include <config.h>
-#include <glib.h>
-
#include <epan/address.h>
#include <QObject>
@@ -53,6 +51,8 @@ public:
// non-property methods:
struct _seq_analysis_item *itemForPosY(int ypos);
+ bool inComment(QPoint pos) const;
+ QString elidedComment(const QString &text) const;
// reimplemented virtual methods:
virtual void clearData() { data_->clear(); }
@@ -73,7 +73,7 @@ private:
QCPAxis *comment_axis_;
WSCPSeqDataMap *data_;
struct _seq_analysis_info *sainfo_;
- guint32 selected_packet_;
+ uint32_t selected_packet_;
double selected_key_;
};
diff --git a/ui/qt/sequence_dialog.cpp b/ui/qt/sequence_dialog.cpp
index 2f5b5ede..8a541979 100644
--- a/ui/qt/sequence_dialog.cpp
+++ b/ui/qt/sequence_dialog.cpp
@@ -35,27 +35,20 @@
#include <QPoint>
// To do:
-// - Resize or show + hide the Time and Comment axes, possibly via one of
-// the following:
-// - Split the time, diagram, and comment sections into three separate
-// widgets inside a QSplitter. This would resemble the GTK+ UI, but we'd
-// have to coordinate between the three and we'd lose time and comment
-// values in PDF and PNG exports.
-// - Add separate controls for the width and/or visibility of the Time and
-// Comment columns.
-// - Fake a splitter widget by catching mouse events in the plot area.
-// Drawing a QCPItemLine or QCPItemPixmap over each Y axis might make
-// this easier.
+// - Resize the Time and Comment axis as well?
// - For general flows, let the user show columns other than COL_INFO.
+// (#12549)
// - Add UTF8 to text dump
// - Save to XMI? https://www.spinellis.gr/umlgraph/
-// - Time: abs vs delta
+// - Save to SVG? https://www.qcustomplot.com/index.php/support/forum/1677
+// - Time: abs vs delta (XXX - This is currently achieved by changing
+// View->Time Display Format before opening the dialog.)
// - Hide nodes
-// - Clickable time + comments?
+// - Clickable time + comments? (XXX - Clicking on them selects the item for
+// the row, is there anything else?)
// - Incorporate packet comments?
// - Change line_style to seq_type (i.e. draw ACKs dashed)
// - Create WSGraph subclasses with common behavior.
-// - Help button and text
static const double min_top_ = -1.0;
static const double min_left_ = -0.5;
@@ -66,14 +59,16 @@ typedef struct {
SequenceInfo *info;
} sequence_items_t;
-SequenceDialog::SequenceDialog(QWidget &parent, CaptureFile &cf, SequenceInfo *info) :
+SequenceDialog::SequenceDialog(QWidget &parent, CaptureFile &cf, SequenceInfo *info, bool voipFeatures) :
WiresharkDialog(parent, cf),
ui(new Ui::SequenceDialog),
info_(info),
num_items_(0),
packet_num_(0),
sequence_w_(1),
- voipFeaturesEnabled(false)
+ axis_pressed_(false),
+ current_rtp_sai_hovered_(nullptr),
+ voipFeaturesEnabled(voipFeatures)
{
QAction *action;
@@ -86,6 +81,7 @@ SequenceDialog::SequenceDialog(QWidget &parent, CaptureFile &cf, SequenceInfo *i
if (!info_) {
info_ = new SequenceInfo(sequence_analysis_info_new());
info_->sainfo()->name = "any";
+ info_->sainfo()->any_addr = true;
} else {
info_->ref();
sequence_analysis_free_nodes(info_->sainfo());
@@ -99,16 +95,33 @@ SequenceDialog::SequenceDialog(QWidget &parent, CaptureFile &cf, SequenceInfo *i
//sp->axisRect()->setRangeDragAxes(sp->xAxis2, sp->yAxis);
//sp->setInteractions(QCP::iRangeDrag);
+ sp->setInteraction(QCP::iSelectAxes, true);
+ sp->xAxis->setSelectableParts(QCPAxis::spNone);
+ sp->xAxis2->setSelectableParts(QCPAxis::spNone);
+ sp->yAxis->setSelectableParts(QCPAxis::spNone);
+ sp->yAxis2->setSelectableParts(QCPAxis::spAxis);
+
sp->xAxis->setVisible(false);
sp->xAxis->setPadding(0);
sp->xAxis->setLabelPadding(0);
sp->xAxis->setTickLabelPadding(0);
+ // Light border for the diagram
QPen base_pen(ColorUtils::alphaBlend(palette().text(), palette().base(), 0.25));
base_pen.setWidthF(0.5);
sp->xAxis2->setBasePen(base_pen);
sp->yAxis->setBasePen(base_pen);
sp->yAxis2->setBasePen(base_pen);
+ // Keep the border the same if/when the axis is selected, instead of blue
+ sp->xAxis2->setSelectedBasePen(base_pen);
+ sp->yAxis->setSelectedBasePen(base_pen);
+ sp->yAxis2->setSelectedBasePen(base_pen);
+
+ /* QCP documentation for setTicks() says "setting show to false does not imply
+ * that tick labels are invisible, too." In practice it seems to make them
+ * invisible, though, so set the length to 0.
+ */
+ sp->yAxis2->setTickLength(0);
sp->xAxis2->setVisible(true);
sp->yAxis2->setVisible(true);
@@ -162,7 +175,18 @@ SequenceDialog::SequenceDialog(QWidget &parent, CaptureFile &cf, SequenceInfo *i
action->setEnabled(false);
set_action_shortcuts_visible_in_context_menu(ctx_menu_.actions());
- ui->addressComboBox->setCurrentIndex(0);
+ sp->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(sp, &QCustomPlot::customContextMenuRequested, this, &SequenceDialog::showContextMenu);
+
+ ui->addressComboBox->addItem(tr("Any"), QVariant(true));
+ ui->addressComboBox->addItem(tr("Network"), QVariant(false));
+ ui->addressComboBox->setCurrentIndex(ui->addressComboBox->findData(QVariant(true)));
+
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ connect(ui->addressComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &SequenceDialog::addressChanged);
+#else
+ connect(ui->addressComboBox, &QComboBox::currentIndexChanged, this, &SequenceDialog::addressChanged);
+#endif
sequence_items_t item_data;
@@ -189,21 +213,30 @@ SequenceDialog::SequenceDialog(QWidget &parent, CaptureFile &cf, SequenceInfo *i
close_bt->setDefault(true);
}
+ enableVoIPFeatures();
+
+ // Enable or disable VoIP features before adding the ProgressFrame,
+ // because the layout position depends on whether player_button_ is
+ // visible.
ProgressFrame::addToButtonBox(ui->buttonBox, &parent);
loadGeometry(parent.width(), parent.height() * 4 / 5);
+ if (cf.isValid() && cf.displayFilter().length() > 0) {
+ ui->displayFilterCheckBox->setChecked(true);
+ }
+
+ connect(ui->displayFilterCheckBox, &QCheckBox::toggled, this, &SequenceDialog::displayFilterCheckBoxToggled);
connect(ui->horizontalScrollBar, SIGNAL(valueChanged(int)), this, SLOT(hScrollBarChanged(int)));
connect(ui->verticalScrollBar, SIGNAL(valueChanged(int)), this, SLOT(vScrollBarChanged(int)));
connect(sp->xAxis2, SIGNAL(rangeChanged(QCPRange)), this, SLOT(xAxisChanged(QCPRange)));
connect(sp->yAxis, SIGNAL(rangeChanged(QCPRange)), this, SLOT(yAxisChanged(QCPRange)));
- connect(sp, SIGNAL(mousePress(QMouseEvent*)), this, SLOT(diagramClicked(QMouseEvent*)));
- connect(sp, SIGNAL(mouseMove(QMouseEvent*)), this, SLOT(mouseMoved(QMouseEvent*)));
- connect(sp, SIGNAL(mouseWheel(QWheelEvent*)), this, SLOT(mouseWheeled(QWheelEvent*)));
-
- // Button must be enabled by VoIP dialogs
- player_button_->setVisible(false);
- player_button_->setEnabled(false);
+ connect(sp, &QCustomPlot::mousePress, this, &SequenceDialog::diagramClicked);
+ connect(sp, &QCustomPlot::mouseRelease, this, &SequenceDialog::mouseReleased);
+ connect(sp, &QCustomPlot::mouseMove, this, &SequenceDialog::mouseMoved);
+ connect(sp, &QCustomPlot::mouseWheel, this, &SequenceDialog::mouseWheeled);
+ connect(sp, &QCustomPlot::axisDoubleClick, this, &SequenceDialog::axisDoubleClicked);
+ connect(sp, &QCustomPlot::afterLayout, this, &SequenceDialog::layoutAxisLabels);
}
SequenceDialog::~SequenceDialog()
@@ -214,10 +247,10 @@ SequenceDialog::~SequenceDialog()
void SequenceDialog::enableVoIPFeatures()
{
- voipFeaturesEnabled = true;
- player_button_->setVisible(true);
- ui->actionSelectRtpStreams->setVisible(true);
- ui->actionDeselectRtpStreams->setVisible(true);
+ player_button_->setVisible(voipFeaturesEnabled);
+ ui->actionSelectRtpStreams->setVisible(voipFeaturesEnabled);
+ ui->actionDeselectRtpStreams->setVisible(voipFeaturesEnabled);
+ // Buttons and actions are enabled when valid call selected
}
void SequenceDialog::updateWidgets()
@@ -225,6 +258,23 @@ void SequenceDialog::updateWidgets()
WiresharkDialog::updateWidgets();
}
+bool SequenceDialog::event(QEvent *event)
+{
+ if (event->type() == QEvent::ToolTip) {
+ QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
+ seq_analysis_item_t *sai = seq_diagram_->itemForPosY(helpEvent->pos().y());
+ if (sai && seq_diagram_->inComment(helpEvent->pos()) && (sai->comment != seq_diagram_->elidedComment(sai->comment))) {
+ QToolTip::showText(helpEvent->globalPos(), sai->comment);
+ } else {
+ QToolTip::hideText();
+ event->ignore();
+ }
+
+ return true;
+ }
+ return QWidget::event(event);
+}
+
void SequenceDialog::showEvent(QShowEvent *)
{
QTimer::singleShot(0, this, SLOT(fillDiagram()));
@@ -312,7 +362,7 @@ void SequenceDialog::hScrollBarChanged(int value)
{
if (qAbs(ui->sequencePlot->xAxis2->range().center()-value/100.0) > 0.01) {
ui->sequencePlot->xAxis2->setRange(value/100.0, ui->sequencePlot->xAxis2->range().size(), Qt::AlignCenter);
- ui->sequencePlot->replot();
+ ui->sequencePlot->replot(QCustomPlot::rpQueuedReplot);
}
}
@@ -320,7 +370,7 @@ void SequenceDialog::vScrollBarChanged(int value)
{
if (qAbs(ui->sequencePlot->yAxis->range().center()-value/100.0) > 0.01) {
ui->sequencePlot->yAxis->setRange(value/100.0, ui->sequencePlot->yAxis->range().size(), Qt::AlignCenter);
- ui->sequencePlot->replot();
+ ui->sequencePlot->replot(QCustomPlot::rpQueuedReplot);
}
}
@@ -336,10 +386,20 @@ void SequenceDialog::yAxisChanged(QCPRange range)
ui->verticalScrollBar->setPageStep(qRound(qreal(range.size()*100.0)));
}
+void SequenceDialog::showContextMenu(const QPoint &pos)
+{
+ ctx_menu_.popup(ui->sequencePlot->mapToGlobal(pos));
+}
+
void SequenceDialog::diagramClicked(QMouseEvent *event)
{
current_rtp_sai_selected_ = NULL;
if (event) {
+ QCPAxis *yAxis2 = ui->sequencePlot->yAxis2;
+ if (std::abs(event->pos().x() - yAxis2->axisRect()->right()) < 5) {
+ yAxis2->setSelectedParts(QCPAxis::spAxis);
+ axis_pressed_ = true;
+ }
seq_analysis_item_t *sai = seq_diagram_->itemForPosY(event->pos().y());
if (voipFeaturesEnabled) {
ui->actionSelectRtpStreams->setEnabled(false);
@@ -359,13 +419,6 @@ void SequenceDialog::diagramClicked(QMouseEvent *event)
case Qt::LeftButton:
on_actionGoToPacket_triggered();
break;
- case Qt::RightButton:
-#if QT_VERSION >= QT_VERSION_CHECK(6, 0 ,0)
- ctx_menu_.popup(event->globalPosition().toPoint());
-#else
- ctx_menu_.popup(event->globalPos());
-#endif
- break;
default:
break;
}
@@ -373,12 +426,47 @@ void SequenceDialog::diagramClicked(QMouseEvent *event)
}
+void SequenceDialog::axisDoubleClicked(QCPAxis *axis, QCPAxis::SelectablePart, QMouseEvent*)
+{
+ if (axis == ui->sequencePlot->yAxis2) {
+ QCP::MarginSides autoMargins = axis->axisRect()->autoMargins();
+ axis->axisRect()->setAutoMargins(autoMargins | QCP::msRight);
+ ui->sequencePlot->replot();
+ axis->axisRect()->setAutoMargins(autoMargins);
+ ui->sequencePlot->replot();
+ }
+}
+
+void SequenceDialog::mouseReleased(QMouseEvent*)
+{
+ QCustomPlot *sp = ui->sequencePlot;
+ sp->yAxis2->setSelectedParts(QCPAxis::spNone);
+ axis_pressed_ = false;
+ sp->replot(QCustomPlot::rpQueuedReplot);
+}
+
void SequenceDialog::mouseMoved(QMouseEvent *event)
{
current_rtp_sai_hovered_ = NULL;
packet_num_ = 0;
QString hint;
+ Qt::CursorShape shape = Qt::ArrowCursor;
if (event) {
+ QCPAxis *yAxis2 = ui->sequencePlot->yAxis2;
+ // For some reason we need this extra bool and can't rely just on
+ // yAxis2->selectedParts().testFlag(QCPAxis::spAxis)
+ if (axis_pressed_) {
+ int x = qMax(event->pos().x(), yAxis2->axisRect()->left());
+ QMargins margins = yAxis2->axisRect()->margins();
+ margins += QMargins(0, 0, yAxis2->axisRect()->right() - x, 0);
+ yAxis2->axisRect()->setMargins(margins);
+ shape = Qt::SplitHCursor;
+ ui->sequencePlot->replot(QCustomPlot::rpQueuedReplot);
+ } else {
+ if (std::abs(event->pos().x() - yAxis2->axisRect()->right()) < 5) {
+ shape = Qt::SplitHCursor;
+ }
+ }
seq_analysis_item_t *sai = seq_diagram_->itemForPosY(event->pos().y());
if (sai) {
if (GA_INFO_TYPE_RTP == sai->info_type) {
@@ -391,6 +479,10 @@ void SequenceDialog::mouseMoved(QMouseEvent *event)
}
}
+ if (ui->sequencePlot->cursor().shape() != shape) {
+ ui->sequencePlot->setCursor(QCursor(shape));
+ }
+
if (hint.isEmpty()) {
if (!info_->sainfo()) {
hint += tr("No data");
@@ -454,14 +546,55 @@ void SequenceDialog::exportDiagram()
if (file_name.length() > 0) {
bool save_ok = false;
+ // The QCustomPlot save functions take a width and a height, measured
+ // in pixels (for the entire viewport).
+ // In order to display the whole graph, we have to change the axes
+ // and scale up the width and height appropriately so that the text
+ // has the proper spacing. (Using the scale factor in some of the
+ // image writing functions makes the text illegible.)
+ // If we set the axes back to their old value without replotting,
+ // there's no visual effects from doing this.
+ QCustomPlot *sp = ui->sequencePlot;
+ QCPRange old_yrange = sp->yAxis->range();
+ QCPRange old_xrange = sp->xAxis2->range();
+ // For the horizontal aspect, we'll display all the nodes.
+ // Nodes can excluded by filtering (hiding nodes is in the todo list.)
+ // Use the current width of a node as determined by the user zooming
+ // with Key_Plus and Key_Minus, multiply that by the number of nodes,
+ // and add in the margin from the Time and Comment columns.
+ // MAX_NUM_NODES is 40, which results in a manageable 8802 pixel width
+ // at the default zoom level on my Linux box.
+ // (If the user has zoomed in unreasonably, that's on the user.)
+ int hmargin = sp->axisRect()->outerRect().width() - sp->axisRect()->width();
+ double nodeSize = (sp->axisRect()->width()) / old_xrange.size();
+ // For the vertical aspect, we need to put a bound on the number of
+ // pixels or items we'll put in an image, as it can get far too large.
+ // (JPEG only supports 16 bit aspect sizes, PNG supports 31 bit but
+ // many viewers don't.)
+ int vmargin = sp->axisRect()->outerRect().height() - sp->axisRect()->height();
+ // 1000 items is a little over 27000 pixels in height on my machine.
+ // XXX - Should this pref be pixels instead of items?
+ //int max_pixel = 24576;
+ //double range_span = ((max_pixel - vmargin) / (one_em_ * 1.5));
+ double range_span = prefs.flow_graph_max_export_items;
+ // Start at the current top item, and QCPRange::bounded does what
+ // we want, with margins of 1.0 on top and bottom.
+ QCPRange new_yrange(old_yrange.lower, old_yrange.lower + range_span);
+ new_yrange = new_yrange.bounded(min_top_, num_items_);
+ sp->yAxis->setRange(new_yrange);
+ // margins of 0.5 on left and right for port number, etc.
+ sp->xAxis2->setRange(min_left_, info_->sainfo()->num_nodes - 0.5);
+ // As seen in resetAxes(), we have an item take ~ 1.5*one_em_ pixels.
+ int ySize = new_yrange.size() * (one_em_ * 1.5) + vmargin;
+ int xSize = (nodeSize * info_->sainfo()->num_nodes) + hmargin;
if (extension.compare(pdf_filter) == 0) {
- save_ok = ui->sequencePlot->savePdf(file_name);
+ save_ok = ui->sequencePlot->savePdf(file_name, xSize, ySize);
} else if (extension.compare(png_filter) == 0) {
- save_ok = ui->sequencePlot->savePng(file_name);
+ save_ok = ui->sequencePlot->savePng(file_name, xSize, ySize);
} else if (extension.compare(bmp_filter) == 0) {
- save_ok = ui->sequencePlot->saveBmp(file_name);
+ save_ok = ui->sequencePlot->saveBmp(file_name, xSize, ySize);
} else if (extension.compare(jpeg_filter) == 0) {
- save_ok = ui->sequencePlot->saveJpg(file_name);
+ save_ok = ui->sequencePlot->saveJpg(file_name, xSize, ySize);
} else if (extension.compare(ascii_filter) == 0 && !file_closed_ && info_->sainfo()) {
FILE *outfile = ws_fopen(file_name.toUtf8().constData(), "w");
if (outfile != NULL) {
@@ -472,11 +605,13 @@ void SequenceDialog::exportDiagram()
save_ok = false;
}
}
+ sp->yAxis->setRange(old_yrange);
+ sp->xAxis2->setRange(old_xrange);
// else error dialog?
if (save_ok) {
mainApp->setLastOpenDirFromFilename(file_name);
} else {
- open_failure_alert_box(file_name.toUtf8().constData(), errno, TRUE);
+ open_failure_alert_box(file_name.toUtf8().constData(), errno, true);
}
}
}
@@ -535,12 +670,20 @@ void SequenceDialog::panAxes(int x_pixels, int y_pixels)
double v_pan = 0.0;
h_pan = sp->xAxis2->range().size() * x_pixels / sp->xAxis2->axisRect()->width();
+ // The nodes are placed on integer x values from 0 to num_nodes - 1.
+ // We allow 0.5 of margin around a node (also reflected in the
+ // horizontalScrollBar range.)
if (h_pan < 0) {
h_pan = qMax(h_pan, min_left_ - sp->xAxis2->range().lower);
} else {
- h_pan = qMin(h_pan, info_->sainfo()->num_nodes - sp->xAxis2->range().upper);
+ h_pan = qMin(h_pan, info_->sainfo()->num_nodes - 0.5 - sp->xAxis2->range().upper);
}
+ if (sp->yAxis->rangeReversed()) {
+ // For reversed axes, lower still references the mathematically
+ // smaller number than upper, so reverse the direction.
+ y_pixels = -y_pixels;
+ }
v_pan = sp->yAxis->range().size() * y_pixels / sp->yAxis->axisRect()->height();
if (v_pan < 0) {
v_pan = qMax(v_pan, min_top_ - sp->yAxis->range().lower);
@@ -548,13 +691,13 @@ void SequenceDialog::panAxes(int x_pixels, int y_pixels)
v_pan = qMin(v_pan, num_items_ - sp->yAxis->range().upper);
}
- if (h_pan && !(sp->xAxis2->range().contains(min_left_) && sp->xAxis2->range().contains(info_->sainfo()->num_nodes))) {
+ if (h_pan && !(sp->xAxis2->range().contains(min_left_) && sp->xAxis2->range().contains(info_->sainfo()->num_nodes - 0.5))) {
sp->xAxis2->moveRange(h_pan);
- sp->replot();
+ sp->replot(QCustomPlot::rpQueuedReplot);
}
if (v_pan && !(sp->yAxis->range().contains(min_top_) && sp->yAxis->range().contains(num_items_))) {
sp->yAxis->moveRange(v_pan);
- sp->replot();
+ sp->replot(QCustomPlot::rpQueuedReplot);
}
}
@@ -578,21 +721,29 @@ void SequenceDialog::resetAxes(bool keep_lower)
sp->yAxis->setRange(top_pos, range_span + top_pos);
double rmin = sp->xAxis2->range().size() / 2;
- ui->horizontalScrollBar->setRange((rmin - 0.5) * 100, (info_->sainfo()->num_nodes - 0.5 - rmin) * 100);
+ ui->horizontalScrollBar->setRange((rmin + min_left_) * 100, (info_->sainfo()->num_nodes - 0.5 - rmin) * 100);
xAxisChanged(sp->xAxis2->range());
ui->horizontalScrollBar->setValue(ui->horizontalScrollBar->minimum()); // Shouldn't be needed.
rmin = (sp->yAxis->range().size() / 2);
- ui->verticalScrollBar->setRange((rmin - 1.0) * 100, (num_items_ - 0.5 - rmin) * 100);
+ ui->verticalScrollBar->setRange((rmin + min_top_) * 100, (num_items_ - 0.5 - rmin) * 100);
yAxisChanged(sp->yAxis->range());
+ sp->replot(QCustomPlot::rpQueuedReplot);
+}
+
+void SequenceDialog::layoutAxisLabels()
+{
// It would be exceedingly handy if we could do one or both of the
// following:
// - Position an axis label above its axis inline with the tick labels.
// - Anchor a QCPItemText to one of the corners of a QCPAxis.
- // Neither of those appear to be possible, so we first call replot in
- // order to lay out our X axes, place our labels, the call replot again.
- sp->replot(QCustomPlot::rpQueuedReplot);
+ // Neither of those appear to be possible, so we place our labels using
+ // absolute positioning immediately after the layout size and positions
+ // are set, and right before the replot (or print) draw step occurs,
+ // using the new QCustomPlot 2.1.0 QCustomPlot::afterLayout signal.
+
+ QCustomPlot *sp = ui->sequencePlot;
QRect axis_rect = sp->axisRect()->rect();
@@ -606,8 +757,6 @@ void SequenceDialog::resetAxes(bool keep_lower)
+ sp->yAxis2->tickLabelPadding()
+ sp->yAxis2->offset(),
axis_rect.top() / 2);
-
- sp->replot(QCustomPlot::rpRefreshHint);
}
void SequenceDialog::resetView()
@@ -618,7 +767,7 @@ void SequenceDialog::resetView()
void SequenceDialog::on_actionGoToPacket_triggered()
{
if (!file_closed_ && packet_num_ > 0) {
- cf_goto_frame(cap_file_.capFile(), packet_num_);
+ cf_goto_frame(cap_file_.capFile(), packet_num_, false);
seq_diagram_->setSelectedPacket(packet_num_);
}
}
@@ -669,12 +818,12 @@ void SequenceDialog::goToAdjacentPacket(bool next)
}
sp->yAxis->moveRange(range_offset);
}
- cf_goto_frame(cap_file_.capFile(), adjacent_packet);
+ cf_goto_frame(cap_file_.capFile(), adjacent_packet, false);
seq_diagram_->setSelectedPacket(adjacent_packet);
}
}
-void SequenceDialog::on_displayFilterCheckBox_toggled(bool)
+void SequenceDialog::displayFilterCheckBoxToggled(bool)
{
fillDiagram();
}
@@ -690,16 +839,15 @@ void SequenceDialog::on_flowComboBox_activated(int index)
fillDiagram();
}
-void SequenceDialog::on_addressComboBox_activated(int index)
+void SequenceDialog::addressChanged(int)
{
if (!info_->sainfo()) return;
- if (index == 0) {
- info_->sainfo()->any_addr = TRUE;
- } else {
- info_->sainfo()->any_addr = FALSE;
+ QVariant data = ui->addressComboBox->currentData();
+ if (data.isValid()) {
+ info_->sainfo()->any_addr = data.toBool();
+ fillDiagram();
}
- fillDiagram();
}
void SequenceDialog::on_actionMoveRight10_triggered()
@@ -809,7 +957,7 @@ bool SequenceDialog::addFlowSequenceItem(const void* key, void *value, void *use
/* XXX - Although "voip" isn't a registered name yet, it appears to have special
handling that will be done outside of registered data */
if (strcmp(name, "voip") == 0)
- return FALSE;
+ return false;
item_data->flow->addItem(sequence_analysis_get_ui_name(analysis), VariantPointer<register_analysis_t>::asQVariant(analysis));
@@ -818,7 +966,7 @@ bool SequenceDialog::addFlowSequenceItem(const void* key, void *value, void *use
item_data->curr_index++;
- return FALSE;
+ return false;
}
QVector<rtpstream_id_t *>SequenceDialog::getSelectedRtpIds()
diff --git a/ui/qt/sequence_dialog.h b/ui/qt/sequence_dialog.h
index 8c321907..6bbc3d00 100644
--- a/ui/qt/sequence_dialog.h
+++ b/ui/qt/sequence_dialog.h
@@ -12,8 +12,6 @@
#include <config.h>
-#include <glib.h>
-
#include "cfile.h"
#include "epan/packet.h"
@@ -49,11 +47,11 @@ class SequenceDialog : public WiresharkDialog
Q_OBJECT
public:
- explicit SequenceDialog(QWidget &parent, CaptureFile &cf, SequenceInfo *info = NULL);
+ explicit SequenceDialog(QWidget &parent, CaptureFile &cf, SequenceInfo *info = NULL, bool voipFeatures = false);
~SequenceDialog();
- void enableVoIPFeatures();
protected:
+ bool event(QEvent *event);
void showEvent(QShowEvent *event);
void resizeEvent(QResizeEvent *event);
void keyPressEvent(QKeyEvent *event);
@@ -71,21 +69,26 @@ private slots:
void vScrollBarChanged(int value);
void xAxisChanged(QCPRange range);
void yAxisChanged(QCPRange range);
+ void showContextMenu(const QPoint &pos);
void diagramClicked(QMouseEvent *event);
+ void axisDoubleClicked(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event);
+ void mouseReleased(QMouseEvent *event);
void mouseMoved(QMouseEvent *event);
void mouseWheeled(QWheelEvent *event);
void fillDiagram();
void resetView();
void exportDiagram();
+ void layoutAxisLabels();
+
+ void addressChanged(int index);
+ void displayFilterCheckBoxToggled(bool checked);
void on_buttonBox_clicked(QAbstractButton *button);
void on_actionGoToPacket_triggered();
void on_actionGoToNextPacket_triggered() { goToAdjacentPacket(true); }
void on_actionGoToPreviousPacket_triggered() { goToAdjacentPacket(false); }
- void on_displayFilterCheckBox_toggled(bool checked);
void on_flowComboBox_activated(int index);
- void on_addressComboBox_activated(int index);
void on_actionMoveRight10_triggered();
void on_actionMoveLeft10_triggered();
void on_actionMoveUp10_triggered();
@@ -109,9 +112,10 @@ private:
SequenceDiagram *seq_diagram_;
SequenceInfo *info_;
int num_items_;
- guint32 packet_num_;
+ uint32_t packet_num_;
double one_em_;
int sequence_w_;
+ bool axis_pressed_;
QPushButton *reset_button_;
QToolButton *player_button_;
QPushButton *export_button_;
@@ -123,6 +127,7 @@ private:
QPointer<RtpStreamDialog> rtp_stream_dialog_; // Singleton pattern used
bool voipFeaturesEnabled;
+ void enableVoIPFeatures();
void zoomXAxis(bool in);
void panAxes(int x_pixels, int y_pixels);
void resetAxes(bool keep_lower = false);
diff --git a/ui/qt/sequence_dialog.ui b/ui/qt/sequence_dialog.ui
index a62e76e0..d116952e 100644
--- a/ui/qt/sequence_dialog.ui
+++ b/ui/qt/sequence_dialog.ui
@@ -156,16 +156,6 @@
</item>
<item>
<widget class="QComboBox" name="addressComboBox">
- <item>
- <property name="text">
- <string>Any</string>
- </property>
- </item>
- <item>
- <property name="text">
- <string>Network</string>
- </property>
- </item>
</widget>
</item>
</layout>
diff --git a/ui/qt/service_response_time_dialog.cpp b/ui/qt/service_response_time_dialog.cpp
index 95bd4801..31c86d58 100644
--- a/ui/qt/service_response_time_dialog.cpp
+++ b/ui/qt/service_response_time_dialog.cpp
@@ -66,7 +66,7 @@ bool register_service_response_tables(const void *, void *value, void*)
srt_init,
tpd_creator);
g_free(cfg_abbr);
- return FALSE;
+ return false;
}
enum {
@@ -205,7 +205,7 @@ ServiceResponseTimeDialog::~ServiceResponseTimeDialog()
{
if (srt_data_.srt_array) {
free_srt_table(srt_, srt_data_.srt_array);
- g_array_free(srt_data_.srt_array, TRUE);
+ g_array_free(srt_data_.srt_array, true);
}
}
@@ -259,7 +259,7 @@ void ServiceResponseTimeDialog::tapDraw(void *srtd_ptr)
void ServiceResponseTimeDialog::endRetapPackets()
{
- for (guint i = 0; i < srt_data_.srt_array->len; i++) {
+ for (unsigned i = 0; i < srt_data_.srt_array->len; i++) {
srt_stat_table *srt_table = g_array_index(srt_data_.srt_array, srt_stat_table*, i);
addSrtTable(srt_table);
}
@@ -270,9 +270,9 @@ void ServiceResponseTimeDialog::fillTree()
{
if (srt_data_.srt_array) {
free_srt_table(srt_, srt_data_.srt_array);
- g_array_free(srt_data_.srt_array, TRUE);
+ g_array_free(srt_data_.srt_array, true);
}
- srt_data_.srt_array = g_array_new(FALSE, TRUE, sizeof(srt_stat_table*));
+ srt_data_.srt_array = g_array_new(false, true, sizeof(srt_stat_table*));
srt_data_.user_data = this;
provideParameterData();
diff --git a/ui/qt/show_packet_bytes_dialog.cpp b/ui/qt/show_packet_bytes_dialog.cpp
index d85a1ea5..62a19649 100644
--- a/ui/qt/show_packet_bytes_dialog.cpp
+++ b/ui/qt/show_packet_bytes_dialog.cpp
@@ -182,10 +182,14 @@ void ShowPacketBytesDialog::updateHintLabel()
if (start_ > 0 || end_ < (finfo_->length - 1)) {
hint.append(" <span style=\"color: red\">" +
- tr("Displaying %Ln byte(s).", "", end_ - start_ + 1) +
+ tr("Using %Ln byte(s).", "", end_ - start_ + 1) +
"</span>");
}
+ if (!decode_as_name_.isEmpty()) {
+ hint.append(" " + tr("Decoded as %1.").arg(decode_as_name_));
+ }
+
ui->hintLabel->setText("<small><i>" + hint + "</i></small>");
}
@@ -194,7 +198,6 @@ void ShowPacketBytesDialog::on_sbStart_valueChanged(int value)
start_ = value;
ui->sbEnd->setMinimum(value);
- updateHintLabel();
updateFieldBytes();
}
@@ -203,7 +206,6 @@ void ShowPacketBytesDialog::on_sbEnd_valueChanged(int value)
end_ = value;
ui->sbStart->setMaximum(value);
- updateHintLabel();
updateFieldBytes();
}
@@ -242,20 +244,40 @@ void ShowPacketBytesDialog::useRegexFind(bool use_regex)
ui->lFind->setText(tr("Find:"));
}
+// This only calls itself with go_back false, so never recurses more than once.
+// NOLINTNEXTLINE(misc-no-recursion)
void ShowPacketBytesDialog::findText(bool go_back)
{
if (ui->leFind->text().isEmpty()) return;
bool found;
+
+ QTextDocument::FindFlags options;
+ if (ui->caseCheckBox->isChecked()) {
+ options |= QTextDocument::FindCaseSensitively;
+ }
if (use_regex_find_) {
#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
+ // https://bugreports.qt.io/browse/QTBUG-88721
+ // QPlainTextEdit::find() searches case-insensitively unless
+ // QTextDocument::FindCaseSensitively is explicitly given.
+ // This *does* apply to QRegularExpression (overriding
+ // CaseInsensitiveOption), but not QRegExp.
+ //
+ // QRegularExpression and QRegExp do not support Perl's /i, but
+ // the former at least does support the mode modifiers (?i) and
+ // (?-i), which can override QTextDocument::FindCaseSensitively.
+ //
+ // To make matters worse, while the QTextDocument::find() documentation
+ // is correct, QPlainTextEdit::find() claims that QRegularExpression
+ // works like QRegExp, which is incorrect.
QRegularExpression regex(ui->leFind->text(), QRegularExpression::UseUnicodePropertiesOption);
#else
- QRegExp regex(ui->leFind->text());
+ QRegExp regex(ui->leFind->text(), (options & QTextDocument::FindCaseSensitively) ? Qt::CaseSensitive : Qt::CaseInsensitive);
#endif
- found = ui->tePacketBytes->find(regex);
+ found = ui->tePacketBytes->find(regex, std::move(options));
} else {
- found = ui->tePacketBytes->find(ui->leFind->text());
+ found = ui->tePacketBytes->find(ui->leFind->text(), std::move(options));
}
if (found) {
@@ -514,7 +536,7 @@ void ShowPacketBytesDialog::symbolizeBuffer(QByteArray &ba)
ba.replace((char)0x7f, symbol); // DEL
}
-QByteArray ShowPacketBytesDialog::decodeQuotedPrintable(const guint8 *bytes, int length)
+QByteArray ShowPacketBytesDialog::decodeQuotedPrintable(const uint8_t *bytes, int length)
{
QByteArray ba;
@@ -542,7 +564,7 @@ QByteArray ShowPacketBytesDialog::decodeQuotedPrintable(const guint8 *bytes, int
void ShowPacketBytesDialog::rot13(QByteArray &ba)
{
for (int i = 0; i < ba.length(); i++) {
- gchar upper = g_ascii_toupper(ba[i]);
+ char upper = g_ascii_toupper(ba[i]);
if (upper >= 'A' && upper <= 'M') ba[i] = ba[i] + 13;
else if (upper >= 'N' && upper <= 'Z') ba[i] = ba[i] - 13;
}
@@ -552,12 +574,13 @@ void ShowPacketBytesDialog::updateFieldBytes(bool initialization)
{
int start = finfo_->start + start_;
int length = end_ - start_ + 1;
- const guint8 *bytes;
- gsize new_length = 0;
+ const uint8_t *bytes;
if (!finfo_->ds_tvb)
return;
+ decode_as_name_.clear();
+
switch (recent.gui_show_bytes_decode) {
case DecodeAsNone:
@@ -568,22 +591,40 @@ void ShowPacketBytesDialog::updateFieldBytes(bool initialization)
case DecodeAsBASE64:
{
bytes = tvb_get_ptr(finfo_->ds_tvb, start, -1);
- field_bytes_ = QByteArray((const char *)bytes, length);
- if (field_bytes_.size() > 1) {
- g_base64_decode_inplace(field_bytes_.data(), &new_length);
+ QByteArray ba = QByteArray::fromRawData((const char *)bytes, length);
+ if (ba.contains('-') || ba.contains('_')) {
+ field_bytes_ = QByteArray::fromBase64(ba, QByteArray::Base64UrlEncoding);
+ decode_as_name_ = "base64url";
+ } else {
+ field_bytes_ = QByteArray::fromBase64(ba, QByteArray::Base64Encoding);
+ decode_as_name_ = "base64";
}
- field_bytes_.resize((int)new_length);
break;
}
case DecodeAsCompressed:
{
- tvbuff *uncompr_tvb = tvb_uncompress(finfo_->ds_tvb, start, length);
- if (uncompr_tvb) {
- bytes = tvb_get_ptr(uncompr_tvb, 0, -1);
- field_bytes_ = QByteArray((const char *)bytes, tvb_reported_length(uncompr_tvb));
- tvb_free(uncompr_tvb);
- } else {
+ static const QList<uncompress_list_t> tvb_uncompress_list = {
+ { "lz77", tvb_uncompress_lz77 },
+ { "lz77huff", tvb_uncompress_lz77huff },
+ { "lznt1", tvb_uncompress_lznt1 },
+ { "snappy", tvb_uncompress_snappy },
+ { "zlib", tvb_uncompress_zlib },
+ { "zstd", tvb_uncompress_zstd },
+ };
+ tvbuff_t *uncompr_tvb = NULL;
+
+ for (auto &tvb_uncompress : tvb_uncompress_list) {
+ uncompr_tvb = tvb_uncompress.function(finfo_->ds_tvb, start, length);
+ if (uncompr_tvb && tvb_reported_length(uncompr_tvb) > 0) {
+ bytes = tvb_get_ptr(uncompr_tvb, 0, -1);
+ field_bytes_ = QByteArray((const char *)bytes, tvb_reported_length(uncompr_tvb));
+ decode_as_name_ = tr("compressed %1").arg(tvb_uncompress.name);
+ tvb_free(uncompr_tvb);
+ break;
+ }
+ }
+ if (!uncompr_tvb) {
field_bytes_.clear();
}
break;
@@ -600,7 +641,7 @@ void ShowPacketBytesDialog::updateFieldBytes(bool initialization)
#if GLIB_CHECK_VERSION(2, 66, 0)
GBytes *ba = g_uri_unescape_bytes((const char*)bytes, length, NULL, NULL);
if (ba != NULL) {
- gsize size;
+ size_t size;
const char* data = (const char *)g_bytes_unref_to_data(ba, &size);
field_bytes_ = QByteArray(data, (int)size);
}
@@ -609,7 +650,7 @@ void ShowPacketBytesDialog::updateFieldBytes(bool initialization)
if (uri_to_bytes((const char*)bytes, ba, length)) {
field_bytes_ = QByteArray((const char *)ba->data, ba->len);
}
- g_byte_array_free(ba, TRUE);
+ g_byte_array_free(ba, true);
#endif
break;
}
@@ -635,11 +676,12 @@ void ShowPacketBytesDialog::updateFieldBytes(bool initialization)
}
updatePacketBytes();
+ updateHintLabel();
}
void ShowPacketBytesDialog::updatePacketBytes(void)
{
- static const gchar hexchars[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
+ static const char hexchars[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
ui->tePacketBytes->clear();
ui->tePacketBytes->setCurrentFont(mainApp->monospaceFont());
@@ -670,7 +712,7 @@ void ShowPacketBytesDialog::updatePacketBytes(void)
QString text("char packet_bytes[] = {\n");
while (pos < len) {
- gchar hexbuf[256];
+ char hexbuf[256];
char *cur = hexbuf;
int i;
@@ -707,7 +749,7 @@ void ShowPacketBytesDialog::updatePacketBytes(void)
QString text("let packet_bytes: [u8; _] = [\n");
while (pos < len) {
- gchar hexbuf[256];
+ char hexbuf[256];
char *cur = hexbuf;
int i;
@@ -755,7 +797,7 @@ void ShowPacketBytesDialog::updatePacketBytes(void)
case SHOW_EBCDIC:
{
QByteArray ba(field_bytes_);
- EBCDIC_to_ASCII((guint8*)ba.data(), static_cast<int>(ba.length()));
+ EBCDIC_to_ASCII((uint8_t*)ba.data(), static_cast<int>(ba.length()));
sanitizeBuffer(ba, false);
ui->tePacketBytes->setLineWrapMode(QTextEdit::WidgetWidth);
ui->tePacketBytes->setPlainText(ba);
diff --git a/ui/qt/show_packet_bytes_dialog.h b/ui/qt/show_packet_bytes_dialog.h
index 80201c81..1f6183fa 100644
--- a/ui/qt/show_packet_bytes_dialog.h
+++ b/ui/qt/show_packet_bytes_dialog.h
@@ -11,7 +11,6 @@
#define SHOW_PACKET_BYTES_DIALOG_H
#include <config.h>
-#include <glib.h>
#include <stdio.h>
#ifdef HAVE_UNISTD_H
@@ -31,6 +30,11 @@ class ShowPacketBytesDialog;
class ShowPacketBytesTextEdit;
}
+struct uncompress_list_t {
+ QString name;
+ tvbuff_t *(*function)(tvbuff_t *, int, int);
+};
+
class ShowPacketBytesDialog : public WiresharkDialog
{
Q_OBJECT
@@ -71,7 +75,7 @@ private:
void updateHintLabel();
void sanitizeBuffer(QByteArray &ba, bool handle_CR);
void symbolizeBuffer(QByteArray &ba);
- QByteArray decodeQuotedPrintable(const guint8 *bytes, int length);
+ QByteArray decodeQuotedPrintable(const uint8_t *bytes, int length);
void rot13(QByteArray &ba);
void updateFieldBytes(bool initialization = false);
void updatePacketBytes();
@@ -81,6 +85,7 @@ private:
const field_info *finfo_;
QByteArray field_bytes_;
QString hint_label_;
+ QString decode_as_name_;
QPushButton *print_button_;
QPushButton *copy_button_;
QPushButton *save_as_button_;
diff --git a/ui/qt/show_packet_bytes_dialog.ui b/ui/qt/show_packet_bytes_dialog.ui
index f60e625d..dfe03757 100644
--- a/ui/qt/show_packet_bytes_dialog.ui
+++ b/ui/qt/show_packet_bytes_dialog.ui
@@ -117,6 +117,13 @@
<widget class="FindLineEdit" name="leFind"/>
</item>
<item>
+ <widget class="QCheckBox" name="caseCheckBox">
+ <property name="text">
+ <string>Case sensitive</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QPushButton" name="bFind">
<property name="text">
<string>Find &amp;Next</string>
diff --git a/ui/qt/simple_dialog.cpp b/ui/qt/simple_dialog.cpp
index b45c7a19..c5a57d4d 100644
--- a/ui/qt/simple_dialog.cpp
+++ b/ui/qt/simple_dialog.cpp
@@ -90,8 +90,8 @@ simple_dialog_format_message(const char *msg)
return g_strdup(msg);
}
-gpointer
-simple_dialog(ESD_TYPE_E type, gint btn_mask, const gchar *msg_format, ...)
+void *
+simple_dialog(ESD_TYPE_E type, int btn_mask, const char *msg_format, ...)
{
va_list ap;
@@ -103,8 +103,8 @@ simple_dialog(ESD_TYPE_E type, gint btn_mask, const gchar *msg_format, ...)
return NULL;
}
-gpointer
-simple_dialog_async(ESD_TYPE_E type, gint btn_mask, const gchar *msg_format, ...)
+void *
+simple_dialog_async(ESD_TYPE_E type, int btn_mask, const char *msg_format, ...)
{
va_list ap;
@@ -121,7 +121,7 @@ simple_dialog_async(ESD_TYPE_E type, gint btn_mask, const gchar *msg_format, ...
* and checkbox, and optional secondary text.
*/
void
-simple_message_box(ESD_TYPE_E type, gboolean *notagain,
+simple_message_box(ESD_TYPE_E type, bool *notagain,
const char *secondary_msg, const char *msg_format, ...)
{
if (notagain && *notagain) {
@@ -202,7 +202,7 @@ SimpleDialog::SimpleDialog(QWidget *parent, ESD_TYPE_E type, int btn_mask, const
check_box_(0),
message_box_(0)
{
- gchar *vmessage;
+ char *vmessage;
QString message;
vmessage = ws_strdup_vprintf(msg_format, ap);
diff --git a/ui/qt/simple_dialog.h b/ui/qt/simple_dialog.h
index 2afda98d..32163e09 100644
--- a/ui/qt/simple_dialog.h
+++ b/ui/qt/simple_dialog.h
@@ -14,8 +14,6 @@
#include <stdio.h>
-#include <glib.h>
-
#include "ui/simple_dialog.h"
#include <QPair>
diff --git a/ui/qt/simple_statistics_dialog.cpp b/ui/qt/simple_statistics_dialog.cpp
index ae715603..c03d6bef 100644
--- a/ui/qt/simple_statistics_dialog.cpp
+++ b/ui/qt/simple_statistics_dialog.cpp
@@ -47,7 +47,7 @@ bool register_simple_stat_tables(const void *key, void *value, void*) {
stu->group,
simple_stat_init,
SimpleStatisticsDialog::createSimpleStatisticsDialog);
- return FALSE;
+ return false;
}
enum {
@@ -188,7 +188,7 @@ void SimpleStatisticsDialog::addMissingRows(struct _stat_data_t *stat_data)
// the top-level tree item text set to the column labels for that table.
// Add any missing tables and rows.
- for (guint table_idx = 0; table_idx < stat_data->stat_tap_data->tables->len; table_idx++) {
+ for (unsigned table_idx = 0; table_idx < stat_data->stat_tap_data->tables->len; table_idx++) {
stat_tap_table* st_table = g_array_index(stat_data->stat_tap_data->tables, stat_tap_table*, table_idx);
QTreeWidgetItem *ti = NULL;
@@ -200,7 +200,7 @@ void SimpleStatisticsDialog::addMissingRows(struct _stat_data_t *stat_data)
} else {
ti = statsTreeWidget()->topLevelItem(table_idx);
}
- for (guint element = ti->childCount(); element < st_table->num_elements; element++) {
+ for (unsigned element = ti->childCount(); element < st_table->num_elements; element++) {
stat_tap_table_item_type* fields = stat_tap_get_field_data(st_table, element, 0);
if (stu_->nfields > 0) {
SimpleStatisticsTreeWidgetItem *ss_ti = new SimpleStatisticsTreeWidgetItem(ti, st_table->num_fields, fields);
diff --git a/ui/qt/stats_tree_dialog.cpp b/ui/qt/stats_tree_dialog.cpp
index 1ec66b7e..f51e252a 100644
--- a/ui/qt/stats_tree_dialog.cpp
+++ b/ui/qt/stats_tree_dialog.cpp
@@ -97,18 +97,15 @@ void StatsTreeDialog::setupNode(stat_node* node)
} else {
st_dlg->statsTreeWidget()->addTopLevelItem(ti);
}
- st_dlg->statsTreeWidget()->resizeColumnToContents(item_col_);
}
void StatsTreeDialog::fillTree()
{
if (!st_cfg_ || file_closed_) return;
- QString display_name = gchar_free_to_qstring(stats_tree_get_displayname(st_cfg_->name));
-
- // The GTK+ UI appends "Stats Tree" to the window title. If we do the same
+ // The GTK+ UI appended "Stats Tree" to the window title. If we do the same
// here we should expand the name completely, e.g. to "Statistics Tree".
- setWindowSubtitle(display_name);
+ setWindowSubtitle(st_cfg_->title);
st_cfg_->pr = &cfg_pr_;
cfg_pr_.st_dlg = this;
@@ -122,7 +119,7 @@ void StatsTreeDialog::fillTree()
// Add number of columns for this stats_tree
QStringList header_labels;
for (int count = 0; count<st_->num_columns; count++) {
- header_labels.push_back(stats_tree_get_column_name(count));
+ header_labels.push_back(stats_tree_get_column_name(st_cfg_, count));
}
statsTreeWidget()->setColumnCount(static_cast<int>(header_labels.count()));
statsTreeWidget()->setHeaderLabels(header_labels);
@@ -142,10 +139,11 @@ void StatsTreeDialog::fillTree()
cap_file_.retapPackets();
drawTreeItems(st_);
- statsTreeWidget()->setSortingEnabled(true);
removeTapListeners();
-
st_cfg_->pr = NULL;
+
+ statsTreeWidget()->setSortingEnabled(true);
+ statsTreeWidget()->resizeColumnToContents(item_col_);
}
void StatsTreeDialog::resetTap(void *st_ptr)
@@ -167,7 +165,7 @@ void StatsTreeDialog::drawTreeItems(void *st_ptr)
while (*iter) {
stat_node *node = VariantPointer<stat_node>::asPtr((*iter)->data(item_col_, Qt::UserRole));
if (node) {
- gchar **valstrs = stats_tree_get_values_from_node(node);
+ char **valstrs = stats_tree_get_values_from_node(node);
for (int count = 0; count<st->num_columns; count++) {
(*iter)->setText(count,valstrs[count]);
g_free(valstrs[count]);
diff --git a/ui/qt/stats_tree_dialog.h b/ui/qt/stats_tree_dialog.h
index de040811..a5f0a236 100644
--- a/ui/qt/stats_tree_dialog.h
+++ b/ui/qt/stats_tree_dialog.h
@@ -14,8 +14,6 @@
#include <config.h>
-#include <glib.h>
-
#include "epan/stats_tree_priv.h"
struct _tree_cfg_pres {
diff --git a/ui/qt/strip_headers_dialog.cpp b/ui/qt/strip_headers_dialog.cpp
index 73775ddf..35f6fa13 100644
--- a/ui/qt/strip_headers_dialog.cpp
+++ b/ui/qt/strip_headers_dialog.cpp
@@ -20,6 +20,8 @@
#include "ui/export_pdu_ui_utils.h"
#include "ui/capture_globals.h"
+#include "main_application.h"
+
StripHeadersDialog::StripHeadersDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::StripHeadersDialog)
@@ -28,12 +30,15 @@ StripHeadersDialog::StripHeadersDialog(QWidget *parent) :
ui->setupUi(this);
+ setWindowTitle(mainApp->windowTitleString(tr("Strip Headers")));
+
for (tap_name_list = get_export_pdu_tap_list(); tap_name_list; tap_name_list = g_slist_next(tap_name_list)) {
if (export_pdu_tap_get_encap((const char*)tap_name_list->data) != WTAP_ENCAP_WIRESHARK_UPPER_PDU) {
ui->comboBox->addItem((const char*)(tap_name_list->data));
}
}
}
+
void StripHeadersDialog::on_buttonBox_accepted()
{
const QByteArray& filter = ui->displayFilterLineEdit->text().toUtf8();
@@ -41,6 +46,12 @@ void StripHeadersDialog::on_buttonBox_accepted()
do_export_pdu(filter.constData(), global_capture_opts.temp_dir, tap_name.constData());
}
+
+void StripHeadersDialog::on_buttonBox_helpRequested()
+{
+ mainApp->helpTopicAction(HELP_STRIP_HEADERS_DIALOG);
+}
+
StripHeadersDialog::~StripHeadersDialog()
{
delete ui;
diff --git a/ui/qt/strip_headers_dialog.h b/ui/qt/strip_headers_dialog.h
index bce54784..d048293b 100644
--- a/ui/qt/strip_headers_dialog.h
+++ b/ui/qt/strip_headers_dialog.h
@@ -30,6 +30,7 @@ private:
private slots:
void on_buttonBox_accepted();
+ void on_buttonBox_helpRequested();
};
#endif // STRIP_HEADERS_DIALOG_H
diff --git a/ui/qt/strip_headers_dialog.ui b/ui/qt/strip_headers_dialog.ui
index cc40162a..3ea44b4c 100644
--- a/ui/qt/strip_headers_dialog.ui
+++ b/ui/qt/strip_headers_dialog.ui
@@ -26,7 +26,7 @@
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok|QDialogButtonBox::Help</set>
</property>
</widget>
<widget class="QWidget" name="layoutWidget">
@@ -75,32 +75,12 @@
<signal>accepted()</signal>
<receiver>StripHeadersDialog</receiver>
<slot>accept()</slot>
- <hints>
- <hint type="sourcelabel">
- <x>248</x>
- <y>254</y>
- </hint>
- <hint type="destinationlabel">
- <x>157</x>
- <y>274</y>
- </hint>
- </hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>StripHeadersDialog</receiver>
<slot>reject()</slot>
- <hints>
- <hint type="sourcelabel">
- <x>316</x>
- <y>260</y>
- </hint>
- <hint type="destinationlabel">
- <x>286</x>
- <y>274</y>
- </hint>
- </hints>
</connection>
</connections>
</ui>
diff --git a/ui/qt/supported_protocols_dialog.cpp b/ui/qt/supported_protocols_dialog.cpp
index eea2d738..10457f23 100644
--- a/ui/qt/supported_protocols_dialog.cpp
+++ b/ui/qt/supported_protocols_dialog.cpp
@@ -93,6 +93,6 @@ void SupportedProtocolsDialog::on_searchLineEdit_textChanged(const QString &sear
* the countdown.
*/
searchLineEditText = search_re;
- guint gui_debounce_timer = prefs_get_uint_value("gui", "debounce.timer");
+ unsigned gui_debounce_timer = prefs_get_uint_value("gui", "debounce.timer");
searchLineEditTimer->start(gui_debounce_timer);
}
diff --git a/ui/qt/tap_parameter_dialog.cpp b/ui/qt/tap_parameter_dialog.cpp
index 4652b672..eeb838dd 100644
--- a/ui/qt/tap_parameter_dialog.cpp
+++ b/ui/qt/tap_parameter_dialog.cpp
@@ -43,10 +43,11 @@
#include <ui/qt/utils/qt_ui_utils.h>
#include "main_application.h"
+#include <ui/qt/widgets/wireshark_file_dialog.h>
+
#include <QClipboard>
#include <QContextMenuEvent>
#include <QMessageBox>
-#include <QFileDialog>
// The GTK+ counterpart uses tap_param_dlg, which we don't use. If we
// need tap parameters we should probably create a TapParameterDialog
@@ -97,6 +98,7 @@ TapParameterDialog::TapParameterDialog(QWidget &parent, CaptureFile &cf, int hel
QString filter = ui->displayFilterLineEdit->text();
emit updateFilter(filter);
}
+ updateWidgets();
show_timer_ = new QTimer(this);
setRetapOnShow(true);
}
@@ -496,7 +498,7 @@ void TapParameterDialog::updateWidgets()
bool edit_enable = true;
bool apply_enable = true;
- if (file_closed_) {
+ if (file_closed_ || !cap_file_.isValid()) {
edit_enable = false;
apply_enable = false;
} else if (!ui->displayFilterLineEdit->checkFilter()) {
@@ -511,9 +513,9 @@ void TapParameterDialog::updateWidgets()
void TapParameterDialog::on_applyFilterButton_clicked()
{
- beginRetapPackets();
- if (!ui->displayFilterLineEdit->checkFilter())
+ if (!ui->displayFilterLineEdit->checkFilter()) {
return;
+ }
QString filter = ui->displayFilterLineEdit->text();
emit updateFilter(filter);
@@ -528,7 +530,6 @@ void TapParameterDialog::on_applyFilterButton_clicked()
fillTree();
ui->applyFilterButton->setEnabled(af_enabled);
ui->displayFilterLineEdit->setEnabled(df_enabled);
- endRetapPackets();
}
void TapParameterDialog::on_actionCopyToClipboard_triggered()
@@ -548,7 +549,7 @@ void TapParameterDialog::on_actionSaveAs_triggered()
#ifdef Q_OS_WIN
HANDLE da_ctx = set_thread_per_monitor_v2_awareness();
#endif
- QFileDialog SaveAsDialog(this, mainApp->windowTitleString(tr("Save Statistics As…")),
+ WiresharkFileDialog SaveAsDialog(this, mainApp->windowTitleString(tr("Save Statistics As…")),
get_open_dialog_initial_dir());
SaveAsDialog.setNameFilter(tr("Plain text file (*.txt);;"
"Comma separated values (*.csv);;"
@@ -582,7 +583,7 @@ void TapParameterDialog::on_actionSaveAs_triggered()
}
// Get selected filename and add extension of necessary
- QString file_name = SaveAsDialog.selectedFiles()[0];
+ QString file_name = SaveAsDialog.selectedNativePath();
if (!file_name.endsWith(file_ext, Qt::CaseInsensitive)) {
file_name.append(file_ext);
}
diff --git a/ui/qt/tap_parameter_dialog.h b/ui/qt/tap_parameter_dialog.h
index 1ed9db78..84a6f69e 100644
--- a/ui/qt/tap_parameter_dialog.h
+++ b/ui/qt/tap_parameter_dialog.h
@@ -18,8 +18,6 @@
#include "config.h"
-#include <glib.h>
-
#include <epan/stat_groups.h>
#include <epan/stat_tap_ui.h>
diff --git a/ui/qt/tcp_stream_dialog.cpp b/ui/qt/tcp_stream_dialog.cpp
index 88f6b757..881ee455 100644
--- a/ui/qt/tcp_stream_dialog.cpp
+++ b/ui/qt/tcp_stream_dialog.cpp
@@ -45,6 +45,8 @@
// - ACK & RWIN segment ticks in tcptrace graph
// - Add missing elements (retrans, URG, SACK, etc) to tcptrace. It probably makes
// sense to subclass QCPGraph for this.
+// - Allow switching the tracer between graphs when there are two / selecting
+// the other graph, at the very least if base_graph_ is disabled.
// The GTK+ version computes a 20 (or 21!) segment moving average. Comment
// out the line below to use that. By default we use a 1 second MA.
@@ -73,6 +75,7 @@ const QString segment_length_label_ = QObject::tr("Segment Length (B)");
const QString sequence_number_label_ = QObject::tr("Sequence Number (B)");
const QString time_s_label_ = QObject::tr("Time (s)");
const QString window_size_label_ = QObject::tr("Window Size (B)");
+const QString cwnd_label_ = QObject::tr("Unacked (Outstanding) Bytes (B)");
QCPErrorBarsNotSelectable::QCPErrorBarsNotSelectable(QCPAxis *keyAxis, QCPAxis *valueAxis) :
QCPErrorBars(keyAxis, valueAxis)
@@ -133,8 +136,8 @@ TCPStreamDialog::TCPStreamDialog(QWidget *parent, capture_file *cf, tcp_graph_ty
ui->streamNumberSpinBox->setStyleSheet("QSpinBox { min-width: 2em; }");
- guint32 th_stream = select_tcpip_session(cap_file_);
- if (th_stream == G_MAXUINT32) {
+ uint32_t th_stream = select_tcpip_session(cap_file_);
+ if (th_stream == UINT32_MAX) {
done(QDialog::Rejected);
return;
}
@@ -181,6 +184,7 @@ TCPStreamDialog::TCPStreamDialog(QWidget *parent, capture_file *cf, tcp_graph_ty
ctx_menu_.addAction(ui->actionToggleSequenceNumbers);
ctx_menu_.addAction(ui->actionToggleTimeOrigin);
ctx_menu_.addAction(ui->actionCrosshairs);
+ connect(ui->actionCrosshairs, &QAction::triggered, this, &TCPStreamDialog::toggleTracerStyle);
ctx_menu_.addSeparator();
ctx_menu_.addAction(ui->actionRoundTripTime);
ctx_menu_.addAction(ui->actionThroughput);
@@ -189,6 +193,11 @@ TCPStreamDialog::TCPStreamDialog(QWidget *parent, capture_file *cf, tcp_graph_ty
ctx_menu_.addAction(ui->actionWindowScaling);
set_action_shortcuts_visible_in_context_menu(ctx_menu_.actions());
+ QCustomPlot *sp = ui->streamPlot;
+
+ sp->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(sp, &QCustomPlot::customContextMenuRequested, this, &TCPStreamDialog::showContextMenu);
+
graph_.type = graph_type;
graph_.stream = th_stream;
findStream();
@@ -226,7 +235,6 @@ TCPStreamDialog::TCPStreamDialog(QWidget *parent, capture_file *cf, tcp_graph_ty
ui->showBytesOutCheckBox->setChecked(true);
ui->showBytesOutCheckBox->blockSignals(false);
- QCustomPlot *sp = ui->streamPlot;
QCPTextElement *file_title = new QCPTextElement(sp, gchar_free_to_qstring(cf_get_display_name(cap_file_)));
file_title->setFont(sp->xAxis->labelFont());
title_ = new QCPTextElement(sp);
@@ -551,6 +559,9 @@ void TCPStreamDialog::fillGraph(bool reset_axes, bool set_focus)
sp->yAxis2->setVisible(false);
sp->yAxis2->setLabel(QString());
+ /* For graphs other than receive window, the axes are not in sync. */
+ disconnect(sp->yAxis, QOverload<const QCPRange&>::of(&QCPAxis::rangeChanged), sp->yAxis2, QOverload<const QCPRange&>::of(&QCPAxis::setRange));
+
if (!cap_file_) {
QString dlg_title = QString(tr("No Capture Data"));
setWindowTitle(dlg_title);
@@ -563,9 +574,13 @@ void TCPStreamDialog::fillGraph(bool reset_axes, bool set_focus)
ts_offset_ = 0;
seq_offset_ = 0;
- bool first = true;
- guint64 bytes_fwd = 0;
- guint64 bytes_rev = 0;
+ bool ts_unset = ts_origin_conn_;
+ // seq_origin_zero_ defaults to true. It really means something like
+ // "use relative or absolute depending on the TCP dissector preferences".
+ // If it's false, then calculate the offset to convert to the other.
+ bool seq_unset = !seq_origin_zero_;
+ uint64_t bytes_fwd = 0;
+ uint64_t bytes_rev = 0;
int pkts_fwd = 0;
int pkts_rev = 0;
@@ -585,15 +600,37 @@ void TCPStreamDialog::fillGraph(bool reset_axes, bool set_focus)
pkts_fwd++;
}
double ts = seg->rel_secs + seg->rel_usecs / 1000000.0;
- if (first) {
- if (ts_origin_conn_) ts_offset_ = ts;
- if (seq_origin_zero_) {
- if (compareHeaders(seg))
- seq_offset_ = seg->th_seq;
- else
- seq_offset_ = seg->th_ack;
+ if (ts_unset) {
+ ts_offset_ = ts;
+ ts_unset = false;
+ }
+ if (seq_unset) {
+ if (compareHeaders(seg)) {
+ if (seg->th_seq != seg->th_rawseq) {
+ seq_offset_ = seg->th_seq - seg->th_rawseq;
+ } else {
+ // As with the TCP dissector, if this isn't the SYN or SYN-ACK,
+ // start the relative sequence numbers at 1.
+ if (seg->th_flags & TH_SYN) {
+ seq_offset_ = seg->th_seq;
+ } else {
+ seq_offset_ = seg->th_seq - 1;
+ }
+ }
+ seq_unset = false;
+ } else {
+ // A SYN in the reverse direction does not tell us the base
+ // sequence number, but for other segments (including SYN-ACK)
+ // start the offset at 1, like the TCP dissector.
+ if ((seg->th_flags & TH_SYN) != TH_SYN) {
+ if (seg->th_seq != seg->th_rawseq) {
+ seq_offset_ = seg->th_seq - seg->th_rawseq;
+ } else {
+ seq_offset_ -= seg->th_ack - 1;
+ }
+ seq_unset = false;
+ }
}
- first = false;
}
if (insert) {
time_stamp_map_.insert(ts - ts_offset_, seg);
@@ -759,7 +796,8 @@ void TCPStreamDialog::resetAxes()
// }
double axis_pixels = sp->xAxis->axisRect()->width();
- sp->xAxis->scaleRange((axis_pixels + (pixel_pad * 2)) / axis_pixels, sp->xAxis->range().center());
+ sp->xAxis->scaleRange((axis_pixels + (pixel_pad * 2)) / axis_pixels,
+ sp->xAxis->range().center());
if (sp->yAxis2->visible()) {
double ratio = sp->yAxis2->range().size() / sp->yAxis->range().size();
@@ -768,7 +806,8 @@ void TCPStreamDialog::resetAxes()
}
axis_pixels = sp->yAxis->axisRect()->height();
- sp->yAxis->scaleRange((axis_pixels + (pixel_pad * 2)) / axis_pixels, sp->yAxis->range().center());
+ sp->yAxis->scaleRange((axis_pixels + (pixel_pad * 2)) / axis_pixels,
+ sp->yAxis->range().center());
sp->replot();
}
@@ -902,6 +941,7 @@ void TCPStreamDialog::fillTcptrace()
sack_eb_->setData(sack_span);
sack2_graph_->setData(sack2_time, sack2_center, true);
sack2_eb_->setData(sack2_span);
+ rwin_graph_->setValueAxis(sp->yAxis);
rwin_graph_->setData(ackrwin_time, rwin, true);
dup_ack_graph_->setData(dup_ack_time, dup_ack, true);
zero_win_graph_->setData(zero_win_time, zero_win, true);
@@ -918,7 +958,7 @@ void TCPStreamDialog::fillTcptrace()
// I expect this to be _relatively_ small, so using vector to store
// them. If this performs badly, it can be refactored with std::list
// or std::map.
-typedef std::pair<guint32, guint32> sack_t;
+typedef std::pair<uint32_t, uint32_t> sack_t;
typedef std::vector<sack_t> sack_list_t;
static inline bool compare_sack(const sack_t& s1, const sack_t& s2) {
return tcp_seq_before(s1.first, s2.first);
@@ -928,8 +968,8 @@ static inline bool compare_sack(const sack_t& s1, const sack_t& s2) {
// - removes previously sacked ranges from seglen (and from old_sacks),
// - adds newly sacked ranges to seglen (and to old_sacks)
static void
-goodput_adjust_for_sacks(guint32 *seglen, guint32 last_ack,
- sack_list_t& new_sacks, guint8 num_sack_ranges,
+goodput_adjust_for_sacks(uint32_t *seglen, uint32_t last_ack,
+ sack_list_t& new_sacks, uint8_t num_sack_ranges,
sack_list_t& old_sacks) {
// Step 1 - For any old_sacks acked by last_ack,
@@ -1198,8 +1238,8 @@ void TCPStreamDialog::fillThroughput()
QVector<double> tput_times, gput_times;
QVector<double> tputs, gputs;
int oldest_seg = 0, oldest_ack = 0;
- guint64 seg_sum = 0, ack_sum = 0;
- guint32 seglen = 0;
+ uint64_t seg_sum = 0, ack_sum = 0;
+ uint32_t seglen = 0;
#ifdef USE_SACKS_IN_GOODPUT_CALC
// to incorporate SACKED segments into goodput calculation,
@@ -1217,7 +1257,7 @@ void TCPStreamDialog::fillThroughput()
// need first acked sequence number to jump-start
// computation of acked bytes per packet
- guint32 last_ack = 0;
+ uint32_t last_ack = 0;
for (struct segment *seg = graph_.segments; seg != NULL; seg = seg->next) {
// first reverse packet with ACK flag tells us first acked sequence #
if (!compareHeaders(seg) && (seg->th_flags & TH_ACK)) {
@@ -1246,7 +1286,7 @@ void TCPStreamDialog::fillThroughput()
QVector<double>& r_Xput_times = is_forward_seg ? tput_times : gput_times;
QVector<double>& r_Xputs = is_forward_seg ? tputs : gputs;
int& r_oldest = is_forward_seg ? oldest_seg : oldest_ack;
- guint64& r_sum = is_forward_seg ? seg_sum : ack_sum;
+ uint64_t& r_sum = is_forward_seg ? seg_sum : ack_sum;
double ts = (seg->rel_secs + seg->rel_usecs / 1000000.0) - ts_offset_;
@@ -1456,9 +1496,15 @@ void TCPStreamDialog::fillRoundTripTime()
base_graph_->setLineStyle(QCPGraph::lsLine);
QVector<double> x_vals, rtt;
- guint32 seq_base = 0;
+ uint32_t seq_base = 0;
struct rtt_unack *unack_list = NULL, *u = NULL;
for (struct segment *seg = graph_.segments; seg != NULL; seg = seg->next) {
+ // XXX - Should this just use seq_offset_? Our comparisons are
+ // wraparound now and should be fine without computing a base
+ // (we're not doing anything to extend sequence numbers to handle
+ // connections longer than 4 GiB), and that would let the user swap.
+ // (We should make clicking the X axis swap seq_origin_zero_ if
+ // bySeqNumber is checked.)
if (compareHeaders(seg)) {
seq_base = seg->th_seq;
break;
@@ -1466,7 +1512,7 @@ void TCPStreamDialog::fillRoundTripTime()
}
for (struct segment *seg = graph_.segments; seg != NULL; seg = seg->next) {
if (compareHeaders(seg)) {
- guint32 seqno = seg->th_seq - seq_base;
+ uint32_t seqno = seg->th_seq - seq_base;
if (seg->th_seglen && !rtt_is_retrans(unack_list, seqno)) {
double rt_val = seg->rel_secs + seg->rel_usecs / 1000000.0;
rt_val -= ts_offset_;
@@ -1479,7 +1525,7 @@ void TCPStreamDialog::fillRoundTripTime()
rtt_put_unack_on_list(&unack_list, u);
}
} else {
- guint32 ack_no = seg->th_ack - seq_base;
+ uint32_t ack_no = seg->th_ack - seq_base;
double rt_val = seg->rel_secs + seg->rel_usecs / 1000000.0;
rt_val -= ts_offset_;
struct rtt_unack *v;
@@ -1512,8 +1558,8 @@ void TCPStreamDialog::fillRoundTripTime()
// If we link those back into the list between u and v,
// then each subsequent SACK selectively ACKs that range.
for (int i = 0; i < seg->num_sack_ranges; ++i) {
- guint32 left = seg->sack_left_edge[i] - seq_base;
- guint32 right = seg->sack_right_edge[i] - seq_base;
+ uint32_t left = seg->sack_left_edge[i] - seq_base;
+ uint32_t right = seg->sack_right_edge[i] - seq_base;
u = rtt_selectively_ack_range(x_vals, bySeqNumber, rtt,
&unack_list, u, v,
left, right, rt_val);
@@ -1546,7 +1592,11 @@ void TCPStreamDialog::fillWindowScale()
QVector<double> rel_time, win_size;
QVector<double> cwnd_time, cwnd_size;
- guint32 last_ack = 0;
+ uint32_t last_ack = 0;
+
+ /* highest expected SEQ seen so far */
+ uint32_t max_next_seq = 0;
+
bool found_first_ack = false;
for (struct segment *seg = graph_.segments; seg != NULL; seg = seg->next) {
double ts = seg->rel_secs + seg->rel_usecs / 1000000.0;
@@ -1554,16 +1604,21 @@ void TCPStreamDialog::fillWindowScale()
// The receive window that applies to this flow comes
// from packets in the opposite direction
if (compareHeaders(seg)) {
- // compute bytes_in_flight for cwnd graph
- guint32 end_seq = seg->th_seq + seg->th_seglen;
+ /* compute bytes_in_flight for cwnd graph,
+ * by comparing the highest next SEQ to the latest ACK
+ */
+ uint32_t end_seq = seg->th_seq + seg->th_seglen;
+ if(end_seq > max_next_seq) {
+ max_next_seq = end_seq;
+ }
if (found_first_ack &&
tcp_seq_eq_or_after(end_seq, last_ack)) {
cwnd_time.append(ts - ts_offset_);
- cwnd_size.append((double)(end_seq - last_ack));
+ cwnd_size.append((double)(max_next_seq - last_ack));
}
} else {
// packet in opposite direction - has advertised rwin
- guint16 flags = seg->th_flags;
+ uint16_t flags = seg->th_flags;
if ((flags & (TH_SYN|TH_RST)) == 0) {
rel_time.append(ts - ts_offset_);
@@ -1579,9 +1634,27 @@ void TCPStreamDialog::fillWindowScale()
}
}
}
+ /* base_graph_ is the one that the tracer is on and allows selecting
+ * segments. XXX - Is the congestion window more interesting to see
+ * the exact value and select?
+ *
+ * We'll put the graphs on the same axis so they'll use the same scale.
+ */
base_graph_->setData(cwnd_time, cwnd_size);
+ rwin_graph_->setValueAxis(sp->yAxis);
rwin_graph_->setData(rel_time, win_size);
- sp->yAxis->setLabel(window_size_label_);
+
+ /* The left axis has the color and label for the unacked bytes,
+ * and the right axis will have the color and label for the window size.
+ */
+ sp->yAxis->setLabel(cwnd_label_);
+ sp->yAxis2->setLabel(window_size_label_);
+ sp->yAxis2->setLabelColor(QColor(graph_color_3));
+ sp->yAxis2->setTickLabelColor(QColor(graph_color_3));
+ sp->yAxis2->setVisible(true);
+
+ /* Keep the ticks on the two axes in sync. */
+ connect(sp->yAxis, QOverload<const QCPRange&>::of(&QCPAxis::rangeChanged), sp->yAxis2, QOverload<const QCPRange&>::of(&QCPAxis::setRange));
}
QString TCPStreamDialog::streamDescription()
@@ -1654,6 +1727,11 @@ QRectF TCPStreamDialog::getZoomRanges(QRect zoom_rect)
return zoom_ranges;
}
+void TCPStreamDialog::showContextMenu(const QPoint& pos)
+{
+ ctx_menu_.popup(ui->streamPlot->mapToGlobal(pos));
+}
+
void TCPStreamDialog::graphClicked(QMouseEvent *event)
{
QCustomPlot *sp = ui->streamPlot;
@@ -1661,15 +1739,7 @@ void TCPStreamDialog::graphClicked(QMouseEvent *event)
// mouse press on graph should reset focus to graph
sp->setFocus();
- if (event->button() == Qt::RightButton) {
- // XXX We should find some way to get streamPlot to handle a
- // contextMenuEvent instead.
-#if QT_VERSION >= QT_VERSION_CHECK(6, 0 ,0)
- ctx_menu_.popup(event->globalPosition().toPoint());
-#else
- ctx_menu_.popup(event->globalPos());
-#endif
- } else if (mouse_drags_) {
+ if (mouse_drags_) {
if (sp->axisRect()->rect().contains(event->pos())) {
sp->setCursor(QCursor(Qt::ClosedHandCursor));
}
@@ -1777,12 +1847,16 @@ void TCPStreamDialog::mouseMoved(QMouseEvent *event)
tracer_->setVisible(true);
packet_num_ = packet_seg->num;
+ // XXX - We should probably change the sequence number displayed by
+ // seq_offset_ but in that case we should also store a base sequence
+ // number for the other direction so the th_ack can also be adjusted
+ // to a relative sequence number.
hint += tr("%1 %2 (%3s len %4 seq %5 ack %6 win %7)")
.arg(cap_file_ ? tr("Click to select packet") : tr("Packet"))
.arg(packet_num_)
.arg(QString::number(packet_seg->rel_secs + packet_seg->rel_usecs / 1000000.0, 'g', 4))
.arg(packet_seg->th_seglen)
- .arg(packet_seg->th_seq)
+ .arg(packet_seg->th_seq) // - seq_offset_)
.arg(packet_seg->th_ack)
.arg(packet_seg->th_win);
tracer_->setGraphKey(ui->streamPlot->xAxis->pixelToCoord(event->pos().x()));
@@ -2105,7 +2179,7 @@ void TCPStreamDialog::on_actionPreviousStream_triggered()
void TCPStreamDialog::on_actionSwitchDirection_triggered()
{
address tmp_addr;
- guint16 tmp_port;
+ uint16_t tmp_port;
copy_address(&tmp_addr, &graph_.src_address);
tmp_port = graph_.src_port;
diff --git a/ui/qt/tcp_stream_dialog.h b/ui/qt/tcp_stream_dialog.h
index c5b97de0..4281538b 100644
--- a/ui/qt/tcp_stream_dialog.h
+++ b/ui/qt/tcp_stream_dialog.h
@@ -12,8 +12,6 @@
#include <config.h>
-#include <glib.h>
-
#include <file.h>
#include <epan/dissectors/packet-tcp.h>
@@ -71,7 +69,7 @@ private:
double ts_offset_;
bool ts_origin_conn_;
QMap<double, struct segment *> sequence_num_map_;
- double seq_offset_;
+ uint32_t seq_offset_;
bool seq_origin_zero_;
struct tcp_graph graph_;
QCPTextElement *title_;
@@ -91,7 +89,7 @@ private:
QCPGraph *zero_win_graph_;
QCPItemTracer *tracer_;
QRectF axis_bounds_;
- guint32 packet_num_;
+ uint32_t packet_num_;
QTransform y_axis_xfrm_;
bool mouse_drags_;
QRubberBand *rubber_band_;
@@ -141,6 +139,7 @@ private:
QRectF getZoomRanges(QRect zoom_rect);
private slots:
+ void showContextMenu(const QPoint &pos);
void graphClicked(QMouseEvent *event);
void axisClicked(QCPAxis *axis, QCPAxis::SelectablePart part, QMouseEvent *event);
void mouseMoved(QMouseEvent *event);
diff --git a/ui/qt/time_shift_dialog.cpp b/ui/qt/time_shift_dialog.cpp
index f1b325f0..5dab7618 100644
--- a/ui/qt/time_shift_dialog.cpp
+++ b/ui/qt/time_shift_dialog.cpp
@@ -116,7 +116,7 @@ void TimeShiftDialog::enableWidgets()
void TimeShiftDialog::checkFrameNumber(SyntaxLineEdit &frame_le)
{
bool frame_valid;
- guint frame_num = frame_le.text().toUInt(&frame_valid);
+ unsigned frame_num = frame_le.text().toUInt(&frame_valid);
syntax_err_.clear();
if (frame_le.text().isEmpty()) {
@@ -137,7 +137,7 @@ void TimeShiftDialog::checkDateTime(SyntaxLineEdit &time_le)
{
int Y, M, D, h, m;
long double s;
- const gchar *err_str;
+ const char *err_str;
syntax_err_.clear();
if (time_le.text().isEmpty()) {
@@ -175,8 +175,8 @@ void TimeShiftDialog::on_shiftAllTimeLineEdit_textChanged(const QString &sa_text
{
int h, m;
long double s;
- gboolean neg;
- const gchar *err_str;
+ bool neg;
+ const char *err_str;
syntax_err_.clear();
if (sa_text.isEmpty()) {
@@ -223,7 +223,7 @@ void TimeShiftDialog::on_setTwoTimeLineEdit_textChanged(const QString &)
void TimeShiftDialog::applyTimeShift()
{
- const gchar *err_str = NULL;
+ const char *err_str = NULL;
if (!cap_file_ || cap_file_->state == FILE_CLOSED || cap_file_->state == FILE_READ_PENDING) return;
diff --git a/ui/qt/time_shift_dialog.h b/ui/qt/time_shift_dialog.h
index 65164946..4e218ba4 100644
--- a/ui/qt/time_shift_dialog.h
+++ b/ui/qt/time_shift_dialog.h
@@ -12,8 +12,6 @@
#include <config.h>
-#include <glib.h>
-
#include "cfile.h"
#include <ui/qt/widgets/syntax_line_edit.h>
diff --git a/ui/qt/uat_dialog.cpp b/ui/qt/uat_dialog.cpp
index 6f9d2a7c..bf518888 100644
--- a/ui/qt/uat_dialog.cpp
+++ b/ui/qt/uat_dialog.cpp
@@ -70,10 +70,6 @@ UatDialog::UatDialog(QWidget *parent, epan_uat *uat) :
ui->uatTreeView->setEditTriggers(ui->uatTreeView->editTriggers() |
QAbstractItemView::CurrentChanged | QAbstractItemView::AnyKeyPressed);
- // Need to add uat_move or uat_insert to the UAT API.
- ui->uatTreeView->setDragEnabled(false);
-// qDebug() << "FIX Add drag reordering to UAT dialog";
-
// Do NOT start editing the first column for the first item
ui->uatTreeView->setCurrentIndex(QModelIndex());
}
@@ -106,7 +102,7 @@ void UatDialog::setUat(epan_uat *uat)
connect(copy_button, &CopyFromProfileButton::copyProfile, this, &UatDialog::copyFromProfile);
}
- QString abs_path = gchar_free_to_qstring(uat_get_actual_filename(uat_, FALSE));
+ QString abs_path = gchar_free_to_qstring(uat_get_actual_filename(uat_, false));
if (abs_path.length() > 0) {
ui->pathLabel->setText(abs_path);
ui->pathLabel->setUrl(QUrl::fromLocalFile(abs_path).toString());
@@ -120,6 +116,7 @@ void UatDialog::setUat(epan_uat *uat)
uat_delegate_ = new UatDelegate;
ui->uatTreeView->setModel(uat_model_);
ui->uatTreeView->setItemDelegate(uat_delegate_);
+ ui->uatTreeView->setSelectionMode(QAbstractItemView::ContiguousSelection);
resizeColumns();
ui->clearToolButton->setEnabled(uat_model_->rowCount() != 0);
@@ -129,6 +126,9 @@ void UatDialog::setUat(epan_uat *uat)
this, SLOT(modelRowsRemoved()));
connect(uat_model_, SIGNAL(modelReset()), this, SLOT(modelRowsReset()));
+ connect(ui->uatTreeView->selectionModel(), &QItemSelectionModel::selectionChanged,
+ this, &UatDialog::uatTreeViewSelectionChanged);
+
ok_button_->setEnabled(!uat_model_->hasErrors());
if (uat_->help && strlen(uat_->help) > 0) {
@@ -144,9 +144,9 @@ void UatDialog::setUat(epan_uat *uat)
void UatDialog::copyFromProfile(QString filename)
{
- gchar *err = NULL;
+ char *err = NULL;
if (uat_load(uat_, filename.toUtf8().constData(), &err)) {
- uat_->changed = TRUE;
+ uat_->changed = true;
uat_model_->reloadUat();
} else {
report_failure("Error while loading %s: %s", uat_->name, err);
@@ -176,6 +176,7 @@ void UatDialog::modelRowsRemoved()
ui->moveUpToolButton->setEnabled(false);
ui->moveDownToolButton->setEnabled(false);
}
+ ui->clearToolButton->setEnabled(uat_model_->rowCount() != 0);
checkForErrorHint(current, QModelIndex());
ok_button_->setEnabled(!uat_model_->hasErrors());
@@ -190,23 +191,32 @@ void UatDialog::modelRowsReset()
ui->moveDownToolButton->setEnabled(false);
}
+void UatDialog::uatTreeViewSelectionChanged(const QItemSelection&, const QItemSelection&)
+{
+ QModelIndexList selectedRows = ui->uatTreeView->selectionModel()->selectedRows();
+ qsizetype num_selected = selectedRows.size();
+ if (num_selected > 0) {
+ std::sort(selectedRows.begin(), selectedRows.end());
+ ui->deleteToolButton->setEnabled(true);
+ ui->copyToolButton->setEnabled(true);
+ ui->moveUpToolButton->setEnabled(selectedRows.first().row() > 0);
+ ui->moveDownToolButton->setEnabled(selectedRows.last().row() < uat_model_->rowCount() - 1);
+ } else {
+ ui->deleteToolButton->setEnabled(false);
+ ui->copyToolButton->setEnabled(false);
+ ui->moveUpToolButton->setEnabled(false);
+ ui->moveDownToolButton->setEnabled(false);
+ }
+}
// Invoked when a different field is selected. Note: when selecting a different
// field after editing, this event is triggered after modelDataChanged.
void UatDialog::on_uatTreeView_currentItemChanged(const QModelIndex &current, const QModelIndex &previous)
{
if (current.isValid()) {
- ui->deleteToolButton->setEnabled(true);
ui->clearToolButton->setEnabled(true);
- ui->copyToolButton->setEnabled(true);
- ui->moveUpToolButton->setEnabled(current.row() != 0);
- ui->moveDownToolButton->setEnabled(current.row() != (uat_model_->rowCount() - 1));
} else {
- ui->deleteToolButton->setEnabled(false);
ui->clearToolButton->setEnabled(false);
- ui->copyToolButton->setEnabled(false);
- ui->moveUpToolButton->setEnabled(false);
- ui->moveDownToolButton->setEnabled(false);
}
checkForErrorHint(current, previous);
@@ -289,46 +299,86 @@ void UatDialog::on_newToolButton_clicked()
void UatDialog::on_deleteToolButton_clicked()
{
- const QModelIndex &current = ui->uatTreeView->currentIndex();
- if (uat_model_ && current.isValid()) {
- if (!uat_model_->removeRows(current.row(), 1)) {
- qDebug() << "Failed to remove row";
+ if (uat_model_ == nullptr) {
+ return;
+ }
+
+ for (const auto &range : ui->uatTreeView->selectionModel()->selection()) {
+ // Each QItemSelectionRange is contiguous
+ if (!range.isEmpty()) {
+ if (!uat_model_->removeRows(range.top(), range.bottom() - range.top() + 1)) {
+ qDebug() << "Failed to remove rows" << range.top() << "to" << range.bottom();
+ }
}
}
}
void UatDialog::on_copyToolButton_clicked()
{
- addRecord(true);
+ if (uat_model_ == nullptr) {
+ return;
+ }
+
+ QModelIndexList selectedRows = ui->uatTreeView->selectionModel()->selectedRows();
+ if (selectedRows.size() > 0) {
+ std::sort(selectedRows.begin(), selectedRows.end());
+
+ QModelIndex copyIdx;
+
+ for (const auto &idx : selectedRows) {
+ copyIdx = uat_model_->copyRow(idx);
+ if (!copyIdx.isValid())
+ {
+ qDebug() << "Failed to copy row" << idx.row();
+ }
+ // trigger updating error messages and the OK button state.
+ modelDataChanged(copyIdx);
+ }
+ // due to an EditTrigger, this will also start editing.
+ ui->uatTreeView->setCurrentIndex(copyIdx);
+ }
+
}
void UatDialog::on_moveUpToolButton_clicked()
{
- const QModelIndex &current = ui->uatTreeView->currentIndex();
- int current_row = current.row();
- if (uat_model_ && current.isValid() && current_row > 0) {
- if (!uat_model_->moveRow(current_row, current_row - 1)) {
- qDebug() << "Failed to move row up";
- return;
+ if (uat_model_ == nullptr) {
+ return;
+ }
+
+ for (const auto &range : ui->uatTreeView->selectionModel()->selection()) {
+ // Each QItemSelectionRange is contiguous
+ if (!range.isEmpty() && range.top() > 0) {
+ // Swap range of rows with the row above the top
+ if (! uat_model_->moveRows(QModelIndex(), range.top(), range.bottom() - range.top() + 1, QModelIndex(), range.top() - 1)) {
+ qDebug() << "Failed to move up rows" << range.top() << "to" << range.bottom();
+ }
+ // Our moveRows implementation calls begin/endMoveRows(), so
+ // range.top() already has the new row number.
+ ui->moveUpToolButton->setEnabled(range.top() > 0);
+ ui->moveDownToolButton->setEnabled(true);
}
- current_row--;
- ui->moveUpToolButton->setEnabled(current_row > 0);
- ui->moveDownToolButton->setEnabled(current_row < (uat_model_->rowCount() - 1));
}
}
void UatDialog::on_moveDownToolButton_clicked()
{
- const QModelIndex &current = ui->uatTreeView->currentIndex();
- int current_row = current.row();
- if (uat_model_ && current.isValid() && current_row < (uat_model_->rowCount() - 1)) {
- if (!uat_model_->moveRow(current_row, current_row + 1)) {
- qDebug() << "Failed to move row down";
- return;
+ if (uat_model_ == nullptr) {
+ return;
+ }
+
+ for (const auto &range : ui->uatTreeView->selectionModel()->selection()) {
+ // Each QItemSelectionRange is contiguous
+ if (!range.isEmpty() && range.bottom() + 1 < uat_model_->rowCount()) {
+ // Swap range of rows with the row below the top
+ if (! uat_model_->moveRows(QModelIndex(), range.top(), range.bottom() - range.top() + 1, QModelIndex(), range.bottom() + 1)) {
+ qDebug() << "Failed to move down rows" << range.top() << "to" << range.bottom();
+ }
+ // Our moveRows implementation calls begin/endMoveRows, so
+ // range.bottom() already has the new row number.
+ ui->moveUpToolButton->setEnabled(true);
+ ui->moveDownToolButton->setEnabled(range.bottom() < uat_model_->rowCount() - 1);
}
- current_row++;
- ui->moveUpToolButton->setEnabled(current_row > 0);
- ui->moveDownToolButton->setEnabled(current_row < (uat_model_->rowCount() - 1));
}
}
diff --git a/ui/qt/uat_dialog.h b/ui/qt/uat_dialog.h
index 92d7d21b..6316198a 100644
--- a/ui/qt/uat_dialog.h
+++ b/ui/qt/uat_dialog.h
@@ -12,14 +12,13 @@
#include <config.h>
-#include <glib.h>
-
#include "geometry_state_dialog.h"
#include <ui/qt/models/uat_model.h>
#include <ui/qt/models/uat_delegate.h>
class QComboBox;
class QPushButton;
+class QItemSelection;
struct epan_uat;
@@ -42,6 +41,7 @@ private slots:
void modelDataChanged(const QModelIndex &topLeft);
void modelRowsRemoved();
void modelRowsReset();
+ void uatTreeViewSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
void on_uatTreeView_currentItemChanged(const QModelIndex &current, const QModelIndex &previous);
void acceptChanges();
void rejectChanges();
diff --git a/ui/qt/uat_dialog.ui b/ui/qt/uat_dialog.ui
index cdc8fbe6..3f373948 100644
--- a/ui/qt/uat_dialog.ui
+++ b/ui/qt/uat_dialog.ui
@@ -12,7 +12,7 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
- <widget class="TabnavTreeView" name="uatTreeView"/>
+ <widget class="RowMoveTreeView" name="uatTreeView"/>
</item>
<item>
<widget class="QLabel" name="hintLabel">
@@ -48,7 +48,7 @@
<bool>false</bool>
</property>
<property name="toolTip">
- <string>Remove this entry.</string>
+ <string>Remove the selected entry(ies).</string>
</property>
</widget>
</item>
@@ -58,7 +58,7 @@
<bool>false</bool>
</property>
<property name="toolTip">
- <string>Copy this entry.</string>
+ <string>Copy the selected entry(ies).</string>
</property>
<property name="text">
<string/>
@@ -71,7 +71,7 @@
<bool>false</bool>
</property>
<property name="toolTip">
- <string>Move entry up.</string>
+ <string>Move the selected entry(ies) up.</string>
</property>
<property name="text">
<string/>
@@ -84,7 +84,7 @@
<bool>false</bool>
</property>
<property name="toolTip">
- <string>Move entry down.</string>
+ <string>Move the selected entry(ies) down.</string>
</property>
<property name="text">
<string/>
@@ -144,9 +144,9 @@
<header>widgets/elided_label.h</header>
</customwidget>
<customwidget>
- <class>TabnavTreeView</class>
+ <class>RowMoveTreeView</class>
<extends>QTreeView</extends>
- <header>widgets/tabnav_tree_view.h</header>
+ <header>widgets/rowmove_tree_view.h</header>
</customwidget>
<customwidget>
<class>StockIconToolButton</class>
diff --git a/ui/qt/uat_frame.cpp b/ui/qt/uat_frame.cpp
index c48cf4c2..1a099feb 100644
--- a/ui/qt/uat_frame.cpp
+++ b/ui/qt/uat_frame.cpp
@@ -9,8 +9,6 @@
#include "config.h"
-#include <glib.h>
-
#include <epan/filter_expressions.h>
#include "uat_frame.h"
@@ -65,8 +63,6 @@ UatFrame::UatFrame(QWidget *parent) :
// start editing as soon as the field is selected or when typing starts
ui->uatTreeView->setEditTriggers(ui->uatTreeView->editTriggers() |
QAbstractItemView::CurrentChanged | QAbstractItemView::AnyKeyPressed);
-
- // XXX - Need to add uat_move or uat_insert to the UAT API for drag/drop
}
UatFrame::~UatFrame()
@@ -95,7 +91,7 @@ void UatFrame::setUat(epan_uat *uat)
connect(ui->copyFromProfileButton, &CopyFromProfileButton::copyProfile, this, &UatFrame::copyFromProfile);
}
- QString abs_path = gchar_free_to_qstring(uat_get_actual_filename(uat_, FALSE));
+ QString abs_path = gchar_free_to_qstring(uat_get_actual_filename(uat_, false));
if (abs_path.length() > 0) {
ui->pathLabel->setText(abs_path);
ui->pathLabel->setUrl(QUrl::fromLocalFile(abs_path).toString());
@@ -109,6 +105,7 @@ void UatFrame::setUat(epan_uat *uat)
uat_delegate_ = new UatDelegate;
ui->uatTreeView->setModel(uat_model_);
ui->uatTreeView->setItemDelegate(uat_delegate_);
+ ui->uatTreeView->setSelectionMode(QAbstractItemView::ContiguousSelection);
resizeColumns();
ui->clearToolButton->setEnabled(uat_model_->rowCount() != 0);
@@ -117,6 +114,9 @@ void UatFrame::setUat(epan_uat *uat)
connect(uat_model_, SIGNAL(rowsRemoved(QModelIndex, int, int)),
this, SLOT(modelRowsRemoved()));
connect(uat_model_, SIGNAL(modelReset()), this, SLOT(modelRowsReset()));
+
+ connect(ui->uatTreeView->selectionModel(), &QItemSelectionModel::selectionChanged,
+ this, &UatFrame::uatTreeViewSelectionChanged);
}
setWindowTitle(title);
@@ -124,9 +124,9 @@ void UatFrame::setUat(epan_uat *uat)
void UatFrame::copyFromProfile(QString filename)
{
- gchar *err = NULL;
+ char *err = NULL;
if (uat_load(uat_, filename.toUtf8().constData(), &err)) {
- uat_->changed = TRUE;
+ uat_->changed = true;
uat_model_->reloadUat();
} else {
report_failure("Error while loading %s: %s", uat_->name, err);
@@ -205,23 +205,33 @@ void UatFrame::addRecord(bool copy_from_current)
modelDataChanged(new_index);
}
-// Invoked when a different field is selected. Note: when selecting a different
-// field after editing, this event is triggered after modelDataChanged.
-void UatFrame::on_uatTreeView_currentItemChanged(const QModelIndex &current, const QModelIndex &previous)
+void UatFrame::uatTreeViewSelectionChanged(const QItemSelection&, const QItemSelection&)
{
- if (current.isValid()) {
+ QModelIndexList selectedRows = ui->uatTreeView->selectionModel()->selectedRows();
+ qsizetype num_selected = selectedRows.size();
+ if (num_selected > 0) {
+ std::sort(selectedRows.begin(), selectedRows.end());
ui->deleteToolButton->setEnabled(true);
- ui->clearToolButton->setEnabled(true);
ui->copyToolButton->setEnabled(true);
- ui->moveUpToolButton->setEnabled(current.row() != 0);
- ui->moveDownToolButton->setEnabled(current.row() != (uat_model_->rowCount() - 1));
+ ui->moveUpToolButton->setEnabled(selectedRows.first().row() > 0);
+ ui->moveDownToolButton->setEnabled(selectedRows.last().row() < uat_model_->rowCount() - 1);
} else {
ui->deleteToolButton->setEnabled(false);
- ui->clearToolButton->setEnabled(false);
ui->copyToolButton->setEnabled(false);
ui->moveUpToolButton->setEnabled(false);
ui->moveDownToolButton->setEnabled(false);
}
+}
+
+// Invoked when a different field is selected. Note: when selecting a different
+// field after editing, this event is triggered after modelDataChanged.
+void UatFrame::on_uatTreeView_currentItemChanged(const QModelIndex &current, const QModelIndex &previous)
+{
+ if (current.isValid()) {
+ ui->clearToolButton->setEnabled(true);
+ } else {
+ ui->clearToolButton->setEnabled(false);
+ }
checkForErrorHint(current, previous);
}
@@ -247,6 +257,7 @@ void UatFrame::modelRowsRemoved()
ui->moveUpToolButton->setEnabled(false);
ui->moveDownToolButton->setEnabled(false);
}
+ ui->clearToolButton->setEnabled(uat_model_->rowCount() != 0);
checkForErrorHint(current, QModelIndex());
}
@@ -311,46 +322,86 @@ void UatFrame::on_newToolButton_clicked()
void UatFrame::on_deleteToolButton_clicked()
{
- const QModelIndex &current = ui->uatTreeView->currentIndex();
- if (uat_model_ && current.isValid()) {
- if (!uat_model_->removeRows(current.row(), 1)) {
- qDebug() << "Failed to remove row";
+ if (uat_model_ == nullptr) {
+ return;
+ }
+
+ for (const auto &range : ui->uatTreeView->selectionModel()->selection()) {
+ // Each QItemSelectionRange is contiguous
+ if (!range.isEmpty()) {
+ if (!uat_model_->removeRows(range.top(), range.bottom() - range.top() + 1)) {
+ qDebug() << "Failed to remove rows" << range.top() << "to" << range.bottom();
+ }
}
}
}
void UatFrame::on_copyToolButton_clicked()
{
- addRecord(true);
+ if (uat_model_ == nullptr) {
+ return;
+ }
+
+ QModelIndexList selectedRows = ui->uatTreeView->selectionModel()->selectedRows();
+ if (selectedRows.size() > 0) {
+ std::sort(selectedRows.begin(), selectedRows.end());
+
+ QModelIndex copyIdx;
+
+ for (const auto &idx : selectedRows) {
+ copyIdx = uat_model_->copyRow(idx);
+ if (!copyIdx.isValid())
+ {
+ qDebug() << "Failed to copy row" << idx.row();
+ }
+ // trigger updating error messages and the OK button state.
+ modelDataChanged(copyIdx);
+ }
+ // due to an EditTrigger, this will also start editing.
+ ui->uatTreeView->setCurrentIndex(copyIdx);
+ }
+
}
void UatFrame::on_moveUpToolButton_clicked()
{
- const QModelIndex &current = ui->uatTreeView->currentIndex();
- int current_row = current.row();
- if (uat_model_ && current.isValid() && current_row > 0) {
- if (!uat_model_->moveRow(current_row, current_row - 1)) {
- qDebug() << "Failed to move row up";
- return;
+ if (uat_model_ == nullptr) {
+ return;
+ }
+
+ for (const auto &range : ui->uatTreeView->selectionModel()->selection()) {
+ // Each QItemSelectionRange is contiguous
+ if (!range.isEmpty() && range.top() > 0) {
+ // Swap range of rows with the row above the top
+ if (! uat_model_->moveRows(QModelIndex(), range.top(), range.bottom() - range.top() + 1, QModelIndex(), range.top() - 1)) {
+ qDebug() << "Failed to move up rows" << range.top() << "to" << range.bottom();
+ }
+ // Our moveRows implementation calls begin/endMoveRows(), so
+ // range.top() already has the new row number.
+ ui->moveUpToolButton->setEnabled(range.top() > 0);
+ ui->moveDownToolButton->setEnabled(true);
}
- current_row--;
- ui->moveUpToolButton->setEnabled(current_row > 0);
- ui->moveDownToolButton->setEnabled(current_row < (uat_model_->rowCount() - 1));
}
}
void UatFrame::on_moveDownToolButton_clicked()
{
- const QModelIndex &current = ui->uatTreeView->currentIndex();
- int current_row = current.row();
- if (uat_model_ && current.isValid() && current_row < (uat_model_->rowCount() - 1)) {
- if (!uat_model_->moveRow(current_row, current_row + 1)) {
- qDebug() << "Failed to move row down";
- return;
+ if (uat_model_ == nullptr) {
+ return;
+ }
+
+ for (const auto &range : ui->uatTreeView->selectionModel()->selection()) {
+ // Each QItemSelectionRange is contiguous
+ if (!range.isEmpty() && range.bottom() + 1 < uat_model_->rowCount()) {
+ // Swap range of rows with the row below the top
+ if (! uat_model_->moveRows(QModelIndex(), range.top(), range.bottom() - range.top() + 1, QModelIndex(), range.bottom() + 1)) {
+ qDebug() << "Failed to move down rows" << range.top() << "to" << range.bottom();
+ }
+ // Our moveRows implementation calls begin/endMoveRows, so
+ // range.bottom() already has the new row number.
+ ui->moveUpToolButton->setEnabled(true);
+ ui->moveDownToolButton->setEnabled(range.bottom() < uat_model_->rowCount() - 1);
}
- current_row++;
- ui->moveUpToolButton->setEnabled(current_row > 0);
- ui->moveDownToolButton->setEnabled(current_row < (uat_model_->rowCount() - 1));
}
}
diff --git a/ui/qt/uat_frame.h b/ui/qt/uat_frame.h
index 870bba9c..f20c10ce 100644
--- a/ui/qt/uat_frame.h
+++ b/ui/qt/uat_frame.h
@@ -16,6 +16,8 @@
#include <ui/qt/models/uat_model.h>
#include <ui/qt/models/uat_delegate.h>
+class QItemSelection;
+
namespace Ui {
class UatFrame;
}
@@ -54,6 +56,7 @@ private slots:
void modelDataChanged(const QModelIndex &topLeft);
void modelRowsRemoved();
void modelRowsReset();
+ void uatTreeViewSelectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
void on_uatTreeView_currentItemChanged(const QModelIndex &current, const QModelIndex &previous);
void on_newToolButton_clicked();
void on_deleteToolButton_clicked();
diff --git a/ui/qt/uat_frame.ui b/ui/qt/uat_frame.ui
index 452ae65d..a49fc29c 100644
--- a/ui/qt/uat_frame.ui
+++ b/ui/qt/uat_frame.ui
@@ -18,7 +18,7 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
- <widget class="TabnavTreeView" name="uatTreeView"/>
+ <widget class="RowMoveTreeView" name="uatTreeView"/>
</item>
<item>
<widget class="QLabel" name="hintLabel">
@@ -54,7 +54,7 @@
<bool>false</bool>
</property>
<property name="toolTip">
- <string>Remove this entry.</string>
+ <string>Remove the selected entry(ies).</string>
</property>
</widget>
</item>
@@ -64,7 +64,7 @@
<bool>false</bool>
</property>
<property name="toolTip">
- <string>Copy this entry.</string>
+ <string>Copy the selected entry(ies).</string>
</property>
<property name="text">
<string/>
@@ -74,7 +74,7 @@
<item>
<widget class="StockIconToolButton" name="moveUpToolButton">
<property name="toolTip">
- <string>Move entry up.</string>
+ <string>Move the selected entry(ies) up.</string>
</property>
<property name="text">
<string/>
@@ -84,7 +84,7 @@
<item>
<widget class="StockIconToolButton" name="moveDownToolButton">
<property name="toolTip">
- <string>Move entry down.</string>
+ <string>Move the selected entry(ies) down.</string>
</property>
<property name="text">
<string/>
@@ -141,9 +141,9 @@
<header>widgets/elided_label.h</header>
</customwidget>
<customwidget>
- <class>TabnavTreeView</class>
+ <class>RowMoveTreeView</class>
<extends>QTreeView</extends>
- <header>widgets/tabnav_tree_view.h</header>
+ <header>widgets/rowmove_tree_view.h</header>
</customwidget>
<customwidget>
<class>StockIconToolButton</class>
diff --git a/ui/qt/utils/color_utils.cpp b/ui/qt/utils/color_utils.cpp
index e7d7c6c5..6024fdb8 100644
--- a/ui/qt/utils/color_utils.cpp
+++ b/ui/qt/utils/color_utils.cpp
@@ -148,10 +148,16 @@ QRgb ColorUtils::sequenceColor(int item)
bool ColorUtils::themeIsDark()
{
#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
- return qApp->styleHints()->colorScheme() == Qt::ColorScheme::Dark;
-#else
- return qApp->palette().windowText().color().lightness() > qApp->palette().window().color().lightness();
+ switch (qApp->styleHints()->colorScheme()) {
+ case Qt::ColorScheme::Dark:
+ return true;
+ case Qt::ColorScheme::Light:
+ return false;
+ case Qt::ColorScheme::Unknown:
+ break;
+ }
#endif
+ return qApp->palette().windowText().color().lightness() > qApp->palette().window().color().lightness();
}
// Qt < 5.12.6 on macOS always uses Qt::blue for the link color, which is
@@ -191,8 +197,10 @@ const QColor ColorUtils::contrastingTextColor(const QColor color)
{
bool background_is_light = color.lightness() > 127;
if ( (background_is_light && !ColorUtils::themeIsDark()) || (!background_is_light && ColorUtils::themeIsDark()) ) {
+ // usually black/darker color in light mode and white/lighter color in dark mode
return QApplication::palette().text().color();
}
+ // usually white/lighter color in light mode and black/darker color in dark mode
return QApplication::palette().base().color();
}
@@ -214,3 +222,8 @@ const QColor ColorUtils::warningBackground()
}
return QColor(tango_butter_2);
}
+
+const QColor ColorUtils::disabledForeground()
+{
+ return alphaBlend(QApplication::palette().windowText(), QApplication::palette().window(), 0.65);
+}
diff --git a/ui/qt/utils/color_utils.h b/ui/qt/utils/color_utils.h
index a205cccc..ac5ed02e 100644
--- a/ui/qt/utils/color_utils.h
+++ b/ui/qt/utils/color_utils.h
@@ -12,8 +12,6 @@
#include <config.h>
-#include <glib.h>
-
#include <epan/color_filters.h>
#include <QBrush>
@@ -82,11 +80,17 @@ public:
*/
static const QColor warningBackground();
+ /**
+ * Returns an appropriate foreground color for disabled text.
+ * @return The foreground color.
+ */
+ static const QColor disabledForeground();
+
private:
static QList<QRgb> graph_colors_;
static QList<QRgb> sequence_colors_;
};
-void color_filter_qt_add_cb(color_filter_t *colorf, gpointer user_data);
+void color_filter_qt_add_cb(color_filter_t *colorf, void *user_data);
#endif // COLOR_UTILS_H
diff --git a/ui/qt/utils/data_printer.cpp b/ui/qt/utils/data_printer.cpp
index a96e1ed4..f3635ee4 100644
--- a/ui/qt/utils/data_printer.cpp
+++ b/ui/qt/utils/data_printer.cpp
@@ -34,17 +34,65 @@ void DataPrinter::toClipboard(DataPrinter::DumpType type, IDataPrintable * print
switch(type)
{
+ case DP_GoLiteral:
+ clipboard_text += QString("[]byte{");
+ for (int i = 0; i < printData.length(); i++) {
+ if (i>0) clipboard_text += ", ";
+ clipboard_text += QString("0x%1").arg((uint8_t) printData[i], 1, 16, QChar('0'));
+ }
+ clipboard_text += QString("}");
+ break;
+ case DP_CArray:
+ clipboard_text += QString("unsigned char bytes[] = {");
+ for (int i = 0; i < printData.length(); i++) {
+ if (i>0) clipboard_text += ", ";
+ clipboard_text += QString("0x%1").arg((uint8_t) printData[i], 1, 16, QChar('0'));
+ }
+ clipboard_text += QString("};");
+ break;
case DP_CString:
// Beginning quote
clipboard_text += QString("\"");
for (int i = 0; i < printData.length(); i++) {
- /* ASCII printable */
- int ch = printData[i];
- if (ch >= 32 && ch <= 126) {
- clipboard_text += QChar(ch);
- }
- else {
- clipboard_text += QString("\\x%1").arg((uint8_t) printData[i], 2, 16, QChar('0'));
+ // backslash and double quote are printable but
+ // must be escaped in a C string.
+ char ch = printData[i];
+ switch (ch) {
+ case '\"':
+ clipboard_text += QString("\\\"");
+ break;
+ case '\\':
+ clipboard_text += QString("\\\\");
+ break;
+ case '\a':
+ clipboard_text += QString("\\a");
+ break;
+ case '\b':
+ clipboard_text += QString("\\b");
+ break;
+ case '\f':
+ clipboard_text += QString("\\f");
+ break;
+ case '\n':
+ clipboard_text += QString("\\n");
+ break;
+ case '\r':
+ clipboard_text += QString("\\r");
+ break;
+ case '\t':
+ clipboard_text += QString("\\t");
+ break;
+ case '\v':
+ clipboard_text += QString("\\v");
+ break;
+ default:
+ // ASCII printable
+ if (ch >= 32 && ch <= 126) {
+ clipboard_text += QChar(ch);
+ }
+ else {
+ clipboard_text += QString("\\%1").arg((uint8_t) printData[i], 3, 8, QChar('0'));
+ }
}
}
// End quote
@@ -54,10 +102,21 @@ void DataPrinter::toClipboard(DataPrinter::DumpType type, IDataPrintable * print
for (int i = 0; i < printData.length(); i++)
clipboard_text += QString("%1").arg((uint8_t) printData[i], 2, 16, QChar('0'));
break;
- case DP_PrintableText:
+ case DP_UTF8Text:
+ // This automatically compensates for invalid UTF-8 in the input
+#if WS_IS_AT_LEAST_GNUC_VERSION(12,1)
+DIAG_OFF(stringop-overread)
+#endif
+ clipboard_text += QString::fromUtf8(printData);
+#if WS_IS_AT_LEAST_GNUC_VERSION(12,1)
+DIAG_ON(stringop-overread)
+#endif
+ break;
+ case DP_ASCIIText:
+ // Copy valid 7-bit printable ASCII bytes, skip the rest
for (int i = 0; i < printData.length(); i++) {
QChar ch(printData[i]);
- if (ch.isSpace() || ch.isPrint()) {
+ if (ch.isSpace() || (ch > (char)0x20 && ch < (char)0x7F)) {
clipboard_text += ch;
}
}
@@ -227,9 +286,14 @@ QActionGroup * DataPrinter::copyActions(QObject * copyClass, QObject * data)
action->setProperty("printertype", DataPrinter::DP_HexOnly);
connect(action, &QAction::triggered, dpi, &DataPrinter::copyIDataBytes);
- action = new QAction(tr("…as Printable Text"), actions);
- action->setToolTip(tr("Copy only the printable text in the packet."));
- action->setProperty("printertype", DataPrinter::DP_PrintableText);
+ action = new QAction(tr("…as UTF-8 Text"), actions);
+ action->setToolTip(tr("Copy packet bytes as text, treating as UTF-8."));
+ action->setProperty("printertype", DataPrinter::DP_UTF8Text);
+ connect(action, &QAction::triggered, dpi, &DataPrinter::copyIDataBytes);
+
+ action = new QAction(tr("…as ASCII Text"), actions);
+ action->setToolTip(tr("Copy packet bytes as text, treating as ASCII."));
+ action->setProperty("printertype", DataPrinter::DP_ASCIIText);
connect(action, &QAction::triggered, dpi, &DataPrinter::copyIDataBytes);
action = new QAction(tr("…as a Hex Stream"), actions);
@@ -252,6 +316,16 @@ QActionGroup * DataPrinter::copyActions(QObject * copyClass, QObject * data)
action->setProperty("printertype", DataPrinter::DP_CString);
connect(action, &QAction::triggered, dpi, &DataPrinter::copyIDataBytes);
+ action = new QAction(tr("…as Go literal"), actions);
+ action->setToolTip(tr("Copy packet bytes as Go literal."));
+ action->setProperty("printertype", DataPrinter::DP_GoLiteral);
+ connect(action, &QAction::triggered, dpi, &DataPrinter::copyIDataBytes);
+
+ action = new QAction(tr("…as C Array"), actions);
+ action->setToolTip(tr("Copy packet bytes as C Array."));
+ action->setProperty("printertype", DataPrinter::DP_CArray);
+ connect(action, &QAction::triggered, dpi, &DataPrinter::copyIDataBytes);
+
return actions;
}
diff --git a/ui/qt/utils/data_printer.h b/ui/qt/utils/data_printer.h
index 882b5752..52c259f8 100644
--- a/ui/qt/utils/data_printer.h
+++ b/ui/qt/utils/data_printer.h
@@ -30,8 +30,11 @@ public:
DP_HexDump,
DP_HexOnly,
DP_HexStream,
- DP_PrintableText,
+ DP_UTF8Text,
+ DP_ASCIIText,
DP_CString,
+ DP_GoLiteral,
+ DP_CArray,
DP_MimeData,
DP_Base64
};
diff --git a/ui/qt/utils/frame_information.cpp b/ui/qt/utils/frame_information.cpp
index d344bc04..facd368d 100644
--- a/ui/qt/utils/frame_information.cpp
+++ b/ui/qt/utils/frame_information.cpp
@@ -48,13 +48,13 @@ void FrameInformation::loadFrameTree()
edt_ = g_new0(epan_dissect_t, 1);
/* proto tree, visible. We need a proto tree if there's custom columns */
- epan_dissect_init(edt_, cap_file_->capFile()->epan, TRUE, TRUE);
+ epan_dissect_init(edt_, cap_file_->capFile()->epan, true, true);
col_custom_prime_edt(edt_, &(cap_file_->capFile()->cinfo));
epan_dissect_run(edt_, cap_file_->capFile()->cd_t, &rec_,
frame_tvbuff_new_buffer(&cap_file_->capFile()->provider, fi_, &buf_),
fi_, &(cap_file_->capFile()->cinfo));
- epan_dissect_fill_in_columns(edt_, TRUE, TRUE);
+ epan_dissect_fill_in_columns(edt_, true, true);
}
FrameInformation::~FrameInformation()
diff --git a/ui/qt/utils/profile_switcher.cpp b/ui/qt/utils/profile_switcher.cpp
new file mode 100644
index 00000000..ded1b1f5
--- /dev/null
+++ b/ui/qt/utils/profile_switcher.cpp
@@ -0,0 +1,140 @@
+/* profile_switcher.cpp
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+// #include <capture_file.h>
+#include <main_application.h>
+
+#include <ui/profile.h>
+#include <ui/recent.h>
+
+#include <ui/qt/capture_file.h>
+#include <ui/qt/models/packet_list_model.h>
+
+#include "profile_switcher.h"
+
+#include "file.h"
+
+#include <epan/epan.h>
+#include <epan/epan_dissect.h>
+#include <epan/prefs.h>
+#include "frame_tvbuff.h"
+
+// Enable switching iff:
+// - We're opening a new capture file via the UI.
+// - We haven't changed our profile, either manually or automatically.
+
+ProfileSwitcher::ProfileSwitcher(QObject *parent) :
+ QObject(parent),
+ capture_file_changed_(true),
+ profile_changed_(false)
+{
+ if (g_list_length(current_profile_list()) == 0) {
+ init_profile_list();
+ }
+ connect(mainApp, &MainApplication::profileChanging, this, &ProfileSwitcher::disableSwitching);
+}
+
+void ProfileSwitcher::captureEventHandler(CaptureEvent ev)
+{
+ if (ev.captureContext() != CaptureEvent::File) {
+ return;
+ }
+
+ CaptureFile *capture_file = qobject_cast<CaptureFile *>(sender());
+ if (!capture_file) {
+ return;
+ }
+
+ // CaptureEvent doesn't have a "this is the same file" flag, so
+ // track that via the filename.
+ switch (ev.eventType()) {
+ case CaptureEvent::Opened:
+ if (previous_cap_file_ != capture_file->filePath()) {
+ capture_file_changed_ = true;
+ profile_changed_ = false;
+ }
+ break;
+ case CaptureEvent::Closing:
+ previous_cap_file_ = capture_file->filePath();
+ break;
+ default:
+ break;
+ }
+}
+
+void ProfileSwitcher::checkPacket(capture_file *cap_file, frame_data *fdata, qsizetype row)
+{
+ if (profile_changed_ || !capture_file_changed_ || row >= recent.gui_profile_switch_check_count) {
+ return;
+ }
+
+ if (row == 0) {
+ clearProfileFilters();
+ for (GList *cur = current_profile_list() ; cur; cur = cur->next) {
+ profile_def *profile = static_cast<profile_def *>(cur->data);
+ if (!profile->auto_switch_filter) {
+ continue;
+ }
+ dfilter_t *dfcode;
+ if (dfilter_compile(profile->auto_switch_filter, &dfcode, NULL) && dfcode) {
+ profile_filters_.append({profile->name, dfcode});
+ }
+ }
+ }
+
+ if (profile_filters_.empty()) {
+ return;
+ }
+
+ QString new_profile;
+ wtap_rec rec;
+ Buffer buf;
+ wtap_rec_init(&rec);
+ ws_buffer_init(&buf, 1514);
+ epan_dissect_t edt;
+
+ for (auto &cur_filter : profile_filters_) {
+ if (!cf_read_record(cap_file, fdata, &rec, &buf)) {
+ continue;
+ }
+ epan_dissect_init(&edt, cap_file->epan, TRUE, FALSE);
+ epan_dissect_prime_with_dfilter(&edt, cur_filter.dfcode);
+ epan_dissect_run(&edt, cap_file->cd_t, &rec,
+ frame_tvbuff_new_buffer(&cap_file->provider, fdata, &buf),
+ fdata, NULL);
+ bool matched = dfilter_apply_edt(cur_filter.dfcode, &edt);
+ epan_dissect_cleanup(&edt);
+ if (matched) {
+ new_profile = cur_filter.name;
+ break;
+ }
+ }
+
+ wtap_rec_cleanup(&rec);
+ ws_buffer_free(&buf);
+
+ if (!new_profile.isEmpty()) {
+ clearProfileFilters();
+ previous_cap_file_ = cap_file->filename;
+ mainApp->setConfigurationProfile(qUtf8Printable(new_profile), false);
+ }
+}
+
+void ProfileSwitcher::clearProfileFilters()
+{
+ for (auto &cur_filter : profile_filters_) {
+ dfilter_free(cur_filter.dfcode);
+ }
+ profile_filters_.clear();
+}
+
+void ProfileSwitcher::disableSwitching()
+{
+ profile_changed_ = true;
+}
diff --git a/ui/qt/utils/profile_switcher.h b/ui/qt/utils/profile_switcher.h
new file mode 100644
index 00000000..57dfd255
--- /dev/null
+++ b/ui/qt/utils/profile_switcher.h
@@ -0,0 +1,48 @@
+/** @file
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#pragma once
+
+#include <config.h>
+
+#include "capture_event.h"
+#include "cfile.h"
+
+#include <QObject>
+#include <QVector>
+
+struct profile_switch_filter {
+ QString name;
+ dfilter_t *dfcode;
+};
+
+class PacketListModel;
+
+class ProfileSwitcher : public QObject
+{
+ Q_OBJECT
+public:
+ explicit ProfileSwitcher(QObject *parent = nullptr);
+
+public slots:
+ void captureEventHandler(CaptureEvent ev);
+ void checkPacket(capture_file *cap_file, frame_data *fdata, qsizetype row);
+
+private:
+ PacketListModel *packet_list_model_;
+ QVector<struct profile_switch_filter> profile_filters_;
+ bool capture_file_changed_;
+ bool profile_changed_;
+ QString previous_cap_file_;
+
+ void clearProfileFilters();
+
+private slots:
+ void disableSwitching();
+};
diff --git a/ui/qt/utils/proto_node.cpp b/ui/qt/utils/proto_node.cpp
index 68d1f4c7..222b2d5e 100644
--- a/ui/qt/utils/proto_node.cpp
+++ b/ui/qt/utils/proto_node.cpp
@@ -12,6 +12,7 @@
#include <epan/prefs.h>
+// NOLINTNEXTLINE(misc-no-recursion)
ProtoNode::ProtoNode(proto_node *node, ProtoNode *parent) :
node_(node), parent_(parent)
{
@@ -28,6 +29,7 @@ ProtoNode::ProtoNode(proto_node *node, ProtoNode *parent) :
for (proto_node *child = node_->first_child; child; child = child->next) {
if (!isHidden(child)) {
+ // We recurse here, but we're limited by tree depth checks in epan
m_children.append(new ProtoNode(child, this));
}
}
@@ -70,7 +72,7 @@ QString ProtoNode::labelText() const
label = fi->rep->representation;
}
else { /* no, make a generic label */
- gchar label_str[ITEM_LABEL_LENGTH];
+ char label_str[ITEM_LABEL_LENGTH];
proto_item_fill_label(fi, label_str);
label = label_str;
}
diff --git a/ui/qt/utils/qt_ui_utils.cpp b/ui/qt/utils/qt_ui_utils.cpp
index 9dad9dd9..addfe208 100644
--- a/ui/qt/utils/qt_ui_utils.cpp
+++ b/ui/qt/utils/qt_ui_utils.cpp
@@ -17,15 +17,13 @@
#include <epan/range.h>
#include <epan/to_str.h>
#include <epan/value_string.h>
-#include <epan/prefs.h>
#include <ui/recent.h>
#include <ui/util.h>
#include "ui/ws_ui_util.h"
#include <wsutil/str_util.h>
-
-#include <ui/qt/main_application.h>
+#include <wsutil/file_util.h>
#include <QAction>
#include <QApplication>
@@ -36,24 +34,31 @@
#include <QFontDatabase>
#include <QProcess>
#include <QUrl>
-#include <QUuid>
#include <QScreen>
+#if defined(Q_OS_MAC)
+#include <ui/macosx/cocoa_bridge.h>
+#elif !defined(Q_OS_WIN) && defined(QT_DBUS_LIB)
+#include <QtDBus/QDBusConnection>
+#include <QtDBus/QDBusMessage>
+#include <QtDBus/QDBusUnixFileDescriptor>
+#endif
+
/*
* We might want to create our own "wsstring" class with convenience
* methods for handling g_malloc()ed strings, GStrings, and a shortcut
* to .toUtf8().constData().
*/
-gchar *qstring_strdup(QString q_string) {
- return g_strdup(q_string.toUtf8().constData());
+char *qstring_strdup(QString q_string) {
+ return g_strdup(qUtf8Printable(q_string));
}
-QString gchar_free_to_qstring(gchar *glib_string) {
+QString gchar_free_to_qstring(char *glib_string) {
return QString(gchar_free_to_qbytearray(glib_string));
}
-QByteArray gchar_free_to_qbytearray(gchar *glib_string)
+QByteArray gchar_free_to_qbytearray(char *glib_string)
{
QByteArray qt_bytearray(glib_string);
g_free(glib_string);
@@ -70,7 +75,7 @@ QByteArray gstring_free_to_qbytearray(GString *glib_gstring)
QByteArray gbytearray_free_to_qbytearray(GByteArray *glib_array)
{
QByteArray qt_ba(reinterpret_cast<char *>(glib_array->data), glib_array->len);
- g_byte_array_free(glib_array, TRUE);
+ g_byte_array_free(glib_array, true);
return qt_ba;
}
@@ -101,7 +106,7 @@ const QString address_to_qstring(const _address *address, bool enclose)
QString address_qstr = QString();
if (address) {
if (enclose && address->type == AT_IPv6) address_qstr += "[";
- gchar *address_gchar_p = address_to_str(NULL, address);
+ char *address_gchar_p = address_to_str(NULL, address);
address_qstr += address_gchar_p;
wmem_free(NULL, address_gchar_p);
if (enclose && address->type == AT_IPv6) address_qstr += "]";
@@ -113,27 +118,27 @@ const QString address_to_display_qstring(const _address *address)
{
QString address_qstr = QString();
if (address) {
- gchar *address_gchar_p = address_to_display(NULL, address);
+ char *address_gchar_p = address_to_display(NULL, address);
address_qstr = address_gchar_p;
wmem_free(NULL, address_gchar_p);
}
return address_qstr;
}
-const QString val_to_qstring(const guint32 val, const value_string *vs, const char *fmt)
+const QString val_to_qstring(const uint32_t val, const value_string *vs, const char *fmt)
{
QString val_qstr;
- gchar* gchar_p = val_to_str_wmem(NULL, val, vs, fmt);
+ char* gchar_p = val_to_str_wmem(NULL, val, vs, fmt);
val_qstr = gchar_p;
wmem_free(NULL, gchar_p);
return val_qstr;
}
-const QString val_ext_to_qstring(const guint32 val, value_string_ext *vse, const char *fmt)
+const QString val_ext_to_qstring(const uint32_t val, value_string_ext *vse, const char *fmt)
{
QString val_qstr;
- gchar* gchar_p = val_to_str_ext_wmem(NULL, val, vse, fmt);
+ char* gchar_p = val_to_str_ext_wmem(NULL, val, vse, fmt);
val_qstr = gchar_p;
wmem_free(NULL, gchar_p);
@@ -155,7 +160,7 @@ const QString bits_s_to_qstring(const double bits_s)
format_size(bits_s, FORMAT_SIZE_UNIT_NONE, FORMAT_SIZE_PREFIX_SI));
}
-const QString file_size_to_qstring(const gint64 size)
+const QString file_size_to_qstring(const int64_t size)
{
return gchar_free_to_qstring(
format_size(size, FORMAT_SIZE_UNIT_BYTES, FORMAT_SIZE_PREFIX_SI));
@@ -209,28 +214,55 @@ void desktop_show_in_folder(const QString file_path)
// https://stackoverflow.com/questions/3490336/how-to-reveal-in-finder-or-show-in-explorer-with-qt
#if defined(Q_OS_WIN)
+ //
+ // See
+ //
+ // https://stackoverflow.com/questions/13680415/how-to-open-explorer-with-a-specific-file-selected
+ //
+ // for a way to do this using Windows Shell APIs, rather than having
+ // to fire up a separate instance of Windows Explorer.
+ //
QString command = "explorer.exe";
QStringList arguments;
QString path = QDir::toNativeSeparators(file_path);
arguments << "/select," << path + "";
success = QProcess::startDetached(command, arguments);
#elif defined(Q_OS_MAC)
- QStringList script_args;
- QString escaped_path = file_path;
-
- escaped_path.replace('"', "\\\"");
- script_args << "-e"
- << QString("tell application \"Finder\" to reveal POSIX file \"%1\"")
- .arg(escaped_path);
- if (QProcess::execute("/usr/bin/osascript", script_args) == 0) {
- success = true;
- script_args.clear();
- script_args << "-e"
- << "tell application \"Finder\" to activate";
- QProcess::execute("/usr/bin/osascript", script_args);
+ CocoaBridge::showInFinder(file_path.toUtf8());
+ success = true;
+#elif defined(QT_DBUS_LIB)
+ // First, try the FileManager1 DBus interface's "ShowItems" method.
+ // https://www.freedesktop.org/wiki/Specifications/file-manager-interface/
+ QDBusMessage message = QDBusMessage::createMethodCall(QLatin1String("org.freedesktop.FileManager1"),
+ QLatin1String("/org/freedesktop/FileManager1"),
+ QLatin1String("org.freedesktop.FileManager1"),
+ QLatin1String("ShowItems"));
+ QStringList uris(QUrl::fromLocalFile(file_path).toString());
+ message << uris << QString();
+
+ message = QDBusConnection::sessionBus().call(message);
+ success = message.type() == QDBusMessage::ReplyMessage;
+
+ // If that failed, perhaps we are sandboxed. Try using Portal Services.
+ // https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.OpenURI.html
+ if (!success) {
+ const int fd = ws_open(QFile::encodeName(file_path), O_CLOEXEC | O_PATH, 0000);
+ if (fd != -1) {
+ QDBusUnixFileDescriptor descriptor;
+ descriptor.giveFileDescriptor(fd);
+ QDBusMessage message = QDBusMessage::createMethodCall(QLatin1String("org.freedesktop.portal.Desktop"),
+ QLatin1String("/org/freedesktop/portal/desktop"),
+ QLatin1String("org.freedesktop.portal.OpenURI"),
+ QLatin1String("OpenDirectory"));
+ message << QString() << QVariant::fromValue(descriptor) << QVariantMap();
+
+ message = QDBusConnection::sessionBus().call(message);
+ success = message.type() == QDBusMessage::ReplyMessage;
+ ws_close(fd);
+ }
}
#else
- // Is there a way to highlight the file using xdg-open?
+ // Any other possibilities to highlight the file before falling back to showing the folder?
#endif
if (!success) {
QFileInfo file_info(file_path);
@@ -251,7 +283,7 @@ bool rect_on_screen(const QRect &rect)
void set_action_shortcuts_visible_in_context_menu(QList<QAction *> actions)
{
-#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) && QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
+#if QT_VERSION < QT_VERSION_CHECK(5, 13, 0)
// For QT_VERSION >= 5.13.0 we call styleHints()->setShowShortcutsInContextMenus(true)
// in WiresharkApplication.
// QTBUG-71471
@@ -310,27 +342,7 @@ QString openDialogInitialDir()
{
QString result;
- switch (prefs.gui_fileopen_style) {
-
- case FO_STYLE_LAST_OPENED:
- /* The user has specified that we should start out in the last directory
- we looked in. If we've already opened a file, use its containing
- directory, if we could determine it, as the directory, otherwise
- use the "last opened" directory saved in the preferences file if
- there was one. */
- /* This is now the default behaviour in file_selection_new() */
- result = QString(get_open_dialog_initial_dir());
- break;
-
- case FO_STYLE_SPECIFIED:
- /* The user has specified that we should always start out in a
- specified directory; if they've specified that directory,
- start out by showing the files in that dir. */
- if (prefs.gui_fileopen_dir[0] != '\0')
- result = QString(prefs.gui_fileopen_dir);
- break;
- }
-
+ result = QString(get_open_dialog_initial_dir());
QDir ld(result);
if (ld.exists())
return result;
diff --git a/ui/qt/utils/qt_ui_utils.h b/ui/qt/utils/qt_ui_utils.h
index 60ccf31d..24888b03 100644
--- a/ui/qt/utils/qt_ui_utils.h
+++ b/ui/qt/utils/qt_ui_utils.h
@@ -61,7 +61,7 @@ struct epan_range;
*
* @return A copy of the QString. UTF-8 allocated with g_malloc().
*/
-gchar *qstring_strdup(QString q_string);
+char *qstring_strdup(QString q_string);
/** Transfer ownership of a GLib character string to a newly constructed QString
*
@@ -70,7 +70,7 @@ gchar *qstring_strdup(QString q_string);
*
* @return A QString instance created from the input string.
*/
-QString gchar_free_to_qstring(gchar *glib_string);
+QString gchar_free_to_qstring(char *glib_string);
/** Transfer ownership of a GLib character string to a newly constructed QString
*
@@ -79,7 +79,7 @@ QString gchar_free_to_qstring(gchar *glib_string);
*
* @return A QByteArray instance created from the input string.
*/
-QByteArray gchar_free_to_qbytearray(gchar *glib_string);
+QByteArray gchar_free_to_qbytearray(char *glib_string);
/** Transfer ownership of a GLib character string to a newly constructed QByteArray
*
@@ -133,7 +133,7 @@ const QString address_to_display_qstring(const struct _address *address);
*
* @return A QString representation of the value_string.
*/
-const QString val_to_qstring(const guint32 val, const struct _value_string *vs, const char *fmt)
+const QString val_to_qstring(const uint32_t val, const struct _value_string *vs, const char *fmt)
G_GNUC_PRINTF(3, 0);
/** Convert a value_string_ext to a QString using val_to_str_ext_wmem().
@@ -144,7 +144,7 @@ G_GNUC_PRINTF(3, 0);
*
* @return A QString representation of the value_string_ext.
*/
-const QString val_ext_to_qstring(const guint32 val, struct _value_string_ext *vse, const char *fmt)
+const QString val_ext_to_qstring(const uint32_t val, struct _value_string_ext *vse, const char *fmt)
G_GNUC_PRINTF(3, 0);
/** Convert a range to a QString using range_convert_range().
@@ -169,7 +169,7 @@ const QString bits_s_to_qstring(const double bits_s);
*
* @return A QString representation of the file size in SI units.
*/
-const QString file_size_to_qstring(const gint64 size);
+const QString file_size_to_qstring(const int64_t size);
/** Convert a time_t value to a human-readable QString using QDateTime.
*
diff --git a/ui/qt/utils/rtp_audio_file.cpp b/ui/qt/utils/rtp_audio_file.cpp
index 591a63bb..8b349182 100644
--- a/ui/qt/utils/rtp_audio_file.cpp
+++ b/ui/qt/utils/rtp_audio_file.cpp
@@ -14,7 +14,7 @@
* File uses Frame as piece of information. One Frame match audio of one
* decoded packet or audio silence in between them. Frame holds information
* about frame type (audio/silence), its length and realtime position and
- * sample possition (where decoded audio is really stored, with gaps omitted).
+ * sample position (where decoded audio is really stored, with gaps omitted).
*
* There are three stages of the object use
* - writing data by frames during decoding of the stream
@@ -124,7 +124,7 @@ void RtpAudioFile::frameUpdateSampleCounters(qint64 written_bytes)
sample_pos_ += written_bytes;
}
-qint64 RtpAudioFile::frameWriteFrame(guint32 frame_num, qint64 real_pos, qint64 sample_pos, qint64 len, rtp_frame_type type)
+qint64 RtpAudioFile::frameWriteFrame(uint32_t frame_num, qint64 real_pos, qint64 sample_pos, qint64 len, rtp_frame_type type)
{
rtp_frame_info frame_info;
@@ -137,7 +137,7 @@ qint64 RtpAudioFile::frameWriteFrame(guint32 frame_num, qint64 real_pos, qint64
return sample_file_frame_->write((char *)&frame_info, sizeof(frame_info));
}
-void RtpAudioFile::frameWriteSilence(guint32 frame_num, qint64 samples)
+void RtpAudioFile::frameWriteSilence(uint32_t frame_num, qint64 samples)
{
if (samples < 1) return;
@@ -147,9 +147,9 @@ void RtpAudioFile::frameWriteSilence(guint32 frame_num, qint64 samples)
frameUpdateRealCounters(silence_bytes);
}
-qint64 RtpAudioFile::frameWriteSamples(guint32 frame_num, const char *data, qint64 max_size)
+qint64 RtpAudioFile::frameWriteSamples(uint32_t frame_num, const char *data, qint64 max_size)
{
- gint64 written;
+ int64_t written;
written = sample_file_->write(data, max_size);
@@ -170,15 +170,15 @@ void RtpAudioFile::setFrameReadStage(qint64 prepend_samples)
{
sample_file_frame_->seek(0);
if (prepend_samples > 0) {
- // Skip first frame which contains openning silence
+ // Skip first frame which contains opening silence
sample_file_frame_->read((char *)&cur_frame_, sizeof(cur_frame_));
}
}
-bool RtpAudioFile::readFrameSamples(gint32 *read_buff_bytes, SAMPLE **read_buff, spx_uint32_t *read_len, guint32 *frame_num, rtp_frame_type *type)
+bool RtpAudioFile::readFrameSamples(int32_t *read_buff_bytes, SAMPLE **read_buff, spx_uint32_t *read_len, uint32_t *frame_num, rtp_frame_type *type)
{
rtp_frame_info frame_info;
- guint64 read_bytes = 0;
+ uint64_t read_bytes = 0;
if (!sample_file_frame_->read((char *)&frame_info, sizeof(frame_info))) {
// Can't read frame, some error occurred
diff --git a/ui/qt/utils/rtp_audio_file.h b/ui/qt/utils/rtp_audio_file.h
index addc3015..b8c53b30 100644
--- a/ui/qt/utils/rtp_audio_file.h
+++ b/ui/qt/utils/rtp_audio_file.h
@@ -33,7 +33,7 @@ typedef struct {
qint64 real_pos;
qint64 sample_pos;
qint64 len;
- guint32 frame_num;
+ uint32_t frame_num;
rtp_frame_type type;
} rtp_frame_info;
@@ -46,12 +46,12 @@ public:
// Functions for writing Frames
void setFrameWriteStage();
- void frameWriteSilence(guint32 frame_num, qint64 samples);
- qint64 frameWriteSamples(guint32 frame_num, const char *data, qint64 max_size);
+ void frameWriteSilence(uint32_t frame_num, qint64 samples);
+ qint64 frameWriteSamples(uint32_t frame_num, const char *data, qint64 max_size);
// Functions for reading Frames
void setFrameReadStage(qint64 prepend_samples);
- bool readFrameSamples(gint32 *read_buff_bytes, SAMPLE **read_buff, spx_uint32_t *read_len, guint32 *frame_num, rtp_frame_type *type);
+ bool readFrameSamples(int32_t *read_buff_bytes, SAMPLE **read_buff, spx_uint32_t *read_len, uint32_t *frame_num, rtp_frame_type *type);
// Functions for reading data during play
void setDataReadStage();
@@ -80,7 +80,7 @@ private:
rtp_frame_info cur_frame_;
// Functions for writing Frames
- qint64 frameWriteFrame(guint32 frame_num, qint64 real_pos, qint64 sample_pos, qint64 len, rtp_frame_type type);
+ qint64 frameWriteFrame(uint32_t frame_num, qint64 real_pos, qint64 sample_pos, qint64 len, rtp_frame_type type);
void frameUpdateRealCounters(qint64 written_bytes);
void frameUpdateSampleCounters(qint64 written_bytes);
diff --git a/ui/qt/utils/rtp_audio_routing_filter.cpp b/ui/qt/utils/rtp_audio_routing_filter.cpp
index 8362d3f9..fd2b48d7 100644
--- a/ui/qt/utils/rtp_audio_routing_filter.cpp
+++ b/ui/qt/utils/rtp_audio_routing_filter.cpp
@@ -64,7 +64,7 @@ qint64 AudioRoutingFilter::readData(char *data, qint64 maxSize)
return input_->read(data, maxSize);
} else {
// For stereo
- gint64 silence = 0;
+ int64_t silence = 0;
// Read half of data
qint64 readBytes = input_->read(data, maxSize/SAMPLE_BYTES);
diff --git a/ui/qt/utils/wireshark_zip_helper.cpp b/ui/qt/utils/wireshark_zip_helper.cpp
index 7bfa0101..bcf670ad 100644
--- a/ui/qt/utils/wireshark_zip_helper.cpp
+++ b/ui/qt/utils/wireshark_zip_helper.cpp
@@ -11,17 +11,18 @@
#include <ui/qt/utils/wireshark_zip_helper.h>
-#ifdef HAVE_MINIZIP
+#if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG)
#include "config.h"
-#include "glib.h"
-
#include <iosfwd>
#include <iostream>
#include <zlib.h> // For Z_DEFLATED, etc.
+#ifdef HAVE_MINIZIP
#include <minizip/unzip.h>
#include <minizip/zip.h>
-
+#else
+#include <minizip-ng/mz_compat.h>
+#endif
#include "epan/prefs.h"
#include "wsutil/file_util.h"
diff --git a/ui/qt/utils/wireshark_zip_helper.h b/ui/qt/utils/wireshark_zip_helper.h
index 2f8e39f8..7845f70a 100644
--- a/ui/qt/utils/wireshark_zip_helper.h
+++ b/ui/qt/utils/wireshark_zip_helper.h
@@ -16,9 +16,13 @@
#include <QDir>
-#ifdef HAVE_MINIZIP
+#if defined(HAVE_MINIZIP) || defined(HAVE_MINIZIPNG)
+#ifdef HAVE_MINIZIP
#include "minizip/zip.h"
+#else
+#include "minizip-ng/mz_compat.h"
+#endif
class WiresharkZipHelper
{
diff --git a/ui/qt/voip_calls_dialog.cpp b/ui/qt/voip_calls_dialog.cpp
index b8a54bd7..a76b8222 100644
--- a/ui/qt/voip_calls_dialog.cpp
+++ b/ui/qt/voip_calls_dialog.cpp
@@ -378,7 +378,7 @@ void VoipCallsDialog::tapDraw(void *tapinfo_ptr)
}
}
-gint VoipCallsDialog::compareCallNums(gconstpointer a, gconstpointer b)
+int VoipCallsDialog::compareCallNums(const void *a, const void *b)
{
const voip_calls_info_t *call_a = (const voip_calls_info_t *)a;
const voip_calls_info_t *call_b = (const voip_calls_info_t *)b;
@@ -459,7 +459,7 @@ void VoipCallsDialog::prepareFilter()
}
QString filter_str;
- QSet<guint16> selected_calls;
+ QSet<uint16_t> selected_calls;
QString frame_numbers;
QList<int> rows;
@@ -509,7 +509,7 @@ void VoipCallsDialog::prepareFilter()
filter_string_fwd = g_string_new(filter_prepend);
g_string_append_printf(filter_string_fwd, "(");
- is_first = TRUE;
+ is_first = true;
/* Build a new filter based on protocol fields */
lista = g_queue_peek_nth_link(voip_calls_get_info()->callsinfos, 0);
while (lista) {
@@ -542,10 +542,10 @@ void VoipCallsDialog::prepareFilter()
g_string_append_printf(filter_string_fwd,
"((h225.guid == %s || q931.call_ref == %x:%x || q931.call_ref == %x:%x)",
guid_str,
- (guint8) (h323info->q931_crv & 0x00ff),
- (guint8)((h323info->q931_crv & 0xff00)>>8),
- (guint8) (h323info->q931_crv2 & 0x00ff),
- (guint8)((h323info->q931_crv2 & 0xff00)>>8));
+ (uint8_t) (h323info->q931_crv & 0x00ff),
+ (uint8_t)((h323info->q931_crv & 0xff00)>>8),
+ (uint8_t) (h323info->q931_crv2 & 0x00ff),
+ (uint8_t)((h323info->q931_crv2 & 0xff00)>>8));
listb = g_list_first(h323info->h245_list);
wmem_free(NULL, guid_str);
while (listb) {
@@ -569,7 +569,7 @@ void VoipCallsDialog::prepareFilter()
"(frame)");
break;
}
- is_first = FALSE;
+ is_first = false;
}
lista = gxx_list_next(lista);
}
@@ -586,7 +586,7 @@ void VoipCallsDialog::showSequence()
{
if (file_closed_) return;
- QSet<guint16> selected_calls;
+ QSet<uint16_t> selected_calls;
foreach (QModelIndex index, ui->callTreeView->selectionModel()->selectedIndexes()) {
voip_calls_info_t *call_info = VoipCallsInfoModel::indexToCallInfo(index);
if (!call_info) {
@@ -603,7 +603,7 @@ void VoipCallsDialog::showSequence()
cur_ga_item = gxx_list_next(cur_ga_item);
}
- SequenceDialog *sequence_dialog = new SequenceDialog(parent_, cap_file_, sequence_info_);
+ SequenceDialog *sequence_dialog = new SequenceDialog(parent_, cap_file_, sequence_info_, true);
// Bypass this dialog and forward signals to parent
connect(sequence_dialog, SIGNAL(rtpStreamsDialogSelectRtpStreams(QVector<rtpstream_id_t *>)), &parent_, SLOT(rtpStreamsDialogSelectRtpStreams(QVector<rtpstream_id_t *>)));
connect(sequence_dialog, SIGNAL(rtpStreamsDialogDeselectRtpStreams(QVector<rtpstream_id_t *>)), &parent_, SLOT(rtpStreamsDialogDeselectRtpStreams(QVector<rtpstream_id_t *>)));
@@ -612,7 +612,6 @@ void VoipCallsDialog::showSequence()
connect(sequence_dialog, SIGNAL(rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_id_t *>)), &parent_, SLOT(rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_id_t *>)));
sequence_dialog->setAttribute(Qt::WA_DeleteOnClose);
- sequence_dialog->enableVoIPFeatures();
sequence_dialog->show();
}
@@ -630,7 +629,7 @@ QVector<rtpstream_id_t *>VoipCallsDialog::getSelectedRtpIds()
//VOIP_CALLS_DEBUG("checking call %u, start frame %u == stream call %u, start frame %u, setup frame %u",
// vci->call_num, vci->start_fd->num,
// rsi->call_num, rsi->start_fd->num, rsi->setup_frame_number);
- if (vci->call_num == static_cast<guint>(rsi->call_num)) {
+ if (vci->call_num == static_cast<unsigned>(rsi->call_num)) {
//VOIP_CALLS_DEBUG("adding call number %u", vci->call_num);
if (-1 == stream_ids.indexOf(&(rsi->id))) {
// Add only new stream
diff --git a/ui/qt/voip_calls_dialog.h b/ui/qt/voip_calls_dialog.h
index 0386dfa7..542fab9d 100644
--- a/ui/qt/voip_calls_dialog.h
+++ b/ui/qt/voip_calls_dialog.h
@@ -12,7 +12,6 @@
#include <config.h>
-#include <glib.h>
#include <mutex>
#include "cfile.h"
@@ -110,7 +109,7 @@ private:
static void tapReset(void *tapinfo_ptr);
static tap_packet_status tapPacket(void *tapinfo_ptr, packet_info *pinfo, epan_dissect_t *, const void *data, tap_flags_t flags);
static void tapDraw(void *tapinfo_ptr);
- static gint compareCallNums(gconstpointer a, gconstpointer b);
+ static int compareCallNums(const void *a, const void *b);
void updateCalls();
void prepareFilter();
diff --git a/ui/qt/welcome_page.cpp b/ui/qt/welcome_page.cpp
index ac37a6d9..1297944c 100644
--- a/ui/qt/welcome_page.cpp
+++ b/ui/qt/welcome_page.cpp
@@ -9,13 +9,12 @@
#include "config.h"
-#include <glib.h>
-
#include <epan/prefs.h>
#include "ui/capture_globals.h"
#include "ui/urls.h"
+#include "wsutil/filesystem.h"
#include "wsutil/version_info.h"
#include "welcome_page.h"
@@ -72,24 +71,28 @@ WelcomePage::WelcomePage(QWidget *parent) :
recent_files_->setTextElideMode(Qt::ElideLeft);
welcome_ui_->recentList->setContextMenuPolicy(Qt::CustomContextMenu);
- connect(recent_files_, SIGNAL(customContextMenuRequested(QPoint)),
- this, SLOT(showRecentContextMenu(QPoint)));
-
- connect(mainApp, SIGNAL(updateRecentCaptureStatus(const QString &, qint64, bool)), this, SLOT(updateRecentCaptures()));
- connect(mainApp, SIGNAL(appInitialized()), this, SLOT(appInitialized()));
- connect(mainApp, SIGNAL(localInterfaceListChanged()), this, SLOT(interfaceListChanged()));
- connect(welcome_ui_->interfaceFrame, SIGNAL(itemSelectionChanged()),
- welcome_ui_->captureFilterComboBox, SIGNAL(interfacesChanged()));
- connect(welcome_ui_->interfaceFrame, SIGNAL(typeSelectionChanged()),
- this, SLOT(interfaceListChanged()));
- connect(welcome_ui_->interfaceFrame, SIGNAL(itemSelectionChanged()), this, SLOT(interfaceSelected()));
- connect(welcome_ui_->captureFilterComboBox->lineEdit(), SIGNAL(textEdited(QString)),
- this, SLOT(captureFilterTextEdited(QString)));
- connect(welcome_ui_->captureFilterComboBox, SIGNAL(captureFilterSyntaxChanged(bool)),
- this, SIGNAL(captureFilterSyntaxChanged(bool)));
- connect(welcome_ui_->captureFilterComboBox, SIGNAL(startCapture()),
- this, SLOT(captureStarting()));
- connect(recent_files_, SIGNAL(itemActivated(QListWidgetItem *)), this, SLOT(openRecentItem(QListWidgetItem *)));
+ connect(recent_files_, &QListWidget::customContextMenuRequested, this, &WelcomePage::showRecentContextMenu);
+
+ connect(mainApp, &MainApplication::updateRecentCaptureStatus, this, &WelcomePage::updateRecentCaptures);
+ connect(mainApp, &MainApplication::preferencesChanged, this, &WelcomePage::updateRecentCaptures);
+ connect(mainApp, &MainApplication::appInitialized, this, &WelcomePage::appInitialized);
+ connect(mainApp, &MainApplication::localInterfaceListChanged, this, &WelcomePage::interfaceListChanged);
+#ifdef HAVE_LIBPCAP
+ connect(mainApp, &MainApplication::scanLocalInterfaces,
+ welcome_ui_->interfaceFrame, &InterfaceFrame::scanLocalInterfaces);
+#endif
+ connect(welcome_ui_->interfaceFrame, &InterfaceFrame::itemSelectionChanged,
+ welcome_ui_->captureFilterComboBox, &CaptureFilterCombo::interfacesChanged);
+ connect(welcome_ui_->interfaceFrame, &InterfaceFrame::typeSelectionChanged,
+ this, &WelcomePage::interfaceListChanged);
+ connect(welcome_ui_->interfaceFrame, &InterfaceFrame::itemSelectionChanged, this, &WelcomePage::interfaceSelected);
+ connect(welcome_ui_->captureFilterComboBox->lineEdit(), &QLineEdit::textEdited,
+ this, &WelcomePage::captureFilterTextEdited);
+ connect(welcome_ui_->captureFilterComboBox, &CaptureFilterCombo::captureFilterSyntaxChanged,
+ this, &WelcomePage::captureFilterSyntaxChanged);
+ connect(welcome_ui_->captureFilterComboBox, &CaptureFilterCombo::startCapture,
+ this, &WelcomePage::captureStarting);
+ connect(recent_files_, &QListWidget::itemActivated, this, &WelcomePage::openRecentItem);
updateRecentCaptures();
splash_overlay_ = new SplashOverlay(this);
@@ -136,11 +139,19 @@ void WelcomePage::setReleaseLabel()
QString full_release;
QDate today = QDate::currentDate();
if ((today.month() == 4 && today.day() == 1) || (today.month() == 7 && today.day() == 14)) {
- full_release = tr("You are sniffing the glue that holds the Internet together using Wireshark ");
+ if (is_packet_configuration_namespace()) {
+ full_release = tr("You are sniffing the glue that holds the Internet together using Wireshark ");
+ } else {
+ full_release = tr("You are sniffing the glue that holds your system together using Logray ");
+ }
} else {
- full_release = tr("You are running Wireshark ");
+ if (is_packet_configuration_namespace()) {
+ full_release = tr("You are running Wireshark ");
+ } else {
+ full_release = tr("You are running Logray ");
+ }
}
- full_release += get_ws_vcs_version_info();
+ full_release += is_packet_configuration_namespace() ? get_ws_vcs_version_info() : get_lr_vcs_version_info();
full_release += ".";
#ifdef HAVE_SOFTWARE_UPDATE
if (prefs.gui_update_enabled) {
@@ -184,7 +195,7 @@ void WelcomePage::captureFilterTextEdited(const QString capture_filter)
if (global_capture_opts.num_selected > 0) {
interface_t *device;
- for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+ for (unsigned i = 0; i < global_capture_opts.all_ifaces->len; i++) {
device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
if (!device->selected) {
continue;
@@ -272,7 +283,7 @@ void WelcomePage::updateRecentCaptures() {
selectedFilename = rfItem->data(Qt::UserRole).toString();
}
- if (mainApp->recentItems().count() == 0) {
+ if (mainApp->recentItems().count() == 0 || prefs.gui_welcome_page_show_recent) {
// Recent menu has been cleared, remove all recent files.
while (recent_files_->count()) {
delete recent_files_->item(0);
@@ -280,39 +291,41 @@ void WelcomePage::updateRecentCaptures() {
}
int rfRow = 0;
- foreach (recent_item_status *ri, mainApp->recentItems()) {
- itemLabel = ri->filename;
+ if(prefs.gui_welcome_page_show_recent) {
+ foreach (recent_item_status *ri, mainApp->recentItems()) {
+ itemLabel = ri->filename;
- if (rfRow >= recent_files_->count()) {
- recent_files_->addItem(itemLabel);
- }
+ if (rfRow >= recent_files_->count()) {
+ recent_files_->addItem(itemLabel);
+ }
- itemLabel.append(" (");
- if (ri->accessible) {
- if (ri->size/1024/1024/1024 > 10) {
- itemLabel.append(QString("%1 GB").arg(ri->size/1024/1024/1024));
- } else if (ri->size/1024/1024 > 10) {
- itemLabel.append(QString("%1 MB").arg(ri->size/1024/1024));
- } else if (ri->size/1024 > 10) {
- itemLabel.append(QString("%1 KB").arg(ri->size/1024));
+ itemLabel.append(" (");
+ if (ri->accessible) {
+ if (ri->size/1024/1024/1024 > 10) {
+ itemLabel.append(QString("%1 GB").arg(ri->size/1024/1024/1024));
+ } else if (ri->size/1024/1024 > 10) {
+ itemLabel.append(QString("%1 MB").arg(ri->size/1024/1024));
+ } else if (ri->size/1024 > 10) {
+ itemLabel.append(QString("%1 KB").arg(ri->size/1024));
+ } else {
+ itemLabel.append(QString("%1 Bytes").arg(ri->size));
+ }
} else {
- itemLabel.append(QString("%1 Bytes").arg(ri->size));
+ itemLabel.append(tr("not found"));
}
- } else {
- itemLabel.append(tr("not found"));
- }
- itemLabel.append(")");
- rfFont.setItalic(!ri->accessible);
- rfItem = recent_files_->item(rfRow);
- rfItem->setText(itemLabel);
- rfItem->setData(Qt::AccessibleTextRole, itemLabel);
- rfItem->setData(Qt::UserRole, ri->filename);
- rfItem->setFlags(ri->accessible ? Qt::ItemIsSelectable | Qt::ItemIsEnabled : Qt::NoItemFlags);
- rfItem->setFont(rfFont);
- if (ri->filename == selectedFilename) {
- rfItem->setSelected(true);
+ itemLabel.append(")");
+ rfFont.setItalic(!ri->accessible);
+ rfItem = recent_files_->item(rfRow);
+ rfItem->setText(itemLabel);
+ rfItem->setData(Qt::AccessibleTextRole, itemLabel);
+ rfItem->setData(Qt::UserRole, ri->filename);
+ rfItem->setFlags(ri->accessible ? Qt::ItemIsSelectable | Qt::ItemIsEnabled : Qt::NoItemFlags);
+ rfItem->setFont(rfFont);
+ if (ri->filename == selectedFilename) {
+ rfItem->setSelected(true);
+ }
+ rfRow++;
}
- rfRow++;
}
int row = recent_files_->count();
@@ -378,17 +391,17 @@ void WelcomePage::showRecentContextMenu(QPoint pos)
QAction *show_action = recent_ctx_menu->addAction(show_in_str_);
show_action->setData(cf_path);
- connect(show_action, SIGNAL(triggered(bool)), this, SLOT(showRecentFolder()));
+ connect(show_action, &QAction::triggered, this, &WelcomePage::showRecentFolder);
QAction *copy_action = recent_ctx_menu->addAction(tr("Copy file path"));
copy_action->setData(cf_path);
- connect(copy_action, SIGNAL(triggered(bool)), this, SLOT(copyRecentPath()));
+ connect(copy_action, &QAction::triggered, this, &WelcomePage::copyRecentPath);
recent_ctx_menu->addSeparator();
QAction *remove_action = recent_ctx_menu->addAction(tr("Remove from list"));
remove_action->setData(cf_path);
- connect(remove_action, SIGNAL(triggered(bool)), this, SLOT(removeRecentPath()));
+ connect(remove_action, &QAction::triggered, this, &WelcomePage::removeRecentPath);
recent_ctx_menu->popup(recent_files_->mapToGlobal(pos));
}
diff --git a/ui/qt/welcome_page.h b/ui/qt/welcome_page.h
index d6243d1a..382d4aa4 100644
--- a/ui/qt/welcome_page.h
+++ b/ui/qt/welcome_page.h
@@ -58,7 +58,7 @@ private:
QListWidget *recent_files_;
signals:
- void startCapture(QStringList);
+ void startCapture(QStringList ifaces);
void recentFileActivated(QString cfile);
void captureFilterSyntaxChanged(bool valid);
void showExtcapOptions(QString &device_name, bool startCaptureOnClose);
diff --git a/ui/qt/welcome_page.ui b/ui/qt/welcome_page.ui
index afc50f5e..d1a0c4f7 100644
--- a/ui/qt/welcome_page.ui
+++ b/ui/qt/welcome_page.ui
@@ -304,6 +304,9 @@ a:hover {
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
</property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
</widget>
</item>
<item>
diff --git a/ui/qt/widgets/additional_toolbar.cpp b/ui/qt/widgets/additional_toolbar.cpp
index c023d149..43eab273 100644
--- a/ui/qt/widgets/additional_toolbar.cpp
+++ b/ui/qt/widgets/additional_toolbar.cpp
@@ -9,8 +9,6 @@
#include <config.h>
-#include <glib.h>
-
#include <ui/qt/widgets/additional_toolbar.h>
#include <ui/qt/widgets/apply_line_edit.h>
#include <ui/qt/utils/qt_ui_utils.h>
@@ -159,7 +157,7 @@ QWidget * AdditionalToolbarWidgetAction::createWidget(QWidget * parent)
}
static void
-toolbar_button_cb(gpointer item, gpointer item_data, gpointer user_data)
+toolbar_button_cb(void *item, void *item_data, void *user_data)
{
if (! item || ! item_data || ! user_data)
return;
@@ -170,7 +168,7 @@ toolbar_button_cb(gpointer item, gpointer item_data, gpointer user_data)
if (widget)
{
if (update_entry->type == EXT_TOOLBAR_UPDATE_VALUE)
- widget->setText((gchar *)update_entry->user_data);
+ widget->setText((char *)update_entry->user_data);
else if (update_entry->type == EXT_TOOLBAR_SET_ACTIVE)
{
bool enableState = GPOINTER_TO_INT(update_entry->user_data) == 1;
@@ -195,7 +193,7 @@ QWidget * AdditionalToolbarWidgetAction::createButton(ext_toolbar_t * item, QWid
}
static void
-toolbar_boolean_cb(gpointer item, gpointer item_data, gpointer user_data)
+toolbar_boolean_cb(void *item, void *item_data, void *user_data)
{
if (! item || ! item_data || ! user_data)
return;
@@ -267,7 +265,7 @@ QWidget * AdditionalToolbarWidgetAction::createLabelFrame(ext_toolbar_t * item,
}
static void
-toolbar_string_cb(gpointer item, gpointer item_data, gpointer user_data)
+toolbar_string_cb(void *item, void *item_data, void *user_data)
{
if (! item || ! item_data || ! user_data)
return;
@@ -282,7 +280,7 @@ toolbar_string_cb(gpointer item, gpointer item_data, gpointer user_data)
if (update_entry->silent)
oldState = edit->blockSignals(true);
- edit->setText((gchar *)update_entry->user_data);
+ edit->setText((char *)update_entry->user_data);
if (update_entry->silent)
edit->blockSignals(oldState);
@@ -321,7 +319,7 @@ QWidget * AdditionalToolbarWidgetAction::createTextEditor(ext_toolbar_t * item,
}
static void
-toolbar_selector_cb(gpointer item, gpointer item_data, gpointer user_data)
+toolbar_selector_cb(void *item, void *item_data, void *user_data)
{
if (! item || ! item_data || ! user_data)
return;
@@ -346,7 +344,7 @@ toolbar_selector_cb(gpointer item, gpointer item_data, gpointer user_data)
if (update_entry->type == EXT_TOOLBAR_UPDATE_VALUE)
{
- QString data = QString((gchar *)update_entry->user_data);
+ QString data = QString((char *)update_entry->user_data);
for (int i = 0; i < sourceModel->rowCount(); i++)
{
@@ -385,8 +383,8 @@ toolbar_selector_cb(gpointer item, gpointer item_data, gpointer user_data)
if (! update_entry->data_index)
return;
- gchar * idx = (gchar *)update_entry->data_index;
- gchar * display = (gchar *)update_entry->user_data;
+ char * idx = (char *)update_entry->data_index;
+ char * display = (char *)update_entry->user_data;
if (update_entry->type == EXT_TOOLBAR_UPDATE_DATABYINDEX)
{
@@ -522,7 +520,7 @@ void AdditionalToolbarWidgetAction::onCheckBoxChecked(int checkState)
if (! item)
return;
- gboolean value = checkState == Qt::Checked ? true : false;
+ bool value = checkState == Qt::Checked ? true : false;
item->callback(item, &value, item->user_data);
}
@@ -539,7 +537,7 @@ void AdditionalToolbarWidgetAction::sendTextToCallback()
ApplyLineEdit * editor = dynamic_cast<ApplyLineEdit *>(sender());
if (! editor)
{
- /* Called from button, searching for acompanying line edit */
+ /* Called from button, searching for accompanying line edit */
QWidget * parent = dynamic_cast<QWidget *>(sender()->parent());
if (parent)
{
diff --git a/ui/qt/widgets/byte_view_text.cpp b/ui/qt/widgets/byte_view_text.cpp
index e81dc0ac..ee1e0195 100644
--- a/ui/qt/widgets/byte_view_text.cpp
+++ b/ui/qt/widgets/byte_view_text.cpp
@@ -70,6 +70,7 @@ ByteViewText::ByteViewText(const QByteArray &data, packet_char_enc encoding, QWi
offset_normal_fg_ = ColorUtils::alphaBlend(palette().windowText(), palette().window(), 0.35);
offset_field_fg_ = ColorUtils::alphaBlend(palette().windowText(), palette().window(), 0.65);
+ ctx_menu_.setToolTipsVisible(true);
window()->winId(); // Required for screenChanged? https://phabricator.kde.org/D20171
connect(window()->windowHandle(), &QWindow::screenChanged, viewport(), [=](const QScreen *) { viewport()->update(); });
@@ -407,11 +408,7 @@ void ByteViewText::updateLayoutMetrics()
int ByteViewText::stringWidth(const QString &line)
{
-#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0))
return viewport()->fontMetrics().horizontalAdvance(line);
-#else
- return viewport()->fontMetrics().boundingRect(line).width();
-#endif
}
// Draw a line of byte view text for a given offset.
diff --git a/ui/qt/widgets/capture_filter_combo.cpp b/ui/qt/widgets/capture_filter_combo.cpp
index 70635cef..95766310 100644
--- a/ui/qt/widgets/capture_filter_combo.cpp
+++ b/ui/qt/widgets/capture_filter_combo.cpp
@@ -126,7 +126,7 @@ void CaptureFilterCombo::rebuildFilterList()
QString cur_filter = currentText();
clear();
for (GList *li = g_list_first(cfilter_list); li != NULL; li = gxx_list_next(li)) {
- addItem(gxx_list_data(const gchar *, li));
+ addItem(gxx_list_data(const char *, li));
}
lineEdit()->setText(cur_filter);
lineEdit()->blockSignals(false);
diff --git a/ui/qt/widgets/capture_filter_edit.cpp b/ui/qt/widgets/capture_filter_edit.cpp
index 3c72fe41..50793143 100644
--- a/ui/qt/widgets/capture_filter_edit.cpp
+++ b/ui/qt/widgets/capture_filter_edit.cpp
@@ -9,8 +9,6 @@
#include "config.h"
-#include <glib.h>
-
#include <epan/proto.h>
#include "capture_opts.h"
@@ -308,7 +306,7 @@ QPair<const QString, bool> CaptureFilterEdit::getSelectedFilter()
#ifdef HAVE_LIBPCAP
int selected_devices = 0;
- for (guint i = 0; i < global_capture_opts.all_ifaces->len; i++) {
+ for (unsigned i = 0; i < global_capture_opts.all_ifaces->len; i++) {
interface_t *device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
if (device->selected) {
selected_devices++;
diff --git a/ui/qt/widgets/compression_group_box.cpp b/ui/qt/widgets/compression_group_box.cpp
new file mode 100644
index 00000000..08a74dae
--- /dev/null
+++ b/ui/qt/widgets/compression_group_box.cpp
@@ -0,0 +1,69 @@
+/* @file
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "compression_group_box.h"
+
+#include <QRadioButton>
+#include <QButtonGroup>
+#include <QVBoxLayout>
+
+CompressionGroupBox::CompressionGroupBox(QWidget *parent) :
+ QGroupBox(parent)
+{
+ setTitle(tr("Compression options"));
+ setFlat(true);
+
+
+ bg_ = new QButtonGroup(this);
+ QVBoxLayout *vbox = new QVBoxLayout();
+
+ QRadioButton *radio1 = new QRadioButton(tr("&Uncompressed"));
+ bg_->addButton(radio1, WTAP_UNCOMPRESSED);
+ vbox->addWidget(radio1);
+
+#if defined (HAVE_ZLIB) || defined (HAVE_ZLIBNG)
+ QRadioButton *radio2 = new QRadioButton(tr("Compress with g&zip"));
+ bg_->addButton(radio2, WTAP_GZIP_COMPRESSED);
+ vbox->addWidget(radio2);
+#endif
+#ifdef HAVE_LZ4FRAME_H
+ QRadioButton *radio3 = new QRadioButton(tr("Compress with &LZ4"));
+ bg_->addButton(radio3, WTAP_LZ4_COMPRESSED);
+ vbox->addWidget(radio3);
+#endif
+
+ radio1->setChecked(true);
+
+ setLayout(vbox);
+
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
+ connect(bg_, &QButtonGroup::idToggled, [=] { emit stateChanged(); });
+#else
+ connect(bg_, QOverload<int, bool>::of(&QButtonGroup::buttonToggled), [=] { emit stateChanged(); });
+#endif
+
+}
+
+CompressionGroupBox::~CompressionGroupBox()
+{
+}
+
+wtap_compression_type CompressionGroupBox::compressionType() const
+{
+ return static_cast<wtap_compression_type>(bg_->checkedId());
+}
+
+void CompressionGroupBox::setCompressionType(wtap_compression_type type)
+{
+ QAbstractButton *button = bg_->button(type);
+ if (button != nullptr) {
+ button->setChecked(true);
+ }
+}
+
diff --git a/ui/qt/widgets/compression_group_box.h b/ui/qt/widgets/compression_group_box.h
new file mode 100644
index 00000000..4e70ca2d
--- /dev/null
+++ b/ui/qt/widgets/compression_group_box.h
@@ -0,0 +1,41 @@
+/** @file
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef COMPRESSION_GROUP_BOX_H
+#define COMPRESSION_GROUP_BOX_H
+
+#include <config.h>
+
+#include <QGroupBox>
+
+#include <wiretap/wtap.h>
+
+class QButtonGroup;
+
+/**
+ * UI element for selecting compression type from among those supported.
+ */
+class CompressionGroupBox : public QGroupBox
+{
+ Q_OBJECT
+
+public:
+ explicit CompressionGroupBox(QWidget *parent = 0);
+ ~CompressionGroupBox();
+ wtap_compression_type compressionType() const;
+ void setCompressionType(wtap_compression_type type);
+
+signals:
+ void stateChanged();
+
+private:
+ QButtonGroup *bg_;
+};
+
+#endif // COMPRESSION_GROUP_BOX_H
diff --git a/ui/qt/widgets/copy_from_profile_button.h b/ui/qt/widgets/copy_from_profile_button.h
index f074bdb8..ea6df816 100644
--- a/ui/qt/widgets/copy_from_profile_button.h
+++ b/ui/qt/widgets/copy_from_profile_button.h
@@ -11,7 +11,6 @@
#define COPY_FROM_PROFILE_BUTTON_H
#include <config.h>
-#include <glib.h>
#include <QMenu>
#include <QPushButton>
diff --git a/ui/qt/widgets/display_filter_combo.cpp b/ui/qt/widgets/display_filter_combo.cpp
index c28afb91..674da765 100644
--- a/ui/qt/widgets/display_filter_combo.cpp
+++ b/ui/qt/widgets/display_filter_combo.cpp
@@ -25,8 +25,31 @@
#include <ui/qt/utils/color_utils.h>
#include "main_application.h"
-// If we ever add support for multiple windows this will need to be replaced.
-static DisplayFilterCombo *cur_display_filter_combo = NULL;
+static QStandardItemModel *cur_model;
+
+extern "C" void dfilter_recent_combo_write_all(FILE *rf) {
+ if (cur_model == nullptr)
+ return;
+
+ for (int i = 0; i < cur_model->rowCount(); i++ ) {
+ const QByteArray& filter = cur_model->item(i)->text().toUtf8();
+ if (!filter.isEmpty()) {
+ fprintf(rf, RECENT_KEY_DISPLAY_FILTER ": %s\n", filter.constData());
+ }
+ }
+}
+
+extern "C" bool dfilter_combo_add_recent(const char *filter) {
+ if (cur_model == nullptr) {
+ cur_model = new QStandardItemModel();
+ cur_model->setSortRole(Qt::UserRole);
+ }
+
+ QStandardItem *new_item = new QStandardItem(filter);
+ new_item->setData(QVariant(QDateTime::currentMSecsSinceEpoch()), Qt::UserRole);
+ cur_model->appendRow(new_item);
+ return true;
+}
DisplayFilterCombo::DisplayFilterCombo(QWidget *parent) :
QComboBox(parent)
@@ -46,36 +69,51 @@ DisplayFilterCombo::DisplayFilterCombo(QWidget *parent) :
// Default is Preferred.
setSizePolicy(QSizePolicy::MinimumExpanding, sizePolicy().verticalPolicy());
setAccessibleName(tr("Display filter selector"));
- cur_display_filter_combo = this;
updateStyleSheet();
setToolTip(tr("Select from previously used filters."));
- QStandardItemModel *model = qobject_cast<QStandardItemModel*>(this->model());
- model->setSortRole(Qt::UserRole);
+#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
+ // Setting the placeholderText keeps newly added items from being the
+ // current item. It only works for the placeholderText of the QComboBox,
+ // not the lineEdit (even though the lineEdit's placeholderText is shown
+ // instead.) This only matters for any combobox created before the recent
+ // display filter list is read (i.e., the main window one.)
+ setPlaceholderText(lineEdit()->placeholderText());
+#endif
+
+ if (cur_model == nullptr) {
+ cur_model = new QStandardItemModel();
+ cur_model->setSortRole(Qt::UserRole);
+ }
+ setModel(cur_model);
connect(mainApp, &MainApplication::preferencesChanged, this, &DisplayFilterCombo::updateMaxCount);
// Ugly cast required (?)
// https://stackoverflow.com/questions/16794695/connecting-overloaded-signals-and-slots-in-qt-5
connect(this, static_cast<void (DisplayFilterCombo::*)(int)>(&DisplayFilterCombo::activated), this, &DisplayFilterCombo::onActivated);
-}
-
-extern "C" void dfilter_recent_combo_write_all(FILE *rf) {
- if (!cur_display_filter_combo)
- return;
- cur_display_filter_combo->writeRecent(rf);
+#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
+ connect(cur_model, &QAbstractItemModel::rowsAboutToBeInserted, this, &DisplayFilterCombo::rowsAboutToBeInserted);
+ connect(cur_model, &QAbstractItemModel::rowsInserted, this, &DisplayFilterCombo::rowsInserted);
+#endif
}
-void DisplayFilterCombo::writeRecent(FILE *rf) {
- int i;
+#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
+void DisplayFilterCombo::rowsAboutToBeInserted(const QModelIndex&, int, int)
+{
+ // If the current text is blank but we're inserting a row, that means
+ // it is being added programmatically from the model, and we want to
+ // clear it afterwards and show the placeholder text instead.
+ clear_state_ = (currentText() == QString());
+}
- for (i = 0; i < count(); i++) {
- const QByteArray& filter = itemText(i).toUtf8();
- if (!filter.isEmpty()) {
- fprintf(rf, RECENT_KEY_DISPLAY_FILTER ": %s\n", filter.constData());
- }
+void DisplayFilterCombo::rowsInserted(const QModelIndex&, int, int)
+{
+ if (clear_state_) {
+ clearEditText();
}
}
+#endif
void DisplayFilterCombo::onActivated(int row)
{
@@ -172,18 +210,3 @@ void DisplayFilterCombo::updateMaxCount()
{
setMaxCount(prefs.gui_recent_df_entries_max);
}
-
-extern "C" gboolean dfilter_combo_add_recent(const gchar *filter) {
- if (!cur_display_filter_combo)
- return FALSE;
-
- // Adding an item to a QComboBox also sets its lineEdit. In our case
- // that means we might trigger a temporary status message so we block
- // the lineEdit's signals.
- // Another approach would be to update QComboBox->model directly.
- bool block_state = cur_display_filter_combo->lineEdit()->blockSignals(true);
- cur_display_filter_combo->addItem(filter, QVariant(QDateTime::currentMSecsSinceEpoch()));
- cur_display_filter_combo->clearEditText();
- cur_display_filter_combo->lineEdit()->blockSignals(block_state);
- return TRUE;
-}
diff --git a/ui/qt/widgets/display_filter_combo.h b/ui/qt/widgets/display_filter_combo.h
index 81fa11ba..d53bfca4 100644
--- a/ui/qt/widgets/display_filter_combo.h
+++ b/ui/qt/widgets/display_filter_combo.h
@@ -23,9 +23,16 @@ public:
void updateStyleSheet();
protected:
+#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
+ void rowsAboutToBeInserted(const QModelIndex&, int, int);
+ void rowsInserted(const QModelIndex&, int, int);
+#endif
virtual bool event(QEvent *event);
private:
+#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
+ bool clear_state_;
+#endif
public slots:
bool checkDisplayFilter();
diff --git a/ui/qt/widgets/display_filter_edit.cpp b/ui/qt/widgets/display_filter_edit.cpp
index 839b14fd..09113da7 100644
--- a/ui/qt/widgets/display_filter_edit.cpp
+++ b/ui/qt/widgets/display_filter_edit.cpp
@@ -9,9 +9,8 @@
#include "config.h"
-#include <glib.h>
-
#include <epan/dfilter/dfilter.h>
+#include <epan/dfilter/dfunctions.h>
#include <ui/recent.h>
@@ -58,8 +57,16 @@
#define DEFAULT_MODIFIER "Ctrl-"
#endif
-// proto.c:fld_abbrev_chars
-static const QString fld_abbrev_chars_ = "-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";
+// ':' is not a legal field character, but it appears inside literals and
+// having it as a token character will keep field completion from being
+// offered in a place where it is syntactically impossible.
+//
+// The other place ':' is used in the grammar is to separate display filter
+// macros from their argument lists in the ${macro:arg;arg} format. Adding
+// ':' here means that the first argument of the list won't have a completion
+// pop-up. (We don't do completion for the macro names, maybe we should?)
+// ${macro;arg;arg} is allowed now, though.
+static const QString fld_abbrev_chars_ = ":-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";
DisplayFilterEdit::DisplayFilterEdit(QWidget *parent, DisplayFilterEditType type) :
SyntaxLineEdit(parent),
@@ -121,6 +128,8 @@ DisplayFilterEdit::DisplayFilterEdit(QWidget *parent, DisplayFilterEditType type
connect(this, &DisplayFilterEdit::returnPressed, this, &DisplayFilterEdit::applyDisplayFilter);
}
+ setDefaultPlaceholderText();
+
connect(this, &DisplayFilterEdit::textChanged, this,
static_cast<void (DisplayFilterEdit::*)(const QString &)>(&DisplayFilterEdit::checkFilter));
@@ -578,16 +587,24 @@ void DisplayFilterEdit::buildCompletionList(const QString &field_word, const QSt
void *field_cookie;
const QByteArray fw_ba = field_word.toUtf8(); // or toLatin1 or toStdString?
const char *fw_utf8 = fw_ba.constData();
- gsize fw_len = (gsize) strlen(fw_utf8);
+ size_t fw_len = (size_t) strlen(fw_utf8);
for (header_field_info *hfinfo = proto_get_first_protocol_field(proto_id, &field_cookie); hfinfo; hfinfo = proto_get_next_protocol_field(proto_id, &field_cookie)) {
if (hfinfo->same_name_prev_id != -1) continue; // Ignore duplicate names.
if (!g_ascii_strncasecmp(fw_utf8, hfinfo->abbrev, fw_len)) {
- if ((gsize) strlen(hfinfo->abbrev) != fw_len) field_list << hfinfo->abbrev;
+ if ((size_t) strlen(hfinfo->abbrev) != fw_len) field_list << hfinfo->abbrev;
}
}
}
}
+
+ // Add display filter functions to the completion list
+ GPtrArray *func_list = df_func_name_list();
+ for (unsigned i = 0; i < func_list->len; i++) {
+ field_list << QString::fromUtf8(static_cast<const char *>(func_list->pdata[i])).append("(");
+ }
+ g_ptr_array_unref(func_list);
+
field_list.sort();
}
@@ -614,19 +631,42 @@ void DisplayFilterEdit::clearFilter()
void DisplayFilterEdit::applyDisplayFilter()
{
if (completer()->popup()->currentIndex().isValid()) {
- // If the popup (not the QCompleter itself) has a currently
- // valid QModelIndex, that means that the popup's
- // QAbstractItemView::activated() signal has not yet
- // been handled, which means that text() has the old value,
- // not the one from the completer.
- return;
+ // If the popup (not the QCompleter itself) has a currently valid
+ // QModelIndex, check to see if text() matches the text from the popup.
+ // If it does, then all is well, go ahead and filter (this happens
+ // if the popup entry is selected via mouse.)
+ //
+ // If it doesn't match, then it has the old value. There are two
+ // possibilities:
+ // 1) The user clicked away from the popup *without* selecting
+ // anything (making the popup disappear), and then hit Enter, in
+ // which case the user wants to filter with text() and doesn't care
+ // about what's in the popup. However, the QModelIndex for the popup
+ // is still valid until some time after this signal is handled.
+ //
+ // 2) The user pressed Return on an entry in the popup, in which
+ // case the user wants to filter with the new value in the popup,
+ // not the value in text(), but for some reason the popup's
+ // activated() signal gets handled *after* returnPressed on the
+ // LineEdit, unfortunately (#19323).
+ //
+ // We haven't figured out how to distinguish case 1 from case 2 yet,
+ // so ignore this force the user to press Enter again, and which
+ // point everything will have reconciled.
+ //
+ // Note that the currentCompletion() / currentIndex.data() of
+ // the completer() itself is "what would be the first completion
+ // of the text currently displayed in the line edit" and has naught
+ // to do with what was selected in the popup.
+ if (text() != completer()->popup()->currentIndex().data()) {
+ return;
+ }
}
if (syntaxState() == Invalid)
return;
- if (text().length() > 0)
- last_applied_ = text();
+ last_applied_ = text();
updateClearButton();
@@ -712,9 +752,7 @@ void DisplayFilterEdit::applyOrPrepareFilter()
if (! pa || pa->property("display_filter").toString().isEmpty())
return;
- QString filterText = pa->property("display_filter").toString();
- last_applied_ = filterText;
- setText(filterText);
+ setText(pa->property("display_filter").toString());
// Holding down the Shift key will only prepare filter.
if (!(QApplication::keyboardModifiers() & Qt::ShiftModifier)) {
@@ -802,7 +840,6 @@ void DisplayFilterEdit::dropEvent(QDropEvent *event)
return;
}
- last_applied_ = filterText;
setText(filterText);
// Holding down the Shift key will only prepare filter.
diff --git a/ui/qt/widgets/dissector_syntax_line_edit.cpp b/ui/qt/widgets/dissector_syntax_line_edit.cpp
index ae8a2247..4f228ce4 100644
--- a/ui/qt/widgets/dissector_syntax_line_edit.cpp
+++ b/ui/qt/widgets/dissector_syntax_line_edit.cpp
@@ -9,8 +9,6 @@
#include "config.h"
-#include <glib.h>
-
#include <epan/packet.h>
#include <wsutil/utf8_entities.h>
@@ -38,6 +36,15 @@ DissectorSyntaxLineEdit::DissectorSyntaxLineEdit(QWidget *parent) :
setCompleter(new QCompleter(completion_model_, this));
setCompletionTokenChars(fld_abbrev_chars_);
+ updateDissectorNames();
+ setDefaultPlaceholderText();
+
+ connect(this, &DissectorSyntaxLineEdit::textChanged, this,
+ static_cast<void (DissectorSyntaxLineEdit::*)(const QString &)>(&DissectorSyntaxLineEdit::checkDissectorName));
+}
+
+void DissectorSyntaxLineEdit::updateDissectorNames()
+{
GList *dissector_names = get_dissector_names();
QStringList dissector_list;
for (GList* l = dissector_names; l != NULL; l = l->next) {
@@ -46,10 +53,6 @@ DissectorSyntaxLineEdit::DissectorSyntaxLineEdit(QWidget *parent) :
g_list_free(dissector_names);
dissector_list.sort();
completion_model_->setStringList(dissector_list);
- setDefaultPlaceholderText();
-
- connect(this, &DissectorSyntaxLineEdit::textChanged, this,
- static_cast<void (DissectorSyntaxLineEdit::*)(const QString &)>(&DissectorSyntaxLineEdit::checkDissectorName));
}
void DissectorSyntaxLineEdit::setDefaultPlaceholderText()
diff --git a/ui/qt/widgets/dissector_syntax_line_edit.h b/ui/qt/widgets/dissector_syntax_line_edit.h
index adcee8c7..a99442b7 100644
--- a/ui/qt/widgets/dissector_syntax_line_edit.h
+++ b/ui/qt/widgets/dissector_syntax_line_edit.h
@@ -20,19 +20,22 @@ class DissectorSyntaxLineEdit : public SyntaxLineEdit
Q_OBJECT
public:
explicit DissectorSyntaxLineEdit(QWidget *parent = 0);
+ void updateDissectorNames();
+ void setDefaultPlaceholderText();
protected:
void keyPressEvent(QKeyEvent *event) { completionKeyPressEvent(event); }
void focusInEvent(QFocusEvent *event) { completionFocusInEvent(event); }
-private slots:
+public slots:
void checkDissectorName(const QString &dissector);
+
+private slots:
void changeEvent(QEvent* event);
private:
QString placeholder_text_;
- void setDefaultPlaceholderText();
void buildCompletionList(const QString &field_word, const QString &preamble);
};
diff --git a/ui/qt/widgets/field_filter_edit.cpp b/ui/qt/widgets/field_filter_edit.cpp
index 7aebf051..b2452c30 100644
--- a/ui/qt/widgets/field_filter_edit.cpp
+++ b/ui/qt/widgets/field_filter_edit.cpp
@@ -9,8 +9,6 @@
#include "config.h"
-#include <glib.h>
-
#include <epan/dfilter/dfilter.h>
#include <wsutil/filter_files.h>
@@ -160,12 +158,12 @@ void FieldFilterEdit::buildCompletionList(const QString &field_word, const QStri
void *field_cookie;
const QByteArray fw_ba = field_word.toUtf8(); // or toLatin1 or toStdString?
const char *fw_utf8 = fw_ba.constData();
- gsize fw_len = (gsize) strlen(fw_utf8);
+ size_t fw_len = (size_t) strlen(fw_utf8);
for (header_field_info *hfinfo = proto_get_first_protocol_field(proto_id, &field_cookie); hfinfo; hfinfo = proto_get_next_protocol_field(proto_id, &field_cookie)) {
if (hfinfo->same_name_prev_id != -1) continue; // Ignore duplicate names.
if (!g_ascii_strncasecmp(fw_utf8, hfinfo->abbrev, fw_len)) {
- if ((gsize) strlen(hfinfo->abbrev) != fw_len) field_list << hfinfo->abbrev;
+ if ((size_t) strlen(hfinfo->abbrev) != fw_len) field_list << hfinfo->abbrev;
}
}
}
diff --git a/ui/qt/widgets/filter_expression_toolbar.cpp b/ui/qt/widgets/filter_expression_toolbar.cpp
index 84dabc47..c17f7aee 100644
--- a/ui/qt/widgets/filter_expression_toolbar.cpp
+++ b/ui/qt/widgets/filter_expression_toolbar.cpp
@@ -181,7 +181,7 @@ WiresharkMimeData * FilterExpressionToolBar::createMimeData(QString name, int po
void FilterExpressionToolBar::onActionMoved(QAction* action, int oldPos, int newPos)
{
- gchar* err = NULL;
+ char* err = NULL;
if (oldPos == newPos)
return;
@@ -237,7 +237,7 @@ void FilterExpressionToolBar::onFilterDropped(QString description, QString filte
return;
filter_expression_new(qUtf8Printable(description),
- qUtf8Printable(filter), qUtf8Printable(description), TRUE);
+ qUtf8Printable(filter), qUtf8Printable(description), true);
save_migrated_uat("Display expressions", &prefs.filter_expressions_old);
filterExpressionsChanged();
@@ -356,16 +356,14 @@ QMenu * FilterExpressionToolBar::findParentMenu(const QStringList tree, void *fe
/* Searching existing main menus */
foreach(QAction * entry, data->toolbar->actions())
{
- QWidget * widget = data->toolbar->widgetForAction(entry);
- QToolButton * tb = qobject_cast<QToolButton *>(widget);
- if (tb && tb->menu() && tb->text().compare(tree.at(0).trimmed()) == 0)
- return findParentMenu(tree.mid(1), fed_data, tb->menu());
+ if (entry->text().compare(tree.at(0).trimmed()) == 0)
+ return findParentMenu(tree.mid(1), fed_data, entry->menu());
}
}
else if (parent)
{
QString menuName = tree.at(0).trimmed();
- /* Iterate to see, if we next have to jump into another submenu */
+ /* Iterate to see if we next have to jump into another submenu */
foreach(QAction *entry, parent->actions())
{
if (entry->menu() && entry->text().compare(menuName) == 0)
@@ -382,16 +380,18 @@ QMenu * FilterExpressionToolBar::findParentMenu(const QStringList tree, void *fe
/* No menu has been found, create one */
QString parentName = tree.at(0).trimmed();
- QToolButton * menuButton = new QToolButton();
- menuButton->setText(parentName);
- menuButton->setPopupMode(QToolButton::MenuButtonPopup);
- QMenu * parentMenu = new QMenu(menuButton);
+ QMenu * parentMenu = new QMenu(data->toolbar);
parentMenu->installEventFilter(data->toolbar);
parentMenu->setProperty(dfe_menu_, QVariant::fromValue(true));
- menuButton->setMenu(parentMenu);
- // Required for QToolButton::MenuButtonPopup.
- connect(menuButton, &QToolButton::pressed, menuButton, &QToolButton::showMenu);
- data->toolbar->addWidget(menuButton);
+ QAction *menuAction = new QAction(data->toolbar);
+ menuAction->setText(parentName);
+ menuAction->setMenu(parentMenu);
+ // QToolButton::MenuButtonPopup means that pressing the button text
+ // itself doesn't open the menu, only pressing the downwards pointing
+ // triangle does. This is difficult to change for the auto created
+ // QToolButton inside the QToolBar. But only auto created tool buttons
+ // will show up in the extension menu at narrow widths (#19887.)
+ data->toolbar->addAction(menuAction);
return findParentMenu(tree.mid(1), fed_data, parentMenu);
}
@@ -407,7 +407,7 @@ bool FilterExpressionToolBar::filter_expression_add_action(const void *key _U_,
struct filter_expression_data* data = (filter_expression_data*)user_data;
if (!fe->enabled)
- return FALSE;
+ return false;
QString label = QString(fe->label);
@@ -449,7 +449,7 @@ bool FilterExpressionToolBar::filter_expression_add_action(const void *key _U_,
connect(dfb_action, &QAction::triggered, data->toolbar, &FilterExpressionToolBar::filterClicked);
data->actions_added = true;
- return FALSE;
+ return false;
}
void FilterExpressionToolBar::filterClicked()
diff --git a/ui/qt/widgets/filter_expression_toolbar.h b/ui/qt/widgets/filter_expression_toolbar.h
index 80724a27..174d927b 100644
--- a/ui/qt/widgets/filter_expression_toolbar.h
+++ b/ui/qt/widgets/filter_expression_toolbar.h
@@ -9,8 +9,6 @@
#include <ui/qt/widgets/drag_drop_toolbar.h>
-#include <glib.h>
-
#include <QMenu>
#ifndef FILTER_EXPRESSION_TOOLBAR_H
diff --git a/ui/qt/widgets/follow_stream_text.cpp b/ui/qt/widgets/follow_stream_text.cpp
index a8e0f2b9..b2492c0b 100644
--- a/ui/qt/widgets/follow_stream_text.cpp
+++ b/ui/qt/widgets/follow_stream_text.cpp
@@ -9,10 +9,16 @@
#include <ui/qt/widgets/follow_stream_text.h>
+#include "epan/prefs.h"
+
+#include <ui/qt/utils/color_utils.h>
+
#include <main_application.h>
+#include <QMap>
#include <QMouseEvent>
#include <QTextCursor>
+#include <QScrollBar>
// To do:
// - Draw text by hand similar to ByteViewText. This would let us add
@@ -20,17 +26,96 @@
// max_document_length_ in FollowStreamDialog.
FollowStreamText::FollowStreamText(QWidget *parent) :
- QPlainTextEdit(parent)
+ QPlainTextEdit(parent), truncated_(false)
{
setMouseTracking(true);
// setMaximumBlockCount(1);
QTextDocument *text_doc = document();
text_doc->setDefaultFont(mainApp->monospaceFont());
+
+ metainfo_fg_ = ColorUtils::alphaBlend(palette().windowText(), palette().window(), 0.35);
+}
+
+const int FollowStreamText::max_document_length_ = 500 * 1000 * 1000; // Just a guess
+
+void FollowStreamText::addTruncated(int cur_pos)
+{
+ if (truncated_) {
+ QTextCharFormat tcf = currentCharFormat();
+ tcf.setBackground(palette().base().color());
+ tcf.setForeground(metainfo_fg_);
+ insertPlainText("\n" + tr("[Stream output truncated]"));
+ moveCursor(QTextCursor::End);
+ } else {
+ verticalScrollBar()->setValue(cur_pos);
+ }
+}
+
+void FollowStreamText::addText(QString text, bool is_from_server, uint32_t packet_num, bool colorize)
+{
+ if (truncated_) {
+ return;
+ }
+
+ int char_count = document()->characterCount();
+ if (char_count + text.length() > max_document_length_) {
+ text.truncate(max_document_length_ - char_count);
+ truncated_ = true;
+ }
+
+ setUpdatesEnabled(false);
+ int cur_pos = verticalScrollBar()->value();
+ moveCursor(QTextCursor::End);
+
+ QTextCharFormat tcf = currentCharFormat();
+ if (!colorize) {
+ tcf.setBackground(palette().base().color());
+ tcf.setForeground(palette().text().color());
+ } else if (is_from_server) {
+ tcf.setForeground(ColorUtils::fromColorT(prefs.st_server_fg));
+ tcf.setBackground(ColorUtils::fromColorT(prefs.st_server_bg));
+ } else {
+ tcf.setForeground(ColorUtils::fromColorT(prefs.st_client_fg));
+ tcf.setBackground(ColorUtils::fromColorT(prefs.st_client_bg));
+ }
+ setCurrentCharFormat(tcf);
+
+ insertPlainText(text);
+ text_pos_to_packet_[textCursor().anchor()] = packet_num;
+
+ addTruncated(cur_pos);
+ setUpdatesEnabled(true);
+}
+
+void FollowStreamText::addDeltaTime(double delta)
+{
+ QString delta_str = QString("\n%1s").arg(QString::number(delta, 'f', 6));
+ if (truncated_) {
+ return;
+ }
+
+ if (document()->characterCount() + delta_str.length() > max_document_length_) {
+ truncated_ = true;
+ }
+
+ setUpdatesEnabled(false);
+ int cur_pos = verticalScrollBar()->value();
+ moveCursor(QTextCursor::End);
+
+ QTextCharFormat tcf = currentCharFormat();
+ tcf.setBackground(palette().base().color());
+ tcf.setForeground(metainfo_fg_);
+ setCurrentCharFormat(tcf);
+
+ insertPlainText(delta_str);
+
+ addTruncated(cur_pos);
+ setUpdatesEnabled(true);
}
void FollowStreamText::mouseMoveEvent(QMouseEvent *event)
{
- emit mouseMovedToTextCursorPosition(cursorForPosition(event->pos()).position());
+ emit mouseMovedToPacket(textPosToPacket(cursorForPosition(event->pos()).position()));
// Don't send the mouseMoveEvents with no buttons pushed to the base
// class, effectively turning off mouse tracking for the base class.
// It causes a lot of useless calculations that hurt scroll performance.
@@ -41,12 +126,37 @@ void FollowStreamText::mouseMoveEvent(QMouseEvent *event)
void FollowStreamText::mousePressEvent(QMouseEvent *event)
{
- emit mouseClickedOnTextCursorPosition(cursorForPosition(event->pos()).position());
+ emit mouseClickedOnPacket(textPosToPacket(cursorForPosition(event->pos()).position()));
QPlainTextEdit::mousePressEvent(event);
}
void FollowStreamText::leaveEvent(QEvent *event)
{
- emit mouseMovedToTextCursorPosition(-1);
+ emit mouseMovedToPacket(0);
QPlainTextEdit::leaveEvent(event);
}
+
+void FollowStreamText::clear()
+{
+ truncated_ = false;
+ text_pos_to_packet_.clear();
+ QPlainTextEdit::clear();
+}
+
+int FollowStreamText::currentPacket() const
+{
+ return textPosToPacket(textCursor().position());
+}
+
+int FollowStreamText::textPosToPacket(int text_pos) const
+{
+ int pkt = 0;
+ if (text_pos >= 0) {
+ QMap<int, uint32_t>::const_iterator it = text_pos_to_packet_.upperBound(text_pos);
+ if (it != text_pos_to_packet_.end()) {
+ pkt = it.value();
+ }
+ }
+
+ return pkt;
+}
diff --git a/ui/qt/widgets/follow_stream_text.h b/ui/qt/widgets/follow_stream_text.h
index 0dd8dca5..0276c872 100644
--- a/ui/qt/widgets/follow_stream_text.h
+++ b/ui/qt/widgets/follow_stream_text.h
@@ -17,6 +17,10 @@ class FollowStreamText : public QPlainTextEdit
Q_OBJECT
public:
explicit FollowStreamText(QWidget *parent = 0);
+ bool isTruncated() const { return truncated_; }
+ void addText(QString text, bool is_from_server, uint32_t packet_num, bool colorize);
+ void addDeltaTime(double delta);
+ int currentPacket() const;
protected:
void mouseMoveEvent(QMouseEvent *event);
@@ -24,12 +28,20 @@ protected:
void leaveEvent(QEvent *event);
signals:
- // Perhaps this is not descriptive enough. We should add more words.
- void mouseMovedToTextCursorPosition(int);
- void mouseClickedOnTextCursorPosition(int);
+ void mouseMovedToPacket(int);
+ void mouseClickedOnPacket(int);
public slots:
+ void clear();
+private:
+ int textPosToPacket(int text_pos) const;
+ void addTruncated(int cur_pos);
+
+ static const int max_document_length_;
+ bool truncated_;
+ QMap<int, uint32_t> text_pos_to_packet_;
+ QColor metainfo_fg_;
};
#endif // FOLLOW_STREAM_TEXT_H
diff --git a/ui/qt/widgets/label_stack.cpp b/ui/qt/widgets/label_stack.cpp
index 4cac15b7..8deedaec 100644
--- a/ui/qt/widgets/label_stack.cpp
+++ b/ui/qt/widgets/label_stack.cpp
@@ -68,9 +68,10 @@ void LabelStack::fillLabel() {
setStyleSheet(style_sheet);
}
setText(si.text);
+ setToolTip(si.tooltip);
}
-void LabelStack::pushText(const QString &text, int ctx) {
+void LabelStack::pushText(const QString &text, int ctx, const QString &tooltip) {
popText(ctx);
if (ctx == temporary_ctx_) {
@@ -83,6 +84,7 @@ void LabelStack::pushText(const QString &text, int ctx) {
StackItem si;
si.text = text;
+ si.tooltip = tooltip;
si.ctx = ctx;
labels_.prepend(si);
fillLabel();
diff --git a/ui/qt/widgets/label_stack.h b/ui/qt/widgets/label_stack.h
index 63657b74..27e41be1 100644
--- a/ui/qt/widgets/label_stack.h
+++ b/ui/qt/widgets/label_stack.h
@@ -21,7 +21,7 @@ class LabelStack : public QLabel
public:
explicit LabelStack(QWidget *parent = 0);
void setTemporaryContext(const int ctx);
- void pushText(const QString &text, int ctx);
+ void pushText(const QString &text, int ctx, const QString &tooltip = QString());
void setShrinkable(bool shrinkable = true);
protected:
@@ -35,6 +35,7 @@ protected:
private:
typedef struct _StackItem {
QString text;
+ QString tooltip;
int ctx;
} StackItem;
diff --git a/ui/qt/widgets/path_selection_edit.cpp b/ui/qt/widgets/path_selection_edit.cpp
index eb30f1d0..660a6f53 100644
--- a/ui/qt/widgets/path_selection_edit.cpp
+++ b/ui/qt/widgets/path_selection_edit.cpp
@@ -10,18 +10,18 @@
#include "config.h"
-#include "epan/prefs.h"
#include "ui/util.h"
#include <ui/qt/widgets/path_selection_edit.h>
#include "ui/qt/widgets/wireshark_file_dialog.h"
+#include "ui/qt/utils/qt_ui_utils.h"
#include <QHBoxLayout>
#include <QToolButton>
#include <QWidget>
#include <QLineEdit>
-PathSelectionEdit::PathSelectionEdit(QString title, QString path, bool selectFile, QWidget *parent) :
+PathSelectionEdit::PathSelectionEdit(QString title, QString path, bool selectFile, QWidget *parent) :
QWidget(parent)
{
_title = title;
@@ -49,7 +49,7 @@ PathSelectionEdit::PathSelectionEdit(QString title, QString path, bool selectFil
setFocusPolicy(_edit->focusPolicy());
}
-PathSelectionEdit::PathSelectionEdit(QWidget *parent) :
+PathSelectionEdit::PathSelectionEdit(QWidget *parent) :
PathSelectionEdit(tr("Select a path"), QString(), true, parent)
{}
@@ -75,11 +75,7 @@ void PathSelectionEdit::browseForPath()
QString openDir = _path;
if (openDir.isEmpty()) {
- if (prefs.gui_fileopen_style == FO_STYLE_LAST_OPENED) {
- openDir = QString(get_open_dialog_initial_dir());
- } else if (prefs.gui_fileopen_style == FO_STYLE_SPECIFIED) {
- openDir = QString(prefs.gui_fileopen_dir);
- }
+ openDir = openDialogInitialDir();
}
QString newPath;
diff --git a/ui/qt/widgets/profile_tree_view.cpp b/ui/qt/widgets/profile_tree_view.cpp
index afa86d71..ebac67c7 100644
--- a/ui/qt/widgets/profile_tree_view.cpp
+++ b/ui/qt/widgets/profile_tree_view.cpp
@@ -7,31 +7,28 @@
* SPDX-License-Identifier: GPL-2.0-or-later
*/
-#include <ui/qt/models/url_link_delegate.h>
#include <ui/qt/models/profile_model.h>
#include <ui/qt/utils/qt_ui_utils.h>
+#include <ui/qt/widgets/display_filter_edit.h>
#include <ui/qt/widgets/profile_tree_view.h>
#include <QDesktopServices>
#include <QDir>
+#include <QHeaderView>
#include <QItemDelegate>
#include <QLineEdit>
-#include <QUrl>
-ProfileUrlLinkDelegate::ProfileUrlLinkDelegate(QObject *parent) : UrlLinkDelegate (parent) {}
+ProfileTreeEditDelegate::ProfileTreeEditDelegate(QWidget *parent) : QItemDelegate(parent), editor_(Q_NULLPTR) {}
-void ProfileUrlLinkDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
+QWidget *ProfileTreeEditDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,
+ const QModelIndex &index) const
{
- /* Only paint links for valid paths */
- if (index.data(ProfileModel::DATA_PATH_IS_NOT_DESCRIPTION).toBool())
- UrlLinkDelegate::paint(painter, option, index);
- else
- QStyledItemDelegate::paint(painter, option, index);
-
+ if (index.column() == ProfileModel::COL_AUTO_SWITCH_FILTER) {
+ return new DisplayFilterEdit(parent);
+ }
+ return QItemDelegate::createEditor(parent, option, index);
}
-ProfileTreeEditDelegate::ProfileTreeEditDelegate(QWidget *parent) : QItemDelegate(parent), editor_(Q_NULLPTR) {}
-
void ProfileTreeEditDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
if (qobject_cast<QLineEdit *>(editor))
@@ -46,8 +43,8 @@ ProfileTreeView::ProfileTreeView(QWidget *parent) :
{
delegate_ = new ProfileTreeEditDelegate();
setItemDelegateForColumn(ProfileModel::COL_NAME, delegate_);
+ setItemDelegateForColumn(ProfileModel::COL_AUTO_SWITCH_FILTER, delegate_);
- connect(this, &QAbstractItemView::clicked, this, &ProfileTreeView::clicked);
connect(delegate_, &ProfileTreeEditDelegate::commitData, this, &ProfileTreeView::itemUpdated);
}
@@ -80,19 +77,6 @@ void ProfileTreeView::selectionChanged(const QItemSelection &selected, const QIt
}
}
-void ProfileTreeView::clicked(const QModelIndex &index)
-{
- if (!index.isValid())
- return;
-
- /* Only paint links for valid paths */
- if (index.data(ProfileModel::DATA_INDEX_VALUE_IS_URL).toBool())
- {
- QString path = QDir::toNativeSeparators(index.data().toString());
- QDesktopServices::openUrl(QUrl::fromLocalFile(path));
- }
-}
-
void ProfileTreeView::selectRow(int row)
{
if (row < 0)
@@ -117,3 +101,30 @@ bool ProfileTreeView::activeEdit()
{
return (state() == QAbstractItemView::EditingState);
}
+
+// If our auto switch filters are shorter than the filter column title,
+// stretch the name column.
+void ProfileTreeView::showEvent(QShowEvent *)
+{
+ bool have_wide_filter = false;
+ int auto_switch_title_width = fontMetrics().horizontalAdvance(model()->headerData(ProfileModel::COL_AUTO_SWITCH_FILTER, Qt::Horizontal).toString());
+ for (int row = 0; row < model()->rowCount(); row++) {
+ QString filter = model()->data(model()->index(row, ProfileModel::COL_AUTO_SWITCH_FILTER)).toString();
+ if (fontMetrics().horizontalAdvance(filter) > auto_switch_title_width) {
+ have_wide_filter = true;
+ break;
+ }
+ }
+
+ if (have_wide_filter) {
+ return;
+ }
+
+ int col_name_size_hint = sizeHintForColumn(ProfileModel::COL_NAME);
+ int col_asf_size_hint = qMax(header()->sectionSizeHint(ProfileModel::COL_AUTO_SWITCH_FILTER), sizeHintForColumn(ProfileModel::COL_AUTO_SWITCH_FILTER));
+ int extra = columnWidth(ProfileModel::COL_AUTO_SWITCH_FILTER) - col_asf_size_hint;
+ if (extra > 0) {
+ setColumnWidth(ProfileModel::COL_NAME, col_name_size_hint + extra);
+ }
+
+}
diff --git a/ui/qt/widgets/profile_tree_view.h b/ui/qt/widgets/profile_tree_view.h
index 9684811e..02492e4b 100644
--- a/ui/qt/widgets/profile_tree_view.h
+++ b/ui/qt/widgets/profile_tree_view.h
@@ -15,16 +15,6 @@
#include <QTreeView>
#include <QItemDelegate>
-class ProfileUrlLinkDelegate : public UrlLinkDelegate
-{
- Q_OBJECT
-
-public:
- explicit ProfileUrlLinkDelegate(QObject *parent = Q_NULLPTR);
-
- virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
-};
-
class ProfileTreeEditDelegate : public QItemDelegate
{
Q_OBJECT
@@ -32,6 +22,7 @@ public:
ProfileTreeEditDelegate(QWidget *parent = Q_NULLPTR);
// QAbstractItemDelegate interface
+ QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
virtual void setEditorData(QWidget *editor, const QModelIndex &index) const;
private:
@@ -54,12 +45,12 @@ signals:
// QWidget interface
protected:
+ virtual void showEvent(QShowEvent *);
virtual void mouseDoubleClickEvent(QMouseEvent *event);
// QAbstractItemView interface
protected slots:
virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected);
- virtual void clicked(const QModelIndex &index);
private:
ProfileTreeEditDelegate *delegate_;
diff --git a/ui/qt/widgets/qcp_axis_ticker_elided.cpp b/ui/qt/widgets/qcp_axis_ticker_elided.cpp
new file mode 100644
index 00000000..154a750a
--- /dev/null
+++ b/ui/qt/widgets/qcp_axis_ticker_elided.cpp
@@ -0,0 +1,74 @@
+/** @file
+ *
+ * QCustomPlot QCPAxisTickerText subclass that elides labels to the
+ * width of the parent QCPAxis's QCPAxisRect's margin for the appropriate
+ * side, for use when the margin is fixed.
+ *
+ * Copyright 2024 John Thacker <johnthacker@gmail.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <ui/qt/widgets/qcp_axis_ticker_elided.h>
+
+#include <QFontMetrics>
+
+QCPAxisTickerElided::QCPAxisTickerElided(QCPAxis *parent) :
+ mParent(parent)
+{
+}
+
+QCP::MarginSide QCPAxisTickerElided::axisTypeToMarginSide(const QCPAxis::AxisType axis)
+{
+ switch (axis) {
+ case QCPAxis::atLeft:
+ return QCP::msLeft;
+ case QCPAxis::atRight:
+ return QCP::msRight;
+ case QCPAxis::atTop:
+ return QCP::msTop;
+ case QCPAxis::atBottom:
+ return QCP::msBottom;
+ }
+ return QCP::msNone;
+}
+
+QString QCPAxisTickerElided::elidedText(const QString& text)
+{
+ QCP::MarginSides autoMargins = mParent->axisRect()->autoMargins();
+ if (autoMargins & axisTypeToMarginSide(mParent->axisType())) {
+ return text;
+ }
+ int elide_w;
+ QMargins margins = mParent->axisRect()->margins();
+ switch (mParent->axisType()) {
+ case QCPAxis::atLeft:
+ elide_w = margins.left();
+ break;
+ case QCPAxis::atRight:
+ elide_w = margins.right();
+ break;
+ case QCPAxis::atTop:
+ elide_w = margins.top();
+ break;
+ case QCPAxis::atBottom:
+ elide_w = margins.bottom();
+ break;
+ default:
+ // ??
+ elide_w = margins.left();
+ }
+
+ return QFontMetrics(mParent->tickLabelFont()).elidedText(text,
+ Qt::ElideRight,
+ elide_w);
+}
+
+QString QCPAxisTickerElided::getTickLabel(double tick, const QLocale& , QChar , int)
+{
+ return elidedText(mTicks.value(tick));
+}
diff --git a/ui/qt/widgets/qcp_axis_ticker_elided.h b/ui/qt/widgets/qcp_axis_ticker_elided.h
new file mode 100644
index 00000000..b542d9a9
--- /dev/null
+++ b/ui/qt/widgets/qcp_axis_ticker_elided.h
@@ -0,0 +1,38 @@
+/** @file
+ *
+ * QCustomPlot QCPAxisTickerText subclass that elides labels to the
+ * width of the parent QCPAxis's QCPAxisRect's margin for the appropriate
+ * side, for use when the margin is fixed.
+ *
+ * Copyright 2024 John Thacker <johnthacker@gmail.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef QCP_AXIS_TICKER_ELIDED_H
+#define QCP_AXIS_TICKER_ELIDED_H
+
+#include <ui/qt/widgets/qcustomplot.h>
+
+class QCPAxisTickerElided : public QCPAxisTickerText
+{
+public:
+ explicit QCPAxisTickerElided(QCPAxis *parent);
+
+ // QCP has marginSideToAxisType but not the inverse
+ static QCP::MarginSide axisTypeToMarginSide(const QCPAxis::AxisType);
+
+ QString elidedText(const QString& text);
+
+protected:
+ virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) override;
+
+private:
+ QCPAxis *mParent;
+};
+
+#endif
diff --git a/ui/qt/widgets/qcp_axis_ticker_si.cpp b/ui/qt/widgets/qcp_axis_ticker_si.cpp
new file mode 100644
index 00000000..be6d35a6
--- /dev/null
+++ b/ui/qt/widgets/qcp_axis_ticker_si.cpp
@@ -0,0 +1,74 @@
+/** @file
+ *
+ * QCustomPlot QCPAxisTicker subclass that creates human-readable
+ * SI unit labels, optionally supporting log scale.
+ *
+ * Copyright 2024 John Thacker <johnthacker@gmail.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <cmath>
+
+#include <ui/qt/widgets/qcp_axis_ticker_si.h>
+#include <ui/qt/utils/qt_ui_utils.h>
+
+#include <wsutil/str_util.h>
+
+QCPAxisTickerSi::QCPAxisTickerSi(format_size_units_e unit, QString customUnit, bool log) :
+ mUnit(unit), mCustomUnit(customUnit), mLog(log)
+{
+}
+
+QString QCPAxisTickerSi::getTickLabel(double tick, const QLocale& , QChar , int precision)
+{
+ QString label = gchar_free_to_qstring(format_units(nullptr, tick, mUnit, FORMAT_SIZE_PREFIX_SI, precision));
+
+ // XXX - format_units isn't consistent about whether we need to
+ // add a space or not
+ if (mUnit == FORMAT_SIZE_UNIT_NONE && !mCustomUnit.isEmpty()) {
+ label += mCustomUnit;
+ }
+ // XXX - "Beautiful typeset powers" for exponentials is handled by QCPAxis,
+ // not QCPAxisTicker and its subclasses, and its detection of exponentials
+ // doesn't handle having a unit or other suffix, so that won't work.
+ // In practical use we'll be within our prefix range, though.
+ return label;
+}
+
+int QCPAxisTickerSi::getSubTickCount(double tickStep)
+{
+ if (mLog) {
+ return QCPAxisTickerLog::getSubTickCount(tickStep);
+ } else {
+ return QCPAxisTicker::getSubTickCount(tickStep);
+ }
+}
+
+QVector<double> QCPAxisTickerSi::createTickVector(double tickStep, const QCPRange &range)
+{
+ if (mLog) {
+ return QCPAxisTickerLog::createTickVector(tickStep, range);
+ } else {
+ return QCPAxisTicker::createTickVector(tickStep, range);
+ }
+}
+
+void QCPAxisTickerSi::setUnit(format_size_units_e unit)
+{
+ mUnit = unit;
+}
+
+void QCPAxisTickerSi::setCustomUnit(QString unit)
+{
+ mCustomUnit = unit;
+}
+
+void QCPAxisTickerSi::setLog(bool log)
+{
+ mLog = log;
+}
diff --git a/ui/qt/widgets/qcp_axis_ticker_si.h b/ui/qt/widgets/qcp_axis_ticker_si.h
new file mode 100644
index 00000000..a9fa51cc
--- /dev/null
+++ b/ui/qt/widgets/qcp_axis_ticker_si.h
@@ -0,0 +1,42 @@
+/** @file
+ *
+ * QCustomPlot QCPAxisTicker subclass that creates human-readable
+ * SI unit labels, optionally supporting log scale.
+ *
+ * Copyright 2024 John Thacker <johnthacker@gmail.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef QCP_AXIS_TICKER_SI_H
+#define QCP_AXIS_TICKER_SI_H
+
+#include <ui/qt/widgets/qcustomplot.h>
+
+#include <wsutil/str_util.h>
+
+class QCPAxisTickerSi : public QCPAxisTickerLog
+{
+public:
+ explicit QCPAxisTickerSi(format_size_units_e unit = FORMAT_SIZE_UNIT_PACKETS, QString customUnit = QString(), bool log = false);
+
+ format_size_units_e getUnit() const { return mUnit; }
+ void setUnit(format_size_units_e unit);
+ void setCustomUnit(QString unit);
+ void setLog(bool log);
+
+protected:
+ virtual QString getTickLabel(double tick, const QLocale &locale, QChar formatChar, int precision) override;
+ virtual int getSubTickCount(double tickStep) override;
+ virtual QVector<double> createTickVector(double tickStep, const QCPRange &range) override;
+
+ format_size_units_e mUnit;
+ QString mCustomUnit;
+ bool mLog;
+};
+
+#endif
diff --git a/ui/qt/widgets/qcp_string_legend_item.cpp b/ui/qt/widgets/qcp_string_legend_item.cpp
new file mode 100644
index 00000000..62596895
--- /dev/null
+++ b/ui/qt/widgets/qcp_string_legend_item.cpp
@@ -0,0 +1,46 @@
+/** @file
+ *
+ * QCustomPlot QCPAbstractLegendItem subclass containing a string.
+ * This is used to add a title to a QCPLegend.
+ *
+ * This file is from https://www.qcustomplot.com/index.php/support/forum/443
+ * where the author David said "I thought I would share in case any one else
+ * is needing the same functionality." Accordingly, this file is in the
+ * public domain.
+ */
+
+#include <ui/qt/widgets/qcp_string_legend_item.h>
+
+QCPStringLegendItem::QCPStringLegendItem(QCPLegend *pParent, const QString& strText)
+ : QCPAbstractLegendItem(pParent)
+ , m_strText(strText)
+{
+}
+
+QString QCPStringLegendItem::text() const
+{
+ return m_strText;
+}
+
+void QCPStringLegendItem::setText(const QString& strText)
+{
+ m_strText = strText;
+}
+
+void QCPStringLegendItem::draw(QCPPainter *pPainter)
+{
+ pPainter->setFont(mFont);
+ pPainter->setPen(QPen(mTextColor));
+ QRectF textRect = pPainter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip, m_strText);
+ pPainter->drawText(mRect.x() + mMargins.left(), mRect.y(), textRect.width(), textRect.height(), Qt::TextDontClip | Qt::AlignHCenter, m_strText);
+}
+
+QSize QCPStringLegendItem::minimumOuterSizeHint() const
+{
+ QSize cSize(0, 0);
+ QFontMetrics fontMetrics(mFont);
+ QRect textRect = fontMetrics.boundingRect(0, 0, 0, 0, Qt::TextDontClip, m_strText);
+ cSize.setWidth(textRect.width() + mMargins.left() + mMargins.right());
+ cSize.setHeight(textRect.height() + mMargins.top() + mMargins.bottom());
+ return cSize;
+}
diff --git a/ui/qt/widgets/qcp_string_legend_item.h b/ui/qt/widgets/qcp_string_legend_item.h
new file mode 100644
index 00000000..d32631ad
--- /dev/null
+++ b/ui/qt/widgets/qcp_string_legend_item.h
@@ -0,0 +1,35 @@
+/** @file
+ *
+ * QCustomPlot QCPAbstractLegendItem subclass containing a string.
+ * This is used to add a title to a QCPLegend.
+ *
+ * This file is from https://www.qcustomplot.com/index.php/support/forum/443
+ * where the author David said "I thought I would share in case any one else
+ * is needing the same functionality." Accordingly, this file is in the
+ * public domain.
+ */
+
+#ifndef QCP_STRING_LEGEND_ITEM_H
+#define QCP_STRING_LEGEND_ITEM_H
+
+#include <ui/qt/widgets/qcustomplot.h>
+
+class QCPStringLegendItem : public QCPAbstractLegendItem
+{
+ Q_OBJECT
+
+public:
+ explicit QCPStringLegendItem(QCPLegend *pParent, const QString& strText);
+
+ QString text() const;
+ void setText(const QString& strText);
+
+protected:
+ virtual void draw(QCPPainter *painter) override;
+ virtual QSize minimumOuterSizeHint() const override;
+
+private:
+ QString m_strText;
+};
+
+#endif
diff --git a/ui/qt/widgets/resize_header_view.cpp b/ui/qt/widgets/resize_header_view.cpp
new file mode 100644
index 00000000..7335265f
--- /dev/null
+++ b/ui/qt/widgets/resize_header_view.cpp
@@ -0,0 +1,45 @@
+/** @file
+ *
+ * Header view with a context menu to resize all sections to contents
+ *
+ * Copyright 2024 John Thacker <johnthacker@gmail.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "resize_header_view.h"
+
+#include <QMenu>
+#include <QContextMenuEvent>
+
+ResizeHeaderView::ResizeHeaderView(Qt::Orientation orientation, QWidget *parent) : QHeaderView(orientation, parent)
+{
+ setStretchLastSection(true);
+ setSectionsMovable(true);
+ // setFirstSectionMovable(true) ?
+}
+
+/*!
+ \fn void ResizeHeaderView::contextMenuEvent(QContextMenuEvent *e)
+
+ Shows a context menu which resizes all sections to their contents.
+ */
+
+void ResizeHeaderView::contextMenuEvent(QContextMenuEvent *e)
+{
+ if (e == nullptr)
+ return;
+
+ QMenu *ctxMenu = new QMenu(this);
+ ctxMenu->setAttribute(Qt::WA_DeleteOnClose);
+
+ QString text = tr("Resize all %1 to contents").arg((orientation() == Qt::Horizontal) ? "columns" : "rows");
+ QAction *act = ctxMenu->addAction(std::move(text));
+ connect(act, &QAction::triggered, this, [&]() { resizeSections(QHeaderView::ResizeToContents); });
+
+ ctxMenu->popup(e->globalPos());
+}
diff --git a/ui/qt/widgets/resize_header_view.h b/ui/qt/widgets/resize_header_view.h
new file mode 100644
index 00000000..a8aa57f3
--- /dev/null
+++ b/ui/qt/widgets/resize_header_view.h
@@ -0,0 +1,31 @@
+/** @file
+ *
+ * Header view with a context menu to resize all sections to contents
+ *
+ * Copyright 2024 John Thacker <johnthacker@gmail.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef RESIZE_HEADER_VIEW_H
+#define RESIZE_HEADER_VIEW_H
+
+#include <config.h>
+#include <QHeaderView>
+
+class ResizeHeaderView : public QHeaderView
+{
+ Q_OBJECT
+
+public:
+ ResizeHeaderView(Qt::Orientation orientation, QWidget *parent = nullptr);
+
+protected:
+ void contextMenuEvent(QContextMenuEvent *e) override;
+
+};
+#endif // RESIZE_HEADER_VIEW_H
diff --git a/ui/qt/widgets/resolved_addresses_view.cpp b/ui/qt/widgets/resolved_addresses_view.cpp
new file mode 100644
index 00000000..82b2a299
--- /dev/null
+++ b/ui/qt/widgets/resolved_addresses_view.cpp
@@ -0,0 +1,261 @@
+/** @file
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <config.h>
+#define WS_LOG_DOMAIN LOG_DOMAIN_QTUI
+
+#include <ui/qt/widgets/resolved_addresses_view.h>
+#include <ui/qt/models/resolved_addresses_models.h>
+#include <ui/qt/widgets/wireshark_file_dialog.h>
+
+#include <QHeaderView>
+#include <QMessageBox>
+#include <QClipboard>
+#include <QTextStream>
+#include <QJsonArray>
+#include <QJsonObject>
+#include <QJsonDocument>
+#include <QContextMenuEvent>
+
+#include "main_application.h"
+
+#include <wsutil/wslog.h>
+
+ResolvedAddressesView::ResolvedAddressesView(QWidget *parent) : QTableView(parent)
+{
+ setEditTriggers(QAbstractItemView::NoEditTriggers);
+ setSortingEnabled(true);
+ setSelectionBehavior(QAbstractItemView::SelectRows);
+ horizontalHeader()->setStretchLastSection(true);
+ verticalHeader()->setVisible(false);
+
+ // creating this action is mostly to override the default Ctrl-C handling
+ // (which could also be done by overriding KeyPressEvent) and to make the
+ // keyboard shortcut show up in the context menu.
+#if QT_VERSION < QT_VERSION_CHECK(6, 3, 0)
+ clip_action_ = new QAction(tr("as Plain Text"), this);
+ clip_action_->setShortcut(QKeySequence(QKeySequence::Copy));
+ connect(clip_action_, &QAction::triggered, this, &ResolvedAddressesView::clipboardAction);
+ addAction(clip_action_);
+#else
+ clip_action_ = addAction(tr("as Plain Text"), QKeySequence(QKeySequence::Copy), this, &ResolvedAddressesView::clipboardAction);
+#endif
+ clip_action_->setProperty("copy_as", ResolvedAddressesView::EXPORT_TEXT);
+ clip_action_->setProperty("selected", true);
+}
+
+QMenu* ResolvedAddressesView::createCopyMenu(bool selected, QWidget *parent)
+{
+ QMenu *copy_menu;
+ if (selected) {
+ copy_menu = new QMenu(tr("Copy selected rows"), parent);
+ } else {
+ copy_menu = new QMenu(tr("Copy table"), parent);
+ }
+ copy_menu->setIcon(QIcon::fromTheme(QStringLiteral("edit-copy")));
+ QAction *ca;
+ if (selected) {
+ copy_menu->addAction(clip_action_);
+ } else {
+ ca = copy_menu->addAction(tr("as Plain Text"), this, &ResolvedAddressesView::clipboardAction);
+ ca->setProperty("copy_as", ResolvedAddressesView::EXPORT_TEXT);
+ ca->setProperty("selected", selected);
+ }
+ ca = copy_menu->addAction(tr("as CSV"), this, &ResolvedAddressesView::clipboardAction);
+ ca->setProperty("copy_as", ResolvedAddressesView::EXPORT_CSV);
+ ca->setProperty("selected", selected);
+ ca = copy_menu->addAction(tr("as JSON"), this, &ResolvedAddressesView::clipboardAction);
+ ca->setProperty("copy_as", ResolvedAddressesView::EXPORT_JSON);
+ ca->setProperty("selected", selected);
+
+ return copy_menu;
+}
+
+void ResolvedAddressesView::contextMenuEvent(QContextMenuEvent *e)
+{
+ if (!e)
+ return;
+
+ QMenu *ctxMenu = new QMenu(this);
+ ctxMenu->setAttribute(Qt::WA_DeleteOnClose);
+ ctxMenu->addMenu(createCopyMenu(true, ctxMenu));
+ QAction *act = ctxMenu->addAction(tr("Save selected rows as…"));
+ act->setIcon(QIcon::fromTheme(QStringLiteral("document-save-as")));
+ act->setProperty("selected", true);
+ connect(act, &QAction::triggered, this, &ResolvedAddressesView::saveAs);
+ ctxMenu->addSeparator();
+ ctxMenu->addMenu(createCopyMenu(false, ctxMenu));
+ act = ctxMenu->addAction(QIcon::fromTheme(QStringLiteral("document-save-as")), tr("Save table as…"), this, &ResolvedAddressesView::saveAs);
+ act->setProperty("selected", false);
+
+ ctxMenu->popup(e->globalPos());
+}
+
+AStringListListModel* ResolvedAddressesView::dataModel() const
+{
+ QSortFilterProxyModel *proxy = qobject_cast<QSortFilterProxyModel *>(model());
+
+ if (proxy) {
+ QAbstractItemModel *source = proxy->sourceModel();
+ while (qobject_cast<QSortFilterProxyModel *>(source) != nullptr) {
+ proxy = qobject_cast<QSortFilterProxyModel *>(source);
+ source = proxy->sourceModel();
+ }
+ return qobject_cast<AStringListListModel *>(source);
+ }
+ return nullptr;
+}
+
+void ResolvedAddressesView::clipboardAction()
+{
+ QAction *ca = qobject_cast<QAction *>(sender());
+ if (ca && ca->property("copy_as").isValid()) {
+ copyToClipboard(static_cast<eResolvedAddressesExport>(ca->property("copy_as").toInt()),
+ ca->property("selected").toBool());
+ }
+}
+
+void ResolvedAddressesView::copyToClipboard(eResolvedAddressesExport format, bool selected)
+{
+ QString clipText;
+ QTextStream stream(&clipText, QIODevice::Text);
+ toTextStream(stream, format, selected);
+ mainApp->clipboard()->setText(stream.readAll());
+}
+
+void ResolvedAddressesView::saveAs()
+{
+ bool selected = false;
+ QAction *ca = qobject_cast<QAction *>(sender());
+ if (ca && ca->property("selected").isValid()) {
+ selected = true;
+ }
+ QString caption(mainApp->windowTitleString(tr("Save Resolved Addresses As…")));
+ QString txtFilter = tr("Plain text (*.txt)");
+ QString csvFilter = tr("CSV Document (*.csv)");
+ QString jsonFilter = tr("JSON Document (*.json)");
+ QString selectedFilter;
+ QString fileName = WiresharkFileDialog::getSaveFileName(this, caption,
+ mainApp->openDialogInitialDir().canonicalPath(),
+ QString("%1;;%2;;%3").arg(txtFilter).arg(csvFilter).arg(jsonFilter),
+ &selectedFilter);
+ if (fileName.isEmpty()) {
+ return;
+ }
+
+ eResolvedAddressesExport format(EXPORT_TEXT);
+ if (selectedFilter.compare(csvFilter) == 0) {
+ format = EXPORT_CSV;
+ } else if (selectedFilter.compare(jsonFilter) == 0) {
+ format = EXPORT_JSON;
+ }
+
+ // macOS and Windows use the native file dialog, which enforces file
+ // extensions. UN*X dialogs generally don't. That's ok here, at
+ // least for the text format, because hosts and ethers and services
+ // files don't have an extension.
+ QFile saveFile(fileName);
+ if (saveFile.open(QFile::WriteOnly | QFile::Text)) {
+ QTextStream stream(&saveFile);
+ toTextStream(stream, format, selected);
+ saveFile.close();
+ } else {
+ QMessageBox::warning(this, tr("Warning").arg(saveFile.fileName()),
+ tr("Unable to save %1: %2").arg(saveFile.fileName().arg(saveFile.errorString())));
+ }
+}
+
+
+void ResolvedAddressesView::toTextStream(QTextStream& stream,
+ eResolvedAddressesExport format, bool selected) const
+{
+ if (model() == nullptr) {
+ return;
+ }
+
+ // XXX: TrafficTree and TapParameterDialog have similar
+ // "export a QAbstractItemModel to a QTextStream in TEXT, CSV or JSON"
+ // functions that could be made into common code.
+ QStringList rowText;
+ if (format == EXPORT_TEXT) {
+ if (qobject_cast<PortsModel*>(dataModel()) != nullptr) {
+ // Format of services(5)
+ if (!selected) {
+ stream << "# service-name\tport/protocol\n";
+ }
+ for (int row = 0; row < model()->rowCount(); row++) {
+ if (selected && !selectionModel()->isRowSelected(row, QModelIndex())) continue;
+ rowText.clear();
+ rowText << model()->data(model()->index(row, PORTS_COL_NAME)).toString();
+ rowText << QString("%1/%2")
+ .arg(model()->data(model()->index(row, PORTS_COL_PORT)).toString())
+ .arg(model()->data(model()->index(row, PORTS_COL_PROTOCOL)).toString());
+ stream << rowText.join("\t") << "\n";
+ }
+ } else {
+ // Format as hosts(5) and ethers(5)
+ if (!selected) {
+ for (int col = 0; col < model()->columnCount(); col++) {
+ rowText << model()->headerData(col, Qt::Horizontal).toString();
+ }
+ stream << "# " << rowText.join("\t") << "\n";
+ }
+ for (int row = 0; row < model()->rowCount(); row++) {
+ if (selected && !selectionModel()->isRowSelected(row, QModelIndex())) continue;
+ rowText.clear();
+ for (int col = 0; col < model()->columnCount(); col++) {
+ rowText << model()->data(model()->index(row, col)).toString();
+ }
+ stream << rowText.join("\t") << "\n";
+ }
+ }
+ } else if (format == EXPORT_CSV) {
+ for (int col = 0; col < model()->columnCount(); col++) {
+ rowText << model()->headerData(col, Qt::Horizontal).toString();
+ }
+ if (!selected) {
+ stream << rowText.join(",") << "\n";
+ }
+ for (int row = 0; row < model()->rowCount(); row++) {
+ if (selected && !selectionModel()->isRowSelected(row, QModelIndex())) continue;
+ rowText.clear();
+ for (int col = 0; col < model()->columnCount(); col++) {
+ QVariant v = model()->data(model()->index(row, col));
+ if (!v.isValid()) {
+ rowText << QStringLiteral("\"\"");
+ } else if (v.userType() == QMetaType::QString) {
+ rowText << QString("\"%1\"").arg(v.toString().replace('\"', "\"\""));
+ } else {
+ rowText << v.toString();
+ }
+ }
+ stream << rowText.join(",") << "\n";
+ }
+ } else if (format == EXPORT_JSON) {
+ QMap<int, QString> headers;
+ for (int col = 0; col < model()->columnCount(); col++)
+ headers.insert(col, model()->headerData(col, Qt::Horizontal, Qt::DisplayRole).toString());
+
+ QJsonArray records;
+
+ for (int row = 0; row < model()->rowCount(); row++) {
+ if (selected && !selectionModel()->isRowSelected(row, QModelIndex())) continue;
+ QJsonObject rowData;
+ foreach(int col, headers.keys()) {
+ QModelIndex idx = model()->index(row, col);
+ rowData.insert(headers[col], model()->data(idx).toString());
+ }
+ records.push_back(rowData);
+ }
+
+ QJsonDocument json;
+ json.setArray(records);
+ stream << json.toJson();
+ }
+}
diff --git a/ui/qt/widgets/resolved_addresses_view.h b/ui/qt/widgets/resolved_addresses_view.h
new file mode 100644
index 00000000..23fb707f
--- /dev/null
+++ b/ui/qt/widgets/resolved_addresses_view.h
@@ -0,0 +1,50 @@
+/** @file
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef RESOLVED_ADDRESSES_VIEW_H
+#define RESOLVED_ADDRESSES_VIEW_H
+
+#include <ui/qt/models/resolved_addresses_models.h>
+
+#include <QTableView>
+#include <QMenu>
+
+class ResolvedAddressesView : public QTableView
+{
+ Q_OBJECT
+
+public:
+ typedef enum {
+ EXPORT_TEXT,
+ EXPORT_CSV,
+ EXPORT_JSON
+ } eResolvedAddressesExport;
+
+ ResolvedAddressesView(QWidget *parent = nullptr);
+
+ QMenu* createCopyMenu(bool selected = false, QWidget *parent = nullptr);
+
+public slots:
+ void saveAs();
+
+protected:
+ void contextMenuEvent(QContextMenuEvent *e) override;
+
+private:
+ QAction *clip_action_;
+
+ AStringListListModel* dataModel() const;
+ void copyToClipboard(eResolvedAddressesExport format, bool selected);
+
+private slots:
+ void clipboardAction();
+ void toTextStream(QTextStream &stream, eResolvedAddressesExport format, bool selected = false) const;
+};
+
+#endif // RESOLVED_ADDRESSES_VIEW_H
diff --git a/ui/qt/widgets/rowmove_tree_view.cpp b/ui/qt/widgets/rowmove_tree_view.cpp
new file mode 100644
index 00000000..fa91b28e
--- /dev/null
+++ b/ui/qt/widgets/rowmove_tree_view.cpp
@@ -0,0 +1,98 @@
+/* @file
+ * Tree view that uses the model's moveRows(), if implemented, to
+ * support internalMoves. The model must also have Qt::MoveAction
+ * among the supportedDropActions, and its item flags must allow drag
+ * and drop.
+ *
+ * The normal Qt Drag and Drop approach for moves involves inserting a
+ * new row and removing the original row. That has greater generality,
+ * but works poorly for views like the I/O Graphs Dialog where a newly
+ * inserted row would require an expensive retap.
+ *
+ * Copyright 2024 John Thacker <johnthacker@gmail.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "rowmove_tree_view.h"
+
+#include <QDropEvent>
+
+RowMoveTreeView::RowMoveTreeView(QWidget *parent) : TabnavTreeView(parent)
+{
+ // QTreeViews default to row selection.
+ // setSelectionMode(QAbstractItemView::ContiguousSelection);
+ // ContiguousSelection works, but we probably want to make sure
+ // that the models we use this for can handle removing multiple
+ // rows (and that the dialogs support doing that.)
+ setDropIndicatorShown(true);
+ // We could override dragMoveEvent to have the dropIndicator cover
+ // the entire row.
+ setDragDropMode(QAbstractItemView::InternalMove);
+ // Classes can change this if they also support other drag and drop
+ // modes.
+}
+
+void RowMoveTreeView::dropEvent(QDropEvent *event)
+{
+ if (event->source() == this && (event->possibleActions() & Qt::MoveAction) && !event->isAccepted()) {
+
+ const QModelIndexList sourceIndices = selectionModel()->selectedRows();
+
+ if (sourceIndices.empty()) {
+ TabnavTreeView::dropEvent(event);
+ return;
+ }
+
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+ QModelIndex destIndex = indexAt(event->position().toPoint());
+#else
+ QModelIndex destIndex = indexAt(event->pos());
+#endif
+ if (!destIndex.isValid() || destIndex.row() == -1) {
+ destIndex = model()->index(model()->rowCount() - 1, 0);
+ }
+ // dropIndicatorPosition() can be used to determine if we're slightly
+ // above the item, slightly below the item, on top, or elsewhere in
+ // the viewPort. We will just use the row number, table-like.
+ // Note that if we setDragDropOverwriteMode(true) then there wouldn't
+ // be graphical hints in between rows, but that could cause issues
+ // if we added non internalMove handling; overriding dragMoveEvent
+ // could also change it.
+
+ const auto minmaxIndex = std::minmax_element(sourceIndices.begin(), sourceIndices.end(),
+ [](const QModelIndex &a, const QModelIndex &b)
+ { return a.row() < b.row(); }
+ );
+
+ // Only allow a contiguous selection. (This check is unnecessary
+ // if the selectionMode is SingleSelection or ContiguousSelection.)
+ // We could handle multiple ranges with multiple moveRows() calls
+ // and QPersistentModelIndexes in place of the QModelIndexes, but
+ // it gets a little confusing, especially if some indices are above
+ // the target row and some are below (the default behavior would be
+ // to move all the indices above to immediately below, and vice versa.)
+ // Microsoft Excel doesn't allow row moves unless the selected
+ // rows are contiguous, and has an alert.
+ //
+ // Note that selectionModel()->selection()->size() is *not*
+ // guaranteed to be the minimal merged number of possible ranges
+ // if the selection order was unusual, so we can't just use it.
+ if ((minmaxIndex.second->row() - minmaxIndex.first->row() + 1) == sourceIndices.size()) {
+ if (model()->moveRows(QModelIndex(), minmaxIndex.first->row(), static_cast<int>(sourceIndices.size()), QModelIndex(), destIndex.row())) {
+ // Prevent QAbstractItemView from removing the sourceIndices
+ // There's an element in the private class (dropEventMoved)
+ // that QTreeWidget and QTableWidget use via the d-pointer,
+ // but as long as the action is no longer a MoveAction when
+ // it returns it won't get removed.
+ event->setDropAction(Qt::IgnoreAction);
+ event->accept();
+ }
+ }
+ }
+ TabnavTreeView::dropEvent(event);
+}
diff --git a/ui/qt/widgets/rowmove_tree_view.h b/ui/qt/widgets/rowmove_tree_view.h
new file mode 100644
index 00000000..ac415c41
--- /dev/null
+++ b/ui/qt/widgets/rowmove_tree_view.h
@@ -0,0 +1,35 @@
+/** @file
+ *
+ * Tree view that uses a model's moveRows(), if implemented, to support
+ * internalMoves.
+ *
+ * Copyright 2024 John Thacker <johnthacker@gmail.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef ROWMOVE_TREE_VIEW_H
+#define ROWMOVE_TREE_VIEW_H
+
+#include <config.h>
+#include <ui/qt/widgets/tabnav_tree_view.h>
+
+/**
+ * Like QTreeView, but instead of changing to the next row (same column) when
+ * pressing Tab while editing, change to the next column (same row).
+ */
+class RowMoveTreeView : public TabnavTreeView
+{
+ Q_OBJECT
+
+public:
+ RowMoveTreeView(QWidget *parent = nullptr);
+
+protected:
+ void dropEvent(QDropEvent *event) override;
+};
+#endif // ROWMOVE_TREE_VIEW_H
diff --git a/ui/qt/widgets/rtp_audio_graph.cpp b/ui/qt/widgets/rtp_audio_graph.cpp
index 1340658b..58ff2f1f 100644
--- a/ui/qt/widgets/rtp_audio_graph.cpp
+++ b/ui/qt/widgets/rtp_audio_graph.cpp
@@ -9,8 +9,6 @@
#include "rtp_audio_graph.h"
-#include <glib.h>
-
#include <epan/prefs.h>
#include <ui/qt/utils/color_utils.h>
diff --git a/ui/qt/widgets/splash_overlay.h b/ui/qt/widgets/splash_overlay.h
index b15d98c4..3f5625fc 100644
--- a/ui/qt/widgets/splash_overlay.h
+++ b/ui/qt/widgets/splash_overlay.h
@@ -12,8 +12,6 @@
#include <config.h>
-#include <glib.h>
-
#include "epan/register.h"
#include <QWidget>
diff --git a/ui/qt/widgets/syntax_line_edit.cpp b/ui/qt/widgets/syntax_line_edit.cpp
index f2c32142..3e1abe96 100644
--- a/ui/qt/widgets/syntax_line_edit.cpp
+++ b/ui/qt/widgets/syntax_line_edit.cpp
@@ -9,8 +9,6 @@
#include "config.h"
-#include <glib.h>
-
#include <epan/prefs.h>
#include <epan/proto.h>
#include <epan/dfilter/dfilter.h>
@@ -86,7 +84,7 @@ void SyntaxLineEdit::setSyntaxState(SyntaxState state) {
QColor deprecated_bg = ColorUtils::fromColorT(&prefs.gui_text_deprecated);
QColor deprecated_fg = ColorUtils::contrastingTextColor(deprecated_bg);
- // Try to matche QLineEdit's placeholder text color (which sets the
+ // Try to match QLineEdit's placeholder text color (which sets the
// alpha channel to 50%, which doesn't work in style sheets).
// Setting the foreground color lets us avoid yet another background
// color preference and should hopefully make things easier to
@@ -212,7 +210,7 @@ bool SyntaxLineEdit::checkDisplayFilter(QString filter)
* We're being lazy and only printing the first warning.
* Would it be better to print all of them?
*/
- syntax_error_message_ = QString(static_cast<gchar *>(warn->data));
+ syntax_error_message_ = QString(static_cast<char *>(warn->data));
} else if (dfp != NULL && (depr = dfilter_deprecated_tokens(dfp)) != NULL) {
// You keep using that word. I do not think it means what you think it means.
// Possible alternatives: ::Troubled, or ::Problematic maybe?
@@ -222,7 +220,7 @@ bool SyntaxLineEdit::checkDisplayFilter(QString filter)
* Would it be better to print all of them?
*/
QString token((const char *)g_ptr_array_index(depr, 0));
- gchar *token_str = qstring_strdup(token.section('.', 0, 0));
+ char *token_str = qstring_strdup(token.section('.', 0, 0));
header_field_info *hfi = proto_registrar_get_byalias(token_str);
if (hfi)
syntax_error_message_ = tr("\"%1\" is deprecated in favour of \"%2\". "
@@ -267,10 +265,23 @@ void SyntaxLineEdit::checkCustomColumn(QString fields)
return;
}
- gchar **splitted_fields = g_regex_split_simple(COL_CUSTOM_PRIME_REGEX,
- fields.toUtf8().constData(), G_REGEX_ANCHORED, G_REGEX_MATCH_ANCHORED);
-
- for (guint i = 0; i < g_strv_length(splitted_fields); i++) {
+#if 0
+ // XXX - Eventually, if the operator we split on is something not supported
+ // in the filter expression syntax (so that we can distinguish multifield
+ // concatenation of column strings from a logical OR), we would split and
+ // then check each split result as a valid display filter.
+ // For now, any expression that is a valid display filter should work.
+ //
+ // We also, for the custom columns, want some of the extra completion
+ // information from DisplayFilterEdit (like the display filter functions),
+ // without all of its integration into the main app, but not every user
+ // of FieldFilterEdit wants that, so perhaps we eventually should have
+ // another class.
+ char **splitted_fields = g_regex_split_simple(COL_CUSTOM_PRIME_REGEX,
+ fields.toUtf8().constData(), (GRegexCompileFlags) G_REGEX_RAW,
+ (GRegexMatchFlags) 0);
+
+ for (unsigned i = 0; i < g_strv_length(splitted_fields); i++) {
if (splitted_fields[i] && *splitted_fields[i]) {
if (proto_check_field_name(splitted_fields[i]) != 0) {
setSyntaxState(SyntaxLineEdit::Invalid);
@@ -280,6 +291,7 @@ void SyntaxLineEdit::checkCustomColumn(QString fields)
}
}
g_strfreev(splitted_fields);
+#endif
checkDisplayFilter(fields);
}
diff --git a/ui/qt/widgets/traffic_tab.cpp b/ui/qt/widgets/traffic_tab.cpp
index 9913acaa..6233d60d 100644
--- a/ui/qt/widgets/traffic_tab.cpp
+++ b/ui/qt/widgets/traffic_tab.cpp
@@ -78,7 +78,7 @@ TrafficTab::TrafficTab(QWidget * parent) :
TrafficTab::~TrafficTab()
{}
-void TrafficTab::setProtocolInfo(QString tableName, TrafficTypesList * trafficList, GList ** recentColumnList, ATapModelCallback createModel)
+void TrafficTab::setProtocolInfo(QString tableName, TrafficTypesList * trafficList, GList ** recentList, GList ** recentColumnList, ATapModelCallback createModel)
{
setTabBasename(tableName);
@@ -86,6 +86,7 @@ void TrafficTab::setProtocolInfo(QString tableName, TrafficTypesList * trafficLi
if (createModel)
_createModel = createModel;
+ _recentList = recentList;
_recentColumnList = recentColumnList;
setOpenTabs(trafficList->protocols(true));
@@ -159,7 +160,7 @@ void TrafficTab::useAbsoluteTime(bool absolute)
{
for(int idx = 0; idx < count(); idx++)
{
- ATapDataModel * atdm = modelForTabIndex(idx);
+ ATapDataModel * atdm = dataModelForTabIndex(idx);
if (atdm)
atdm->useAbsoluteTime(absolute);
}
@@ -169,7 +170,7 @@ void TrafficTab::useNanosecondTimestamps(bool nanoseconds)
{
for(int idx = 0; idx < count(); idx++)
{
- ATapDataModel * atdm = modelForTabIndex(idx);
+ ATapDataModel * atdm = dataModelForTabIndex(idx);
if (atdm)
atdm->useNanosecondTimestamps(nanoseconds);
}
@@ -179,7 +180,7 @@ void TrafficTab::disableTap()
{
for(int idx = 0; idx < count(); idx++)
{
- ATapDataModel * atdm = modelForTabIndex(idx);
+ ATapDataModel * atdm = dataModelForTabIndex(idx);
if (atdm)
atdm->disableTap();
}
@@ -260,6 +261,12 @@ void TrafficTab::insertProtoTab(int protoId, bool emitSignals)
if (tabId >= 0)
tabBar()->setTabData(tabId, storage);
+ // Identify the last known opened tab
+ int lastOpened_protoId = -1;
+ GList *selected_tab = g_list_first(*_recentList);
+ if (selected_tab != nullptr) {
+ lastOpened_protoId = proto_get_id_by_short_name((const char *)selected_tab->data);
+ }
/* We reset the correct tab idxs. That operations is costly, but it is only
* called during this operation and ensures, that other operations do not
@@ -270,6 +277,11 @@ void TrafficTab::insertProtoTab(int protoId, bool emitSignals)
_tabs.insert(tabData.protoId(), idx);
}
+ // Restore the last known opened tab
+ if(lastOpened_protoId == protoId) {
+ setCurrentIndex(tabId);
+ }
+
if (emitSignals) {
emit tabsChanged(_tabs.keys());
emit retapRequired();
@@ -329,7 +341,7 @@ QVariant TrafficTab::currentItemData(int role)
* to ensure proper handling. Especially ConversationDialog depends on this
* method always returning data */
if (!idx.isValid()) {
- ATapDataModel * model = modelForTabIndex(currentIndex());
+ TrafficDataFilterProxy * model = modelForTabIndex(currentIndex());
idx = model->index(0, 0);
}
return idx.data(role);
@@ -365,7 +377,7 @@ void TrafficTab::modelReset()
emit tabDataChanged(tabIdx);
}
-ATapDataModel * TrafficTab::modelForTabIndex(int tabIdx)
+TrafficDataFilterProxy * TrafficTab::modelForTabIndex(int tabIdx)
{
if (tabIdx == -1)
tabIdx = currentIndex();
@@ -373,26 +385,40 @@ ATapDataModel * TrafficTab::modelForTabIndex(int tabIdx)
return modelForWidget(widget(tabIdx));
}
-ATapDataModel * TrafficTab::modelForWidget(QWidget * searchWidget)
+TrafficDataFilterProxy * TrafficTab::modelForWidget(QWidget * searchWidget)
{
if (qobject_cast<QTreeView *>(searchWidget)) {
QTreeView * tree = qobject_cast<QTreeView *>(searchWidget);
if (qobject_cast<TrafficDataFilterProxy *>(tree->model())) {
- TrafficDataFilterProxy * qsfpm = qobject_cast<TrafficDataFilterProxy *>(tree->model());
- if (qsfpm && qobject_cast<ATapDataModel *>(qsfpm->sourceModel())) {
- return qobject_cast<ATapDataModel *>(qsfpm->sourceModel());
- }
+ return qobject_cast<TrafficDataFilterProxy *>(tree->model());
}
}
return nullptr;
}
+ATapDataModel * TrafficTab::dataModelForTabIndex(int tabIdx)
+{
+ if (tabIdx == -1)
+ tabIdx = currentIndex();
+
+ return dataModelForWidget(widget(tabIdx));
+}
+
+ATapDataModel * TrafficTab::dataModelForWidget(QWidget * searchWidget)
+{
+ TrafficDataFilterProxy * qsfpm = modelForWidget(searchWidget);
+ if (qsfpm && qobject_cast<ATapDataModel *>(qsfpm->sourceModel())) {
+ return qobject_cast<ATapDataModel *>(qsfpm->sourceModel());
+ }
+ return nullptr;
+}
+
void TrafficTab::setFilter(QString filter)
{
for (int idx = 0; idx < count(); idx++ )
{
- ATapDataModel * atdm = modelForTabIndex(idx);
+ ATapDataModel * atdm = dataModelForTabIndex(idx);
if (! atdm)
continue;
atdm->setFilter(filter);
@@ -406,7 +432,7 @@ void TrafficTab::setNameResolution(bool checked)
for (int idx = 0; idx < count(); idx++ )
{
- ATapDataModel * atdm = modelForTabIndex(idx);
+ ATapDataModel * atdm = dataModelForTabIndex(idx);
if (! atdm)
continue;
atdm->setResolveNames(checked);
@@ -422,7 +448,7 @@ void TrafficTab::setNameResolution(bool checked)
bool TrafficTab::hasNameResolution(int tabIdx)
{
int tab = tabIdx == -1 || tabIdx >= count() ? currentIndex() : tabIdx;
- ATapDataModel * dataModel = modelForTabIndex(tab);
+ ATapDataModel * dataModel = dataModelForTabIndex(tab);
if (! dataModel)
return false;
@@ -443,12 +469,12 @@ bool TrafficTab::hasGeoIPData(int tabIdx)
{
int tab = tabIdx == -1 || tabIdx >= count() ? currentIndex() : tabIdx;
- ATapDataModel * dataModel = modelForTabIndex(tab);
+ ATapDataModel * dataModel = dataModelForTabIndex(tab);
return dataModel->hasGeoIPData();
}
bool
-TrafficTab::writeGeoIPMapFile(QFile * fp, bool json_only, ATapDataModel * dataModel)
+TrafficTab::writeGeoIPMapFile(QFile * fp, bool json_only, TrafficDataFilterProxy * model)
{
QTextStream out(fp);
@@ -508,14 +534,15 @@ TrafficTab::writeGeoIPMapFile(QFile * fp, bool json_only, ATapDataModel * dataMo
QJsonArray features;
/* Append map data. */
- for(int row = 0; row < dataModel->rowCount(QModelIndex()); row++)
+ for(int row = 0; row < model->rowCount(QModelIndex()); row++)
{
- QModelIndex index = dataModel->index(row, 0);
+ QModelIndex index = model->mapToSource(model->index(row, 0));
+ ATapDataModel *dataModel = qobject_cast<ATapDataModel *>(model->sourceModel());
const mmdb_lookup_t * result = VariantPointer<const mmdb_lookup_t>::asPtr(dataModel->data(index, ATapDataModel::GEODATA_LOOKUPTABLE));
if (!maxmind_db_has_coords(result)) {
// result could be NULL if the caller did not trigger a lookup
- // before. result->found could be FALSE if no MMDB entry exists.
+ // before. result->found could be false if no MMDB entry exists.
continue;
}
@@ -545,8 +572,8 @@ TrafficTab::writeGeoIPMapFile(QFile * fp, bool json_only, ATapDataModel * dataMo
if (qobject_cast<EndpointDataModel *>(dataModel)) {
EndpointDataModel * endpointModel = qobject_cast<EndpointDataModel *>(dataModel);
- property["packets"] = endpointModel->data(endpointModel->index(row, EndpointDataModel::ENDP_COLUMN_PACKETS)).toString();
- property["bytes"] = endpointModel->data(endpointModel->index(row, EndpointDataModel::ENDP_COLUMN_BYTES)).toString();
+ property["packets"] = endpointModel->data(index.siblingAtColumn(EndpointDataModel::ENDP_COLUMN_PACKETS)).toString();
+ property["bytes"] = endpointModel->data(index.siblingAtColumn(EndpointDataModel::ENDP_COLUMN_BYTES)).toString();
}
arrEntry["properties"] = property;
features.append(arrEntry);
@@ -568,7 +595,7 @@ TrafficTab::writeGeoIPMapFile(QFile * fp, bool json_only, ATapDataModel * dataMo
QUrl TrafficTab::createGeoIPMap(bool json_only, int tabIdx)
{
int tab = tabIdx == -1 || tabIdx >= count() ? currentIndex() : tabIdx;
- ATapDataModel * dataModel = modelForTabIndex(tab);
+ ATapDataModel * dataModel = dataModelForTabIndex(tab);
if (! (dataModel && dataModel->hasGeoIPData())) {
QMessageBox::warning(this, tr("Map file error"), tr("No endpoints available to map"));
return QUrl();
@@ -581,7 +608,7 @@ QUrl TrafficTab::createGeoIPMap(bool json_only, int tabIdx)
return QUrl();
}
- if (!writeGeoIPMapFile(&tf, json_only, dataModel)) {
+ if (!writeGeoIPMapFile(&tf, json_only, modelForTabIndex(tab))) {
tf.close();
return QUrl();
}
@@ -592,7 +619,7 @@ QUrl TrafficTab::createGeoIPMap(bool json_only, int tabIdx)
#endif
void TrafficTab::detachTab(int tabIdx, QPoint pos) {
- ATapDataModel * model = modelForTabIndex(tabIdx);
+ ATapDataModel * model = dataModelForTabIndex(tabIdx);
if (!model)
return;
@@ -608,7 +635,7 @@ void TrafficTab::detachTab(int tabIdx, QPoint pos) {
void TrafficTab::attachTab(QWidget * content, QString name)
{
- ATapDataModel * model = modelForWidget(content);
+ ATapDataModel * model = dataModelForWidget(content);
if (!model) {
attachTab(content, name);
return;
diff --git a/ui/qt/widgets/traffic_tab.h b/ui/qt/widgets/traffic_tab.h
index 71c48ae5..ff0bacc5 100644
--- a/ui/qt/widgets/traffic_tab.h
+++ b/ui/qt/widgets/traffic_tab.h
@@ -12,10 +12,9 @@
#include "config.h"
-#include <glib.h>
-
#include <ui/qt/models/atap_data_model.h>
#include <ui/qt/filter_action.h>
+#include <ui/qt/widgets/traffic_tree.h>
#include <ui/qt/widgets/detachable_tabwidget.h>
#include <ui/qt/widgets/traffic_types_list.h>
@@ -94,7 +93,7 @@ public:
*
* @see ATapModelCallback
*/
- void setProtocolInfo(QString tableName, TrafficTypesList * trafficList, GList ** recentColumnList, ATapModelCallback createModel);
+ void setProtocolInfo(QString tableName, TrafficTypesList * trafficList, GList ** recentList, GList ** recentColumnList, ATapModelCallback createModel);
/**
* @brief Set the Delegate object for the tab. It will apply for all
@@ -221,20 +220,23 @@ private:
QMap<int, int> _tabs;
ATapModelCallback _createModel;
ATapCreateDelegate _createDelegate;
+ GList ** _recentList;
GList ** _recentColumnList;
bool _disableTaps;
bool _nameResolution;
QTreeView * createTree(int protoId);
- ATapDataModel * modelForTabIndex(int tabIdx = -1);
- ATapDataModel * modelForWidget(QWidget * widget);
+ TrafficDataFilterProxy * modelForTabIndex(int tabIdx = -1);
+ TrafficDataFilterProxy * modelForWidget(QWidget * widget);
+ ATapDataModel * dataModelForTabIndex(int tabIdx = -1);
+ ATapDataModel * dataModelForWidget(QWidget * widget);
void insertProtoTab(int protoId, bool emitSignals = true);
void removeProtoTab(int protoId, bool emitSignals = true);
#ifdef HAVE_MAXMINDDB
- bool writeGeoIPMapFile(QFile * fp, bool json_only, ATapDataModel * dataModel);
+ bool writeGeoIPMapFile(QFile * fp, bool json_only, TrafficDataFilterProxy * model);
#endif
private slots:
diff --git a/ui/qt/widgets/traffic_tree.cpp b/ui/qt/widgets/traffic_tree.cpp
index be154d7d..4325e556 100644
--- a/ui/qt/widgets/traffic_tree.cpp
+++ b/ui/qt/widgets/traffic_tree.cpp
@@ -204,7 +204,7 @@ void TrafficTreeHeaderView::columnTriggered(bool checked)
for (int col = 0; col < tree->dataModel()->columnCount(); col++) {
if (proxy->columnVisible(col)) {
visible << col;
- gchar *nr = qstring_strdup(QString::number(col));
+ char *nr = qstring_strdup(QString::number(col));
*_recentColumnList = g_list_append(*_recentColumnList, nr);
}
}
@@ -473,7 +473,35 @@ bool TrafficDataFilterProxy::lessThan(const QModelIndex &source_left, const QMod
int addressTypeA = model->data(source_left, ATapDataModel::DATA_ADDRESS_TYPE).toInt();
int addressTypeB = model->data(source_right, ATapDataModel::DATA_ADDRESS_TYPE).toInt();
if (addressTypeA != 0 && addressTypeB != 0 && addressTypeA != addressTypeB) {
- result = addressTypeA < addressTypeB;
+
+ /* Handle subnets when they are compared to IP addresses */
+ if ( (addressTypeA == AT_STRINGZ) && (addressTypeB == AT_IPv4) ) {
+ QString subnet = datA.toString();
+ qint64 lpart = subnet.indexOf("/");
+ ws_in4_addr ip4addr;
+
+ if(ws_inet_pton4(subnet.left(lpart).toUtf8().data(), &ip4addr)) {
+ quint32 valA = g_ntohl(ip4addr);
+ quint32 valB = model->data(source_right, ATapDataModel::DATA_IPV4_INTEGER).value<quint32>();
+ result = valA < valB;
+ identical = valA == valB;
+ }
+ // else: never supposed to happen
+ } else if ( (addressTypeA == AT_IPv4) && (addressTypeB == AT_STRINGZ) ) {
+ QString subnet = datB.toString();
+ qint64 lpart = subnet.indexOf("/");
+ ws_in4_addr ip4addr;
+ if(ws_inet_pton4(subnet.left(lpart).toUtf8().data(), &ip4addr)) {
+ quint32 valA = model->data(source_left, ATapDataModel::DATA_IPV4_INTEGER).value<quint32>();
+ quint32 valB = g_ntohl(ip4addr);
+ result = valA < valB;
+ identical = valA == valB;
+ }
+ // else: never supposed to happen
+ } else {
+ result = addressTypeA < addressTypeB;
+ }
+
} else if (addressTypeA != 0 && addressTypeA == addressTypeB) {
if (addressTypeA == AT_IPv4) {
@@ -693,8 +721,28 @@ QMenu * TrafficTree::createActionSubMenu(FilterAction::Action cur_action, QModel
foreach (FilterAction::ActionType at, FilterAction::actionTypes()) {
if (isConversation && conv_item) {
QMenu *subsubmenu = subMenu->addMenu(FilterAction::actionTypeName(at));
- if (hasConvId && (cur_action == FilterAction::ActionApply || cur_action == FilterAction::ActionPrepare)) {
- QString filter = QString("%1.stream eq %2").arg(conv_item->ctype == CONVERSATION_TCP ? "tcp" : "udp").arg(conv_item->conv_id);
+
+ /* For IP, ensure subnets-like conversations won't enable Stream ID filters (!CONV_ID_UNSET) */
+ if (hasConvId && (conv_item->conv_id!=CONV_ID_UNSET) && (cur_action == FilterAction::ActionApply || cur_action == FilterAction::ActionPrepare)) {
+ QString filter;
+ switch (conv_item->ctype) {
+ case CONVERSATION_TCP:
+ filter = QString("%1.stream eq %2").arg("tcp").arg(conv_item->conv_id);
+ break;
+ case CONVERSATION_UDP:
+ filter = QString("%1.stream eq %2").arg("udp").arg(conv_item->conv_id);
+ break;
+ case CONVERSATION_IP:
+ filter = QString("%1.stream eq %2").arg("ip").arg(conv_item->conv_id);
+ break;
+ case CONVERSATION_IPV6:
+ filter = QString("%1.stream eq %2").arg("ipv6").arg(conv_item->conv_id);
+ break;
+ case CONVERSATION_ETH:
+ default:
+ filter = QString("%1.stream eq %2").arg("eth").arg(conv_item->conv_id);
+ break;
+ }
FilterAction * act = new FilterAction(subsubmenu, cur_action, at, tr("Filter on stream id"));
act->setProperty("filter", filter);
subsubmenu->addAction(act);
diff --git a/ui/qt/widgets/traffic_tree.h b/ui/qt/widgets/traffic_tree.h
index 5bc87e91..00d91783 100644
--- a/ui/qt/widgets/traffic_tree.h
+++ b/ui/qt/widgets/traffic_tree.h
@@ -12,8 +12,6 @@
#include "config.h"
-#include <glib.h>
-
#include <ui/recent.h>
#include <ui/qt/models/atap_data_model.h>
diff --git a/ui/qt/widgets/traffic_types_list.cpp b/ui/qt/widgets/traffic_types_list.cpp
index 30126ef9..ddbe34a3 100644
--- a/ui/qt/widgets/traffic_types_list.cpp
+++ b/ui/qt/widgets/traffic_types_list.cpp
@@ -9,9 +9,8 @@
#include "config.h"
-#include <glib.h>
-
#include <epan/conversation_table.h>
+#include <epan/prefs.h>
#include <ui/qt/widgets/traffic_types_list.h>
@@ -48,12 +47,12 @@ static bool iterateProtocols(const void *key, void *value, void *userdata)
QList<TrafficTypesRowData> * protocols = (QList<TrafficTypesRowData> *)userdata;
register_ct_t* ct = (register_ct_t*)value;
- const QString title = (const gchar*)key;
+ const QString title = (const char*)key;
int proto_id = get_conversation_proto_id(ct);
TrafficTypesRowData entry(proto_id, title);
protocols->append(entry);
- return FALSE;
+ return false;
}
TrafficTypesModel::TrafficTypesModel(GList ** recentList, QObject *parent) :
@@ -152,6 +151,26 @@ bool TrafficTypesModel::setData(const QModelIndex &idx, const QVariant &value, i
if (_allTaps.count() <= idx.row())
return false;
+ // When updating the tabs, save the current selection, it will be restored below
+ GList *selected_tab = g_list_first(*_recentList);
+ int rct_protoId = -1;
+ if (selected_tab != nullptr) {
+ rct_protoId = proto_get_id_by_short_name((const char *)selected_tab->data);
+
+ // Did the user just uncheck the current selection?
+ if (_allTaps[idx.row()].protocol() == rct_protoId && value.toInt() == Qt::Unchecked) {
+ // Yes. The code below will restore it. Rather than removing it,
+ // resetting the model, and then adding it back, just return.
+ // The user might want to uncheck the current selection, in which
+ // case the code needs to changed to handle that.
+ //
+ // Note that not allowing the current first tab to be unselected does
+ // have the advantage of preventing a crash from having no tabs
+ // selected in the Endpoint dialog (#18250).
+ return false;
+ }
+ }
+
_allTaps[idx.row()].setChecked(value.toInt() == Qt::Checked);
QList<int> selected;
@@ -161,12 +180,21 @@ bool TrafficTypesModel::setData(const QModelIndex &idx, const QVariant &value, i
for (int cnt = 0; cnt < _allTaps.count(); cnt++) {
if (_allTaps[cnt].checked()) {
int protoId = _allTaps[cnt].protocol();
- selected.append(protoId);
- char *title = g_strdup(proto_get_protocol_short_name(find_protocol_by_id(protoId)));
- *_recentList = g_list_append(*_recentList, title);
+ if(protoId != rct_protoId) {
+ selected.append(protoId);
+ char *title = g_strdup(proto_get_protocol_short_name(find_protocol_by_id(protoId)));
+ *_recentList = g_list_append(*_recentList, title);
+ }
}
}
+ if (rct_protoId != -1) {
+ // restore the selection by prepending it to the recent list
+ char *rct_title = g_strdup(proto_get_protocol_short_name(find_protocol_by_id(rct_protoId)));
+ selected.prepend(rct_protoId);
+ *_recentList = g_list_prepend(*_recentList, rct_title);
+ }
+
emit protocolsChanged(selected);
emit dataChanged(idx, idx);
diff --git a/ui/qt/widgets/traffic_types_list.h b/ui/qt/widgets/traffic_types_list.h
index 00798c50..2666eb78 100644
--- a/ui/qt/widgets/traffic_types_list.h
+++ b/ui/qt/widgets/traffic_types_list.h
@@ -12,8 +12,6 @@
#include "config.h"
-#include <glib.h>
-
#include <QTreeView>
#include <QAbstractListModel>
#include <QMap>
@@ -122,4 +120,4 @@ private:
TrafficListSortModel * _sortModel;
};
-#endif // TRAFFIC_TYPES_LIST_H \ No newline at end of file
+#endif // TRAFFIC_TYPES_LIST_H
diff --git a/ui/qt/widgets/wireless_timeline.cpp b/ui/qt/widgets/wireless_timeline.cpp
index dcdcd4f8..87eb1079 100644
--- a/ui/qt/widgets/wireless_timeline.cpp
+++ b/ui/qt/widgets/wireless_timeline.cpp
@@ -75,7 +75,7 @@ static void reset_rgb(float rgb[TIMELINE_HEIGHT][3])
rgb[i][0] = rgb[i][1] = rgb[i][2] = 1.0;
}
-static void render_pixels(QPainter &p, gint x, gint width, float rgb[TIMELINE_HEIGHT][3], float ratio)
+static void render_pixels(QPainter &p, int x, int width, float rgb[TIMELINE_HEIGHT][3], float ratio)
{
int previous = 0, i;
for (i = 1; i <= TIMELINE_HEIGHT; i++) {
@@ -92,7 +92,7 @@ static void render_pixels(QPainter &p, gint x, gint width, float rgb[TIMELINE_HE
reset_rgb(rgb);
}
-static void render_rectangle(QPainter &p, gint x, gint width, guint height, int dfilter, float r, float g, float b, float ratio)
+static void render_rectangle(QPainter &p, int x, int width, unsigned height, int dfilter, float r, float g, float b, float ratio)
{
p.fillRect(QRectF(x/ratio, TIMELINE_HEIGHT/2-height, width/ratio, dfilter ? height * 2 : height), pcolor(r,g,b));
}
@@ -157,29 +157,25 @@ void WirelessTimeline::mouseReleaseEvent(QMouseEvent *event)
return;
/* this was a click */
- guint num = find_packet(localPos.x());
+ unsigned num = find_packet(localPos.x());
if (num == 0)
return;
- frame_data *fdata = frame_data_sequence_find(cfile.provider.frames, num);
- if (!fdata->passed_dfilter && fdata->prev_dis_num > 0)
- num = fdata->prev_dis_num;
-
- cf_goto_frame(&cfile, num);
+ cf_goto_frame(&cfile, num, false);
}
void WirelessTimeline::clip_tsf()
{
// did we go past the start of the file?
- if (((gint64) start_tsf) < ((gint64) first->start_tsf)) {
+ if (((int64_t) start_tsf) < ((int64_t) first->start_tsf)) {
// align the start of the file at the left edge
- guint64 shift = first->start_tsf - start_tsf;
+ uint64_t shift = first->start_tsf - start_tsf;
start_tsf += shift;
end_tsf += shift;
}
if (end_tsf > last->end_tsf) {
- guint64 shift = end_tsf - last->end_tsf;
+ uint64_t shift = end_tsf - last->end_tsf;
start_tsf -= shift;
end_tsf -= shift;
}
@@ -194,32 +190,32 @@ void WirelessTimeline::selectedFrameChanged(QList<int>)
if (cfile.current_frame) {
struct wlan_radio *wr = get_wlan_radio(cfile.current_frame->num);
- guint left_margin = 0.9 * start_tsf + 0.1 * end_tsf;
- guint right_margin = 0.1 * start_tsf + 0.9 * end_tsf;
- guint64 half_window = (end_tsf - start_tsf)/2;
+ unsigned left_margin = 0.9 * start_tsf + 0.1 * end_tsf;
+ unsigned right_margin = 0.1 * start_tsf + 0.9 * end_tsf;
+ uint64_t half_window = (end_tsf - start_tsf)/2;
if (wr) {
// are we to the left of the left margin?
if (wr->start_tsf < left_margin) {
// scroll the left edge back to the left margin
- guint64 offset = left_margin - wr->start_tsf;
+ uint64_t offset = left_margin - wr->start_tsf;
if (offset < half_window) {
// small movement; keep packet to margin
start_tsf -= offset;
end_tsf -= offset;
} else {
// large movement; move packet to center of window
- guint64 center = (wr->start_tsf + wr->end_tsf)/2;
+ uint64_t center = (wr->start_tsf + wr->end_tsf)/2;
start_tsf = center - half_window;
end_tsf = center + half_window;
}
} else if (wr->end_tsf > right_margin) {
- guint64 offset = wr->end_tsf - right_margin;
+ uint64_t offset = wr->end_tsf - right_margin;
if (offset < half_window) {
start_tsf += offset;
end_tsf += offset;
} else {
- guint64 center = (wr->start_tsf + wr->end_tsf)/2;
+ uint64_t center = (wr->start_tsf + wr->end_tsf)/2;
start_tsf = center - half_window;
end_tsf = center + half_window;
}
@@ -234,10 +230,10 @@ void WirelessTimeline::selectedFrameChanged(QList<int>)
/* given an x position find which packet that corresponds to.
* if it's inter frame space the subsequent packet is returned */
-guint
+unsigned
WirelessTimeline::find_packet(qreal x_position)
{
- guint64 x_time = start_tsf + (x_position/width() * (end_tsf - start_tsf));
+ uint64_t x_time = start_tsf + (x_position/width() * (end_tsf - start_tsf));
return find_packet_tsf(x_time);
}
@@ -267,7 +263,7 @@ void WirelessTimeline::captureFileReadFinished()
*/
/* TODO: update GUI to handle captures with occasional frames missing TSF data */
/* TODO: indicate error message to the user */
- for (guint32 n = 1; n < cfile.count; n++) {
+ for (uint32_t n = 1; n < cfile.count; n++) {
struct wlan_radio *w = get_wlan_radio(n);
if (w->start_tsf == 0 || w->end_tsf == 0) {
QString err = tr("Packet number %1 does not include TSF timestamp, not showing timeline.").arg(n);
@@ -315,11 +311,11 @@ void WirelessTimeline::resizeEvent(QResizeEvent*)
// Calculate the x position on the GUI from the timestamp
-int WirelessTimeline::position(guint64 tsf, float ratio)
+int WirelessTimeline::position(uint64_t tsf, float ratio)
{
int position = -100;
- if (tsf != G_MAXUINT64) {
+ if (tsf != UINT64_MAX) {
position = ((double) tsf - start_tsf)*width()*ratio/(end_tsf-start_tsf);
}
return position;
@@ -378,11 +374,11 @@ tap_packet_status WirelessTimeline::tap_timeline_packet(void *tapdata, packet_in
const struct wlan_radio *wlan_radio_info = (const struct wlan_radio *)data;
/* Save the radio information in our own (GUI) hashtable */
- g_hash_table_insert(timeline->radio_packet_list, GUINT_TO_POINTER(pinfo->num), (gpointer)wlan_radio_info);
+ g_hash_table_insert(timeline->radio_packet_list, GUINT_TO_POINTER(pinfo->num), (void *)wlan_radio_info);
return TAP_PACKET_DONT_REDRAW;
}
-struct wlan_radio* WirelessTimeline::get_wlan_radio(guint32 packet_num)
+struct wlan_radio* WirelessTimeline::get_wlan_radio(uint32_t packet_num)
{
return (struct wlan_radio*)g_hash_table_lookup(radio_packet_list, GUINT_TO_POINTER(packet_num));
}
@@ -402,7 +398,7 @@ bool WirelessTimeline::event(QEvent *event)
{
if (event->type() == QEvent::ToolTip) {
QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
- guint packet = find_packet(helpEvent->pos().x());
+ unsigned packet = find_packet(helpEvent->pos().x());
if (packet) {
doToolTip(get_wlan_radio(packet), helpEvent->globalPos(), helpEvent->x());
} else {
@@ -452,16 +448,16 @@ void WirelessTimeline::bgColorizationProgress(int first, int last)
void WirelessTimeline::zoom(double x_fraction)
{
/* adjust the zoom around the selected packet */
- guint64 file_range = last->end_tsf - first->start_tsf;
- guint64 center = start_tsf + x_fraction * (end_tsf - start_tsf);
- guint64 span = pow(file_range, 1.0 - zoom_level / TIMELINE_MAX_ZOOM);
+ uint64_t file_range = last->end_tsf - first->start_tsf;
+ uint64_t center = start_tsf + x_fraction * (end_tsf - start_tsf);
+ uint64_t span = pow(file_range, 1.0 - zoom_level / TIMELINE_MAX_ZOOM);
start_tsf = center - span * x_fraction;
end_tsf = center + span * (1.0 - x_fraction);
clip_tsf();
update();
}
-int WirelessTimeline::find_packet_tsf(guint64 tsf)
+int WirelessTimeline::find_packet_tsf(uint64_t tsf)
{
if (cfile.count < 1)
return 0;
@@ -469,11 +465,11 @@ int WirelessTimeline::find_packet_tsf(guint64 tsf)
if (cfile.count < 2)
return 1;
- guint32 min_count = 1;
- guint32 max_count = cfile.count-1;
+ uint32_t min_count = 1;
+ uint32_t max_count = cfile.count-1;
- guint64 min_tsf = get_wlan_radio(min_count)->end_tsf;
- guint64 max_tsf = get_wlan_radio(max_count)->end_tsf;
+ uint64_t min_tsf = get_wlan_radio(min_count)->end_tsf;
+ uint64_t max_tsf = get_wlan_radio(max_count)->end_tsf;
for (;;) {
if (tsf >= max_tsf)
@@ -482,11 +478,11 @@ int WirelessTimeline::find_packet_tsf(guint64 tsf)
if (tsf < min_tsf)
return min_count;
- guint32 middle = (min_count + max_count)/2;
+ uint32_t middle = (min_count + max_count)/2;
if (middle == min_count)
return middle+1;
- guint64 middle_tsf = get_wlan_radio(middle)->end_tsf;
+ uint64_t middle_tsf = get_wlan_radio(middle)->end_tsf;
if (tsf >= middle_tsf) {
min_count = middle;
@@ -550,9 +546,9 @@ WirelessTimeline::paintEvent(QPaintEvent *qpe)
if (ri == NULL) continue;
- gint8 rssi = ri->aggregate ? ri->aggregate->rssi : ri->rssi;
- guint height = (rssi+100)/2;
- gint end_nav;
+ int8_t rssi = ri->aggregate ? ri->aggregate->rssi : ri->rssi;
+ unsigned height = (rssi+100)/2;
+ int end_nav;
/* leave a margin above the packets so the selected packet can be seen */
if (height > TIMELINE_HEIGHT/2-6)
@@ -567,7 +563,7 @@ WirelessTimeline::paintEvent(QPaintEvent *qpe)
if (ri->start_tsf == 0 || ri->end_tsf == 0)
continue;
- x = ((gint64) (ri->start_tsf - start_tsf))*zoom;
+ x = ((int64_t) (ri->start_tsf - start_tsf))*zoom;
/* is there a previous anti-aliased pixel to output */
if (last_x >= 0 && ((int) x) != last_x) {
/* write it out now */
@@ -606,7 +602,7 @@ WirelessTimeline::paintEvent(QPaintEvent *qpe)
/* record NAV field at higher magnifications */
end_nav = x + width + ri->nav*zoom;
if (zoom >= 0.01 && ri->nav && end_nav > 0) {
- gint y = 2*(packet % (TIMELINE_HEIGHT/2));
+ int y = 2*(packet % (TIMELINE_HEIGHT/2));
qs.addLine(QLineF((x+width)/ratio, y, end_nav/ratio, y), QPen(pcolor(red,green,blue)));
}
diff --git a/ui/qt/widgets/wireless_timeline.h b/ui/qt/widgets/wireless_timeline.h
index de43d123..cf67ff4e 100644
--- a/ui/qt/widgets/wireless_timeline.h
+++ b/ui/qt/widgets/wireless_timeline.h
@@ -21,8 +21,6 @@
#include <config.h>
-#include <glib.h>
-
#include "file.h"
#include "ui/ws_ui_util.h"
@@ -75,21 +73,21 @@ protected:
static void tap_timeline_reset(void* tapdata);
static tap_packet_status tap_timeline_packet(void *tapdata, packet_info* pinfo, epan_dissect_t* edt, const void *data, tap_flags_t flags);
- struct wlan_radio* get_wlan_radio(guint32 packet_num);
+ struct wlan_radio* get_wlan_radio(uint32_t packet_num);
void clip_tsf();
- int position(guint64 tsf, float ratio);
- int find_packet_tsf(guint64 tsf);
+ int position(uint64_t tsf, float ratio);
+ int find_packet_tsf(uint64_t tsf);
void doToolTip(struct wlan_radio *wr, QPoint pos, int x);
void zoom(double x_fraction);
double zoom_level;
qreal start_x, last_x;
PacketList *packet_list;
- guint find_packet(qreal x);
+ unsigned find_packet(qreal x);
float rgb[TIMELINE_HEIGHT][3];
- guint64 start_tsf;
- guint64 end_tsf;
+ uint64_t start_tsf;
+ uint64_t end_tsf;
int first_packet; /* first packet displayed */
struct wlan_radio *first, *last;
capture_file *capfile;
diff --git a/ui/qt/widgets/wireshark_file_dialog.cpp b/ui/qt/widgets/wireshark_file_dialog.cpp
index acf9c7db..3c5b8d3e 100644
--- a/ui/qt/widgets/wireshark_file_dialog.cpp
+++ b/ui/qt/widgets/wireshark_file_dialog.cpp
@@ -43,6 +43,15 @@ WiresharkFileDialog::WiresharkFileDialog(QWidget *parent, const QString &caption
#endif
}
+QString WiresharkFileDialog::selectedNativePath() const
+{
+ if (selectedFiles().isEmpty()) {
+ // The API implies this can't happen
+ return QString();
+ }
+ return QDir::toNativeSeparators(selectedFiles().at(0));
+}
+
QString WiresharkFileDialog::getExistingDirectory(QWidget *parent, const QString &caption, const QString &dir, Options options)
{
#ifdef Q_OS_WIN
@@ -52,7 +61,7 @@ QString WiresharkFileDialog::getExistingDirectory(QWidget *parent, const QString
#ifdef Q_OS_WIN
revert_thread_per_monitor_v2_awareness(da_ctx);
#endif
- return ed;
+ return QDir::toNativeSeparators(ed);
}
QString WiresharkFileDialog::getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, Options options)
@@ -64,7 +73,7 @@ QString WiresharkFileDialog::getOpenFileName(QWidget *parent, const QString &cap
#ifdef Q_OS_WIN
revert_thread_per_monitor_v2_awareness(da_ctx);
#endif
- return ofn;
+ return QDir::toNativeSeparators(ofn);
}
QString WiresharkFileDialog::getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, Options options)
@@ -76,5 +85,5 @@ QString WiresharkFileDialog::getSaveFileName(QWidget *parent, const QString &cap
#ifdef Q_OS_WIN
revert_thread_per_monitor_v2_awareness(da_ctx);
#endif
- return sfn;
+ return QDir::toNativeSeparators(sfn);
}
diff --git a/ui/qt/widgets/wireshark_file_dialog.h b/ui/qt/widgets/wireshark_file_dialog.h
index 43ac67a6..7d452b3d 100644
--- a/ui/qt/widgets/wireshark_file_dialog.h
+++ b/ui/qt/widgets/wireshark_file_dialog.h
@@ -15,6 +15,11 @@
/**
* @brief The WiresharkFileDialog class
*
+ * Qt uses '/' as a universal path separator and converts to native path
+ * separators, i.e., '\' on Windows, only immediately before displaying a
+ * path to a user. This class can return the path with native path
+ * separators.
+ *
* Qt <= 5.9 supports setting old (Windows 8.1) per-monitor DPI awareness
* via Qt:AA_EnableHighDpiScaling. We do this in main.cpp. In order for
* native dialogs to be rendered correctly we need to set per-monitor
@@ -23,13 +28,15 @@
* we need to revert our thread context when we're done.
* The class functions below are simple wrappers around their QFileDialog
* equivalents that set PMv2 awareness before showing native dialogs on
- * Windows and resets it afterward.
+ * Windows and resets it afterward. They also return the result with native
+ * directory separators on Windows.
*/
class WiresharkFileDialog : public QFileDialog
{
public:
WiresharkFileDialog(QWidget *parent = nullptr, const QString &caption = QString(), const QString &directory = QString(), const QString &filter = QString());
+ QString selectedNativePath() const;
static QString getExistingDirectory(QWidget *parent = Q_NULLPTR, const QString &caption = QString(), const QString &dir = QString(), Options options = ShowDirsOnly);
static QString getOpenFileName(QWidget *parent = Q_NULLPTR, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = Q_NULLPTR, Options options = Options());
static QString getSaveFileName(QWidget *parent = Q_NULLPTR, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = Q_NULLPTR, Options options = Options());
diff --git a/ui/qt/wireless_frame.cpp b/ui/qt/wireless_frame.cpp
index 2247b113..4b5e14c2 100644
--- a/ui/qt/wireless_frame.cpp
+++ b/ui/qt/wireless_frame.cpp
@@ -12,8 +12,6 @@
#include "config.h"
-#include <glib.h>
-
#include <capture/capture_session.h>
#include <capture/capture_sync.h>
@@ -23,6 +21,7 @@
#include <wsutil/utf8_entities.h>
#include <wsutil/802_11-utils.h>
#include "main_application.h"
+#include "utils/qt_ui_utils.h"
#include <QProcess>
#include <QAbstractItemView>
@@ -129,7 +128,7 @@ void WirelessFrame::updateInterfaceList()
ws80211_free_interfaces(interfaces_);
interfaces_ = ws80211_find_interfaces();
const QString old_iface = ui->interfaceComboBox->currentText();
- guint iface_count = 0;
+ unsigned iface_count = 0;
bool list_changed = false;
// Don't interfere with user activity.
@@ -148,7 +147,7 @@ void WirelessFrame::updateInterfaceList()
if ((int) iface_count != ui->interfaceComboBox->count()) {
list_changed = true;
} else {
- for (guint i = 0; i < iface_count; i++) {
+ for (unsigned i = 0; i < iface_count; i++) {
struct ws80211_interface *iface = g_array_index(interfaces_, struct ws80211_interface *, i);
if (ui->interfaceComboBox->itemText(i).compare(iface->ifname) != 0) {
list_changed = true;
@@ -159,7 +158,7 @@ void WirelessFrame::updateInterfaceList()
if (list_changed) {
ui->interfaceComboBox->clear();
- for (guint i = 0; i < iface_count; i++) {
+ for (unsigned i = 0; i < iface_count; i++) {
struct ws80211_interface *iface = g_array_index(interfaces_, struct ws80211_interface *, i);
ui->interfaceComboBox->addItem(iface->ifname);
if (old_iface.compare(iface->ifname) == 0) {
@@ -226,7 +225,7 @@ void WirelessFrame::getInterfaceInfo()
return;
}
- for (guint i = 0; i < interfaces_->len; i++) {
+ for (unsigned i = 0; i < interfaces_->len; i++) {
struct ws80211_interface *iface = g_array_index(interfaces_, struct ws80211_interface *, i);
if (cur_iface.compare(iface->ifname) == 0) {
struct ws80211_iface_info iface_info;
@@ -234,8 +233,8 @@ void WirelessFrame::getInterfaceInfo()
ws80211_get_iface_info(iface->ifname, &iface_info);
- for (guint j = 0; j < iface->frequencies->len; j++) {
- guint32 frequency = g_array_index(iface->frequencies, guint32, j);
+ for (unsigned j = 0; j < iface->frequencies->len; j++) {
+ uint32_t frequency = g_array_index(iface->frequencies, uint32_t, j);
double ghz = frequency / 1000.0;
QString chan_str = QString("%1 " UTF8_MIDDLE_DOT " %2%3")
.arg(ieee80211_mhz_to_chan(frequency))
@@ -304,15 +303,15 @@ void WirelessFrame::setInterfaceInfo()
int chan_type = ui->channelTypeComboBox->itemData(cur_type_idx).toInt();
int bandwidth = getBandwidthFromChanType(chan_type);
int center_freq = getCenterFrequency(frequency, bandwidth);
- const gchar *chan_type_s = ws80211_chan_type_to_str(chan_type);
- gchar *center_freq_s = NULL;
- gchar *data, *primary_msg, *secondary_msg;
+ const char *chan_type_s = ws80211_chan_type_to_str(chan_type);
+ char *center_freq_s = NULL;
+ char *data, *primary_msg, *secondary_msg;
int ret;
if (frequency < 0 || chan_type < 0) return;
if (center_freq != -1) {
- center_freq_s = g_strdup(QString::number(center_freq).toUtf8().constData());
+ center_freq_s = qstring_strdup(QString::number(center_freq));
}
ret = sync_interface_set_80211_chan(cur_iface.toUtf8().constData(),
diff --git a/ui/qt/wireshark_application.cpp b/ui/qt/wireshark_application.cpp
index 7b37dabc..40f9443c 100644
--- a/ui/qt/wireshark_application.cpp
+++ b/ui/qt/wireshark_application.cpp
@@ -9,7 +9,7 @@
#include "wireshark_application.h"
-WiresharkApplication *wsApp = NULL;
+WiresharkApplication *wsApp;
WiresharkApplication::WiresharkApplication(int &argc, char **argv) :
MainApplication(argc, argv)
diff --git a/ui/qt/wireshark_de.ts b/ui/qt/wireshark_de.ts
index 28d3c38b..35255910 100644
--- a/ui/qt/wireshark_de.ts
+++ b/ui/qt/wireshark_de.ts
@@ -44,8 +44,8 @@
<translation>Ordner</translation>
</message>
<message>
- <source>Filter by path</source>
- <translation>Nach Pfad filtern</translation>
+ <source>Search Folders</source>
+ <translation>Ordner suchen</translation>
</message>
<message>
<source>Plugins</source>
@@ -80,6 +80,14 @@
<translation>Lizenzen</translation>
</message>
<message>
+ <source>About Logray</source>
+ <translation>Über Logray</translation>
+ </message>
+ <message>
+ <source>Logray</source>
+ <translation>Logray</translation>
+ </message>
+ <message>
<source>The directory does not exist</source>
<translation>Das Verzeichnis existiert nicht</translation>
</message>
@@ -755,6 +763,28 @@
</message>
</context>
<context>
+ <name>CaptureCommentDialog</name>
+ <message>
+ <source>Edit Capture Comments</source>
+ <translation>Aufzeichnungskommentare bearbeiten</translation>
+ </message>
+ <message>
+ <source>Add Comment</source>
+ <translation>Kommentar hinzufügen</translation>
+ </message>
+ <message>
+ <source>Section %1</source>
+ <translation>Bereich %1</translation>
+ </message>
+</context>
+<context>
+ <name>CaptureCommentTabWidget</name>
+ <message>
+ <source>Comment %1</source>
+ <translation>Kommentar %1</translation>
+ </message>
+</context>
+<context>
<name>CaptureFile</name>
<message>
<source> [closing]</source>
@@ -863,10 +893,6 @@
<translation>Lesefilter:</translation>
</message>
<message>
- <source>Compress with g&amp;zip</source>
- <translation>Mit g&amp;zip komprimieren</translation>
- </message>
- <message>
<source>Open Capture File</source>
<oldsource>Wireshark: Open Capture File</oldsource>
<translation>Mitschnittdatei öffnen</translation>
@@ -948,8 +974,8 @@
<translation>Details</translation>
</message>
<message>
- <source>Capture file comments</source>
- <translation>Mitschnittdateikommentare</translation>
+ <source>Edit Comments</source>
+ <translation>Kommentare bearbeiten</translation>
</message>
<message>
<source>Refresh</source>
@@ -960,10 +986,6 @@
<translation>In die Zwischenablage kopieren</translation>
</message>
<message>
- <source>Save Comments</source>
- <translation>Kommentar speichern</translation>
- </message>
- <message>
<source>Capture File Properties</source>
<translation>Mitschnittdateieigenschaften</translation>
</message>
@@ -1012,10 +1034,18 @@
<translation>Erstes Paket</translation>
</message>
<message>
+ <source>First event</source>
+ <translation>Erstes Ereignis</translation>
+ </message>
+ <message>
<source>Last packet</source>
<translation>Letztes Paket</translation>
</message>
<message>
+ <source>Last event</source>
+ <translation>Letztes Ereignis</translation>
+ </message>
+ <message>
<source>Elapsed</source>
<translation>Zeitspanne</translation>
</message>
@@ -1052,6 +1082,10 @@
<translation>Verworfene Pakete</translation>
</message>
<message>
+ <source>Dropped events</source>
+ <translation>Verworfene Ereignisse</translation>
+ </message>
+ <message>
<source>Capture filter</source>
<translation>Mitschnittfilter</translation>
</message>
@@ -1064,6 +1098,10 @@
<translation>Paketgrößenlimit (snaplen)</translation>
</message>
<message>
+ <source>Event size limit (snaplen)</source>
+ <translation>Max. Ereignisgröße (snaplen)</translation>
+ </message>
+ <message>
<source>none</source>
<translation>keine</translation>
</message>
@@ -1072,6 +1110,26 @@
<translation>%1 Byte</translation>
</message>
<message>
+ <source>Comments</source>
+ <translation>Kommentare</translation>
+ </message>
+ <message>
+ <source>Comment %1: </source>
+ <translation>Kommentar %1:</translation>
+ </message>
+ <message>
+ <source>Decryption Secrets</source>
+ <translation>Entschlüsselungs-Secrets</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Typ</translation>
+ </message>
+ <message>
+ <source>Size</source>
+ <translation>Größe</translation>
+ </message>
+ <message>
<source>Statistics</source>
<translation>Statistik</translation>
</message>
@@ -1096,6 +1154,10 @@
<translation>Pakete</translation>
</message>
<message>
+ <source>Events</source>
+ <translation>Ereignisse</translation>
+ </message>
+ <message>
<source>Time span, s</source>
<translation>Zeitspanne, s</translation>
</message>
@@ -1105,7 +1167,11 @@
</message>
<message>
<source>Average packet size, B</source>
- <translation>Durschnittliche Paketgröße, B</translation>
+ <translation>Durchschnittliche Paketgröße, B</translation>
+ </message>
+ <message>
+ <source>Average event size, B</source>
+ <translation>Durchschnittliche Ereignisgröße, B</translation>
</message>
<message>
<source>Bytes</source>
@@ -1113,21 +1179,21 @@
</message>
<message>
<source>Average bytes/s</source>
- <translation>Durschnittliche Byte/s</translation>
+ <translation>Durchschnittliche Byte/s</translation>
</message>
<message>
<source>Average bits/s</source>
- <translation>Durschnittliche Bit/s</translation>
- </message>
- <message>
- <source>Section Comment</source>
- <translation>Kommentar Bereich</translation>
+ <translation>Durchschnittliche Bit/s</translation>
</message>
<message>
<source>Packet Comments</source>
<translation>Paketkommentar</translation>
</message>
<message>
+ <source>Event Comments</source>
+ <translation>Ereigniskommentare</translation>
+ </message>
+ <message>
<source>&lt;p&gt;Frame %1: </source>
<translation>&lt;p&gt;Frame %1:</translation>
</message>
@@ -1139,6 +1205,14 @@
</translation>
</message>
+ <message>
+ <source>Created by Logray %1
+
+</source>
+ <translation>Erstellt von Logray %1
+
+</translation>
+ </message>
</context>
<context>
<name>CaptureFilterCombo</name>
@@ -1366,6 +1440,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angeben.</translation>
</message>
<message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for some more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Normalerweise erfasst eine WLAN-Netzwerkkarte nur Verkehr, der zu oder von ihrer Netzwerkadresse gesendet wird. Zudem wird nur &lt;em&gt;user data&lt;/em&gt;-Verkehr mit &amp;quot;fake&amp;quot; Ethernet-Headern aufgezeichnet. Wenn Sie den gesamten Datenverkehr, den die Netzwerkkarte &amp;quot;sehen&amp;quot; kann, aufzeichnen möchten, an 802.11 Management-/Kontrollpaketen oder Radio-Layer-Infos interessiert sind, wählen Sie diese Option an. Monitor-Mode-Verfügbarkeit hängt von der Netzwerkkarte und den Treibern ab. Schauen Sie für mehr Informationen zum Mitschneiden in WLAN-Netzwerken ins Wiki.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>Enable monitor mode on all 802.11 interfaces</source>
+ <translation>Monitor Modus für alle 802.11 Schnittstellen aktivieren</translation>
+ </message>
+ <message>
<source>compression</source>
<translation>Komprimierung</translation>
</message>
@@ -1378,6 +1460,30 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>gzip</translation>
</message>
<message>
+ <source>File infix pattern</source>
+ <translation>Datei Infix Muster</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;In multiple file mode, the date and time and file index number are inserted between filename template and any suffix. Select their order.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Beim Erzeugen mehrerer Dateien werden Datum und Uhrzeit sowie die Datei-Indexnummer zwischen dem Dateinamen und Suffix eingefügt. Wählen Sie deren Sortierungsart.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>YYYYmmDDHHMMSS_NNNNN</source>
+ <translation>YYYYmmDDHHMMSS_NNNNN</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Date and time before the file index number. This causes files to sort in creation time order, and keeps files from the same batch closely ordered.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Datum und Uhrzeit vor der Datei-Indexnummer. Dies führt zur Sortierung nach Erstellungszeit und hält Dateien vom gleichen Stapel in der Sortierung eng zusammen.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>NNNNN_YYYYmmDDHHMMSS</source>
+ <translation>NNNNN_YYYYmmDDHHMMSS</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;File index number before the date and time. This is the historic Wireshark ordering.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Datei-Indexnummer vor Datum und Uhrzeit. Dies ist die alte Wireshark Sortierung.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;After capturing has switched to the next file and the given number of files has exceeded, the oldest file will be removed.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Nachdem die Aufzeichnung in die nächste Datei gewechselt hat und die angegebene Anzahl an Dateien erreicht wurde, wird die älteste Datei entfernt.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1466,6 +1572,10 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Mitschneiden beenden, nachdem die angegebene Anzahl an Paketen mitgeschnitten wurde.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
+ <source>Stop capturing after the specified number of files have been created.</source>
+ <translation>Mitschneiden beenden, nachdem die angegebene Anzahl an Dateien erstellt wurde.</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Stop capturing after the specified amount of data has been captured.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Mitschneiden beenden, nachdem die angegebene Datenmenge mitgeschnitten wurde.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1526,8 +1636,8 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Fehler</translation>
</message>
<message>
- <source>Multiple files: Requested filesize too large. The filesize cannot be greater than 2 GiB.</source>
- <translation>Dateisatz: Angeforderte Dateigröße zu groß. Die Dateigröße kann nicht größer als 2 GiB sein.</translation>
+ <source>Multiple files: Requested filesize too large. The filesize cannot be greater than 2 TB.</source>
+ <translation>Dateisatz: Angeforderte Dateigröße zu groß. Die Dateigröße kann nicht größer als 2 TB sein.</translation>
</message>
<message>
<source>Multiple files: No capture file name given. You must specify a filename if you want to use multiple files.</source>
@@ -1557,6 +1667,14 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Pakete im promiskuitiven Modus mitschneiden</translation>
</message>
<message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Normalerweise erfasst eine WLAN-Netzwerkkarte nur Verkehr, der zu oder von ihrer Netzwerkadresse gesendet wird. Zudem wird nur &lt;em&gt;user data&lt;/em&gt; -Verkehr mit &amp;quot;fake&amp;quot; Ethernet-Headern aufgezeichnet. Wenn Sie den gesamten Datenverkehr, den die Netzwerkkarte &amp;quot;sehen&amp;quot; kann, aufzeichnen möchten, an 802.11 Management-/Kontrollpaketen oder Radio-Layer-Infos interessiert sind, wählen Sie diese Option an. Monitor-Mode-Verfügbarkeit hängt von der Netzwerkkarte und den Treibern ab. Schauen Sie für mehr Informationen zum Mitschneiden in WLAN-Netzwerken ins Wiki.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>Capture packets in monitor mode on 802.11 devices</source>
+ <translation>Pakete im Monitor Modus der 802.11 Schnittstelle mitschneiden</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Capture packets in the next-generation capture file format.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Pakete im pcapng Dateiformat aufzeichnen.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1784,6 +1902,14 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Aufgelöst</translation>
</message>
<message>
+ <source>Width</source>
+ <translation>Breite</translation>
+ </message>
+ <message>
+ <source>Alignment</source>
+ <translation>Ausrichtung</translation>
+ </message>
+ <message>
<source>&lt;html&gt;Show human-readable strings instead of raw values for fields. Only applicable to custom columns with fields that have value strings.&lt;/html&gt;</source>
<translation>&lt;html&gt;In Feldern menschenleserliche Zeichenketten anstatt Rohwerte anzeigen. Nur auf benutzerdefinierte Spalten mit Zeichenketten anwendbar.&lt;/html&gt;</translation>
</message>
@@ -1831,6 +1957,25 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
</message>
</context>
<context>
+ <name>CompressionGroupBox</name>
+ <message>
+ <source>Compression options</source>
+ <translation>Komprimierungsoptionen</translation>
+ </message>
+ <message>
+ <source>&amp;Uncompressed</source>
+ <translation>&amp;Unkomprimiert</translation>
+ </message>
+ <message>
+ <source>Compress with g&amp;zip</source>
+ <translation>Mit g&amp;zip komprimieren</translation>
+ </message>
+ <message>
+ <source>Compress with &amp;LZ4</source>
+ <translation>Mit &amp;LZ4 komprimieren</translation>
+ </message>
+</context>
+<context>
<name>ConversationDataModel</name>
<message>
<source>Address A</source>
@@ -1897,6 +2042,10 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Bits/s B </translation>
</message>
<message>
+ <source>Flows</source>
+ <translation>Flows</translation>
+ </message>
+ <message>
<source>Total Packets</source>
<translation>Pakete gesamt</translation>
</message>
@@ -2011,14 +2160,6 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Paketbytes als Hex Dump kopieren</translation>
</message>
<message>
- <source>…as Printable Text</source>
- <translation>…als druckbarer Text</translation>
- </message>
- <message>
- <source>Copy only the printable text in the packet.</source>
- <translation>Nur den druckbaren Text im Paket kopieren.</translation>
- </message>
- <message>
<source>…as MIME Data</source>
<translation>...als MIME Daten</translation>
</message>
@@ -2031,10 +2172,42 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Paket-Bytes als druckbare ASCII-Zeichen und Escape-Sequenzen kopieren.</translation>
</message>
<message>
+ <source>…as Go literal</source>
+ <translation>als Go Literal</translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as Go literal.</source>
+ <translation>Paketbytes als Go Literal kopieren</translation>
+ </message>
+ <message>
+ <source>…as C Array</source>
+ <translation>…als C Array</translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as C Array.</source>
+ <translation>Paketbytes als C Array kopieren.</translation>
+ </message>
+ <message>
<source>…as a Hex Stream</source>
<translation>...als Hex Stream</translation>
</message>
<message>
+ <source>…as UTF-8 Text</source>
+ <translation>…als UTF-8 Text</translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as text, treating as UTF-8.</source>
+ <translation>Paketbytes als Text kopieren (als UTF-8 behandeln).</translation>
+ </message>
+ <message>
+ <source>…as ASCII Text</source>
+ <translation>…als ASCII Text</translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as text, treating as ASCII.</source>
+ <translation>Paketbytes als Text kopieren (als ASCII behandeln).</translation>
+ </message>
+ <message>
<source>Copy packet bytes as a stream of hex.</source>
<translation>Paketbytes als Hexstream kopieren.</translation>
</message>
@@ -2830,6 +3003,10 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<source>Display filter:</source>
<translation>Anzeigefilter:</translation>
</message>
+ <message>
+ <source>Export PDUs</source>
+ <translation>PDUs exportieren</translation>
+ </message>
</context>
<context>
<name>ExtArgSelector</name>
@@ -2869,10 +3046,6 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Start</translation>
</message>
<message>
- <source>Save</source>
- <translation>Speichern</translation>
- </message>
- <message>
<source>Default</source>
<translation>Standard</translation>
</message>
@@ -3014,6 +3187,14 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Anzeigefilter</translation>
</message>
<message>
+ <source>Display Filter Macros</source>
+ <translation>Anzeigefilter Makros</translation>
+ </message>
+ <message>
+ <source>New macro</source>
+ <translation>Neues Makro</translation>
+ </message>
+ <message>
<source>Open </source>
<translation>Öffnen</translation>
</message>
@@ -3097,10 +3278,18 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<context>
<name>FilterListModel</name>
<message>
+ <source>Macro Name</source>
+ <translation>Makroname</translation>
+ </message>
+ <message>
<source>Filter Name</source>
<translation>Filtername</translation>
</message>
<message>
+ <source>Macro Expression</source>
+ <translation>Makroausdruck</translation>
+ </message>
+ <message>
<source>Filter Expression</source>
<translation>Filterausdruck</translation>
</message>
@@ -3186,22 +3375,10 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<context>
<name>FolderListModel</name>
<message>
- <source>&quot;File&quot; dialogs</source>
- <translation>&quot;Datei&quot; Dialoge</translation>
- </message>
- <message>
- <source>capture files</source>
- <translation>Mitschnittdateien</translation>
- </message>
- <message>
<source>Temp</source>
<translation>Temp</translation>
</message>
<message>
- <source>untitled capture files</source>
- <translation>Unbenannte Mitschnittdateien</translation>
- </message>
- <message>
<source>Personal configuration</source>
<translation>Benutzerspezifische Konfiguration</translation>
</message>
@@ -3210,14 +3387,6 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Globale Konfiguration</translation>
</message>
<message>
- <source>dfilters, preferences, ethers, …</source>
- <translation>dfilters, preferences, ethers, …</translation>
- </message>
- <message>
- <source>dfilters, preferences, manuf, …</source>
- <translation>dfilters, preferences, manuf, …</translation>
- </message>
- <message>
<source>System</source>
<translation>System</translation>
</message>
@@ -3230,18 +3399,10 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Programm</translation>
</message>
<message>
- <source>program files</source>
- <translation>program files</translation>
- </message>
- <message>
<source>Personal Plugins</source>
<translation>Benutzerspezifische Plugins</translation>
</message>
<message>
- <source>binary plugins</source>
- <translation>binary plugins</translation>
- </message>
- <message>
<source>Global Plugins</source>
<translation>Globale Plugins</translation>
</message>
@@ -3258,11 +3419,35 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Lua Skripte</translation>
</message>
<message>
+ <source>&quot;File&quot; dialog location</source>
+ <translation>&quot;Datei&quot; Dialog Pfad</translation>
+ </message>
+ <message>
+ <source>Capture files</source>
+ <translation>Mitschnittdateien</translation>
+ </message>
+ <message>
+ <source>Untitled capture files</source>
+ <translation>Unbenannte Mitschnittdateien</translation>
+ </message>
+ <message>
+ <source>Preferences, profiles, manuf, …</source>
+ <translation>Einstellungen, Profile, manuf, …</translation>
+ </message>
+ <message>
+ <source>Program files</source>
+ <translation>Programmdateien</translation>
+ </message>
+ <message>
+ <source>Binary plugins</source>
+ <translation>Binary Plug-Ins</translation>
+ </message>
+ <message>
<source>Personal Extcap path</source>
<translation>Benutzerspezifischer Extcap Pfad</translation>
</message>
<message>
- <source>external capture (extcap) plugins</source>
+ <source>External capture (extcap) plugins</source>
<translation>Externe Aufzeichnungs-Plug-Ins (extcap)</translation>
</message>
<message>
@@ -3299,7 +3484,7 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
</message>
<message>
<source>Location</source>
- <translation>Lokation</translation>
+ <translation>Pfad</translation>
</message>
<message>
<source>Typical Files</source>
@@ -3400,6 +3585,24 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
</translation>
</message>
<message>
+ <source>Event %1. </source>
+ <translation>Ereignis %1.</translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;reads&lt;/span&gt;, </source>
+ <translation>
+ <numerusform>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;Lesevorgang&lt;/span&gt;, </numerusform>
+ <numerusform>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;Lesevorgänge&lt;/span&gt;, </numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;writes&lt;/span&gt;, </source>
+ <translation>
+ <numerusform>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;Schreibvorgang&lt;/span&gt;, </numerusform>
+ <numerusform>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;Schreibvorgänge&lt;/span&gt;, </numerusform>
+ </translation>
+ </message>
+ <message>
<source> Click to select.</source>
<translation> Zur Auswahl anklicken.</translation>
</message>
@@ -3432,6 +3635,18 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>%1 Stream in ausgewähltem Paket nicht gefunden.</translation>
</message>
<message>
+ <source>Read activity(%6)</source>
+ <translation>Leseaktivität(%6)</translation>
+ </message>
+ <message>
+ <source>Write activity(%6)</source>
+ <translation>Schreibaktivität(%6)</translation>
+ </message>
+ <message>
+ <source>Entire I/O activity (%1)</source>
+ <translation>Gesamte E/A Aktivität (%1)</translation>
+ </message>
+ <message>
<source>Entire conversation (%1)</source>
<translation>Gesamte Verbindung (%1)</translation>
</message>
@@ -3447,10 +3662,6 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<source>Save Stream Content As…</source>
<translation>Stream Inhalt speichern als…</translation>
</message>
- <message>
- <source>[Stream output truncated]</source>
- <translation>[Streamausgabe gekürzt]</translation>
- </message>
<message numerus="yes">
<source>%Ln total stream(s).</source>
<translation>
@@ -3478,9 +3689,20 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Hinweis.</translation>
</message>
<message>
- <source>Show data as</source>
- <oldsource>Show and save data as</oldsource>
- <translation>Daten anzeigen als</translation>
+ <source>Show as</source>
+ <translation>Anzeigen als</translation>
+ </message>
+ <message>
+ <source>No delta times</source>
+ <translation>Keine Delta-Zeiten</translation>
+ </message>
+ <message>
+ <source>Turn delta times</source>
+ <translation>Delta-Zeiten umdrehen</translation>
+ </message>
+ <message>
+ <source>All delta times</source>
+ <translation>Alle Delta-Zeiten</translation>
</message>
<message>
<source>Stream</source>
@@ -3495,11 +3717,22 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Suchen:</translation>
</message>
<message>
+ <source>Case sensitive</source>
+ <translation>Groß- / Kleinschreibung beachten</translation>
+ </message>
+ <message>
<source>Find &amp;Next</source>
<translation>&amp;Nächstes suchen</translation>
</message>
</context>
<context>
+ <name>FollowStreamText</name>
+ <message>
+ <source>[Stream output truncated]</source>
+ <translation>[Streamausgabe gekürzt]</translation>
+ </message>
+</context>
+<context>
<name>FontColorPreferencesFrame</name>
<message>
<source>Frame</source>
@@ -3835,29 +4068,28 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <source>Remove this graph.</source>
- <oldsource>Remove this dissection behavior.</oldsource>
- <translation>Diesen Graph entfernen.</translation>
- </message>
- <message>
<source>Add a new graph.</source>
<translation>Einen neuen Graph hinzufügen.</translation>
</message>
<message>
- <source>Duplicate this graph.</source>
- <translation>Diesen Graph duplizieren.</translation>
- </message>
- <message>
<source>Clear all graphs.</source>
<translation>Alle Graphen löschen.</translation>
</message>
<message>
- <source>Move this graph upwards.</source>
- <translation>Graphen nach oben verschieben.</translation>
+ <source>Remove the selected graph(s).</source>
+ <translation>Ausgewählte(n) Graphen entfernen.</translation>
+ </message>
+ <message>
+ <source>Duplicate the selected graph(s).</source>
+ <translation>Ausgewählte(n) Graphen duplizieren.</translation>
</message>
<message>
- <source>Move this graph downwards.</source>
- <translation>Graphen nach unten verschieben.</translation>
+ <source>Move the selected graph(s) upwards.</source>
+ <translation>Ausgewählte(n) Graphen nach oben verschieben.</translation>
+ </message>
+ <message>
+ <source>Move the selected graph(s) downwards.</source>
+ <translation>Ausgewählte(n) Graphen nach unten verschieben.</translation>
</message>
<message>
<source>Mouse</source>
@@ -3900,10 +4132,6 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Legende einschalten</translation>
</message>
<message>
- <source>Reset</source>
- <translation>Zurücksetzen</translation>
- </message>
- <message>
<source>Reset Graph</source>
<translation>Graph zurücksetzen</translation>
</message>
@@ -4117,6 +4345,42 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Graph von einem anderen Profil kopieren.</translation>
</message>
<message>
+ <source>1 μs</source>
+ <translation>1 μs</translation>
+ </message>
+ <message>
+ <source>2 μs</source>
+ <translation>2 μs</translation>
+ </message>
+ <message>
+ <source>5 μs</source>
+ <translation>5 μs</translation>
+ </message>
+ <message>
+ <source>10 μs</source>
+ <translation>10 μs</translation>
+ </message>
+ <message>
+ <source>20 μs</source>
+ <translation>20 μs</translation>
+ </message>
+ <message>
+ <source>50 μs</source>
+ <translation>50 μs</translation>
+ </message>
+ <message>
+ <source>100 μs</source>
+ <translation>100 μs</translation>
+ </message>
+ <message>
+ <source>200 μs</source>
+ <translation>200 μs</translation>
+ </message>
+ <message>
+ <source>500 μs</source>
+ <translation>500 μs</translation>
+ </message>
+ <message>
<source>1 ms</source>
<translation>1 ms</translation>
</message>
@@ -4161,6 +4425,14 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>5 Sek.</translation>
</message>
<message>
+ <source>2 min</source>
+ <translation>2 min</translation>
+ </message>
+ <message>
+ <source>5 min</source>
+ <translation>5 min</translation>
+ </message>
+ <message>
<source>Wireshark I/O Graphs: %1</source>
<translation>Wireshark I/O Graphen: %1</translation>
</message>
@@ -4173,6 +4445,14 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Gefilterte Ereignisse</translation>
</message>
<message>
+ <source>All packets</source>
+ <translation>Alle Pakete</translation>
+ </message>
+ <message>
+ <source>All events</source>
+ <translation>Alle Ereignisse</translation>
+ </message>
+ <message>
<source>All Packets</source>
<translation>Alle Pakete</translation>
</message>
@@ -4185,8 +4465,8 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Alle Ereignisse</translation>
</message>
<message>
- <source>Access Denied</source>
- <translation>Zugriff verboten</translation>
+ <source>All Execs</source>
+ <translation>Alle Ausführungen</translation>
</message>
<message>
<source>Hover over the graph for details.</source>
@@ -4233,6 +4513,34 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Klicken um einen Teil des Graphen auszuwählen.</translation>
</message>
<message>
+ <source>%1 Intervals </source>
+ <translation>%1 Intervalle </translation>
+ </message>
+ <message>
+ <source>Move to top left</source>
+ <translation>Nach oben links verschieben</translation>
+ </message>
+ <message>
+ <source>Move to top center</source>
+ <translation>Nach oben mittig verschieben</translation>
+ </message>
+ <message>
+ <source>Move to top right</source>
+ <translation>Nach oben rechts verschieben</translation>
+ </message>
+ <message>
+ <source>Move to bottom left</source>
+ <translation>Nach unten links verschieben</translation>
+ </message>
+ <message>
+ <source>Move to bottom center</source>
+ <translation>Nach unten mittig verschieben</translation>
+ </message>
+ <message>
+ <source>Move to bottom right</source>
+ <translation>Nach unten rechts verschieben</translation>
+ </message>
+ <message>
<source>Portable Document Format (*.pdf)</source>
<translation>Portable Document Format (*.pdf)</translation>
</message>
@@ -4985,6 +5293,13 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
</message>
</context>
<context>
+ <name>InterfaceTreeDelegate</name>
+ <message>
+ <source>default</source>
+ <translation>Standard</translation>
+ </message>
+</context>
+<context>
<name>InterfaceTreeModel</name>
<message>
<source>Show</source>
@@ -5961,8 +6276,8 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<context>
<name>LteMacStatisticsDialog</name>
<message>
- <source>LTE Mac Statistics</source>
- <translation>LTE Mac Statistiken</translation>
+ <source>LTE/NR Mac Statistics</source>
+ <translation>LTE/NR Mac Statistiken</translation>
</message>
<message>
<source>Include SR frames in filter</source>
@@ -6266,12 +6581,12 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Sequenznummer</translation>
</message>
<message>
- <source>LTE RLC Graph (UE=%1 chan=%2%3 %4 - %5)</source>
- <translation>LTE RLC Graph (UE=%1 Kanal=%2%3 %4 - %5)</translation>
+ <source>%1 RLC Graph (UE=%2 chan=%3%4 %5 - %6)</source>
+ <translation>%1 RLC Graph (UE=%2 Kanal=%3%4 %5 - %6)</translation>
</message>
<message>
- <source>LTE RLC Graph - no channel selected</source>
- <translation>LTE RLC Graph - Kein Kanal ausgewählt</translation>
+ <source>3GPP RLC Graph - no channel selected</source>
+ <translation>3GPP RLC Graph - kein Kanal ausgewählt</translation>
</message>
<message>
<source>Save As…</source>
@@ -6325,8 +6640,8 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<context>
<name>LteRlcStatisticsDialog</name>
<message>
- <source>LTE RLC Statistics</source>
- <translation>LTE RLC Statistiken</translation>
+ <source>3GPP RLC Statistics</source>
+ <translation>3GPP RLC Statistiken</translation>
</message>
<message>
<source>Include SR frames in filter</source>
@@ -6412,6 +6727,10 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Profil: %1</translation>
</message>
<message>
+ <source> %1 Displayed: %2 (%3%)</source>
+ <translation> %1 Angezeigt: %2 (%3%)</translation>
+ </message>
+ <message>
<source>Manage Profiles…</source>
<translation>Profile verwalten…</translation>
</message>
@@ -6473,6 +6792,13 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<numerusform>%Ln Bytes</numerusform>
</translation>
</message>
+ <message numerus="yes">
+ <source>%Ln bit(s)</source>
+ <translation>
+ <numerusform>%Ln Bit</numerusform>
+ <numerusform>%Ln Bits</numerusform>
+ </translation>
+ </message>
<message>
<source>Byte %1</source>
<translation>Byte %1</translation>
@@ -6486,9 +6812,12 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Ausgewähltes Paket: %1 %2</translation>
</message>
<message>
- <source>Packets: %1 %4 Displayed: %2 (%3%)</source>
- <oldsource>Packets: %1 %4 Displayed: %2 %4 Marked: %3</oldsource>
- <translation>Pakete: %1 %4 Angezeigt: %2 (%3%)</translation>
+ <source>Selected Event: %1 %2 </source>
+ <translation>Ausgewählte Ereignisse: %1 %2 </translation>
+ </message>
+ <message>
+ <source>Events: %1</source>
+ <translation>Ereignisse: %1</translation>
</message>
<message>
<source> %1 Selected: %2 (%3%)</source>
@@ -6520,6 +6849,10 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Keine Pakete</translation>
</message>
<message>
+ <source>No Events</source>
+ <translation>Keine Ereignisse</translation>
+ </message>
+ <message>
<source>From Zip File...</source>
<translation>Aus ZIP Datei...</translation>
</message>
@@ -6552,6 +6885,13 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
</message>
</context>
<context>
+ <name>MainWindow</name>
+ <message>
+ <source>Display filter as %1</source>
+ <translation>Filter anzeigen als %1</translation>
+ </message>
+</context>
+<context>
<name>MainWindowPreferencesFrame</name>
<message>
<source>Frame</source>
@@ -6583,6 +6923,10 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Zuletzt genutztem Ordner</translation>
</message>
<message>
+ <source>The current working directory</source>
+ <translation>Das aktuelle Arbeitsverzeichnis</translation>
+ </message>
+ <message>
<source>Show up to</source>
<translation>Anzeigen von maximal</translation>
</message>
@@ -7013,6 +7357,10 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Zeige Feldwerte</translation>
</message>
<message>
+ <source>Refresh</source>
+ <translation>Aktualisieren</translation>
+ </message>
+ <message>
<source>Save Diagram As…</source>
<translation>Diagramm speichern als…</translation>
</message>
@@ -7060,6 +7408,10 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Paketbytes anzeigen</translation>
</message>
<message>
+ <source>Layout:</source>
+ <translation>Ansicht:</translation>
+ </message>
+ <message>
<source>Packet %1</source>
<translation>Paket %1</translation>
</message>
@@ -7082,6 +7434,13 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<numerusform>%Ln Bytes</numerusform>
</translation>
</message>
+ <message numerus="yes">
+ <source>%Ln bit(s)</source>
+ <translation>
+ <numerusform>%Ln Bit</numerusform>
+ <numerusform>%Ln Bits</numerusform>
+ </translation>
+ </message>
</context>
<context>
<name>PacketFormatGroupBox</name>
@@ -7541,10 +7900,22 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Dieses Profil kopieren.</translation>
</message>
<message>
+ <source>The number of packets or events to check for automatic profile switching.</source>
+ <translation>Die für den automatischen Profilwechsel geprüfte Anzahl von Paketen oder Ereignissen.</translation>
+ </message>
+ <message>
+ <source>Auto switch packet limit</source>
+ <translation>Autoswitch Paketlimit</translation>
+ </message>
+ <message>
<source>Configuration Profiles</source>
<translation>Profile konfigurieren</translation>
</message>
<message>
+ <source>Auto switch event limit</source>
+ <translation>Autoswitch Ereignislimit</translation>
+ </message>
+ <message>
<source>Import</source>
<comment>noun</comment>
<translation>Importieren</translation>
@@ -7727,6 +8098,10 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>gelöscht</translation>
</message>
<message>
+ <source>Auto Switch Filter</source>
+ <translation>Autoswitch Filter</translation>
+ </message>
+ <message>
<source>copy</source>
<comment>noun</comment>
<translation>Kopie</translation>
@@ -8086,6 +8461,10 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Window Größe (B)</translation>
</message>
<message>
+ <source>Unacked (Outstanding) Bytes (B)</source>
+ <translation>Nicht-ACK-bestätigte (ausstehende) Bytes (B)</translation>
+ </message>
+ <message>
<source>[no capture file]</source>
<translation>[keine Mitschnittdatei]</translation>
</message>
@@ -8246,6 +8625,14 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Marker fehlt?</translation>
</message>
<message>
+ <source>LTE</source>
+ <translation>LTE</translation>
+ </message>
+ <message>
+ <source>NR</source>
+ <translation>NR</translation>
+ </message>
+ <message>
<source>C-RNTI</source>
<translation>C-RNTI</translation>
</message>
@@ -8266,6 +8653,10 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>UEId</translation>
</message>
<message>
+ <source>RAT</source>
+ <translation>RAT</translation>
+ </message>
+ <message>
<source>UL Frames</source>
<translation>UL Frames</translation>
</message>
@@ -8489,9 +8880,69 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<source>Browse…</source>
<translation>Öffnen…</translation>
</message>
+ <message>
+ <source>PACKETS</source>
+ <translation>PAKETE</translation>
+ </message>
+ <message>
+ <source>EVENTS</source>
+ <translation>EREIGNISSE</translation>
+ </message>
+ <message>
+ <source>BYTES</source>
+ <translation>BYTES</translation>
+ </message>
+ <message>
+ <source>BITS</source>
+ <translation>BITS</translation>
+ </message>
+ <message>
+ <source>COUNT FRAMES</source>
+ <translation>ANZAHL FRAMES</translation>
+ </message>
+ <message>
+ <source>COUNT FIELDS</source>
+ <translation>ANZAHL FELDER</translation>
+ </message>
+ <message>
+ <source>SUM</source>
+ <translation>SUMME</translation>
+ </message>
+ <message>
+ <source>MAX</source>
+ <translation>MAX</translation>
+ </message>
+ <message>
+ <source>MIN</source>
+ <translation>MIN</translation>
+ </message>
+ <message>
+ <source>AVERAGE</source>
+ <translation>DURCHSCHNITT</translation>
+ </message>
+ <message>
+ <source>THROUGHPUT</source>
+ <translation>DURCHSATZ</translation>
+ </message>
+ <message>
+ <source>LOAD</source>
+ <translation>LAST</translation>
+ </message>
+ <message>
+ <source>Left</source>
+ <translation>Links</translation>
+ </message>
+ <message>
+ <source>Center</source>
+ <translation>Zentriert</translation>
+ </message>
+ <message>
+ <source>Right</source>
+ <translation>Rechts</translation>
+ </message>
</context>
<context>
- <name>QObject::QObject</name>
+ <name>QObject::QObject::QObject</name>
<message>
<source>CCCH</source>
<translation>CCCH</translation>
@@ -8592,6 +9043,13 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
</message>
</context>
<context>
+ <name>ResizeHeaderView</name>
+ <message>
+ <source>Resize all %1 to contents</source>
+ <translation>Alle %1 an Inhalt anpassen</translation>
+ </message>
+</context>
+<context>
<name>ResolvedAddressesDialog</name>
<message>
<source>Dialog</source>
@@ -8707,6 +9165,14 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Aufgelöste Adressen</translation>
</message>
<message>
+ <source>Copy</source>
+ <translation>Kopieren</translation>
+ </message>
+ <message>
+ <source>Save as…</source>
+ <translation>Speichern als...</translation>
+ </message>
+ <message>
<source># Resolved addresses found in %1</source>
<translation># Resolved addresses found in %1 </translation>
</message>
@@ -8720,6 +9186,61 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
</message>
</context>
<context>
+ <name>ResolvedAddressesView</name>
+ <message>
+ <source>as Plain Text</source>
+ <translation>als reiner Text</translation>
+ </message>
+ <message>
+ <source>Copy selected rows</source>
+ <translation>Ausgewählte Reihen kopieren</translation>
+ </message>
+ <message>
+ <source>Copy table</source>
+ <translation>Tabelle kopieren</translation>
+ </message>
+ <message>
+ <source>as CSV</source>
+ <translation>als CSV</translation>
+ </message>
+ <message>
+ <source>as JSON</source>
+ <translation>als JSON</translation>
+ </message>
+ <message>
+ <source>Save selected rows as…</source>
+ <translation>Ausgewählte Reihen speichern...</translation>
+ </message>
+ <message>
+ <source>Save table as…</source>
+ <translation>Tabelle speichern als...</translation>
+ </message>
+ <message>
+ <source>Save Resolved Addresses As…</source>
+ <translation>Aufgelöste Adressen speichern als...</translation>
+ </message>
+ <message>
+ <source>Plain text (*.txt)</source>
+ <translation>Reiner Text (*.txt)</translation>
+ </message>
+ <message>
+ <source>CSV Document (*.csv)</source>
+ <translation>CSV Dokument (*.csv)</translation>
+ </message>
+ <message>
+ <source>JSON Document (*.json)</source>
+ <translation>JSON Dokument (*.json)</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Warnung</translation>
+ </message>
+ <message>
+ <source>Unable to save %1: %2</source>
+ <translation>Speichern von %1 nicht möglich: %2</translation>
+ </message>
+</context>
+<context>
<name>ResponseTimeDelayDialog</name>
<message>
<source>%1 Response Time Delay Statistics</source>
@@ -10394,6 +10915,10 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Paket Bytes</translation>
</message>
<message>
+ <source>&lt;b&gt;Options:&lt;/b&gt;</source>
+ <translation>&lt;b&gt;Optionen:&lt;/b&gt;</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for strings containing narrow (UTF-8 and ASCII) or wide (UTF-16) characters.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Zeichenketten suchen, die schmale (UTF-8 oder ASCII) or breite (UTF-16) Zeichen enthalten.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -10414,6 +10939,18 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Groß- / Kleinschreibung beachten</translation>
</message>
<message>
+ <source>Backwards</source>
+ <translation>Rückwärts</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for a subsequent occurrence in the current packet before advancing to the next packet.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Nach weiterem Vorkommen im aktuellen Paket suchen bevor mit dem nächsten Paket fortgefahren wird.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>Multiple occurrences</source>
+ <translation>Mehreres Vorkommen</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5), a plain string (e.g. My String) or a regular expression (e.g. colou?r).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<oldsource>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5) or a plain string (e.g. My String).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</oldsource>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Nach Daten suchen, durch Angabe eines Anzeigefilters (z.B. ip.addr==10.1.1.1), oder mit einer Hexadezimalen Zeichenkette (z.B. fffffda5) oder einer einfachen Zeichenkette (z.B. Meine Zeichenkette), oder eines regulären Ausdrucks (z.B. colou?r).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
@@ -10451,6 +10988,22 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Ungültiger Filter.</translation>
</message>
<message>
+ <source>Event List</source>
+ <translation>Ereignisliste</translation>
+ </message>
+ <message>
+ <source>Event Details</source>
+ <translation>Ereignisdetails</translation>
+ </message>
+ <message>
+ <source>Event Bytes</source>
+ <translation>Ereignis-Bytes</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search the Info column of the event list (summary pane), decoded event display labels (tree view pane) or the ASCII-converted event data (hex view pane).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Durchsuchen der Informationsspalte der Ereignisliste (Übersichtsfenster), der dekodierten Ereignisanzeigebeschriftungen (Baumansicht) oder der ASCII-konvertierten Ereignisdaten (Hex-Ansicht).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
<source>That filter doesn&apos;t test anything.</source>
<translation>Dieser Filter hat keine Auswirkung.</translation>
</message>
@@ -10894,6 +11447,10 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Suchen:</translation>
</message>
<message>
+ <source>Case sensitive</source>
+ <translation>Groß- / Kleinschreibung beachten</translation>
+ </message>
+ <message>
<source>Find &amp;Next</source>
<translation>&amp;Nächstes suchen</translation>
</message>
@@ -10989,14 +11546,22 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Speichern als…</translation>
</message>
<message>
+ <source>Decoded as %1.</source>
+ <translation>Dekodiert als %1.</translation>
+ </message>
+ <message>
<source>Save Selected Packet Bytes As…</source>
<translation>Ausgewählte Paketbytes speichern als…</translation>
</message>
+ <message>
+ <source>compressed %1</source>
+ <translation>%1 komprimiert</translation>
+ </message>
<message numerus="yes">
- <source>Displaying %Ln byte(s).</source>
+ <source>Using %Ln byte(s).</source>
<translation>
- <numerusform>Zeige %Ln Byte an.</numerusform>
- <numerusform>Zeige %Ln Bytes an.</numerusform>
+ <numerusform>Verwende %Ln Byte.</numerusform>
+ <numerusform>Verwende %Ln Bytes.</numerusform>
</translation>
</message>
<message>
@@ -11096,6 +11661,10 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<source>Display filter:</source>
<translation>Anzeigefilter:</translation>
</message>
+ <message>
+ <source>Strip Headers</source>
+ <translation>Kopfdaten entfernen</translation>
+ </message>
</context>
<context>
<name>SupportedProtocolsDialog</name>
@@ -12069,22 +12638,20 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Einen neuen Eintrag erstellen.</translation>
</message>
<message>
- <source>Remove this entry.</source>
- <oldsource>Remove this profile.</oldsource>
- <translation>Diesen Eintrag entfernen.</translation>
+ <source>Remove the selected entry(ies).</source>
+ <translation>Ausgewählte(n) Eintrag(e) entfernen.</translation>
</message>
<message>
- <source>Copy this entry.</source>
- <oldsource>Copy this profile.</oldsource>
- <translation>Diesen Eintrag kopieren.</translation>
+ <source>Copy the selected entry(ies).</source>
+ <translation>Ausgewählte(n) Eintrag(e) kopieren.</translation>
</message>
<message>
- <source>Move entry up.</source>
- <translation>Eintrag nach oben verschieben.</translation>
+ <source>Move the selected entry(ies) up.</source>
+ <translation>Ausgewählte(n) Eintrag(e) nach oben verschieben.</translation>
</message>
<message>
- <source>Move entry down.</source>
- <translation>Eintrag nach unten verschieben.</translation>
+ <source>Move the selected entry(ies) down.</source>
+ <translation>Ausgewählte(n) Eintrag(e) nach unten verschieben.</translation>
</message>
<message>
<source>Clear all entries.</source>
@@ -12110,20 +12677,20 @@ Um zum Beispiel eine neue Datei zu jeder vollen Stunde zu haben, 1 Stunde angebe
<translation>Einen neuen Eintrag erstellen.</translation>
</message>
<message>
- <source>Remove this entry.</source>
- <translation>Diesen Eintrag entfernen.</translation>
+ <source>Remove the selected entry(ies).</source>
+ <translation>Ausgewählte(n) Eintrag(e) entfernen.</translation>
</message>
<message>
- <source>Copy this entry.</source>
- <translation>Diesen Eintrag kopieren.</translation>
+ <source>Copy the selected entry(ies).</source>
+ <translation>Ausgewählte(n) Eintrag(e) kopieren.</translation>
</message>
<message>
- <source>Move entry up.</source>
- <translation>Eintrag nach oben verschieben.</translation>
+ <source>Move the selected entry(ies) up.</source>
+ <translation>Ausgewählte(n) Eintrag(e) nach oben verschieben.</translation>
</message>
<message>
- <source>Move entry down.</source>
- <translation>Eintrag nach unten verschieben.</translation>
+ <source>Move the selected entry(ies) down.</source>
+ <translation>Ausgewählte(n) Eintrag(e) nach unten verschieben.</translation>
</message>
<message>
<source>Clear all entries.</source>
@@ -12494,10 +13061,18 @@ a:hover {
<translation>Mit Wireshark den Kleber schnüffeln, der das Internet zusammenhält.</translation>
</message>
<message>
+ <source>You are sniffing the glue that holds your system together using Logray </source>
+ <translation>Mit Logray den Kleber schnüffeln, der Ihr System zusammenhält.</translation>
+ </message>
+ <message>
<source>You are running Wireshark </source>
<translation>Sie nutzen Wireshark </translation>
</message>
<message>
+ <source>You are running Logray </source>
+ <translation>Sie nutzen Logray</translation>
+ </message>
+ <message>
<source> You receive automatic updates.</source>
<translation>Updates werden automatisch heruntergeladen.</translation>
</message>
@@ -12774,14 +13349,6 @@ a:hover {
<translation>Keine Dateien gefunden</translation>
</message>
<message>
- <source>&amp;Contents</source>
- <translation>&amp;Inhalt</translation>
- </message>
- <message>
- <source>Wireshark Filter</source>
- <translation>Wireshark Filter</translation>
- </message>
- <message>
<source>TShark</source>
<translation>TShark</translation>
</message>
@@ -13047,10 +13614,6 @@ a:hover {
<translation>Wireless Toolbar</translation>
</message>
<message>
- <source>Help contents</source>
- <translation>Hilfe Inhalt</translation>
- </message>
- <message>
<source>FAQs</source>
<translation>Häufige Fragen (en)</translation>
</message>
@@ -13171,11 +13734,6 @@ a:hover {
<translation>Vorheriges Paket finden</translation>
</message>
<message>
- <source>&amp;Mark/Unmark Packet(s)</source>
- <oldsource>&amp;Mark/Unmark Packet</oldsource>
- <translation>Paket &amp;markieren</translation>
- </message>
- <message>
<source>Mark All Displayed</source>
<translation>Alle angezeigte Pakete markieren</translation>
</message>
@@ -13204,11 +13762,6 @@ a:hover {
<translation>Zum vorherigen markierten Paket gehen</translation>
</message>
<message>
- <source>&amp;Ignore/Unignore Packet(s)</source>
- <oldsource>&amp;Ignore/Unignore Packet</oldsource>
- <translation>Paket &amp;ignorieren bzw. zurücksetzen</translation>
- </message>
- <message>
<source>Ignore All Displayed</source>
<translation>Alle angezeigten Pakete ignorieren</translation>
</message>
@@ -13649,10 +14202,6 @@ a:hover {
<translation>Ansicht zurücksetzen</translation>
</message>
<message>
- <source>Reset appearance layout to default size</source>
- <translation>Anzeige auf Ausgangsgröße zurücksetzen</translation>
- </message>
- <message>
<source>Seconds Since First Captured Packet</source>
<translation>Sekunden seit erstem aufgezeichneten Paket</translation>
</message>
@@ -13662,19 +14211,19 @@ a:hover {
</message>
<message>
<source>Tenths of a millisecond</source>
- <translation>Zehntelmillisekunde</translation>
+ <translation>Zehntelmillisekunden</translation>
</message>
<message>
<source>Hundredths of a millisecond</source>
- <translation>Hundertstelmillisekunde</translation>
+ <translation>Hundertstelmillisekunden</translation>
</message>
<message>
<source>Tenths of a microsecond</source>
- <translation>Zehntelmikrosekunde</translation>
+ <translation>Zehntelmikrosekunden</translation>
</message>
<message>
<source>Hundredths of a microsecond</source>
- <translation>Hundertstelmikrosekunde</translation>
+ <translation>Hundertstelmikrosekunden</translation>
</message>
<message>
<source>Packet &amp;Diagram</source>
@@ -13813,22 +14362,30 @@ a:hover {
<translation>MAC Adressblöcke</translation>
</message>
<message>
- <source>TLS Keylog Launcher</source>
- <translation>TLS Keylog Launcher</translation>
- </message>
- <message>
- <source>Release Notes</source>
- <translation>Veröffentlichungshinweise</translation>
- </message>
- <message>
<source>&amp;Options…</source>
<translation>&amp;Optionen...</translation>
</message>
<message>
+ <source>&amp;3GPP Uu</source>
+ <translation>&amp;3GPP Uu</translation>
+ </message>
+ <message>
<source>&amp;Wireless</source>
<translation>&amp;Wireless</translation>
</message>
<message>
+ <source>&amp;User&apos;s Guide</source>
+ <translation>Ben&amp;utzerhandbuch (en)</translation>
+ </message>
+ <message>
+ <source>Wireshark User&apos;s Guide</source>
+ <translation>Wireshark Benutzerhandbuch (en)</translation>
+ </message>
+ <message>
+ <source>Display Filters</source>
+ <translation>Anzeigefilter</translation>
+ </message>
+ <message>
<source>Capture &amp;Filters…</source>
<translation>Mitschnitt&amp;filter...</translation>
</message>
@@ -13873,10 +14430,18 @@ a:hover {
<translation>Vorheriges finden</translation>
</message>
<message>
+ <source>&amp;Mark/Unmark Selected</source>
+ <translation>Ausgewählte &amp;markieren</translation>
+ </message>
+ <message>
<source>Mark or unmark each selected packet</source>
<translation>Jedes ausgewählte Paket markieren bzw. Markierung rückgängig machen</translation>
</message>
<message>
+ <source>&amp;Ignore/Unignore Selected</source>
+ <translation>Ausgewählte &amp;ignorieren</translation>
+ </message>
+ <message>
<source>Ignore or unignore each selected packet</source>
<translation>Jedes ausgewählte Paket ignorieren bzw. Ignorieren zurücksetzen</translation>
</message>
@@ -13917,6 +14482,18 @@ a:hover {
<translation>TCP Durchsatz</translation>
</message>
<message>
+ <source>General</source>
+ <translation>Allgemein</translation>
+ </message>
+ <message>
+ <source>Query-Response</source>
+ <translation>Query-Response</translation>
+ </message>
+ <message>
+ <source>DNS Query-Response Statistics</source>
+ <translation>DNS Query-Response Statistiken</translation>
+ </message>
+ <message>
<source>Request Sequences</source>
<translation>Anfrage Sequenzen</translation>
</message>
@@ -13925,6 +14502,14 @@ a:hover {
<translation>HTTP Anfrage Sequenzen</translation>
</message>
<message>
+ <source>E2AP</source>
+ <translation>E2AP</translation>
+ </message>
+ <message>
+ <source>E2AP Messages</source>
+ <translation>E2AP Nachrichten</translation>
+ </message>
+ <message>
<source>Decode &amp;As…</source>
<translation>Dekodieren &amp;als...</translation>
</message>
@@ -13985,6 +14570,10 @@ a:hover {
<translation>Normale Größe</translation>
</message>
<message>
+ <source>Reset layout to default size</source>
+ <translation>Anzeige auf Standardgröße zurücksetzen</translation>
+ </message>
+ <message>
<source>Resize Columns</source>
<translation>Spaltengröße anpassen</translation>
</message>
@@ -14074,11 +14663,11 @@ a:hover {
</message>
<message>
<source>Tenths of a second</source>
- <translation>Zehntelsekunde</translation>
+ <translation>Zehntelsekunden</translation>
</message>
<message>
<source>Hundredths of a second</source>
- <translation>Hundertstel</translation>
+ <translation>Hundertstelsekunden</translation>
</message>
<message>
<source>Milliseconds</source>
@@ -14243,6 +14832,14 @@ a:hover {
<translation>Zum Paket gehen auf das das ausgewählte Feld referenziert.</translation>
</message>
<message>
+ <source>TLS Keylog Launcher</source>
+ <translation>TLS Keylog Launcher</translation>
+ </message>
+ <message>
+ <source>Release Notes</source>
+ <translation>Release Notes</translation>
+ </message>
+ <message>
<source>&amp;VoIP Calls</source>
<translation>&amp;VoIP Anrufe</translation>
</message>
@@ -14275,10 +14872,6 @@ a:hover {
<translation>&amp;GSM</translation>
</message>
<message>
- <source>&amp;LTE</source>
- <translation>&amp;LTE</translation>
- </message>
- <message>
<source>&amp;MTP3</source>
<translation>&amp;MTP3</translation>
</message>
@@ -14563,6 +15156,10 @@ a:hover {
<translation>&amp;Ohne Speichern beenden</translation>
</message>
<message>
+ <source>USB CDC Data</source>
+ <translation>USB CDC-Daten</translation>
+ </message>
+ <message>
<source>There is no &quot;rtp.ssrc&quot; field in this version of Wireshark.</source>
<translation>In dieser Wireshark-Version ist kein &quot;rtp.ssrc&quot; Feld vorhanden.</translation>
</message>
diff --git a/ui/qt/wireshark_dialog.cpp b/ui/qt/wireshark_dialog.cpp
index 4045868f..ae8fc73c 100644
--- a/ui/qt/wireshark_dialog.cpp
+++ b/ui/qt/wireshark_dialog.cpp
@@ -9,8 +9,6 @@
#include "config.h"
-#include <glib.h>
-
#include "cfile.h"
#include <epan/packet.h>
@@ -95,7 +93,7 @@ void WiresharkDialog::updateWidgets()
setWindowSubtitle(subtitle_);
}
-bool WiresharkDialog::registerTapListener(const char *tap_name, void *tap_data, const char *filter, guint flags, tap_reset_cb tap_reset, tap_packet_cb tap_packet, tap_draw_cb tap_draw)
+bool WiresharkDialog::registerTapListener(const char *tap_name, void *tap_data, const char *filter, unsigned flags, tap_reset_cb tap_reset, tap_packet_cb tap_packet, tap_draw_cb tap_draw)
{
GString *error_string = register_tap_listener(tap_name, tap_data, filter, flags,
tap_reset, tap_packet, tap_draw, NULL);
diff --git a/ui/qt/wireshark_dialog.h b/ui/qt/wireshark_dialog.h
index ad557ebc..20fd7113 100644
--- a/ui/qt/wireshark_dialog.h
+++ b/ui/qt/wireshark_dialog.h
@@ -39,6 +39,11 @@ public:
// XXX Unlike the entire QWidget API, parent is mandatory here.
explicit WiresharkDialog(QWidget &parent, CaptureFile &capture_file);
+ /**
+ * @brief true if the file has been closed, false otherwise.
+ */
+ bool fileClosed() const { return file_closed_; }
+
protected:
virtual void keyPressEvent(QKeyEvent *event) { QDialog::keyPressEvent(event); }
virtual void accept();
@@ -93,7 +98,7 @@ protected:
* @param tap_draw Draw callback.
*/
bool registerTapListener(const char *tap_name, void *tap_data,
- const char *filter, guint flags,
+ const char *filter, unsigned flags,
tap_reset_cb tap_reset,
tap_packet_cb tap_packet,
tap_draw_cb tap_draw);
@@ -103,17 +108,21 @@ protected:
*/
virtual void removeTapListeners();
- /**
- * @brief true if the file has been closed, false otherwise.
- */
- // XXX Needs a getter?
+ // XXX - Move this to private, have subclasses use the getter?
bool file_closed_;
/**
* @brief Check to see if the user has closed (and not minimized) the dialog.
* @return true if the dialog has been closed, false otherwise.
*/
- bool dialogClosed() { return dialog_closed_; }
+ bool dialogClosed() const { return dialog_closed_; }
+
+ /**
+ * @brief Check to see if we're currently retapping. If this is positive,
+ * tapping will fail in process_specified_records.
+ * @return The current retap depth. (In current implementation, 0 or 1.)
+ */
+ int retapDepth() const { return retap_depth_; }
/**
* @brief Called when the capture file is about to close. This can be
diff --git a/ui/qt/wireshark_en.ts b/ui/qt/wireshark_en.ts
index 2dab6ca4..5f343152 100644
--- a/ui/qt/wireshark_en.ts
+++ b/ui/qt/wireshark_en.ts
@@ -44,7 +44,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Filter by path</source>
+ <source>Search Folders</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -80,6 +80,14 @@
<translation type="unfinished"></translation>
</message>
<message>
+ <source>About Logray</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Logray</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>The directory does not exist</source>
<translation type="unfinished"></translation>
</message>
@@ -755,6 +763,28 @@
</message>
</context>
<context>
+ <name>CaptureCommentDialog</name>
+ <message>
+ <source>Edit Capture Comments</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add Comment</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Section %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>CaptureCommentTabWidget</name>
+ <message>
+ <source>Comment %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>CaptureFile</name>
<message>
<source> [closing]</source>
@@ -863,10 +893,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Compress with g&amp;zip</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Open Capture File</source>
<oldsource>Wireshark: Open Capture File</oldsource>
<translation type="unfinished"></translation>
@@ -948,7 +974,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Capture file comments</source>
+ <source>Edit Comments</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -960,10 +986,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Save Comments</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Capture File Properties</source>
<translation type="unfinished"></translation>
</message>
@@ -1012,10 +1034,18 @@
<translation type="unfinished"></translation>
</message>
<message>
+ <source>First event</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Last packet</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Last event</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Elapsed</source>
<translation type="unfinished"></translation>
</message>
@@ -1052,6 +1082,10 @@
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Dropped events</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Capture filter</source>
<translation type="unfinished"></translation>
</message>
@@ -1064,6 +1098,10 @@
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Event size limit (snaplen)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>none</source>
<translation type="unfinished"></translation>
</message>
@@ -1072,6 +1110,26 @@
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Comments</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Comment %1: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Decryption Secrets</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Statistics</source>
<translation type="unfinished"></translation>
</message>
@@ -1096,6 +1154,10 @@
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Events</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Time span, s</source>
<translation type="unfinished"></translation>
</message>
@@ -1108,6 +1170,10 @@
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Average event size, B</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Bytes</source>
<translation type="unfinished"></translation>
</message>
@@ -1120,11 +1186,11 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Section Comment</source>
+ <source>Packet Comments</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Packet Comments</source>
+ <source>Event Comments</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1137,6 +1203,12 @@
</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Created by Logray %1
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>CaptureFilterCombo</name>
@@ -1363,6 +1435,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for some more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enable monitor mode on all 802.11 interfaces</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>compression</source>
<translation type="unfinished"></translation>
</message>
@@ -1375,6 +1455,30 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>File infix pattern</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;In multiple file mode, the date and time and file index number are inserted between filename template and any suffix. Select their order.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>YYYYmmDDHHMMSS_NNNNN</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Date and time before the file index number. This causes files to sort in creation time order, and keeps files from the same batch closely ordered.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>NNNNN_YYYYmmDDHHMMSS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;File index number before the date and time. This is the historic Wireshark ordering.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;After capturing has switched to the next file and the given number of files has exceeded, the oldest file will be removed.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
@@ -1463,6 +1567,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Stop capturing after the specified number of files have been created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Stop capturing after the specified amount of data has been captured.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
@@ -1523,7 +1631,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
- <source>Multiple files: Requested filesize too large. The filesize cannot be greater than 2 GiB.</source>
+ <source>Multiple files: Requested filesize too large. The filesize cannot be greater than 2 TB.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1554,6 +1662,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Capture packets in monitor mode on 802.11 devices</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Capture packets in the next-generation capture file format.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
@@ -1781,6 +1897,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Width</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Alignment</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;Show human-readable strings instead of raw values for fields. Only applicable to custom columns with fields that have value strings.&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
@@ -1828,6 +1952,25 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>CompressionGroupBox</name>
+ <message>
+ <source>Compression options</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Uncompressed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Compress with g&amp;zip</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Compress with &amp;LZ4</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>ConversationDataModel</name>
<message>
<source>Address A</source>
@@ -1894,6 +2037,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Flows</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Total Packets</source>
<translation type="unfinished"></translation>
</message>
@@ -2008,23 +2155,31 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
- <source>…as Printable Text</source>
+ <source>…as MIME Data</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Copy only the printable text in the packet.</source>
+ <source>…as C String</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>…as MIME Data</source>
+ <source>Copy packet bytes as printable ASCII characters and escape sequences.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>…as C String</source>
+ <source>…as Go literal</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Copy packet bytes as printable ASCII characters and escape sequences.</source>
+ <source>Copy packet bytes as Go literal.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>…as C Array</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as C Array.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2032,6 +2187,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>…as UTF-8 Text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as text, treating as UTF-8.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>…as ASCII Text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as text, treating as ASCII.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Copy packet bytes as a stream of hex.</source>
<translation type="unfinished"></translation>
</message>
@@ -2825,6 +2996,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Display filter:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Export PDUs</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>ExtArgSelector</name>
@@ -2864,10 +3039,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
- <source>Save</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Default</source>
<translation type="unfinished"></translation>
</message>
@@ -3009,6 +3180,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Display Filter Macros</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>New macro</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Open </source>
<translation type="unfinished"></translation>
</message>
@@ -3092,10 +3271,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>FilterListModel</name>
<message>
+ <source>Macro Name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Filter Name</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Macro Expression</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Filter Expression</source>
<translation type="unfinished"></translation>
</message>
@@ -3181,75 +3368,71 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>FolderListModel</name>
<message>
- <source>&quot;File&quot; dialogs</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>capture files</source>
+ <source>Temp</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Temp</source>
+ <source>Personal configuration</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>untitled capture files</source>
+ <source>Global configuration</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Personal configuration</source>
+ <source>System</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Global configuration</source>
+ <source>ethers, ipxnets</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>dfilters, preferences, ethers, …</source>
+ <source>Program</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>dfilters, preferences, manuf, …</source>
+ <source>Personal Plugins</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>System</source>
+ <source>Global Plugins</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>ethers, ipxnets</source>
+ <source>Personal Lua Plugins</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Program</source>
+ <source>Global Lua Plugins</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>program files</source>
+ <source>Lua scripts</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Personal Plugins</source>
+ <source>&quot;File&quot; dialog location</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>binary plugins</source>
+ <source>Capture files</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Global Plugins</source>
+ <source>Untitled capture files</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Personal Lua Plugins</source>
+ <source>Preferences, profiles, manuf, …</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Global Lua Plugins</source>
+ <source>Program files</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Lua scripts</source>
+ <source>Binary plugins</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -3257,7 +3440,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
- <source>external capture (extcap) plugins</source>
+ <source>External capture (extcap) plugins</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -3395,6 +3578,24 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</translation>
</message>
<message>
+ <source>Event %1. </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;reads&lt;/span&gt;, </source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;writes&lt;/span&gt;, </source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
<source> Click to select.</source>
<translation type="unfinished"></translation>
</message>
@@ -3427,6 +3628,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Read activity(%6)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Write activity(%6)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Entire I/O activity (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Entire conversation (%1)</source>
<translation type="unfinished"></translation>
</message>
@@ -3442,10 +3655,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Save Stream Content As…</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <source>[Stream output truncated]</source>
- <translation type="unfinished"></translation>
- </message>
<message numerus="yes">
<source>%Ln total stream(s).</source>
<translation type="unfinished">
@@ -3473,8 +3682,19 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
- <source>Show data as</source>
- <oldsource>Show and save data as</oldsource>
+ <source>Show as</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>No delta times</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Turn delta times</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All delta times</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -3490,11 +3710,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Case sensitive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Find &amp;Next</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
+ <name>FollowStreamText</name>
+ <message>
+ <source>[Stream output truncated]</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FontColorPreferencesFrame</name>
<message>
<source>Frame</source>
@@ -3801,28 +4032,27 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
- <source>Remove this graph.</source>
- <oldsource>Remove this dissection behavior.</oldsource>
+ <source>Add a new graph.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Add a new graph.</source>
+ <source>Clear all graphs.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Duplicate this graph.</source>
+ <source>Remove the selected graph(s).</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Clear all graphs.</source>
+ <source>Duplicate the selected graph(s).</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Move this graph upwards.</source>
+ <source>Move the selected graph(s) upwards.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Move this graph downwards.</source>
+ <source>Move the selected graph(s) downwards.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -3866,10 +4096,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
- <source>Reset</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Reset Graph</source>
<translation type="unfinished"></translation>
</message>
@@ -4083,6 +4309,42 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>1 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>2 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>5 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>10 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>20 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>50 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>100 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>200 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>500 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>1 ms</source>
<translation type="unfinished"></translation>
</message>
@@ -4127,6 +4389,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>2 min</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>5 min</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Wireshark I/O Graphs: %1</source>
<translation type="unfinished"></translation>
</message>
@@ -4139,6 +4409,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>All packets</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All events</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>All Packets</source>
<translation type="unfinished"></translation>
</message>
@@ -4151,7 +4429,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
- <source>Access Denied</source>
+ <source>All Execs</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -4199,6 +4477,34 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>%1 Intervals </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to top left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to top center</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to top right</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to bottom left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to bottom center</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to bottom right</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Portable Document Format (*.pdf)</source>
<translation type="unfinished"></translation>
</message>
@@ -4951,6 +5257,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>InterfaceTreeDelegate</name>
+ <message>
+ <source>default</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>InterfaceTreeModel</name>
<message>
<source>Show</source>
@@ -5927,7 +6240,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>LteMacStatisticsDialog</name>
<message>
- <source>LTE Mac Statistics</source>
+ <source>LTE/NR Mac Statistics</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -6207,11 +6520,11 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
- <source>LTE RLC Graph (UE=%1 chan=%2%3 %4 - %5)</source>
+ <source>%1 RLC Graph (UE=%2 chan=%3%4 %5 - %6)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>LTE RLC Graph - no channel selected</source>
+ <source>3GPP RLC Graph - no channel selected</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -6266,7 +6579,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>LteRlcStatisticsDialog</name>
<message>
- <source>LTE RLC Statistics</source>
+ <source>3GPP RLC Statistics</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -6353,6 +6666,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source> %1 Displayed: %2 (%3%)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Manage Profiles…</source>
<translation type="unfinished"></translation>
</message>
@@ -6414,6 +6731,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<numerusform>%Ln bytes</numerusform>
</translation>
</message>
+ <message numerus="yes">
+ <source>%Ln bit(s)</source>
+ <translation>
+ <numerusform>%Ln bit</numerusform>
+ <numerusform>%Ln bits</numerusform>
+ </translation>
+ </message>
<message>
<source>Byte %1</source>
<translation type="unfinished"></translation>
@@ -6427,8 +6751,11 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
- <source>Packets: %1 %4 Displayed: %2 (%3%)</source>
- <oldsource>Packets: %1 %4 Displayed: %2 %4 Marked: %3</oldsource>
+ <source>Selected Event: %1 %2 </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Events: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -6461,6 +6788,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>No Events</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>From Zip File...</source>
<translation type="unfinished"></translation>
</message>
@@ -6493,6 +6824,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>MainWindow</name>
+ <message>
+ <source>Display filter as %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>MainWindowPreferencesFrame</name>
<message>
<source>Frame</source>
@@ -6524,6 +6862,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>The current working directory</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Show up to</source>
<translation type="unfinished"></translation>
</message>
@@ -6954,6 +7296,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Refresh</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Save Diagram As…</source>
<translation type="unfinished"></translation>
</message>
@@ -7001,6 +7347,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Layout:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Packet %1</source>
<translation type="unfinished"></translation>
</message>
@@ -7023,6 +7373,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<numerusform>%Ln bytes</numerusform>
</translation>
</message>
+ <message numerus="yes">
+ <source>%Ln bit(s)</source>
+ <translation>
+ <numerusform>%Ln bit</numerusform>
+ <numerusform>%Ln bits</numerusform>
+ </translation>
+ </message>
</context>
<context>
<name>PacketFormatGroupBox</name>
@@ -7480,10 +7837,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>The number of packets or events to check for automatic profile switching.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Auto switch packet limit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Configuration Profiles</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Auto switch event limit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Import</source>
<comment>noun</comment>
<translation type="unfinished"></translation>
@@ -7666,6 +8035,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Auto Switch Filter</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>copy</source>
<comment>noun</comment>
<translation type="unfinished"></translation>
@@ -8025,6 +8398,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Unacked (Outstanding) Bytes (B)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>[no capture file]</source>
<translation type="unfinished"></translation>
</message>
@@ -8185,6 +8562,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>LTE</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>NR</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>C-RNTI</source>
<translation type="unfinished"></translation>
</message>
@@ -8205,6 +8590,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>RAT</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>UL Frames</source>
<translation type="unfinished"></translation>
</message>
@@ -8428,9 +8817,69 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Browse…</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>PACKETS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>EVENTS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>BYTES</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>BITS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>COUNT FRAMES</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>COUNT FIELDS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>SUM</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>MAX</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>MIN</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>AVERAGE</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>THROUGHPUT</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>LOAD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Center</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Right</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
- <name>QObject::QObject</name>
+ <name>QObject::QObject::QObject</name>
<message>
<source>CCCH</source>
<translation type="unfinished"></translation>
@@ -8531,6 +8980,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>ResizeHeaderView</name>
+ <message>
+ <source>Resize all %1 to contents</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>ResolvedAddressesDialog</name>
<message>
<source>Dialog</source>
@@ -8646,6 +9102,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save as…</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source># Resolved addresses found in %1</source>
<translation type="unfinished"></translation>
</message>
@@ -8657,6 +9121,61 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>ResolvedAddressesView</name>
+ <message>
+ <source>as Plain Text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy selected rows</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy table</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>as CSV</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>as JSON</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save selected rows as…</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save table as…</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save Resolved Addresses As…</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Plain text (*.txt)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>CSV Document (*.csv)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>JSON Document (*.json)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Unable to save %1: %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>ResponseTimeDelayDialog</name>
<message>
<source>%1 Response Time Delay Statistics</source>
@@ -10327,6 +10846,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>&lt;b&gt;Options:&lt;/b&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for strings containing narrow (UTF-8 and ASCII) or wide (UTF-16) characters.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
@@ -10347,6 +10870,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Backwards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for a subsequent occurrence in the current packet before advancing to the next packet.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Multiple occurrences</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5), a plain string (e.g. My String) or a regular expression (e.g. colou?r).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<oldsource>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5) or a plain string (e.g. My String).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</oldsource>
<translation type="unfinished"></translation>
@@ -10384,6 +10919,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Event List</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Event Details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Event Bytes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search the Info column of the event list (summary pane), decoded event display labels (tree view pane) or the ASCII-converted event data (hex view pane).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>That filter doesn&apos;t test anything.</source>
<translation type="unfinished"></translation>
</message>
@@ -10804,6 +11355,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Case sensitive</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Find &amp;Next</source>
<translation type="unfinished"></translation>
</message>
@@ -10899,14 +11454,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Decoded as %1.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Save Selected Packet Bytes As…</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>compressed %1</source>
+ <translation type="unfinished"></translation>
+ </message>
<message numerus="yes">
- <source>Displaying %Ln byte(s).</source>
+ <source>Using %Ln byte(s).</source>
<translation type="unfinished">
- <numerusform>Displaying %Ln byte.</numerusform>
- <numerusform>Displaying %Ln bytes.</numerusform>
+ <numerusform>Using %Ln byte.</numerusform>
+ <numerusform>Using %Ln bytes.</numerusform>
</translation>
</message>
<message>
@@ -11006,6 +11569,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Display filter:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Strip Headers</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>SupportedProtocolsDialog</name>
@@ -11940,21 +12507,19 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
- <source>Remove this entry.</source>
- <oldsource>Remove this profile.</oldsource>
+ <source>Remove the selected entry(ies).</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Copy this entry.</source>
- <oldsource>Copy this profile.</oldsource>
+ <source>Copy the selected entry(ies).</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry up.</source>
+ <source>Move the selected entry(ies) up.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry down.</source>
+ <source>Move the selected entry(ies) down.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -11981,19 +12546,19 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
- <source>Remove this entry.</source>
+ <source>Remove the selected entry(ies).</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Copy this entry.</source>
+ <source>Copy the selected entry(ies).</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry up.</source>
+ <source>Move the selected entry(ies) up.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry down.</source>
+ <source>Move the selected entry(ies) down.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -12323,10 +12888,18 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
+ <source>You are sniffing the glue that holds your system together using Logray </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>You are running Wireshark </source>
<translation type="unfinished"></translation>
</message>
<message>
+ <source>You are running Logray </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source> You receive automatic updates.</source>
<translation type="unfinished"></translation>
</message>
@@ -12603,14 +13176,6 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Contents</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Wireshark Filter</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>TShark</source>
<translation type="unfinished"></translation>
</message>
@@ -12876,10 +13441,6 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
- <source>Help contents</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>FAQs</source>
<translation type="unfinished"></translation>
</message>
@@ -13002,7 +13563,7 @@ a:hover {
<message>
<source>&amp;Mark/Unmark Packet(s)</source>
<oldsource>&amp;Mark/Unmark Packet</oldsource>
- <translation type="unfinished">&amp;Mark/Unmark Packet</translation>
+ <translation type="obsolete">&amp;Mark/Unmark Packet</translation>
</message>
<message>
<source>Mark All Displayed</source>
@@ -13035,7 +13596,7 @@ a:hover {
<message>
<source>&amp;Ignore/Unignore Packet(s)</source>
<oldsource>&amp;Ignore/Unignore Packet</oldsource>
- <translation type="unfinished">&amp;Ignore/Unignore Packet</translation>
+ <translation type="obsolete">&amp;Ignore/Unignore Packet</translation>
</message>
<message>
<source>Ignore All Displayed</source>
@@ -13478,10 +14039,6 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
- <source>Reset appearance layout to default size</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Seconds Since First Captured Packet</source>
<translation type="unfinished"></translation>
</message>
@@ -13642,19 +14199,27 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
- <source>TLS Keylog Launcher</source>
+ <source>&amp;Options…</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Release Notes</source>
+ <source>&amp;3GPP Uu</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Options…</source>
+ <source>&amp;Wireless</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Wireless</source>
+ <source>&amp;User&apos;s Guide</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Wireshark User&apos;s Guide</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Display Filters</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -13702,10 +14267,18 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
+ <source>&amp;Mark/Unmark Selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Mark or unmark each selected packet</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <source>&amp;Ignore/Unignore Selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Ignore or unignore each selected packet</source>
<translation type="unfinished"></translation>
</message>
@@ -13746,6 +14319,18 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
+ <source>General</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Query-Response</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>DNS Query-Response Statistics</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Request Sequences</source>
<translation type="unfinished"></translation>
</message>
@@ -13754,6 +14339,14 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
+ <source>E2AP</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>E2AP Messages</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Decode &amp;As…</source>
<translation type="unfinished"></translation>
</message>
@@ -13814,6 +14407,10 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Reset layout to default size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Resize Columns</source>
<translation type="unfinished"></translation>
</message>
@@ -14072,6 +14669,14 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
+ <source>TLS Keylog Launcher</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Release Notes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&amp;VoIP Calls</source>
<translation type="unfinished"></translation>
</message>
@@ -14104,10 +14709,6 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;LTE</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>&amp;MTP3</source>
<translation type="unfinished"></translation>
</message>
@@ -14392,6 +14993,10 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
+ <source>USB CDC Data</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>There is no &quot;rtp.ssrc&quot; field in this version of Wireshark.</source>
<translation type="unfinished"></translation>
</message>
diff --git a/ui/qt/wireshark_es.ts b/ui/qt/wireshark_es.ts
index 3f5a016c..acd75cb1 100644
--- a/ui/qt/wireshark_es.ts
+++ b/ui/qt/wireshark_es.ts
@@ -44,8 +44,8 @@
<translation>Carpetas</translation>
</message>
<message>
- <source>Filter by path</source>
- <translation>Filtrar por ruta</translation>
+ <source>Search Folders</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Plugins</source>
@@ -80,6 +80,14 @@
<translation>Licencia</translation>
</message>
<message>
+ <source>About Logray</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Logray</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>The directory does not exist</source>
<translation>El directorio no existe</translation>
</message>
@@ -755,6 +763,28 @@
</message>
</context>
<context>
+ <name>CaptureCommentDialog</name>
+ <message>
+ <source>Edit Capture Comments</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add Comment</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Section %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>CaptureCommentTabWidget</name>
+ <message>
+ <source>Comment %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>CaptureFile</name>
<message>
<source> [closing]</source>
@@ -840,10 +870,6 @@
<translation>Filtro de lectura:</translation>
</message>
<message>
- <source>Compress with g&amp;zip</source>
- <translation>Comprimir con g&amp;zip</translation>
- </message>
- <message>
<source>Open Capture File</source>
<oldsource>Wireshark: Open Capture File</oldsource>
<translation>Abrir archivo de captura</translation>
@@ -925,8 +951,8 @@
<translation>Detalles</translation>
</message>
<message>
- <source>Capture file comments</source>
- <translation>Comentarios de archivo de captura</translation>
+ <source>Edit Comments</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Refresh</source>
@@ -937,10 +963,6 @@
<translation>Copiar al portapapeles</translation>
</message>
<message>
- <source>Save Comments</source>
- <translation>Guardar comentarios</translation>
- </message>
- <message>
<source>Capture File Properties</source>
<translation>Propiedades de archivo de captura</translation>
</message>
@@ -989,10 +1011,18 @@
<translation>Primer paquete</translation>
</message>
<message>
+ <source>First event</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Last packet</source>
<translation>Último paquete</translation>
</message>
<message>
+ <source>Last event</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Elapsed</source>
<translation>Transcurrido</translation>
</message>
@@ -1029,6 +1059,10 @@
<translation>Paquetes perdidos</translation>
</message>
<message>
+ <source>Dropped events</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Capture filter</source>
<translation>Filtro de captura</translation>
</message>
@@ -1041,6 +1075,10 @@
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Event size limit (snaplen)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>none</source>
<translation>ninguno</translation>
</message>
@@ -1049,6 +1087,26 @@
<translation>%1 bytes</translation>
</message>
<message>
+ <source>Comments</source>
+ <translation type="unfinished">Comentarios</translation>
+ </message>
+ <message>
+ <source>Comment %1: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Decryption Secrets</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation type="unfinished">Tipo</translation>
+ </message>
+ <message>
+ <source>Size</source>
+ <translation type="unfinished">Tamaño</translation>
+ </message>
+ <message>
<source>Statistics</source>
<translation>Estadísticas</translation>
</message>
@@ -1073,6 +1131,10 @@
<translation>Paquetes</translation>
</message>
<message>
+ <source>Events</source>
+ <translation type="unfinished">Eventos</translation>
+ </message>
+ <message>
<source>Time span, s</source>
<translation>Espacio de tiempo, s</translation>
</message>
@@ -1085,6 +1147,10 @@
<translation>Promedio de tamaño de paquete, B</translation>
</message>
<message>
+ <source>Average event size, B</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Bytes</source>
<translation>Bytes</translation>
</message>
@@ -1097,14 +1163,14 @@
<translation>Promedio de bits/s</translation>
</message>
<message>
- <source>Section Comment</source>
- <translation>Sección de comentarios</translation>
- </message>
- <message>
<source>Packet Comments</source>
<translation>Comentarios de paquete</translation>
</message>
<message>
+ <source>Event Comments</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;p&gt;Frame %1: </source>
<translation>&lt;p&gt;Trama %1:</translation>
</message>
@@ -1114,6 +1180,12 @@
</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Created by Logray %1
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>CaptureFilterCombo</name>
@@ -1341,6 +1413,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</translation>
</message>
<message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for some more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enable monitor mode on all 802.11 interfaces</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>compression</source>
<translation>compresión</translation>
</message>
@@ -1353,6 +1433,30 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation>gzip</translation>
</message>
<message>
+ <source>File infix pattern</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;In multiple file mode, the date and time and file index number are inserted between filename template and any suffix. Select their order.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>YYYYmmDDHHMMSS_NNNNN</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Date and time before the file index number. This causes files to sort in creation time order, and keeps files from the same batch closely ordered.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>NNNNN_YYYYmmDDHHMMSS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;File index number before the date and time. This is the historic Wireshark ordering.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;After capturing has switched to the next file and the given number of files has exceeded, the oldest file will be removed.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Después de que la captura haya cambiado al siguiente archivo y el número proporcionado haya excedido, se eliminará el archivo más antiguo.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1441,6 +1545,10 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Detiene la captura después de haber sido creado el número especificado de archivos.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
+ <source>Stop capturing after the specified number of files have been created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Stop capturing after the specified amount of data has been captured.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Detiene la captura después de haber sido capturada la cantidad de datos especificada.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1501,8 +1609,8 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation>Error</translation>
</message>
<message>
- <source>Multiple files: Requested filesize too large. The filesize cannot be greater than 2 GiB.</source>
- <translation>Varios archivos: El tamaño de archivo solicitado es demasiado grande. El tamaño de archivo no puede ser mayor de 2 GiB. </translation>
+ <source>Multiple files: Requested filesize too large. The filesize cannot be greater than 2 TB.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Multiple files: No capture file name given. You must specify a filename if you want to use multiple files.</source>
@@ -1532,6 +1640,14 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation>Capturar paquetes en modo promiscuo</translation>
</message>
<message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Capture packets in monitor mode on 802.11 devices</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Capture packets in the next-generation capture file format.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Captura paquetes en formato de archivo de captura de próxima generación.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1759,6 +1875,14 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Width</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Alignment</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;Show human-readable strings instead of raw values for fields. Only applicable to custom columns with fields that have value strings.&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
@@ -1806,6 +1930,25 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
</context>
<context>
+ <name>CompressionGroupBox</name>
+ <message>
+ <source>Compression options</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Uncompressed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Compress with g&amp;zip</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Compress with &amp;LZ4</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>ConversationDataModel</name>
<message>
<source>Address A</source>
@@ -1872,6 +2015,10 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation>Bits/s B </translation>
</message>
<message>
+ <source>Flows</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Total Packets</source>
<translation>Paquetes totales</translation>
</message>
@@ -1986,23 +2133,31 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation type="unfinished"></translation>
</message>
<message>
- <source>…as Printable Text</source>
+ <source>…as MIME Data</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Copy only the printable text in the packet.</source>
+ <source>…as C String</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>…as MIME Data</source>
+ <source>Copy packet bytes as printable ASCII characters and escape sequences.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>…as C String</source>
+ <source>…as Go literal</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Copy packet bytes as printable ASCII characters and escape sequences.</source>
+ <source>Copy packet bytes as Go literal.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>…as C Array</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as C Array.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2010,6 +2165,22 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation type="unfinished"></translation>
</message>
<message>
+ <source>…as UTF-8 Text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as text, treating as UTF-8.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>…as ASCII Text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as text, treating as ASCII.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Copy packet bytes as a stream of hex.</source>
<translation type="unfinished"></translation>
</message>
@@ -2805,6 +2976,10 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<source>Display filter:</source>
<translation>Filtro de visualización:</translation>
</message>
+ <message>
+ <source>Export PDUs</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>ExtArgSelector</name>
@@ -2844,10 +3019,6 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation type="unfinished"></translation>
</message>
<message>
- <source>Save</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Default</source>
<translation type="unfinished">Predeterminado</translation>
</message>
@@ -2989,6 +3160,14 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation>Filtros de visualización</translation>
</message>
<message>
+ <source>Display Filter Macros</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>New macro</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Open </source>
<translation type="unfinished">Abrir</translation>
</message>
@@ -3072,10 +3251,18 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<context>
<name>FilterListModel</name>
<message>
+ <source>Macro Name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Filter Name</source>
<translation>Nombre de filtro</translation>
</message>
<message>
+ <source>Macro Expression</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Filter Expression</source>
<translation>Expresión de filtro</translation>
</message>
@@ -3161,22 +3348,10 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<context>
<name>FolderListModel</name>
<message>
- <source>&quot;File&quot; dialogs</source>
- <translation>Diálogos de &quot;Archivo&quot;</translation>
- </message>
- <message>
- <source>capture files</source>
- <translation>archivos de captura</translation>
- </message>
- <message>
<source>Temp</source>
<translation>Temporal</translation>
</message>
<message>
- <source>untitled capture files</source>
- <translation>archivos de captura sin título</translation>
- </message>
- <message>
<source>Personal configuration</source>
<translation>Configuración personal</translation>
</message>
@@ -3185,14 +3360,6 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation>Configuración global</translation>
</message>
<message>
- <source>dfilters, preferences, ethers, …</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>dfilters, preferences, manuf, …</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>System</source>
<translation>Sistema</translation>
</message>
@@ -3205,18 +3372,10 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation>Programa</translation>
</message>
<message>
- <source>program files</source>
- <translation>archivos de programa</translation>
- </message>
- <message>
<source>Personal Plugins</source>
<translation>Complementos personales</translation>
</message>
<message>
- <source>binary plugins</source>
- <translation>complementos binarios</translation>
- </message>
- <message>
<source>Global Plugins</source>
<translation>Complementos globales</translation>
</message>
@@ -3233,11 +3392,35 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation type="unfinished"></translation>
</message>
<message>
+ <source>&quot;File&quot; dialog location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Capture files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Untitled capture files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Preferences, profiles, manuf, …</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Program files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Binary plugins</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Personal Extcap path</source>
<translation>Ruta personal de Extcap</translation>
</message>
<message>
- <source>external capture (extcap) plugins</source>
+ <source>External capture (extcap) plugins</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -3361,6 +3544,24 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</translation>
</message>
<message>
+ <source>Event %1. </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;reads&lt;/span&gt;, </source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;writes&lt;/span&gt;, </source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
<source> Click to select.</source>
<translation>Clic para seleccionar.</translation>
</message>
@@ -3393,6 +3594,18 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Read activity(%6)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Write activity(%6)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Entire I/O activity (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Entire conversation (%1)</source>
<translation>Conversación completa (%1)</translation>
</message>
@@ -3408,10 +3621,6 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<source>Save Stream Content As…</source>
<translation>Guardar contenido de secuencia como…</translation>
</message>
- <message>
- <source>[Stream output truncated]</source>
- <translation type="unfinished"></translation>
- </message>
<message numerus="yes">
<source>%Ln total stream(s).</source>
<translation type="unfinished">
@@ -3439,9 +3648,20 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation>Hint.</translation>
</message>
<message>
- <source>Show data as</source>
- <oldsource>Show and save data as</oldsource>
- <translation>Mostrar datos como</translation>
+ <source>Show as</source>
+ <translation type="unfinished">Mostrar como</translation>
+ </message>
+ <message>
+ <source>No delta times</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Turn delta times</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All delta times</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Stream</source>
@@ -3456,11 +3676,22 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation>Buscar:</translation>
</message>
<message>
+ <source>Case sensitive</source>
+ <translation type="unfinished">Mayúsculas y minúsculas</translation>
+ </message>
+ <message>
<source>Find &amp;Next</source>
<translation>Buscar &amp;siguiente</translation>
</message>
</context>
<context>
+ <name>FollowStreamText</name>
+ <message>
+ <source>[Stream output truncated]</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FontColorPreferencesFrame</name>
<message>
<source>Frame</source>
@@ -3796,28 +4027,27 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <source>Remove this graph.</source>
- <oldsource>Remove this dissection behavior.</oldsource>
- <translation>Elimina esta gráfica.</translation>
- </message>
- <message>
<source>Add a new graph.</source>
<translation>Añade una nueva gráfica.</translation>
</message>
<message>
- <source>Duplicate this graph.</source>
- <translation>Duplica esta gráfica.</translation>
- </message>
- <message>
<source>Clear all graphs.</source>
<translation>Vacía todas las gráficas.</translation>
</message>
<message>
- <source>Move this graph upwards.</source>
+ <source>Remove the selected graph(s).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Duplicate the selected graph(s).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move the selected graph(s) upwards.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Move this graph downwards.</source>
+ <source>Move the selected graph(s) downwards.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -3861,10 +4091,6 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation type="unfinished"></translation>
</message>
<message>
- <source>Reset</source>
- <translation>Restablecer</translation>
- </message>
- <message>
<source>Reset Graph</source>
<translation>Restablecer gráfica</translation>
</message>
@@ -3967,7 +4193,7 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
<message>
<source>Go to packet currently under the cursor</source>
- <translation type="unfinished"></translation>
+ <translation>Va al paquete actualmente debajo del cursor</translation>
</message>
<message>
<source>G</source>
@@ -4078,6 +4304,42 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation>Copia gráficas desde otro perfil.</translation>
</message>
<message>
+ <source>1 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>2 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>5 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>10 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>20 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>50 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>100 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>200 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>500 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>1 ms</source>
<translation>1 ms</translation>
</message>
@@ -4122,6 +4384,14 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation>5 sec</translation>
</message>
<message>
+ <source>2 min</source>
+ <translation type="unfinished">10 min {2 ?}</translation>
+ </message>
+ <message>
+ <source>5 min</source>
+ <translation type="unfinished">10 min {5 ?}</translation>
+ </message>
+ <message>
<source>Wireshark I/O Graphs: %1</source>
<translation>Gráficas E/S de Wireshark: %1</translation>
</message>
@@ -4134,6 +4404,14 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation type="unfinished"></translation>
</message>
<message>
+ <source>All packets</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All events</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>All Packets</source>
<translation>Todos los paquetes</translation>
</message>
@@ -4146,7 +4424,7 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation type="unfinished"></translation>
</message>
<message>
- <source>Access Denied</source>
+ <source>All Execs</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -4183,7 +4461,7 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
<message>
<source>Release to zoom, x = %1 to %2, y = %3 to %4</source>
- <translation>Soltar para zoom, x = %1 a %2, y = %3 a %4</translation>
+ <translation>Suelte para zoom, x = %1 a %2, y = %3 a %4</translation>
</message>
<message>
<source>Unable to select range.</source>
@@ -4194,6 +4472,34 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation>Clic para seleccionar una parte de la gráfica.</translation>
</message>
<message>
+ <source>%1 Intervals </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to top left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to top center</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to top right</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to bottom left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to bottom center</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to bottom right</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Portable Document Format (*.pdf)</source>
<translation>Formato de documento portable (*.pdf)</translation>
</message>
@@ -4946,6 +5252,13 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
</context>
<context>
+ <name>InterfaceTreeDelegate</name>
+ <message>
+ <source>default</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>InterfaceTreeModel</name>
<message>
<source>Show</source>
@@ -5922,7 +6235,7 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<context>
<name>LteMacStatisticsDialog</name>
<message>
- <source>LTE Mac Statistics</source>
+ <source>LTE/NR Mac Statistics</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -6147,7 +6460,7 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
<message>
<source>Go to packet currently under the cursor</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Va al paquete actualmente debajo del cursor</translation>
</message>
<message>
<source>G</source>
@@ -6202,11 +6515,11 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation type="unfinished"></translation>
</message>
<message>
- <source>LTE RLC Graph (UE=%1 chan=%2%3 %4 - %5)</source>
+ <source>%1 RLC Graph (UE=%2 chan=%3%4 %5 - %6)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>LTE RLC Graph - no channel selected</source>
+ <source>3GPP RLC Graph - no channel selected</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -6227,7 +6540,7 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
<message>
<source>Release to zoom, x = %1 to %2, y = %3 to %4</source>
- <translation type="unfinished">Soltar para zoom, x = %1 a %2, y = %3 a %4</translation>
+ <translation type="unfinished">Suelte para zoom, x = %1 a %2, y = %3 a %4</translation>
</message>
<message>
<source>Unable to select range.</source>
@@ -6261,7 +6574,7 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<context>
<name>LteRlcStatisticsDialog</name>
<message>
- <source>LTE RLC Statistics</source>
+ <source>3GPP RLC Statistics</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -6348,6 +6661,10 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation>Perfil: %1</translation>
</message>
<message>
+ <source> %1 Displayed: %2 (%3%)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Manage Profiles…</source>
<translation>Administrar perfiles…</translation>
</message>
@@ -6409,6 +6726,13 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<numerusform></numerusform>
</translation>
</message>
+ <message numerus="yes">
+ <source>%Ln bit(s)</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
<message>
<source>Byte %1</source>
<translation>Byte %1</translation>
@@ -6422,9 +6746,12 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation>Paquete seleccionado: %1 %2</translation>
</message>
<message>
- <source>Packets: %1 %4 Displayed: %2 (%3%)</source>
- <oldsource>Packets: %1 %4 Displayed: %2 %4 Marked: %3</oldsource>
- <translation>Paquetes: %1 %4 Mostrado: %2 (%3%)</translation>
+ <source>Selected Event: %1 %2 </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Events: %1</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source> %1 Selected: %2 (%3%)</source>
@@ -6456,6 +6783,10 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation>No hay paquetes</translation>
</message>
<message>
+ <source>No Events</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>From Zip File...</source>
<translation type="unfinished"></translation>
</message>
@@ -6488,6 +6819,13 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
</context>
<context>
+ <name>MainWindow</name>
+ <message>
+ <source>Display filter as %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>MainWindowPreferencesFrame</name>
<message>
<source>Frame</source>
@@ -6519,6 +6857,10 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation>La carpeta usada más recientemente</translation>
</message>
<message>
+ <source>The current working directory</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Show up to</source>
<translation>Mostrar hasta</translation>
</message>
@@ -6949,6 +7291,10 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Refresh</source>
+ <translation type="unfinished">Actualizar</translation>
+ </message>
+ <message>
<source>Save Diagram As…</source>
<translation type="unfinished"></translation>
</message>
@@ -6996,6 +7342,10 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation>Mostrar bytes de paquete</translation>
</message>
<message>
+ <source>Layout:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Packet %1</source>
<translation>Paquete %1</translation>
</message>
@@ -7018,6 +7368,13 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<numerusform></numerusform>
</translation>
</message>
+ <message numerus="yes">
+ <source>%Ln bit(s)</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
</context>
<context>
<name>PacketFormatGroupBox</name>
@@ -7475,10 +7832,22 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation>Copia este perfil.</translation>
</message>
<message>
+ <source>The number of packets or events to check for automatic profile switching.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Auto switch packet limit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Configuration Profiles</source>
<translation>Configuración de perfiles</translation>
</message>
<message>
+ <source>Auto switch event limit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Import</source>
<comment>noun</comment>
<translation>Importar</translation>
@@ -7647,6 +8016,10 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Auto Switch Filter</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>copy</source>
<comment>noun</comment>
<translation type="unfinished"></translation>
@@ -8006,6 +8379,10 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Unacked (Outstanding) Bytes (B)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>[no capture file]</source>
<translation>[no hay archivo de captura]</translation>
</message>
@@ -8166,6 +8543,14 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation type="unfinished"></translation>
</message>
<message>
+ <source>LTE</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>NR</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>C-RNTI</source>
<translation type="unfinished"></translation>
</message>
@@ -8186,6 +8571,10 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation>UEId</translation>
</message>
<message>
+ <source>RAT</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>UL Frames</source>
<translation>Tramas UL</translation>
</message>
@@ -8409,12 +8798,72 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<source>Browse…</source>
<translation type="unfinished">Explorar…</translation>
</message>
+ <message>
+ <source>PACKETS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>EVENTS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>BYTES</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>BITS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>COUNT FRAMES</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>COUNT FIELDS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>SUM</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>MAX</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>MIN</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>AVERAGE</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>THROUGHPUT</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>LOAD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Center</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Right</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
- <name>QObject::QObject</name>
+ <name>QObject::QObject::QObject</name>
<message>
<source>CCCH</source>
- <translation>CCCH</translation>
+ <translation type="unfinished">CCCH</translation>
</message>
</context>
<context>
@@ -8512,6 +8961,13 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
</context>
<context>
+ <name>ResizeHeaderView</name>
+ <message>
+ <source>Resize all %1 to contents</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>ResolvedAddressesDialog</name>
<message>
<source>Dialog</source>
@@ -8627,6 +9083,14 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation>Direcciones resueltas</translation>
</message>
<message>
+ <source>Copy</source>
+ <translation type="unfinished">Copiar</translation>
+ </message>
+ <message>
+ <source>Save as…</source>
+ <translation type="unfinished">Guardar como…</translation>
+ </message>
+ <message>
<source># Resolved addresses found in %1</source>
<translation># Direcciones resultas encontradas en %1</translation>
</message>
@@ -8640,6 +9104,61 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
</context>
<context>
+ <name>ResolvedAddressesView</name>
+ <message>
+ <source>as Plain Text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy selected rows</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy table</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>as CSV</source>
+ <translation type="unfinished">como CSV</translation>
+ </message>
+ <message>
+ <source>as JSON</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save selected rows as…</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save table as…</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save Resolved Addresses As…</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Plain text (*.txt)</source>
+ <translation type="unfinished">Texto plano (*.txt)</translation>
+ </message>
+ <message>
+ <source>CSV Document (*.csv)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>JSON Document (*.json)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation type="unfinished">Advertencia</translation>
+ </message>
+ <message>
+ <source>Unable to save %1: %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>ResponseTimeDelayDialog</name>
<message>
<source>%1 Response Time Delay Statistics</source>
@@ -8977,11 +9496,11 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
<message>
<source>Prepare &amp;Filter</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Preparar &amp;filtro</translation>
</message>
<message>
<source>Prepare a filter matching the selected stream(s).</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Prepara un filtro que coincide con los flujo(s) seleccionado(s).</translation>
</message>
<message>
<source>&amp;Current Tab</source>
@@ -9284,7 +9803,7 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
<message>
<source>Invert selection</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Invierte la selección</translation>
</message>
<message>
<source>Play/Pause</source>
@@ -9332,11 +9851,11 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
<message>
<source>Prepare &amp;Filter</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Preparar &amp;filtro</translation>
</message>
<message>
<source>Prepare a filter matching the selected stream(s).</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Prepara un filtro que coincide con los flujo(s) seleccionado(s).</translation>
</message>
<message>
<source>R&amp;efresh streams</source>
@@ -9392,7 +9911,7 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
<message>
<source>Go to packet currently under the cursor</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Va al paquete actualmente debajo del cursor</translation>
</message>
<message>
<source>Play the stream</source>
@@ -9420,7 +9939,7 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
<message>
<source>Select</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Seleccionar</translation>
</message>
<message>
<source>Audio Routing</source>
@@ -9611,7 +10130,7 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
<message>
<source>Start Time</source>
- <translation type="unfinished"></translation>
+ <translation>Hora de inicio</translation>
</message>
<message>
<source>Duration</source>
@@ -9667,7 +10186,7 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
<message>
<source>Prepare &amp;Filter</source>
- <translation type="unfinished"></translation>
+ <translation>Preparar &amp;filtro</translation>
</message>
<message>
<source>&amp;Export</source>
@@ -9763,7 +10282,7 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
<message>
<source>Invert selection</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Invierte la selección</translation>
</message>
<message>
<source>Go To Setup</source>
@@ -9779,7 +10298,7 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
<message>
<source>Prepare a filter matching the selected stream(s).</source>
- <translation type="unfinished"></translation>
+ <translation>Prepara un filtro que coincide con los flujo(s) seleccionado(s).</translation>
</message>
<message>
<source>P</source>
@@ -9811,7 +10330,7 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
<message>
<source>Copy stream list as CSV.</source>
- <translation type="unfinished">Copia el listado de secuencias como CSV.</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Copy as YAML</source>
@@ -9819,7 +10338,7 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
<message>
<source>Copy stream list as YAML.</source>
- <translation type="unfinished">Copia el listado de secuencias como YAML.</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>RTP Streams</source>
@@ -9827,7 +10346,7 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
<message>
<source>Select</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Seleccionar</translation>
</message>
<message>
<source>as CSV</source>
@@ -10310,6 +10829,10 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation>Bytes de paquete</translation>
</message>
<message>
+ <source>&lt;b&gt;Options:&lt;/b&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for strings containing narrow (UTF-8 and ASCII) or wide (UTF-16) characters.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Busca cadenas que contienen caracteres reducidos (UTF-8 y ASCII) o ampliados (UTF-16).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -10330,6 +10853,18 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation>Mayúsculas y minúsculas</translation>
</message>
<message>
+ <source>Backwards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for a subsequent occurrence in the current packet before advancing to the next packet.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Multiple occurrences</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5), a plain string (e.g. My String) or a regular expression (e.g. colou?r).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<oldsource>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5) or a plain string (e.g. My String).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</oldsource>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Busca datos usando sintaxis de filtro de visualización (e.j. ip.addr==10.1.1.1), una cadena hexadecimal (e.j. fffffda5), una cadena simple (e.j. mi cadena) o una expresión regular (e.j. colo?r).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
@@ -10367,6 +10902,22 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation>Filtro no valido.</translation>
</message>
<message>
+ <source>Event List</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Event Details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Event Bytes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search the Info column of the event list (summary pane), decoded event display labels (tree view pane) or the ASCII-converted event data (hex view pane).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>That filter doesn&apos;t test anything.</source>
<translation>Este filtro no comprueba nada.</translation>
</message>
@@ -10666,7 +11217,7 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
<message>
<source>Go to packet currently under the cursor</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Va al paquete actualmente debajo del cursor</translation>
</message>
<message>
<source>G</source>
@@ -10787,6 +11338,10 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation>Buscar:</translation>
</message>
<message>
+ <source>Case sensitive</source>
+ <translation type="unfinished">Mayúsculas y minúsculas</translation>
+ </message>
+ <message>
<source>Find &amp;Next</source>
<translation>Buscar &amp;siguiente</translation>
</message>
@@ -10882,11 +11437,19 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation type="unfinished">Guardar como…</translation>
</message>
<message>
+ <source>Decoded as %1.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Save Selected Packet Bytes As…</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>compressed %1</source>
+ <translation type="unfinished"></translation>
+ </message>
<message numerus="yes">
- <source>Displaying %Ln byte(s).</source>
+ <source>Using %Ln byte(s).</source>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
@@ -10989,6 +11552,10 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<source>Display filter:</source>
<translation type="unfinished">Filtro de visualización:</translation>
</message>
+ <message>
+ <source>Strip Headers</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>SupportedProtocolsDialog</name>
@@ -11371,7 +11938,7 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
<message>
<source>Go to packet currently under the cursor</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Va al paquete actualmente debajo del cursor</translation>
</message>
<message>
<source>G</source>
@@ -11567,7 +12134,7 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
<message>
<source>Release to zoom, x = %1 to %2, y = %3 to %4</source>
- <translation type="unfinished">Soltar para zoom, x = %1 a %2, y = %3 a %4</translation>
+ <translation>Suelte para zoom, x = %1 a %2, y = %3 a %4</translation>
</message>
<message>
<source>Unable to select range.</source>
@@ -11923,22 +12490,20 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation>Crea una nueva entrada.</translation>
</message>
<message>
- <source>Remove this entry.</source>
- <oldsource>Remove this profile.</oldsource>
- <translation>Elimina esta entrada.</translation>
+ <source>Remove the selected entry(ies).</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Copy this entry.</source>
- <oldsource>Copy this profile.</oldsource>
- <translation>Copia esta entrada.</translation>
+ <source>Copy the selected entry(ies).</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry up.</source>
- <translation>Mueve entrada hacia arriba.</translation>
+ <source>Move the selected entry(ies) up.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry down.</source>
- <translation>Mueve entrada hacia abajo.</translation>
+ <source>Move the selected entry(ies) down.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Clear all entries.</source>
@@ -11964,20 +12529,20 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
<translation>Crea una nueva entrada.</translation>
</message>
<message>
- <source>Remove this entry.</source>
- <translation>Elimina esta entrada.</translation>
+ <source>Remove the selected entry(ies).</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Copy this entry.</source>
- <translation>Copia esta entrada.</translation>
+ <source>Copy the selected entry(ies).</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry up.</source>
- <translation>Mueve entrada hacia arriba.</translation>
+ <source>Move the selected entry(ies) up.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry down.</source>
- <translation>Mueve entrada hacia abajo.</translation>
+ <source>Move the selected entry(ies) down.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Clear all entries.</source>
@@ -12020,19 +12585,19 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
<message>
<source>Flow &amp;Sequence</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;Secuencia de flujo</translation>
</message>
<message>
<source>Show flow sequence for selected call(s).</source>
- <translation type="unfinished"></translation>
+ <translation>Muestra la secuencia de flujo para la(s) llamada(s) seleccionada(s).</translation>
</message>
<message>
<source>Prepare &amp;Filter</source>
- <translation type="unfinished"></translation>
+ <translation>Preparar &amp;filtro</translation>
</message>
<message>
<source>Prepare a filter matching the selected calls(s).</source>
- <translation type="unfinished"></translation>
+ <translation>Prepara un filtro que coincide con la(s) llamada(s) seleccionada(s).</translation>
</message>
<message>
<source>Cop&amp;y</source>
@@ -12044,11 +12609,11 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
<message>
<source>All</source>
- <translation type="unfinished"></translation>
+ <translation>Todo</translation>
</message>
<message>
<source>Select all</source>
- <translation type="unfinished">Selecciona todo</translation>
+ <translation>Selecciona todo</translation>
</message>
<message>
<source>None</source>
@@ -12056,11 +12621,11 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
<message>
<source>Invert</source>
- <translation type="unfinished">Invertir</translation>
+ <translation>Invertir</translation>
</message>
<message>
<source>Invert selection</source>
- <translation type="unfinished"></translation>
+ <translation>Invierte la selección</translation>
</message>
<message>
<source>Select related RTP streams</source>
@@ -12088,23 +12653,23 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
<message>
<source>Display time as time of day</source>
- <translation type="unfinished"></translation>
+ <translation>Mostrar hora como hora de día</translation>
</message>
<message>
<source>Copy as CSV</source>
- <translation type="unfinished">Copiar como CSV</translation>
+ <translation>Copiar como CSV</translation>
</message>
<message>
<source>Copy stream list as CSV.</source>
- <translation type="unfinished">Copia el listado de secuencias como CSV.</translation>
+ <translation>Copia la lista de secuencias como CSV.</translation>
</message>
<message>
<source>Copy as YAML</source>
- <translation type="unfinished">Copiar como YAML</translation>
+ <translation>Copiar como YAML</translation>
</message>
<message>
<source>Copy stream list as YAML.</source>
- <translation type="unfinished">Copia el listado de secuencias como YAML.</translation>
+ <translation>Copia la lista de secuencias como YAML.</translation>
</message>
<message>
<source>SIP Flows</source>
@@ -12112,7 +12677,7 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
<message>
<source>VoIP Calls</source>
- <translation type="unfinished"></translation>
+ <translation>Llamadas VoIP</translation>
</message>
<message>
<source>as CSV</source>
@@ -12124,7 +12689,7 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
<message>
<source>Select</source>
- <translation type="unfinished"></translation>
+ <translation>Seleccionar</translation>
</message>
</context>
<context>
@@ -12143,11 +12708,11 @@ Por ejemplo, use 1 hora para tener creado un nuevo archivo cada hora en punto.</
</message>
<message>
<source>Start Time</source>
- <translation type="unfinished"></translation>
+ <translation>Hora de inicio</translation>
</message>
<message>
<source>Stop Time</source>
- <translation type="unfinished"></translation>
+ <translation>Hora de finalización</translation>
</message>
<message>
<source>Initial Speaker</source>
@@ -12348,10 +12913,18 @@ a:hover {
<translation>Está absorbiendo el pegamento que mantiene unido internet usando Wireshark</translation>
</message>
<message>
+ <source>You are sniffing the glue that holds your system together using Logray </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>You are running Wireshark </source>
<translation>Está ejecutando Wireshark</translation>
</message>
<message>
+ <source>You are running Logray </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source> You receive automatic updates.</source>
<translation>Recibe actualizaciones automáticas.</translation>
</message>
@@ -12628,14 +13201,6 @@ a:hover {
<translation>No se encontraron archivos</translation>
</message>
<message>
- <source>&amp;Contents</source>
- <translation>&amp;Contenidos</translation>
- </message>
- <message>
- <source>Wireshark Filter</source>
- <translation>Filtro de Wireshark</translation>
- </message>
- <message>
<source>TShark</source>
<translation>TShark</translation>
</message>
@@ -12901,10 +13466,6 @@ a:hover {
<translation>Barra de herramientas de wireless</translation>
</message>
<message>
- <source>Help contents</source>
- <translation>Contenidos de ayuda</translation>
- </message>
- <message>
<source>FAQs</source>
<translation>FAQs</translation>
</message>
@@ -13025,11 +13586,6 @@ a:hover {
<translation>Busca el paquete anterior</translation>
</message>
<message>
- <source>&amp;Mark/Unmark Packet(s)</source>
- <oldsource>&amp;Mark/Unmark Packet</oldsource>
- <translation>&amp;Marcar/Desmarcar paquete</translation>
- </message>
- <message>
<source>Mark All Displayed</source>
<translation>Marcar todos los mostrados</translation>
</message>
@@ -13058,11 +13614,6 @@ a:hover {
<translation>Va al paquete marcado anterior</translation>
</message>
<message>
- <source>&amp;Ignore/Unignore Packet(s)</source>
- <oldsource>&amp;Ignore/Unignore Packet</oldsource>
- <translation>&amp;Ignorar/No ignorar paquete</translation>
- </message>
- <message>
<source>Ignore All Displayed</source>
<translation>Ignorar todos los mostrados</translation>
</message>
@@ -13212,7 +13763,7 @@ a:hover {
</message>
<message>
<source>Flow sequence diagram</source>
- <translation>Diagrama de flujo de secuencia</translation>
+ <translation>Diagrama de secuencia de flujo</translation>
</message>
<message>
<source>ANCP</source>
@@ -13503,10 +14054,6 @@ a:hover {
<translation>Restablecer diseño</translation>
</message>
<message>
- <source>Reset appearance layout to default size</source>
- <translation>Restablece el diseño de apariencia al tamaño por defecto</translation>
- </message>
- <message>
<source>Seconds Since First Captured Packet</source>
<translation>Segundos desde primer paquete capturado</translation>
</message>
@@ -13667,20 +14214,28 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
- <source>TLS Keylog Launcher</source>
+ <source>&amp;Options…</source>
+ <translation>&amp;Opciones…</translation>
+ </message>
+ <message>
+ <source>&amp;3GPP Uu</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Release Notes</source>
+ <source>&amp;Wireless</source>
+ <translation>&amp;Wireless</translation>
+ </message>
+ <message>
+ <source>&amp;User&apos;s Guide</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Options…</source>
- <translation>&amp;Opciones…</translation>
+ <source>Wireshark User&apos;s Guide</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Wireless</source>
- <translation>&amp;Wireless</translation>
+ <source>Display Filters</source>
+ <translation type="unfinished">Filtros de visualización</translation>
</message>
<message>
<source>Capture &amp;Filters…</source>
@@ -13727,10 +14282,18 @@ a:hover {
<translation>Buscar ant&amp;erior</translation>
</message>
<message>
+ <source>&amp;Mark/Unmark Selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Mark or unmark each selected packet</source>
<translation>Marca o desmarca cada paquete seleccionado</translation>
</message>
<message>
+ <source>&amp;Ignore/Unignore Selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Ignore or unignore each selected packet</source>
<translation>Ignora o no ignora cada paquete seleccionado</translation>
</message>
@@ -13771,6 +14334,18 @@ a:hover {
<translation>Rendimiento TCP</translation>
</message>
<message>
+ <source>General</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Query-Response</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>DNS Query-Response Statistics</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Request Sequences</source>
<translation>Secuencias de petición</translation>
</message>
@@ -13779,6 +14354,14 @@ a:hover {
<translation>Secuencias de solicitud HTTP</translation>
</message>
<message>
+ <source>E2AP</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>E2AP Messages</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Decode &amp;As…</source>
<translation>Decodificar &amp;como…</translation>
</message>
@@ -13839,6 +14422,10 @@ a:hover {
<translation>Tamaño normal</translation>
</message>
<message>
+ <source>Reset layout to default size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Resize Columns</source>
<translation>Cambiar tamaño de columnas</translation>
</message>
@@ -14097,6 +14684,14 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
+ <source>TLS Keylog Launcher</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Release Notes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&amp;VoIP Calls</source>
<translation>&amp;Llamadas VoIP</translation>
</message>
@@ -14129,10 +14724,6 @@ a:hover {
<translation>&amp;GSM</translation>
</message>
<message>
- <source>&amp;LTE</source>
- <translation>&amp;LTE</translation>
- </message>
- <message>
<source>&amp;MTP3</source>
<translation>&amp;MTP3</translation>
</message>
@@ -14417,6 +15008,10 @@ a:hover {
<translation>Salir &amp;sin guardar</translation>
</message>
<message>
+ <source>USB CDC Data</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>There is no &quot;rtp.ssrc&quot; field in this version of Wireshark.</source>
<translation type="unfinished"></translation>
</message>
diff --git a/ui/qt/wireshark_fr.ts b/ui/qt/wireshark_fr.ts
index 29e8c5ac..b16a4c38 100644
--- a/ui/qt/wireshark_fr.ts
+++ b/ui/qt/wireshark_fr.ts
@@ -29,7 +29,7 @@
</message>
<message>
<source>Copy to Clipboard</source>
- <translation type="unfinished"></translation>
+ <translation>Copier dans le Presse-papiers</translation>
</message>
<message>
<source>Authors</source>
@@ -44,8 +44,8 @@
<translation>Dossiers</translation>
</message>
<message>
- <source>Filter by path</source>
- <translation>Filtrer par chemin</translation>
+ <source>Search Folders</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Plugins</source>
@@ -80,6 +80,14 @@
<translation>Licence</translation>
</message>
<message>
+ <source>About Logray</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Logray</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>The directory does not exist</source>
<translation>Le dossier n&apos;existe pas</translation>
</message>
@@ -731,11 +739,11 @@
</message>
<message>
<source>…as decimal</source>
- <translation type="unfinished"></translation>
+ <translation>...en décimal</translation>
</message>
<message>
<source>…as octal</source>
- <translation type="unfinished"></translation>
+ <translation>...en octal</translation>
</message>
<message>
<source>…as bits</source>
@@ -755,6 +763,28 @@
</message>
</context>
<context>
+ <name>CaptureCommentDialog</name>
+ <message>
+ <source>Edit Capture Comments</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add Comment</source>
+ <translation>Ajouter un commentaire</translation>
+ </message>
+ <message>
+ <source>Section %1</source>
+ <translation>Section %1</translation>
+ </message>
+</context>
+<context>
+ <name>CaptureCommentTabWidget</name>
+ <message>
+ <source>Comment %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>CaptureFile</name>
<message>
<source> [closing]</source>
@@ -840,10 +870,6 @@
<translation>Filtre de lecture :</translation>
</message>
<message>
- <source>Compress with g&amp;zip</source>
- <translation>Compresser avec g&amp;zip</translation>
- </message>
- <message>
<source>Open Capture File</source>
<oldsource>Wireshark: Open Capture File</oldsource>
<translation>Ouvrir un fichier de capture</translation>
@@ -925,8 +951,8 @@
<translation>Détails</translation>
</message>
<message>
- <source>Capture file comments</source>
- <translation>Commentaires du fichier de capture</translation>
+ <source>Edit Comments</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Refresh</source>
@@ -937,10 +963,6 @@
<translation>Copier dans le Presse-papiers</translation>
</message>
<message>
- <source>Save Comments</source>
- <translation>Enregister les commentaires</translation>
- </message>
- <message>
<source>Capture File Properties</source>
<translation>Propriétés du fichier de capture</translation>
</message>
@@ -989,10 +1011,18 @@
<translation>Premier paquet</translation>
</message>
<message>
+ <source>First event</source>
+ <translation>Premier événement</translation>
+ </message>
+ <message>
<source>Last packet</source>
<translation>Dernier paquet</translation>
</message>
<message>
+ <source>Last event</source>
+ <translation>Dernier événement</translation>
+ </message>
+ <message>
<source>Elapsed</source>
<translation>Temps écoulé</translation>
</message>
@@ -1029,6 +1059,10 @@
<translation>Paquets rejetés</translation>
</message>
<message>
+ <source>Dropped events</source>
+ <translation>Événements rejetés</translation>
+ </message>
+ <message>
<source>Capture filter</source>
<translation>Filtre de capture</translation>
</message>
@@ -1041,6 +1075,10 @@
<translation>Limite de taille de paquet (snaplen)</translation>
</message>
<message>
+ <source>Event size limit (snaplen)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>none</source>
<translation>aucun</translation>
</message>
@@ -1049,6 +1087,26 @@
<translation>%1 octets</translation>
</message>
<message>
+ <source>Comments</source>
+ <translation type="unfinished">Commentaires</translation>
+ </message>
+ <message>
+ <source>Comment %1: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Decryption Secrets</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation type="unfinished">Type</translation>
+ </message>
+ <message>
+ <source>Size</source>
+ <translation>Taille</translation>
+ </message>
+ <message>
<source>Statistics</source>
<translation>Statistiques</translation>
</message>
@@ -1073,6 +1131,10 @@
<translation>Paquets</translation>
</message>
<message>
+ <source>Events</source>
+ <translation>Événements</translation>
+ </message>
+ <message>
<source>Time span, s</source>
<translation>Temps, s</translation>
</message>
@@ -1085,6 +1147,10 @@
<translation>Taille des paquets moyenne, O</translation>
</message>
<message>
+ <source>Average event size, B</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Bytes</source>
<translation>Octets</translation>
</message>
@@ -1097,14 +1163,14 @@
<translation>Débit moyen (bits/s)</translation>
</message>
<message>
- <source>Section Comment</source>
- <translation>Commentaire de la Section</translation>
- </message>
- <message>
<source>Packet Comments</source>
<translation>Commentaires du Paquet</translation>
</message>
<message>
+ <source>Event Comments</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;p&gt;Frame %1: </source>
<translation>&lt;p&gt;Trame %1 : </translation>
</message>
@@ -1116,6 +1182,12 @@
</translation>
</message>
+ <message>
+ <source>Created by Logray %1
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>CaptureFilterCombo</name>
@@ -1343,6 +1415,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les heures à l&apos;heure.</translation>
</message>
<message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for some more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Habituellement, une carte réseau sans-fil ne capture que le trafic émis vers et depuis sa propre adresse réseau, et capture seulement le trafic de &lt;em&gt;données utilisateur&lt;/em&gt; avec un &amp;quot;faux&amp;quot; en-tête Ethernet. Si vous voulez capturer tout le trafic que la carte réseau sans-fil peut &amp;quot;voir&amp;quot;, ou êtes intéressés par les paquets de gestion ou de contrôle 802.11, ou les informations de niveau radio, cochez cette option. La disponibilité du mode Moniteur dépend de la carte sans-fil et de son pilote. Consultez le Wiki pour de plus amples détails concernant la capture de paquets sur un réseau WLAN.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>Enable monitor mode on all 802.11 interfaces</source>
+ <translation>Activer le mode Moniteur sur toutes les interfaces 802.11</translation>
+ </message>
+ <message>
<source>compression</source>
<translation>compression</translation>
</message>
@@ -1355,6 +1435,30 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>gzip</translation>
</message>
<message>
+ <source>File infix pattern</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;In multiple file mode, the date and time and file index number are inserted between filename template and any suffix. Select their order.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Dans le mode fichiers multiples, date et heure ainsi que le numéro d&apos;index du fichier sont insérés entre le nom de fichier et le suffixe. Sélectionnez leur ordre.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>YYYYmmDDHHMMSS_NNNNN</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Date and time before the file index number. This causes files to sort in creation time order, and keeps files from the same batch closely ordered.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Date et heure avant le numéro d&apos;index du fichier. Ceci force le tri des fichiers par ordre de leur heure de création et garde les fichiers d&apos;un même batch proches.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>NNNNN_YYYYmmDDHHMMSS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;File index number before the date and time. This is the historic Wireshark ordering.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Numéro d&apos;index de fichier avant la date et heure. Ceci est l&apos;ordre utilisé historiquement par Wireshark.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;After capturing has switched to the next file and the given number of files has exceeded, the oldest file will be removed.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Après basculement de la capture vers le fichier suivant, si le nombre de fichiers indiqué est dépassé, le fichier le plus ancien sera supprimé.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1443,6 +1547,10 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Arrête la capture après avoir créé le nombre de fichiers indiqués.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
+ <source>Stop capturing after the specified number of files have been created.</source>
+ <translation>Arrête la capture après avoir créé le nombre de fichiers indiqués.</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Stop capturing after the specified amount of data has been captured.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Arrêter la capture après avoir capturé le volume de données indiqué.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1503,8 +1611,8 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Erreur</translation>
</message>
<message>
- <source>Multiple files: Requested filesize too large. The filesize cannot be greater than 2 GiB.</source>
- <translation>Fichiers multiples : la taille demandée est trop élevée. La taille d&apos;un fichier ne doit pas dépasser 2 Gio.</translation>
+ <source>Multiple files: Requested filesize too large. The filesize cannot be greater than 2 TB.</source>
+ <translation>Fichier multiples : la taille demandée est trop élevée, elle ne doit pas être supérieure à 2 To.</translation>
</message>
<message>
<source>Multiple files: No capture file name given. You must specify a filename if you want to use multiple files.</source>
@@ -1534,6 +1642,14 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Capture de Paquets en mode promiscuous</translation>
</message>
<message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Habituellement, une carte réseau sans-fil ne capture que le trafic émis vers et depuis sa propre adresse réseau, et capture seulement le trafic de &lt;em&gt;données utilisateur&lt;/em&gt; avec un &amp;quot;faux&amp;quot; en-tête Ethernet. Si vous voulez capturer tout le trafic que la carte réseau sans-fil peut &amp;quot;voir&amp;quot;, ou êtes intéressés par les paquets de gestion ou de contrôle 802.11, ou les informations de niveau radio, cochez cette option. La disponibilité du mode Moniteur dépend de la carte sans-fil et de son pilote. Consultez le Wiki pour de plus amples détails concernant la capture de paquets sur un réseau WLAN.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>Capture packets in monitor mode on 802.11 devices</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Capture packets in the next-generation capture file format.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Paquets de capture dans le nouveau format (pcap-ng) de fichier de capture.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1551,15 +1667,15 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
</message>
<message>
<source>Interval between updates (ms)</source>
- <translation type="unfinished"></translation>
+ <translation>Intervalle entre les mises à jour (ms)</translation>
</message>
<message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;How often the capture notifies the GUI of new packets. Affects how often the GUI updates and the granularity of timers.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;A quelle fréquence la capture informe l&apos;interface graphique pour de nouveaux paquets. Ceci affecte la fréquence de mise à jour de l&apos;interface graphique et la granularité des chronomètres.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The interval between new packet updates. Affects how often the GUI updates and the granularity of timers.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;L&apos;intervalle entre les mises à jours des nouveaux paquets. Ceci affecte la fréquence de mises à jour de l&apos;interface graphique et la granularité des chronomètres.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<source>Don&apos;t load interfaces on startup</source>
@@ -1761,6 +1877,14 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Résolu</translation>
</message>
<message>
+ <source>Width</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Alignment</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;Show human-readable strings instead of raw values for fields. Only applicable to custom columns with fields that have value strings.&lt;/html&gt;</source>
<translation>&lt;html&gt;Afficher des chaînes lisibles par l&apos;homme au lieu de valeurs brutes pour les champs. Applicable uniquement aux colonnes personnalisées avec des champs contenant des chaînes de valeur.</translation>
</message>
@@ -1808,6 +1932,25 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
</message>
</context>
<context>
+ <name>CompressionGroupBox</name>
+ <message>
+ <source>Compression options</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Uncompressed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Compress with g&amp;zip</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Compress with &amp;LZ4</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>ConversationDataModel</name>
<message>
<source>Address A</source>
@@ -1874,6 +2017,10 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Bits/s B</translation>
</message>
<message>
+ <source>Flows</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Total Packets</source>
<translation>Paquets totaux</translation>
</message>
@@ -1988,23 +2135,31 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Copier les octets du paquet sous forme de vidage Hex.</translation>
</message>
<message>
- <source>…as Printable Text</source>
+ <source>…as MIME Data</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>…as C String</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Copy only the printable text in the packet.</source>
+ <source>Copy packet bytes as printable ASCII characters and escape sequences.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>…as MIME Data</source>
+ <source>…as Go literal</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>…as C String</source>
+ <source>Copy packet bytes as Go literal.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Copy packet bytes as printable ASCII characters and escape sequences.</source>
+ <source>…as C Array</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as C Array.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2012,6 +2167,22 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>…sous forme de flux Hex</translation>
</message>
<message>
+ <source>…as UTF-8 Text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as text, treating as UTF-8.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>…as ASCII Text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as text, treating as ASCII.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Copy packet bytes as a stream of hex.</source>
<translation>Copier les octets du paquet sous forme de flux Hex.</translation>
</message>
@@ -2226,11 +2397,11 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
</message>
<message>
<source>By default order comparisons and contains/matches/in relations are true if any value matches. The quantifier &quot;all&quot; can be used to apply the test to all values in a frame.</source>
- <translation type="unfinished"></translation>
+ <translation>Par défaut, les comparaisons d&apos;ordre et les relations contains/matches/in sont vraies si l&apos;une des valeurs correspond. Le quantificateur &quot;all&quot; peut être utilisé pour appliquer le test à toutes les valeur de la trame.</translation>
</message>
<message>
<source>Quantifier</source>
- <translation type="unfinished"></translation>
+ <translation>Quantificateur</translation>
</message>
<message>
<source>Any</source>
@@ -2468,11 +2639,11 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
</message>
<message>
<source>Latitude</source>
- <translation type="unfinished"></translation>
+ <translation>Latitude</translation>
</message>
<message>
<source>Longitude</source>
- <translation type="unfinished"></translation>
+ <translation>Longitude</translation>
</message>
<message>
<source>AS Number</source>
@@ -2805,6 +2976,10 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<source>Display filter:</source>
<translation>Filtre d&apos;affichage :</translation>
</message>
+ <message>
+ <source>Export PDUs</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>ExtArgSelector</name>
@@ -2844,10 +3019,6 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Démarrer</translation>
</message>
<message>
- <source>Save</source>
- <translation>Sauvegarder</translation>
- </message>
- <message>
<source>Default</source>
<translation>Défaut</translation>
</message>
@@ -2989,6 +3160,14 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Filtres d&apos;affichage</translation>
</message>
<message>
+ <source>Display Filter Macros</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>New macro</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Open </source>
<translation>Ouvrir</translation>
</message>
@@ -3072,10 +3251,18 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<context>
<name>FilterListModel</name>
<message>
+ <source>Macro Name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Filter Name</source>
<translation>Nom du filtre</translation>
</message>
<message>
+ <source>Macro Expression</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Filter Expression</source>
<translation>Expression de filtre</translation>
</message>
@@ -3161,22 +3348,10 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<context>
<name>FolderListModel</name>
<message>
- <source>&quot;File&quot; dialogs</source>
- <translation>&quot;Fichier&quot; dialogues</translation>
- </message>
- <message>
- <source>capture files</source>
- <translation>capturer des fichiers</translation>
- </message>
- <message>
<source>Temp</source>
<translation>Temp</translation>
</message>
<message>
- <source>untitled capture files</source>
- <translation>fichiers de capture sans titre</translation>
- </message>
- <message>
<source>Personal configuration</source>
<translation>Paramétrage personnel</translation>
</message>
@@ -3185,14 +3360,6 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Configuration globale</translation>
</message>
<message>
- <source>dfilters, preferences, ethers, …</source>
- <translation>dfiltres, préférences, éthers, …</translation>
- </message>
- <message>
- <source>dfilters, preferences, manuf, …</source>
- <translation>filtres, préférences, fabrication, …</translation>
- </message>
- <message>
<source>System</source>
<translation>Système</translation>
</message>
@@ -3205,18 +3372,10 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Programme</translation>
</message>
<message>
- <source>program files</source>
- <translation>fichiers de programme</translation>
- </message>
- <message>
<source>Personal Plugins</source>
<translation>Plugins personnels</translation>
</message>
<message>
- <source>binary plugins</source>
- <translation>plugins binaires</translation>
- </message>
- <message>
<source>Global Plugins</source>
<translation>Plugins globaux</translation>
</message>
@@ -3233,11 +3392,35 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation type="unfinished"></translation>
</message>
<message>
+ <source>&quot;File&quot; dialog location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Capture files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Untitled capture files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Preferences, profiles, manuf, …</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Program files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Binary plugins</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Personal Extcap path</source>
<translation>Chemin d&apos;accès Extcap personnel</translation>
</message>
<message>
- <source>external capture (extcap) plugins</source>
+ <source>External capture (extcap) plugins</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -3361,6 +3544,24 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
</translation>
</message>
<message>
+ <source>Event %1. </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;reads&lt;/span&gt;, </source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;writes&lt;/span&gt;, </source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
<source> Click to select.</source>
<translation>Cliquez pour sélectionner</translation>
</message>
@@ -3393,6 +3594,18 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Read activity(%6)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Write activity(%6)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Entire I/O activity (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Entire conversation (%1)</source>
<translation>Conversation entière (%1)</translation>
</message>
@@ -3408,10 +3621,6 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<source>Save Stream Content As…</source>
<translation>Enregistrer le contenu du flux sous…</translation>
</message>
- <message>
- <source>[Stream output truncated]</source>
- <translation>[Sortie du flux tronquée]</translation>
- </message>
<message numerus="yes">
<source>%Ln total stream(s).</source>
<translation type="unfinished">
@@ -3439,9 +3648,20 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Astuce.</translation>
</message>
<message>
- <source>Show data as</source>
- <oldsource>Show and save data as</oldsource>
- <translation>Afficher les données comme</translation>
+ <source>Show as</source>
+ <translation type="unfinished">Montrer comme</translation>
+ </message>
+ <message>
+ <source>No delta times</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Turn delta times</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All delta times</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Stream</source>
@@ -3456,11 +3676,22 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Trouver :</translation>
</message>
<message>
+ <source>Case sensitive</source>
+ <translation>Sensible à la casse</translation>
+ </message>
+ <message>
<source>Find &amp;Next</source>
<translation>Trouver Suiva&amp;nt</translation>
</message>
</context>
<context>
+ <name>FollowStreamText</name>
+ <message>
+ <source>[Stream output truncated]</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FontColorPreferencesFrame</name>
<message>
<source>Frame</source>
@@ -3798,29 +4029,28 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <source>Remove this graph.</source>
- <oldsource>Remove this dissection behavior.</oldsource>
- <translation>Enlever ce graphique.</translation>
- </message>
- <message>
<source>Add a new graph.</source>
<translation>Ajouter un nouveau graphique.</translation>
</message>
<message>
- <source>Duplicate this graph.</source>
- <translation>Dupliquer ce graphique.</translation>
- </message>
- <message>
<source>Clear all graphs.</source>
<translation>Effacer tous les graphiques.</translation>
</message>
<message>
- <source>Move this graph upwards.</source>
- <translation type="unfinished"></translation>
+ <source>Remove the selected graph(s).</source>
+ <translation>Supprimer le(s) graphe(s) sélectionné(s).</translation>
</message>
<message>
- <source>Move this graph downwards.</source>
- <translation type="unfinished"></translation>
+ <source>Duplicate the selected graph(s).</source>
+ <translation>Dupliquer le(s) graphe(s) sélectionné(s).</translation>
+ </message>
+ <message>
+ <source>Move the selected graph(s) upwards.</source>
+ <translation>Déplacer le(s) graphe(s) sélectionné(s) vers le haut.</translation>
+ </message>
+ <message>
+ <source>Move the selected graph(s) downwards.</source>
+ <translation>Déplacer le(s) graphe(s) sélectionné(s) vers le bas.</translation>
</message>
<message>
<source>Mouse</source>
@@ -3856,17 +4086,13 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
</message>
<message>
<source>Automatic update</source>
- <translation type="unfinished"></translation>
+ <translation>Mise à jour automatique</translation>
</message>
<message>
<source>Enable legend</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Reset</source>
- <translation>Réinitialiser</translation>
- </message>
- <message>
<source>Reset Graph</source>
<translation>Réinitialiser le Graphique</translation>
</message>
@@ -4080,6 +4306,42 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Copier les graphiques d&apos;un autre profil.</translation>
</message>
<message>
+ <source>1 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>2 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>5 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>10 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>20 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>50 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>100 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>200 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>500 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>1 ms</source>
<translation>1 ms</translation>
</message>
@@ -4124,6 +4386,14 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>5 s</translation>
</message>
<message>
+ <source>2 min</source>
+ <translation type="unfinished">10 min {2 ?}</translation>
+ </message>
+ <message>
+ <source>5 min</source>
+ <translation type="unfinished">10 min {5 ?}</translation>
+ </message>
+ <message>
<source>Wireshark I/O Graphs: %1</source>
<translation>Graphiques E/S Wireshark : %1</translation>
</message>
@@ -4136,6 +4406,14 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation type="unfinished"></translation>
</message>
<message>
+ <source>All packets</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All events</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>All Packets</source>
<translation>Tous les paquets</translation>
</message>
@@ -4148,7 +4426,7 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation type="unfinished"></translation>
</message>
<message>
- <source>Access Denied</source>
+ <source>All Execs</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -4161,7 +4439,7 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
</message>
<message>
<source>No events in interval</source>
- <translation type="unfinished"></translation>
+ <translation>Aucun événement dans l’intervalle</translation>
</message>
<message>
<source>Click to select packet</source>
@@ -4177,7 +4455,7 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
</message>
<message>
<source>Event</source>
- <translation type="unfinished">Évènement</translation>
+ <translation>Événement</translation>
</message>
<message>
<source>%1 (%2s%3).</source>
@@ -4196,6 +4474,34 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Cliquez pour sélectionner une partie du graphique.</translation>
</message>
<message>
+ <source>%1 Intervals </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to top left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to top center</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to top right</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to bottom left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to bottom center</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to bottom right</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Portable Document Format (*.pdf)</source>
<translation>Portable Document Format (*.pdf)</translation>
</message>
@@ -4948,6 +5254,13 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
</message>
</context>
<context>
+ <name>InterfaceTreeDelegate</name>
+ <message>
+ <source>default</source>
+ <translation type="unfinished">défaut</translation>
+ </message>
+</context>
+<context>
<name>InterfaceTreeModel</name>
<message>
<source>Show</source>
@@ -5902,7 +6215,7 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
</message>
<message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If more than this many rows are displayed, then sorting by columns that require packet dissection will be disabled. Increasing this number increases memory consumption by caching column values.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;S&apos;il y a plus de ce nombre de colonnes affichées, alors les tris par colonnes qui requièrent la dissection des paquets sera désactivée. Augmenter ce nombre augmente la mémoire utilisée par le cache de valeurs de colonnes..&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<source>Enable mouse-over colorization</source>
@@ -5924,8 +6237,8 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<context>
<name>LteMacStatisticsDialog</name>
<message>
- <source>LTE Mac Statistics</source>
- <translation>Statistiques LTE Mac</translation>
+ <source>LTE/NR Mac Statistics</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Include SR frames in filter</source>
@@ -6228,12 +6541,12 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Numéro de Séquence</translation>
</message>
<message>
- <source>LTE RLC Graph (UE=%1 chan=%2%3 %4 - %5)</source>
- <translation>Graphique LTE RLC (UE=%1 chan=%2%3 %4 - %5)</translation>
+ <source>%1 RLC Graph (UE=%2 chan=%3%4 %5 - %6)</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>LTE RLC Graph - no channel selected</source>
- <translation>Graphique LTE RLC - aucun canal sélectionné </translation>
+ <source>3GPP RLC Graph - no channel selected</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Save As…</source>
@@ -6287,8 +6600,8 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<context>
<name>LteRlcStatisticsDialog</name>
<message>
- <source>LTE RLC Statistics</source>
- <translation>Statistiques LTE RLC</translation>
+ <source>3GPP RLC Statistics</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Include SR frames in filter</source>
@@ -6374,6 +6687,10 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Profil : %1</translation>
</message>
<message>
+ <source> %1 Displayed: %2 (%3%)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Manage Profiles…</source>
<translation>Gérer les profils…</translation>
</message>
@@ -6435,6 +6752,13 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<numerusform></numerusform>
</translation>
</message>
+ <message numerus="yes">
+ <source>%Ln bit(s)</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
<message>
<source>Byte %1</source>
<translation>Octet %1</translation>
@@ -6448,9 +6772,12 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Paquet sélectionné : %1 %2 </translation>
</message>
<message>
- <source>Packets: %1 %4 Displayed: %2 (%3%)</source>
- <oldsource>Packets: %1 %4 Displayed: %2 %4 Marked: %3</oldsource>
- <translation>Paquets : %1 %4 Affichés : %2 (%3%)</translation>
+ <source>Selected Event: %1 %2 </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Events: %1</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source> %1 Selected: %2 (%3%)</source>
@@ -6482,12 +6809,16 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Pas de paquets</translation>
</message>
<message>
- <source>From Zip File...</source>
+ <source>No Events</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <source>From Zip File...</source>
+ <translation type="unfinished">à partir d&apos;un fichier Zip...</translation>
+ </message>
+ <message>
<source>From Directory...</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">à partir d&apos;un répertoire</translation>
</message>
<message>
<source>Selected Personal Profile...</source>
@@ -6514,6 +6845,13 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
</message>
</context>
<context>
+ <name>MainWindow</name>
+ <message>
+ <source>Display filter as %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>MainWindowPreferencesFrame</name>
<message>
<source>Frame</source>
@@ -6545,6 +6883,10 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Le dernier dossier utilisé</translation>
</message>
<message>
+ <source>The current working directory</source>
+ <translation>Le répertoire de travail courant</translation>
+ </message>
+ <message>
<source>Show up to</source>
<translation>Afficher</translation>
</message>
@@ -6696,7 +7038,7 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
</message>
<message>
<source>MAC Address</source>
- <translation type="unfinished"></translation>
+ <translation>Adresse MAC</translation>
</message>
<message>
<source>Search vendor name using a case-insentitive regular expression.</source>
@@ -6975,6 +7317,10 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Afficher les valeurs de champ</translation>
</message>
<message>
+ <source>Refresh</source>
+ <translation type="unfinished">Rafraîchir</translation>
+ </message>
+ <message>
<source>Save Diagram As…</source>
<translation>Enregistrer le diagramme sous…</translation>
</message>
@@ -7022,6 +7368,10 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Afficher les octets du paquet</translation>
</message>
<message>
+ <source>Layout:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Packet %1</source>
<translation>Paquet %1</translation>
</message>
@@ -7044,6 +7394,13 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<numerusform></numerusform>
</translation>
</message>
+ <message numerus="yes">
+ <source>%Ln bit(s)</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
</context>
<context>
<name>PacketFormatGroupBox</name>
@@ -7503,10 +7860,22 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Copier ce profil.</translation>
</message>
<message>
+ <source>The number of packets or events to check for automatic profile switching.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Auto switch packet limit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Configuration Profiles</source>
<translation>Profils de configuration</translation>
</message>
<message>
+ <source>Auto switch event limit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Import</source>
<comment>noun</comment>
<translation>Importer</translation>
@@ -7518,11 +7887,11 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
</message>
<message>
<source>From Zip File...</source>
- <translation type="unfinished"></translation>
+ <translation>à partir d&apos;un fichier Zip...</translation>
</message>
<message>
<source>From Directory...</source>
- <translation type="unfinished"></translation>
+ <translation>à partir d&apos;un répertoire</translation>
</message>
<message numerus="yes">
<source>%Ln Selected Personal Profile(s)...</source>
@@ -7675,6 +8044,10 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>supprimé</translation>
</message>
<message>
+ <source>Auto Switch Filter</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>copy</source>
<comment>noun</comment>
<translation>copier</translation>
@@ -7921,7 +8294,7 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
</message>
<message>
<source>Disable unused protocols</source>
- <translation type="unfinished"></translation>
+ <translation>Désactiver les protocoles non utilisés</translation>
</message>
<message>
<source>Disable all protocols but those listed.</source>
@@ -7957,7 +8330,7 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
</message>
<message>
<source>Protocols</source>
- <translation type="unfinished"></translation>
+ <translation>Protocoles</translation>
</message>
<message>
<source>Disable unused</source>
@@ -7977,7 +8350,7 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
</message>
<message>
<source>Unused protocols have been disabled.</source>
- <translation type="unfinished"></translation>
+ <translation>Les protocoles non utilisés ont été désactivés.</translation>
</message>
<message>
<source>Protocol changes have been reverted.</source>
@@ -8034,6 +8407,10 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Taille de fenetres (b)</translation>
</message>
<message>
+ <source>Unacked (Outstanding) Bytes (B)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>[no capture file]</source>
<translation>[pas de fichier de capture]</translation>
</message>
@@ -8194,6 +8571,14 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Marqueur manquant?</translation>
</message>
<message>
+ <source>LTE</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>NR</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>C-RNTI</source>
<translation>C-RNTI</translation>
</message>
@@ -8214,6 +8599,10 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>UEId</translation>
</message>
<message>
+ <source>RAT</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>UL Frames</source>
<translation>UL Trames</translation>
</message>
@@ -8437,12 +8826,72 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<source>Browse…</source>
<translation>Parcourir…</translation>
</message>
+ <message>
+ <source>PACKETS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>EVENTS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>BYTES</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>BITS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>COUNT FRAMES</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>COUNT FIELDS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>SUM</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>MAX</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>MIN</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>AVERAGE</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>THROUGHPUT</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>LOAD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Left</source>
+ <translation type="unfinished">Gauche</translation>
+ </message>
+ <message>
+ <source>Center</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Right</source>
+ <translation type="unfinished">Droite</translation>
+ </message>
</context>
<context>
- <name>QObject::QObject</name>
+ <name>QObject::QObject::QObject</name>
<message>
<source>CCCH</source>
- <translation>CCCH</translation>
+ <translation type="unfinished">CCCH</translation>
</message>
</context>
<context>
@@ -8540,6 +8989,13 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
</message>
</context>
<context>
+ <name>ResizeHeaderView</name>
+ <message>
+ <source>Resize all %1 to contents</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>ResolvedAddressesDialog</name>
<message>
<source>Dialog</source>
@@ -8655,6 +9111,14 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Adresses résolues</translation>
</message>
<message>
+ <source>Copy</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save as…</source>
+ <translation>Enregistrer sous…</translation>
+ </message>
+ <message>
<source># Resolved addresses found in %1</source>
<translation># Adresses résolues trouvées dans %1</translation>
</message>
@@ -8668,6 +9132,61 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
</message>
</context>
<context>
+ <name>ResolvedAddressesView</name>
+ <message>
+ <source>as Plain Text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy selected rows</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy table</source>
+ <translation>Copier la table</translation>
+ </message>
+ <message>
+ <source>as CSV</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>as JSON</source>
+ <translation type="unfinished">comme JSON</translation>
+ </message>
+ <message>
+ <source>Save selected rows as…</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save table as…</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save Resolved Addresses As…</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Plain text (*.txt)</source>
+ <translation type="unfinished">Texte (*.txt)</translation>
+ </message>
+ <message>
+ <source>CSV Document (*.csv)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>JSON Document (*.json)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation type="unfinished">Avertissement</translation>
+ </message>
+ <message>
+ <source>Unable to save %1: %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>ResponseTimeDelayDialog</name>
<message>
<source>%1 Response Time Delay Statistics</source>
@@ -10342,6 +10861,10 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Taille du paquet</translation>
</message>
<message>
+ <source>&lt;b&gt;Options:&lt;/b&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for strings containing narrow (UTF-8 and ASCII) or wide (UTF-16) characters.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Recherche les chaines contenant UTF-8 / ASCII ou UTF-16 caractères.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -10362,6 +10885,18 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Sensible à la casse</translation>
</message>
<message>
+ <source>Backwards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for a subsequent occurrence in the current packet before advancing to the next packet.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Chercher une autre occurrence dans le paquet courant avant de passer au prochain paquet.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>Multiple occurrences</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5), a plain string (e.g. My String) or a regular expression (e.g. colou?r).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<oldsource>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5) or a plain string (e.g. My String).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</oldsource>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Rechercher des données à l&apos;aide de la syntaxe du filtre d&apos;affichage (par exemple, ip.addr==10.1.1.1), une chaîne hexadécimale (par exemple, fffffda5), une chaîne simple (par exemple, My String) ou une expression régulière (par exemple, colou?r).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
@@ -10399,6 +10934,22 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Filtre Invalide.</translation>
</message>
<message>
+ <source>Event List</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Event Details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Event Bytes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search the Info column of the event list (summary pane), decoded event display labels (tree view pane) or the ASCII-converted event data (hex view pane).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>That filter doesn&apos;t test anything.</source>
<translation>Ce filtre ne teste rien.</translation>
</message>
@@ -10840,6 +11391,10 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Trouver :</translation>
</message>
<message>
+ <source>Case sensitive</source>
+ <translation>Sensible à la casse</translation>
+ </message>
+ <message>
<source>Find &amp;Next</source>
<translation>Rechercher le &amp;suivant</translation>
</message>
@@ -10935,11 +11490,19 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<translation>Enregistrer sous…</translation>
</message>
<message>
+ <source>Decoded as %1.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Save Selected Packet Bytes As…</source>
<translation>Enregistrer les octets de paquet sélectionnés sous…</translation>
</message>
+ <message>
+ <source>compressed %1</source>
+ <translation type="unfinished"></translation>
+ </message>
<message numerus="yes">
- <source>Displaying %Ln byte(s).</source>
+ <source>Using %Ln byte(s).</source>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
@@ -11042,6 +11605,10 @@ Pas exemple, inquiquez 1 heure pour avoir un nouveau fichier créé toutes les h
<source>Display filter:</source>
<translation>Filtre d&apos;affichage :</translation>
</message>
+ <message>
+ <source>Strip Headers</source>
+ <translation>Retirer les en-têtes</translation>
+ </message>
</context>
<context>
<name>SupportedProtocolsDialog</name>
@@ -11695,23 +12262,23 @@ Changer la direction de la connexion (voir le flux inverse).&lt;/p&gt;&lt;/body&
<name>TLSKeylogDialog</name>
<message>
<source>Dialog</source>
- <translation type="unfinished">Dialogue</translation>
+ <translation>Dialogue</translation>
</message>
<message>
<source>Browse…</source>
- <translation type="unfinished"></translation>
+ <translation>Parcourir…</translation>
</message>
<message>
<source>Command line</source>
- <translation type="unfinished"></translation>
+ <translation>Ligne de commande</translation>
</message>
<message>
<source>Run an application with the SSLKEYLOGFILE environment variable set to the file specified by the TLS key log filename preference. This enables TLS decryption in Wireshark. Set the key log file and start the capture before launching the application to ensure that the initial TLS handshakes are captured.</source>
- <translation type="unfinished"></translation>
+ <translation>Exécutez une application avec la variable d&apos;environnement SSLKEYLOGFILE définie avec le fichier spécifié dans la préférence nom de fichier journal de clé TLS. Cela permet le déchiffrement TLS dans Wireshark. Définissez le fichier d&apos;enregistrement des clés et démarrez la capture avant de lancer l&apos;application afin de vous assurer que les poignées de main TLS initiales sont capturées.</translation>
</message>
<message>
<source>&lt;span style=&quot; font-size:small;&quot;&gt;Firefox and Chrome are known to work. If your desired browser is currently running, close it first before launching it below. Command line options are supported.&lt;/span&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;span style=&quot; font-size:small;&quot;&gt;Firefox et Chrome sont connus pour fonctionner correctement. Si le navigateur de votre choix est actuellement en cours d’exécution, fermez-le d’abord avant de le lancer ci-dessous. Les options de ligne de commande sont prises en charge.&lt;/span&gt;</translation>
</message>
<message>
<source>TLS (Pre)-Master-Secret log file path (tls.keylog_file)</source>
@@ -11719,11 +12286,11 @@ Changer la direction de la connexion (voir le flux inverse).&lt;/p&gt;&lt;/body&
</message>
<message>
<source>&lt;span style=&quot; font-size:small;&quot;&gt;TLS session secrets will be logged to this file. If you change this field, hit the Save button to update the TLS protocol preferences.&lt;/span&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;span style=&quot; font-size:small;&quot;&gt;Les secrets de session TLS seront enregistrés dans ce fichier. Si vous changez ce champ, cliquez sur le bouton Sauvegarder pour mettre à jour les préférences du protocole TLS.&lt;/span&gt;</translation>
</message>
<message>
<source>Launch application with SSLKEYLOGFILE</source>
- <translation type="unfinished"></translation>
+ <translation>Démarrez l&apos;application avec SSLKEYLOGFILE</translation>
</message>
<message>
<source>Launch</source>
@@ -11731,7 +12298,7 @@ Changer la direction de la connexion (voir le flux inverse).&lt;/p&gt;&lt;/body&
</message>
<message>
<source>Save</source>
- <translation type="unfinished">Sauvegarder</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>TLS Keylog file</source>
@@ -11739,7 +12306,7 @@ Changer la direction de la connexion (voir le flux inverse).&lt;/p&gt;&lt;/body&
</message>
<message>
<source>Program to start with SSLKEYLOGFILE</source>
- <translation type="unfinished"></translation>
+ <translation>Programme à démarrer avec SSLKEYLOGFILE</translation>
</message>
</context>
<context>
@@ -11859,7 +12426,7 @@ Changer la direction de la connexion (voir le flux inverse).&lt;/p&gt;&lt;/body&
</message>
<message>
<source>Time shifting is not available while capturing packets.</source>
- <translation type="unfinished"></translation>
+ <translation>Le décalage de temps n&apos;est pas disponible pendant la capture de paquet.</translation>
</message>
</context>
<context>
@@ -12016,22 +12583,20 @@ Changer la direction de la connexion (voir le flux inverse).&lt;/p&gt;&lt;/body&
<translation>Créer une nouvelle entrée</translation>
</message>
<message>
- <source>Remove this entry.</source>
- <oldsource>Remove this profile.</oldsource>
- <translation>Supprimer cette entrée.</translation>
+ <source>Remove the selected entry(ies).</source>
+ <translation>Supprimer les entrées sélectionnées.</translation>
</message>
<message>
- <source>Copy this entry.</source>
- <oldsource>Copy this profile.</oldsource>
- <translation>Copier cette entrée.</translation>
+ <source>Copy the selected entry(ies).</source>
+ <translation>Copier les entrées sélectionnées.</translation>
</message>
<message>
- <source>Move entry up.</source>
- <translation>Déplacer l&apos;entrée vers le haut.</translation>
+ <source>Move the selected entry(ies) up.</source>
+ <translation>Déplacer les entrées sélectionnées vers le haut.</translation>
</message>
<message>
- <source>Move entry down.</source>
- <translation>Déplacer l&apos;entrée vers le bas.</translation>
+ <source>Move the selected entry(ies) down.</source>
+ <translation>Déplacer les entrées sélectionnées vers le bas.</translation>
</message>
<message>
<source>Clear all entries.</source>
@@ -12057,20 +12622,20 @@ Changer la direction de la connexion (voir le flux inverse).&lt;/p&gt;&lt;/body&
<translation>Créer une nouvelle entrée.</translation>
</message>
<message>
- <source>Remove this entry.</source>
- <translation>Supprimer cette entrée.</translation>
+ <source>Remove the selected entry(ies).</source>
+ <translation>Supprimer les entrées sélectionnées.</translation>
</message>
<message>
- <source>Copy this entry.</source>
- <translation>Copier cette entrée.</translation>
+ <source>Copy the selected entry(ies).</source>
+ <translation>Copier les entrées sélectionnées.</translation>
</message>
<message>
- <source>Move entry up.</source>
- <translation>Déplacer l&apos;entrée vers le haut.</translation>
+ <source>Move the selected entry(ies) up.</source>
+ <translation>Déplacer les entrées sélectionnées vers le haut.</translation>
</message>
<message>
- <source>Move entry down.</source>
- <translation>Déplacer l&apos;entrée vers le bas.</translation>
+ <source>Move the selected entry(ies) down.</source>
+ <translation>Déplacer les entrées sélectionnées vers le bas.</translation>
</message>
<message>
<source>Clear all entries.</source>
@@ -12399,10 +12964,18 @@ a:hover {
<translation>Vous reniflez la colle qui maintient Internet ensemble à l&apos;aide de Wireshark </translation>
</message>
<message>
+ <source>You are sniffing the glue that holds your system together using Logray </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>You are running Wireshark </source>
<translation>Vous exécutez Wireshark </translation>
</message>
<message>
+ <source>You are running Logray </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source> You receive automatic updates.</source>
<translation> Vous recevez les mises à jour automatiques.</translation>
</message>
@@ -12679,14 +13252,6 @@ a:hover {
<translation>Pas de fichier trouvé</translation>
</message>
<message>
- <source>&amp;Contents</source>
- <translation>&amp;Aide</translation>
- </message>
- <message>
- <source>Wireshark Filter</source>
- <translation>Filtre Wireshark</translation>
- </message>
- <message>
<source>TShark</source>
<translation>TShark</translation>
</message>
@@ -12952,10 +13517,6 @@ a:hover {
<translation>Barre d&apos;outils Wireless</translation>
</message>
<message>
- <source>Help contents</source>
- <translation>Contenu de l&apos;aide</translation>
- </message>
- <message>
<source>FAQs</source>
<translation>FAQ</translation>
</message>
@@ -13076,11 +13637,6 @@ a:hover {
<translation>Trouver le paquet précédent</translation>
</message>
<message>
- <source>&amp;Mark/Unmark Packet(s)</source>
- <oldsource>&amp;Mark/Unmark Packet</oldsource>
- <translation>&amp;Marquer/Démarquer le(s) paquet(s)</translation>
- </message>
- <message>
<source>Mark All Displayed</source>
<translation>Marquer tout comme Affichées</translation>
</message>
@@ -13109,11 +13665,6 @@ a:hover {
<translation>Aller au paquet précédent marqué</translation>
</message>
<message>
- <source>&amp;Ignore/Unignore Packet(s)</source>
- <oldsource>&amp;Ignore/Unignore Packet</oldsource>
- <translation>&amp;Ignorer/Annuler le(s) paquet(s)</translation>
- </message>
- <message>
<source>Ignore All Displayed</source>
<translation>Ignorer tous les affichés</translation>
</message>
@@ -13554,32 +14105,28 @@ a:hover {
<translation>Réinitialiser la mise en page</translation>
</message>
<message>
- <source>Reset appearance layout to default size</source>
- <translation>Réinitialiser la disposition de l&apos;apparence à la taille par défaut</translation>
- </message>
- <message>
<source>Seconds Since First Captured Packet</source>
<translation>Secondes depuis le premier paquet capturé</translation>
</message>
<message>
<source>Show packet times as the seconds since the first captured packet.</source>
- <translation type="unfinished"></translation>
+ <translation>Afficher les temps paquets en secondes depuis le premier paquet capturé.</translation>
</message>
<message>
<source>Tenths of a millisecond</source>
- <translation type="unfinished"></translation>
+ <translation>Dixièmes de millisecondes</translation>
</message>
<message>
<source>Hundredths of a millisecond</source>
- <translation type="unfinished"></translation>
+ <translation>Centièmes de millisecondes</translation>
</message>
<message>
<source>Tenths of a microsecond</source>
- <translation type="unfinished"></translation>
+ <translation>Dixièmes de microsecondes</translation>
</message>
<message>
<source>Hundredths of a microsecond</source>
- <translation type="unfinished"></translation>
+ <translation>Centièmes de microsecondes</translation>
</message>
<message>
<source>Packet &amp;Diagram</source>
@@ -13718,20 +14265,28 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
- <source>TLS Keylog Launcher</source>
+ <source>&amp;Options…</source>
+ <translation>&amp;Options...</translation>
+ </message>
+ <message>
+ <source>&amp;3GPP Uu</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Release Notes</source>
+ <source>&amp;Wireless</source>
+ <translation>&amp;Wireless</translation>
+ </message>
+ <message>
+ <source>&amp;User&apos;s Guide</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Options…</source>
- <translation>&amp;Options...</translation>
+ <source>Wireshark User&apos;s Guide</source>
+ <translation>Manuel utilisateur Wireshark</translation>
</message>
<message>
- <source>&amp;Wireless</source>
- <translation>&amp;Wireless</translation>
+ <source>Display Filters</source>
+ <translation>Filtres d&apos;affichage</translation>
</message>
<message>
<source>Capture &amp;Filters…</source>
@@ -13778,10 +14333,18 @@ a:hover {
<translation>Trouver Pré&amp;cédent</translation>
</message>
<message>
+ <source>&amp;Mark/Unmark Selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Mark or unmark each selected packet</source>
<translation>Marquer ou décocher chaque paquet sélectionné</translation>
</message>
<message>
+ <source>&amp;Ignore/Unignore Selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Ignore or unignore each selected packet</source>
<translation>Ignorer ou désignorer chaque paquet sélectionné</translation>
</message>
@@ -13822,6 +14385,18 @@ a:hover {
<translation>Débit TCP</translation>
</message>
<message>
+ <source>General</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Query-Response</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>DNS Query-Response Statistics</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Request Sequences</source>
<translation>Séquences de requêtes</translation>
</message>
@@ -13830,6 +14405,14 @@ a:hover {
<translation>Séquences de requête HTTP</translation>
</message>
<message>
+ <source>E2AP</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>E2AP Messages</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Decode &amp;As…</source>
<translation>Décoder &amp;Comme...</translation>
</message>
@@ -13890,6 +14473,10 @@ a:hover {
<translation>Taille Normale</translation>
</message>
<message>
+ <source>Reset layout to default size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Resize Columns</source>
<translation>Redimensionner les Colonnes</translation>
</message>
@@ -14148,6 +14735,14 @@ a:hover {
<translation>Aller au paquet référencé par le champ sélectionné.</translation>
</message>
<message>
+ <source>TLS Keylog Launcher</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Release Notes</source>
+ <translation>Notes de version</translation>
+ </message>
+ <message>
<source>&amp;VoIP Calls</source>
<translation>&amp;Appels VoIP</translation>
</message>
@@ -14180,10 +14775,6 @@ a:hover {
<translation>&amp;GSM</translation>
</message>
<message>
- <source>&amp;LTE</source>
- <translation>&amp;LTE</translation>
- </message>
- <message>
<source>&amp;MTP3</source>
<translation>&amp;MTP3</translation>
</message>
@@ -14468,6 +15059,10 @@ a:hover {
<translation>Quitter &amp;sans enregistrer</translation>
</message>
<message>
+ <source>USB CDC Data</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>There is no &quot;rtp.ssrc&quot; field in this version of Wireshark.</source>
<translation>Il n&apos;y a pas de &quot;rtp.ssrc&quot; champ dans cette version de Wireshark.</translation>
</message>
@@ -14617,7 +15212,7 @@ a:hover {
</message>
<message>
<source> before updating</source>
- <translation type="unfinished"></translation>
+ <translation>avant de mettre à jour</translation>
</message>
<message>
<source>There are no TLS Session Keys to save.</source>
@@ -14640,11 +15235,11 @@ a:hover {
</message>
<message>
<source>There are no available secrets used to decrypt TLS traffic in the capture file. Would you like to view information about how to decrypt TLS traffic on the wiki?</source>
- <translation type="unfinished"></translation>
+ <translation>Il n’existe aucun secret disponible utilisé pour déchiffrer le trafic TLS dans le fichier de capture. Souhaitez-vous consulter des informations sur la façon de déchiffrer le trafic TLS sur le wiki ?</translation>
</message>
<message>
<source>Are you sure you want to discard all decryption secrets?</source>
- <translation type="unfinished"></translation>
+ <translation>Voulez-vous vraiment supprimer tous les secrets pour le déchiffrement ?</translation>
</message>
<message>
<source>No filter available. Try another %1.</source>
diff --git a/ui/qt/wireshark_it.ts b/ui/qt/wireshark_it.ts
index 772d32cd..3a84fd06 100644
--- a/ui/qt/wireshark_it.ts
+++ b/ui/qt/wireshark_it.ts
@@ -44,8 +44,8 @@
<translation>Cartelle</translation>
</message>
<message>
- <source>Filter by path</source>
- <translation>Filtro per percorso</translation>
+ <source>Search Folders</source>
+ <translation>Cerca cartelle</translation>
</message>
<message>
<source>Plugins</source>
@@ -80,6 +80,14 @@
<translation>Licenza</translation>
</message>
<message>
+ <source>About Logray</source>
+ <translation>Informazioni su Logray</translation>
+ </message>
+ <message>
+ <source>Logray</source>
+ <translation>Logray</translation>
+ </message>
+ <message>
<source>The directory does not exist</source>
<translation>La cartella non esiste</translation>
</message>
@@ -755,6 +763,28 @@
</message>
</context>
<context>
+ <name>CaptureCommentDialog</name>
+ <message>
+ <source>Edit Capture Comments</source>
+ <translation>Modifica commento della cattura</translation>
+ </message>
+ <message>
+ <source>Add Comment</source>
+ <translation>Aggiungi commento</translation>
+ </message>
+ <message>
+ <source>Section %1</source>
+ <translation>Sezione %1</translation>
+ </message>
+</context>
+<context>
+ <name>CaptureCommentTabWidget</name>
+ <message>
+ <source>Comment %1</source>
+ <translation>Commento %1</translation>
+ </message>
+</context>
+<context>
<name>CaptureFile</name>
<message>
<source> [closing]</source>
@@ -863,10 +893,6 @@
<translation>Filtro di lettura:</translation>
</message>
<message>
- <source>Compress with g&amp;zip</source>
- <translation>Comprimi con g&amp;zip</translation>
- </message>
- <message>
<source>Open Capture File</source>
<oldsource>Wireshark: Open Capture File</oldsource>
<translation>Apri un file di cattura</translation>
@@ -948,8 +974,8 @@
<translation>Dettagli</translation>
</message>
<message>
- <source>Capture file comments</source>
- <translation>Commenti del file di cattura</translation>
+ <source>Edit Comments</source>
+ <translation>Modifica commenti</translation>
</message>
<message>
<source>Refresh</source>
@@ -960,10 +986,6 @@
<translation>Copia negli appunti</translation>
</message>
<message>
- <source>Save Comments</source>
- <translation>Salva i commenti</translation>
- </message>
- <message>
<source>Capture File Properties</source>
<translation>Proprietà del file di cattura</translation>
</message>
@@ -1012,10 +1034,18 @@
<translation>Primo pacchetto</translation>
</message>
<message>
+ <source>First event</source>
+ <translation>Primo evento</translation>
+ </message>
+ <message>
<source>Last packet</source>
<translation>Ultimo pacchetto</translation>
</message>
<message>
+ <source>Last event</source>
+ <translation>Ultimo evento</translation>
+ </message>
+ <message>
<source>Elapsed</source>
<translation>Trascorso</translation>
</message>
@@ -1052,6 +1082,10 @@
<translation>Pacchetti persi</translation>
</message>
<message>
+ <source>Dropped events</source>
+ <translation>Eventi scartati</translation>
+ </message>
+ <message>
<source>Capture filter</source>
<translation>Filtro di cattura</translation>
</message>
@@ -1064,6 +1098,10 @@
<translation>Dimensione limite del pacchetto (snaplen)</translation>
</message>
<message>
+ <source>Event size limit (snaplen)</source>
+ <translation>Limite dimensione degli eventi (snaplen)</translation>
+ </message>
+ <message>
<source>none</source>
<translation>nessuno</translation>
</message>
@@ -1072,6 +1110,26 @@
<translation>%1 byte</translation>
</message>
<message>
+ <source>Comments</source>
+ <translation>Commenti</translation>
+ </message>
+ <message>
+ <source>Comment %1: </source>
+ <translation>Commento %1:</translation>
+ </message>
+ <message>
+ <source>Decryption Secrets</source>
+ <translation>Segreti di decifratura</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tipo</translation>
+ </message>
+ <message>
+ <source>Size</source>
+ <translation>Dimensione</translation>
+ </message>
+ <message>
<source>Statistics</source>
<translation>Statistiche</translation>
</message>
@@ -1096,6 +1154,10 @@
<translation>Pacchetti</translation>
</message>
<message>
+ <source>Events</source>
+ <translation>Eventi</translation>
+ </message>
+ <message>
<source>Time span, s</source>
<translation>Tempo, s</translation>
</message>
@@ -1108,6 +1170,10 @@
<translation>Dimensione media dei pacchetti, B</translation>
</message>
<message>
+ <source>Average event size, B</source>
+ <translation>Dimensione media degli eventi, B</translation>
+ </message>
+ <message>
<source>Bytes</source>
<translation>Byte</translation>
</message>
@@ -1120,14 +1186,14 @@
<translation>Bit/s medi</translation>
</message>
<message>
- <source>Section Comment</source>
- <translation>Commento sezione</translation>
- </message>
- <message>
<source>Packet Comments</source>
<translation>Commenti pacchetto</translation>
</message>
<message>
+ <source>Event Comments</source>
+ <translation>Commenti evento</translation>
+ </message>
+ <message>
<source>&lt;p&gt;Frame %1: </source>
<translation>&lt;p&gt;Frame %1: </translation>
</message>
@@ -1139,6 +1205,14 @@
</translation>
</message>
+ <message>
+ <source>Created by Logray %1
+
+</source>
+ <translation>Creato da Logray %1
+
+</translation>
+ </message>
</context>
<context>
<name>CaptureFilterCombo</name>
@@ -1366,6 +1440,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</translation>
</message>
<message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for some more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Di solito una scheda di rete wireless catturerà solo il traffico inviato e ricevuto dal suo indirizzo di rete e catturerà solo il traffico &lt;em&gt;dati dell&apos;utente&lt;/em&gt; con intestazioni Ethernet &amp;quot;fittizie&amp;quot;. Se desideri catturare tutto il traffico che transita sulle schede di rete wireless o sei interessato ai pacchetti di gestione o di controllo 802.11, o alle informazioni del livello radio, seleziona questa opzione. La disponibilità della modalità di monitoraggio dipende dalla scheda di rete wireless e dal driver. Consulta il Wiki per ulteriori dettagli sulla cattura dei pacchetti nelle reti WLAN.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>Enable monitor mode on all 802.11 interfaces</source>
+ <translation>Abilita la modalità monitor su tutte le interfacce 802.11</translation>
+ </message>
+ <message>
<source>compression</source>
<translation>compressione</translation>
</message>
@@ -1378,6 +1460,30 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>gzip</translation>
</message>
<message>
+ <source>File infix pattern</source>
+ <translation>Modello di infisso dei file</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;In multiple file mode, the date and time and file index number are inserted between filename template and any suffix. Select their order.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;In modalità file multipli, la data e l&apos;ora e il numero di indice del file sono inseriti tra il modello del nome del file e qualsiasi suffisso. Seleziona il loro ordine.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>YYYYmmDDHHMMSS_NNNNN</source>
+ <translation>AAAAmmGGHHMMSS_NNNNN</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Date and time before the file index number. This causes files to sort in creation time order, and keeps files from the same batch closely ordered.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Data e ora prima del numero di indice del file. Ciò fa sì che i file vengano ordinati in base all&apos;ora di creazione e mantiene i file dello stesso lotto ordinati in modo stretto.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>NNNNN_YYYYmmDDHHMMSS</source>
+ <translation>NNNNN_AAAAmmGGHHMMSS</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;File index number before the date and time. This is the historic Wireshark ordering.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Numero di indice del file prima della data e dell&apos;ora. Questo è l&apos;ordinamento storico di Wireshark.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;After capturing has switched to the next file and the given number of files has exceeded, the oldest file will be removed.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Dopo che la cattura è passata al file successivo e il numero di file prescelto è stato superato, il file più vecchio sarà rimosso.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1459,23 +1565,27 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
</message>
<message>
<source>Stop capturing after the specified number of packets have been captured.</source>
- <translation>Ferma la cattura dopo che un certo numero di pacchetti è stato catturato.</translation>
+ <translation>Ferma la cattura dopo che il numero di pacchetti specificato è stato catturato.</translation>
</message>
<message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Stop capturing after the specified number of files have been created.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ferma la cattura dopo che il numero di file specificato è stato creato.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
+ <source>Stop capturing after the specified number of files have been created.</source>
+ <translation>Ferma la cattura dopo che il numero di file specificato è stato creato.</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Stop capturing after the specified amount of data has been captured.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ferma la cattura dopo che una certa quantità di dati è stata catturata.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ferma la cattura dopo che la quantità di dati specificata è stata catturata.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<source>Stop capturing after the specified amount of data has been captured.</source>
- <translation>Ferma la cattura dopo che una certa quantità di dati è stata catturata.</translation>
+ <translation>Ferma la cattura dopo che la quantità di dati specificata è stata catturata.</translation>
</message>
<message>
<source>Stop capturing after the specified amount of time has passed.</source>
- <translation>Ferma la cattura dopo che la quantità di tempo specificato è trascorsa.</translation>
+ <translation>Ferma la cattura dopo che la quantità di tempo specificata è trascorsa.</translation>
</message>
<message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Optionally specify a temporary directory for unnamed capture files.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
@@ -1526,8 +1636,8 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Errore</translation>
</message>
<message>
- <source>Multiple files: Requested filesize too large. The filesize cannot be greater than 2 GiB.</source>
- <translation>File multipli: la dimensione del file richiesta è troppo grande. La dimensione del file non può essere superiore a 2 GiB.</translation>
+ <source>Multiple files: Requested filesize too large. The filesize cannot be greater than 2 TB.</source>
+ <translation>File multipli: la dimensione del file richiesta è troppo grande. La dimensione del file non può essere superiore a 2 TB.</translation>
</message>
<message>
<source>Multiple files: No capture file name given. You must specify a filename if you want to use multiple files.</source>
@@ -1557,6 +1667,14 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Cattura i pacchetti in modalità promiscua</translation>
</message>
<message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Di solito una scheda di rete wireless catturerà solo il traffico inviato e ricevuto dal suo indirizzo di rete e catturerà solo il traffico &lt;em&gt;dati dell&apos;utente&lt;/em&gt; con intestazioni Ethernet &amp;quot;fittizie&amp;quot;. Se desideri catturare tutto il traffico che transita sulle schede di rete wireless o sei interessato ai pacchetti di gestione o di controllo 802.11, o alle informazioni del livello radio, seleziona questa opzione. La disponibilità della modalità di monitoraggio dipende dalla scheda di rete wireless e dal driver. Consulta il Wiki per ulteriori dettagli sulla cattura dei pacchetti nelle reti WLAN.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>Capture packets in monitor mode on 802.11 devices</source>
+ <translation>Cattura i pacchetti in modalità monitor sui dispositivi 802.11</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Capture packets in the next-generation capture file format.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Cattura i pacchetti nel formato di file di nuova generazione.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1578,11 +1696,11 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
</message>
<message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;How often the capture notifies the GUI of new packets. Affects how often the GUI updates and the granularity of timers.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;La frequenza con cui l&apos;acquisizione notifica alla GUI i nuovi pacchetti. Influisce sulla frequenza degli aggiornamenti della GUI e sulla granularità dei timer.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;La frequenza con cui l&apos;acquisizione notifica all&apos;interfaccia grafica i nuovi pacchetti. Influisce sulla frequenza degli aggiornamenti dell&apos;interfaccia e sulla granularità dei timer.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The interval between new packet updates. Affects how often the GUI updates and the granularity of timers.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;L&apos;intervallo tra gli aggiornamenti dei nuovi pacchetti. Influisce sulla frequenza degli aggiornamenti della GUI e sulla granularità dei timer.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;L&apos;intervallo tra gli aggiornamenti dei nuovi pacchetti. Influisce sulla frequenza degli aggiornamenti dell&apos;interfaccia grafica e sulla granularità dei timer.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<source>Don&apos;t load interfaces on startup</source>
@@ -1784,6 +1902,14 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Risolto</translation>
</message>
<message>
+ <source>Width</source>
+ <translation>Larghezza</translation>
+ </message>
+ <message>
+ <source>Alignment</source>
+ <translation>Allineamento</translation>
+ </message>
+ <message>
<source>&lt;html&gt;Show human-readable strings instead of raw values for fields. Only applicable to custom columns with fields that have value strings.&lt;/html&gt;</source>
<translation>&lt;html&gt;Mostra stringhe comprensibili invece che i valori grezzi dei campi. Applicabile solo alle colonne personalizzate con campi che hanno stringhe con valori.&lt;/html&gt;</translation>
</message>
@@ -1831,6 +1957,25 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
</message>
</context>
<context>
+ <name>CompressionGroupBox</name>
+ <message>
+ <source>Compression options</source>
+ <translation>Opzioni di compressione</translation>
+ </message>
+ <message>
+ <source>&amp;Uncompressed</source>
+ <translation>&amp;Non compresso</translation>
+ </message>
+ <message>
+ <source>Compress with g&amp;zip</source>
+ <translation>Comprimi con g&amp;zip</translation>
+ </message>
+ <message>
+ <source>Compress with &amp;LZ4</source>
+ <translation>Comprimi con &amp;LZ4</translation>
+ </message>
+</context>
+<context>
<name>ConversationDataModel</name>
<message>
<source>Address A</source>
@@ -1897,6 +2042,10 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Bit/s B</translation>
</message>
<message>
+ <source>Flows</source>
+ <translation>Flussi</translation>
+ </message>
+ <message>
<source>Total Packets</source>
<translation>Pacchetti totali</translation>
</message>
@@ -2011,14 +2160,6 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Copia i byte del pacchetto come un dump esadecimale.</translation>
</message>
<message>
- <source>…as Printable Text</source>
- <translation>...come testo stampabile</translation>
- </message>
- <message>
- <source>Copy only the printable text in the packet.</source>
- <translation>Copia solo il testo stampabile nel pacchetto.</translation>
- </message>
- <message>
<source>…as MIME Data</source>
<translation>…come dati MIME</translation>
</message>
@@ -2031,10 +2172,42 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Copia i byte dei pacchetti come caratteri ASCII stampabili e sequenze di escape.</translation>
</message>
<message>
+ <source>…as Go literal</source>
+ <translation>…come Go letterale</translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as Go literal.</source>
+ <translation>Copia i byte del pacchetto come Go letterale.</translation>
+ </message>
+ <message>
+ <source>…as C Array</source>
+ <translation>...come Array C</translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as C Array.</source>
+ <translation>Copia i byte del pacchetto come Array C.</translation>
+ </message>
+ <message>
<source>…as a Hex Stream</source>
<translation>...come un flusso esadecimale</translation>
</message>
<message>
+ <source>…as UTF-8 Text</source>
+ <translation>…come testo UTF-8</translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as text, treating as UTF-8.</source>
+ <translation>Copia i byte del pacchetto come testo, trattandolo come UTF-8.</translation>
+ </message>
+ <message>
+ <source>…as ASCII Text</source>
+ <translation>…come testo ASCII</translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as text, treating as ASCII.</source>
+ <translation>Copia i byte del pacchetto come testo, trattandolo come ASCII.</translation>
+ </message>
+ <message>
<source>Copy packet bytes as a stream of hex.</source>
<translation>Copia i byte del pacchetto come un flusso esadecimale.</translation>
</message>
@@ -2830,6 +3003,10 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<source>Display filter:</source>
<translation>Filtro di visualizzazione:</translation>
</message>
+ <message>
+ <source>Export PDUs</source>
+ <translation>Esporta PDU</translation>
+ </message>
</context>
<context>
<name>ExtArgSelector</name>
@@ -2869,10 +3046,6 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Avvia</translation>
</message>
<message>
- <source>Save</source>
- <translation>Salva</translation>
- </message>
- <message>
<source>Default</source>
<translation>Predefinito</translation>
</message>
@@ -3014,6 +3187,14 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Filtri di visualizzazione</translation>
</message>
<message>
+ <source>Display Filter Macros</source>
+ <translation>Visualizza macro dei filtri</translation>
+ </message>
+ <message>
+ <source>New macro</source>
+ <translation>Nuova macro</translation>
+ </message>
+ <message>
<source>Open </source>
<translation>Apri </translation>
</message>
@@ -3097,10 +3278,18 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<context>
<name>FilterListModel</name>
<message>
+ <source>Macro Name</source>
+ <translation>Nome macro</translation>
+ </message>
+ <message>
<source>Filter Name</source>
<translation>Nome filtro</translation>
</message>
<message>
+ <source>Macro Expression</source>
+ <translation>Espressione macro</translation>
+ </message>
+ <message>
<source>Filter Expression</source>
<translation>Espressione del filtro</translation>
</message>
@@ -3186,22 +3375,10 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<context>
<name>FolderListModel</name>
<message>
- <source>&quot;File&quot; dialogs</source>
- <translation>Finestre &quot;File&quot;</translation>
- </message>
- <message>
- <source>capture files</source>
- <translation>file di cattura</translation>
- </message>
- <message>
<source>Temp</source>
<translation>Temporanei</translation>
</message>
<message>
- <source>untitled capture files</source>
- <translation>file di cattura senza titolo</translation>
- </message>
- <message>
<source>Personal configuration</source>
<translation>Configurazione personale</translation>
</message>
@@ -3210,14 +3387,6 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Configurazione globale</translation>
</message>
<message>
- <source>dfilters, preferences, ethers, …</source>
- <translation>dfilters, preferences, ethers, </translation>
- </message>
- <message>
- <source>dfilters, preferences, manuf, …</source>
- <translation>dfilters, preferences, manuf, </translation>
- </message>
- <message>
<source>System</source>
<translation>Sistema</translation>
</message>
@@ -3230,18 +3399,10 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Programma</translation>
</message>
<message>
- <source>program files</source>
- <translation>file di programma</translation>
- </message>
- <message>
<source>Personal Plugins</source>
<translation>Plugin personali</translation>
</message>
<message>
- <source>binary plugins</source>
- <translation>plugin binari</translation>
- </message>
- <message>
<source>Global Plugins</source>
<translation>Plugin globali</translation>
</message>
@@ -3258,12 +3419,36 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Script Lua</translation>
</message>
<message>
+ <source>&quot;File&quot; dialog location</source>
+ <translation>Posizione finestra &quot;File&quot;</translation>
+ </message>
+ <message>
+ <source>Capture files</source>
+ <translation>File di cattura</translation>
+ </message>
+ <message>
+ <source>Untitled capture files</source>
+ <translation>File di cattura senza titolo</translation>
+ </message>
+ <message>
+ <source>Preferences, profiles, manuf, …</source>
+ <translation>Preferenze, profili, prod, …</translation>
+ </message>
+ <message>
+ <source>Program files</source>
+ <translation>File di programma</translation>
+ </message>
+ <message>
+ <source>Binary plugins</source>
+ <translation>Plugin binari</translation>
+ </message>
+ <message>
<source>Personal Extcap path</source>
<translation>Percorso Extcap personale</translation>
</message>
<message>
- <source>external capture (extcap) plugins</source>
- <translation>estensioni di cattura esterna (extcap)</translation>
+ <source>External capture (extcap) plugins</source>
+ <translation>Plugin di cattura esterna (extcap)</translation>
</message>
<message>
<source>Global Extcap path</source>
@@ -3400,6 +3585,24 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
</translation>
</message>
<message>
+ <source>Event %1. </source>
+ <translation>Evento %1.</translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;reads&lt;/span&gt;, </source>
+ <translation>
+ <numerusform>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;scrittura&lt;/span&gt;,</numerusform>
+ <numerusform>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;scritture&lt;/span&gt;,</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;writes&lt;/span&gt;, </source>
+ <translation>
+ <numerusform>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;scritture&lt;/span&gt;,</numerusform>
+ <numerusform>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;scritture&lt;/span&gt;,</numerusform>
+ </translation>
+ </message>
+ <message>
<source> Click to select.</source>
<translation> Fai clic per selezionare.</translation>
</message>
@@ -3432,6 +3635,18 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Flussi %1 non trovati nel pacchetto selezionato.</translation>
</message>
<message>
+ <source>Read activity(%6)</source>
+ <translation>Attività di lettura(%6)</translation>
+ </message>
+ <message>
+ <source>Write activity(%6)</source>
+ <translation>Attività di scrittura(%6)</translation>
+ </message>
+ <message>
+ <source>Entire I/O activity (%1)</source>
+ <translation>Intera attività I/O (%1)</translation>
+ </message>
+ <message>
<source>Entire conversation (%1)</source>
<translation>Conversazione intera (%1)</translation>
</message>
@@ -3447,10 +3662,6 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<source>Save Stream Content As…</source>
<translation>Salva il contenuto del flusso come...</translation>
</message>
- <message>
- <source>[Stream output truncated]</source>
- <translation>[Flusso di output troncato]</translation>
- </message>
<message numerus="yes">
<source>%Ln total stream(s).</source>
<translation>
@@ -3478,9 +3689,20 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Suggerimento.</translation>
</message>
<message>
- <source>Show data as</source>
- <oldsource>Show and save data as</oldsource>
- <translation>Mostra dati come</translation>
+ <source>Show as</source>
+ <translation>Mostra come</translation>
+ </message>
+ <message>
+ <source>No delta times</source>
+ <translation>Nessun delta dei tempi</translation>
+ </message>
+ <message>
+ <source>Turn delta times</source>
+ <translation>Attiva i delta dei tempi</translation>
+ </message>
+ <message>
+ <source>All delta times</source>
+ <translation>Tutti i delta dei tempi</translation>
</message>
<message>
<source>Stream</source>
@@ -3495,11 +3717,22 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Trova:</translation>
</message>
<message>
+ <source>Case sensitive</source>
+ <translation>Distingui maiuscole</translation>
+ </message>
+ <message>
<source>Find &amp;Next</source>
<translation>Trova &amp;successivo</translation>
</message>
</context>
<context>
+ <name>FollowStreamText</name>
+ <message>
+ <source>[Stream output truncated]</source>
+ <translation>[Flusso di uscita troncato]</translation>
+ </message>
+</context>
+<context>
<name>FontColorPreferencesFrame</name>
<message>
<source>Frame</source>
@@ -3835,28 +4068,27 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <source>Remove this graph.</source>
- <oldsource>Remove this dissection behavior.</oldsource>
- <translation>Rimuovi questo grafico.</translation>
- </message>
- <message>
<source>Add a new graph.</source>
<translation>Aggiungi un nuovo grafico.</translation>
</message>
<message>
- <source>Duplicate this graph.</source>
- <translation>Duplica questo grafico.</translation>
- </message>
- <message>
<source>Clear all graphs.</source>
<translation>Cancella tutti i grafici.</translation>
</message>
<message>
- <source>Move this graph upwards.</source>
- <translation>Sposta questo grafico verso l&apos;alto.</translation>
+ <source>Remove the selected graph(s).</source>
+ <translation>Rimuovi i grafici selezionati.</translation>
+ </message>
+ <message>
+ <source>Duplicate the selected graph(s).</source>
+ <translation>Duplica i grafici selezionati.</translation>
+ </message>
+ <message>
+ <source>Move the selected graph(s) upwards.</source>
+ <translation>Sposta i grafici selezionati in alto.</translation>
</message>
<message>
- <source>Move this graph downwards.</source>
+ <source>Move the selected graph(s) downwards.</source>
<translation>Sposta questo grafico verso il basso.</translation>
</message>
<message>
@@ -3869,7 +4101,7 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
</message>
<message>
<source>drags</source>
- <translation>trascinamenti</translation>
+ <translation>trascina</translation>
</message>
<message>
<source>Select using the mouse button.</source>
@@ -3877,7 +4109,7 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
</message>
<message>
<source>zooms</source>
- <translation>zoom</translation>
+ <translation>ingrandisce</translation>
</message>
<message>
<source>Interval</source>
@@ -3900,10 +4132,6 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Abilita la legenda</translation>
</message>
<message>
- <source>Reset</source>
- <translation>Ripristina</translation>
- </message>
- <message>
<source>Reset Graph</source>
<translation>Ripristina il grafico</translation>
</message>
@@ -4117,6 +4345,42 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Copia grafici da un altro profilo.</translation>
</message>
<message>
+ <source>1 μs</source>
+ <translation>1 μs</translation>
+ </message>
+ <message>
+ <source>2 μs</source>
+ <translation>2 μs</translation>
+ </message>
+ <message>
+ <source>5 μs</source>
+ <translation>5 μs</translation>
+ </message>
+ <message>
+ <source>10 μs</source>
+ <translation>10 μs</translation>
+ </message>
+ <message>
+ <source>20 μs</source>
+ <translation>20 μs</translation>
+ </message>
+ <message>
+ <source>50 μs</source>
+ <translation>50 μs</translation>
+ </message>
+ <message>
+ <source>100 μs</source>
+ <translation>100 μs</translation>
+ </message>
+ <message>
+ <source>200 μs</source>
+ <translation>200 μs</translation>
+ </message>
+ <message>
+ <source>500 μs</source>
+ <translation>500 μs</translation>
+ </message>
+ <message>
<source>1 ms</source>
<translation>1 ms</translation>
</message>
@@ -4161,6 +4425,14 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>5 sec</translation>
</message>
<message>
+ <source>2 min</source>
+ <translation>2 min</translation>
+ </message>
+ <message>
+ <source>5 min</source>
+ <translation>5 min</translation>
+ </message>
+ <message>
<source>Wireshark I/O Graphs: %1</source>
<translation>Grafici di I/O di Wireshark: %1</translation>
</message>
@@ -4173,6 +4445,14 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Eventi filtrati</translation>
</message>
<message>
+ <source>All packets</source>
+ <translation>Tutti i pacchetti</translation>
+ </message>
+ <message>
+ <source>All events</source>
+ <translation>Tutti gli eventi</translation>
+ </message>
+ <message>
<source>All Packets</source>
<translation>Tutti i pacchetti</translation>
</message>
@@ -4185,8 +4465,8 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Tutti gli eventi</translation>
</message>
<message>
- <source>Access Denied</source>
- <translation>Accesso negato</translation>
+ <source>All Execs</source>
+ <translation>Tutti gli eseguibili</translation>
</message>
<message>
<source>Hover over the graph for details.</source>
@@ -4233,6 +4513,34 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Fai clic per selezionare una porzione del grafico.</translation>
</message>
<message>
+ <source>%1 Intervals </source>
+ <translation>%1 intervalli</translation>
+ </message>
+ <message>
+ <source>Move to top left</source>
+ <translation>Sposta in alto a sinistra</translation>
+ </message>
+ <message>
+ <source>Move to top center</source>
+ <translation>Sposta in alto al centro</translation>
+ </message>
+ <message>
+ <source>Move to top right</source>
+ <translation>Sposta in alto a destra</translation>
+ </message>
+ <message>
+ <source>Move to bottom left</source>
+ <translation>Sposta in basso a sinistra</translation>
+ </message>
+ <message>
+ <source>Move to bottom center</source>
+ <translation>Sposta in basso al centro</translation>
+ </message>
+ <message>
+ <source>Move to bottom right</source>
+ <translation>Sposta in basso a destra</translation>
+ </message>
+ <message>
<source>Portable Document Format (*.pdf)</source>
<translation>Portable Document Format (*.pdf)</translation>
</message>
@@ -4985,6 +5293,13 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
</message>
</context>
<context>
+ <name>InterfaceTreeDelegate</name>
+ <message>
+ <source>default</source>
+ <translation>predefinito</translation>
+ </message>
+</context>
+<context>
<name>InterfaceTreeModel</name>
<message>
<source>Show</source>
@@ -5919,7 +6234,7 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
</message>
<message>
<source>Packet List settings:</source>
- <translation>Impostazioni elenco dei pacchetti:</translation>
+ <translation>Impostazioni elenco pacchetti:</translation>
</message>
<message>
<source>Show packet separator</source>
@@ -5961,8 +6276,8 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<context>
<name>LteMacStatisticsDialog</name>
<message>
- <source>LTE Mac Statistics</source>
- <translation>Statistiche Mac LTE</translation>
+ <source>LTE/NR Mac Statistics</source>
+ <translation>Statistiche Mac LTE/NR</translation>
</message>
<message>
<source>Include SR frames in filter</source>
@@ -6047,7 +6362,7 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
</message>
<message>
<source>drags</source>
- <translation>trascinamenti</translation>
+ <translation>trascina</translation>
</message>
<message>
<source>Select using the mouse button.</source>
@@ -6055,7 +6370,7 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
</message>
<message>
<source>zooms</source>
- <translation>ingrandimenti</translation>
+ <translation>ingrandisce</translation>
</message>
<message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Reset the graph to its initial state.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
@@ -6266,12 +6581,12 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Numero di sequenza</translation>
</message>
<message>
- <source>LTE RLC Graph (UE=%1 chan=%2%3 %4 - %5)</source>
- <translation>Grafico RLC LTE (UE=%1 can=%2%3 %4 - %5)</translation>
+ <source>%1 RLC Graph (UE=%2 chan=%3%4 %5 - %6)</source>
+ <translation>Grafico RLC %1 (UE=%2 can=%3%4 %5 - %6)</translation>
</message>
<message>
- <source>LTE RLC Graph - no channel selected</source>
- <translation>Grafico RLC LTE - nessun canale selezionato</translation>
+ <source>3GPP RLC Graph - no channel selected</source>
+ <translation>Grafico 3GPP RLC LTE - nessun canale selezionato</translation>
</message>
<message>
<source>Save As…</source>
@@ -6325,8 +6640,8 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<context>
<name>LteRlcStatisticsDialog</name>
<message>
- <source>LTE RLC Statistics</source>
- <translation>Statistiche RLC LTE</translation>
+ <source>3GPP RLC Statistics</source>
+ <translation>Statistiche 3GPP RLC</translation>
</message>
<message>
<source>Include SR frames in filter</source>
@@ -6412,6 +6727,10 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Profilo: %1</translation>
</message>
<message>
+ <source> %1 Displayed: %2 (%3%)</source>
+ <translation>%1 visualizzati: %2 (%3%)</translation>
+ </message>
+ <message>
<source>Manage Profiles…</source>
<translation>Gestisci i profili...</translation>
</message>
@@ -6473,6 +6792,13 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<numerusform>%Ln byte</numerusform>
</translation>
</message>
+ <message numerus="yes">
+ <source>%Ln bit(s)</source>
+ <translation>
+ <numerusform>%Ln bit</numerusform>
+ <numerusform>%Ln bit</numerusform>
+ </translation>
+ </message>
<message>
<source>Byte %1</source>
<translation>Byte %1</translation>
@@ -6486,9 +6812,12 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Pacchetto selezionato: %1 %2 </translation>
</message>
<message>
- <source>Packets: %1 %4 Displayed: %2 (%3%)</source>
- <oldsource>Packets: %1 %4 Displayed: %2 %4 Marked: %3</oldsource>
- <translation>Pacchetti: %1 %4 visualizzati: %2 (%3%)</translation>
+ <source>Selected Event: %1 %2 </source>
+ <translation>Evento selezionato: %1 %2</translation>
+ </message>
+ <message>
+ <source>Events: %1</source>
+ <translation>Eventi: %1</translation>
</message>
<message>
<source> %1 Selected: %2 (%3%)</source>
@@ -6520,6 +6849,10 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Nessun pacchetto</translation>
</message>
<message>
+ <source>No Events</source>
+ <translation>Nessun evento</translation>
+ </message>
+ <message>
<source>From Zip File...</source>
<translation>Da file Zip...</translation>
</message>
@@ -6552,6 +6885,13 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
</message>
</context>
<context>
+ <name>MainWindow</name>
+ <message>
+ <source>Display filter as %1</source>
+ <translation>Filtro di visualizzazione come %1</translation>
+ </message>
+</context>
+<context>
<name>MainWindowPreferencesFrame</name>
<message>
<source>Frame</source>
@@ -6583,6 +6923,10 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>La cartella usata più di recente</translation>
</message>
<message>
+ <source>The current working directory</source>
+ <translation>La cartella di lavoro attuale</translation>
+ </message>
+ <message>
<source>Show up to</source>
<translation>Mostra fino a</translation>
</message>
@@ -6738,7 +7082,7 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
</message>
<message>
<source>Search vendor name using a case-insentitive regular expression.</source>
- <translation>Cerca il nome del fornitore utilizzando un&apos;espressione regolare senza distinzione tra maiuscole e minuscole.</translation>
+ <translation>Cerca il nome del produttore utilizzando un&apos;espressione regolare senza distinzione tra maiuscole e minuscole.</translation>
</message>
<message>
<source>Vendor Name</source>
@@ -7013,6 +7357,10 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Mostra i valori dei campi</translation>
</message>
<message>
+ <source>Refresh</source>
+ <translation>Aggiorna</translation>
+ </message>
+ <message>
<source>Save Diagram As…</source>
<translation>Salva diagramma come...</translation>
</message>
@@ -7060,6 +7408,10 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Mostra byte del pacchetto</translation>
</message>
<message>
+ <source>Layout:</source>
+ <translation>Disposizione:</translation>
+ </message>
+ <message>
<source>Packet %1</source>
<translation>Pacchetto %1</translation>
</message>
@@ -7082,6 +7434,13 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<numerusform>%Ln byte</numerusform>
</translation>
</message>
+ <message numerus="yes">
+ <source>%Ln bit(s)</source>
+ <translation>
+ <numerusform>%Ln bit</numerusform>
+ <numerusform>%Ln bit</numerusform>
+ </translation>
+ </message>
</context>
<context>
<name>PacketFormatGroupBox</name>
@@ -7291,7 +7650,7 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
</message>
<message>
<source>Also include packets depended upon, such as those used to reassemble displayed packets</source>
- <translation>Includi anche i pacchetti di dipendenza, come quelli utilizzati per riassemblare i pacchetti visualizzati</translation>
+ <translation>Includi anche i pacchetti di dipendenza, come quelli utilizzati per ri-assemblare i pacchetti visualizzati</translation>
</message>
<message>
<source>First &amp;to last marked</source>
@@ -7541,10 +7900,22 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Copia questo profilo.</translation>
</message>
<message>
+ <source>The number of packets or events to check for automatic profile switching.</source>
+ <translation>Il numero di pacchetti o eventi da verificare per la commutazione automatica del profilo.</translation>
+ </message>
+ <message>
+ <source>Auto switch packet limit</source>
+ <translation>Limite pacchetti per commutazione automatica</translation>
+ </message>
+ <message>
<source>Configuration Profiles</source>
<translation>Profili di configurazione</translation>
</message>
<message>
+ <source>Auto switch event limit</source>
+ <translation>Limite eventi per commutazione automatica</translation>
+ </message>
+ <message>
<source>Import</source>
<comment>noun</comment>
<translation>Importa</translation>
@@ -7727,6 +8098,10 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>eliminato</translation>
</message>
<message>
+ <source>Auto Switch Filter</source>
+ <translation>Cambio automatico del filtro</translation>
+ </message>
+ <message>
<source>copy</source>
<comment>noun</comment>
<translation>copia</translation>
@@ -8086,6 +8461,10 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Dimensione della finestra (B)</translation>
</message>
<message>
+ <source>Unacked (Outstanding) Bytes (B)</source>
+ <translation>Byte senza ack (eccezionali) (B)</translation>
+ </message>
+ <message>
<source>[no capture file]</source>
<translation>[nessun file di cattura]</translation>
</message>
@@ -8246,6 +8625,14 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Marcatore mancante?</translation>
</message>
<message>
+ <source>LTE</source>
+ <translation>LTE</translation>
+ </message>
+ <message>
+ <source>NR</source>
+ <translation>NR</translation>
+ </message>
+ <message>
<source>C-RNTI</source>
<translation>C-RNTI</translation>
</message>
@@ -8266,6 +8653,10 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>UEId</translation>
</message>
<message>
+ <source>RAT</source>
+ <translation>RAT</translation>
+ </message>
+ <message>
<source>UL Frames</source>
<translation>UL Frame</translation>
</message>
@@ -8489,9 +8880,69 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<source>Browse…</source>
<translation>Sfoglia...</translation>
</message>
+ <message>
+ <source>PACKETS</source>
+ <translation>PACCHETTI</translation>
+ </message>
+ <message>
+ <source>EVENTS</source>
+ <translation>EVENTI</translation>
+ </message>
+ <message>
+ <source>BYTES</source>
+ <translation>BYTE</translation>
+ </message>
+ <message>
+ <source>BITS</source>
+ <translation>BIT</translation>
+ </message>
+ <message>
+ <source>COUNT FRAMES</source>
+ <translation>NUMERO FRAME</translation>
+ </message>
+ <message>
+ <source>COUNT FIELDS</source>
+ <translation>NUMERO CAMPI</translation>
+ </message>
+ <message>
+ <source>SUM</source>
+ <translation>SOMMA</translation>
+ </message>
+ <message>
+ <source>MAX</source>
+ <translation>MAX</translation>
+ </message>
+ <message>
+ <source>MIN</source>
+ <translation>MIN</translation>
+ </message>
+ <message>
+ <source>AVERAGE</source>
+ <translation>MEDIA</translation>
+ </message>
+ <message>
+ <source>THROUGHPUT</source>
+ <translation>THROUGHPUT</translation>
+ </message>
+ <message>
+ <source>LOAD</source>
+ <translation>CARICO</translation>
+ </message>
+ <message>
+ <source>Left</source>
+ <translation>Sinistra</translation>
+ </message>
+ <message>
+ <source>Center</source>
+ <translation>Centro</translation>
+ </message>
+ <message>
+ <source>Right</source>
+ <translation>Destra</translation>
+ </message>
</context>
<context>
- <name>QObject::QObject</name>
+ <name>QObject::QObject::QObject</name>
<message>
<source>CCCH</source>
<translation>CCCH</translation>
@@ -8592,6 +9043,13 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
</message>
</context>
<context>
+ <name>ResizeHeaderView</name>
+ <message>
+ <source>Resize all %1 to contents</source>
+ <translation>Ridimensiona tutte le %1 al contenuto</translation>
+ </message>
+</context>
+<context>
<name>ResolvedAddressesDialog</name>
<message>
<source>Dialog</source>
@@ -8707,6 +9165,14 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Indirizzi risolti</translation>
</message>
<message>
+ <source>Copy</source>
+ <translation>Copia</translation>
+ </message>
+ <message>
+ <source>Save as…</source>
+ <translation>Salva come...</translation>
+ </message>
+ <message>
<source># Resolved addresses found in %1</source>
<translation># Trovati indirizzi risolti in %1</translation>
</message>
@@ -8720,6 +9186,61 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
</message>
</context>
<context>
+ <name>ResolvedAddressesView</name>
+ <message>
+ <source>as Plain Text</source>
+ <translation>come testo semplice</translation>
+ </message>
+ <message>
+ <source>Copy selected rows</source>
+ <translation>Copia le righe selezionate</translation>
+ </message>
+ <message>
+ <source>Copy table</source>
+ <translation>Copia la tabella</translation>
+ </message>
+ <message>
+ <source>as CSV</source>
+ <translation>come CSV</translation>
+ </message>
+ <message>
+ <source>as JSON</source>
+ <translation>come JSON</translation>
+ </message>
+ <message>
+ <source>Save selected rows as…</source>
+ <translation>Salva le righe selezionate come...</translation>
+ </message>
+ <message>
+ <source>Save table as…</source>
+ <translation>Salva la tabella come...</translation>
+ </message>
+ <message>
+ <source>Save Resolved Addresses As…</source>
+ <translation>Salva gli indirizzi risolti come...</translation>
+ </message>
+ <message>
+ <source>Plain text (*.txt)</source>
+ <translation>Testo semplice (*.txt)</translation>
+ </message>
+ <message>
+ <source>CSV Document (*.csv)</source>
+ <translation>Documento CSV (*.csv)</translation>
+ </message>
+ <message>
+ <source>JSON Document (*.json)</source>
+ <translation>Documento JSON (*.json)</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Avviso</translation>
+ </message>
+ <message>
+ <source>Unable to save %1: %2</source>
+ <translation>Impossibile salvare %1: %2</translation>
+ </message>
+</context>
+<context>
<name>ResponseTimeDelayDialog</name>
<message>
<source>%1 Response Time Delay Statistics</source>
@@ -10394,6 +10915,10 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Byte del pacchetto</translation>
</message>
<message>
+ <source>&lt;b&gt;Options:&lt;/b&gt;</source>
+ <translation>&lt;b&gt;Opzioni:&lt;/b&gt;</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for strings containing narrow (UTF-8 and ASCII) or wide (UTF-16) characters.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Cerca le stringhe che contengono i caratteri ridotti (UTF-8 e ASCII) o allargati (UTF-16).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -10414,6 +10939,18 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Distingui maiuscole</translation>
</message>
<message>
+ <source>Backwards</source>
+ <translation>Indietro</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for a subsequent occurrence in the current packet before advancing to the next packet.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Cerca un&apos;occorrenza successiva nel pacchetto corrente prima di passare al pacchetto successivo.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>Multiple occurrences</source>
+ <translation>Occorrenze multiple</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5), a plain string (e.g. My String) or a regular expression (e.g. colou?r).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<oldsource>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5) or a plain string (e.g. My String).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</oldsource>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Cerca nei dati utilizzando la sintassi dei filtri di visualizzazione (ad es. ip.addr==10.1.1.1), una stringa esadecimale (ad es. fffffda5) o una stringa semplice (ad es. Mia Stringa) o un&apos;espressione regolare (ad es. colou?r).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
@@ -10451,6 +10988,22 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Filtro non valido.</translation>
</message>
<message>
+ <source>Event List</source>
+ <translation>Elenco eventi</translation>
+ </message>
+ <message>
+ <source>Event Details</source>
+ <translation>Dettagli evento</translation>
+ </message>
+ <message>
+ <source>Event Bytes</source>
+ <translation>Byte evento</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search the Info column of the event list (summary pane), decoded event display labels (tree view pane) or the ASCII-converted event data (hex view pane).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt; Cerca nella colonna Info dell&apos;elenco degli eventi (pannello di riepilogo), etichette di visualizzazione degli eventi decodificati (pannello della vista ad albero) o i dati dell&apos;evento convertiti in ASCII (pannello della vista esadecimale).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
<source>That filter doesn&apos;t test anything.</source>
<translation>Il filtro non verifica niente.</translation>
</message>
@@ -10894,6 +11447,10 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Trova:</translation>
</message>
<message>
+ <source>Case sensitive</source>
+ <translation>Distingui maiuscole</translation>
+ </message>
+ <message>
<source>Find &amp;Next</source>
<translation>Trova &amp;successivo</translation>
</message>
@@ -10989,14 +11546,22 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Salva come...</translation>
</message>
<message>
+ <source>Decoded as %1.</source>
+ <translation>Decodificato come %1.</translation>
+ </message>
+ <message>
<source>Save Selected Packet Bytes As…</source>
<translation>Salva byte del pacchetto selezionato come...</translation>
</message>
+ <message>
+ <source>compressed %1</source>
+ <translation>compressi %1</translation>
+ </message>
<message numerus="yes">
- <source>Displaying %Ln byte(s).</source>
+ <source>Using %Ln byte(s).</source>
<translation>
- <numerusform>Visualizzazione di %Ln byte.</numerusform>
- <numerusform>Visualizzazione di %Ln byte.</numerusform>
+ <numerusform>Utilizzo di %Ln byte.</numerusform>
+ <numerusform>Utilizzo di %Ln byte.</numerusform>
</translation>
</message>
<message>
@@ -11096,6 +11661,10 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<source>Display filter:</source>
<translation>Filtro di visualizzazione:</translation>
</message>
+ <message>
+ <source>Strip Headers</source>
+ <translation>Rimuovi intestazioni</translation>
+ </message>
</context>
<context>
<name>SupportedProtocolsDialog</name>
@@ -11320,7 +11889,7 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
</message>
<message>
<source>drags</source>
- <translation>trascinamenti</translation>
+ <translation>trascina</translation>
</message>
<message>
<source>Select using the mouse button.</source>
@@ -11328,7 +11897,7 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
</message>
<message>
<source>zooms</source>
- <translation>zoom</translation>
+ <translation>ingrandisce</translation>
</message>
<message>
<source>Display Round Trip Time vs Sequence Number</source>
@@ -11907,7 +12476,7 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
</message>
<message>
<source>Time shifting is not available while capturing packets.</source>
- <translation>Il spostamento temporale non è disponibile durante l&apos;acquisizione dei pacchetti.</translation>
+ <translation>Lo spostamento temporale non è disponibile durante la cattura dei pacchetti.</translation>
</message>
</context>
<context>
@@ -12064,22 +12633,20 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Crea una nuova voce.</translation>
</message>
<message>
- <source>Remove this entry.</source>
- <oldsource>Remove this profile.</oldsource>
- <translation>Rimuovi questa voce.</translation>
+ <source>Remove the selected entry(ies).</source>
+ <translation>Rimuovi le voci selezionate.</translation>
</message>
<message>
- <source>Copy this entry.</source>
- <oldsource>Copy this profile.</oldsource>
- <translation>Copia questa voce.</translation>
+ <source>Copy the selected entry(ies).</source>
+ <translation>Copia le voci selezionate.</translation>
</message>
<message>
- <source>Move entry up.</source>
- <translation>Sposta su la voce.</translation>
+ <source>Move the selected entry(ies) up.</source>
+ <translation>Sposta le voci selezionate in alto.</translation>
</message>
<message>
- <source>Move entry down.</source>
- <translation>Sposta giù la voce.</translation>
+ <source>Move the selected entry(ies) down.</source>
+ <translation>Sposta le voci selezionate in basso.</translation>
</message>
<message>
<source>Clear all entries.</source>
@@ -12105,20 +12672,20 @@ Ad esempio, usa 1 ora per fare in modo che un nuovo file sia creato ogni ora.</t
<translation>Crea una nuova voce.</translation>
</message>
<message>
- <source>Remove this entry.</source>
- <translation>Rimuovi questa voce.</translation>
+ <source>Remove the selected entry(ies).</source>
+ <translation>Rimuovi le voci selezionate.</translation>
</message>
<message>
- <source>Copy this entry.</source>
- <translation>Copia questa voce.</translation>
+ <source>Copy the selected entry(ies).</source>
+ <translation>Copia le voci selezionate.</translation>
</message>
<message>
- <source>Move entry up.</source>
- <translation>Sposta su la voce.</translation>
+ <source>Move the selected entry(ies) up.</source>
+ <translation>Sposta le voci selezionate in alto.</translation>
</message>
<message>
- <source>Move entry down.</source>
- <translation>Sposta giù la voce.</translation>
+ <source>Move the selected entry(ies) down.</source>
+ <translation>Sposta le voci selezionate in basso.</translation>
</message>
<message>
<source>Clear all entries.</source>
@@ -12489,10 +13056,18 @@ a:hover {
<translation>Stai annusando la colla che tiene insieme Internet con Wireshark</translation>
</message>
<message>
+ <source>You are sniffing the glue that holds your system together using Logray </source>
+ <translation>Questo è il collante che tiene insieme il tuo sistema usando Logray</translation>
+ </message>
+ <message>
<source>You are running Wireshark </source>
<translation>Stai eseguendo Wireshark </translation>
</message>
<message>
+ <source>You are running Logray </source>
+ <translation>Stai eseguendo Logray</translation>
+ </message>
+ <message>
<source> You receive automatic updates.</source>
<translation> Ricevi aggiornamenti automatici.</translation>
</message>
@@ -12769,14 +13344,6 @@ a:hover {
<translation>File non trovati</translation>
</message>
<message>
- <source>&amp;Contents</source>
- <translation>&amp;Contenuti</translation>
- </message>
- <message>
- <source>Wireshark Filter</source>
- <translation>Filtro di Wireshark</translation>
- </message>
- <message>
<source>TShark</source>
<translation>TShark</translation>
</message>
@@ -12906,7 +13473,7 @@ a:hover {
</message>
<message>
<source>Export TLS Session Keys…</source>
- <translation>Esporta chiavi di sessione SSL...</translation>
+ <translation>Esporta chiavi di sessione TLS...</translation>
</message>
<message>
<source>List Files</source>
@@ -13042,10 +13609,6 @@ a:hover {
<translation>Barra degli strumenti wireless</translation>
</message>
<message>
- <source>Help contents</source>
- <translation>Contenuti della guida</translation>
- </message>
- <message>
<source>FAQs</source>
<translation>FAQ</translation>
</message>
@@ -13166,11 +13729,6 @@ a:hover {
<translation>Vai al pacchetto precedente</translation>
</message>
<message>
- <source>&amp;Mark/Unmark Packet(s)</source>
- <oldsource>&amp;Mark/Unmark Packet</oldsource>
- <translation>&amp;Marca/Deseleziona pacchetto</translation>
- </message>
- <message>
<source>Mark All Displayed</source>
<translation>Marca tutti i visualizzati</translation>
</message>
@@ -13199,11 +13757,6 @@ a:hover {
<translation>Val al prossimo pacchetto marchiato</translation>
</message>
<message>
- <source>&amp;Ignore/Unignore Packet(s)</source>
- <oldsource>&amp;Ignore/Unignore Packet</oldsource>
- <translation>&amp;Ignora/Considera pacchetto</translation>
- </message>
- <message>
<source>Ignore All Displayed</source>
<translation>Ignora tutti i visualizzati</translation>
</message>
@@ -13644,10 +14197,6 @@ a:hover {
<translation>Ripristina disposizione</translation>
</message>
<message>
- <source>Reset appearance layout to default size</source>
- <translation>Ripristina la disposizione dell&apos;aspetto alla dimensione predefinita</translation>
- </message>
- <message>
<source>Seconds Since First Captured Packet</source>
<translation>Secondi dal primo pacchetto catturato</translation>
</message>
@@ -13773,7 +14322,7 @@ a:hover {
</message>
<message>
<source>Show UTP multicast stream statistics.</source>
- <translation>Mostra le statistiche del flusso multicast UDP.</translation>
+ <translation>Mostra le statistiche del flusso multicast UTP.</translation>
</message>
<message>
<source>WLAN Traffic</source>
@@ -13808,22 +14357,30 @@ a:hover {
<translation>Blocchi di indirizzi MAC</translation>
</message>
<message>
- <source>TLS Keylog Launcher</source>
- <translation>Esecutore Keylog TLS</translation>
- </message>
- <message>
- <source>Release Notes</source>
- <translation>Note di rilascio</translation>
- </message>
- <message>
<source>&amp;Options…</source>
<translation>&amp;Opzioni...</translation>
</message>
<message>
+ <source>&amp;3GPP Uu</source>
+ <translation>&amp;3GPP Uu</translation>
+ </message>
+ <message>
<source>&amp;Wireless</source>
<translation>&amp;Wireless</translation>
</message>
<message>
+ <source>&amp;User&apos;s Guide</source>
+ <translation>Manuale &amp;utente</translation>
+ </message>
+ <message>
+ <source>Wireshark User&apos;s Guide</source>
+ <translation>Manuale utente di Wireshark</translation>
+ </message>
+ <message>
+ <source>Display Filters</source>
+ <translation>Filtri di visualizzazione</translation>
+ </message>
+ <message>
<source>Capture &amp;Filters…</source>
<translation>&amp;Filtri di cattura...</translation>
</message>
@@ -13868,10 +14425,18 @@ a:hover {
<translation>Tro&amp;va precedente</translation>
</message>
<message>
+ <source>&amp;Mark/Unmark Selected</source>
+ <translation>&amp;Marca/Deseleziona selezionati</translation>
+ </message>
+ <message>
<source>Mark or unmark each selected packet</source>
<translation>Marca o rimuovi ogni pacchetto selezionato</translation>
</message>
<message>
+ <source>&amp;Ignore/Unignore Selected</source>
+ <translation>&amp;Ignora/considera selezionati</translation>
+ </message>
+ <message>
<source>Ignore or unignore each selected packet</source>
<translation>Ignora o considera ogni pacchetto selezionato</translation>
</message>
@@ -13912,6 +14477,18 @@ a:hover {
<translation>Throughput TCP</translation>
</message>
<message>
+ <source>General</source>
+ <translation>Generale</translation>
+ </message>
+ <message>
+ <source>Query-Response</source>
+ <translation>Query-Risposta</translation>
+ </message>
+ <message>
+ <source>DNS Query-Response Statistics</source>
+ <translation>Statistiche Query-Risposta DNS</translation>
+ </message>
+ <message>
<source>Request Sequences</source>
<translation>Sequenze richiesta</translation>
</message>
@@ -13920,6 +14497,14 @@ a:hover {
<translation>Sequenze richiesta HTTP</translation>
</message>
<message>
+ <source>E2AP</source>
+ <translation>E2AP</translation>
+ </message>
+ <message>
+ <source>E2AP Messages</source>
+ <translation>Messaggi E2AP</translation>
+ </message>
+ <message>
<source>Decode &amp;As…</source>
<translation>Decodific&amp;a come...</translation>
</message>
@@ -13980,6 +14565,10 @@ a:hover {
<translation>Dimensione normale</translation>
</message>
<message>
+ <source>Reset layout to default size</source>
+ <translation>Ripristina la disposizione alla dimensione predefinita </translation>
+ </message>
+ <message>
<source>Resize Columns</source>
<translation>Ridimensiona colonne</translation>
</message>
@@ -14238,6 +14827,14 @@ a:hover {
<translation>Vai al pacchetto referenziato dal campo selezionato.</translation>
</message>
<message>
+ <source>TLS Keylog Launcher</source>
+ <translation>Esecutore Keylog TLS</translation>
+ </message>
+ <message>
+ <source>Release Notes</source>
+ <translation>Note di rilascio</translation>
+ </message>
+ <message>
<source>&amp;VoIP Calls</source>
<translation>Chiamate &amp;VoIP</translation>
</message>
@@ -14270,10 +14867,6 @@ a:hover {
<translation>&amp;GSM</translation>
</message>
<message>
- <source>&amp;LTE</source>
- <translation>&amp;LTE</translation>
- </message>
- <message>
<source>&amp;MTP3</source>
<translation>&amp;MTP3</translation>
</message>
@@ -14558,6 +15151,10 @@ a:hover {
<translation>Esci senza sal&amp;vare</translation>
</message>
<message>
+ <source>USB CDC Data</source>
+ <translation>Dati USB CDC</translation>
+ </message>
+ <message>
<source>There is no &quot;rtp.ssrc&quot; field in this version of Wireshark.</source>
<translation>Non c&apos;è alcun campo &quot;rtp.ssrc&quot; in questa versione di Wireshark.</translation>
</message>
@@ -14719,7 +15316,7 @@ a:hover {
</message>
<message>
<source>There are no TLS Session Keys to save.</source>
- <translation>Non ci sono chiavi di sessione SSL da salvare.</translation>
+ <translation>Non ci sono chiavi di sessione TLS da salvare.</translation>
</message>
<message numerus="yes">
<source>Export TLS Session Keys (%Ln key(s))</source>
diff --git a/ui/qt/wireshark_ja_JP.ts b/ui/qt/wireshark_ja_JP.ts
index 0d1e1f7f..013ad12c 100644
--- a/ui/qt/wireshark_ja_JP.ts
+++ b/ui/qt/wireshark_ja_JP.ts
@@ -44,8 +44,8 @@
<translation>フォルダ</translation>
</message>
<message>
- <source>Filter by path</source>
- <translation>パスでフィルタ</translation>
+ <source>Search Folders</source>
+ <translation>フォルダを検索</translation>
</message>
<message>
<source>Plugins</source>
@@ -80,6 +80,14 @@
<translation>ライセンス</translation>
</message>
<message>
+ <source>About Logray</source>
+ <translation>Lograyについて</translation>
+ </message>
+ <message>
+ <source>Logray</source>
+ <translation>Logray</translation>
+ </message>
+ <message>
<source>The directory does not exist</source>
<translation>ディレクトリがありません</translation>
</message>
@@ -754,6 +762,28 @@
</message>
</context>
<context>
+ <name>CaptureCommentDialog</name>
+ <message>
+ <source>Edit Capture Comments</source>
+ <translation>キャプチャコメントを編集</translation>
+ </message>
+ <message>
+ <source>Add Comment</source>
+ <translation>コメントを追加</translation>
+ </message>
+ <message>
+ <source>Section %1</source>
+ <translation>セクション %1</translation>
+ </message>
+</context>
+<context>
+ <name>CaptureCommentTabWidget</name>
+ <message>
+ <source>Comment %1</source>
+ <translation>コメント %1</translation>
+ </message>
+</context>
+<context>
<name>CaptureFile</name>
<message>
<source> [closing]</source>
@@ -859,10 +889,6 @@
<translation>読込フィルタ:</translation>
</message>
<message>
- <source>Compress with g&amp;zip</source>
- <translation>gzip形式で圧縮(&amp;z)</translation>
- </message>
- <message>
<source>Open Capture File</source>
<oldsource>Wireshark: Open Capture File</oldsource>
<translation>キャプチャファイルを開く</translation>
@@ -941,8 +967,8 @@
<translation>詳細</translation>
</message>
<message>
- <source>Capture file comments</source>
- <translation>キャプチャファイルコメント</translation>
+ <source>Edit Comments</source>
+ <translation>コメントを編集</translation>
</message>
<message>
<source>Refresh</source>
@@ -953,10 +979,6 @@
<translation>クリップボードにコピー</translation>
</message>
<message>
- <source>Save Comments</source>
- <translation>コメントを保存</translation>
- </message>
- <message>
<source>Capture File Properties</source>
<translation>キャプチャファイルプロパティ</translation>
</message>
@@ -1005,10 +1027,18 @@
<translation>最初のパケット</translation>
</message>
<message>
+ <source>First event</source>
+ <translation>最初のイベント</translation>
+ </message>
+ <message>
<source>Last packet</source>
<translation>最後のパケット</translation>
</message>
<message>
+ <source>Last event</source>
+ <translation>最後のイベント</translation>
+ </message>
+ <message>
<source>Elapsed</source>
<translation>経過時間</translation>
</message>
@@ -1045,6 +1075,10 @@
<translation>欠落したパケット</translation>
</message>
<message>
+ <source>Dropped events</source>
+ <translation>欠落したイベント</translation>
+ </message>
+ <message>
<source>Capture filter</source>
<translation>キャプチャフィルタ</translation>
</message>
@@ -1057,6 +1091,10 @@
<translation>パケットサイズ制限(snaplen)</translation>
</message>
<message>
+ <source>Event size limit (snaplen)</source>
+ <translation>イベントサイズ制限(snaplen)</translation>
+ </message>
+ <message>
<source>none</source>
<translation>なし</translation>
</message>
@@ -1065,6 +1103,26 @@
<translation>%1 バイト</translation>
</message>
<message>
+ <source>Comments</source>
+ <translation>コメント</translation>
+ </message>
+ <message>
+ <source>Comment %1: </source>
+ <translation>コメント %1:</translation>
+ </message>
+ <message>
+ <source>Decryption Secrets</source>
+ <translation>復号化シークレット</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>種別</translation>
+ </message>
+ <message>
+ <source>Size</source>
+ <translation>サイズ</translation>
+ </message>
+ <message>
<source>Statistics</source>
<translation>統計</translation>
</message>
@@ -1089,6 +1147,10 @@
<translation>パケット数</translation>
</message>
<message>
+ <source>Events</source>
+ <translation>イベント</translation>
+ </message>
+ <message>
<source>Time span, s</source>
<translation>時間間隔,秒</translation>
</message>
@@ -1101,6 +1163,10 @@
<translation>平均パケットサイズ,バイト</translation>
</message>
<message>
+ <source>Average event size, B</source>
+ <translation>平均イベントサイズ,バイト</translation>
+ </message>
+ <message>
<source>Bytes</source>
<translation>バイト数</translation>
</message>
@@ -1113,14 +1179,14 @@
<translation>平均ビット数毎秒</translation>
</message>
<message>
- <source>Section Comment</source>
- <translation>セクション コメント</translation>
- </message>
- <message>
<source>Packet Comments</source>
<translation>パケットコメント</translation>
</message>
<message>
+ <source>Event Comments</source>
+ <translation>イベント コメント</translation>
+ </message>
+ <message>
<source>&lt;p&gt;Frame %1: </source>
<translation>&lt;p&gt;フレーム %1: </translation>
</message>
@@ -1132,6 +1198,14 @@
</translation>
</message>
+ <message>
+ <source>Created by Logray %1
+
+</source>
+ <translation>Logray %1 によって作成されました
+
+</translation>
+ </message>
</context>
<context>
<name>CaptureFilterCombo</name>
@@ -1358,6 +1432,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>(時計の)時刻が特定の間隔になったら次のファイルに切り替えます。例えば、1時間に設定すると毎時1時間ごとに新しいファイルが作成されます</translation>
</message>
<message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for some more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;通常、無線 ネットワークカードは自身のネットワークアドレスに送受信されるトラフィックのみキャプチャして、&amp;quot;偽の&amp;quot; Ethernetヘッダで &lt;em&gt;ユーザデータ&lt;/em&gt; トラフィックのみ取得します。もし無線ネットワークカードが&amp;quot;見える&amp;quot;すべてのトラフィックをキャプチャしたい、802.11管理や制御パケットや無線の物理層のヘッダ情報に興味がある場合にはこのオプションをマークしてください。モニターモードが利用できるかは無線カードとドライバに依存します。無線ネットワークに関してのパケットキャプチャのさらなる詳細についてはWikiを参照ください。&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>Enable monitor mode on all 802.11 interfaces</source>
+ <translation>すべての802.11インターフェースにおいてモニターモードを有効化します</translation>
+ </message>
+ <message>
<source>compression</source>
<translation>圧縮</translation>
</message>
@@ -1370,6 +1452,30 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>gzip</translation>
</message>
<message>
+ <source>File infix pattern</source>
+ <translation>ファイルinfixパターン</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;In multiple file mode, the date and time and file index number are inserted between filename template and any suffix. Select their order.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;複数ファイルモードにおいては、日付、時間とファイルインデックス番号がファイル名テンプレートとサフィックスの間に挿入されます。順番を選択してください。&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>YYYYmmDDHHMMSS_NNNNN</source>
+ <translation>YYYYmmDDHHMMSS_NNNNN</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Date and time before the file index number. This causes files to sort in creation time order, and keeps files from the same batch closely ordered.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;ファイルインデックス番号の前に日付と時刻を示します。これによりファイルは作成時fの順序でソートされ、同じバッチのファイルが近くに配置されます。&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>NNNNN_YYYYmmDDHHMMSS</source>
+ <translation>NNNNN_YYYYmmDDHHMMSS</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;File index number before the date and time. This is the historic Wireshark ordering.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;日付と時刻の前にファイルインデックスを示します。これは歴史的なWiresharkの順序です。&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;After capturing has switched to the next file and the given number of files has exceeded, the oldest file will be removed.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;キャプチャが次のファイルに切り替えられた後、与えられたファイル数を超過したら、最も古いファイルが消されます&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1458,6 +1564,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;指定した数のファイルを作成した後キャプチャを停止します&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
+ <source>Stop capturing after the specified number of files have been created.</source>
+ <translation>指定したファイル数が作成された後にキャプチャを停止します</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Stop capturing after the specified amount of data has been captured.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;指定した量のデータがキャプチャされたらキャプチャを停止します&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1518,8 +1628,8 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>エラー</translation>
</message>
<message>
- <source>Multiple files: Requested filesize too large. The filesize cannot be greater than 2 GiB.</source>
- <translation>複数ファイル:要求されたファイルサイズが大きすぎます。ファイルサイズは2GBより大きくできません</translation>
+ <source>Multiple files: Requested filesize too large. The filesize cannot be greater than 2 TB.</source>
+ <translation>複数ファイル:要求されたファイルサイズが大きすぎます。ファイルサイズは2テラバイトより大きくできません</translation>
</message>
<message>
<source>Multiple files: No capture file name given. You must specify a filename if you want to use multiple files.</source>
@@ -1549,6 +1659,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>プロミスキャスモードでパケットをキャプチャ</translation>
</message>
<message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;通常、無線 ネットワークカードは自身のネットワークアドレスに送受信されるトラフィックのみキャプチャして、&amp;quot;偽の&amp;quot; Ethernetヘッダで &lt;em&gt;ユーザデータ&lt;/em&gt; トラフィックのみ取得します。もし無線ネットワークカードが&amp;quot;見える&amp;quot;すべてのトラフィックをキャプチャしたい、802.11管理や制御パケットや無線の物理層のヘッダ情報に興味がある場合にはこのオプションをマークしてください。モニターモードが利用できるかは無線カードとドライバに依存します。無線ネットワークに関してのパケットキャプチャのさらなる詳細についてはWikiを参照ください。&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>Capture packets in monitor mode on 802.11 devices</source>
+ <translation>802.11デバイスにおいてモニターモードでパケットをキャプチャします</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Capture packets in the next-generation capture file format.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;次世代のキャプチャファイル形式でパケットをキャプチャします&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1776,6 +1894,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>解決済</translation>
</message>
<message>
+ <source>Width</source>
+ <translation>幅</translation>
+ </message>
+ <message>
+ <source>Alignment</source>
+ <translation>揃え</translation>
+ </message>
+ <message>
<source>&lt;html&gt;Show human-readable strings instead of raw values for fields. Only applicable to custom columns with fields that have value strings.&lt;/html&gt;</source>
<translation>&lt;html&gt;123raw(無加工)のフィールド値の代わりに人が読むことのできる文字列を表示します。有効な文字列を含むフィールドを持つカスタム列へ適用する場合にのみ適用できます。&lt;/html&gt;</translation>
</message>
@@ -1823,6 +1949,25 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>CompressionGroupBox</name>
+ <message>
+ <source>Compression options</source>
+ <translation>圧縮オプション</translation>
+ </message>
+ <message>
+ <source>&amp;Uncompressed</source>
+ <translation>非圧縮(&amp;U)</translation>
+ </message>
+ <message>
+ <source>Compress with g&amp;zip</source>
+ <translation>gzip形式で圧縮(&amp;z)</translation>
+ </message>
+ <message>
+ <source>Compress with &amp;LZ4</source>
+ <translation>LZ4形式で圧縮(&amp;L)</translation>
+ </message>
+</context>
+<context>
<name>ConversationDataModel</name>
<message>
<source>Address A</source>
@@ -1889,6 +2034,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>ビット毎秒 B</translation>
</message>
<message>
+ <source>Flows</source>
+ <translation>フロー</translation>
+ </message>
+ <message>
<source>Total Packets</source>
<translation>全パケット</translation>
</message>
@@ -2003,14 +2152,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>16進数ダンプとしてパケットバイト列をコピー</translation>
</message>
<message>
- <source>…as Printable Text</source>
- <translation>印刷可能なテキストとして…</translation>
- </message>
- <message>
- <source>Copy only the printable text in the packet.</source>
- <translation>パケット内の印刷可能なテキストだけをコピー</translation>
- </message>
- <message>
<source>…as MIME Data</source>
<translation>MIMEデータとして...</translation>
</message>
@@ -2023,10 +2164,42 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>印刷可能なASCII文字とエスケープシーケンスとしてパケットバイト列をコピー</translation>
</message>
<message>
+ <source>…as Go literal</source>
+ <translation>…Go 言語のリテラルとして</translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as Go literal.</source>
+ <translation>Go言語のリテラルとしてパケットバイト列をコピーします。</translation>
+ </message>
+ <message>
+ <source>…as C Array</source>
+ <translation>…C言語配列として</translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as C Array.</source>
+ <translation>C言語配列としてパケットバイト列をコピーします。</translation>
+ </message>
+ <message>
<source>…as a Hex Stream</source>
<translation>16進数ストリームとして…</translation>
</message>
<message>
+ <source>…as UTF-8 Text</source>
+ <translation>…UTF-8テキストとして</translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as text, treating as UTF-8.</source>
+ <translation>UTF-8として扱ってパケットバイト列をテキストとしてコピーします</translation>
+ </message>
+ <message>
+ <source>…as ASCII Text</source>
+ <translation>ASCII形式テキストとして…</translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as text, treating as ASCII.</source>
+ <translation>ASCII形式として扱ってパケットバイト列をテキストとしてコピーします</translation>
+ </message>
+ <message>
<source>Copy packet bytes as a stream of hex.</source>
<translation>16進数ストリームとしてパケットバイト列をコピー</translation>
</message>
@@ -2822,6 +2995,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Display filter:</source>
<translation>表示フィルタ:</translation>
</message>
+ <message>
+ <source>Export PDUs</source>
+ <translation>PDUをエクスポート</translation>
+ </message>
</context>
<context>
<name>ExtArgSelector</name>
@@ -2861,10 +3038,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>開始</translation>
</message>
<message>
- <source>Save</source>
- <translation>保存</translation>
- </message>
- <message>
<source>Default</source>
<translation>デフォルト</translation>
</message>
@@ -3005,6 +3178,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>表示フィルタ</translation>
</message>
<message>
+ <source>Display Filter Macros</source>
+ <translation>表示フィルタマクロ</translation>
+ </message>
+ <message>
+ <source>New macro</source>
+ <translation>新規マクロ</translation>
+ </message>
+ <message>
<source>Open </source>
<translation>開く </translation>
</message>
@@ -3088,10 +3269,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>FilterListModel</name>
<message>
+ <source>Macro Name</source>
+ <translation>マクロ名</translation>
+ </message>
+ <message>
<source>Filter Name</source>
<translation>フィルタ名</translation>
</message>
<message>
+ <source>Macro Expression</source>
+ <translation>マクロ式</translation>
+ </message>
+ <message>
<source>Filter Expression</source>
<translation>フィルタ式</translation>
</message>
@@ -3177,22 +3366,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>FolderListModel</name>
<message>
- <source>&quot;File&quot; dialogs</source>
- <translation>&quot;ファイル&quot; ダイアログ</translation>
- </message>
- <message>
- <source>capture files</source>
- <translation>キャプチャファイル</translation>
- </message>
- <message>
<source>Temp</source>
<translation>一時的</translation>
</message>
<message>
- <source>untitled capture files</source>
- <translation>名称未設定キャプチャファイル</translation>
- </message>
- <message>
<source>Personal configuration</source>
<translation>個人設定</translation>
</message>
@@ -3201,14 +3378,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>グローバル設定</translation>
</message>
<message>
- <source>dfilters, preferences, ethers, …</source>
- <translation>dfilters, preferences, ethers, …</translation>
- </message>
- <message>
- <source>dfilters, preferences, manuf, …</source>
- <translation>dfilters, preferences, manuf, …</translation>
- </message>
- <message>
<source>System</source>
<translation>システム</translation>
</message>
@@ -3221,18 +3390,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>プログラム</translation>
</message>
<message>
- <source>program files</source>
- <translation>プログラムファイル</translation>
- </message>
- <message>
<source>Personal Plugins</source>
<translation>個人プラグイン</translation>
</message>
<message>
- <source>binary plugins</source>
- <translation>バイナリプラグイン</translation>
- </message>
- <message>
<source>Global Plugins</source>
<translation>グローバルプラグイン</translation>
</message>
@@ -3249,11 +3410,35 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Luaスクリプト</translation>
</message>
<message>
+ <source>&quot;File&quot; dialog location</source>
+ <translation>&quot;ファイル&quot; ダイアログの場所</translation>
+ </message>
+ <message>
+ <source>Capture files</source>
+ <translation>キャプチャファイル</translation>
+ </message>
+ <message>
+ <source>Untitled capture files</source>
+ <translation>名称未設定キャプチャファイル</translation>
+ </message>
+ <message>
+ <source>Preferences, profiles, manuf, …</source>
+ <translation>設定, プロファイル, manuf, …</translation>
+ </message>
+ <message>
+ <source>Program files</source>
+ <translation>プログラムファイル</translation>
+ </message>
+ <message>
+ <source>Binary plugins</source>
+ <translation>バイナリプラグイン</translation>
+ </message>
+ <message>
<source>Personal Extcap path</source>
<translation>個人Extcapパス</translation>
</message>
<message>
- <source>external capture (extcap) plugins</source>
+ <source>External capture (extcap) plugins</source>
<translation>外部キャプチャ(extcap)プラグイン</translation>
</message>
<message>
@@ -3386,6 +3571,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</translation>
</message>
<message>
+ <source>Event %1. </source>
+ <translation>イベント %1 </translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;reads&lt;/span&gt;, </source>
+ <translation>
+ <numerusform>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;読み取り&lt;/span&gt;, </numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;writes&lt;/span&gt;, </source>
+ <translation>
+ <numerusform>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;書き込み&lt;/span&gt;, </numerusform>
+ </translation>
+ </message>
+ <message>
<source> Click to select.</source>
<translation>クリックして選択します</translation>
</message>
@@ -3418,6 +3619,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>選択したパケットに %1 ストリームは見つかりませんでした</translation>
</message>
<message>
+ <source>Read activity(%6)</source>
+ <translation>読み取りアクティビティ(%6)</translation>
+ </message>
+ <message>
+ <source>Write activity(%6)</source>
+ <translation>書き込みアクティビティ(%6)</translation>
+ </message>
+ <message>
+ <source>Entire I/O activity (%1)</source>
+ <translation>全体のI/Oアクティビティ(%1)</translation>
+ </message>
+ <message>
<source>Entire conversation (%1)</source>
<translation>全体の対話 (%1)</translation>
</message>
@@ -3433,10 +3646,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Save Stream Content As…</source>
<translation>…としてストリーム内容を保存</translation>
</message>
- <message>
- <source>[Stream output truncated]</source>
- <translation>[ストリーム出力が切り詰められました]</translation>
- </message>
<message numerus="yes">
<source>%Ln total stream(s).</source>
<translation>
@@ -3462,9 +3671,20 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>ヒント</translation>
</message>
<message>
- <source>Show data as</source>
- <oldsource>Show and save data as</oldsource>
- <translation>としてデータを表示</translation>
+ <source>Show as</source>
+ <translation>として表示</translation>
+ </message>
+ <message>
+ <source>No delta times</source>
+ <translation>デルタ時間なし</translation>
+ </message>
+ <message>
+ <source>Turn delta times</source>
+ <translation>ターンデルタ時間</translation>
+ </message>
+ <message>
+ <source>All delta times</source>
+ <translation>全デルタ時間</translation>
</message>
<message>
<source>Stream</source>
@@ -3479,11 +3699,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>検索:</translation>
</message>
<message>
+ <source>Case sensitive</source>
+ <translation>大文字小文字を区別</translation>
+ </message>
+ <message>
<source>Find &amp;Next</source>
<translation>次を検索(&amp;N)</translation>
</message>
</context>
<context>
+ <name>FollowStreamText</name>
+ <message>
+ <source>[Stream output truncated]</source>
+ <translation>[ストリーム出力が切り詰められました]</translation>
+ </message>
+</context>
+<context>
<name>FontColorPreferencesFrame</name>
<message>
<source>Frame</source>
@@ -3819,29 +4050,28 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <source>Remove this graph.</source>
- <oldsource>Remove this dissection behavior.</oldsource>
- <translation>このグラフを削除します</translation>
- </message>
- <message>
<source>Add a new graph.</source>
<translation>新規グラフを追加します</translation>
</message>
<message>
- <source>Duplicate this graph.</source>
- <translation>このグラフを複製します</translation>
- </message>
- <message>
<source>Clear all graphs.</source>
<translation>すべてのグラフをクリア</translation>
</message>
<message>
- <source>Move this graph upwards.</source>
- <translation>このグラフを上に移動します</translation>
+ <source>Remove the selected graph(s).</source>
+ <translation>選択したグラフを削除します</translation>
</message>
<message>
- <source>Move this graph downwards.</source>
- <translation>このグラフを下に移動します</translation>
+ <source>Duplicate the selected graph(s).</source>
+ <translation>選択したグラフを複製します</translation>
+ </message>
+ <message>
+ <source>Move the selected graph(s) upwards.</source>
+ <translation>選択したグラフを上に移動します</translation>
+ </message>
+ <message>
+ <source>Move the selected graph(s) downwards.</source>
+ <translation>選択したグラフを下に移動します</translation>
</message>
<message>
<source>Mouse</source>
@@ -3884,10 +4114,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>凡例を有効化</translation>
</message>
<message>
- <source>Reset</source>
- <translation>リセット</translation>
- </message>
- <message>
<source>Reset Graph</source>
<translation>グラフをリセット</translation>
</message>
@@ -4101,6 +4327,42 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>別のプロファイルからグラフをコピーします</translation>
</message>
<message>
+ <source>1 μs</source>
+ <translation>1マイクロ秒</translation>
+ </message>
+ <message>
+ <source>2 μs</source>
+ <translation>2マイクロ秒</translation>
+ </message>
+ <message>
+ <source>5 μs</source>
+ <translation>5マイクロ秒</translation>
+ </message>
+ <message>
+ <source>10 μs</source>
+ <translation>10マイクロ秒</translation>
+ </message>
+ <message>
+ <source>20 μs</source>
+ <translation>20マイクロ秒</translation>
+ </message>
+ <message>
+ <source>50 μs</source>
+ <translation>50マイクロ秒</translation>
+ </message>
+ <message>
+ <source>100 μs</source>
+ <translation>100マイクロ秒</translation>
+ </message>
+ <message>
+ <source>200 μs</source>
+ <translation>200マイクロ秒</translation>
+ </message>
+ <message>
+ <source>500 μs</source>
+ <translation>500マイクロ秒</translation>
+ </message>
+ <message>
<source>1 ms</source>
<translation>1ミリ秒</translation>
</message>
@@ -4145,6 +4407,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>5 秒</translation>
</message>
<message>
+ <source>2 min</source>
+ <translation>2分</translation>
+ </message>
+ <message>
+ <source>5 min</source>
+ <translation>5分</translation>
+ </message>
+ <message>
<source>Wireshark I/O Graphs: %1</source>
<translation>Wireshark入出力グラフ: %1</translation>
</message>
@@ -4157,6 +4427,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>フィルタされたイベント</translation>
</message>
<message>
+ <source>All packets</source>
+ <translation>すべてのパケット</translation>
+ </message>
+ <message>
+ <source>All events</source>
+ <translation>すべてのイベント</translation>
+ </message>
+ <message>
<source>All Packets</source>
<translation>すべてのパケット</translation>
</message>
@@ -4169,8 +4447,8 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>すべてのイベント</translation>
</message>
<message>
- <source>Access Denied</source>
- <translation>アクセス拒否</translation>
+ <source>All Execs</source>
+ <translation>全ての Execs</translation>
</message>
<message>
<source>Hover over the graph for details.</source>
@@ -4217,6 +4495,34 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>クリックしてグラフの割合を選びます</translation>
</message>
<message>
+ <source>%1 Intervals </source>
+ <translation>%1 インターバル</translation>
+ </message>
+ <message>
+ <source>Move to top left</source>
+ <translation>左上に移動</translation>
+ </message>
+ <message>
+ <source>Move to top center</source>
+ <translation>中央上に移動</translation>
+ </message>
+ <message>
+ <source>Move to top right</source>
+ <translation>右上に移動</translation>
+ </message>
+ <message>
+ <source>Move to bottom left</source>
+ <translation>左下に移動</translation>
+ </message>
+ <message>
+ <source>Move to bottom center</source>
+ <translation>中央下に移動</translation>
+ </message>
+ <message>
+ <source>Move to bottom right</source>
+ <translation>右下に移動</translation>
+ </message>
+ <message>
<source>Portable Document Format (*.pdf)</source>
<translation>PDF形式 (*.pdf)</translation>
</message>
@@ -4912,7 +5218,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>&lt;p&gt;Local interfaces are unavailable because the packet capture driver isn&apos;t loaded.&lt;/p&gt;&lt;p&gt;You can fix this by running &lt;pre&gt;net start npcap&lt;/pre&gt; if you have Npcap installed or &lt;pre&gt;net start npf&lt;/pre&gt; if you have WinPcap installed. Both commands must be run as Administrator.&lt;/p&gt;</source>
- <translation>&lt;p&gt;キャプチャドライバが読み込まれていないためローカル印ーフェースは利用できません。&lt;/p&gt;&lt;p&gt;以下を実行することで修正することができます。 もしNpcapをインストールした場合、&lt;pre&gt;net start npcap&lt;/pre&gt; もしWinPcapをインストールした場合、&lt;pre&gt;net start npf&lt;/pre&gt; 両方のコマンドは管理者権限として実行する必要があります。&lt;/p&gt;</translation>
+ <translation>&lt;p&gt;キャプチャドライバが読み込まれていないためローカルインターフェースは利用できません。&lt;/p&gt;&lt;p&gt;以下を実行することで修正することができます。 もしNpcapをインストールした場合、&lt;pre&gt;net start npcap&lt;/pre&gt; もしWinPcapをインストールした場合、&lt;pre&gt;net start npf&lt;/pre&gt; 両方のコマンドは管理者権限として実行する必要があります。&lt;/p&gt;</translation>
</message>
<message>
<source>&lt;p&gt;You don&apos;t have permission to capture on local interfaces.&lt;/p&gt;&lt;p&gt;You can fix this by &lt;a href=&quot;file://%1&quot;&gt;installing ChmodBPF&lt;/a&gt;.&lt;/p&gt;</source>
@@ -4969,6 +5275,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>InterfaceTreeDelegate</name>
+ <message>
+ <source>default</source>
+ <translation>デフォルト</translation>
+ </message>
+</context>
+<context>
<name>InterfaceTreeModel</name>
<message>
<source>Show</source>
@@ -5943,8 +6256,8 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>LteMacStatisticsDialog</name>
<message>
- <source>LTE Mac Statistics</source>
- <translation>LTE MAC統計</translation>
+ <source>LTE/NR Mac Statistics</source>
+ <translation>LTE/NR Mac 統計</translation>
</message>
<message>
<source>Include SR frames in filter</source>
@@ -6252,12 +6565,12 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>シーケンス番号</translation>
</message>
<message>
- <source>LTE RLC Graph (UE=%1 chan=%2%3 %4 - %5)</source>
- <translation>LTE RLCグラフ (UE=%1 chan=%2%3 %4 - %5)</translation>
+ <source>%1 RLC Graph (UE=%2 chan=%3%4 %5 - %6)</source>
+ <translation>%1 RLC グラフ (UE=%2 chan=%3%4 %5 - %6)</translation>
</message>
<message>
- <source>LTE RLC Graph - no channel selected</source>
- <translation>LTE RLCグラフ - チャンネルが選択されていません</translation>
+ <source>3GPP RLC Graph - no channel selected</source>
+ <translation>3GPP RLC グラフ - チャンネルが選択されていません</translation>
</message>
<message>
<source>Save As…</source>
@@ -6311,8 +6624,8 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>LteRlcStatisticsDialog</name>
<message>
- <source>LTE RLC Statistics</source>
- <translation>LTE RLC統計</translation>
+ <source>3GPP RLC Statistics</source>
+ <translation>3GPP RLC 統計</translation>
</message>
<message>
<source>Include SR frames in filter</source>
@@ -6398,6 +6711,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>プロファイル: %1</translation>
</message>
<message>
+ <source> %1 Displayed: %2 (%3%)</source>
+ <translation> %1 表示: %2 (%3%)</translation>
+ </message>
+ <message>
<source>Manage Profiles…</source>
<translation>プロファイルの管理...</translation>
</message>
@@ -6458,6 +6775,12 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<numerusform>%Ln バイト</numerusform>
</translation>
</message>
+ <message numerus="yes">
+ <source>%Ln bit(s)</source>
+ <translation>
+ <numerusform>%Ln ビット</numerusform>
+ </translation>
+ </message>
<message>
<source>Byte %1</source>
<translation>%1 バイト</translation>
@@ -6471,9 +6794,12 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>選択されたパケット: %1 %2 </translation>
</message>
<message>
- <source>Packets: %1 %4 Displayed: %2 (%3%)</source>
- <oldsource>Packets: %1 %4 Displayed: %2 %4 Marked: %3</oldsource>
- <translation>パケット数: %1 %4 表示: %2 (%3%)</translation>
+ <source>Selected Event: %1 %2 </source>
+ <translation>選択したイベント: %1 %2 </translation>
+ </message>
+ <message>
+ <source>Events: %1</source>
+ <translation>イベント: %1</translation>
</message>
<message>
<source> %1 Selected: %2 (%3%)</source>
@@ -6505,6 +6831,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>パケットなし</translation>
</message>
<message>
+ <source>No Events</source>
+ <translation>イベントなし</translation>
+ </message>
+ <message>
<source>From Zip File...</source>
<translation>Zipファイルより...</translation>
</message>
@@ -6536,6 +6866,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>MainWindow</name>
+ <message>
+ <source>Display filter as %1</source>
+ <translation>%1 として表示フィルタ</translation>
+ </message>
+</context>
+<context>
<name>MainWindowPreferencesFrame</name>
<message>
<source>Frame</source>
@@ -6567,6 +6904,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>一番最近に使ったフォルダ</translation>
</message>
<message>
+ <source>The current working directory</source>
+ <translation>現在の稼働ディレクトリ</translation>
+ </message>
+ <message>
<source>Show up to</source>
<translation>ここまで表示</translation>
</message>
@@ -6997,6 +7338,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>フィールド値を表示</translation>
</message>
<message>
+ <source>Refresh</source>
+ <translation>更新</translation>
+ </message>
+ <message>
<source>Save Diagram As…</source>
<translation>…としてダイアグラムを保存</translation>
</message>
@@ -7044,6 +7389,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>パケットバイト列を表示</translation>
</message>
<message>
+ <source>Layout:</source>
+ <translation>レイアウト:</translation>
+ </message>
+ <message>
<source>Packet %1</source>
<translation>パケット %1</translation>
</message>
@@ -7065,6 +7414,12 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<numerusform>%Ln バイト</numerusform>
</translation>
</message>
+ <message numerus="yes">
+ <source>%Ln bit(s)</source>
+ <translation>
+ <numerusform>%Ln ビット</numerusform>
+ </translation>
+ </message>
</context>
<context>
<name>PacketFormatGroupBox</name>
@@ -7524,10 +7879,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>このプロファイルをコピーします</translation>
</message>
<message>
+ <source>The number of packets or events to check for automatic profile switching.</source>
+ <translation>自動プロファイルスイッチのためのパケットやイベントの数</translation>
+ </message>
+ <message>
+ <source>Auto switch packet limit</source>
+ <translation>自動スイッチパケット限度</translation>
+ </message>
+ <message>
<source>Configuration Profiles</source>
<translation>設定プロファイル</translation>
</message>
<message>
+ <source>Auto switch event limit</source>
+ <translation>自動スイッチイベント限度</translation>
+ </message>
+ <message>
<source>Import</source>
<comment>noun</comment>
<translation>インポート</translation>
@@ -7703,6 +8070,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>削除済</translation>
</message>
<message>
+ <source>Auto Switch Filter</source>
+ <translation>自動スイッチフィルタ</translation>
+ </message>
+ <message>
<source>copy</source>
<comment>noun</comment>
<translation>コピー</translation>
@@ -8062,6 +8433,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>ウインドウサイズ(バイト)</translation>
</message>
<message>
+ <source>Unacked (Outstanding) Bytes (B)</source>
+ <translation>ACKされていない(未処理の)バイト(B)</translation>
+ </message>
+ <message>
<source>[no capture file]</source>
<translation>[キャプチャファイルなし]</translation>
</message>
@@ -8222,6 +8597,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>マーカー欠如?</translation>
</message>
<message>
+ <source>LTE</source>
+ <translation>LTE</translation>
+ </message>
+ <message>
+ <source>NR</source>
+ <translation>NR</translation>
+ </message>
+ <message>
<source>C-RNTI</source>
<translation>C-RNTI</translation>
</message>
@@ -8242,6 +8625,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>UEId</translation>
</message>
<message>
+ <source>RAT</source>
+ <translation>RAT</translation>
+ </message>
+ <message>
<source>UL Frames</source>
<translation>UL フレーム</translation>
</message>
@@ -8465,9 +8852,69 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Browse…</source>
<translation>参照…</translation>
</message>
+ <message>
+ <source>PACKETS</source>
+ <translation>パケット</translation>
+ </message>
+ <message>
+ <source>EVENTS</source>
+ <translation>イベント</translation>
+ </message>
+ <message>
+ <source>BYTES</source>
+ <translation>バイト</translation>
+ </message>
+ <message>
+ <source>BITS</source>
+ <translation>ビット</translation>
+ </message>
+ <message>
+ <source>COUNT FRAMES</source>
+ <translation>フレーム数</translation>
+ </message>
+ <message>
+ <source>COUNT FIELDS</source>
+ <translation>フィールド数</translation>
+ </message>
+ <message>
+ <source>SUM</source>
+ <translation>合計</translation>
+ </message>
+ <message>
+ <source>MAX</source>
+ <translation>最大</translation>
+ </message>
+ <message>
+ <source>MIN</source>
+ <translation>最小</translation>
+ </message>
+ <message>
+ <source>AVERAGE</source>
+ <translation>平均</translation>
+ </message>
+ <message>
+ <source>THROUGHPUT</source>
+ <translation>スループット</translation>
+ </message>
+ <message>
+ <source>LOAD</source>
+ <translation>読込</translation>
+ </message>
+ <message>
+ <source>Left</source>
+ <translation>左</translation>
+ </message>
+ <message>
+ <source>Center</source>
+ <translation>中央</translation>
+ </message>
+ <message>
+ <source>Right</source>
+ <translation>右</translation>
+ </message>
</context>
<context>
- <name>QObject::QObject</name>
+ <name>QObject::QObject::QObject</name>
<message>
<source>CCCH</source>
<translation>CCCH</translation>
@@ -8568,6 +9015,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>ResizeHeaderView</name>
+ <message>
+ <source>Resize all %1 to contents</source>
+ <translation>全ての %1 を内容に合わせてリサイズします</translation>
+ </message>
+</context>
+<context>
<name>ResolvedAddressesDialog</name>
<message>
<source>Dialog</source>
@@ -8683,6 +9137,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>解決したアドレス</translation>
</message>
<message>
+ <source>Copy</source>
+ <translation>コピー</translation>
+ </message>
+ <message>
+ <source>Save as…</source>
+ <translation>…として保存</translation>
+ </message>
+ <message>
<source># Resolved addresses found in %1</source>
<translation># %1 に解決したアドレスが見つかりました</translation>
</message>
@@ -8696,6 +9158,61 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>ResolvedAddressesView</name>
+ <message>
+ <source>as Plain Text</source>
+ <translation>プレインテキストとして</translation>
+ </message>
+ <message>
+ <source>Copy selected rows</source>
+ <translation>選択した行をコピー</translation>
+ </message>
+ <message>
+ <source>Copy table</source>
+ <translation>表をコピー</translation>
+ </message>
+ <message>
+ <source>as CSV</source>
+ <translation>CSVとして</translation>
+ </message>
+ <message>
+ <source>as JSON</source>
+ <translation>JSONとして</translation>
+ </message>
+ <message>
+ <source>Save selected rows as…</source>
+ <translation>選択した行を…として保存</translation>
+ </message>
+ <message>
+ <source>Save table as…</source>
+ <translation>…として表を保存</translation>
+ </message>
+ <message>
+ <source>Save Resolved Addresses As…</source>
+ <translation>…として解決したアドレスを保存</translation>
+ </message>
+ <message>
+ <source>Plain text (*.txt)</source>
+ <translation>プレインテキスト (*.txt)</translation>
+ </message>
+ <message>
+ <source>CSV Document (*.csv)</source>
+ <translation>CSV書類 (*.csv)</translation>
+ </message>
+ <message>
+ <source>JSON Document (*.json)</source>
+ <translation>JSON書類 (*.json)</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>警告</translation>
+ </message>
+ <message>
+ <source>Unable to save %1: %2</source>
+ <translation>%1を保存できません: %2</translation>
+ </message>
+</context>
+<context>
<name>ResponseTimeDelayDialog</name>
<message>
<source>%1 Response Time Delay Statistics</source>
@@ -10370,6 +10887,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>パケットバイト列</translation>
</message>
<message>
+ <source>&lt;b&gt;Options:&lt;/b&gt;</source>
+ <translation>&lt;b&gt;オプション:&lt;/b&gt;</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for strings containing narrow (UTF-8 and ASCII) or wide (UTF-16) characters.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;ナロー文字列 (UTF-8とASCII)もしくはワイド(UTF-16)文字を検索&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -10390,6 +10911,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>大文字小文字を区別</translation>
</message>
<message>
+ <source>Backwards</source>
+ <translation>戻る</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for a subsequent occurrence in the current packet before advancing to the next packet.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;次のパケットへ進む前に現在のパケットの中で続いて起こるフィールド値を検索します。&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>Multiple occurrences</source>
+ <translation>複数発生するフィールド値</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5), a plain string (e.g. My String) or a regular expression (e.g. colou?r).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<oldsource>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5) or a plain string (e.g. My String).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</oldsource>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;表示フィルタ構文(例 ip.addr==10.1.1.1),16数文字列(例 ffffda5),平文文字列(例 My String)もしくは正規表現(例 colou?r)を用いてデータを検索しますt;/body&gt;&lt;/html&gt;</translation>
@@ -10427,6 +10960,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>無効なフィルタです</translation>
</message>
<message>
+ <source>Event List</source>
+ <translation>イベントリスト</translation>
+ </message>
+ <message>
+ <source>Event Details</source>
+ <translation>イベント詳細</translation>
+ </message>
+ <message>
+ <source>Event Bytes</source>
+ <translation>イベントバイト数</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search the Info column of the event list (summary pane), decoded event display labels (tree view pane) or the ASCII-converted event data (hex view pane).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;イベント一覧(概要部分)やデコードされたイベント表示ラベル(ツリー表示部分)やアスキー変換されたイベントデータ(16進数表示部分)を検索します&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
<source>That filter doesn&apos;t test anything.</source>
<translation>そのフィルタは何も検査しません</translation>
</message>
@@ -10849,7 +11398,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Decode as</source>
- <translation>としてでコード</translation>
+ <translation>としてデコード</translation>
</message>
<message>
<source>Show as</source>
@@ -10868,6 +11417,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>検索:</translation>
</message>
<message>
+ <source>Case sensitive</source>
+ <translation>大文字小文字を区別</translation>
+ </message>
+ <message>
<source>Find &amp;Next</source>
<translation>次を検索</translation>
</message>
@@ -10962,13 +11515,21 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>…として保存</translation>
</message>
<message>
+ <source>Decoded as %1.</source>
+ <translation>%1 としてデコードされました</translation>
+ </message>
+ <message>
<source>Save Selected Packet Bytes As…</source>
<translation>…として選択したパケットバイト列を保存</translation>
</message>
+ <message>
+ <source>compressed %1</source>
+ <translation>%1 を圧縮しました</translation>
+ </message>
<message numerus="yes">
- <source>Displaying %Ln byte(s).</source>
+ <source>Using %Ln byte(s).</source>
<translation>
- <numerusform>%Ln バイトを表示中</numerusform>
+ <numerusform>%Ln バイトを利用</numerusform>
</translation>
</message>
<message>
@@ -11068,6 +11629,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Display filter:</source>
<translation>表示フィルタ:</translation>
</message>
+ <message>
+ <source>Strip Headers</source>
+ <translation>ヘッダーを除去</translation>
+ </message>
</context>
<context>
<name>SupportedProtocolsDialog</name>
@@ -12041,22 +12606,20 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>新規エントリを作成します</translation>
</message>
<message>
- <source>Remove this entry.</source>
- <oldsource>Remove this profile.</oldsource>
- <translation>このエントリを削除します</translation>
+ <source>Remove the selected entry(ies).</source>
+ <translation>選択したエントリを削除します</translation>
</message>
<message>
- <source>Copy this entry.</source>
- <oldsource>Copy this profile.</oldsource>
- <translation>このエントリをコピーします</translation>
+ <source>Copy the selected entry(ies).</source>
+ <translation>選択したエントリをコピーします</translation>
</message>
<message>
- <source>Move entry up.</source>
- <translation>エントリを上に移動します</translation>
+ <source>Move the selected entry(ies) up.</source>
+ <translation>選択したエントリを上に移動します</translation>
</message>
<message>
- <source>Move entry down.</source>
- <translation>エントリを下に移動します</translation>
+ <source>Move the selected entry(ies) down.</source>
+ <translation>選択したエントリを下に移動します</translation>
</message>
<message>
<source>Clear all entries.</source>
@@ -12082,20 +12645,20 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>新規エントリを作成します</translation>
</message>
<message>
- <source>Remove this entry.</source>
- <translation>このエントリを削除します</translation>
+ <source>Remove the selected entry(ies).</source>
+ <translation>選択したエントリを削除します</translation>
</message>
<message>
- <source>Copy this entry.</source>
- <translation>このエントリをコピーします</translation>
+ <source>Copy the selected entry(ies).</source>
+ <translation>選択したエントリをコピーします</translation>
</message>
<message>
- <source>Move entry up.</source>
- <translation>エントリを上に移動します</translation>
+ <source>Move the selected entry(ies) up.</source>
+ <translation>選択したエントリを上に移動します</translation>
</message>
<message>
- <source>Move entry down.</source>
- <translation>エントリを下に移動します</translation>
+ <source>Move the selected entry(ies) down.</source>
+ <translation>選択したエントリを下に移動します</translation>
</message>
<message>
<source>Clear all entries.</source>
@@ -12465,10 +13028,18 @@ a:hover {
<translation>あなたはWiresharkを使ってインターネットを互いにつなぐ膠をキャプチャしています</translation>
</message>
<message>
+ <source>You are sniffing the glue that holds your system together using Logray </source>
+ <translation>あなたはLograyを使ってシステムを互いに繋ぐ膠をキャプチャしています</translation>
+ </message>
+ <message>
<source>You are running Wireshark </source>
<translation>Wiresharkを起動中</translation>
</message>
<message>
+ <source>You are running Logray </source>
+ <translation>Lograyを起動中です </translation>
+ </message>
+ <message>
<source> You receive automatic updates.</source>
<translation>自動アップデートを受信します</translation>
</message>
@@ -12745,14 +13316,6 @@ a:hover {
<translation>ファイルが見つかりませんでした</translation>
</message>
<message>
- <source>&amp;Contents</source>
- <translation>目次(&amp;C)</translation>
- </message>
- <message>
- <source>Wireshark Filter</source>
- <translation>Wiresharkフィルタ</translation>
- </message>
- <message>
<source>TShark</source>
<translation>Tshark</translation>
</message>
@@ -13018,10 +13581,6 @@ a:hover {
<translation>無線ツールバー</translation>
</message>
<message>
- <source>Help contents</source>
- <translation>ヘルプ目次</translation>
- </message>
- <message>
<source>FAQs</source>
<translation>FAQ&apos;s</translation>
</message>
@@ -13142,11 +13701,6 @@ a:hover {
<translation>前のパケットを検索します</translation>
</message>
<message>
- <source>&amp;Mark/Unmark Packet(s)</source>
- <oldsource>&amp;Mark/Unmark Packet</oldsource>
- <translation>パケットをマーク/マーク解除(&amp;M)</translation>
- </message>
- <message>
<source>Mark All Displayed</source>
<translation>表示されているものをすべてマークします</translation>
</message>
@@ -13175,11 +13729,6 @@ a:hover {
<translation>前にマークされたパケットに移動します</translation>
</message>
<message>
- <source>&amp;Ignore/Unignore Packet(s)</source>
- <oldsource>&amp;Ignore/Unignore Packet</oldsource>
- <translation>パケットを無視/無視を解除(&amp;I)</translation>
- </message>
- <message>
<source>Ignore All Displayed</source>
<translation>表示されているものすべてを無視します</translation>
</message>
@@ -13620,10 +14169,6 @@ a:hover {
<translation>レイアウトをリセット</translation>
</message>
<message>
- <source>Reset appearance layout to default size</source>
- <translation>外観のレイアウトをデフォルトのサイズにリセットします</translation>
- </message>
- <message>
<source>Seconds Since First Captured Packet</source>
<translation>最初にキャプチャしたパケットからの経過時間</translation>
</message>
@@ -13784,22 +14329,30 @@ a:hover {
<translation>MACアドレスブロック</translation>
</message>
<message>
- <source>TLS Keylog Launcher</source>
- <translation>TLSキーログランチャー</translation>
- </message>
- <message>
- <source>Release Notes</source>
- <translation>リリースノート</translation>
- </message>
- <message>
<source>&amp;Options…</source>
<translation>オプション…(&amp;O)</translation>
</message>
<message>
+ <source>&amp;3GPP Uu</source>
+ <translation>&amp;3GPP Uu</translation>
+ </message>
+ <message>
<source>&amp;Wireless</source>
<translation>無線(&amp;W)</translation>
</message>
<message>
+ <source>&amp;User&apos;s Guide</source>
+ <translation>&amp;ユーザーズガイド</translation>
+ </message>
+ <message>
+ <source>Wireshark User&apos;s Guide</source>
+ <translation>ワイヤーシャークユーザーズガイド</translation>
+ </message>
+ <message>
+ <source>Display Filters</source>
+ <translation>表示フィルタ</translation>
+ </message>
+ <message>
<source>Capture &amp;Filters…</source>
<translation>キャプチャフィルタ…(&amp;F)</translation>
</message>
@@ -13844,10 +14397,18 @@ a:hover {
<translation>前を検索(&amp;v)</translation>
</message>
<message>
+ <source>&amp;Mark/Unmark Selected</source>
+ <translation>選択をマーク/マーク解除(&amp;M)</translation>
+ </message>
+ <message>
<source>Mark or unmark each selected packet</source>
<translation>各々の選択されたパケットをマーク/マーク解除します</translation>
</message>
<message>
+ <source>&amp;Ignore/Unignore Selected</source>
+ <translation>選択を無視/無視を解除(&amp;I)</translation>
+ </message>
+ <message>
<source>Ignore or unignore each selected packet</source>
<translation>各々の選択されたパケットを無視/無視を解除します</translation>
</message>
@@ -13888,6 +14449,18 @@ a:hover {
<translation>TCP スループット</translation>
</message>
<message>
+ <source>General</source>
+ <translation>一般</translation>
+ </message>
+ <message>
+ <source>Query-Response</source>
+ <translation>クエリ-応答</translation>
+ </message>
+ <message>
+ <source>DNS Query-Response Statistics</source>
+ <translation>DNSクエリ-応答統計</translation>
+ </message>
+ <message>
<source>Request Sequences</source>
<translation>リクエストシーケンス</translation>
</message>
@@ -13896,6 +14469,14 @@ a:hover {
<translation>HTTPリクエストシーケンス</translation>
</message>
<message>
+ <source>E2AP</source>
+ <translation>E2AP</translation>
+ </message>
+ <message>
+ <source>E2AP Messages</source>
+ <translation>E2AP メッセージ</translation>
+ </message>
+ <message>
<source>Decode &amp;As…</source>
<translation>…としてデコード(&amp;A)</translation>
</message>
@@ -13956,6 +14537,10 @@ a:hover {
<translation>標準サイズ</translation>
</message>
<message>
+ <source>Reset layout to default size</source>
+ <translation>デフォルトサイズにレイアウトをリセット</translation>
+ </message>
+ <message>
<source>Resize Columns</source>
<translation>列幅を再調整</translation>
</message>
@@ -14214,6 +14799,14 @@ a:hover {
<translation>選択されたフィールドによって参照されたパケットへ移動します</translation>
</message>
<message>
+ <source>TLS Keylog Launcher</source>
+ <translation>TLSキーログランチャー</translation>
+ </message>
+ <message>
+ <source>Release Notes</source>
+ <translation>リリースノート</translation>
+ </message>
+ <message>
<source>&amp;VoIP Calls</source>
<translation>VoIP通話(&amp;V)</translation>
</message>
@@ -14246,10 +14839,6 @@ a:hover {
<translation>&amp;GSM</translation>
</message>
<message>
- <source>&amp;LTE</source>
- <translation>&amp;LTE</translation>
- </message>
- <message>
<source>&amp;MTP3</source>
<translation>&amp;MTP3</translation>
</message>
@@ -14534,6 +15123,10 @@ a:hover {
<translation>保存しないで終了(&amp;w)</translation>
</message>
<message>
+ <source>USB CDC Data</source>
+ <translation>USB CDC データ</translation>
+ </message>
+ <message>
<source>There is no &quot;rtp.ssrc&quot; field in this version of Wireshark.</source>
<translation>このバージョンのWiresharkには &quot;rtp.ssrc&quot; フィールドはありません</translation>
</message>
diff --git a/ui/qt/wireshark_ko.ts b/ui/qt/wireshark_ko.ts
index 94c1648f..e95bea54 100644
--- a/ui/qt/wireshark_ko.ts
+++ b/ui/qt/wireshark_ko.ts
@@ -44,8 +44,8 @@
<translation>폴더</translation>
</message>
<message>
- <source>Filter by path</source>
- <translation>경로로 필터</translation>
+ <source>Search Folders</source>
+ <translation>폴더 검색</translation>
</message>
<message>
<source>Plugins</source>
@@ -80,6 +80,14 @@
<translation>라이선스</translation>
</message>
<message>
+ <source>About Logray</source>
+ <translation>Logray 정보</translation>
+ </message>
+ <message>
+ <source>Logray</source>
+ <translation>Logray</translation>
+ </message>
+ <message>
<source>The directory does not exist</source>
<translation>디렉터리가 존재하지 않음</translation>
</message>
@@ -754,6 +762,28 @@
</message>
</context>
<context>
+ <name>CaptureCommentDialog</name>
+ <message>
+ <source>Edit Capture Comments</source>
+ <translation>캡처 주석 편집</translation>
+ </message>
+ <message>
+ <source>Add Comment</source>
+ <translation>주석 추가</translation>
+ </message>
+ <message>
+ <source>Section %1</source>
+ <translation>부분 %1</translation>
+ </message>
+</context>
+<context>
+ <name>CaptureCommentTabWidget</name>
+ <message>
+ <source>Comment %1</source>
+ <translation>주석 %1</translation>
+ </message>
+</context>
+<context>
<name>CaptureFile</name>
<message>
<source> [closing]</source>
@@ -821,7 +851,7 @@
<source>%1, timed out at %Ln packet(s)</source>
<oldsource>%1, timed out at %2 packets</oldsource>
<translation type="vanished">
- <numerusform>%1, 패킷 %Ln개 이후 시간 초과됨</numerusform>
+ <numerusform>%1, 패킷 %Ln개 이후 시간 초과</numerusform>
</translation>
</message>
<message numerus="yes">
@@ -859,10 +889,6 @@
<translation>읽기 필터:</translation>
</message>
<message>
- <source>Compress with g&amp;zip</source>
- <translation>gzip 형식으로 압축(&amp;Z)</translation>
- </message>
- <message>
<source>Open Capture File</source>
<oldsource>Wireshark: Open Capture File</oldsource>
<translation>캡처 파일 열기</translation>
@@ -941,8 +967,8 @@
<translation>자세한 정보</translation>
</message>
<message>
- <source>Capture file comments</source>
- <translation>캡처 파일 주석</translation>
+ <source>Edit Comments</source>
+ <translation>주석 편집</translation>
</message>
<message>
<source>Refresh</source>
@@ -953,10 +979,6 @@
<translation>클립보드에 복사</translation>
</message>
<message>
- <source>Save Comments</source>
- <translation>주석 저장</translation>
- </message>
- <message>
<source>Capture File Properties</source>
<translation>캡처 파일 속성</translation>
</message>
@@ -1005,10 +1027,18 @@
<translation>처음 패킷</translation>
</message>
<message>
+ <source>First event</source>
+ <translation>첫 이벤트</translation>
+ </message>
+ <message>
<source>Last packet</source>
<translation>마지막 패킷</translation>
</message>
<message>
+ <source>Last event</source>
+ <translation>마지막 이벤트</translation>
+ </message>
+ <message>
<source>Elapsed</source>
<translation>경과 시간</translation>
</message>
@@ -1045,6 +1075,10 @@
<translation>누락된 패킷</translation>
</message>
<message>
+ <source>Dropped events</source>
+ <translation>누락된 이벤트</translation>
+ </message>
+ <message>
<source>Capture filter</source>
<translation>캡처 필터</translation>
</message>
@@ -1057,6 +1091,10 @@
<translation>패킷 크기 제한(snaplen)</translation>
</message>
<message>
+ <source>Event size limit (snaplen)</source>
+ <translation>이벤트 크기 제한(snaplen)</translation>
+ </message>
+ <message>
<source>none</source>
<translation>없음</translation>
</message>
@@ -1065,6 +1103,26 @@
<translation>%1바이트</translation>
</message>
<message>
+ <source>Comments</source>
+ <translation>주석</translation>
+ </message>
+ <message>
+ <source>Comment %1: </source>
+ <translation>주석 %1</translation>
+ </message>
+ <message>
+ <source>Decryption Secrets</source>
+ <translation>복호화 비밀 정보</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>유형</translation>
+ </message>
+ <message>
+ <source>Size</source>
+ <translation>크기</translation>
+ </message>
+ <message>
<source>Statistics</source>
<translation>통계</translation>
</message>
@@ -1089,6 +1147,10 @@
<translation>패킷 수</translation>
</message>
<message>
+ <source>Events</source>
+ <translation>이벤트</translation>
+ </message>
+ <message>
<source>Time span, s</source>
<translation>시간 간격, 초</translation>
</message>
@@ -1101,6 +1163,10 @@
<translation>평균 패킷 크기, 바이트</translation>
</message>
<message>
+ <source>Average event size, B</source>
+ <translation>평균 이벤트 크기, 바이트</translation>
+ </message>
+ <message>
<source>Bytes</source>
<translation>바이트</translation>
</message>
@@ -1113,14 +1179,14 @@
<translation>초당 평균 비트 수</translation>
</message>
<message>
- <source>Section Comment</source>
- <translation>부분 주석</translation>
- </message>
- <message>
<source>Packet Comments</source>
<translation>패킷 주석</translation>
</message>
<message>
+ <source>Event Comments</source>
+ <translation>이벤트 주석</translation>
+ </message>
+ <message>
<source>&lt;p&gt;Frame %1: </source>
<translation>&lt;p&gt;프레임 %1: </translation>
</message>
@@ -1132,6 +1198,14 @@
</translation>
</message>
+ <message>
+ <source>Created by Logray %1
+
+</source>
+ <translation>Logray %1에서 생성됨
+
+</translation>
+ </message>
</context>
<context>
<name>CaptureFilterCombo</name>
@@ -1359,6 +1433,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
예를 들어 1시간으로 설정하면 매시간마다 새로운 파일을 만듭니다.</translation>
</message>
<message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for some more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;일반적으로 무선 네트워크 카드는 수신이나 발신 네트워크 주소가 자기 자신인 트래픽만 캡처하며, &lt;em&gt;사용자 데이터&lt;/em&gt; 트래픽에는 &amp;quot;가짜&amp;quot; 이더넷 헤더를 추가하여 캡처합니다. 무선 네트워크 카드가 &amp;quot;볼 수&amp;quot; 있는 모든 트래픽을 캡처하거나, 802.11 관리 및 제어 패킷 또는 라디오 계층 정보를 보려면 이 옵션을 선택하십시오. 무선 네트워크 카드와 드라이버에 따라서 모니터 모드 사용 가능 여부가 달라집니다. Wi-Fi 네트워크에서 패킷을 캡처하는 과정에 대한 자세한 정보를 보려면 위키 페이지를 참조하십시오.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>Enable monitor mode on all 802.11 interfaces</source>
+ <translation>모든 802.11 인터페이스에서 모니터 모드 활성화</translation>
+ </message>
+ <message>
<source>compression</source>
<translation>압축</translation>
</message>
@@ -1371,6 +1453,30 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>gzip</translation>
</message>
<message>
+ <source>File infix pattern</source>
+ <translation>파일 중위 표기 패턴</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;In multiple file mode, the date and time and file index number are inserted between filename template and any suffix. Select their order.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;여러 파일 모드에서는 파일 이름과 접두사 사이에 날짜, 시간, 파일 순서 번호가 추가됩니다. 이들의 순서를 선택하십시오.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>YYYYmmDDHHMMSS_NNNNN</source>
+ <translation>YYYYmmDDHHMMSS_NNNNN</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Date and time before the file index number. This causes files to sort in creation time order, and keeps files from the same batch closely ordered.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;파일 순서 번호 이전에 날짜와 시간을 배치합니다. 파일을 이름 순으로 정렬했을 때 생성 시간 순서를 따르며, 같은 배치에서 생성된 파일이 인접하게 배치됩니다.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>NNNNN_YYYYmmDDHHMMSS</source>
+ <translation>NNNNN_YYYYmmDDHHMMSS</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;File index number before the date and time. This is the historic Wireshark ordering.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;날짜와 시간 이전에 파일 순서 번호를 배치합니다. Wireshark에서 역사적으로 사용했던 방식입니다..&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;After capturing has switched to the next file and the given number of files has exceeded, the oldest file will be removed.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;다음 파일로 캡처를 전환한 후 생성하기로 지정한 파일 개수를 초과하면 가장 오래된 파일을 지울 것입니다.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1444,7 +1550,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Stop capture automatically after…</source>
- <translation>다음 이후 자동으로 캡처 정지</translation>
+ <translation>다음 이후 자동으로 캡처 정지…</translation>
</message>
<message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Stop capturing after the specified number of packets have been captured.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
@@ -1459,6 +1565,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;지정한 개수의 파일을 생성한 후 캡처를 정지합니다.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
+ <source>Stop capturing after the specified number of files have been created.</source>
+ <translation>지정한 개수의 파일을 생성한 후 캡처를 정지합니다.</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Stop capturing after the specified amount of data has been captured.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;지정한 분량의 데이터를 캡처한 후 캡처를 정지합니다.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1468,7 +1578,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Stop capturing after the specified amount of time has passed.</source>
- <translation>지정한 시간이 지난 뒤 캡처를 정지합니다.</translation>
+ <translation>지정한 시간이 지난 후 캡처를 정지합니다.</translation>
</message>
<message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Optionally specify a temporary directory for unnamed capture files.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
@@ -1519,8 +1629,8 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>오류</translation>
</message>
<message>
- <source>Multiple files: Requested filesize too large. The filesize cannot be greater than 2 GiB.</source>
- <translation>여러 파일: 요청한 파일 크기가 너무 큽니다. 파일 최대 크기는 2 GiB입니다.</translation>
+ <source>Multiple files: Requested filesize too large. The filesize cannot be greater than 2 TB.</source>
+ <translation>여러 파일: 요청한 파일 크기가 너무 큽니다. 파일 크기는 2 TB를 초과할 수 없습니다.</translation>
</message>
<message>
<source>Multiple files: No capture file name given. You must specify a filename if you want to use multiple files.</source>
@@ -1550,6 +1660,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>무작위 모드로 패킷 캡처</translation>
</message>
<message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;일반적으로 무선 네트워크 카드는 수신이나 발신 네트워크 주소가 자기 자신인 트래픽만 캡처하며, &lt;em&gt;사용자 데이터&lt;/em&gt; 트래픽에는 &amp;quot;가짜&amp;quot; 이더넷 헤더를 추가하여 캡처합니다. 무선 네트워크 카드가 &amp;quot;볼 수&amp;quot; 있는 모든 트래픽을 캡처하거나, 802.11 관리 및 제어 패킷 또는 라디오 계층 정보를 보려면 이 옵션을 선택하십시오. 무선 네트워크 카드와 드라이버에 따라서 모니터 모드 사용 가능 여부가 달라집니다. Wi-Fi 네트워크에서 패킷을 캡처하는 과정에 대한 자세한 정보를 보려면 위키 페이지를 참조하십시오.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>Capture packets in monitor mode on 802.11 devices</source>
+ <translation>802.11 인터페이스에서 모니터 모드 활성화</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Capture packets in the next-generation capture file format.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;다음 세대(Next Generation)의 캡처 파일 형식으로 패킷을 캡처합니다.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1777,6 +1895,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>해석됨</translation>
</message>
<message>
+ <source>Width</source>
+ <translation>폭</translation>
+ </message>
+ <message>
+ <source>Alignment</source>
+ <translation>정렬</translation>
+ </message>
+ <message>
<source>&lt;html&gt;Show human-readable strings instead of raw values for fields. Only applicable to custom columns with fields that have value strings.&lt;/html&gt;</source>
<translation>&lt;html&gt;필드의 원시값 대신 사람이 읽을 수 있는 문자열로 보여 줍니다. 문자열 값을 갖는 필드를 가진 사용자 지정 칼럼에 대해서만 적용 가능합니다.&lt;/html&gt;</translation>
</message>
@@ -1824,6 +1950,25 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>CompressionGroupBox</name>
+ <message>
+ <source>Compression options</source>
+ <translation>압축 옵션</translation>
+ </message>
+ <message>
+ <source>&amp;Uncompressed</source>
+ <translation>압축하지 않음(&amp;U)</translation>
+ </message>
+ <message>
+ <source>Compress with g&amp;zip</source>
+ <translation>gzip으로 압축(&amp;Z)</translation>
+ </message>
+ <message>
+ <source>Compress with &amp;LZ4</source>
+ <translation>LZ4로 압축(&amp;L)</translation>
+ </message>
+</context>
+<context>
<name>ConversationDataModel</name>
<message>
<source>Address A</source>
@@ -1890,6 +2035,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>비트/초 B</translation>
</message>
<message>
+ <source>Flows</source>
+ <translation>플로</translation>
+ </message>
+ <message>
<source>Total Packets</source>
<translation>전체 패킷</translation>
</message>
@@ -2004,14 +2153,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>16진수 덤프 형식으로 패킷 바이트를 복사합니다.</translation>
</message>
<message>
- <source>…as Printable Text</source>
- <translation>출력 가능한 문자열로 복사</translation>
- </message>
- <message>
- <source>Copy only the printable text in the packet.</source>
- <translation>패킷 내의 출력 가능한 문자열만 복사합니다.</translation>
- </message>
- <message>
<source>…as MIME Data</source>
<translation>MIME 데이터로 복사</translation>
</message>
@@ -2024,10 +2165,42 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>출력 가능한 ASCII 문자와 탈출 시퀀스로 패킷 바이트를 복사합니다.</translation>
</message>
<message>
+ <source>…as Go literal</source>
+ <translation>Go 리터럴로 복사</translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as Go literal.</source>
+ <translation>Go 리터럴 형식으로 패킷 바이트를 복사합니다.</translation>
+ </message>
+ <message>
+ <source>…as C Array</source>
+ <translation>C 언어 배열로 복사</translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as C Array.</source>
+ <translation>C 언어 배열 형식으로 패킷 바이트를 복사합니다.</translation>
+ </message>
+ <message>
<source>…as a Hex Stream</source>
<translation>16진수 스트림으로 복사</translation>
</message>
<message>
+ <source>…as UTF-8 Text</source>
+ <translation>UTF-8 텍스트로 복사</translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as text, treating as UTF-8.</source>
+ <translation>패킷 바이트를 UTF-8 텍스트로 취급하여 복사합니다.</translation>
+ </message>
+ <message>
+ <source>…as ASCII Text</source>
+ <translation>ASCII 텍스트로 복사</translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as text, treating as ASCII.</source>
+ <translation>패킷 바이트를 ASCII 텍스트로 취급하여 복사합니다.</translation>
+ </message>
+ <message>
<source>Copy packet bytes as a stream of hex.</source>
<translation>16진수 스트림으로 패킷 바이트를 복사합니다.</translation>
</message>
@@ -2823,6 +2996,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Display filter:</source>
<translation>표시 필터:</translation>
</message>
+ <message>
+ <source>Export PDUs</source>
+ <translation>PDU 내보내기</translation>
+ </message>
</context>
<context>
<name>ExtArgSelector</name>
@@ -2862,10 +3039,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>시작</translation>
</message>
<message>
- <source>Save</source>
- <translation>저장</translation>
- </message>
- <message>
<source>Default</source>
<translation>기본값</translation>
</message>
@@ -3006,6 +3179,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>표시 필터</translation>
</message>
<message>
+ <source>Display Filter Macros</source>
+ <translation>표시 필터 매크로</translation>
+ </message>
+ <message>
+ <source>New macro</source>
+ <translation>새 매크로</translation>
+ </message>
+ <message>
<source>Open </source>
<translation>열기: </translation>
</message>
@@ -3089,10 +3270,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>FilterListModel</name>
<message>
+ <source>Macro Name</source>
+ <translation>매크로 이름</translation>
+ </message>
+ <message>
<source>Filter Name</source>
<translation>필터 이름</translation>
</message>
<message>
+ <source>Macro Expression</source>
+ <translation>매크로 표현식</translation>
+ </message>
+ <message>
<source>Filter Expression</source>
<translation>필터 표현식</translation>
</message>
@@ -3178,22 +3367,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>FolderListModel</name>
<message>
- <source>&quot;File&quot; dialogs</source>
- <translation>&quot;파일&quot; 대화 상자</translation>
- </message>
- <message>
- <source>capture files</source>
- <translation>캡처 파일</translation>
- </message>
- <message>
<source>Temp</source>
<translation>임시</translation>
</message>
<message>
- <source>untitled capture files</source>
- <translation>이름 없는 캡처 파일</translation>
- </message>
- <message>
<source>Personal configuration</source>
<translation>개인 환경 설정</translation>
</message>
@@ -3202,14 +3379,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>전역 설정</translation>
</message>
<message>
- <source>dfilters, preferences, ethers, …</source>
- <translation>dfilters, 설정, ethers, …</translation>
- </message>
- <message>
- <source>dfilters, preferences, manuf, …</source>
- <translation>dfilters, 설정, manuf, …</translation>
- </message>
- <message>
<source>System</source>
<translation>시스템</translation>
</message>
@@ -3222,18 +3391,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>프로그램</translation>
</message>
<message>
- <source>program files</source>
- <translation>프로그램 파일</translation>
- </message>
- <message>
<source>Personal Plugins</source>
<translation>사용자 플러그인</translation>
</message>
<message>
- <source>binary plugins</source>
- <translation>바이너리 플러그인</translation>
- </message>
- <message>
<source>Global Plugins</source>
<translation>전역 플러그인</translation>
</message>
@@ -3250,12 +3411,36 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Lua 스크립트</translation>
</message>
<message>
+ <source>&quot;File&quot; dialog location</source>
+ <translation>&quot;파일&quot; 대화 상자 위치</translation>
+ </message>
+ <message>
+ <source>Capture files</source>
+ <translation>캡처 파일</translation>
+ </message>
+ <message>
+ <source>Untitled capture files</source>
+ <translation>제목 없는 캡처 파일</translation>
+ </message>
+ <message>
+ <source>Preferences, profiles, manuf, …</source>
+ <translation>설정, 프로필, 제조사, …</translation>
+ </message>
+ <message>
+ <source>Program files</source>
+ <translation>프로그램 파일</translation>
+ </message>
+ <message>
+ <source>Binary plugins</source>
+ <translation>바이너리 플러그인</translation>
+ </message>
+ <message>
<source>Personal Extcap path</source>
<translation>사용자 Extcap 경로</translation>
</message>
<message>
- <source>external capture (extcap) plugins</source>
- <translation>외부 캡처(Extcap) 플러그인</translation>
+ <source>External capture (extcap) plugins</source>
+ <translation>외부 캡처(extcap) 플러그인</translation>
</message>
<message>
<source>Global Extcap path</source>
@@ -3325,7 +3510,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<message numerus="yes">
<source>%Ln server pkt(s), </source>
<translation type="vanished">
- <numerusform>서버 패킷 %Ln개, </numerusform>
+ <numerusform>서버 패킷 %Ln개,</numerusform>
</translation>
</message>
<message>
@@ -3387,6 +3572,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</translation>
</message>
<message>
+ <source>Event %1. </source>
+ <translation>이벤트 %1개. </translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;reads&lt;/span&gt;, </source>
+ <translation>
+ <numerusform>&lt;span style=&quot;color: %1; background-color:%2&quot;&gt;읽기&lt;/span&gt; %Ln개, </numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;writes&lt;/span&gt;, </source>
+ <translation>
+ <numerusform>&lt;span style=&quot;color: %1; background-color:%2&quot;&gt;쓰기&lt;/span&gt; %Ln개, </numerusform>
+ </translation>
+ </message>
+ <message>
<source> Click to select.</source>
<translation> 클릭하면 선택합니다.</translation>
</message>
@@ -3419,6 +3620,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>선택한 패킷에서 %1 스트림을 찾을 수 없습니다.</translation>
</message>
<message>
+ <source>Read activity(%6)</source>
+ <translation>읽기 활동(%6)</translation>
+ </message>
+ <message>
+ <source>Write activity(%6)</source>
+ <translation>쓰기 활동(%6)</translation>
+ </message>
+ <message>
+ <source>Entire I/O activity (%1)</source>
+ <translation>전체 I/O 활동(%M)</translation>
+ </message>
+ <message>
<source>Entire conversation (%1)</source>
<translation>전체 대화(%1)</translation>
</message>
@@ -3434,10 +3647,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Save Stream Content As…</source>
<translation>다른 이름으로 스트림 내용 저장…</translation>
</message>
- <message>
- <source>[Stream output truncated]</source>
- <translation>[스트림 출력이 잘림]</translation>
- </message>
<message numerus="yes">
<source>%Ln total stream(s).</source>
<translation>
@@ -3463,9 +3672,20 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>필터 힌트.</translation>
</message>
<message>
- <source>Show data as</source>
- <oldsource>Show and save data as</oldsource>
- <translation>다음 형식으로 표시:</translation>
+ <source>Show as</source>
+ <translation>다른 형식으로 표시</translation>
+ </message>
+ <message>
+ <source>No delta times</source>
+ <translation>델타 시간 없음</translation>
+ </message>
+ <message>
+ <source>Turn delta times</source>
+ <translation>턴 델타 시간</translation>
+ </message>
+ <message>
+ <source>All delta times</source>
+ <translation>모든 델타 시간</translation>
</message>
<message>
<source>Stream</source>
@@ -3480,11 +3700,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>찾기:</translation>
</message>
<message>
+ <source>Case sensitive</source>
+ <translation>대소문자 구분</translation>
+ </message>
+ <message>
<source>Find &amp;Next</source>
<translation>다음 찾기(&amp;N)</translation>
</message>
</context>
<context>
+ <name>FollowStreamText</name>
+ <message>
+ <source>[Stream output truncated]</source>
+ <translation>[스트림 출력 잘림]</translation>
+ </message>
+</context>
+<context>
<name>FontColorPreferencesFrame</name>
<message>
<source>Frame</source>
@@ -3820,29 +4051,28 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <source>Remove this graph.</source>
- <oldsource>Remove this dissection behavior.</oldsource>
- <translation>이 그래프를 삭제합니다.</translation>
- </message>
- <message>
<source>Add a new graph.</source>
<translation>새로운 그래프를 추가합니다.</translation>
</message>
<message>
- <source>Duplicate this graph.</source>
- <translation>이 그래프를 복제합니다.</translation>
- </message>
- <message>
<source>Clear all graphs.</source>
<translation>모든 그래프를 지웁니다.</translation>
</message>
<message>
- <source>Move this graph upwards.</source>
- <translation>이 그래프를 위로 이동합니다.</translation>
+ <source>Remove the selected graph(s).</source>
+ <translation>선택한 그래프를 삭제합니다.</translation>
+ </message>
+ <message>
+ <source>Duplicate the selected graph(s).</source>
+ <translation>선택한 그래프를 복제합니다.</translation>
+ </message>
+ <message>
+ <source>Move the selected graph(s) upwards.</source>
+ <translation>선택한 그래프를 위로 이동합니다.</translation>
</message>
<message>
- <source>Move this graph downwards.</source>
- <translation>이 그래프를 아래로 이동합니다.</translation>
+ <source>Move the selected graph(s) downwards.</source>
+ <translation>선택한 그래프를 아래로 이동합니다.</translation>
</message>
<message>
<source>Mouse</source>
@@ -3885,10 +4115,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>범례 활성화</translation>
</message>
<message>
- <source>Reset</source>
- <translation>초기화</translation>
- </message>
- <message>
<source>Reset Graph</source>
<translation>그래프 초기화</translation>
</message>
@@ -4102,6 +4328,42 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>다른 프로필에서 그래프를 복사합니다.</translation>
</message>
<message>
+ <source>1 μs</source>
+ <translation>1 μs</translation>
+ </message>
+ <message>
+ <source>2 μs</source>
+ <translation>2 μs</translation>
+ </message>
+ <message>
+ <source>5 μs</source>
+ <translation>5 μs</translation>
+ </message>
+ <message>
+ <source>10 μs</source>
+ <translation>10 μs</translation>
+ </message>
+ <message>
+ <source>20 μs</source>
+ <translation>20 μs</translation>
+ </message>
+ <message>
+ <source>50 μs</source>
+ <translation>50 μs</translation>
+ </message>
+ <message>
+ <source>100 μs</source>
+ <translation>100 μs</translation>
+ </message>
+ <message>
+ <source>200 μs</source>
+ <translation>200 μs</translation>
+ </message>
+ <message>
+ <source>500 μs</source>
+ <translation>500 μs</translation>
+ </message>
+ <message>
<source>1 ms</source>
<translation>1 ms</translation>
</message>
@@ -4146,6 +4408,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>5초</translation>
</message>
<message>
+ <source>2 min</source>
+ <translation>2분</translation>
+ </message>
+ <message>
+ <source>5 min</source>
+ <translation>5분</translation>
+ </message>
+ <message>
<source>Wireshark I/O Graphs: %1</source>
<translation>Wireshark I/O 그래프: %1</translation>
</message>
@@ -4158,6 +4428,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>필터된 이벤트</translation>
</message>
<message>
+ <source>All packets</source>
+ <translation>모든 패킷</translation>
+ </message>
+ <message>
+ <source>All events</source>
+ <translation>모든 이벤트</translation>
+ </message>
+ <message>
<source>All Packets</source>
<translation>모든 패킷</translation>
</message>
@@ -4170,8 +4448,8 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>모든 이벤트</translation>
</message>
<message>
- <source>Access Denied</source>
- <translation>접근 거부됨</translation>
+ <source>All Execs</source>
+ <translation>모든 실행</translation>
</message>
<message>
<source>Hover over the graph for details.</source>
@@ -4218,6 +4496,34 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>클릭하여 그래프의 부분을 선택하십시오.</translation>
</message>
<message>
+ <source>%1 Intervals </source>
+ <translation>간격 %1</translation>
+ </message>
+ <message>
+ <source>Move to top left</source>
+ <translation>왼쪽 위로 이동</translation>
+ </message>
+ <message>
+ <source>Move to top center</source>
+ <translation>가운데 위로 이동</translation>
+ </message>
+ <message>
+ <source>Move to top right</source>
+ <translation>오른쪽 위로 이동</translation>
+ </message>
+ <message>
+ <source>Move to bottom left</source>
+ <translation>왼쪽 아래로 이동</translation>
+ </message>
+ <message>
+ <source>Move to bottom center</source>
+ <translation>가운데 아래로 이동</translation>
+ </message>
+ <message>
+ <source>Move to bottom right</source>
+ <translation>오른쪽 아래로 이동</translation>
+ </message>
+ <message>
<source>Portable Document Format (*.pdf)</source>
<translation>PDF 형식 (*.pdf)</translation>
</message>
@@ -4970,6 +5276,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>InterfaceTreeDelegate</name>
+ <message>
+ <source>default</source>
+ <translation>기본값</translation>
+ </message>
+</context>
+<context>
<name>InterfaceTreeModel</name>
<message>
<source>Show</source>
@@ -5469,7 +5782,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>details for transport</source>
- <translation>전송 상세 정보</translation>
+ <translation>전송 자세한 정보</translation>
</message>
<message>
<source>XXXXX:XXX.XXX.XXX.XXX:XXXXX:XXXXXXXX:XXX.XXX.XXX.XXX:XXXXX</source>
@@ -5878,7 +6191,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Packet Details</source>
- <translation>패킷 상세 정보</translation>
+ <translation>패킷 자세한 정보</translation>
</message>
<message>
<source>Packet Bytes</source>
@@ -5944,8 +6257,8 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>LteMacStatisticsDialog</name>
<message>
- <source>LTE Mac Statistics</source>
- <translation>LTE MAC 통계</translation>
+ <source>LTE/NR Mac Statistics</source>
+ <translation>LTE/NR MAC 통계</translation>
</message>
<message>
<source>Include SR frames in filter</source>
@@ -6249,12 +6562,12 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>시퀀스 번호</translation>
</message>
<message>
- <source>LTE RLC Graph (UE=%1 chan=%2%3 %4 - %5)</source>
- <translation>LTE RLC 그래프(UE=%1 chan=%2%3 %4 - %5)</translation>
+ <source>%1 RLC Graph (UE=%2 chan=%3%4 %5 - %6)</source>
+ <translation>%1 RLC 그래프 (UE=%2 chan=%3%4 %5 - %6)</translation>
</message>
<message>
- <source>LTE RLC Graph - no channel selected</source>
- <translation>LTE RLC 그래프 - 선택한 채널 없음</translation>
+ <source>3GPP RLC Graph - no channel selected</source>
+ <translation>3GPP RLC 그래프 - 선택한 채널 없음</translation>
</message>
<message>
<source>Save As…</source>
@@ -6308,8 +6621,8 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>LteRlcStatisticsDialog</name>
<message>
- <source>LTE RLC Statistics</source>
- <translation>LTE RLC 통계</translation>
+ <source>3GPP RLC Statistics</source>
+ <translation>3GPP RLC 통계</translation>
</message>
<message>
<source>Include SR frames in filter</source>
@@ -6395,6 +6708,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>프로필: %1</translation>
</message>
<message>
+ <source> %1 Displayed: %2 (%3%)</source>
+ <translation> %1개 표시됨: %2(%3%)</translation>
+ </message>
+ <message>
<source>Manage Profiles…</source>
<translation>프로필 관리…</translation>
</message>
@@ -6455,6 +6772,12 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<numerusform>%Ln바이트</numerusform>
</translation>
</message>
+ <message numerus="yes">
+ <source>%Ln bit(s)</source>
+ <translation>
+ <numerusform>%Ln비트</numerusform>
+ </translation>
+ </message>
<message>
<source>Byte %1</source>
<translation>바이트 %1</translation>
@@ -6468,9 +6791,12 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>선택된 패킷: %1 %2 </translation>
</message>
<message>
- <source>Packets: %1 %4 Displayed: %2 (%3%)</source>
- <oldsource>Packets: %1 %4 Displayed: %2 %4 Marked: %3</oldsource>
- <translation>패킷 수: %1 %4 표시됨: %2(%3%)</translation>
+ <source>Selected Event: %1 %2 </source>
+ <translation>선택된 이벤트: %1 %2 </translation>
+ </message>
+ <message>
+ <source>Events: %1</source>
+ <translation>이벤트: %1</translation>
</message>
<message>
<source> %1 Selected: %2 (%3%)</source>
@@ -6502,6 +6828,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>패킷 없음</translation>
</message>
<message>
+ <source>No Events</source>
+ <translation>이벤트 없음</translation>
+ </message>
+ <message>
<source>From Zip File...</source>
<translation>ZIP 파일에서...</translation>
</message>
@@ -6533,6 +6863,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>MainWindow</name>
+ <message>
+ <source>Display filter as %1</source>
+ <translation>%1(으)로 표시 필터</translation>
+ </message>
+</context>
+<context>
<name>MainWindowPreferencesFrame</name>
<message>
<source>Frame</source>
@@ -6564,6 +6901,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>가장 최근에 사용한 폴더</translation>
</message>
<message>
+ <source>The current working directory</source>
+ <translation>현재 작업 디렉터리</translation>
+ </message>
+ <message>
<source>Show up to</source>
<translation>최대 표시 개수</translation>
</message>
@@ -6994,6 +7335,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>필드 값 표시</translation>
</message>
<message>
+ <source>Refresh</source>
+ <translation>새로 고침</translation>
+ </message>
+ <message>
<source>Save Diagram As…</source>
<translation>다른 이름으로 다이어그램 저장…</translation>
</message>
@@ -7041,6 +7386,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>패킷 바이트 표시</translation>
</message>
<message>
+ <source>Layout:</source>
+ <translation>레이아웃:</translation>
+ </message>
+ <message>
<source>Packet %1</source>
<translation>패킷 %1</translation>
</message>
@@ -7062,6 +7411,12 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<numerusform>%Ln바이트</numerusform>
</translation>
</message>
+ <message numerus="yes">
+ <source>%Ln bit(s)</source>
+ <translation>
+ <numerusform>%Ln비트</numerusform>
+ </translation>
+ </message>
</context>
<context>
<name>PacketFormatGroupBox</name>
@@ -7521,10 +7876,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>이 프로필을 복사합니다.</translation>
</message>
<message>
+ <source>The number of packets or events to check for automatic profile switching.</source>
+ <translation>자동 프로필 전환 시 점검할 패킷이나 이벤트 개수입니다.</translation>
+ </message>
+ <message>
+ <source>Auto switch packet limit</source>
+ <translation>자동 전환 패킷 제한</translation>
+ </message>
+ <message>
<source>Configuration Profiles</source>
<translation>설정 프로필</translation>
</message>
<message>
+ <source>Auto switch event limit</source>
+ <translation>자동 전환 이벤트 제한</translation>
+ </message>
+ <message>
<source>Import</source>
<comment>noun</comment>
<translation>가져오기</translation>
@@ -7700,6 +8067,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>삭제됨</translation>
</message>
<message>
+ <source>Auto Switch Filter</source>
+ <translation>자동 전환 필터</translation>
+ </message>
+ <message>
<source>copy</source>
<comment>noun</comment>
<translation>복사</translation>
@@ -8059,6 +8430,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>윈도 크기(바이트)</translation>
</message>
<message>
+ <source>Unacked (Outstanding) Bytes (B)</source>
+ <translation>ACK되지 않은(대기 중) 바이트(바이트)</translation>
+ </message>
+ <message>
<source>[no capture file]</source>
<translation>[캡처 파일 없음]</translation>
</message>
@@ -8219,6 +8594,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>마커 없음?</translation>
</message>
<message>
+ <source>LTE</source>
+ <translation>LTE</translation>
+ </message>
+ <message>
+ <source>NR</source>
+ <translation>NR</translation>
+ </message>
+ <message>
<source>C-RNTI</source>
<translation>C-RNTI</translation>
</message>
@@ -8239,6 +8622,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>UEId</translation>
</message>
<message>
+ <source>RAT</source>
+ <translation>RAT</translation>
+ </message>
+ <message>
<source>UL Frames</source>
<translation>UL 프레임</translation>
</message>
@@ -8462,9 +8849,69 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Browse…</source>
<translation>찾아보기...</translation>
</message>
+ <message>
+ <source>PACKETS</source>
+ <translation>패킷</translation>
+ </message>
+ <message>
+ <source>EVENTS</source>
+ <translation>이벤트</translation>
+ </message>
+ <message>
+ <source>BYTES</source>
+ <translation>바이트</translation>
+ </message>
+ <message>
+ <source>BITS</source>
+ <translation>비트</translation>
+ </message>
+ <message>
+ <source>COUNT FRAMES</source>
+ <translation>프레임 개수</translation>
+ </message>
+ <message>
+ <source>COUNT FIELDS</source>
+ <translation>필드 개수</translation>
+ </message>
+ <message>
+ <source>SUM</source>
+ <translation>합계</translation>
+ </message>
+ <message>
+ <source>MAX</source>
+ <translation>최댓값</translation>
+ </message>
+ <message>
+ <source>MIN</source>
+ <translation>최솟값</translation>
+ </message>
+ <message>
+ <source>AVERAGE</source>
+ <translation>평균</translation>
+ </message>
+ <message>
+ <source>THROUGHPUT</source>
+ <translation>처리량</translation>
+ </message>
+ <message>
+ <source>LOAD</source>
+ <translation>부하</translation>
+ </message>
+ <message>
+ <source>Left</source>
+ <translation>왼쪽</translation>
+ </message>
+ <message>
+ <source>Center</source>
+ <translation>가운데</translation>
+ </message>
+ <message>
+ <source>Right</source>
+ <translation>오른쪽</translation>
+ </message>
</context>
<context>
- <name>QObject::QObject</name>
+ <name>QObject::QObject::QObject</name>
<message>
<source>CCCH</source>
<translation>CCCH</translation>
@@ -8565,6 +9012,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>ResizeHeaderView</name>
+ <message>
+ <source>Resize all %1 to contents</source>
+ <translation>모든 %1을(를) 내용에 맞게 조정</translation>
+ </message>
+</context>
+<context>
<name>ResolvedAddressesDialog</name>
<message>
<source>Dialog</source>
@@ -8680,6 +9134,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>해석된 주소</translation>
</message>
<message>
+ <source>Copy</source>
+ <translation>복사</translation>
+ </message>
+ <message>
+ <source>Save as…</source>
+ <translation>다른 이름으로 저장…</translation>
+ </message>
+ <message>
<source># Resolved addresses found in %1</source>
<translation># %1에서 발견된 해석된 주소</translation>
</message>
@@ -8693,6 +9155,61 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>ResolvedAddressesView</name>
+ <message>
+ <source>as Plain Text</source>
+ <translation>일반 텍스트로</translation>
+ </message>
+ <message>
+ <source>Copy selected rows</source>
+ <translation>선택한 행 복사</translation>
+ </message>
+ <message>
+ <source>Copy table</source>
+ <translation>표 복사</translation>
+ </message>
+ <message>
+ <source>as CSV</source>
+ <translation>CSV로</translation>
+ </message>
+ <message>
+ <source>as JSON</source>
+ <translation>JSON으로</translation>
+ </message>
+ <message>
+ <source>Save selected rows as…</source>
+ <translation>선택한 행을 다른 이름으로 저장…</translation>
+ </message>
+ <message>
+ <source>Save table as…</source>
+ <translation>표를 다른 이름으로 저장…</translation>
+ </message>
+ <message>
+ <source>Save Resolved Addresses As…</source>
+ <translation>해석된 주소를 다른 이름으로 저장…</translation>
+ </message>
+ <message>
+ <source>Plain text (*.txt)</source>
+ <translation>일반 텍스트 (*.txt)</translation>
+ </message>
+ <message>
+ <source>CSV Document (*.csv)</source>
+ <translation>CSV 문서 (*.csv)</translation>
+ </message>
+ <message>
+ <source>JSON Document (*.json)</source>
+ <translation>JSON 문서 (*.json)</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>경고</translation>
+ </message>
+ <message>
+ <source>Unable to save %1: %2</source>
+ <translation>%1을(를) 저장할 수 없음: %2</translation>
+ </message>
+</context>
+<context>
<name>ResponseTimeDelayDialog</name>
<message>
<source>%1 Response Time Delay Statistics</source>
@@ -10367,6 +10884,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>패킷 바이트</translation>
</message>
<message>
+ <source>&lt;b&gt;Options:&lt;/b&gt;</source>
+ <translation>&lt;b&gt;옵션:&lt;/b&gt;</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for strings containing narrow (UTF-8 and ASCII) or wide (UTF-16) characters.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;좁은 문자(UTF-8과 ASCII) 또는 넓은 문자(UTF-16)를 포함하는 문자열을 검색합니다.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -10387,6 +10908,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>대소문자 구분</translation>
</message>
<message>
+ <source>Backwards</source>
+ <translation>역방향</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for a subsequent occurrence in the current packet before advancing to the next packet.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;다음 패킷으로 진행하기 전에 현재 패킷에서 일치 여부를 계속 검색합니다.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>Multiple occurrences</source>
+ <translation>여러 번 발견됨</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5), a plain string (e.g. My String) or a regular expression (e.g. colou?r).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<oldsource>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5) or a plain string (e.g. My String).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</oldsource>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;표시 필터 문법(예: ip.addr==10.1.1.1), 16진수 문자열(예: ffffda5), 일반 문자열(예: My String) 또는 정규 표현식(예: colou?r)을 사용하여 데이터를 검색합니다.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
@@ -10424,6 +10957,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>잘못된 필터입니다.</translation>
</message>
<message>
+ <source>Event List</source>
+ <translation>이벤트 목록</translation>
+ </message>
+ <message>
+ <source>Event Details</source>
+ <translation>이벤트 자세한 정보</translation>
+ </message>
+ <message>
+ <source>Event Bytes</source>
+ <translation>이벤트 바이트</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search the Info column of the event list (summary pane), decoded event display labels (tree view pane) or the ASCII-converted event data (hex view pane).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;이벤트 목록의 정보 열(요약 패널), 디코드된 이벤트 표시 이름표(트리 보기 패널), ASCII로 변환된 이벤트 데이터(16진수 보기 패널) 중에서 검색합니다.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
<source>That filter doesn&apos;t test anything.</source>
<translation>필터에서 아무것도 시험하지 않습니다.</translation>
</message>
@@ -10865,6 +11414,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>찾기:</translation>
</message>
<message>
+ <source>Case sensitive</source>
+ <translation>대소문자 구분</translation>
+ </message>
+ <message>
<source>Find &amp;Next</source>
<translation>다음 찾기(&amp;N)</translation>
</message>
@@ -10959,13 +11512,21 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>다른 이름으로 저장…</translation>
</message>
<message>
+ <source>Decoded as %1.</source>
+ <translation>%1(으)로 디코드했습니다.</translation>
+ </message>
+ <message>
<source>Save Selected Packet Bytes As…</source>
<translation>선택한 패킷 바이트를 다른 이름으로 저장…</translation>
</message>
+ <message>
+ <source>compressed %1</source>
+ <translation>%1 압축됨</translation>
+ </message>
<message numerus="yes">
- <source>Displaying %Ln byte(s).</source>
+ <source>Using %Ln byte(s).</source>
<translation>
- <numerusform>%Ln바이트를 표시하고 있습니다.</numerusform>
+ <numerusform>%Ln바이트를 사용합니다.</numerusform>
</translation>
</message>
<message>
@@ -11065,6 +11626,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Display filter:</source>
<translation>표시 필터:</translation>
</message>
+ <message>
+ <source>Strip Headers</source>
+ <translation>헤더 잘라내기</translation>
+ </message>
</context>
<context>
<name>SupportedProtocolsDialog</name>
@@ -12038,22 +12603,20 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>새 항목을 만듭니다.</translation>
</message>
<message>
- <source>Remove this entry.</source>
- <oldsource>Remove this profile.</oldsource>
- <translation>이 항목을 삭제합니다.</translation>
+ <source>Remove the selected entry(ies).</source>
+ <translation>선택한 항목을 삭제합니다.</translation>
</message>
<message>
- <source>Copy this entry.</source>
- <oldsource>Copy this profile.</oldsource>
- <translation>이 항목을 복사합니다.</translation>
+ <source>Copy the selected entry(ies).</source>
+ <translation>선택한 항목을 복사합니다.</translation>
</message>
<message>
- <source>Move entry up.</source>
- <translation>항목을 위로 이동합니다.</translation>
+ <source>Move the selected entry(ies) up.</source>
+ <translation>선택한 항목을 위로 이동합니다.</translation>
</message>
<message>
- <source>Move entry down.</source>
- <translation>항목을 아래로 이동합니다.</translation>
+ <source>Move the selected entry(ies) down.</source>
+ <translation>선택한 항목을 아래로 이동합니다.</translation>
</message>
<message>
<source>Clear all entries.</source>
@@ -12079,20 +12642,20 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>새 항목을 만듭니다.</translation>
</message>
<message>
- <source>Remove this entry.</source>
- <translation>이 항목을 삭제합니다.</translation>
+ <source>Remove the selected entry(ies).</source>
+ <translation>선택한 항목을 삭제합니다.</translation>
</message>
<message>
- <source>Copy this entry.</source>
- <translation>이 항목을 복사합니다.</translation>
+ <source>Copy the selected entry(ies).</source>
+ <translation>선택한 항목을 복사합니다.</translation>
</message>
<message>
- <source>Move entry up.</source>
- <translation>항목을 위로 이동합니다.</translation>
+ <source>Move the selected entry(ies) up.</source>
+ <translation>선택한 항목을 위로 이동합니다.</translation>
</message>
<message>
- <source>Move entry down.</source>
- <translation>항목을 아래로 이동합니다.</translation>
+ <source>Move the selected entry(ies) down.</source>
+ <translation>선택한 항목을 아래로 이동합니다.</translation>
</message>
<message>
<source>Clear all entries.</source>
@@ -12462,10 +13025,18 @@ a:hover {
<translation>Wireshark를 사용하여 인터넷을 고정하는 접착제의 냄새를 맡고(스니핑) 있습니다 </translation>
</message>
<message>
+ <source>You are sniffing the glue that holds your system together using Logray </source>
+ <translation>Logray를 사용하여 시스템을 고정하는 접착제의 냄새를 맡고(스니핑) 있습니다 </translation>
+ </message>
+ <message>
<source>You are running Wireshark </source>
<translation>실행 중인 Wireshark 버전: </translation>
</message>
<message>
+ <source>You are running Logray </source>
+ <translation>실행 중인 Logray 버전: </translation>
+ </message>
+ <message>
<source> You receive automatic updates.</source>
<translation> 자동 업데이트를 받고 있습니다.</translation>
</message>
@@ -12742,14 +13313,6 @@ a:hover {
<translation>찾은 파일 없음</translation>
</message>
<message>
- <source>&amp;Contents</source>
- <translation>내용(&amp;C)</translation>
- </message>
- <message>
- <source>Wireshark Filter</source>
- <translation>Wireshark 필터</translation>
- </message>
- <message>
<source>TShark</source>
<translation>TShark</translation>
</message>
@@ -13015,10 +13578,6 @@ a:hover {
<translation>무선 도구 모음</translation>
</message>
<message>
- <source>Help contents</source>
- <translation>도움말 내용</translation>
- </message>
- <message>
<source>FAQs</source>
<translation>자주 묻는 질문</translation>
</message>
@@ -13139,11 +13698,6 @@ a:hover {
<translation>이전 패킷 찾기</translation>
</message>
<message>
- <source>&amp;Mark/Unmark Packet(s)</source>
- <oldsource>&amp;Mark/Unmark Packet</oldsource>
- <translation>패킷 마크/해제(&amp;M)</translation>
- </message>
- <message>
<source>Mark All Displayed</source>
<translation>표시된 모든 패킷 마크</translation>
</message>
@@ -13172,11 +13726,6 @@ a:hover {
<translation>이전 마크한 패킷으로 이동</translation>
</message>
<message>
- <source>&amp;Ignore/Unignore Packet(s)</source>
- <oldsource>&amp;Ignore/Unignore Packet</oldsource>
- <translation>패킷 무시/해제(&amp;I)</translation>
- </message>
- <message>
<source>Ignore All Displayed</source>
<translation>표시된 모든 패킷 무시</translation>
</message>
@@ -13617,10 +14166,6 @@ a:hover {
<translation>레이아웃 초기화</translation>
</message>
<message>
- <source>Reset appearance layout to default size</source>
- <translation>외관 레이아웃을 기본 크기로 초기화</translation>
- </message>
- <message>
<source>Seconds Since First Captured Packet</source>
<translation>최초로 캡처된 패킷부터 지난 초 단위 시간</translation>
</message>
@@ -13781,22 +14326,30 @@ a:hover {
<translation>MAC 주소 블록</translation>
</message>
<message>
- <source>TLS Keylog Launcher</source>
- <translation>TLS 키로그 실행기</translation>
- </message>
- <message>
- <source>Release Notes</source>
- <translation>릴리스 노트</translation>
- </message>
- <message>
<source>&amp;Options…</source>
<translation>옵션(&amp;O)…</translation>
</message>
<message>
+ <source>&amp;3GPP Uu</source>
+ <translation>3GPP Uu(&amp;3)</translation>
+ </message>
+ <message>
<source>&amp;Wireless</source>
<translation>무선(&amp;W)</translation>
</message>
<message>
+ <source>&amp;User&apos;s Guide</source>
+ <translation>사용자 설명서(&amp;U)</translation>
+ </message>
+ <message>
+ <source>Wireshark User&apos;s Guide</source>
+ <translation>Wireshark 사용자 설명서</translation>
+ </message>
+ <message>
+ <source>Display Filters</source>
+ <translation>표시 필터</translation>
+ </message>
+ <message>
<source>Capture &amp;Filters…</source>
<translation>캡처 필터(&amp;F)…</translation>
</message>
@@ -13841,10 +14394,18 @@ a:hover {
<translation>이전 찾기(&amp;V)</translation>
</message>
<message>
+ <source>&amp;Mark/Unmark Selected</source>
+ <translation>선택 항목 마크/해제(&amp;M)</translation>
+ </message>
+ <message>
<source>Mark or unmark each selected packet</source>
<translation>각 선택된 패킷 마크/해제</translation>
</message>
<message>
+ <source>&amp;Ignore/Unignore Selected</source>
+ <translation>선택 항목 무시/해제(&amp;I)</translation>
+ </message>
+ <message>
<source>Ignore or unignore each selected packet</source>
<translation>각 선택된 패킷 무시/해제</translation>
</message>
@@ -13885,6 +14446,18 @@ a:hover {
<translation>TCP 처리량</translation>
</message>
<message>
+ <source>General</source>
+ <translation>일반</translation>
+ </message>
+ <message>
+ <source>Query-Response</source>
+ <translation>질의-응답</translation>
+ </message>
+ <message>
+ <source>DNS Query-Response Statistics</source>
+ <translation>DNS 질의-응답 통계</translation>
+ </message>
+ <message>
<source>Request Sequences</source>
<translation>요청 시퀀스</translation>
</message>
@@ -13893,6 +14466,14 @@ a:hover {
<translation>HTTP 요청 시퀀스</translation>
</message>
<message>
+ <source>E2AP</source>
+ <translation>E2AP</translation>
+ </message>
+ <message>
+ <source>E2AP Messages</source>
+ <translation>E2AP 메시지</translation>
+ </message>
+ <message>
<source>Decode &amp;As…</source>
<translation>다른 형식으로 디코드(&amp;A)…</translation>
</message>
@@ -13953,6 +14534,10 @@ a:hover {
<translation>보통 크기</translation>
</message>
<message>
+ <source>Reset layout to default size</source>
+ <translation>레이아웃을 기본값으로 초기화</translation>
+ </message>
+ <message>
<source>Resize Columns</source>
<translation>열 크기 조정</translation>
</message>
@@ -14211,6 +14796,14 @@ a:hover {
<translation>선택한 필드에서 참조하는 패킷으로 이동합니다.</translation>
</message>
<message>
+ <source>TLS Keylog Launcher</source>
+ <translation>TLS 키로그 실행기</translation>
+ </message>
+ <message>
+ <source>Release Notes</source>
+ <translation>릴리스 노트</translation>
+ </message>
+ <message>
<source>&amp;VoIP Calls</source>
<translation>VoIP 호(&amp;V)</translation>
</message>
@@ -14243,10 +14836,6 @@ a:hover {
<translation>GSM(&amp;G)</translation>
</message>
<message>
- <source>&amp;LTE</source>
- <translation>LTE(&amp;L)</translation>
- </message>
- <message>
<source>&amp;MTP3</source>
<translation>MTP3(&amp;M)</translation>
</message>
@@ -14531,6 +15120,10 @@ a:hover {
<translation>저장하지 않고 끝내기(&amp;W)</translation>
</message>
<message>
+ <source>USB CDC Data</source>
+ <translation>USB CDC 데이터</translation>
+ </message>
+ <message>
<source>There is no &quot;rtp.ssrc&quot; field in this version of Wireshark.</source>
<translation>이 버전의 Wireshark에는 &quot;rtp.ssrc&quot; 필드가 없습니다.</translation>
</message>
diff --git a/ui/qt/wireshark_main_window.cpp b/ui/qt/wireshark_main_window.cpp
index 040c45ba..d1f7dcd0 100644
--- a/ui/qt/wireshark_main_window.cpp
+++ b/ui/qt/wireshark_main_window.cpp
@@ -12,7 +12,7 @@
/*
* The generated Ui_WiresharkMainWindow::setupUi() can grow larger than our configured limit,
- * so turn off -Wframe-larger-than= for ui_main_window.h.
+ * so turn off -Wframe-larger-than= for ui_wireshark_main_window.h.
*/
DIAG_OFF(frame-larger-than=)
#include <ui_wireshark_main_window.h>
@@ -32,6 +32,7 @@ DIAG_ON(frame-larger-than=)
#include <frame_tvbuff.h>
#include "ui/iface_toolbar.h"
+#include "ui/commandline.h"
#ifdef HAVE_LIBPCAP
#include "ui/capture.h"
@@ -75,6 +76,7 @@ DIAG_ON(frame-larger-than=)
#include <ui/qt/widgets/filter_expression_toolbar.h>
#include <ui/qt/utils/color_utils.h>
+#include <ui/qt/utils/profile_switcher.h>
#include <ui/qt/utils/qt_ui_utils.h>
#include <ui/qt/utils/stock_icon.h>
#include <ui/qt/utils/variant_pointer.h>
@@ -96,7 +98,7 @@ DIAG_ON(frame-larger-than=)
//menu_recent_file_write_all
// If we ever add support for multiple windows this will need to be replaced.
-static WiresharkMainWindow *gbl_cur_main_window_ = NULL;
+static WiresharkMainWindow *gbl_cur_main_window_;
static void plugin_if_mainwindow_apply_filter(GHashTable * data_set)
{
@@ -119,9 +121,9 @@ static void plugin_if_mainwindow_preference(GHashTable * data_set)
const char * pref_value;
DIAG_OFF_CAST_AWAY_CONST
- if (g_hash_table_lookup_extended(data_set, "pref_module", NULL, (gpointer *)&module_name) &&
- g_hash_table_lookup_extended(data_set, "pref_key", NULL, (gpointer *)&pref_name) &&
- g_hash_table_lookup_extended(data_set, "pref_value", NULL, (gpointer *)&pref_value))
+ if (g_hash_table_lookup_extended(data_set, "pref_module", NULL, (void * *)&module_name) &&
+ g_hash_table_lookup_extended(data_set, "pref_key", NULL, (void * *)&pref_name) &&
+ g_hash_table_lookup_extended(data_set, "pref_value", NULL, (void * *)&pref_value))
{
unsigned int changed_flags = prefs_store_ext(module_name, pref_name, pref_value);
if (changed_flags) {
@@ -137,7 +139,7 @@ static void plugin_if_mainwindow_gotoframe(GHashTable * data_set)
if (!gbl_cur_main_window_ || !data_set)
return;
- gpointer framenr;
+ void *framenr;
if (g_hash_table_lookup_extended(data_set, "frame_nr", NULL, &framenr)) {
if (GPOINTER_TO_UINT(framenr) != 0)
@@ -215,7 +217,7 @@ static void plugin_if_mainwindow_get_ws_info(GHashTable * data_set)
}
else {
ws_info->cf_framenr = 0;
- ws_info->frame_passed_dfilter = FALSE;
+ ws_info->frame_passed_dfilter = false;
}
}
else
@@ -223,7 +225,7 @@ static void plugin_if_mainwindow_get_ws_info(GHashTable * data_set)
/* Initialise the other ws_info structure values */
ws_info->cf_count = 0;
ws_info->cf_framenr = 0;
- ws_info->frame_passed_dfilter = FALSE;
+ ws_info->frame_passed_dfilter = false;
}
}
@@ -293,7 +295,7 @@ static void mainwindow_add_toolbar(const iface_toolbar *toolbar_entry)
}
}
-static void mainwindow_remove_toolbar(const gchar *menu_title)
+static void mainwindow_remove_toolbar(const char *menu_title)
{
if (gbl_cur_main_window_ && menu_title)
{
@@ -301,16 +303,22 @@ static void mainwindow_remove_toolbar(const gchar *menu_title)
}
}
-QMenu* WiresharkMainWindow::findOrAddMenu(QMenu *parent_menu, QString& menu_text) {
- QList<QAction *> actions = parent_menu->actions();
- QList<QAction *>::const_iterator i;
- for (i = actions.constBegin(); i != actions.constEnd(); ++i) {
- if ((*i)->text()==menu_text) {
- return (*i)->menu();
+QMenu* WiresharkMainWindow::findOrAddMenu(QMenu *parent_menu, const QStringList& menu_parts) {
+ for (auto const & menu_text : menu_parts) {
+ bool found = false;
+ for (auto const & action : parent_menu->actions()) {
+ if (action->text() == menu_text.trimmed()) {
+ parent_menu = action->menu();
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ // If we get here the menu entry was not found, add a sub menu
+ parent_menu = parent_menu->addMenu(menu_text.trimmed());
}
}
- // If we get here there menu entry was not found, add a sub menu
- return parent_menu->addMenu(menu_text);
+ return parent_menu;
}
WiresharkMainWindow::WiresharkMainWindow(QWidget *parent) :
@@ -325,7 +333,8 @@ WiresharkMainWindow::WiresharkMainWindow(QWidget *parent) :
freeze_focus_(NULL),
was_maximized_(false),
capture_stopping_(false),
- capture_filter_valid_(false)
+ capture_filter_valid_(false),
+ use_capturing_title_(false)
#ifdef HAVE_LIBPCAP
, capture_options_dialog_(NULL)
, info_data_()
@@ -335,10 +344,9 @@ WiresharkMainWindow::WiresharkMainWindow(QWidget *parent) :
#endif
{
if (!gbl_cur_main_window_) {
- connect(mainApp, SIGNAL(openStatCommandDialog(QString, const char*, void*)),
- this, SLOT(openStatCommandDialog(QString, const char*, void*)));
- connect(mainApp, SIGNAL(openTapParameterDialog(QString, const QString, void*)),
- this, SLOT(openTapParameterDialog(QString, const QString, void*)));
+ connect(mainApp, &MainApplication::openStatCommandDialog, this, &WiresharkMainWindow::openStatCommandDialog);
+ connect(mainApp, &MainApplication::openTapParameterDialog,
+ this, [=](const QString cfg_str, const QString arg, void *userdata) {openTapParameterDialog(cfg_str, arg, userdata);});
}
gbl_cur_main_window_ = this;
#ifdef HAVE_LIBPCAP
@@ -363,23 +371,20 @@ WiresharkMainWindow::WiresharkMainWindow(QWidget *parent) :
menu_groups_ = QList<register_stat_group_t>()
<< REGISTER_PACKET_ANALYZE_GROUP_UNSORTED
- << REGISTER_ANALYZE_GROUP_CONVERSATION_FILTER
<< REGISTER_PACKET_STAT_GROUP_UNSORTED
<< REGISTER_STAT_GROUP_GENERIC
- << REGISTER_STAT_GROUP_CONVERSATION_LIST
- << REGISTER_STAT_GROUP_ENDPOINT_LIST
<< REGISTER_STAT_GROUP_RESPONSE_TIME
<< REGISTER_STAT_GROUP_RSERPOOL
- << REGISTER_STAT_GROUP_TELEPHONY
- << REGISTER_STAT_GROUP_TELEPHONY_ANSI
- << REGISTER_STAT_GROUP_TELEPHONY_GSM
- << REGISTER_STAT_GROUP_TELEPHONY_LTE
- << REGISTER_STAT_GROUP_TELEPHONY_MTP3
- << REGISTER_STAT_GROUP_TELEPHONY_SCTP
+ << REGISTER_TELEPHONY_GROUP_UNSORTED
+ << REGISTER_TELEPHONY_GROUP_ANSI
+ << REGISTER_TELEPHONY_GROUP_GSM
+ << REGISTER_TELEPHONY_GROUP_3GPP_UU
+ << REGISTER_TELEPHONY_GROUP_MTP3
+ << REGISTER_TELEPHONY_GROUP_SCTP
<< REGISTER_TOOLS_GROUP_UNSORTED;
setWindowIcon(mainApp->normalIcon());
- setTitlebarForCaptureFile();
+ updateTitlebar();
setMenusForCaptureFile();
setForCapturedPackets(false);
setMenusForFileSet(false);
@@ -392,36 +397,37 @@ WiresharkMainWindow::WiresharkMainWindow(QWidget *parent) :
qRegisterMetaType<FilterAction::Action>("FilterAction::Action");
qRegisterMetaType<FilterAction::ActionType>("FilterAction::ActionType");
- connect(this, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)),
- this, SLOT(queuedFilterAction(QString, FilterAction::Action, FilterAction::ActionType)),
- Qt::QueuedConnection);
+ connect(this, &WiresharkMainWindow::filterAction, this, &WiresharkMainWindow::queuedFilterAction, Qt::QueuedConnection);
//To prevent users use features before initialization complete
//Otherwise unexpected problems may occur
setFeaturesEnabled(false);
- connect(mainApp, SIGNAL(appInitialized()), this, SLOT(setFeaturesEnabled()));
- connect(mainApp, SIGNAL(appInitialized()), this, SLOT(applyGlobalCommandLineOptions()));
- connect(mainApp, SIGNAL(appInitialized()), this, SLOT(zoomText()));
- connect(mainApp, SIGNAL(appInitialized()), this, SLOT(initViewColorizeMenu()));
- connect(mainApp, SIGNAL(appInitialized()), this, SLOT(addStatsPluginsToMenu()));
- connect(mainApp, SIGNAL(appInitialized()), this, SLOT(addDynamicMenus()));
- connect(mainApp, SIGNAL(appInitialized()), this, SLOT(addPluginIFStructures()));
- connect(mainApp, SIGNAL(appInitialized()), this, SLOT(initConversationMenus()));
- connect(mainApp, SIGNAL(appInitialized()), this, SLOT(initExportObjectsMenus()));
- connect(mainApp, SIGNAL(appInitialized()), this, SLOT(initFollowStreamMenus()));
-
- connect(mainApp, SIGNAL(profileChanging()), this, SLOT(saveWindowGeometry()));
- connect(mainApp, SIGNAL(preferencesChanged()), this, SLOT(layoutPanes()));
- connect(mainApp, SIGNAL(preferencesChanged()), this, SLOT(layoutToolbars()));
- connect(mainApp, SIGNAL(preferencesChanged()), this, SLOT(updatePreferenceActions()));
- connect(mainApp, SIGNAL(preferencesChanged()), this, SLOT(zoomText()));
- connect(mainApp, SIGNAL(preferencesChanged()), this, SLOT(setTitlebarForCaptureFile()));
-
- connect(mainApp, SIGNAL(updateRecentCaptureStatus(const QString &, qint64, bool)), this, SLOT(updateRecentCaptures()));
+ connect(mainApp, &MainApplication::appInitialized, this, [this]() { setFeaturesEnabled(); });
+ connect(mainApp, &MainApplication::appInitialized, this, &WiresharkMainWindow::applyGlobalCommandLineOptions);
+ connect(mainApp, &MainApplication::appInitialized, this, &WiresharkMainWindow::zoomText);
+ connect(mainApp, &MainApplication::appInitialized, this, &WiresharkMainWindow::initViewColorizeMenu);
+ connect(mainApp, &MainApplication::appInitialized, this, &WiresharkMainWindow::addStatsPluginsToMenu);
+ connect(mainApp, &MainApplication::appInitialized, this, &WiresharkMainWindow::addDynamicMenus);
+ connect(mainApp, &MainApplication::appInitialized, this, &WiresharkMainWindow::addPluginIFStructures);
+ connect(mainApp, &MainApplication::appInitialized, this, &WiresharkMainWindow::initConversationMenus);
+ connect(mainApp, &MainApplication::appInitialized, this, &WiresharkMainWindow::initExportObjectsMenus);
+ connect(mainApp, &MainApplication::appInitialized, this, &WiresharkMainWindow::initFollowStreamMenus);
+ connect(mainApp, &MainApplication::appInitialized, this,
+ [=]() { addDisplayFilterTranslationActions(main_ui_->menuEditCopy); });
+
+ connect(mainApp, &MainApplication::profileChanging, this, &WiresharkMainWindow::saveWindowGeometry);
+ connect(mainApp, &MainApplication::preferencesChanged, this, &WiresharkMainWindow::layoutPanes);
+ connect(mainApp, &MainApplication::preferencesChanged, this, &WiresharkMainWindow::layoutToolbars);
+ connect(mainApp, &MainApplication::preferencesChanged, this, &WiresharkMainWindow::updatePreferenceActions);
+ connect(mainApp, &MainApplication::preferencesChanged, this, &WiresharkMainWindow::zoomText);
+ connect(mainApp, &MainApplication::preferencesChanged, this, &WiresharkMainWindow::updateTitlebar);
+
+ connect(mainApp, &MainApplication::updateRecentCaptureStatus, this, &WiresharkMainWindow::updateRecentCaptures);
+ connect(mainApp, &MainApplication::preferencesChanged, this, &WiresharkMainWindow::updateRecentCaptures);
updateRecentCaptures();
#if defined(HAVE_SOFTWARE_UPDATE) && defined(Q_OS_WIN)
- connect(mainApp, SIGNAL(softwareUpdateRequested()), this, SLOT(softwareUpdateRequested()),
+ connect(mainApp, &MainApplication::softwareUpdateRequested, this, &WiresharkMainWindow::softwareUpdateRequested,
Qt::BlockingQueuedConnection);
#endif
@@ -430,12 +436,13 @@ WiresharkMainWindow::WiresharkMainWindow(QWidget *parent) :
funnel_statistics_ = new FunnelStatistics(this, capture_file_);
connect(df_combo_box_, &QComboBox::editTextChanged, funnel_statistics_, &FunnelStatistics::displayFilterTextChanged);
connect(funnel_statistics_, &FunnelStatistics::setDisplayFilter, this, &WiresharkMainWindow::setDisplayFilter);
- connect(funnel_statistics_, SIGNAL(openCaptureFile(QString, QString)),
- this, SLOT(openCaptureFile(QString, QString)));
+ connect(funnel_statistics_, &FunnelStatistics::openCaptureFile, this,
+ [=](QString cf_path, QString filter) { openCaptureFile(cf_path, filter); });
+
+ connect(df_combo_box_, &QComboBox::editTextChanged, this, &WiresharkMainWindow::updateDisplayFilterTranslationActions);
file_set_dialog_ = new FileSetDialog(this);
- connect(file_set_dialog_, SIGNAL(fileSetOpenCaptureFile(QString)),
- this, SLOT(openCaptureFile(QString)));
+ connect(file_set_dialog_, &FileSetDialog::fileSetOpenCaptureFile, this, [=](QString cf_path) { openCaptureFile(cf_path); });
initMainToolbarIcons();
@@ -452,20 +459,17 @@ WiresharkMainWindow::WiresharkMainWindow(QWidget *parent) :
main_ui_->displayFilterToolBar->addWidget(filter_expression_toolbar_);
#if defined(HAVE_LIBNL) && defined(HAVE_NL80211)
- connect(wireless_frame_, SIGNAL(showWirelessPreferences(QString)),
- this, SLOT(showPreferencesDialog(QString)));
+ connect(wireless_frame_, &WirelessFrame::showWirelessPreferences, this, &WiresharkMainWindow::showPreferencesDialog);
#endif
main_ui_->goToFrame->hide();
- connect(main_ui_->goToFrame, SIGNAL(visibilityChanged(bool)),
- main_ui_->actionGoGoToPacket, SLOT(setChecked(bool)));
+ connect(main_ui_->goToFrame, &AccordionFrame::visibilityChanged, main_ui_->actionGoGoToPacket, &QAction::setChecked);
// XXX For some reason the cursor is drawn funny with an input mask set
// https://bugreports.qt-project.org/browse/QTBUG-7174
main_ui_->searchFrame->hide();
- connect(main_ui_->searchFrame, SIGNAL(visibilityChanged(bool)),
- main_ui_->actionEditFindPacket, SLOT(setChecked(bool)));
+ connect(main_ui_->searchFrame, &SearchFrame::visibilityChanged, main_ui_->actionEditFindPacket, &QAction::setChecked);
main_ui_->addressEditorFrame->hide();
main_ui_->columnEditorFrame->hide();
@@ -512,7 +516,7 @@ main_ui_->goToLineEdit->setValidator(goToLineQiv);
#ifdef HAVE_SOFTWARE_UPDATE
QAction *update_sep = main_ui_->menuHelp->insertSeparator(main_ui_->actionHelpAbout);
main_ui_->menuHelp->insertAction(update_sep, update_action_);
- connect(update_action_, SIGNAL(triggered()), this, SLOT(checkForUpdates()));
+ connect(update_action_, &QAction::triggered, this, &WiresharkMainWindow::checkForUpdates);
#endif
master_split_.setObjectName("splitterMaster");
extra_split_.setObjectName("splitterExtra");
@@ -525,18 +529,19 @@ main_ui_->goToLineEdit->setValidator(goToLineQiv);
packet_list_ = new PacketList(&master_split_);
main_ui_->wirelessTimelineWidget->setPacketList(packet_list_);
- connect(packet_list_, SIGNAL(framesSelected(QList<int>)), this, SLOT(setMenusForSelectedPacket()));
- connect(packet_list_, SIGNAL(framesSelected(QList<int>)), this, SIGNAL(framesSelected(QList<int>)));
+ connect(packet_list_, &PacketList::framesSelected, this, &WiresharkMainWindow::setMenusForSelectedPacket);
+ connect(packet_list_, &PacketList::framesSelected, this, &WiresharkMainWindow::framesSelected);
QAction *action = main_ui_->menuPacketComment->addAction(tr("Add New Comment…"));
connect(action, &QAction::triggered, this, &WiresharkMainWindow::addPacketComment);
action->setShortcut(QKeySequence(Qt::CTRL | Qt::ALT | Qt::Key_C));
- connect(main_ui_->menuPacketComment, SIGNAL(aboutToShow()), this, SLOT(setEditCommentsMenu()));
+ connect(main_ui_->menuPacketComment, &QMenu::aboutToShow, this, &WiresharkMainWindow::setEditCommentsMenu);
proto_tree_ = new ProtoTree(&master_split_);
proto_tree_->installEventFilter(this);
packet_list_->setProtoTree(proto_tree_);
+ packet_list_->setProfileSwitcher(profile_switcher_);
packet_list_->installEventFilter(this);
packet_diagram_ = new PacketDiagram(&master_split_);
@@ -576,40 +581,27 @@ main_ui_->goToLineEdit->setValidator(goToLineQiv);
setTabOrder(df_combo_box_->lineEdit(), packet_list_);
setTabOrder(packet_list_, proto_tree_);
- connect(&capture_file_, SIGNAL(captureEvent(CaptureEvent)),
- this, SLOT(captureEventHandler(CaptureEvent)));
- connect(&capture_file_, SIGNAL(captureEvent(CaptureEvent)),
- mainApp, SLOT(captureEventHandler(CaptureEvent)));
- connect(&capture_file_, SIGNAL(captureEvent(CaptureEvent)),
- main_ui_->statusBar, SLOT(captureEventHandler(CaptureEvent)));
-
- connect(mainApp, SIGNAL(freezePacketList(bool)),
- packet_list_, SLOT(freezePacketList(bool)));
- connect(mainApp, SIGNAL(columnsChanged()),
- packet_list_, SLOT(columnsChanged()));
- connect(mainApp, SIGNAL(preferencesChanged()),
- packet_list_, SLOT(preferencesChanged()));
- connect(mainApp, SIGNAL(recentPreferencesRead()),
- this, SLOT(applyRecentPaneGeometry()));
- connect(mainApp, SIGNAL(recentPreferencesRead()),
- this, SLOT(updateRecentActions()));
- connect(mainApp, SIGNAL(packetDissectionChanged()),
- this, SLOT(redissectPackets()), Qt::QueuedConnection);
-
- connect(mainApp, SIGNAL(checkDisplayFilter()),
- this, SLOT(checkDisplayFilter()));
- connect(mainApp, SIGNAL(fieldsChanged()),
- this, SLOT(fieldsChanged()));
- connect(mainApp, SIGNAL(reloadLuaPlugins()),
- this, SLOT(reloadLuaPlugins()));
-
- connect(main_ui_->mainStack, SIGNAL(currentChanged(int)),
- this, SLOT(mainStackChanged(int)));
-
- connect(welcome_page_, SIGNAL(startCapture(QStringList)),
- this, SLOT(startCapture(QStringList)));
- connect(welcome_page_, SIGNAL(recentFileActivated(QString)),
- this, SLOT(openCaptureFile(QString)));
+ connect(&capture_file_, &CaptureFile::captureEvent, this, &WiresharkMainWindow::captureEventHandler);
+ connect(&capture_file_, &CaptureFile::captureEvent, mainApp, &WiresharkApplication::captureEventHandler);
+ connect(&capture_file_, &CaptureFile::captureEvent, main_ui_->statusBar, &MainStatusBar::captureEventHandler);
+ connect(&capture_file_, &CaptureFile::captureEvent, profile_switcher_, &ProfileSwitcher::captureEventHandler);
+
+ connect(mainApp, &MainApplication::freezePacketList, packet_list_, &PacketList::freezePacketList);
+ connect(mainApp, &MainApplication::columnsChanged, packet_list_, &PacketList::columnsChanged);
+ connect(mainApp, &MainApplication::colorsChanged, packet_list_, &PacketList::colorsChanged);
+ connect(mainApp, &MainApplication::preferencesChanged, packet_list_, &PacketList::preferencesChanged);
+ connect(mainApp, &MainApplication::recentPreferencesRead, this, &WiresharkMainWindow::applyRecentPaneGeometry);
+ connect(mainApp, &MainApplication::recentPreferencesRead, this, &WiresharkMainWindow::updateRecentActions);
+ connect(mainApp, &MainApplication::packetDissectionChanged, this, &WiresharkMainWindow::redissectPackets, Qt::QueuedConnection);
+
+ connect(mainApp, &MainApplication::checkDisplayFilter, this, &WiresharkMainWindow::checkDisplayFilter);
+ connect(mainApp, &MainApplication::fieldsChanged, this, &WiresharkMainWindow::fieldsChanged);
+ connect(mainApp, &MainApplication::reloadLuaPlugins, this, &WiresharkMainWindow::reloadLuaPlugins);
+
+ connect(main_ui_->mainStack, &QStackedWidget::currentChanged, this, &WiresharkMainWindow::mainStackChanged);
+
+ connect(welcome_page_, &WelcomePage::startCapture, this, [this](QStringList interfaces) { startCapture(interfaces); });
+ connect(welcome_page_, &WelcomePage::recentFileActivated, this, [this](QString cfile) { openCaptureFile(cfile); });
connect(main_ui_->addressEditorFrame, &AddressEditorFrame::redissectPackets,
this, &WiresharkMainWindow::redissectPackets);
@@ -632,10 +624,9 @@ main_ui_->goToLineEdit->setValidator(goToLineQiv);
connect(this, &WiresharkMainWindow::setCaptureFile,
proto_tree_, &ProtoTree::setCaptureFile);
- connect(mainApp, SIGNAL(zoomMonospaceFont(QFont)),
- packet_list_, SLOT(setMonospaceFont(QFont)));
- connect(mainApp, SIGNAL(zoomMonospaceFont(QFont)),
- proto_tree_, SLOT(setMonospaceFont(QFont)));
+ connect(mainApp, &MainApplication::zoomMonospaceFont, packet_list_, &PacketList::setMonospaceFont);
+ connect(mainApp, &MainApplication::zoomRegularFont, packet_list_, &PacketList::setRegularFont);
+ connect(mainApp, &MainApplication::zoomMonospaceFont, proto_tree_, &ProtoTree::setMonospaceFont);
connectFileMenuActions();
connectEditMenuActions();
@@ -649,26 +640,18 @@ main_ui_->goToLineEdit->setValidator(goToLineQiv);
connectToolsMenuActions();
connectHelpMenuActions();
- connect(packet_list_, SIGNAL(packetDissectionChanged()),
- this, SLOT(redissectPackets()));
- connect(packet_list_, SIGNAL(showColumnPreferences(QString)),
- this, SLOT(showPreferencesDialog(QString)));
- connect(packet_list_, SIGNAL(showProtocolPreferences(QString)),
- this, SLOT(showPreferencesDialog(QString)));
+ connect(packet_list_, &PacketList::packetDissectionChanged, this, &WiresharkMainWindow::redissectPackets);
+ connect(packet_list_, &PacketList::showColumnPreferences, this, &WiresharkMainWindow::showPreferencesDialog);
+ connect(packet_list_, &PacketList::showProtocolPreferences, this, &WiresharkMainWindow::showPreferencesDialog);
connect(packet_list_, SIGNAL(editProtocolPreference(preference*, pref_module*)),
main_ui_->preferenceEditorFrame, SLOT(editPreference(preference*, pref_module*)));
- connect(packet_list_, SIGNAL(editColumn(int)), this, SLOT(showColumnEditor(int)));
- connect(main_ui_->columnEditorFrame, SIGNAL(columnEdited()),
- packet_list_, SLOT(columnsChanged()));
- connect(packet_list_, SIGNAL(doubleClicked(QModelIndex)),
- this, SLOT(openPacketDialog()));
- connect(packet_list_, SIGNAL(packetListScrolled(bool)),
- main_ui_->actionGoAutoScroll, SLOT(setChecked(bool)));
-
- connect(proto_tree_, SIGNAL(openPacketInNewWindow(bool)),
- this, SLOT(openPacketDialog(bool)));
- connect(proto_tree_, SIGNAL(showProtocolPreferences(QString)),
- this, SLOT(showPreferencesDialog(QString)));
+ connect(packet_list_, &PacketList::editColumn, this, &WiresharkMainWindow::showColumnEditor);
+ connect(main_ui_->columnEditorFrame, &ColumnEditorFrame::columnEdited, packet_list_, &PacketList::columnsChanged);
+ connect(packet_list_, &QAbstractItemView::doubleClicked, this, [=](const QModelIndex &){ openPacketDialog(); });
+ connect(packet_list_, &PacketList::packetListScrolled, main_ui_->actionGoAutoScroll, &QAction::setChecked);
+
+ connect(proto_tree_, &ProtoTree::openPacketInNewWindow, this, &WiresharkMainWindow::openPacketDialog);
+ connect(proto_tree_, &ProtoTree::showProtocolPreferences, this, &WiresharkMainWindow::showPreferencesDialog);
connect(proto_tree_, SIGNAL(editProtocolPreference(preference*, pref_module*)),
main_ui_->preferenceEditorFrame, SLOT(editPreference(preference*, pref_module*)));
@@ -690,16 +673,13 @@ main_ui_->goToLineEdit->setValidator(goToLineQiv);
#ifdef HAVE_LIBPCAP
QTreeWidget *iface_tree = findChild<QTreeWidget *>("interfaceTree");
if (iface_tree) {
- connect(iface_tree, SIGNAL(itemSelectionChanged()),
- this, SLOT(interfaceSelectionChanged()));
+ connect(iface_tree, &QTreeWidget::itemSelectionChanged, this, &WiresharkMainWindow::interfaceSelectionChanged);
}
- connect(main_ui_->welcomePage, SIGNAL(captureFilterSyntaxChanged(bool)),
- this, SLOT(captureFilterSyntaxChanged(bool)));
+ connect(main_ui_->welcomePage, &WelcomePage::captureFilterSyntaxChanged,
+ this, &WiresharkMainWindow::captureFilterSyntaxChanged);
- connect(this, SIGNAL(showExtcapOptions(QString&, bool)),
- this, SLOT(showExtcapOptionsDialog(QString&, bool)));
- connect(this->welcome_page_, SIGNAL(showExtcapOptions(QString&, bool)),
- this, SLOT(showExtcapOptionsDialog(QString&, bool)));
+ connect(this, &WiresharkMainWindow::showExtcapOptions, this, &WiresharkMainWindow::showExtcapOptionsDialog);
+ connect(this->welcome_page_, &WelcomePage::showExtcapOptions, this, &WiresharkMainWindow::showExtcapOptionsDialog);
#endif // HAVE_LIBPCAP
@@ -730,7 +710,7 @@ main_ui_->goToLineEdit->setValidator(goToLineQiv);
main_ui_->actionHelpMPText2pcap->setToolTip(gchar_free_to_qstring(topic_action_url(LOCALPAGE_MAN_TEXT2PCAP)));
main_ui_->actionHelpMPTShark->setToolTip(gchar_free_to_qstring(topic_action_url(LOCALPAGE_MAN_TSHARK)));
- main_ui_->actionHelpContents->setToolTip(gchar_free_to_qstring(topic_action_url(ONLINEPAGE_USERGUIDE)));
+ main_ui_->actionHelpContents->setToolTip(gchar_free_to_qstring(topic_action_url(HELP_CONTENT)));
main_ui_->actionHelpWebsite->setToolTip(gchar_free_to_qstring(topic_action_url(ONLINEPAGE_HOME)));
main_ui_->actionHelpFAQ->setToolTip(gchar_free_to_qstring(topic_action_url(ONLINEPAGE_FAQ)));
main_ui_->actionHelpAsk->setToolTip(gchar_free_to_qstring(topic_action_url(ONLINEPAGE_ASK)));
@@ -744,11 +724,14 @@ main_ui_->goToLineEdit->setValidator(goToLineQiv);
WiresharkMainWindow::~WiresharkMainWindow()
{
disconnect(main_ui_->mainStack, 0, 0, 0);
+ if (previous_focus_ != nullptr) {
+ disconnect(previous_focus_, &QWidget::destroyed, this, &WiresharkMainWindow::resetPreviousFocus);
+ }
#ifndef Q_OS_MAC
// Below dialogs inherit GeometryStateDialog
// For reasons described in geometry_state_dialog.h no parent is set when
- // instantiating the dialogs and as a resul objects are not automatically
+ // instantiating the dialogs and as a result objects are not automatically
// freed by its parent. Free then here explicitly to avoid leak and numerous
// Valgrind complaints.
delete file_set_dialog_;
@@ -816,8 +799,8 @@ void WiresharkMainWindow::addInterfaceToolbar(const iface_toolbar *toolbar_entry
menu->insertAction(before, action);
InterfaceToolbar *interface_toolbar = new InterfaceToolbar(this, toolbar_entry);
- connect(mainApp, SIGNAL(appInitialized()), interface_toolbar, SLOT(interfaceListChanged()));
- connect(mainApp, SIGNAL(localInterfaceListChanged()), interface_toolbar, SLOT(interfaceListChanged()));
+ connect(mainApp, &MainApplication::appInitialized, interface_toolbar, &InterfaceToolbar::interfaceListChanged);
+ connect(mainApp, &MainApplication::localInterfaceListChanged, interface_toolbar, &InterfaceToolbar::interfaceListChanged);
QToolBar *toolbar = new QToolBar(this);
toolbar->addWidget(interface_toolbar);
@@ -836,7 +819,7 @@ void WiresharkMainWindow::addInterfaceToolbar(const iface_toolbar *toolbar_entry
menu->menuAction()->setVisible(true);
}
-void WiresharkMainWindow::removeInterfaceToolbar(const gchar *menu_title)
+void WiresharkMainWindow::removeInterfaceToolbar(const char *menu_title)
{
QMenu *menu = main_ui_->menuInterfaceToolbars;
QAction *action = NULL;
@@ -945,13 +928,6 @@ void WiresharkMainWindow::keyPressEvent(QKeyEvent *event) {
}
void WiresharkMainWindow::closeEvent(QCloseEvent *event) {
- if (main_ui_->actionCaptureStop->isEnabled()) {
- // Capture is running, we should stop it before close and ignore the event
- stopCapture();
- event->ignore();
- return;
- }
-
saveWindowGeometry();
/* If we're in the middle of stopping a capture, don't do anything;
@@ -1069,10 +1045,10 @@ void WiresharkMainWindow::dropEvent(QDropEvent *event)
if (cf_merge_files_to_tempfile(this, global_capture_opts.temp_dir, &tmpname, static_cast<int>(local_files.size()),
in_filenames,
wtap_pcapng_file_type_subtype(),
- FALSE) == CF_OK) {
+ false) == CF_OK) {
/* Merge succeeded; close the currently-open file and try
to open the merged capture file. */
- openCaptureFile(tmpname, QString(), WTAP_TYPE_AUTO, TRUE);
+ openCaptureFile(tmpname, QString(), WTAP_TYPE_AUTO, true);
}
g_free(tmpname);
@@ -1091,7 +1067,23 @@ void WiresharkMainWindow::loadWindowGeometry()
#ifndef Q_OS_MAC
if (recent.gui_geometry_main_maximized) {
- setWindowState(Qt::WindowMaximized);
+ // [save|restore]Geometry does a better job (on Linux and Windows)
+ // of restoring to the original monitor because it saves
+ // QGuiApplication::screens().indexOf(screen())
+ // (it also saves Qt::WindowFullScreen, restores the non-maximized
+ // size even when starting out maximized, etc.)
+ // Monitors of different DPI might still be tricky:
+ // https://bugreports.qt.io/browse/QTBUG-70721
+ // https://bugreports.qt.io/browse/QTBUG-77385
+ //
+ // We might eventually want to always use restoreGeometry, but
+ // for now at least use it just for maximized because it's better
+ // then what we've been doing.
+ if (recent.gui_geometry_main == nullptr ||
+ !restoreGeometry(QByteArray::fromHex(recent.gui_geometry_main))) {
+
+ setWindowState(Qt::WindowMaximized);
+ }
} else
#endif
{
@@ -1122,6 +1114,13 @@ void WiresharkMainWindow::loadWindowGeometry()
void WiresharkMainWindow::saveWindowGeometry()
{
+ if (prefs.gui_geometry_save_position ||
+ prefs.gui_geometry_save_size ||
+ prefs.gui_geometry_save_maximized) {
+ g_free(recent.gui_geometry_main);
+ recent.gui_geometry_main = g_strdup(saveGeometry().toHex().constData());
+ }
+
if (prefs.gui_geometry_save_position) {
recent.gui_geometry_main_x = pos().x();
recent.gui_geometry_main_y = pos().y();
@@ -1134,6 +1133,9 @@ void WiresharkMainWindow::saveWindowGeometry()
if (prefs.gui_geometry_save_maximized) {
// On macOS this is false when it shouldn't be
+ // XXX: Does save/restoreGeometry work any better on macOS
+ // for maximized windows? Apparently not:
+ // https://bugreports.qt.io/browse/QTBUG-100272
recent.gui_geometry_main_maximized = isMaximized();
}
@@ -1141,6 +1143,14 @@ void WiresharkMainWindow::saveWindowGeometry()
recent.gui_geometry_main_upper_pane = master_split_.sizes()[0];
}
+ g_free(recent.gui_geometry_main_master_split);
+ g_free(recent.gui_geometry_main_extra_split);
+ recent.gui_geometry_main_master_split = g_strdup(master_split_.saveState().toHex().constData());
+ recent.gui_geometry_main_extra_split = g_strdup(extra_split_.saveState().toHex().constData());
+
+ // Saving the QSplitter state is more accurate (#19361), but save
+ // the old GTK-style pane information for backwards compatibility
+ // for switching back and forth with older versions.
if (master_split_.sizes().length() > 2) {
recent.gui_geometry_main_lower_pane = master_split_.sizes()[1];
} else if (extra_split_.sizes().length() > 0) {
@@ -1151,7 +1161,7 @@ void WiresharkMainWindow::saveWindowGeometry()
// Our event loop becomes nested whenever we call update_progress_dlg, which
// includes several places in file.c. The GTK+ UI stays out of trouble by
// showing a modal progress dialog. We attempt to do the equivalent below by
-// disabling parts of the main window. At a minumum the ProgressFrame in the
+// disabling parts of the main window. At a minimum the ProgressFrame in the
// main status bar must remain accessible.
//
// We might want to do this any time the main status bar progress frame is
@@ -1193,7 +1203,7 @@ void WiresharkMainWindow::mergeCaptureFile()
if (prefs.gui_ask_unsaved) {
if (cf_has_unsaved_data(capture_file_.capFile())) {
QMessageBox msg_dialog;
- gchar *display_basename;
+ char *display_basename;
int response;
msg_dialog.setIcon(QMessageBox::Question);
@@ -1263,17 +1273,17 @@ void WiresharkMainWindow::mergeCaptureFile()
/* chronological order */
in_filenames[0] = g_strdup(capture_file_.capFile()->filename);
in_filenames[1] = qstring_strdup(file_name);
- merge_status = cf_merge_files_to_tempfile(this, global_capture_opts.temp_dir, &tmpname, 2, in_filenames, file_type, FALSE);
+ merge_status = cf_merge_files_to_tempfile(this, global_capture_opts.temp_dir, &tmpname, 2, in_filenames, file_type, false);
} else if (merge_dlg.mergeType() <= 0) {
/* prepend file */
in_filenames[0] = qstring_strdup(file_name);
in_filenames[1] = g_strdup(capture_file_.capFile()->filename);
- merge_status = cf_merge_files_to_tempfile(this, global_capture_opts.temp_dir, &tmpname, 2, in_filenames, file_type, TRUE);
+ merge_status = cf_merge_files_to_tempfile(this, global_capture_opts.temp_dir, &tmpname, 2, in_filenames, file_type, true);
} else {
/* append file */
in_filenames[0] = g_strdup(capture_file_.capFile()->filename);
in_filenames[1] = qstring_strdup(file_name);
- merge_status = cf_merge_files_to_tempfile(this, global_capture_opts.temp_dir, &tmpname, 2, in_filenames, file_type, TRUE);
+ merge_status = cf_merge_files_to_tempfile(this, global_capture_opts.temp_dir, &tmpname, 2, in_filenames, file_type, true);
}
g_free(in_filenames[0]);
@@ -1288,8 +1298,10 @@ void WiresharkMainWindow::mergeCaptureFile()
cf_close(capture_file_.capFile());
/* Try to open the merged capture file. */
+ // XXX - Just free rfcode and call
+ // openCaptureFile(tmpname, read_filter, WTAP_TYPE_AUTO, true);
CaptureFile::globalCapFile()->window = this;
- if (cf_open(CaptureFile::globalCapFile(), tmpname, WTAP_TYPE_AUTO, TRUE /* temporary file */, &err) != CF_OK) {
+ if (cf_open(CaptureFile::globalCapFile(), tmpname, WTAP_TYPE_AUTO, true /* temporary file */, &err) != CF_OK) {
/* We couldn't open it; fail. */
CaptureFile::globalCapFile()->window = NULL;
dfilter_free(rfcode);
@@ -1302,7 +1314,7 @@ void WiresharkMainWindow::mergeCaptureFile()
previous read filter attached to "cf"). */
cf_set_rfcode(CaptureFile::globalCapFile(), rfcode);
- switch (cf_read(CaptureFile::globalCapFile(), /*reloading=*/FALSE)) {
+ switch (cf_read(CaptureFile::globalCapFile(), /*reloading=*/false)) {
case CF_READ_OK:
case CF_READ_ERROR:
@@ -1320,8 +1332,7 @@ void WiresharkMainWindow::mergeCaptureFile()
return;
}
- /* Save the name of the containing directory specified in the path name. */
- mainApp->setLastOpenDirFromFilename(tmpname);
+ /* This is a tempfile; don't change the last open directory. */
g_free(tmpname);
main_ui_->statusBar->showExpert();
return;
@@ -1343,12 +1354,12 @@ void WiresharkMainWindow::importCaptureFile() {
return;
}
- openCaptureFile(import_dlg.capfileName());
+ openCaptureFile(import_dlg.capfileName(), QString(), WTAP_TYPE_AUTO, true);
}
bool WiresharkMainWindow::saveCaptureFile(capture_file *cf, bool dont_reopen) {
QString file_name;
- gboolean discard_comments;
+ bool discard_comments;
if (cf->is_tempfile) {
/* This is a temporary capture file, so saving it means saving
@@ -1358,7 +1369,7 @@ bool WiresharkMainWindow::saveCaptureFile(capture_file *cf, bool dont_reopen) {
probably pcapng, which supports comments and, if it's
not pcapng, let the user decide what they want to do
if they've added comments. */
- return saveAsCaptureFile(cf, FALSE, dont_reopen);
+ return saveAsCaptureFile(cf, false, dont_reopen);
} else {
if (cf->unsaved_changes) {
cf_write_status_t status;
@@ -1377,7 +1388,7 @@ bool WiresharkMainWindow::saveCaptureFile(capture_file *cf, bool dont_reopen) {
case SAVE:
/* The file can be saved in the specified format as is;
just drive on and save in the format they selected. */
- discard_comments = FALSE;
+ discard_comments = false;
break;
case SAVE_WITHOUT_COMMENTS:
@@ -1385,7 +1396,7 @@ bool WiresharkMainWindow::saveCaptureFile(capture_file *cf, bool dont_reopen) {
but it can be saved without the comments, and the user
said "OK, discard the comments", so save it in the
format they specified without the comments. */
- discard_comments = TRUE;
+ discard_comments = true;
break;
case SAVE_IN_ANOTHER_FORMAT:
@@ -1393,7 +1404,7 @@ bool WiresharkMainWindow::saveCaptureFile(capture_file *cf, bool dont_reopen) {
support comments, and the user said not to delete the
comments. Do a "Save As" so the user can select
one of those formats and choose a file name. */
- return saveAsCaptureFile(cf, TRUE, dont_reopen);
+ return saveAsCaptureFile(cf, true, dont_reopen);
case CANCELLED:
/* The user said "forget it". Just return. */
@@ -1461,8 +1472,8 @@ bool WiresharkMainWindow::saveAsCaptureFile(capture_file *cf, bool must_support_
int file_type;
wtap_compression_type compression_type;
cf_write_status_t status;
- gchar *dirname;
- gboolean discard_comments = FALSE;
+ char *dirname;
+ bool discard_comments = false;
if (!cf) {
return false;
@@ -1479,7 +1490,7 @@ bool WiresharkMainWindow::saveAsCaptureFile(capture_file *cf, bool must_support_
case SAVE:
/* The file can be saved in the specified format as is;
just drive on and save in the format they selected. */
- discard_comments = FALSE;
+ discard_comments = false;
break;
case SAVE_WITHOUT_COMMENTS:
@@ -1487,7 +1498,7 @@ bool WiresharkMainWindow::saveAsCaptureFile(capture_file *cf, bool must_support_
but it can be saved without the comments, and the user
said "OK, discard the comments", so save it in the
format they specified without the comments. */
- discard_comments = TRUE;
+ discard_comments = true;
break;
case SAVE_IN_ANOTHER_FORMAT:
@@ -1497,7 +1508,7 @@ bool WiresharkMainWindow::saveAsCaptureFile(capture_file *cf, bool must_support_
formats that don't support comments trimmed from it,
so run the dialog again, to let the user decide
whether to save in one of those formats or give up. */
- must_support_comments = TRUE;
+ must_support_comments = true;
continue;
case CANCELLED:
@@ -1518,11 +1529,6 @@ bool WiresharkMainWindow::saveAsCaptureFile(capture_file *cf, bool must_support_
}
compression_type = save_as_dlg.compressionType();
-#ifdef Q_OS_WIN
- // the Windows dialog does not fixup extensions, do it manually here.
- fileAddExtension(file_name, file_type, compression_type);
-#endif // Q_OS_WIN
-
//#ifndef _WIN32
// /* If the file exists and it's user-immutable or not writable,
// ask the user whether they want to override that. */
@@ -1564,7 +1570,7 @@ bool WiresharkMainWindow::saveAsCaptureFile(capture_file *cf, bool must_support_
cf->unsaved_changes = false; //we just saved so we signal that we have no unsaved changes
updateForUnsavedChanges(); // we update the title bar to remove the *
/* Add this filename to the list of recent files in the "Recent Files" submenu */
- add_menu_recent_capture_file(qUtf8Printable(file_name));
+ add_menu_recent_capture_file(qUtf8Printable(file_name), false);
return true;
case CF_WRITE_ERROR:
@@ -1585,7 +1591,7 @@ void WiresharkMainWindow::exportSelectedPackets() {
wtap_compression_type compression_type;
packet_range_t range;
cf_write_status_t status;
- gchar *dirname;
+ char *dirname;
bool discard_comments = false;
if (!capture_file_.capFile())
@@ -1593,8 +1599,8 @@ void WiresharkMainWindow::exportSelectedPackets() {
/* Init the packet range */
packet_range_init(&range, capture_file_.capFile());
- range.process_filtered = TRUE;
- range.include_dependents = TRUE;
+ range.process_filtered = true;
+ range.include_dependents = true;
QList<int> rows = packet_list_->selectedRows(true);
@@ -1614,7 +1620,7 @@ void WiresharkMainWindow::exportSelectedPackets() {
case SAVE:
/* The file can be saved in the specified format as is;
just drive on and save in the format they selected. */
- discard_comments = FALSE;
+ discard_comments = false;
break;
case SAVE_WITHOUT_COMMENTS:
@@ -1622,7 +1628,7 @@ void WiresharkMainWindow::exportSelectedPackets() {
but it can be saved without the comments, and the user
said "OK, discard the comments", so save it in the
format they specified without the comments. */
- discard_comments = TRUE;
+ discard_comments = true;
break;
case SAVE_IN_ANOTHER_FORMAT:
@@ -1650,7 +1656,7 @@ void WiresharkMainWindow::exportSelectedPackets() {
*/
if (files_identical(capture_file_.capFile()->filename, qUtf8Printable(file_name))) {
QMessageBox msg_box;
- gchar *display_basename = g_filename_display_basename(qUtf8Printable(file_name));
+ char *display_basename = g_filename_display_basename(qUtf8Printable(file_name));
msg_box.setIcon(QMessageBox::Critical);
msg_box.setText(QString(tr("Unable to export to \"%1\".").arg(display_basename)));
@@ -1674,10 +1680,6 @@ void WiresharkMainWindow::exportSelectedPackets() {
goto cleanup;
}
compression_type = esp_dlg.compressionType();
-#ifdef Q_OS_WIN
- // the Windows dialog does not fixup extensions, do it manually here.
- fileAddExtension(file_name, file_type, compression_type);
-#endif // Q_OS_WIN
//#ifndef _WIN32
// /* If the file exists and it's user-immutable or not writable,
@@ -1706,7 +1708,7 @@ void WiresharkMainWindow::exportSelectedPackets() {
if (discard_comments)
packet_list_->redrawVisiblePackets();
/* Add this filename to the list of recent files in the "Recent Files" submenu */
- add_menu_recent_capture_file(qUtf8Printable(file_name));
+ add_menu_recent_capture_file(qUtf8Printable(file_name), false);
goto cleanup;
case CF_WRITE_ERROR:
@@ -1740,110 +1742,6 @@ void WiresharkMainWindow::exportDissections(export_type_e export_type) {
ed_dlg->show();
}
-#ifdef Q_OS_WIN
-/*
- * Ensure that:
- *
- * If the file is to be compressed:
- *
- * if there is a set of extensions used by the file type to be used,
- * the file name has one of those extensions followed by the extension
- * for the compression type to be used;
- *
- * otherwise, the file name has the extension for the compression type
- * to be used;
- *
- * otherwise:
- *
- * if there is a set of extensions used by the file type to be used,
- * the file name has one of those extensions.
- */
-void WiresharkMainWindow::fileAddExtension(QString &file_name, int file_type, wtap_compression_type compression_type) {
- QString file_name_lower;
- GSList *extensions_list;
- const char *compressed_file_extension;
- gboolean add_extension_for_file_type;
-
- /* Lower-case the file name, so the extension matching is case-insensitive. */
- file_name_lower = file_name.toLower();
-
- /* Get a list of all extensions used for this file type; don't
- include the ones with compression type extensions, as we
- only want to check for the extension for the compression
- type we'll be using. */
- extensions_list = wtap_get_file_extensions_list(file_type, FALSE);
-
- /* Get the extension for the compression type we'll be using;
- NULL is returned if the type isn't supported or compression
- is not being done. */
- compressed_file_extension = wtap_compression_type_extension(compression_type);
-
- if (extensions_list != NULL) {
- GSList *extension;
-
- /* This file type has one or more extensions.
- Start out assuming we need to add the default one. */
- add_extension_for_file_type = TRUE;
-
- /* OK, see if the file has one of those extensions, followed
- by the appropriate compression type extension if it's to be
- compressed. */
- for (extension = extensions_list; extension != NULL;
- extension = g_slist_next(extension)) {
- QString file_suffix = QString(".") + (char *)extension->data;
- if (compressed_file_extension != NULL)
- file_suffix += QString(".") + compressed_file_extension;
- if (file_name_lower.endsWith(file_suffix)) {
- /*
- * The file name has one of the extensions for this file
- * type, followed by a compression type extension if
- * appropriate, so we don't need to add an extension for
- * the file type or the compression type.
- */
- add_extension_for_file_type = FALSE;
- break;
- }
- }
- } else {
- /* We have no extensions for this file type. Just check
- to see if we need to add an extension for the compressed
- file type.
-
- Start out assuming we do. */
- add_extension_for_file_type = TRUE;
- if (compressed_file_extension != NULL) {
- QString file_suffix = QString(".") + compressed_file_extension;
- if (file_name_lower.endsWith(file_suffix)) {
- /*
- * The file name has the appropriate compressed file extension,
- * so we don't need to add an extension for the compression
- * type.
- */
- add_extension_for_file_type = FALSE;
- }
- }
- }
-
- /*
- * If we need to add an extension for the file type or compressed
- * file type, do so.
- */
- if (add_extension_for_file_type) {
- if (wtap_default_file_extension(file_type) != NULL) {
- /* This file type has a default extension; append it. */
- file_name += QString(".") + wtap_default_file_extension(file_type);
- }
- if (compression_type != WTAP_UNCOMPRESSED) {
- /*
- * The file is to be compressed, so append the extension for
- * its compression type.
- */
- file_name += QString(".") + compressed_file_extension;
- }
- }
-}
-#endif // Q_OS_WIN
-
bool WiresharkMainWindow::testCaptureFileClose(QString before_what, FileCloseContext context) {
bool capture_in_progress = false;
bool do_close_file = false;
@@ -1891,7 +1789,7 @@ bool WiresharkMainWindow::testCaptureFileClose(QString before_what, FileCloseCon
return false;
}
- QMessageBox msg_dialog;
+ QMessageBox msg_dialog(this);
QString question;
QString infotext;
QPushButton *save_button;
@@ -1916,7 +1814,7 @@ bool WiresharkMainWindow::testCaptureFileClose(QString before_what, FileCloseCon
}
} else {
// No capture in progress and not a tempfile, so this is not unsaved packets
- gchar *display_basename = g_filename_display_basename(capture_file_.capFile()->filename);
+ char *display_basename = g_filename_display_basename(capture_file_.capFile()->filename);
question = tr("Do you want to save the changes you've made to the capture file \"%1\"%2?").arg(display_basename, before_what);
infotext = tr("Your changes will be lost if you don't save them.");
g_free(display_basename);
@@ -1991,7 +1889,7 @@ bool WiresharkMainWindow::testCaptureFileClose(QString before_what, FileCloseCon
*/
QList<QAbstractButton *> buttons = msg_dialog.buttons();
for (int i = 0; i < buttons.size(); ++i) {
- QPushButton *button = static_cast<QPushButton *>(buttons.at(i));;
+ QPushButton *button = static_cast<QPushButton *>(buttons.at(i));
button->setAutoDefault(false);
}
@@ -2001,7 +1899,13 @@ bool WiresharkMainWindow::testCaptureFileClose(QString before_what, FileCloseCon
*/
discard_button->setFocus();
#endif
-
+ /*
+ * On Windows, if multiple Wireshark processes are open, another
+ * application has focus, and "Close all [Wireshark] windows" is
+ * chosen from the taskbar, we need to activate the window to
+ * at least flash the taskbar (#16309).
+ */
+ activateWindow();
msg_dialog.exec();
/* According to the Qt doc:
* when using QMessageBox with custom buttons, exec() function returns an opaque value.
@@ -2119,7 +2023,7 @@ void WiresharkMainWindow::findTextCodecs() {
// annoying to properly place IBM00858 and IBM00924 in the middle of
// code page numbers not zero padded to 5 digits.
// We could manipulate the key further to have more commonly used
- // charsets earlier. IANA MIB ordering would be unxpected:
+ // charsets earlier. IANA MIB ordering would be unexpected:
// https://www.iana.org/assignments/character-sets/character-sets.xml
// For data about use in HTTP (other protocols can be quite different):
// https://w3techs.com/technologies/overview/character_encoding
@@ -2152,11 +2056,10 @@ void WiresharkMainWindow::initMainToolbarIcons()
main_ui_->actionCaptureRestart->setIcon(StockIcon("x-capture-restart"));
main_ui_->actionCaptureOptions->setIcon(StockIcon("x-capture-options"));
- // Menu icons are disabled in main_window.ui for these items.
+ // Menu icons are disabled in wireshark_main_window.ui for these File-> items.
main_ui_->actionFileOpen->setIcon(StockIcon("document-open"));
main_ui_->actionFileSave->setIcon(StockIcon("x-capture-file-save"));
main_ui_->actionFileClose->setIcon(StockIcon("x-capture-file-close"));
- main_ui_->actionViewReload->setIcon(StockIcon("x-capture-file-reload"));
main_ui_->actionEditFindPacket->setIcon(StockIcon("edit-find"));
main_ui_->actionGoPreviousPacket->setIcon(StockIcon("go-previous"));
@@ -2183,6 +2086,8 @@ void WiresharkMainWindow::initMainToolbarIcons()
main_ui_->actionViewZoomOut->setIcon(StockIcon("zoom-out"));
main_ui_->actionViewNormalSize->setIcon(StockIcon("zoom-original"));
main_ui_->actionViewResizeColumns->setIcon(StockIcon("x-resize-columns"));
+ main_ui_->actionViewResetLayout->setIcon(StockIcon("x-reset-layout_2"));
+ main_ui_->actionViewReload->setIcon(StockIcon("x-capture-file-reload"));
main_ui_->actionNewDisplayFilterExpression->setIcon(StockIcon("list-add"));
}
@@ -2219,7 +2124,7 @@ void WiresharkMainWindow::initShowHideMainWidgets()
/* Initially hide the additional toolbars menus */
main_ui_->menuAdditionalToolbars->menuAction()->setVisible(false);
- connect(show_hide_actions_, SIGNAL(triggered(QAction*)), this, SLOT(showHideMainWidgets(QAction*)));
+ connect(show_hide_actions_, &QActionGroup::triggered, this, &WiresharkMainWindow::showHideMainWidgets);
}
void WiresharkMainWindow::initTimeDisplayFormatMenu()
@@ -2246,7 +2151,7 @@ void WiresharkMainWindow::initTimeDisplayFormatMenu()
time_display_actions_->addAction(tda);
}
- connect(time_display_actions_, SIGNAL(triggered(QAction*)), this, SLOT(setTimestampFormat(QAction*)));
+ connect(time_display_actions_, &QActionGroup::triggered, this, &WiresharkMainWindow::setTimestampFormat);
}
void WiresharkMainWindow::initTimePrecisionFormatMenu()
@@ -2274,7 +2179,7 @@ void WiresharkMainWindow::initTimePrecisionFormatMenu()
time_precision_actions_->addAction(tpa);
}
- connect(time_precision_actions_, SIGNAL(triggered(QAction*)), this, SLOT(setTimestampPrecision(QAction*)));
+ connect(time_precision_actions_, &QActionGroup::triggered, this, &WiresharkMainWindow::setTimestampPrecision);
}
// Menu items which will be disabled when we freeze() and whose state will
@@ -2284,10 +2189,10 @@ void WiresharkMainWindow::initFreezeActions()
QList<QAction *> freeze_actions = QList<QAction *>()
<< main_ui_->actionFileClose
<< main_ui_->actionViewReload
- << main_ui_->actionEditMarkPacket
+ << main_ui_->actionEditMarkSelected
<< main_ui_->actionEditMarkAllDisplayed
<< main_ui_->actionEditUnmarkAllDisplayed
- << main_ui_->actionEditIgnorePacket
+ << main_ui_->actionEditIgnoreSelected
<< main_ui_->actionEditIgnoreAllDisplayed
<< main_ui_->actionEditUnignoreAllDisplayed
<< main_ui_->actionEditSetTimeReference
@@ -2315,8 +2220,8 @@ void WiresharkMainWindow::initConversationMenus()
ConversationAction *conv_action = new ConversationAction(main_ui_->menuConversationFilter, conv_filter);
main_ui_->menuConversationFilter->addAction(conv_action);
- connect(this, SIGNAL(packetInfoChanged(_packet_info*)), conv_action, SLOT(setPacketInfo(_packet_info*)));
- connect(conv_action, SIGNAL(triggered()), this, SLOT(applyConversationFilter()), Qt::QueuedConnection);
+ connect(this, &WiresharkMainWindow::packetInfoChanged, conv_action, &ConversationAction::setPacketInfo);
+ connect(conv_action, &ConversationAction::triggered, this, &WiresharkMainWindow::applyConversationFilter, Qt::QueuedConnection);
// Packet list context menu items
packet_list_->conversationMenu()->addAction(conv_action);
@@ -2330,15 +2235,15 @@ void WiresharkMainWindow::initConversationMenus()
conv_action->setIcon(cc_action->icon());
conv_action->setColorNumber(i++);
submenu->addAction(conv_action);
- connect(this, SIGNAL(packetInfoChanged(_packet_info*)), conv_action, SLOT(setPacketInfo(_packet_info*)));
- connect(conv_action, SIGNAL(triggered()), this, SLOT(colorizeActionTriggered()));
+ connect(this, &WiresharkMainWindow::packetInfoChanged, conv_action, &ConversationAction::setPacketInfo);
+ connect(conv_action, &ConversationAction::triggered, this, &WiresharkMainWindow::colorizeActionTriggered);
}
conv_action = new ConversationAction(submenu, conv_filter);
conv_action->setText(main_ui_->actionViewColorizeNewColoringRule->text());
submenu->addAction(conv_action);
- connect(this, SIGNAL(packetInfoChanged(_packet_info*)), conv_action, SLOT(setPacketInfo(_packet_info*)));
- connect(conv_action, SIGNAL(triggered()), this, SLOT(colorizeActionTriggered()));
+ connect(this, &WiresharkMainWindow::packetInfoChanged, conv_action, &ConversationAction::setPacketInfo);
+ connect(conv_action, &ConversationAction::triggered, this, &WiresharkMainWindow::colorizeActionTriggered);
// Proto tree conversation menu is filled in in ProtoTree::contextMenuEvent.
// We should probably do that here.
@@ -2353,15 +2258,15 @@ void WiresharkMainWindow::initConversationMenus()
colorize_action->setIcon(cc_action->icon());
colorize_action->setColorNumber(i++);
proto_tree_->colorizeMenu()->addAction(colorize_action);
- connect(this, SIGNAL(fieldFilterChanged(QByteArray)), colorize_action, SLOT(setFieldFilter(QByteArray)));
- connect(colorize_action, SIGNAL(triggered()), this, SLOT(colorizeActionTriggered()));
+ connect(this, &WiresharkMainWindow::fieldFilterChanged, colorize_action, &ColorizeAction::setFieldFilter);
+ connect(colorize_action, &ColorizeAction::triggered, this, &WiresharkMainWindow::colorizeActionTriggered);
}
colorize_action = new ColorizeAction(proto_tree_->colorizeMenu());
colorize_action->setText(main_ui_->actionViewColorizeNewColoringRule->text());
proto_tree_->colorizeMenu()->addAction(colorize_action);
- connect(this, SIGNAL(fieldFilterChanged(QByteArray)), colorize_action, SLOT(setFieldFilter(QByteArray)));
- connect(colorize_action, SIGNAL(triggered()), this, SLOT(colorizeActionTriggered()));
+ connect(this, &WiresharkMainWindow::fieldFilterChanged, colorize_action, &ColorizeAction::setFieldFilter);
+ connect(colorize_action, &ColorizeAction::triggered, this, &WiresharkMainWindow::colorizeActionTriggered);
}
bool WiresharkMainWindow::addExportObjectsMenuItem(const void *, void *value, void *userdata)
@@ -2375,9 +2280,9 @@ bool WiresharkMainWindow::addExportObjectsMenuItem(const void *, void *value, vo
//initially disable until a file is loaded (then file signals will take over)
export_action->setEnabled(false);
- connect(&window->capture_file_, SIGNAL(captureEvent(CaptureEvent)), export_action, SLOT(captureFileEvent(CaptureEvent)));
- connect(export_action, SIGNAL(triggered()), window, SLOT(applyExportObject()));
- return FALSE;
+ connect(&window->capture_file_, &CaptureFile::captureEvent, export_action, &ExportObjectAction::captureFileEvent);
+ connect(export_action, &ExportObjectAction::triggered, window, &WiresharkMainWindow::applyExportObject);
+ return false;
}
void WiresharkMainWindow::initExportObjectsMenus()
@@ -2417,12 +2322,14 @@ bool WiresharkMainWindow::addFollowStreamMenuItem(const void *key, void *value,
follow_action->setText(tr("HTTP/2 Stream"));
} else if (g_strcmp0(short_name, "SIP") == 0) {
follow_action->setText(tr("SIP Call"));
+ } else if (g_strcmp0(short_name, "USBCOM") == 0) {
+ follow_action->setText(tr("USB CDC Data"));
}
connect(follow_action, &QAction::triggered, window,
[window, follow]() { window->openFollowStreamDialog(get_follow_proto_id(follow)); },
Qt::QueuedConnection);
- return FALSE;
+ return false;
}
void WiresharkMainWindow::initFollowStreamMenus()
@@ -2434,24 +2341,8 @@ void WiresharkMainWindow::initFollowStreamMenus()
// Titlebar
void WiresharkMainWindow::setTitlebarForCaptureFile()
{
- if (capture_file_.capFile() && capture_file_.capFile()->filename) {
- setWSWindowTitle(QString("[*]%1").arg(capture_file_.fileDisplayName()));
- //
- // XXX - on non-Mac platforms, put in the application
- // name? Or do so only for temporary files?
- //
- if (!capture_file_.capFile()->is_tempfile) {
- //
- // Set the file path; that way, for macOS, it'll set the
- // "proxy icon".
- //
- setWindowFilePath(capture_file_.filePath());
- }
- setWindowModified(cf_has_unsaved_data(capture_file_.capFile()));
- } else {
- /* We have no capture file. */
- setWSWindowTitle();
- }
+ use_capturing_title_ = false;
+ updateTitlebar();
}
QString WiresharkMainWindow::replaceWindowTitleVariables(QString title)
@@ -2459,6 +2350,18 @@ QString WiresharkMainWindow::replaceWindowTitleVariables(QString title)
title.replace("%P", get_profile_name());
title.replace("%V", get_ws_vcs_version_info());
+#ifdef HAVE_LIBPCAP
+ if (global_commandline_info.capture_comments) {
+ // Use the first capture comment from command line.
+ title.replace("%C", (char *)g_ptr_array_index(global_commandline_info.capture_comments, 0));
+ } else {
+ // No capture comment.
+ title.remove("%C");
+ }
+#else
+ title.remove("%C");
+#endif
+
if (title.contains("%F")) {
// %F is file path of the capture file.
if (capture_file_.capFile()) {
@@ -2528,10 +2431,30 @@ void WiresharkMainWindow::setWSWindowTitle(QString title)
void WiresharkMainWindow::setTitlebarForCaptureInProgress()
{
- if (capture_file_.capFile()) {
+ use_capturing_title_ = true;
+ updateTitlebar();
+}
+
+void WiresharkMainWindow::updateTitlebar()
+{
+ if (use_capturing_title_ && capture_file_.capFile()) {
setWSWindowTitle(tr("Capturing from %1").arg(cf_get_tempfile_source(capture_file_.capFile())));
+ } else if (capture_file_.capFile() && capture_file_.capFile()->filename) {
+ setWSWindowTitle(QString("[*]%1").arg(capture_file_.fileDisplayName()));
+ //
+ // XXX - on non-Mac platforms, put in the application
+ // name? Or do so only for temporary files?
+ //
+ if (!capture_file_.capFile()->is_tempfile) {
+ //
+ // Set the file path; that way, for macOS, it'll set the
+ // "proxy icon".
+ //
+ setWindowFilePath(capture_file_.filePath());
+ }
+ setWindowModified(cf_has_unsaved_data(capture_file_.capFile()));
} else {
- /* We have no capture in progress. */
+ /* We have no capture file. */
setWSWindowTitle();
}
}
@@ -2708,7 +2631,7 @@ void WiresharkMainWindow::setWindowIcon(const QIcon &icon) {
}
void WiresharkMainWindow::updateForUnsavedChanges() {
- setTitlebarForCaptureFile();
+ updateTitlebar();
setMenusForCaptureFile();
}
@@ -2722,7 +2645,7 @@ void WiresharkMainWindow::changeEvent(QEvent* event)
main_ui_->retranslateUi(this);
// make sure that the "Clear Menu" item is retranslated
mainApp->emitAppSignal(WiresharkApplication::RecentCapturesChanged);
- setTitlebarForCaptureFile();
+ updateTitlebar();
break;
case QEvent::LocaleChange: {
QString locale = QLocale::system().name();
@@ -2773,6 +2696,13 @@ void WiresharkMainWindow::addMenuActions(QList<QAction *> &actions, int menu_gro
switch (menu_group) {
case REGISTER_PACKET_ANALYZE_GROUP_UNSORTED:
case REGISTER_PACKET_STAT_GROUP_UNSORTED:
+ case REGISTER_STAT_GROUP_GENERIC:
+ // XXX - The Lua documentation claims that ANALYZE_GROUP_UNSORTED
+ // is under the Analyze menu, and STAT_GROUP_GENERIC and
+ // PACKET_STAT_GROUP_UNSORTED are distinguished by whether they
+ // go before the separator in the group of non protocol-specific
+ // actions or after the separator with the protocol-specific
+ // actions. We currently put them all in the same place.
main_ui_->menuStatistics->insertAction(
main_ui_->actionStatistics_REGISTER_STAT_GROUP_UNSORTED,
action);
@@ -2783,24 +2713,30 @@ void WiresharkMainWindow::addMenuActions(QList<QAction *> &actions, int menu_gro
case REGISTER_STAT_GROUP_RSERPOOL:
main_ui_->menuRSerPool->addAction(action);
break;
- case REGISTER_STAT_GROUP_TELEPHONY:
+ case REGISTER_TELEPHONY_GROUP_UNSORTED:
main_ui_->menuTelephony->addAction(action);
break;
- case REGISTER_STAT_GROUP_TELEPHONY_ANSI:
+ case REGISTER_TELEPHONY_GROUP_ANSI:
main_ui_->menuANSI->addAction(action);
break;
- case REGISTER_STAT_GROUP_TELEPHONY_GSM:
+ case REGISTER_TELEPHONY_GROUP_GSM:
main_ui_->menuGSM->addAction(action);
break;
- case REGISTER_STAT_GROUP_TELEPHONY_LTE:
+ case REGISTER_TELEPHONY_GROUP_3GPP_UU:
main_ui_->menuLTE->addAction(action);
break;
- case REGISTER_STAT_GROUP_TELEPHONY_MTP3:
+ case REGISTER_TELEPHONY_GROUP_MTP3:
main_ui_->menuMTP3->addAction(action);
break;
+ case REGISTER_TELEPHONY_GROUP_SCTP:
+ // XXX - There are two SCTP menus, under Analyze and Telephony,
+ // that have the same default actions. The default actions from
+ // Analyze are copied to the PacketList context menu.
+ main_ui_->menuTelephonySCTP->addAction(action);
+ break;
case REGISTER_TOOLS_GROUP_UNSORTED:
{
- // Allow the creation of submenus. Mimics the behavor of
+ // Allow the creation of submenus. Mimics the behavior of
// ui/gtk/main_menubar.c:add_menu_item_to_main_menubar
// and GtkUIManager.
//
@@ -2829,9 +2765,9 @@ void WiresharkMainWindow::addMenuActions(QList<QAction *> &actions, int menu_gro
// distinguish various types of actions. Setting their objectName
// seems to work OK.
if (action->objectName() == TapParameterDialog::actionName()) {
- connect(action, SIGNAL(triggered(bool)), this, SLOT(openTapParameterDialog()));
+ connect(action, &QAction::triggered, this, [=]() { openTapParameterDialog(); });
} else if (action->objectName() == FunnelStatistics::actionName()) {
- connect(action, SIGNAL(triggered(bool)), funnel_statistics_, SLOT(funnelActionTriggered()));
+ connect(action, &QAction::triggered, funnel_statistics_, &FunnelStatistics::funnelActionTriggered);
}
}
}
@@ -2841,6 +2777,7 @@ void WiresharkMainWindow::removeMenuActions(QList<QAction *> &actions, int menu_
switch (menu_group) {
case REGISTER_PACKET_ANALYZE_GROUP_UNSORTED:
case REGISTER_PACKET_STAT_GROUP_UNSORTED:
+ case REGISTER_STAT_GROUP_GENERIC:
main_ui_->menuStatistics->removeAction(action);
break;
case REGISTER_STAT_GROUP_RESPONSE_TIME:
@@ -2849,21 +2786,24 @@ void WiresharkMainWindow::removeMenuActions(QList<QAction *> &actions, int menu_
case REGISTER_STAT_GROUP_RSERPOOL:
main_ui_->menuRSerPool->removeAction(action);
break;
- case REGISTER_STAT_GROUP_TELEPHONY:
+ case REGISTER_TELEPHONY_GROUP_UNSORTED:
main_ui_->menuTelephony->removeAction(action);
break;
- case REGISTER_STAT_GROUP_TELEPHONY_ANSI:
+ case REGISTER_TELEPHONY_GROUP_ANSI:
main_ui_->menuANSI->removeAction(action);
break;
- case REGISTER_STAT_GROUP_TELEPHONY_GSM:
+ case REGISTER_TELEPHONY_GROUP_GSM:
main_ui_->menuGSM->removeAction(action);
break;
- case REGISTER_STAT_GROUP_TELEPHONY_LTE:
+ case REGISTER_TELEPHONY_GROUP_3GPP_UU:
main_ui_->menuLTE->removeAction(action);
break;
- case REGISTER_STAT_GROUP_TELEPHONY_MTP3:
+ case REGISTER_TELEPHONY_GROUP_MTP3:
main_ui_->menuMTP3->removeAction(action);
break;
+ case REGISTER_TELEPHONY_GROUP_SCTP:
+ main_ui_->menuTelephonySCTP->removeAction(action);
+ break;
case REGISTER_TOOLS_GROUP_UNSORTED:
{
// Allow removal of submenus.
@@ -2894,12 +2834,12 @@ void WiresharkMainWindow::removeMenuActions(QList<QAction *> &actions, int menu_
void WiresharkMainWindow::addDynamicMenus()
{
// Manual additions
- mainApp->addDynamicMenuGroupItem(REGISTER_STAT_GROUP_TELEPHONY_GSM, main_ui_->actionTelephonyGsmMapSummary);
- mainApp->addDynamicMenuGroupItem(REGISTER_STAT_GROUP_TELEPHONY_LTE, main_ui_->actionTelephonyLteMacStatistics);
- mainApp->addDynamicMenuGroupItem(REGISTER_STAT_GROUP_TELEPHONY_LTE, main_ui_->actionTelephonyLteRlcStatistics);
- mainApp->addDynamicMenuGroupItem(REGISTER_STAT_GROUP_TELEPHONY_LTE, main_ui_->actionTelephonyLteRlcGraph);
- mainApp->addDynamicMenuGroupItem(REGISTER_STAT_GROUP_TELEPHONY_MTP3, main_ui_->actionTelephonyMtp3Summary);
- mainApp->addDynamicMenuGroupItem(REGISTER_STAT_GROUP_TELEPHONY, main_ui_->actionTelephonySipFlows);
+ mainApp->addDynamicMenuGroupItem(REGISTER_TELEPHONY_GROUP_GSM, main_ui_->actionTelephonyGsmMapSummary);
+ mainApp->addDynamicMenuGroupItem(REGISTER_TELEPHONY_GROUP_3GPP_UU, main_ui_->actionTelephonyLteMacStatistics);
+ mainApp->addDynamicMenuGroupItem(REGISTER_TELEPHONY_GROUP_3GPP_UU, main_ui_->actionTelephonyLteRlcStatistics);
+ mainApp->addDynamicMenuGroupItem(REGISTER_TELEPHONY_GROUP_3GPP_UU, main_ui_->actionTelephonyLteRlcGraph);
+ mainApp->addDynamicMenuGroupItem(REGISTER_TELEPHONY_GROUP_MTP3, main_ui_->actionTelephonyMtp3Summary);
+ mainApp->addDynamicMenuGroupItem(REGISTER_TELEPHONY_GROUP_UNSORTED, main_ui_->actionTelephonySipFlows);
// Fill in each menu
foreach(register_stat_group_t menu_group, menu_groups_) {
@@ -2910,16 +2850,16 @@ void WiresharkMainWindow::addDynamicMenus()
// Empty menus don't show up: https://bugreports.qt.io/browse/QTBUG-33728
// We've added a placeholder in order to make sure some menus are visible.
// Hide them as needed.
- if (mainApp->dynamicMenuGroupItems(REGISTER_STAT_GROUP_TELEPHONY_ANSI).length() > 0) {
+ if (mainApp->dynamicMenuGroupItems(REGISTER_TELEPHONY_GROUP_ANSI).length() > 0) {
main_ui_->actionTelephonyANSIPlaceholder->setVisible(false);
}
- if (mainApp->dynamicMenuGroupItems(REGISTER_STAT_GROUP_TELEPHONY_GSM).length() > 0) {
+ if (mainApp->dynamicMenuGroupItems(REGISTER_TELEPHONY_GROUP_GSM).length() > 0) {
main_ui_->actionTelephonyGSMPlaceholder->setVisible(false);
}
- if (mainApp->dynamicMenuGroupItems(REGISTER_STAT_GROUP_TELEPHONY_LTE).length() > 0) {
+ if (mainApp->dynamicMenuGroupItems(REGISTER_TELEPHONY_GROUP_3GPP_UU).length() > 0) {
main_ui_->actionTelephonyLTEPlaceholder->setVisible(false);
}
- if (mainApp->dynamicMenuGroupItems(REGISTER_STAT_GROUP_TELEPHONY_MTP3).length() > 0) {
+ if (mainApp->dynamicMenuGroupItems(REGISTER_TELEPHONY_GROUP_MTP3).length() > 0) {
main_ui_->actionTelephonyMTP3Placeholder->setVisible(false);
}
}
@@ -2938,7 +2878,7 @@ void WiresharkMainWindow::reloadDynamicMenus()
mainApp->clearRemovedMenuGroupItems();
}
-void WiresharkMainWindow::externalMenuHelper(ext_menu_t * menu, QMenu * subMenu, gint depth)
+void WiresharkMainWindow::externalMenuHelper(ext_menu_t * menu, QMenu * subMenu, int depth)
{
QAction * itemAction = Q_NULLPTR;
ext_menubar_t * item = Q_NULLPTR;
@@ -3127,7 +3067,7 @@ QString WiresharkMainWindow::findRtpStreams(QVector<rtpstream_id_t *> *stream_id
{
rtpstream_tapinfo_t tapinfo;
rtpstream_id_t *new_id;
- const gchar filter_text[] = "rtp && rtp.version == 2 && rtp.ssrc && (ip || ipv6)";
+ const char filter_text[] = "rtp && rtp.version == 2 && rtp.ssrc && (ip || ipv6)";
dfilter_t *sfcode;
df_error_t *df_err = NULL;
diff --git a/ui/qt/wireshark_main_window.h b/ui/qt/wireshark_main_window.h
index 781a1b28..a1cc8b17 100644
--- a/ui/qt/wireshark_main_window.h
+++ b/ui/qt/wireshark_main_window.h
@@ -40,8 +40,6 @@
#include <config.h>
-#include <glib.h>
-
#include "file.h"
#include "ui/ws_ui_util.h"
@@ -123,7 +121,7 @@ public:
void removeAdditionalToolbar(QString toolbarName);
void addInterfaceToolbar(const iface_toolbar *toolbar_entry);
- void removeInterfaceToolbar(const gchar *menu_title);
+ void removeInterfaceToolbar(const char *menu_title);
QString getMwFileName();
void setMwFileName(QString fileName);
@@ -181,6 +179,7 @@ private:
bool capture_stopping_;
bool capture_filter_valid_;
+ bool use_capturing_title_;
#ifdef HAVE_LIBPCAP
capture_session cap_session_;
CaptureOptionsDialog *capture_options_dialog_;
@@ -233,10 +232,10 @@ private:
QString replaceWindowTitleVariables(QString title);
void updateStyleSheet();
- void externalMenuHelper(ext_menu_t * menu, QMenu * subMenu, gint depth);
+ void externalMenuHelper(ext_menu_t * menu, QMenu * subMenu, int depth);
void setForCaptureInProgress(bool capture_in_progress = false, bool handle_toolbars = false, GArray *ifaces = NULL);
- QMenu* findOrAddMenu(QMenu *parent_menu, QString& menu_text);
+ QMenu* findOrAddMenu(QMenu *parent_menu, const QStringList& menu_parts);
void captureFileReadStarted(const QString &action);
@@ -269,11 +268,11 @@ public slots:
* @param cf_path Path to the file.
* @param display_filter Display filter to apply. May be empty.
* @param type File type.
- * @param is_tempfile TRUE/FALSE.
+ * @param is_tempfile true/false.
* @return True on success, false on failure.
*/
// XXX We might want to return a cf_read_status_t or a CaptureFile.
- bool openCaptureFile(QString cf_path, QString display_filter, unsigned int type, gboolean is_tempfile = FALSE);
+ bool openCaptureFile(QString cf_path, QString display_filter, unsigned int type, bool is_tempfile = false);
bool openCaptureFile(QString cf_path = QString(), QString display_filter = QString()) { return openCaptureFile(cf_path, display_filter, WTAP_TYPE_AUTO); }
void filterPackets(QString new_filter = QString(), bool force = false);
void updateForUnsavedChanges();
@@ -299,8 +298,8 @@ public slots:
void captureFileClosing();
void captureFileClosed();
- void launchRLCGraph(bool channelKnown, guint16 ueid, guint8 rlcMode,
- guint16 channelType, guint16 channelId, guint8 direction);
+ void launchRLCGraph(bool channelKnown, uint8_t RAT, uint16_t ueid, uint8_t rlcMode,
+ uint16_t channelType, uint16_t channelId, uint8_t direction);
void rtpPlayerDialogReplaceRtpStreams(QVector<rtpstream_id_t *> stream_ids);
void rtpPlayerDialogAddRtpStreams(QVector<rtpstream_id_t *> stream_ids);
@@ -332,6 +331,7 @@ private slots:
*/
void startCapture(QStringList);
void startCapture();
+ void pushLiveCaptureInProgress();
void popLiveCaptureInProgress();
void stopCapture();
@@ -363,6 +363,7 @@ private slots:
void addPluginIFStructures();
QMenu * searchSubMenu(QString objectName);
void activatePluginIFToolbar(bool);
+ void updateTitlebar();
void startInterfaceCapture(bool valid, const QString capture_filter);
@@ -398,7 +399,7 @@ private slots:
// Automatically connected slots ("on_<object>_<signal>").
//
- // The slots below follow the naming conventaion described in
+ // The slots below follow the naming convention described in
// https://doc.qt.io/archives/qt-4.8/qmetaobject.html#connectSlotsByName
// and are automatically connected at initialization time via
// main_ui_->setupUi, which in turn calls connectSlotsByName.
@@ -423,7 +424,7 @@ private slots:
void editConfigurationProfiles();
void editTimeShiftFinished(int);
void addPacketCommentFinished(PacketCommentDialog* pc_dialog, int result);
- void editPacketCommentFinished(PacketCommentDialog* pc_dialog, int result, guint nComment);
+ void editPacketCommentFinished(PacketCommentDialog* pc_dialog, int result, unsigned nComment);
void deleteAllPacketComments();
void deleteAllPacketCommentsFinished(int result);
void injectSecrets();
@@ -464,7 +465,7 @@ private slots:
void applyConversationFilter();
void applyExportObject();
- void openFollowStreamDialog(int proto_id, guint stream_num, guint sub_stream_num, bool use_stream_index = true);
+ void openFollowStreamDialog(int proto_id, unsigned stream_num, unsigned sub_stream_num, bool use_stream_index = true);
void openFollowStreamDialog(int proto_id);
void statCommandExpertInfo(const char *, void *);
@@ -494,8 +495,9 @@ private slots:
void statCommandWlanStatistics(const char *arg, void *);
- void openStatisticsTreeDialog(const gchar *abbr);
+ void openStatisticsTreeDialog(const char *abbr);
void statCommandIOGraph(const char *, void *);
+ void showIOGraphDialog(io_graph_item_unit_t value_units, QString);
void connectTelephonyMenuActions();
diff --git a/ui/qt/wireshark_main_window.ui b/ui/qt/wireshark_main_window.ui
index cb01e642..5ff9f8e5 100644
--- a/ui/qt/wireshark_main_window.ui
+++ b/ui/qt/wireshark_main_window.ui
@@ -471,6 +471,13 @@
<addaction name="actionStatisticsBACappObjectId"/>
<addaction name="actionStatisticsBACappService"/>
</widget>
+ <widget class="QMenu" name="menuDNS">
+ <property name="title">
+ <string>DNS</string>
+ </property>
+ <addaction name="actionStatisticsDNS"/>
+ <addaction name="actionStatisticsDNS_QR"/>
+ </widget>
<widget class="QMenu" name="menuHTTP">
<property name="title">
<string>HTTP</string>
@@ -554,7 +561,7 @@
<addaction name="actionStatisticsANCP"/>
<addaction name="menuBACnet"/>
<addaction name="actionStatisticsCollectd"/>
- <addaction name="actionStatisticsDNS"/>
+ <addaction name="menuDNS"/>
<addaction name="actionStatisticsFlowGraph"/>
<addaction name="actionStatisticsHART_IP"/>
<addaction name="actionStatisticsHpfeeds"/>
@@ -608,7 +615,7 @@
</widget>
<widget class="QMenu" name="menuLTE">
<property name="title">
- <string>&amp;LTE</string>
+ <string>&amp;3GPP Uu</string>
</property>
<addaction name="actionTelephonyLTEPlaceholder"/>
</widget>
@@ -639,6 +646,7 @@
<addaction name="actionTelephonyUCPMessages"/>
<addaction name="actionTelephonyF1APMessages"/>
<addaction name="actionTelephonyNGAPMessages"/>
+ <addaction name="actionTelephonyE2APMessages"/>
</widget>
<widget class="QMenu" name="menuEdit">
<property name="title">
@@ -670,13 +678,13 @@
<addaction name="actionEditFindNext"/>
<addaction name="actionEditFindPrevious"/>
<addaction name="separator"/>
- <addaction name="actionEditMarkPacket"/>
+ <addaction name="actionEditMarkSelected"/>
<addaction name="actionEditMarkAllDisplayed"/>
<addaction name="actionEditUnmarkAllDisplayed"/>
<addaction name="actionEditNextMark"/>
<addaction name="actionEditPreviousMark"/>
<addaction name="separator"/>
- <addaction name="actionEditIgnorePacket"/>
+ <addaction name="actionEditIgnoreSelected"/>
<addaction name="actionEditIgnoreAllDisplayed"/>
<addaction name="actionEditUnignoreAllDisplayed"/>
<addaction name="separator"/>
@@ -779,6 +787,7 @@
<addaction name="actionViewZoomOut"/>
<addaction name="actionViewNormalSize"/>
<addaction name="actionViewResizeColumns"/>
+ <addaction name="actionViewResetLayout"/>
</widget>
<widget class="MainStatusBar" name="statusBar"/>
<widget class="QToolBar" name="displayFilterToolBar">
@@ -893,17 +902,15 @@
</action>
<action name="actionHelpContents">
<property name="text">
- <string>&amp;Contents</string>
+ <string>&amp;User's Guide</string>
</property>
+ <!-- This tooltip is replaced with the URL -->
<property name="toolTip">
- <string>Help contents</string>
+ <string>Wireshark User's Guide</string>
</property>
<property name="shortcut">
<string notr="true">F1</string>
</property>
- <property name="iconVisibleInMenu">
- <bool>true</bool>
- </property>
</action>
<action name="actionHelpMPWireshark">
<property name="text">
@@ -912,7 +919,7 @@
</action>
<action name="actionHelpMPWireshark_Filter">
<property name="text">
- <string>Wireshark Filter</string>
+ <string>Display Filters</string>
</property>
</action>
<action name="actionHelpMPTShark">
@@ -1463,9 +1470,9 @@
<string notr="true">Ctrl+B</string>
</property>
</action>
- <action name="actionEditMarkPacket">
+ <action name="actionEditMarkSelected">
<property name="text">
- <string>&amp;Mark/Unmark Packet(s)</string>
+ <string>&amp;Mark/Unmark Selected</string>
</property>
<property name="toolTip">
<string>Mark or unmark each selected packet</string>
@@ -1518,9 +1525,9 @@
<string notr="true">Ctrl+Shift+B</string>
</property>
</action>
- <action name="actionEditIgnorePacket">
+ <action name="actionEditIgnoreSelected">
<property name="text">
- <string>&amp;Ignore/Unignore Packet(s)</string>
+ <string>&amp;Ignore/Unignore Selected</string>
</property>
<property name="toolTip">
<string>Ignore or unignore each selected packet</string>
@@ -1812,12 +1819,20 @@
</action>
<action name="actionStatisticsDNS">
<property name="text">
- <string>DNS</string>
+ <string>General</string>
</property>
<property name="toolTip">
<string>DNS statistics</string>
</property>
</action>
+ <action name="actionStatisticsDNS_QR">
+ <property name="text">
+ <string>Query-Response</string>
+ </property>
+ <property name="toolTip">
+ <string>DNS Query-Response Statistics</string>
+ </property>
+ </action>
<action name="actionStatisticsHART_IP">
<property name="text">
<string>HART-IP</string>
@@ -1970,6 +1985,14 @@
<string>NGAP Messages</string>
</property>
</action>
+ <action name="actionTelephonyE2APMessages">
+ <property name="text">
+ <string>E2AP</string>
+ </property>
+ <property name="toolTip">
+ <string>E2AP Messages</string>
+ </property>
+ </action>
<action name="actionAnalyzeDecodeAs">
<property name="text">
<string>Decode &amp;As…</string>
@@ -2181,7 +2204,7 @@
<string>Reset Layout</string>
</property>
<property name="toolTip">
- <string>Reset appearance layout to default size</string>
+ <string>Reset layout to default size</string>
</property>
<property name="shortcut">
<string notr="true">Ctrl+Shift+W</string>
diff --git a/ui/qt/wireshark_main_window_slots.cpp b/ui/qt/wireshark_main_window_slots.cpp
index 74943adc..db1e15f7 100644
--- a/ui/qt/wireshark_main_window_slots.cpp
+++ b/ui/qt/wireshark_main_window_slots.cpp
@@ -19,7 +19,7 @@
/*
* The generated Ui_WiresharkMainWindow::setupUi() can grow larger than our configured limit,
- * so turn off -Wframe-larger-than= for ui_main_window.h.
+ * so turn off -Wframe-larger-than= for ui_wireshark_main_window.h.
*/
DIAG_OFF(frame-larger-than=)
#include <ui_wireshark_main_window.h>
@@ -188,14 +188,14 @@ DIAG_ON(frame-larger-than=)
// Public slots
//
-bool WiresharkMainWindow::openCaptureFile(QString cf_path, QString read_filter, unsigned int type, gboolean is_tempfile)
+bool WiresharkMainWindow::openCaptureFile(QString cf_path, QString read_filter, unsigned int type, bool is_tempfile)
{
QString file_name = "";
dfilter_t *rfcode = NULL;
df_error_t *df_err = NULL;
int err;
- gboolean name_param;
- gboolean ret = true;
+ bool name_param;
+ bool ret = true;
// was a file name given as function parameter?
name_param = !cf_path.isEmpty();
@@ -262,7 +262,7 @@ bool WiresharkMainWindow::openCaptureFile(QString cf_path, QString read_filter,
continue;
}
- switch (cf_read(CaptureFile::globalCapFile(), /*reloading=*/FALSE)) {
+ switch (cf_read(CaptureFile::globalCapFile(), /*reloading=*/false)) {
case CF_READ_OK:
case CF_READ_ERROR:
/* Just because we got an error, that doesn't mean we were unable
@@ -282,7 +282,9 @@ bool WiresharkMainWindow::openCaptureFile(QString cf_path, QString read_filter,
break;
}
- mainApp->setLastOpenDirFromFilename(cf_path);
+ if (!is_tempfile) {
+ mainApp->setLastOpenDirFromFilename(cf_path);
+ }
main_ui_->statusBar->showExpert();
@@ -364,6 +366,16 @@ void WiresharkMainWindow::layoutToolbars()
}
}
+static const char* layout_icons[] = {
+ NULL,
+ "x-reset-layout_5",
+ "x-reset-layout_2",
+ "x-reset-layout_1",
+ "x-reset-layout_4",
+ "x-reset-layout_3",
+ "x-reset-layout_6"
+};
+
void WiresharkMainWindow::updatePreferenceActions()
{
main_ui_->actionViewPacketList->setEnabled(prefs_has_layout_pane_content(layout_pane_content_plist));
@@ -374,6 +386,9 @@ void WiresharkMainWindow::updatePreferenceActions()
main_ui_->actionViewNameResolutionPhysical->setChecked(gbl_resolv_flags.mac_name);
main_ui_->actionViewNameResolutionNetwork->setChecked(gbl_resolv_flags.network_name);
main_ui_->actionViewNameResolutionTransport->setChecked(gbl_resolv_flags.transport_name);
+
+ if (prefs.gui_layout_type > 0)
+ main_ui_->actionViewResetLayout->setIcon(StockIcon(layout_icons[prefs.gui_layout_type]));
}
void WiresharkMainWindow::updateRecentActions()
@@ -422,7 +437,7 @@ void WiresharkMainWindow::updateRecentActions()
main_ui_->actionGoAutoScroll->setChecked(recent.capture_auto_scroll);
}
-// Don't connect to this directly. Connect to or emit fiterAction(...) instead.
+// Don't connect to this directly. Connect to or emit filterAction(...) instead.
void WiresharkMainWindow::queuedFilterAction(QString action_filter, FilterAction::Action action, FilterAction::ActionType type)
{
QString cur_filter, new_filter;
@@ -506,17 +521,17 @@ void WiresharkMainWindow::queuedFilterAction(QString action_filter, FilterAction
#ifdef HAVE_LIBPCAP
void WiresharkMainWindow::captureCapturePrepared(capture_session *session) {
setTitlebarForCaptureInProgress();
-
setWindowIcon(mainApp->captureIcon());
+ pushLiveCaptureInProgress();
/* Disable menu items that make no sense if you're currently running
a capture. */
bool handle_toolbars = (session->session_will_restart ? false : true);
setForCaptureInProgress(true, handle_toolbars, session->capture_opts->ifaces);
-// set_capture_if_dialog_for_capture_in_progress(TRUE);
+// set_capture_if_dialog_for_capture_in_progress(true);
// /* Don't set up main window for a capture file. */
-// main_set_for_capture_file(FALSE);
+// main_set_for_capture_file(false);
showCapture();
}
@@ -526,6 +541,7 @@ void WiresharkMainWindow::captureCaptureUpdateStarted(capture_session *session)
switching to the next multiple file. */
setTitlebarForCaptureInProgress();
setWindowIcon(mainApp->captureIcon());
+ pushLiveCaptureInProgress();
bool handle_toolbars = (session->session_will_restart ? false : true);
setForCaptureInProgress(true, handle_toolbars, session->capture_opts->ifaces);
@@ -540,6 +556,7 @@ void WiresharkMainWindow::captureCaptureUpdateFinished(capture_session *session)
/* Update the main window as appropriate */
updateForUnsavedChanges();
+ setTitlebarForCaptureFile();
/* Enable menu items that make sense if you're not currently running
a capture. */
@@ -561,6 +578,7 @@ void WiresharkMainWindow::captureCaptureFixedFinished(capture_session *) {
/* The capture isn't stopping any more - it's stopped. */
capture_stopping_ = false;
+ setTitlebarForCaptureFile();
/* Enable menu items that make sense if you're not currently running
a capture. */
@@ -583,7 +601,7 @@ void WiresharkMainWindow::captureCaptureFixedFinished(capture_session *) {
void WiresharkMainWindow::captureCaptureFailed(capture_session *) {
/* Capture isn't stopping any more. */
capture_stopping_ = false;
-
+ setTitlebarForCaptureFile();
setForCaptureInProgress(false);
showWelcome();
@@ -666,7 +684,7 @@ void WiresharkMainWindow::captureEventHandler(CaptureEvent ev)
thaw();
break;
case CaptureEvent::Flushed:
- draw_tap_listeners(FALSE);
+ draw_tap_listeners(false);
break;
default:
break;
@@ -756,7 +774,7 @@ void WiresharkMainWindow::captureFileReadStarted(const QString &action) {
// tap_param_dlg_update();
/* Set up main window for a capture file. */
-// main_set_for_capture_file(TRUE);
+// main_set_for_capture_file(true);
mainApp->popStatus(WiresharkApplication::FileStatus);
QString msg = QString(tr("%1: %2")).arg(action).arg(capture_file_.fileName());
@@ -770,7 +788,7 @@ void WiresharkMainWindow::captureFileReadStarted(const QString &action) {
void WiresharkMainWindow::captureFileReadFinished() {
if (!capture_file_.capFile()->is_tempfile && capture_file_.capFile()->filename) {
/* Add this filename to the list of recent files in the "Recent Files" submenu */
- add_menu_recent_capture_file(capture_file_.capFile()->filename);
+ add_menu_recent_capture_file(capture_file_.capFile()->filename, false);
/* Remember folder for next Open dialog and save it in recent */
mainApp->setLastOpenDirFromFilename(capture_file_.capFile()->filename);
@@ -795,6 +813,7 @@ void WiresharkMainWindow::captureFileReadFinished() {
void WiresharkMainWindow::captureFileClosing() {
setMenusForCaptureFile(true);
+ setTitlebarForCaptureFile();
setForCapturedPackets(false);
setForCaptureInProgress(false);
@@ -839,12 +858,12 @@ void WiresharkMainWindow::startCapture() {
startCapture(QStringList());
}
-void WiresharkMainWindow::startCapture(QStringList interfaces _U_) {
+void WiresharkMainWindow::startCapture(QStringList interfaces) {
#ifdef HAVE_LIBPCAP
interface_options *interface_opts;
- guint i;
+ unsigned i;
interface_t *device;
- gboolean can_start_capture = TRUE;
+ bool can_start_capture = true;
if (interfaces.count() > 0) {
global_capture_opts.num_selected = 0;
@@ -852,11 +871,11 @@ void WiresharkMainWindow::startCapture(QStringList interfaces _U_) {
device = &g_array_index(global_capture_opts.all_ifaces, interface_t, i);
if (interfaces.contains(device->name)) {
- device->selected = TRUE;
+ device->selected = true;
global_capture_opts.num_selected++;
}
else {
- device->selected = FALSE;
+ device->selected = false;
}
}
}
@@ -877,11 +896,11 @@ void WiresharkMainWindow::startCapture(QStringList interfaces _U_) {
*/
if (extcap_requires_configuration(device->name))
{
- /* Request openning of extcap options dialog */
+ /* Request opening of extcap options dialog */
QString device_name(device->name);
emit showExtcapOptions(device_name, false);
/* Cancel start of capture */
- can_start_capture = FALSE;
+ can_start_capture = false;
}
}
}
@@ -924,24 +943,6 @@ void WiresharkMainWindow::startCapture(QStringList interfaces _U_) {
info_data_.ui.ui = this;
if (capture_start(&global_capture_opts, NULL, &cap_session_, &info_data_,
main_window_update)) {
- capture_options *capture_opts = cap_session_.capture_opts;
- GString *interface_names;
-
- /* Add "interface name<live capture in progress>" on main status bar */
- interface_names = get_iface_list_string(capture_opts, 0);
- if (strlen(interface_names->str) > 0) {
- g_string_append(interface_names, ":");
- }
- g_string_append(interface_names, " ");
-
- mainApp->popStatus(WiresharkApplication::FileStatus);
- QString msg = QString("%1<live capture in progress>").arg(interface_names->str);
- QString msgtip = QString("to file: ");
- if (capture_opts->save_file)
- msgtip += capture_opts->save_file;
- mainApp->pushStatus(WiresharkApplication::FileStatus, msg, msgtip);
- g_string_free(interface_names, TRUE);
-
/* The capture succeeded, which means the capture filter syntax is
valid; add this capture filter to the recent capture filter list. */
QByteArray filter_ba;
@@ -979,6 +980,30 @@ DIAG_ON(stringop-overread)
} else {
CaptureFile::globalCapFile()->window = NULL;
}
+#else // HAVE_LIBPCAP
+ Q_UNUSED(interfaces)
+#endif // HAVE_LIBPCAP
+}
+
+void WiresharkMainWindow::pushLiveCaptureInProgress() {
+#ifdef HAVE_LIBPCAP
+ capture_options *capture_opts = cap_session_.capture_opts;
+ GString *interface_names;
+
+ /* Add "interface name<live capture in progress>" on main status bar */
+ interface_names = get_iface_list_string(capture_opts, 0);
+ if (strlen(interface_names->str) > 0) {
+ g_string_append(interface_names, ":");
+ }
+ g_string_append(interface_names, " ");
+
+ mainApp->popStatus(WiresharkApplication::FileStatus);
+ QString msg = QString("%1<live capture in progress>").arg(interface_names->str);
+ QString msgtip = QString("to file: ");
+ if (capture_opts->save_file)
+ msgtip += capture_opts->save_file;
+ mainApp->pushStatus(WiresharkApplication::FileStatus, msg, msgtip);
+ g_string_free(interface_names, TRUE);
#endif // HAVE_LIBPCAP
}
@@ -1044,7 +1069,9 @@ void WiresharkMainWindow::updateRecentCaptures() {
/* Iterate through the actions in menuOpenRecentCaptureFile,
* removing special items, a maybe duplicate entry and every item above count_max */
+#if defined(Q_OS_MAC)
int shortcut = Qt::Key_0;
+#endif
foreach(recent_item_status *ri, mainApp->recentItems()) {
// Add the new item
ra = new QAction(recentMenu);
@@ -1053,12 +1080,14 @@ void WiresharkMainWindow::updateRecentCaptures() {
ra->setEnabled(ri->accessible);
recentMenu->insertAction(NULL, ra);
action_cf_name = ra->data().toString();
+#if defined(Q_OS_MAC)
if (shortcut <= Qt::Key_9) {
ra->setShortcut(Qt::META | (Qt::Key)shortcut);
shortcut++;
}
+#endif
ra->setText(action_cf_name);
- connect(ra, SIGNAL(triggered()), this, SLOT(recentActionTriggered()));
+ connect(ra, &QAction::triggered, this, &WiresharkMainWindow::recentActionTriggered);
/* This is slow, at least on my VM here. The added links also open Wireshark
* in a new window. It might make more sense to add a recent item when we
@@ -1082,8 +1111,15 @@ void WiresharkMainWindow::updateRecentCaptures() {
QFileInfo fi(ri->filename);
rda->setText(fi.fileName());
dock_menu_->insertAction(NULL, rda);
- connect(rda, SIGNAL(triggered()), ra, SLOT(trigger()));
+ connect(rda, &QAction::triggered, ra, &QAction::trigger);
+#endif
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ if (recentMenu->actions().count() == static_cast<int>(prefs.gui_recent_files_count_max)) {
+#else
+ if (recentMenu->actions().count() == static_cast<qsizetype>(prefs.gui_recent_files_count_max)) {
#endif
+ break;
+ }
}
if (recentMenu->actions().count() > 0) {
@@ -1096,7 +1132,7 @@ void WiresharkMainWindow::updateRecentCaptures() {
ra = new QAction(recentMenu);
ra->setText(tr("Clear Menu"));
recentMenu->insertAction(NULL, ra);
- connect(ra, SIGNAL(triggered()), mainApp, SLOT(clearRecentCaptures()));
+ connect(ra, &QAction::triggered, mainApp, &MainApplication::clearRecentCaptures);
} else {
if (main_ui_->actionDummyNoFilesFound) {
recentMenu->addAction(main_ui_->actionDummyNoFilesFound);
@@ -1138,10 +1174,10 @@ void WiresharkMainWindow::setEditCommentsMenu()
const int thisRow = selectedRows().first();
frame_data * current_frame = frameDataForRow(thisRow);
wtap_block_t pkt_block = cf_get_packet_block(capture_file_.capFile(), current_frame);
- guint nComments = wtap_block_count_option(pkt_block, OPT_COMMENT);
+ unsigned nComments = wtap_block_count_option(pkt_block, OPT_COMMENT);
if (nComments > 0) {
main_ui_->menuPacketComment->addSeparator();
- for (guint i = 0; i < nComments; i++) {
+ for (unsigned i = 0; i < nComments; i++) {
QString comment = packet_list_->getPacketComment(i);
comment = this->commentToMenuText(comment);
action = main_ui_->menuPacketComment->addAction(tr("Edit \"%1\"", "edit packet comment").arg(comment));
@@ -1150,7 +1186,7 @@ void WiresharkMainWindow::setEditCommentsMenu()
}
main_ui_->menuPacketComment->addSeparator();
- for (guint i = 0; i < nComments; i++) {
+ for (unsigned i = 0; i < nComments; i++) {
QString comment = packet_list_->getPacketComment(i);
comment = this->commentToMenuText(comment);
action = main_ui_->menuPacketComment->addAction(tr("Delete \"%1\"", "delete packet comment").arg(comment));
@@ -1172,8 +1208,8 @@ void WiresharkMainWindow::setEditCommentsMenu()
void WiresharkMainWindow::setMenusForSelectedPacket()
{
- gboolean is_ip = FALSE, is_tcp = FALSE, is_udp = FALSE, is_sctp = FALSE, is_tls = FALSE, is_rtp = FALSE, is_lte_rlc = FALSE,
- is_quic = FALSE, is_exported_pdu = FALSE;
+ bool is_ip = false, is_tcp = false, is_udp = false, is_sctp = false, is_tls = false, is_rtp = false, is_lte_rlc = false,
+ is_quic = false, is_exported_pdu = false;
/* Making the menu context-sensitive allows for easier selection of the
desired item and has the added benefit, with large captures, of
@@ -1237,7 +1273,7 @@ void WiresharkMainWindow::setMenusForSelectedPacket()
another_is_time_ref = have_time_ref && rows.count() <= 1 &&
!(capture_file_.capFile()->ref_time_count == 1 && frame_selected && current_frame->ref_time);
- if (capture_file_.capFile()->edt && ! multi_selection)
+ if (capture_file_.capFile()->edt && ! multi_selection && frame_selected)
{
proto_get_frame_protocols(capture_file_.capFile()->edt->pi.layers,
&is_ip, &is_tcp, &is_udp, &is_sctp,
@@ -1249,30 +1285,31 @@ void WiresharkMainWindow::setMenusForSelectedPacket()
if (is_exported_pdu &&
(capture_file_.capFile()->edt->pi.net_src.type == AT_IPv4 || capture_file_.capFile()->edt->pi.net_src.type == AT_IPv6) &&
(capture_file_.capFile()->edt->pi.net_dst.type == AT_IPv4 || capture_file_.capFile()->edt->pi.net_dst.type == AT_IPv6)) {
- is_ip = TRUE;
+ is_ip = true;
}
foreach (FollowStreamAction *follow_action, main_ui_->menuFollow->findChildren<FollowStreamAction *>()) {
/* QUIC has TLS handshakes; don't enabled Follow TLS Stream if
* there's QUIC.
*/
- gboolean is_frame = proto_is_frame_protocol(capture_file_.capFile()->edt->pi.layers, follow_action->filterName());
+ bool is_frame = proto_is_frame_protocol(capture_file_.capFile()->edt->pi.layers, follow_action->filterName());
if (g_strcmp0(follow_action->filterName(), "tls") == 0) {
follow_action->setEnabled(is_frame && !is_quic);
} else {
follow_action->setEnabled(is_frame);
}
}
+ } else {
+ foreach (FollowStreamAction *follow_action, main_ui_->menuFollow->findChildren<FollowStreamAction *>()) {
+ follow_action->setEnabled(false);
+ }
}
}
- main_ui_->actionEditMarkPacket->setText(tr("&Mark/Unmark Packet(s)", "", static_cast<int>(selectedRows().count())));
- main_ui_->actionEditIgnorePacket->setText(tr("&Ignore/Unignore Packet(s)", "", static_cast<int>(selectedRows().count())));
-
main_ui_->actionCopyListAsText->setEnabled(selectedRows().count() > 0);
main_ui_->actionCopyListAsCSV->setEnabled(selectedRows().count() > 0);
main_ui_->actionCopyListAsYAML->setEnabled(selectedRows().count() > 0);
- main_ui_->actionEditMarkPacket->setEnabled(frame_selected || multi_selection);
+ main_ui_->actionEditMarkSelected->setEnabled(frame_selected || multi_selection);
main_ui_->actionEditMarkAllDisplayed->setEnabled(have_frames);
/* Unlike un-ignore, do not allow unmark of all frames when no frames are displayed */
main_ui_->actionEditUnmarkAllDisplayed->setEnabled(have_marked);
@@ -1287,7 +1324,7 @@ void WiresharkMainWindow::setMenusForSelectedPacket()
main_ui_->menuPacketComment->setEnabled(enableEditComments && selectedRows().count() > 0);
main_ui_->actionDeleteAllPacketComments->setEnabled(enableEditComments);
- main_ui_->actionEditIgnorePacket->setEnabled(frame_selected || multi_selection);
+ main_ui_->actionEditIgnoreSelected->setEnabled(frame_selected || multi_selection);
main_ui_->actionEditIgnoreAllDisplayed->setEnabled(have_filtered);
/* Allow un-ignore of all frames even with no frames currently displayed */
main_ui_->actionEditUnignoreAllDisplayed->setEnabled(have_ignored);
@@ -1361,10 +1398,26 @@ void WiresharkMainWindow::setMenusForSelectedTreeRow(FieldInformation *finfo) {
if (fi && fi->ds_tvb && (fi->length > 0)) {
have_packet_bytes = true;
}
+
+ if (!(capture_file_.capFile()->search_in_progress && (capture_file_.capFile()->hex || (capture_file_.capFile()->string && capture_file_.capFile()->packet_data)))) {
+ // If we're not in the middle of a packet bytes search, then set
+ // search_pos and search_len so that we can start a new search
+ // from this point. (If we are, then we already set it.)
+ if (fi && capture_file_.capFile()->edt && (fi->ds_tvb == capture_file_.capFile()->edt->tvb)) {
+ // We can only do a Packet Bytes search in the main bytes from
+ // the frame, not from any secondary data sources. (XXX: This
+ // might be surprising to users, though.)
+ capture_file_.capFile()->search_pos = (uint32_t)(finfo->position().start + finfo->position().length - 1);
+ capture_file_.capFile()->search_len = (uint32_t)finfo->position().length;
+ } else {
+ capture_file_.capFile()->search_pos = 0;
+ capture_file_.capFile()->search_len = 0;
+ }
+ }
}
if (capture_file_.capFile() != NULL && fi != NULL) {
- header_field_info *hfinfo = fi->hfinfo;
+ const header_field_info *hfinfo = fi->hfinfo;
int linked_frame = -1;
can_match_selected = proto_can_match_selected(capture_file_.capFile()->finfo_selected, capture_file_.capFile()->edt);
@@ -1522,7 +1575,7 @@ void WiresharkMainWindow::checkDisplayFilter()
void WiresharkMainWindow::fieldsChanged()
{
- gchar *err_msg = NULL;
+ char *err_msg = NULL;
if (!color_filters_reload(&err_msg, color_filter_add_cb)) {
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
g_free(err_msg);
@@ -1545,7 +1598,7 @@ void WiresharkMainWindow::reloadLuaPlugins()
if (mainApp->isReloadingLua())
return;
- gboolean uses_lua_filehandler = FALSE;
+ bool uses_lua_filehandler = false;
if (capture_file_.capFile()) {
// Check if the current capture file is opened with a Lua FileHandler
@@ -1633,11 +1686,11 @@ void WiresharkMainWindow::initViewColorizeMenu()
<< main_ui_->actionViewColorizeConversation7 << main_ui_->actionViewColorizeConversation8
<< main_ui_->actionViewColorizeConversation9 << main_ui_->actionViewColorizeConversation10;
- guint8 color_num = 1;
+ uint8_t color_num = 1;
foreach(QAction *cc_action, cc_actions) {
cc_action->setData(color_num);
- connect(cc_action, SIGNAL(triggered()), this, SLOT(colorizeConversation()));
+ connect(cc_action, &QAction::triggered, this, &WiresharkMainWindow::colorizeConversation);
const color_filter_t *colorf = color_filters_tmp_color(color_num);
if (colorf) {
@@ -1674,16 +1727,15 @@ void WiresharkMainWindow::addStatsPluginsToMenu() {
parent_menu = main_ui_->menuStatistics;
// gtk/main_menubar.c compresses double slashes, hence SkipEmptyParts
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
- QStringList cfg_name_parts = QString(cfg->name).split("/", Qt::SkipEmptyParts);
+ QStringList cfg_name_parts = QString(cfg->path).split(STATS_TREE_MENU_SEPARATOR, Qt::SkipEmptyParts);
#else
- QStringList cfg_name_parts = QString(cfg->name).split("/", QString::SkipEmptyParts);
+ QStringList cfg_name_parts = QString(cfg->path).split(STATS_TREE_MENU_SEPARATOR, QString::SkipEmptyParts);
#endif
if (cfg_name_parts.isEmpty()) continue;
- QString stat_name = cfg_name_parts.takeLast();
+ QString stat_name = cfg_name_parts.takeLast().trimmed();
if (!cfg_name_parts.isEmpty()) {
- QString menu_name = cfg_name_parts.join("/");
- parent_menu = findOrAddMenu(parent_menu, menu_name);
+ parent_menu = findOrAddMenu(parent_menu, cfg_name_parts);
}
stats_tree_action = new QAction(stat_name, this);
@@ -1757,10 +1809,8 @@ void WiresharkMainWindow::openTapParameterDialog(const QString cfg_str, const QS
TapParameterDialog *tp_dialog = TapParameterDialog::showTapParameterStatistics(*this, capture_file_, cfg_str, arg, userdata);
if (!tp_dialog) return;
- connect(tp_dialog, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)),
- this, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)));
- connect(tp_dialog, SIGNAL(updateFilter(QString)),
- df_combo_box_->lineEdit(), SLOT(setText(QString)));
+ connect(tp_dialog, &TapParameterDialog::filterAction, this, &WiresharkMainWindow::filterAction);
+ connect(tp_dialog, &TapParameterDialog::updateFilter, df_combo_box_->lineEdit(), &QLineEdit::setText);
tp_dialog->show();
}
@@ -1881,7 +1931,7 @@ void WiresharkMainWindow::exportPacketBytes()
);
if (file_name.length() > 0) {
- const guint8 *data_p;
+ const uint8_t *data_p;
data_p = tvb_get_ptr(capture_file_.capFile()->finfo_selected->ds_tvb, 0, -1) +
capture_file_.capFile()->finfo_selected->start;
@@ -1953,8 +2003,8 @@ void WiresharkMainWindow::exportTLSSessionKeys()
tr("TLS Session Keys (*.keys *.txt);;All Files (" ALL_FILES_WILDCARD ")")
);
if (file_name.length() > 0) {
- gsize keylist_length;
- gchar *keylist = ssl_export_sessions(&keylist_length);
+ size_t keylist_length;
+ char *keylist = ssl_export_sessions(&keylist_length);
write_file_binary_mode(qUtf8Printable(file_name), keylist, keylist_length);
/* Save the directory name for future file dialogs. */
@@ -2023,7 +2073,7 @@ void WiresharkMainWindow::connectEditMenuActions()
// The items below are used in the packet list and detail context menus.
// Use QueuedConnections so that the context menus aren't destroyed
// prematurely.
- connect(main_ui_->actionEditMarkPacket, &QAction::triggered, this, [this]() {
+ connect(main_ui_->actionEditMarkSelected, &QAction::triggered, this, [this]() {
freeze();
packet_list_->markFrame();
thaw();
@@ -2056,7 +2106,7 @@ void WiresharkMainWindow::connectEditMenuActions()
}
}, Qt::QueuedConnection);
- connect(main_ui_->actionEditIgnorePacket, &QAction::triggered, this, [this]() {
+ connect(main_ui_->actionEditIgnoreSelected, &QAction::triggered, this, [this]() {
freeze();
packet_list_->ignoreFrame();
thaw();
@@ -2140,7 +2190,7 @@ void WiresharkMainWindow::copySelectedItems(WiresharkMainWindow::CopySelected se
break;
case CopySelectedValue:
if (finfo_selected && capture_file_.capFile()->edt != 0) {
- gchar* field_str = get_node_field_value(finfo_selected, capture_file_.capFile()->edt);
+ char* field_str = get_node_field_value(finfo_selected, capture_file_.capFile()->edt);
clip.append(field_str);
g_free(field_str);
}
@@ -2231,11 +2281,10 @@ void WiresharkMainWindow::findPacket()
void WiresharkMainWindow::editTimeShift()
{
TimeShiftDialog *ts_dialog = new TimeShiftDialog(this, capture_file_.capFile());
- connect(ts_dialog, SIGNAL(finished(int)), this, SLOT(editTimeShiftFinished(int)));
+ connect(ts_dialog, &TimeShiftDialog::finished, this, &WiresharkMainWindow::editTimeShiftFinished);
- connect(this, SIGNAL(setCaptureFile(capture_file*)),
- ts_dialog, SLOT(setCaptureFile(capture_file*)));
- connect(ts_dialog, SIGNAL(timeShifted()), packet_list_, SLOT(applyTimeShift()));
+ connect(this, &WiresharkMainWindow::setCaptureFile, ts_dialog, &TimeShiftDialog::setCaptureFile);
+ connect(ts_dialog, &TimeShiftDialog::timeShifted, packet_list_, &PacketList::applyTimeShift, Qt::QueuedConnection);
ts_dialog->setWindowModality(Qt::ApplicationModal);
ts_dialog->setAttribute(Qt::WA_DeleteOnClose);
@@ -2282,7 +2331,7 @@ void WiresharkMainWindow::editPacketComment()
return;
QAction *ra = qobject_cast<QAction*>(sender());
- guint nComment = ra->data().toUInt();
+ unsigned nComment = ra->data().toUInt();
PacketCommentDialog* pc_dialog;
pc_dialog = new PacketCommentDialog(true, this, packet_list_->getPacketComment(nComment));
connect(pc_dialog, &QDialog::finished, std::bind(&WiresharkMainWindow::editPacketCommentFinished, this, pc_dialog, std::placeholders::_1, nComment));
@@ -2291,7 +2340,7 @@ void WiresharkMainWindow::editPacketComment()
pc_dialog->show();
}
-void WiresharkMainWindow::editPacketCommentFinished(PacketCommentDialog* pc_dialog _U_, int result _U_, guint nComment)
+void WiresharkMainWindow::editPacketCommentFinished(PacketCommentDialog* pc_dialog _U_, int result _U_, unsigned nComment)
{
if (result == QDialog::Accepted) {
packet_list_->setPacketComment(nComment, pc_dialog->text());
@@ -2302,7 +2351,7 @@ void WiresharkMainWindow::editPacketCommentFinished(PacketCommentDialog* pc_dial
void WiresharkMainWindow::deletePacketComment()
{
QAction *ra = qobject_cast<QAction*>(sender());
- guint nComment = ra->data().toUInt();
+ unsigned nComment = ra->data().toUInt();
packet_list_->setPacketComment(nComment, QString(""));
updateForUnsavedChanges();
}
@@ -2316,7 +2365,7 @@ void WiresharkMainWindow::deleteCommentsFromPackets()
void WiresharkMainWindow::deleteAllPacketComments()
{
QMessageBox *msg_dialog = new QMessageBox();
- connect(msg_dialog, SIGNAL(finished(int)), this, SLOT(deleteAllPacketCommentsFinished(int)));
+ connect(msg_dialog, &QMessageBox::finished, this, &WiresharkMainWindow::deleteAllPacketCommentsFinished);
msg_dialog->setIcon(QMessageBox::Question);
msg_dialog->setText(tr("Are you sure you want to remove all packet comments?"));
@@ -2355,7 +2404,7 @@ void WiresharkMainWindow::injectSecrets()
if (ret != QMessageBox::Yes) return;
- QUrl wiki_url = QString(WS_WIKI_URL("TLS/#tls-decryption"));
+ QUrl wiki_url = QString(WS_WIKI_URL("TLS#tls-decryption"));
QDesktopServices::openUrl(wiki_url);
return;
}
@@ -2377,7 +2426,7 @@ void WiresharkMainWindow::discardAllSecrets()
return;
QMessageBox* msg_dialog = new QMessageBox();
- connect(msg_dialog, SIGNAL(finished(int)), this, SLOT(discardAllSecretsFinished(int)));
+ connect(msg_dialog, &QMessageBox::finished, this, &WiresharkMainWindow::discardAllSecretsFinished);
msg_dialog->setIcon(QMessageBox::Question);
msg_dialog->setText(tr("Are you sure you want to discard all decryption secrets?"));
@@ -2398,7 +2447,7 @@ void WiresharkMainWindow::discardAllSecretsFinished(int result)
*/
capture_file* cf = capture_file_.capFile();
if (wtap_file_discard_decryption_secrets(cf->provider.wth)) {
- cf->unsaved_changes = TRUE;
+ cf->unsaved_changes = true;
updateForUnsavedChanges();
}
}
@@ -2415,7 +2464,7 @@ void WiresharkMainWindow::editConfigurationProfiles()
void WiresharkMainWindow::showPreferencesDialog(QString module_name)
{
PreferencesDialog *pref_dialog = new PreferencesDialog(this);
- connect(pref_dialog, SIGNAL(destroyed(QObject*)), mainApp, SLOT(flushAppSignals()));
+ connect(pref_dialog, &PreferencesDialog::destroyed, mainApp, &MainApplication::flushAppSignals);
saveWindowGeometry(); // Save in case the layout panes are rearranged
pref_dialog->setPane(module_name);
@@ -2494,7 +2543,7 @@ void WiresharkMainWindow::connectViewMenuActions()
[this]() { showColoringRulesDialog(); });
connect(main_ui_->actionViewColorizeResetColorization, &QAction::triggered, this, [this]() {
- gchar *err_msg = NULL;
+ char *err_msg = NULL;
if (!color_filters_reset_tmp(&err_msg)) {
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
g_free(err_msg);
@@ -2509,6 +2558,10 @@ void WiresharkMainWindow::connectViewMenuActions()
connect(main_ui_->actionViewResetLayout, &QAction::triggered, this, [this]() {
recent.gui_geometry_main_upper_pane = 0;
recent.gui_geometry_main_lower_pane = 0;
+ g_free(recent.gui_geometry_main_master_split);
+ g_free(recent.gui_geometry_main_extra_split);
+ recent.gui_geometry_main_master_split = NULL;
+ recent.gui_geometry_main_extra_split = NULL;
applyRecentPaneGeometry();
});
@@ -2592,7 +2645,7 @@ void WiresharkMainWindow::showHideMainWidgets(QAction *action)
if (widget == toolbar) {
GList *entry = g_list_find_custom(recent.interface_toolbars, action->text().toUtf8(), (GCompareFunc)strcmp);
if (show && !entry) {
- recent.interface_toolbars = g_list_append(recent.interface_toolbars, g_strdup(action->text().toUtf8().constData()));
+ recent.interface_toolbars = g_list_append(recent.interface_toolbars, qstring_strdup(action->text()));
} else if (!show && entry) {
recent.interface_toolbars = g_list_remove(recent.interface_toolbars, entry->data);
}
@@ -2691,9 +2744,9 @@ void WiresharkMainWindow::editResolvedName()
void WiresharkMainWindow::setNameResolution()
{
- gbl_resolv_flags.mac_name = main_ui_->actionViewNameResolutionPhysical->isChecked() ? TRUE : FALSE;
- gbl_resolv_flags.network_name = main_ui_->actionViewNameResolutionNetwork->isChecked() ? TRUE : FALSE;
- gbl_resolv_flags.transport_name = main_ui_->actionViewNameResolutionTransport->isChecked() ? TRUE : FALSE;
+ gbl_resolv_flags.mac_name = main_ui_->actionViewNameResolutionPhysical->isChecked() ? true : false;
+ gbl_resolv_flags.network_name = main_ui_->actionViewNameResolutionNetwork->isChecked() ? true : false;
+ gbl_resolv_flags.transport_name = main_ui_->actionViewNameResolutionTransport->isChecked() ? true : false;
if (packet_list_) {
packet_list_->resetColumns();
@@ -2727,8 +2780,8 @@ void WiresharkMainWindow::colorizeConversation(bool create_rule)
if (capture_file_.capFile() && selectedRows().count() > 0) {
packet_info *pi = capture_file_.packetInfo();
- guint8 cc_num = colorize_action->data().toUInt();
- gchar *filter = conversation_filter_from_packet(pi);
+ uint8_t cc_num = colorize_action->data().toUInt();
+ char *filter = conversation_filter_from_packet(pi);
if (filter == NULL) {
mainApp->pushStatus(WiresharkApplication::TemporaryStatus, tr("Unable to build conversation filter."));
return;
@@ -2742,8 +2795,8 @@ void WiresharkMainWindow::colorizeConversation(bool create_rule)
this, &WiresharkMainWindow::filterAction);
coloring_rules_dialog.exec();
} else {
- gchar *err_msg = NULL;
- if (!color_filters_set_tmp(cc_num, filter, FALSE, &err_msg)) {
+ char *err_msg = NULL;
+ if (!color_filters_set_tmp(cc_num, filter, false, &err_msg)) {
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
g_free(err_msg);
}
@@ -2779,8 +2832,8 @@ void WiresharkMainWindow::colorizeWithFilter(QByteArray filter, int color_number
if (color_number > 0) {
// Assume "Color X"
- gchar *err_msg = NULL;
- if (!color_filters_set_tmp(color_number, filter.constData(), FALSE, &err_msg)) {
+ char *err_msg = NULL;
+ if (!color_filters_set_tmp(color_number, filter.constData(), false, &err_msg)) {
simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
g_free(err_msg);
}
@@ -2803,7 +2856,7 @@ void WiresharkMainWindow::openPacketDialog(bool from_reference)
/* Find the frame for which we're popping up a dialog */
if (from_reference) {
- guint32 framenum = fvalue_get_uinteger(capture_file_.capFile()->finfo_selected->value);
+ uint32_t framenum = fvalue_get_uinteger(capture_file_.capFile()->finfo_selected->value);
if (framenum == 0)
return;
@@ -2929,9 +2982,9 @@ void WiresharkMainWindow::connectGoMenuActions()
}
void WiresharkMainWindow::goToConversationFrame(bool go_next) {
- gchar *filter = NULL;
+ char *filter = NULL;
dfilter_t *dfcode = NULL;
- gboolean found_packet = FALSE;
+ bool found_packet = false;
packet_info *pi = capture_file_.packetInfo();
if (!pi) {
@@ -2985,7 +3038,7 @@ void WiresharkMainWindow::connectCaptureMenuActions()
#ifdef HAVE_LIBPCAP
connect(main_ui_->actionCaptureRestart, &QAction::triggered, this, [this]() {
QString before_what(tr(" before restarting the capture"));
- cap_session_.capture_opts->restart = TRUE;
+ cap_session_.capture_opts->restart = true;
if (!testCaptureFileClose(before_what, Restart)) {
return;
}
@@ -3061,13 +3114,13 @@ void WiresharkMainWindow::startCaptureTriggered()
// /*
// * There's an options dialog; get the values from it and close it.
// */
-// gboolean success;
+// bool success;
// /* Determine if "capture start" while building of the "capture options" window */
// /* is in progress. If so, ignore the "capture start. */
// /* XXX: Would it be better/cleaner for the "capture options" window code to */
// /* disable the capture start button temporarily ? */
-// if (cap_open_complete == FALSE) {
+// if (cap_open_complete == false) {
// return; /* Building options window: ignore "capture start" */
// }
// success = capture_dlg_prep(cap_open_w);
@@ -3110,14 +3163,10 @@ void WiresharkMainWindow::connectAnalyzeMenuActions()
});
connect(main_ui_->actionAnalyzeDisplayFilterMacros, &QAction::triggered, this, [=]() {
- struct epan_uat* dfm_uat;
- dfilter_macro_get_uat(&dfm_uat);
- UatDialog *uat_dlg = new UatDialog(parentWidget(), dfm_uat);
- connect(uat_dlg, SIGNAL(destroyed(QObject*)), mainApp, SLOT(flushAppSignals()));
-
- uat_dlg->setWindowModality(Qt::ApplicationModal);
- uat_dlg->setAttribute(Qt::WA_DeleteOnClose);
- uat_dlg->show();
+ FilterDialog *display_filter_dlg = new FilterDialog(window(), FilterDialog::DisplayMacro);
+ display_filter_dlg->setWindowModality(Qt::ApplicationModal);
+ display_filter_dlg->setAttribute(Qt::WA_DeleteOnClose);
+ display_filter_dlg->show();
});
connect(main_ui_->actionDisplayFilterExpression, &QAction::triggered, this, [=]() {
@@ -3133,7 +3182,7 @@ void WiresharkMainWindow::connectAnalyzeMenuActions()
connect(main_ui_->actionAnalyzeEnabledProtocols, &QAction::triggered, this, [=]() {
EnabledProtocolsDialog *enable_proto_dialog = new EnabledProtocolsDialog(this);
- connect(enable_proto_dialog, SIGNAL(destroyed(QObject*)), mainApp, SLOT(flushAppSignals()));
+ connect(enable_proto_dialog, &EnabledProtocolsDialog::destroyed, mainApp, &MainApplication::flushAppSignals);
enable_proto_dialog->setWindowModality(Qt::ApplicationModal);
enable_proto_dialog->setAttribute(Qt::WA_DeleteOnClose);
@@ -3145,7 +3194,7 @@ void WiresharkMainWindow::connectAnalyzeMenuActions()
bool create_new = da_action && da_action->property("create_new").toBool();
DecodeAsDialog *da_dialog = new DecodeAsDialog(this, capture_file_.capFile(), create_new);
- connect(da_dialog, SIGNAL(destroyed(QObject*)), mainApp, SLOT(flushAppSignals()));
+ connect(da_dialog, &DecodeAsDialog::destroyed, mainApp, &MainApplication::flushAppSignals);
da_dialog->setWindowModality(Qt::ApplicationModal);
da_dialog->setAttribute(Qt::WA_DeleteOnClose);
@@ -3209,7 +3258,7 @@ void WiresharkMainWindow::matchFieldFilter(FilterAction::Action action, FilterAc
void WiresharkMainWindow::applyFieldAsColumn()
{
if (capture_file_.capFile() != 0 && capture_file_.capFile()->finfo_selected != 0) {
- header_field_info *hfinfo = capture_file_.capFile()->finfo_selected->hfinfo;
+ const header_field_info *hfinfo = capture_file_.capFile()->finfo_selected->hfinfo;
int col = column_prefs_has_custom(hfinfo->abbrev);
if (col == -1) {
insertColumn(hfinfo->name, hfinfo->abbrev);
@@ -3224,7 +3273,7 @@ void WiresharkMainWindow::applyFieldAsColumn()
if (!get_column_visible(col)) {
packet_list_->setColumnHidden(col, false);
- set_column_visible(col, TRUE);
+ set_column_visible(col, true);
prefs_main_write();
}
}
@@ -3261,10 +3310,10 @@ void WiresharkMainWindow::applyExportObject()
export_dialog->show();
}
-void WiresharkMainWindow::openFollowStreamDialog(int proto_id, guint stream_num, guint sub_stream_num, bool use_stream_index) {
+void WiresharkMainWindow::openFollowStreamDialog(int proto_id, unsigned stream_num, unsigned sub_stream_num, bool use_stream_index) {
FollowStreamDialog *fsd = new FollowStreamDialog(*this, capture_file_, proto_id);
- connect(fsd, SIGNAL(updateFilter(QString, bool)), this, SLOT(filterPackets(QString, bool)));
- connect(fsd, SIGNAL(goToPacket(int)), packet_list_, SLOT(goToPacket(int)));
+ connect(fsd, &FollowStreamDialog::updateFilter, this, &WiresharkMainWindow::filterPackets);
+ connect(fsd, &FollowStreamDialog::goToPacket, this, [=](int packet_num) {packet_list_->goToPacket(packet_num);});
fsd->addCodecs(text_codec_map_);
fsd->show();
if (use_stream_index) {
@@ -3283,10 +3332,8 @@ void WiresharkMainWindow::openFollowStreamDialog(int proto_id) {
void WiresharkMainWindow::openSCTPAllAssocsDialog()
{
SCTPAllAssocsDialog *sctp_dialog = new SCTPAllAssocsDialog(this, capture_file_.capFile());
- connect(sctp_dialog, SIGNAL(filterPackets(QString, bool)),
- this, SLOT(filterPackets(QString, bool)));
- connect(this, SIGNAL(setCaptureFile(capture_file*)),
- sctp_dialog, SLOT(setCaptureFile(capture_file*)));
+ connect(sctp_dialog, &SCTPAllAssocsDialog::filterPackets, this, &WiresharkMainWindow::filterPackets);
+ connect(this, &WiresharkMainWindow::setCaptureFile, sctp_dialog, &SCTPAllAssocsDialog::setCaptureFile);
sctp_dialog->fillTable();
if (sctp_dialog->isMinimized() == true)
@@ -3314,8 +3361,7 @@ void WiresharkMainWindow::on_actionSCTPAnalyseThisAssociation_triggered()
return;
}
SCTPAssocAnalyseDialog *sctp_analyse = new SCTPAssocAnalyseDialog(this, assoc, capture_file_.capFile());
- connect(sctp_analyse, SIGNAL(filterPackets(QString, bool)),
- this, SLOT(filterPackets(QString, bool)));
+ connect(sctp_analyse, &SCTPAssocAnalyseDialog::filterPackets, this, &WiresharkMainWindow::filterPackets);
if (sctp_analyse->isMinimized() == true)
{
@@ -3344,9 +3390,8 @@ void WiresharkMainWindow::on_actionSCTPFilterThisAssociation_triggered()
void WiresharkMainWindow::statCommandWlanStatistics(const char *arg, void *)
{
WlanStatisticsDialog *wlan_stats_dlg = new WlanStatisticsDialog(*this, capture_file_, arg);
- connect(wlan_stats_dlg, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)),
- this, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)));
wlan_stats_dlg->show();
+ connect(wlan_stats_dlg, &WlanStatisticsDialog::filterAction, this, &WiresharkMainWindow::filterAction);
}
// -z expert
@@ -3355,10 +3400,9 @@ void WiresharkMainWindow::statCommandExpertInfo(const char *, void *)
const DisplayFilterEdit *df_edit = dynamic_cast<DisplayFilterEdit *>(df_combo_box_->lineEdit());
ExpertInfoDialog *expert_dialog = new ExpertInfoDialog(*this, capture_file_, df_edit->text());
- connect(expert_dialog->getExpertInfoView(), SIGNAL(goToPacket(int, int)),
- packet_list_, SLOT(goToPacket(int, int)));
- connect(expert_dialog, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)),
- this, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)));
+ connect(expert_dialog->getExpertInfoView(), &ExpertInfoTreeView::goToPacket,
+ this, [=](int packet_num) {packet_list_->goToPacket(packet_num);});
+ connect(expert_dialog, &ExpertInfoDialog::filterAction, this, &WiresharkMainWindow::filterAction);
expert_dialog->show();
}
@@ -3372,8 +3416,8 @@ void WiresharkMainWindow::connectStatisticsMenuActions()
{
connect(main_ui_->actionStatisticsCaptureFileProperties, &QAction::triggered, this, [=]() {
CaptureFilePropertiesDialog *capture_file_properties_dialog = new CaptureFilePropertiesDialog(*this, capture_file_);
- connect(capture_file_properties_dialog, SIGNAL(captureCommentChanged()),
- this, SLOT(updateForUnsavedChanges()));
+ connect(capture_file_properties_dialog, &CaptureFilePropertiesDialog::captureCommentChanged,
+ this, &WiresharkMainWindow::updateForUnsavedChanges);
capture_file_properties_dialog->show();
});
@@ -3381,8 +3425,7 @@ void WiresharkMainWindow::connectStatisticsMenuActions()
connect(main_ui_->actionStatisticsProtocolHierarchy, &QAction::triggered, this, [=]() {
ProtocolHierarchyDialog *phd = new ProtocolHierarchyDialog(*this, capture_file_);
- connect(phd, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)),
- this, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)));
+ connect(phd, &ProtocolHierarchyDialog::filterAction, this, &WiresharkMainWindow::filterAction);
phd->show();
});
@@ -3400,6 +3443,7 @@ void WiresharkMainWindow::connectStatisticsMenuActions()
connect(main_ui_->actionStatisticsCollectd, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("collectd"); });
connect(main_ui_->actionStatisticsDNS, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("dns"); });
+ connect(main_ui_->actionStatisticsDNS_QR, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("dns_qr"); });
connect(main_ui_->actionStatisticsHART_IP, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("hart_ip"); });
connect(main_ui_->actionStatisticsHpfeeds, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("hpfeeds"); });
connect(main_ui_->actionStatisticsHTTP2, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("http2"); });
@@ -3451,28 +3495,22 @@ void WiresharkMainWindow::connectStatisticsMenuActions()
connect(main_ui_->actionStatistics29WestUIM_Streams, &QAction::triggered, this, [=]() {
LBMStreamDialog *stream_dialog = new LBMStreamDialog(this, capture_file_.capFile());
- // connect(stream_dialog, SIGNAL(goToPacket(int)),
- // packet_list_, SLOT(goToPacket(int)));
- connect(this, SIGNAL(setCaptureFile(capture_file*)),
- stream_dialog, SLOT(setCaptureFile(capture_file*)));
+ // connect(stream_dialog, &LBMStreamDialog::goToPacket, packet_list_, &PacketList::goToPacket);
+ connect(this, &WiresharkMainWindow::setCaptureFile, stream_dialog, &LBMStreamDialog::setCaptureFile);
stream_dialog->show();
});
connect(main_ui_->actionStatistics29WestLBTRM, &QAction::triggered, this, [=]() {
LBMLBTRMTransportDialog * lbtrm_dialog = new LBMLBTRMTransportDialog(this, capture_file_.capFile());
- connect(lbtrm_dialog, SIGNAL(goToPacket(int)),
- packet_list_, SLOT(goToPacket(int)));
- connect(this, SIGNAL(setCaptureFile(capture_file*)),
- lbtrm_dialog, SLOT(setCaptureFile(capture_file*)));
+ connect(lbtrm_dialog, &LBMLBTRMTransportDialog::goToPacket, this, [=](int packet_num) {packet_list_->goToPacket(packet_num);});
+ connect(this, &WiresharkMainWindow::setCaptureFile, lbtrm_dialog, &LBMLBTRMTransportDialog::setCaptureFile);
lbtrm_dialog->show();
});
connect(main_ui_->actionStatistics29WestLBTRU, &QAction::triggered, this, [=]() {
LBMLBTRUTransportDialog * lbtru_dialog = new LBMLBTRUTransportDialog(this, capture_file_.capFile());
- connect(lbtru_dialog, SIGNAL(goToPacket(int)),
- packet_list_, SLOT(goToPacket(int)));
- connect(this, SIGNAL(setCaptureFile(capture_file*)),
- lbtru_dialog, SLOT(setCaptureFile(capture_file*)));
+ connect(lbtru_dialog, &LBMLBTRUTransportDialog::goToPacket, this, [=](int packet_num) {packet_list_->goToPacket(packet_num);});
+ connect(this, &WiresharkMainWindow::setCaptureFile, lbtru_dialog, &LBMLBTRUTransportDialog::setCaptureFile);
lbtru_dialog->show();
});
@@ -3505,10 +3543,8 @@ void WiresharkMainWindow::connectStatisticsMenuActions()
void WiresharkMainWindow::openTcpStreamDialog(int graph_type)
{
TCPStreamDialog *stream_dialog = new TCPStreamDialog(this, capture_file_.capFile(), (tcp_graph_type)graph_type);
- connect(stream_dialog, SIGNAL(goToPacket(int)),
- packet_list_, SLOT(goToPacket(int)));
- connect(this, SIGNAL(setCaptureFile(capture_file*)),
- stream_dialog, SLOT(setCaptureFile(capture_file*)));
+ connect(stream_dialog, &TCPStreamDialog::goToPacket, this, [=](int packet_num) {packet_list_->goToPacket(packet_num);});
+ connect(this, &WiresharkMainWindow::setCaptureFile, stream_dialog, &TCPStreamDialog::setCaptureFile);
if (stream_dialog->result() == QDialog::Accepted) {
stream_dialog->show();
}
@@ -3518,31 +3554,68 @@ void WiresharkMainWindow::openTcpStreamDialog(int graph_type)
void WiresharkMainWindow::statCommandMulticastStatistics(const char *arg, void *)
{
MulticastStatisticsDialog *mcast_stats_dlg = new MulticastStatisticsDialog(*this, capture_file_, arg);
- connect(mcast_stats_dlg, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)),
- this, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)));
+ connect(mcast_stats_dlg, &MulticastStatisticsDialog::filterAction, this, &WiresharkMainWindow::filterAction);
mcast_stats_dlg->show();
}
-void WiresharkMainWindow::openStatisticsTreeDialog(const gchar *abbr)
+void WiresharkMainWindow::openStatisticsTreeDialog(const char *abbr)
{
StatsTreeDialog *st_dialog = new StatsTreeDialog(*this, capture_file_, abbr);
-// connect(st_dialog, SIGNAL(goToPacket(int)),
-// packet_list_, SLOT(goToPacket(int)));
+// connect(st_dialog, &StatsTreeDialog::goToPacket, packet_list_, &PacketList::goToPacket);
st_dialog->show();
}
// -z io,stat
void WiresharkMainWindow::statCommandIOGraph(const char *, void *)
{
+ showIOGraphDialog(IOG_ITEM_UNIT_PACKETS, QString());
+}
+
+void WiresharkMainWindow::showIOGraphDialog(io_graph_item_unit_t value_units, QString yfield)
+{
const DisplayFilterEdit *df_edit = qobject_cast<DisplayFilterEdit *>(df_combo_box_->lineEdit());
+ IOGraphDialog *iog_dialog = nullptr;
QString displayFilter;
if (df_edit)
displayFilter = df_edit->text();
- IOGraphDialog *iog_dialog = new IOGraphDialog(*this, capture_file_, displayFilter);
- connect(iog_dialog, SIGNAL(goToPacket(int)), packet_list_, SLOT(goToPacket(int)));
- connect(this, SIGNAL(reloadFields()), iog_dialog, SLOT(reloadFields()));
- iog_dialog->show();
+ if (!yfield.isEmpty()) {
+ QList<IOGraphDialog *> iographdialogs = findChildren<IOGraphDialog *>();
+ // GeometryStateDialogs aren't parented on Linux and Windows
+ // (see geometry_state_dialog.h), so we search for an
+ // I/O Dialog in all the top level widgets.
+ if (iographdialogs.isEmpty()) {
+ foreach(QWidget *topLevelWidget, mainApp->topLevelWidgets()) {
+ if (qobject_cast<IOGraphDialog*>(topLevelWidget)) {
+ iographdialogs << qobject_cast<IOGraphDialog*>(topLevelWidget);
+ }
+ }
+ }
+ bool iog_found = false;
+ foreach(iog_dialog, iographdialogs) {
+ if (!iog_dialog->fileClosed()) {
+ iog_found = true;
+ iog_dialog->addGraph(true, displayFilter, value_units, yfield);
+ break;
+ }
+ }
+ if (!iog_found) {
+ iog_dialog = nullptr;
+ }
+ }
+
+ if (iog_dialog == nullptr) {
+ iog_dialog = new IOGraphDialog(*this, capture_file_, displayFilter, value_units, yfield);
+ connect(iog_dialog, &IOGraphDialog::goToPacket, this, [=](int packet_num) {packet_list_->goToPacket(packet_num);});
+ connect(this, &WiresharkMainWindow::reloadFields, iog_dialog, &IOGraphDialog::reloadFields);
+ }
+ if (iog_dialog->isMinimized()) {
+ iog_dialog->showNormal();
+ } else {
+ iog_dialog->show();
+ }
+ iog_dialog->raise();
+ iog_dialog->activateWindow();
}
// Telephony Menu
@@ -3570,7 +3643,7 @@ void WiresharkMainWindow::connectTelephonyMenuActions()
connect(main_ui_->actionTelephonyLteMacStatistics, &QAction::triggered, this, [=]() { statCommandLteMacStatistics(NULL, NULL); });
connect(main_ui_->actionTelephonyLteRlcGraph, &QAction::triggered, this, [=]() {
// We don't yet know the channel.
- launchRLCGraph(false, 0, 0, 0, 0, 0);
+ launchRLCGraph(false, RLC_RAT_LTE, 0, 0, 0, 0, 0);
});
connect(main_ui_->actionTelephonyLteRlcStatistics, &QAction::triggered, this, [=]() { statCommandLteRlcStatistics(NULL, NULL); });
@@ -3595,6 +3668,8 @@ void WiresharkMainWindow::connectTelephonyMenuActions()
connect(main_ui_->actionTelephonyNGAPMessages, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("ngap"); });
+ connect(main_ui_->actionTelephonyE2APMessages, &QAction::triggered, this, [=]() { openStatisticsTreeDialog("e2ap"); });
+
connect(main_ui_->actionTelephonySipFlows, &QAction::triggered, this, [=]() {
VoipCallsDialog *dialog = VoipCallsDialog::openVoipCallsDialogSip(*this, capture_file_, packet_list_);
dialog->show();
@@ -3626,38 +3701,35 @@ RtpAnalysisDialog *WiresharkMainWindow::openTelephonyRtpAnalysisDialog()
return dialog;
}
-// -z mac-lte,stat
+// -z mac-3gpp,stat
void WiresharkMainWindow::statCommandLteMacStatistics(const char *arg, void *)
{
LteMacStatisticsDialog *lte_mac_stats_dlg = new LteMacStatisticsDialog(*this, capture_file_, arg);
- connect(lte_mac_stats_dlg, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)),
- this, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)));
+ connect(lte_mac_stats_dlg, &LteMacStatisticsDialog::filterAction, this, &WiresharkMainWindow::filterAction);
lte_mac_stats_dlg->show();
}
void WiresharkMainWindow::statCommandLteRlcStatistics(const char *arg, void *)
{
LteRlcStatisticsDialog *lte_rlc_stats_dlg = new LteRlcStatisticsDialog(*this, capture_file_, arg);
- connect(lte_rlc_stats_dlg, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)),
- this, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)));
+ connect(lte_rlc_stats_dlg, &LteRlcStatisticsDialog::filterAction, this, &WiresharkMainWindow::filterAction);
// N.B. It is necessary for the RLC Statistics window to launch the RLC graph in this way, to ensure
// that the goToPacket() signal/slot connection gets set up...
- connect(lte_rlc_stats_dlg, SIGNAL(launchRLCGraph(bool, guint16, guint8, guint16, guint16, guint8)),
- this, SLOT(launchRLCGraph(bool, guint16, guint8, guint16, guint16, guint8)));
+ connect(lte_rlc_stats_dlg, &LteRlcStatisticsDialog::launchRLCGraph, this, &WiresharkMainWindow::launchRLCGraph);
lte_rlc_stats_dlg->show();
}
void WiresharkMainWindow::launchRLCGraph(bool channelKnown,
- guint16 ueid, guint8 rlcMode,
- guint16 channelType, guint16 channelId, guint8 direction)
+ uint8_t RAT, uint16_t ueid, uint8_t rlcMode,
+ uint16_t channelType, uint16_t channelId, uint8_t direction)
{
LteRlcGraphDialog *lrg_dialog = new LteRlcGraphDialog(*this, capture_file_, channelKnown);
- connect(lrg_dialog, SIGNAL(goToPacket(int)), packet_list_, SLOT(goToPacket(int)));
+ connect(lrg_dialog, &LteRlcGraphDialog::goToPacket, this, [=](int packet_num) {packet_list_->goToPacket(packet_num);});
// This is a bit messy, but wanted to hide these parameters from users of
// on_actionTelephonyLteRlcGraph_triggered().
if (channelKnown) {
- lrg_dialog->setChannelInfo(ueid, rlcMode, channelType, channelId, direction);
+ lrg_dialog->setChannelInfo(RAT, ueid, rlcMode, channelType, channelId, direction);
}
lrg_dialog->show();
}
@@ -3724,28 +3796,27 @@ void WiresharkMainWindow::connectWirelessMenuActions()
{
connect(main_ui_->actionBluetoothATT_Server_Attributes, &QAction::triggered, this, [=]() {
BluetoothAttServerAttributesDialog *bluetooth_att_sever_attributes_dialog = new BluetoothAttServerAttributesDialog(*this, capture_file_);
- connect(bluetooth_att_sever_attributes_dialog, SIGNAL(goToPacket(int)),
- packet_list_, SLOT(goToPacket(int)));
- connect(bluetooth_att_sever_attributes_dialog, SIGNAL(updateFilter(QString, bool)),
- this, SLOT(filterPackets(QString, bool)));
+ connect(bluetooth_att_sever_attributes_dialog, &BluetoothAttServerAttributesDialog::goToPacket,
+ this, [=](int packet_num) {packet_list_->goToPacket(packet_num);});
+ connect(bluetooth_att_sever_attributes_dialog, &BluetoothAttServerAttributesDialog::updateFilter,
+ this, &WiresharkMainWindow::filterPackets);
bluetooth_att_sever_attributes_dialog->show();
});
connect(main_ui_->actionBluetoothDevices, &QAction::triggered, this, [=]() {
BluetoothDevicesDialog *bluetooth_devices_dialog = new BluetoothDevicesDialog(*this, capture_file_, packet_list_);
- connect(bluetooth_devices_dialog, SIGNAL(goToPacket(int)),
- packet_list_, SLOT(goToPacket(int)));
- connect(bluetooth_devices_dialog, SIGNAL(updateFilter(QString, bool)),
- this, SLOT(filterPackets(QString, bool)));
+ connect(bluetooth_devices_dialog, &BluetoothDevicesDialog::goToPacket, this, [=](int packet_num) {packet_list_->goToPacket(packet_num);});
+ connect(bluetooth_devices_dialog, &BluetoothDevicesDialog::updateFilter,
+ this, &WiresharkMainWindow::filterPackets);
bluetooth_devices_dialog->show();
});
connect(main_ui_->actionBluetoothHCI_Summary, &QAction::triggered, this, [=]() {
BluetoothHciSummaryDialog *bluetooth_hci_summary_dialog = new BluetoothHciSummaryDialog(*this, capture_file_);
- connect(bluetooth_hci_summary_dialog, SIGNAL(goToPacket(int)),
- packet_list_, SLOT(goToPacket(int)));
- connect(bluetooth_hci_summary_dialog, SIGNAL(updateFilter(QString, bool)),
- this, SLOT(filterPackets(QString, bool)));
+ connect(bluetooth_hci_summary_dialog, &BluetoothHciSummaryDialog::goToPacket,
+ this, [=](int packet_num) {packet_list_->goToPacket(packet_num);});
+ connect(bluetooth_hci_summary_dialog, &BluetoothHciSummaryDialog::updateFilter,
+ this, &WiresharkMainWindow::filterPackets);
bluetooth_hci_summary_dialog->show();
});
@@ -3824,7 +3895,7 @@ void WiresharkMainWindow::checkForUpdates()
void WiresharkMainWindow::setPreviousFocus() {
previous_focus_ = mainApp->focusWidget();
if (previous_focus_ != nullptr) {
- connect(previous_focus_, SIGNAL(destroyed()), this, SLOT(resetPreviousFocus()));
+ connect(previous_focus_, &QWidget::destroyed, this, &WiresharkMainWindow::resetPreviousFocus);
}
}
@@ -3836,7 +3907,7 @@ void WiresharkMainWindow::goToCancelClicked()
{
main_ui_->goToFrame->animatedHide();
if (previous_focus_) {
- disconnect(previous_focus_, SIGNAL(destroyed()), this, SLOT(resetPreviousFocus()));
+ disconnect(previous_focus_, &QWidget::destroyed, this, &WiresharkMainWindow::resetPreviousFocus);
previous_focus_->setFocus();
resetPreviousFocus();
}
@@ -3871,24 +3942,23 @@ void WiresharkMainWindow::showResolvedAddressesDialog()
void WiresharkMainWindow::showConversationsDialog()
{
ConversationDialog *conv_dialog = new ConversationDialog(*this, capture_file_);
- connect(conv_dialog, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)),
- this, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)));
- connect(conv_dialog, SIGNAL(openFollowStreamDialog(int, guint, guint)),
- this, SLOT(openFollowStreamDialog(int, guint, guint)));
- connect(conv_dialog, SIGNAL(openTcpStreamGraph(int)),
- this, SLOT(openTcpStreamDialog(int)));
+ connect(conv_dialog, &ConversationDialog::filterAction, this, &WiresharkMainWindow::filterAction);
+ connect(conv_dialog, &ConversationDialog::openFollowStreamDialog, this,
+ [=](int proto_id, unsigned stream_num, unsigned sub_stream_num) {
+ openFollowStreamDialog(proto_id, stream_num, sub_stream_num);
+ });
+ connect(conv_dialog, &ConversationDialog::openTcpStreamGraph, this, &WiresharkMainWindow::openTcpStreamDialog);
conv_dialog->show();
}
void WiresharkMainWindow::showEndpointsDialog()
{
EndpointDialog *endp_dialog = new EndpointDialog(*this, capture_file_);
- connect(endp_dialog, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)),
- this, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)));
- connect(endp_dialog, SIGNAL(openFollowStreamDialog(int)),
- this, SLOT(openFollowStreamDialog(int)));
- connect(endp_dialog, SIGNAL(openTcpStreamGraph(int)),
- this, SLOT(openTcpStreamDialog(int)));
+ connect(endp_dialog, &EndpointDialog::filterAction, this, &WiresharkMainWindow::filterAction);
+ connect(endp_dialog, &EndpointDialog::openFollowStreamDialog, this,
+ [=](int proto_id) {openFollowStreamDialog(proto_id);
+ });
+ connect(endp_dialog, &EndpointDialog::openTcpStreamGraph, this, &WiresharkMainWindow::openTcpStreamDialog);
endp_dialog->show();
}
@@ -3906,9 +3976,9 @@ void WiresharkMainWindow::externalMenuItemTriggered()
entry = (ext_menubar_t *)v.value<void *>();
if (entry->type == EXT_MENUBAR_ITEM) {
- entry->callback(EXT_MENUBAR_QT_GUI, (gpointer)((void *)main_ui_), entry->user_data);
+ entry->callback(EXT_MENUBAR_QT_GUI, (void *)((void *)main_ui_), entry->user_data);
} else {
- QDesktopServices::openUrl(QUrl(QString((gchar *)entry->user_data)));
+ QDesktopServices::openUrl(QUrl(QString((char *)entry->user_data)));
}
}
}
@@ -3932,15 +4002,11 @@ void WiresharkMainWindow::showExtcapOptionsDialog(QString &device_name, bool sta
if (extcap_options_dialog) {
extcap_options_dialog->setModal(true);
extcap_options_dialog->setAttribute(Qt::WA_DeleteOnClose);
- if (startCaptureOnClose) {
- connect(extcap_options_dialog, SIGNAL(finished(int)),
- this, SLOT(extcap_options_finished(int)));
- }
+ connect(extcap_options_dialog, &ExtcapOptionsDialog::finished, this, &WiresharkMainWindow::extcap_options_finished);
#ifdef HAVE_LIBPCAP
- if (capture_options_dialog_ && startCaptureOnClose) {
+ if (capture_options_dialog_) {
/* Allow capture options dialog to close */
- connect(extcap_options_dialog, SIGNAL(accepted()),
- capture_options_dialog_, SLOT(accept()));
+ connect(extcap_options_dialog, &ExtcapOptionsDialog::accepted, capture_options_dialog_, &CaptureOptionsDialog::accept);
}
#endif
extcap_options_dialog->show();
diff --git a/ui/qt/wireshark_pl.ts b/ui/qt/wireshark_pl.ts
index efd144dc..530878c0 100644
--- a/ui/qt/wireshark_pl.ts
+++ b/ui/qt/wireshark_pl.ts
@@ -21,7 +21,7 @@
</message>
<message>
<source>&lt;span size=\&quot;x-large\&quot; weight=\&quot;bold\&quot;&gt;Network Protocol Analyzer&lt;/span&gt;</source>
- <translation>&lt;span size=\&quot;x-large\&quot; weight=\&quot;bold\&quot;&gt;Analizator protokołów sieciowych&lt;/span&gt;</translation>
+ <translation>&lt;span size=\&quot;x-large\&quot; weight=\&quot;bold\&quot;&gt;Analizator Protokołów&lt;/span&gt;</translation>
</message>
<message>
<source>Copy the version information to the clipboard</source>
@@ -44,8 +44,8 @@
<translation>Foldery</translation>
</message>
<message>
- <source>Filter by path</source>
- <translation>Filtruj po ścieżce</translation>
+ <source>Search Folders</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Plugins</source>
@@ -80,6 +80,14 @@
<translation>Licencja</translation>
</message>
<message>
+ <source>About Logray</source>
+ <translation>O Logray</translation>
+ </message>
+ <message>
+ <source>Logray</source>
+ <translation>Logray</translation>
+ </message>
+ <message>
<source>The directory does not exist</source>
<translation>Katalog nie istnieje.</translation>
</message>
@@ -109,10 +117,10 @@
</message>
<message numerus="yes">
<source>Copy Row(s)</source>
- <translation>
- <numerusform>Kopiuj wiersz</numerusform>
- <numerusform>Kopiuj wiersze</numerusform>
- <numerusform>Kopiuj wiersze</numerusform>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
</translation>
</message>
</context>
@@ -137,7 +145,7 @@
</message>
<message>
<source>Can&apos;t assign %1 to %2.</source>
- <translation>Nie można przypisać %1 do %2.</translation>
+ <translation>Nie można przypisać %1 do %2</translation>
</message>
</context>
<context>
@@ -756,6 +764,28 @@
</message>
</context>
<context>
+ <name>CaptureCommentDialog</name>
+ <message>
+ <source>Edit Capture Comments</source>
+ <translation>Edytuj komentarze przechwytywania</translation>
+ </message>
+ <message>
+ <source>Add Comment</source>
+ <translation>Dodaj komentarz</translation>
+ </message>
+ <message>
+ <source>Section %1</source>
+ <translation>Sekcja %1</translation>
+ </message>
+</context>
+<context>
+ <name>CaptureCommentTabWidget</name>
+ <message>
+ <source>Comment %1</source>
+ <translation>Komentarz %1</translation>
+ </message>
+</context>
+<context>
<name>CaptureFile</name>
<message>
<source> [closing]</source>
@@ -812,32 +842,6 @@
<source>Automatically detect file type</source>
<translation>Automatycznie wykryj typ pliku</translation>
</message>
- <message numerus="yes">
- <source>%1, error after %Ln packet(s)</source>
- <oldsource>%1, error after %2 packets</oldsource>
- <translation type="vanished">
- <numerusform>%1, błąd po wczytaniu %Ln pakiet</numerusform>
- <numerusform>%1, błąd po wczytaniu %Ln pakietów</numerusform>
- <numerusform>%1, błąd po wczytaniu %Ln pakietów</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source>%1, timed out at %Ln packet(s)</source>
- <oldsource>%1, timed out at %2 packets</oldsource>
- <translation type="vanished">
- <numerusform>%1, przekroczenie czasu przy %Ln pakiecie</numerusform>
- <numerusform>%1, przekroczenie czasu przy %Ln pakiecie</numerusform>
- <numerusform>%1, przekroczenie czasu przy %Ln pakiecie</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source>%1, %Ln packet(s)</source>
- <translation type="vanished">
- <numerusform>%1, %Ln pakiet</numerusform>
- <numerusform>%1, %Ln pakiety</numerusform>
- <numerusform>%1, %Ln pakietów</numerusform>
- </translation>
- </message>
<message>
<source>Prepend packets</source>
<translation>Dodaj pakiety na początku</translation>
@@ -867,10 +871,6 @@
<translation>Filtr wczytywania:</translation>
</message>
<message>
- <source>Compress with g&amp;zip</source>
- <translation>Kompresuj używając gzip</translation>
- </message>
- <message>
<source>Open Capture File</source>
<oldsource>Wireshark: Open Capture File</oldsource>
<translation>Otwórz plik przechwytywania</translation>
@@ -921,26 +921,26 @@
<message numerus="yes">
<source>%1, error after %Ln data record(s)</source>
<oldsource>%1, error after %Ln record(s)</oldsource>
- <translation>
- <numerusform>%1, błąd po wczytaniu %Ln pakietu</numerusform>
- <numerusform>%1, błąd po wczytaniu %Ln pakietów</numerusform>
- <numerusform>%1, błąd po wczytaniu %Ln pakietów</numerusform>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
<source>%1, timed out at %Ln data record(s)</source>
- <translation>
- <numerusform>%1, przekroczono limit czasu dla %Ln rekordu danych</numerusform>
- <numerusform>%1, przekroczono limit czasu dla %Ln rekordów danych</numerusform>
- <numerusform>%1, przekroczono limit czasu dla %Ln rekordów danych</numerusform>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
<source>%1, %Ln data record(s)</source>
- <translation>
- <numerusform>%1, %Ln rekord danych</numerusform>
- <numerusform>%1, %Ln rekordy danych</numerusform>
- <numerusform>%1, %Ln rekordów danych</numerusform>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message>
@@ -955,8 +955,8 @@
<translation>Szczegóły</translation>
</message>
<message>
- <source>Capture file comments</source>
- <translation>Komentarze pliku przechwytywania</translation>
+ <source>Edit Comments</source>
+ <translation>Edytuj komentarze</translation>
</message>
<message>
<source>Refresh</source>
@@ -967,10 +967,6 @@
<translation>Skopiuj do schowka</translation>
</message>
<message>
- <source>Save Comments</source>
- <translation>Zapisz komentarze</translation>
- </message>
- <message>
<source>Capture File Properties</source>
<translation>Szczegóły pliku przechwytywania</translation>
</message>
@@ -1019,10 +1015,18 @@
<translation>Pierwszy pakiet</translation>
</message>
<message>
+ <source>First event</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Last packet</source>
<translation>Ostatni pakiet</translation>
</message>
<message>
+ <source>Last event</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Elapsed</source>
<translation>Minęło</translation>
</message>
@@ -1059,6 +1063,10 @@
<translation>Porzucone pakiety</translation>
</message>
<message>
+ <source>Dropped events</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Capture filter</source>
<translation>Filtr przechwytywania</translation>
</message>
@@ -1071,6 +1079,10 @@
<translation>Limit rozmiaru pakietu (snaplen)</translation>
</message>
<message>
+ <source>Event size limit (snaplen)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>none</source>
<translation>brak</translation>
</message>
@@ -1079,6 +1091,26 @@
<translation>%1 bajtów</translation>
</message>
<message>
+ <source>Comments</source>
+ <translation>Komentarze</translation>
+ </message>
+ <message>
+ <source>Comment %1: </source>
+ <translation>Komentarz %1: </translation>
+ </message>
+ <message>
+ <source>Decryption Secrets</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Typ</translation>
+ </message>
+ <message>
+ <source>Size</source>
+ <translation>Rozmiar</translation>
+ </message>
+ <message>
<source>Statistics</source>
<translation>Statystyki</translation>
</message>
@@ -1103,6 +1135,10 @@
<translation>Pakiety</translation>
</message>
<message>
+ <source>Events</source>
+ <translation type="unfinished">Events</translation>
+ </message>
+ <message>
<source>Time span, s</source>
<translation>Okres czasu, s</translation>
</message>
@@ -1115,6 +1151,10 @@
<translation>Średni rozmiar pakietu, B</translation>
</message>
<message>
+ <source>Average event size, B</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Bytes</source>
<translation>Bajty</translation>
</message>
@@ -1127,14 +1167,14 @@
<translation>Średnio bitów/s</translation>
</message>
<message>
- <source>Section Comment</source>
- <translation>Komentarz sekcji</translation>
- </message>
- <message>
<source>Packet Comments</source>
<translation>Komentarze pakietu</translation>
</message>
<message>
+ <source>Event Comments</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;p&gt;Frame %1: </source>
<translation>&lt;p&gt;Ramka %1: </translation>
</message>
@@ -1144,6 +1184,14 @@
</source>
<translation>Stworzony dzięki Wiresharkowi %1</translation>
</message>
+ <message>
+ <source>Created by Logray %1
+
+</source>
+ <translation>Stworzony dzięki Logray %1
+
+</translation>
+ </message>
</context>
<context>
<name>CaptureFilterCombo</name>
@@ -1262,7 +1310,7 @@
</message>
<message>
<source>Show and hide interfaces, add comments, and manage pipes and remote interfaces.</source>
- <translation>Pokaż lub ukryj interfejsy, dodaj komentarze i zarządzaj interfejsami pipe oraz zdalnymi.</translation>
+ <translation>Pokaż lub ukryj interfejsy, dodaj komentarze i zarządzaj potokami oraz zdalnymi interfejsami.</translation>
</message>
<message>
<source>Manage Interfaces…</source>
@@ -1326,7 +1374,7 @@
</message>
<message>
<source>packets</source>
- <translation>pakiety</translation>
+ <translation>pakietów</translation>
</message>
<message>
<source>Switch to the next file after the file size exceeds the specified file size.</source>
@@ -1358,7 +1406,7 @@
</message>
<message>
<source>hours</source>
- <translation>godzinach</translation>
+ <translation>godzin</translation>
</message>
<message>
<source>when time is a multiple of</source>
@@ -1370,6 +1418,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for some more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Zwykle bezprzewodowa karta sieciowa przechwytuje tylko ruch wysyłany do i z jej własnego adresu sieciowego, i tylko przechwytuje ruch &lt;em&gt;danych użytkownika&lt;/em&gt; z &amp;quot;fałszywymi&amp;quot; ruch nagłówkami Ethernet. Jeśli chcesz przechwytywać cały ruch, który karty sieci bezprzewodowej mogą „widzieć”, lub interesują Cię pakiety zarządzania lub kontroli standardu 802.11 albo informacje warstwy radiowej, zaznacz tę opcję. Dostępność trybu monitorowania zależy od karty bezprzewodowej i sterownika. Więcej szczegółów na temat przechwytywania pakietów w sieciach WLAN można znaleźć na Wiki.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>Enable monitor mode on all 802.11 interfaces</source>
+ <translation>Włącz tryb monitora na wszystkich interfejsach 802.11</translation>
+ </message>
+ <message>
<source>compression</source>
<translation>kompresja</translation>
</message>
@@ -1382,8 +1438,32 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>gzip</translation>
</message>
<message>
+ <source>File infix pattern</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;In multiple file mode, the date and time and file index number are inserted between filename template and any suffix. Select their order.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>YYYYmmDDHHMMSS_NNNNN</source>
+ <translation>YYYYmmDDHHMMSS_NNNNN</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Date and time before the file index number. This causes files to sort in creation time order, and keeps files from the same batch closely ordered.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>NNNNN_YYYYmmDDHHMMSS</source>
+ <translation>NNNNN_YYYYmmDDHHMMSS</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;File index number before the date and time. This is the historic Wireshark ordering.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;After capturing has switched to the next file and the given number of files has exceeded, the oldest file will be removed.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Kiedy przechwytywanie jest przekierowywane do nowego pliku i liczba plików zostanie przekroczona to skasuj najstarszy plik.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Use a ring buffer with </source>
@@ -1391,7 +1471,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>files</source>
- <translation>pliki</translation>
+ <translation>plików</translation>
</message>
<message>
<source>Options</source>
@@ -1403,7 +1483,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Using this option will show the captured packets immediately on the main screen. Please note: this will slow down capturing, so increased packet drops might appear.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Wybierając tą opcję przechwytywane pakiety będą bezpośrednio wyświetlane na ekranie. Uwaga: to może spowalniać przechwytywanie, co może skutkować możliwością zgubienia pakietów.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Update list of packets in real-time</source>
@@ -1470,6 +1550,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Zatrzymaj przechwytywanie po stworzeniu określonej liczby plików.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
+ <source>Stop capturing after the specified number of files have been created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Stop capturing after the specified amount of data has been captured.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Zatrzymaj przechwytywanie po przekroczeniu ustalonego rozmiaru danych.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1523,15 +1607,15 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>no addresses</source>
- <translation>brak adresu</translation>
+ <translation>brak adresów</translation>
</message>
<message>
<source>Error</source>
<translation>Błąd</translation>
</message>
<message>
- <source>Multiple files: Requested filesize too large. The filesize cannot be greater than 2 GiB.</source>
- <translation>Wiele plików: Żądana wielkość pliku jest zbyt duża. Wielkość pliku nie może być większa niż 2 GiB.</translation>
+ <source>Multiple files: Requested filesize too large. The filesize cannot be greater than 2 TB.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Multiple files: No capture file name given. You must specify a filename if you want to use multiple files.</source>
@@ -1539,7 +1623,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Multiple files: No file limit given. You must specify a file size, interval, or number of packets for each file.</source>
- <translation>Wiele plików: bez limitu plików. Dla każdego pliku należy określić rozmiar pliku, interwał lub liczbę pakietów.</translation>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -1561,6 +1645,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Zrzucaj pakiety w trybie mieszanym</translation>
</message>
<message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Capture packets in monitor mode on 802.11 devices</source>
+ <translation>Przechwytuj pakiety w trybie monitora na urządzeniach 802.11</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Capture packets in the next-generation capture file format.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Zapisuj pakiety w formacie pcap-ng&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1742,7 +1834,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Resolve Names:</source>
- <translation>Rozwiązuj nazwy:</translation>
+ <translation>Rozwiąż nazwy:</translation>
</message>
<message>
<source>&lt;html&gt;&lt;head/&gt;&lt;p&gt;Show human-readable strings instead of raw values for fields. Only applicable to custom columns with fields that have value strings.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
@@ -1788,6 +1880,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Rozwiązane</translation>
</message>
<message>
+ <source>Width</source>
+ <translation>Szerokość</translation>
+ </message>
+ <message>
+ <source>Alignment</source>
+ <translation>Wyrównanie</translation>
+ </message>
+ <message>
<source>&lt;html&gt;Show human-readable strings instead of raw values for fields. Only applicable to custom columns with fields that have value strings.&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
@@ -1835,6 +1935,25 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>CompressionGroupBox</name>
+ <message>
+ <source>Compression options</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Uncompressed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Compress with g&amp;zip</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Compress with &amp;LZ4</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>ConversationDataModel</name>
<message>
<source>Address A</source>
@@ -1901,6 +2020,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Bitów/sek. B</translation>
</message>
<message>
+ <source>Flows</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Total Packets</source>
<translation>Całkowita liczba pakietów</translation>
</message>
@@ -1921,7 +2044,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Graph…</source>
- <translation>Wykres</translation>
+ <translation>Wykres...</translation>
</message>
<message>
<source>Graph a TCP conversation.</source>
@@ -1947,7 +2070,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Copy entries from another profile.</source>
- <translation>Kopiuj z innego profilu.</translation>
+ <translation>Skopiuj wpisy z innego profilu.</translation>
</message>
<message>
<source>System default</source>
@@ -2008,21 +2131,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>…as Hex Dump</source>
- <translation>…jako Hex Dump</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Copy packet bytes as a hex dump.</source>
<translation>Kopiuj bajty pakietu jako Hex.</translation>
</message>
<message>
- <source>…as Printable Text</source>
- <translation>…drukowalny tekst</translation>
- </message>
- <message>
- <source>Copy only the printable text in the packet.</source>
- <translation>Kopiuj tylko drukowalny tekst z pakietu.</translation>
- </message>
- <message>
<source>…as MIME Data</source>
<translation>…jako dane MIME</translation>
</message>
@@ -2035,8 +2150,40 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>…as Go literal</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as Go literal.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>…as C Array</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as C Array.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>…as a Hex Stream</source>
- <translation>…jako strumień Hex</translation>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>…as UTF-8 Text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as text, treating as UTF-8.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>…as ASCII Text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as text, treating as ASCII.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Copy packet bytes as a stream of hex.</source>
@@ -2090,7 +2237,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Change behavior when the field matches this value</source>
- <translation type="unfinished"></translation>
+ <translation>Zmień zachowanie, gdy pole odpowiada tej wartości</translation>
</message>
<message>
<source>Field value type (and base, if Integer)</source>
@@ -2168,7 +2315,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Display Filter Expression…</source>
- <translation type="unfinished">Wyrażenie filtru wyświetlania...</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Apply a display filter %1 &lt;%2/&gt;</source>
@@ -2344,7 +2491,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<name>DissectorTablesProxyModel</name>
<message>
<source>Table Type</source>
- <translation>Typ Tabeli</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>String</source>
@@ -2391,7 +2538,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>in</source>
- <translation>w</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Enable All</source>
@@ -2536,7 +2683,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Save As…</source>
- <translation>Zapisz jako…</translation>
+ <translation>Zapisz jako...</translation>
</message>
<message>
<source>Map file error</source>
@@ -2774,7 +2921,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Only display entries containing this string</source>
- <translation type="unfinished"></translation>
+ <translation>Wyświetlaj tylko wpisy zawierające ten ciąg</translation>
</message>
<message>
<source>Preview</source>
@@ -2834,6 +2981,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Display filter:</source>
<translation>Filtr:</translation>
</message>
+ <message>
+ <source>Export PDUs</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>ExtArgSelector</name>
@@ -2873,10 +3024,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Start</translation>
</message>
<message>
- <source>Save</source>
- <translation>Zapisz</translation>
- </message>
- <message>
<source>Default</source>
<translation>Domyślnie</translation>
</message>
@@ -2933,10 +3080,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<message numerus="yes">
<source>%Ln File(s) in Set</source>
<oldsource>%1 File%2 in Set</oldsource>
- <translation>
- <numerusform>%Ln plik w zbiorze</numerusform>
- <numerusform>%Ln pliki w zbiorze</numerusform>
- <numerusform>%Ln plików w zbiorze</numerusform>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
</translation>
</message>
</context>
@@ -2967,11 +3114,11 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<name>FilterAction</name>
<message>
<source>Selected</source>
- <translation>Wybrane</translation>
+ <translation>Wybrany</translation>
</message>
<message>
<source>Not Selected</source>
- <translation>Nie wybrane</translation>
+ <translation>Nie wybrany</translation>
</message>
<message>
<source>…and Selected</source>
@@ -3019,6 +3166,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Filtry wyświetlania</translation>
</message>
<message>
+ <source>Display Filter Macros</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>New macro</source>
+ <translation>Nowe makro</translation>
+ </message>
+ <message>
<source>Open </source>
<translation>Otwórz</translation>
</message>
@@ -3061,7 +3216,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Comment:</source>
- <translation>Komentarz</translation>
+ <translation>Komentarz:</translation>
</message>
<message>
<source>Enter a comment for the filter button</source>
@@ -3102,10 +3257,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>FilterListModel</name>
<message>
+ <source>Macro Name</source>
+ <translation>Nazwa makra</translation>
+ </message>
+ <message>
<source>Filter Name</source>
<translation>Nazwa filtra</translation>
</message>
<message>
+ <source>Macro Expression</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Filter Expression</source>
<translation>Wyrażenie filtru</translation>
</message>
@@ -3114,11 +3277,11 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<name>FindLineEdit</name>
<message>
<source>Textual Find</source>
- <translation type="unfinished"></translation>
+ <translation>Wyszukiwanie tekstu</translation>
</message>
<message>
<source>Regular Expression Find</source>
- <translation type="unfinished"></translation>
+ <translation>Wyszukiwanie wyrażeniem regularnym</translation>
</message>
</context>
<context>
@@ -3191,22 +3354,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>FolderListModel</name>
<message>
- <source>&quot;File&quot; dialogs</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>capture files</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Temp</source>
<translation>Temp</translation>
</message>
<message>
- <source>untitled capture files</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Personal configuration</source>
<translation type="unfinished"></translation>
</message>
@@ -3215,14 +3366,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Konfiguracja globalna</translation>
</message>
<message>
- <source>dfilters, preferences, ethers, …</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>dfilters, preferences, manuf, …</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>System</source>
<translation type="unfinished"></translation>
</message>
@@ -3235,18 +3378,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
- <source>program files</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Personal Plugins</source>
<translation>Wtyczki osobiste</translation>
</message>
<message>
- <source>binary plugins</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Global Plugins</source>
<translation>Globalne wtyczki</translation>
</message>
@@ -3263,11 +3398,35 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Skrypty Lua</translation>
</message>
<message>
+ <source>&quot;File&quot; dialog location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Capture files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Untitled capture files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Preferences, profiles, manuf, …</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Program files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Binary plugins</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Personal Extcap path</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>external capture (extcap) plugins</source>
+ <source>External capture (extcap) plugins</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -3329,22 +3488,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Print</source>
<translation>Drukuj</translation>
</message>
- <message numerus="yes">
- <source>%Ln client pkt(s), </source>
- <translation type="vanished">
- <numerusform>%Ln pakiet klienta,</numerusform>
- <numerusform>%Ln pakiety klienta,</numerusform>
- <numerusform>%Ln pakietów klienta,</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source>%Ln server pkt(s), </source>
- <translation type="vanished">
- <numerusform>%Ln pakiet serwera,</numerusform>
- <numerusform>%Ln pakiety serwera,</numerusform>
- <numerusform>%Ln pakietów serwera,</numerusform>
- </translation>
- </message>
<message>
<source>ASCII</source>
<translation>ASCII</translation>
@@ -3387,26 +3530,46 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message numerus="yes">
<source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;client&lt;/span&gt; pkt(s), </source>
- <translation>
- <numerusform>%Ln pakiet &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;klienta&lt;/span&gt;, </numerusform>
- <numerusform>%Ln pakiety &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;klienta&lt;/span&gt;, </numerusform>
- <numerusform>%Ln pakietów &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;klienta&lt;/span&gt;, </numerusform>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
<source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;server&lt;/span&gt; pkt(s), </source>
- <translation>
- <numerusform>%Ln pakiet &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;serwera&lt;/span&gt;,</numerusform>
- <numerusform>%Ln pakiety &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;serwera&lt;/span&gt;, </numerusform>
- <numerusform>%Ln pakietów &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;serwera&lt;/span&gt;, </numerusform>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
<source>%Ln turn(s).</source>
- <translation>
- <numerusform>%Ln próba.</numerusform>
- <numerusform>%Ln próby.</numerusform>
- <numerusform>%Ln prób.</numerusform>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Event %1. </source>
+ <translation>Zdarzenie %1.</translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;reads&lt;/span&gt;, </source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;writes&lt;/span&gt;, </source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message>
@@ -3442,6 +3605,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Nie znaleziono strumienia %1 w wybranym pakiecie.</translation>
</message>
<message>
+ <source>Read activity(%6)</source>
+ <translation>Aktywność odczytu(%6)</translation>
+ </message>
+ <message>
+ <source>Write activity(%6)</source>
+ <translation>Aktywność zapisu(%6)</translation>
+ </message>
+ <message>
+ <source>Entire I/O activity (%1)</source>
+ <translation>Cała aktywność we/wy (%1)</translation>
+ </message>
+ <message>
<source>Entire conversation (%1)</source>
<translation type="unfinished"></translation>
</message>
@@ -3457,16 +3632,12 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Save Stream Content As…</source>
<translation>Zapisz zawartość strumienia jako...</translation>
</message>
- <message>
- <source>[Stream output truncated]</source>
- <translation type="unfinished"></translation>
- </message>
<message numerus="yes">
<source>%Ln total stream(s).</source>
- <translation>
- <numerusform>%Ln strumień.</numerusform>
- <numerusform>%Ln strumienie.</numerusform>
- <numerusform>%Ln strumieni.</numerusform>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
@@ -3490,9 +3661,20 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Podpowiedź.</translation>
</message>
<message>
- <source>Show data as</source>
- <oldsource>Show and save data as</oldsource>
- <translation>Pokazuj dane jako</translation>
+ <source>Show as</source>
+ <translation>Pokaż jako</translation>
+ </message>
+ <message>
+ <source>No delta times</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Turn delta times</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All delta times</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Stream</source>
@@ -3507,11 +3689,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Znajdź:</translation>
</message>
<message>
+ <source>Case sensitive</source>
+ <translation>Rozróżniaj wielkość znaków</translation>
+ </message>
+ <message>
<source>Find &amp;Next</source>
<translation>Znajdź &amp;następny</translation>
</message>
</context>
<context>
+ <name>FollowStreamText</name>
+ <message>
+ <source>[Stream output truncated]</source>
+ <translation>[Obcięto dane strumienia]</translation>
+ </message>
+</context>
+<context>
<name>FontColorPreferencesFrame</name>
<message>
<source>Frame</source>
@@ -3580,7 +3773,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<message>
<source>Sample warning filter</source>
<oldsource>Sample deprecated filter</oldsource>
- <translation>Przykładowy filtr z ostrzeżeniem</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Example GIF query packets have jumbo window sizes</source>
@@ -3840,29 +4033,28 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <source>Remove this graph.</source>
- <oldsource>Remove this dissection behavior.</oldsource>
- <translation>Usuń ten wykres.</translation>
- </message>
- <message>
<source>Add a new graph.</source>
<translation>Utwórz nowy wykres.</translation>
</message>
<message>
- <source>Duplicate this graph.</source>
- <translation>Duplikuj ten wykres.</translation>
- </message>
- <message>
<source>Clear all graphs.</source>
<translation>Wyczyść wszystkie wykresy.</translation>
</message>
<message>
- <source>Move this graph upwards.</source>
- <translation>Przesuń ten wykres w górę.</translation>
+ <source>Remove the selected graph(s).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Duplicate the selected graph(s).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move the selected graph(s) upwards.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Move this graph downwards.</source>
- <translation>Przesuń ten wykres w dół.</translation>
+ <source>Move the selected graph(s) downwards.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Mouse</source>
@@ -3905,10 +4097,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Włącz legendę</translation>
</message>
<message>
- <source>Reset</source>
- <translation>Reset</translation>
- </message>
- <message>
<source>Reset Graph</source>
<translation>Resetuj wykres</translation>
</message>
@@ -4107,7 +4295,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>I/O Graphs</source>
- <translation>Wykresy I/O</translation>
+ <translation>Wykresy we./wy.</translation>
</message>
<message>
<source>Save As…</source>
@@ -4122,6 +4310,42 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Skopiuj wykresy z innego profilu.</translation>
</message>
<message>
+ <source>1 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>2 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>5 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>10 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>20 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>50 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>100 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>200 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>500 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>1 ms</source>
<translation>1 ms</translation>
</message>
@@ -4166,8 +4390,16 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>5 sek.</translation>
</message>
<message>
+ <source>2 min</source>
+ <translation type="unfinished">10 min {2 ?}</translation>
+ </message>
+ <message>
+ <source>5 min</source>
+ <translation type="unfinished">10 min {5 ?}</translation>
+ </message>
+ <message>
<source>Wireshark I/O Graphs: %1</source>
- <translation>Wireshark wykres we./wy.: %1</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Filtered packets</source>
@@ -4178,6 +4410,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Filtrowane zdarzenia</translation>
</message>
<message>
+ <source>All packets</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All events</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>All Packets</source>
<translation>Wszystkie pakiety</translation>
</message>
@@ -4190,8 +4430,8 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Wszystkie zdarzenia</translation>
</message>
<message>
- <source>Access Denied</source>
- <translation>Brak dostępu</translation>
+ <source>All Execs</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Hover over the graph for details.</source>
@@ -4238,6 +4478,34 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Kliknij by wybrać obszar wykresu.</translation>
</message>
<message>
+ <source>%1 Intervals </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to top left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to top center</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to top right</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to bottom left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to bottom center</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to bottom right</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Portable Document Format (*.pdf)</source>
<translation>Dokument PDF (*.pdf)</translation>
</message>
@@ -4259,7 +4527,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Save Graph As…</source>
- <translation>Zapisz wykres jako...</translation>
+ <translation>Zapisz wykres jako</translation>
</message>
</context>
<context>
@@ -4714,7 +4982,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Prefix each frame with an Ethernet and IP header</source>
- <translation>Poprzedź każdą ramkę nagłówkami Ethernet i IPv4</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>IP</source>
@@ -4722,19 +4990,19 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Prefix each frame with an Ethernet, IP and UDP header</source>
- <translation>Poprzedź każdą ramkę nagłówkami Ethernet, IPv4 i UDP</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Prefix each frame with an Ethernet, IP and TCP header</source>
- <translation>Poprzedź każdą ramkę nagłówkami Ethernet, IPv4 i TCP</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Prefix each frame with an Ethernet, IP and SCTP header</source>
- <translation>Poprzedź każdą ramkę nagłówkami Ethernet, IPv4 i SCTP</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Prefix each frame with an Ethernet, IP and SCTP (DATA) header</source>
- <translation>Poprzedź każdą ramkę nagłówkami Ethernet, IPv4 i SCTP (dane)</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Source address:</source>
@@ -4885,7 +5153,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Pipe</source>
- <translation type="unfinished"></translation>
+ <translation>Potok</translation>
</message>
<message>
<source>STDIN</source>
@@ -4990,6 +5258,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>InterfaceTreeDelegate</name>
+ <message>
+ <source>default</source>
+ <translation type="unfinished">domyślny</translation>
+ </message>
+</context>
+<context>
<name>InterfaceTreeModel</name>
<message>
<source>Show</source>
@@ -5013,7 +5288,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Local Pipe Path</source>
- <translation type="unfinished"></translation>
+ <translation>Ścieżka lokalnego potoku</translation>
</message>
<message>
<source>Comment</source>
@@ -5053,7 +5328,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Extcap interface: %1</source>
- <translation type="unfinished"></translation>
+ <translation>Interfejs extcap: %1</translation>
</message>
<message>
<source>No addresses</source>
@@ -5968,8 +6243,8 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>LteMacStatisticsDialog</name>
<message>
- <source>LTE Mac Statistics</source>
- <translation>Statystyki LTE Mac</translation>
+ <source>LTE/NR Mac Statistics</source>
+ <translation>Statystyki LTE/NR Mac</translation>
</message>
<message>
<source>Include SR frames in filter</source>
@@ -6074,7 +6349,8 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Switch the direction of the connection (view the opposite flow).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Zmień kierunek przepływu w połączeniu (przepływ w przeciwnym kierunku).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Zmień kierunek przepływu w połączeni (przepływ przeciwny).
+&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<source>Switch Direction</source>
@@ -6273,12 +6549,12 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Numer sekwencyjny</translation>
</message>
<message>
- <source>LTE RLC Graph (UE=%1 chan=%2%3 %4 - %5)</source>
- <translation>Wykres LTE RLC (UE=%1 kanał=%2%3 %4 - %5)</translation>
+ <source>%1 RLC Graph (UE=%2 chan=%3%4 %5 - %6)</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>LTE RLC Graph - no channel selected</source>
- <translation>Wykres LTE RLC - brak wybranego kanału</translation>
+ <source>3GPP RLC Graph - no channel selected</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Save As…</source>
@@ -6332,8 +6608,8 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>LteRlcStatisticsDialog</name>
<message>
- <source>LTE RLC Statistics</source>
- <translation>Statystyki LTE RLC</translation>
+ <source>3GPP RLC Statistics</source>
+ <translation>Statystyki 3GPP RLC</translation>
</message>
<message>
<source>Include SR frames in filter</source>
@@ -6419,6 +6695,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Profil: %1</translation>
</message>
<message>
+ <source> %1 Displayed: %2 (%3%)</source>
+ <translation> %1 Wyświetlanych: %2 (%3%)</translation>
+ </message>
+ <message>
<source>Manage Profiles…</source>
<translation>Zarządzaj profilami...</translation>
</message>
@@ -6475,10 +6755,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<message numerus="yes">
<source>%Ln byte(s)</source>
<oldsource>, %1 bytes</oldsource>
- <translation>
- <numerusform>%Ln bajt</numerusform>
- <numerusform>%Ln bajty</numerusform>
- <numerusform>%Ln bajtów</numerusform>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln bit(s)</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message>
@@ -6494,9 +6782,12 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Wybrany pakiet: %1 %2</translation>
</message>
<message>
- <source>Packets: %1 %4 Displayed: %2 (%3%)</source>
- <oldsource>Packets: %1 %4 Displayed: %2 %4 Marked: %3</oldsource>
- <translation>Pakietów: %1 %4 Wyświetlanych: %2 (%3%)</translation>
+ <source>Selected Event: %1 %2 </source>
+ <translation>Wybrane zdarzenie: %1 %2</translation>
+ </message>
+ <message>
+ <source>Events: %1</source>
+ <translation>Zdarzenie: %1</translation>
</message>
<message>
<source> %1 Selected: %2 (%3%)</source>
@@ -6528,6 +6819,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Brak pakietów</translation>
</message>
<message>
+ <source>No Events</source>
+ <translation>Brak zdarzeń</translation>
+ </message>
+ <message>
<source>From Zip File...</source>
<translation>Z pliku ZIP....</translation>
</message>
@@ -6561,6 +6856,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>MainWindow</name>
+ <message>
+ <source>Display filter as %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>MainWindowPreferencesFrame</name>
<message>
<source>Frame</source>
@@ -6592,6 +6894,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Ostanio użyty folder</translation>
</message>
<message>
+ <source>The current working directory</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Show up to</source>
<translation>Pokazuj aż do</translation>
</message>
@@ -6676,19 +6982,19 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Add a pipe to capture from or remove an existing pipe from the list.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Dodaj lub usuń rurę z listy.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Dodaj lub usuń potok z listy.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<source>Pipes</source>
- <translation>Rury</translation>
+ <translation>Potoki</translation>
</message>
<message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Add a new pipe using default settings.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Dodaj nową rurę używając domyślnych ustawień.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Dodaj nowy potok używając domyślnych ustawień.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Remove the selected pipe from the list.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usuń wybraną rurę z listy.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usuń wybrany potok z listy.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<source>Remote Interfaces</source>
@@ -6716,7 +7022,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>This version of Wireshark does not save pipe settings.</source>
- <translation>Ta wersja Wiresharka nie obsługuje ustawień rur.</translation>
+ <translation>Ta wersja programu Wireshark nie obsługuje ustawień potoków.</translation>
</message>
<message>
<source>This version of Wireshark does not save remote settings.</source>
@@ -6728,7 +7034,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>New Pipe</source>
- <translation>Nowa rura</translation>
+ <translation>Nowy potok</translation>
</message>
</context>
<context>
@@ -6786,7 +7092,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Short Name</source>
- <translation>Krótka Nazwa</translation>
+ <translation>Krótka nazwa</translation>
</message>
<message>
<source>Vendor Name</source>
@@ -7022,6 +7328,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Pokaż wartości pól</translation>
</message>
<message>
+ <source>Refresh</source>
+ <translation type="unfinished">Odśwież</translation>
+ </message>
+ <message>
<source>Save Diagram As…</source>
<translation>Zapisz diagram jako…</translation>
</message>
@@ -7069,6 +7379,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Pokaż bajty pakietu</translation>
</message>
<message>
+ <source>Layout:</source>
+ <translation>Wygląd:</translation>
+ </message>
+ <message>
<source>Packet %1</source>
<translation>Pakiet %1</translation>
</message>
@@ -7086,10 +7400,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message numerus="yes">
<source>%Ln byte(s)</source>
- <translation>
- <numerusform>%Ln bajt</numerusform>
- <numerusform>%Ln bajty</numerusform>
- <numerusform>%Ln bajtów</numerusform>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln bit(s)</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
</translation>
</message>
</context>
@@ -7323,7 +7645,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<name>PathSelectionDelegate</name>
<message>
<source>Open a pipe</source>
- <translation type="unfinished"></translation>
+ <translation>Otwórz potok</translation>
</message>
</context>
<context>
@@ -7512,7 +7834,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>&amp;Print…</source>
- <translation>&amp;Drukuj…</translation>
+ <translation>&amp;Drukuj...</translation>
</message>
<message>
<source>Page &amp;Setup…</source>
@@ -7550,10 +7872,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Kopiuj ten profil.</translation>
</message>
<message>
+ <source>The number of packets or events to check for automatic profile switching.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Auto switch packet limit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Configuration Profiles</source>
<translation>Konfiguracja profili</translation>
</message>
<message>
+ <source>Auto switch event limit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Import</source>
<comment>noun</comment>
<translation>Importuj</translation>
@@ -7573,10 +7907,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message numerus="yes">
<source>%Ln Selected Personal Profile(s)...</source>
- <translation>
- <numerusform>%Ln wybrany profil osobisty...</numerusform>
- <numerusform>%Ln wybrane profile osobiste...</numerusform>
- <numerusform>%Ln wybranych profili osobistych...</numerusform>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message>
@@ -7603,29 +7937,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Select zip file for export</source>
<translation>Wybierz plik ZIP do wyeksportowania</translation>
</message>
- <message numerus="yes">
- <source>… %Ln selected personal profile(s)</source>
- <translation type="vanished">
- <numerusform>... %Ln wybrany profil osobisty</numerusform>
- <numerusform>... %Ln wybrane profile osobiste</numerusform>
- <numerusform>... %Ln wybranych profili osobistych</numerusform>
- </translation>
- </message>
- <message numerus="yes">
- <source>%Ln selected personal profile(s)</source>
- <translation type="vanished">
- <numerusform>%Ln wybrany profil osobisty</numerusform>
- <numerusform>%Ln wybrane profile osobiste</numerusform>
- <numerusform>%Ln wybranych profili osobistych</numerusform>
- </translation>
- </message>
<message>
<source>An import of profiles is not allowed, while changes are pending</source>
<translation>Import profili nie jest dozwolony, dopóki oczekujące zmiany nie zostaną wprowadzone</translation>
</message>
<message>
<source>An import is pending to be saved. Additional imports are not allowed</source>
- <translation>Import oczekuje na zapisanie. Kolejny import nie jest dozwolony</translation>
+ <translation>Import oczekuje na zapisanie. Dodatkowy import nie jest dozwolony</translation>
</message>
<message>
<source>An export of profiles is only allowed for personal profiles</source>
@@ -7637,10 +7955,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message numerus="yes">
<source>%Ln profile(s) exported</source>
- <translation>
- <numerusform>%Ln profil wyeksportowany</numerusform>
- <numerusform>%Ln profile wyeksportowane</numerusform>
- <numerusform>%Ln profili wyeksportowanych</numerusform>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message>
@@ -7669,18 +7987,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message numerus="yes">
<source>%Ln profile(s) imported</source>
- <translation>
- <numerusform>%Ln profil zaimportowany</numerusform>
- <numerusform>%Ln profile zaimportowane</numerusform>
- <numerusform>%Ln profili zaimportowanych</numerusform>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
<source>, %Ln profile(s) skipped</source>
- <translation>
- <numerusform>, %Ln profil pominięto</numerusform>
- <numerusform>, %Ln profile pominięto</numerusform>
- <numerusform>, %Ln profili pominięto</numerusform>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message>
@@ -7743,6 +8061,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>usunięte</translation>
</message>
<message>
+ <source>Auto Switch Filter</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>copy</source>
<comment>noun</comment>
<translation>kopiuj</translation>
@@ -7785,7 +8107,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Renamed from: %1</source>
- <translation>Przemianowano z %1</translation>
+ <translation>Przemianowano z: %1</translation>
</message>
<message>
<source>Copied from: %1</source>
@@ -7894,7 +8216,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Filter Field Reference</source>
- <translation>Odwołania filtru pola</translation>
+ <translation type="unfinished">Odwołania filtru pola</translation>
</message>
<message>
<source>Copied </source>
@@ -8102,6 +8424,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Rozmiar okna (B)</translation>
</message>
<message>
+ <source>Unacked (Outstanding) Bytes (B)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>[no capture file]</source>
<translation>[nie załadowano pliku przechytywania]</translation>
</message>
@@ -8123,7 +8449,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Prepare as Filter</source>
- <translation>Przygotuj jako filtr</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Find</source>
@@ -8262,6 +8588,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Brakujący znacznik?</translation>
</message>
<message>
+ <source>LTE</source>
+ <translation>LTE</translation>
+ </message>
+ <message>
+ <source>NR</source>
+ <translation>NR</translation>
+ </message>
+ <message>
<source>C-RNTI</source>
<translation>C-RNTI</translation>
</message>
@@ -8282,6 +8616,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>UEId</translation>
</message>
<message>
+ <source>RAT</source>
+ <translation>RAT</translation>
+ </message>
+ <message>
<source>UL Frames</source>
<translation>Ramki UL</translation>
</message>
@@ -8505,9 +8843,69 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Browse…</source>
<translation>Przeglądaj…</translation>
</message>
+ <message>
+ <source>PACKETS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>EVENTS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>BYTES</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>BITS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>COUNT FRAMES</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>COUNT FIELDS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>SUM</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>MAX</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>MIN</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>AVERAGE</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>THROUGHPUT</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>LOAD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Left</source>
+ <translation type="unfinished">W lewo</translation>
+ </message>
+ <message>
+ <source>Center</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Right</source>
+ <translation type="unfinished">W prawo</translation>
+ </message>
</context>
<context>
- <name>QObject::QObject</name>
+ <name>QObject::QObject::QObject</name>
<message>
<source>CCCH</source>
<translation>CCCH</translation>
@@ -8608,6 +9006,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>ResizeHeaderView</name>
+ <message>
+ <source>Resize all %1 to contents</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>ResolvedAddressesDialog</name>
<message>
<source>Dialog</source>
@@ -8723,6 +9128,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Rozwiązane Adresy</translation>
</message>
<message>
+ <source>Copy</source>
+ <translation>Kopiuj</translation>
+ </message>
+ <message>
+ <source>Save as…</source>
+ <translation>Zapisz jako…</translation>
+ </message>
+ <message>
<source># Resolved addresses found in %1</source>
<translation># Rozwiązane adresy znalezione w %1</translation>
</message>
@@ -8736,6 +9149,61 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>ResolvedAddressesView</name>
+ <message>
+ <source>as Plain Text</source>
+ <translation>jako zwykły tekst</translation>
+ </message>
+ <message>
+ <source>Copy selected rows</source>
+ <translation>Skopiuj wybrane wiersze</translation>
+ </message>
+ <message>
+ <source>Copy table</source>
+ <translation>Skopiuj tabelę</translation>
+ </message>
+ <message>
+ <source>as CSV</source>
+ <translation>jako CSV</translation>
+ </message>
+ <message>
+ <source>as JSON</source>
+ <translation>jako JSON</translation>
+ </message>
+ <message>
+ <source>Save selected rows as…</source>
+ <translation>Zapisz wybrane wiersze jako…</translation>
+ </message>
+ <message>
+ <source>Save table as…</source>
+ <translation>Zapisz tabelę jako…</translation>
+ </message>
+ <message>
+ <source>Save Resolved Addresses As…</source>
+ <translation>Zapisz rozwiązane adresy jako…</translation>
+ </message>
+ <message>
+ <source>Plain text (*.txt)</source>
+ <translation>Zwykły tekst (*.txt)</translation>
+ </message>
+ <message>
+ <source>CSV Document (*.csv)</source>
+ <translation>Dokument CSV (*.csv)</translation>
+ </message>
+ <message>
+ <source>JSON Document (*.json)</source>
+ <translation>Dokument JSON (*.json)</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Ostrzeżenie</translation>
+ </message>
+ <message>
+ <source>Unable to save %1: %2</source>
+ <translation>Nie można zapisać %1: %2</translation>
+ </message>
+</context>
+<context>
<name>ResponseTimeDelayDialog</name>
<message>
<source>%1 Response Time Delay Statistics</source>
@@ -8957,7 +9425,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source> %1 streams, </source>
- <translation>%1 strumieni,</translation>
+ <translation>%1 strumieni.</translation>
</message>
<message>
<source>Save one stream CSV</source>
@@ -9073,15 +9541,15 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Prepare &amp;Filter</source>
- <translation>Przygotuj &amp;filtr</translation>
+ <translation>Przygotuj filtr</translation>
</message>
<message>
<source>Prepare a filter matching the selected stream(s).</source>
- <translation>Przygotuj filtr pasujący do wybranego(ych) strumieni.</translation>
+ <translation type="unfinished">Przygotuj filtr dla zaznaczonych strumieni.</translation>
</message>
<message>
<source>&amp;Current Tab</source>
- <translation>&amp;Bieżąca karta</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Prepare a filter matching current tab.</source>
@@ -9356,7 +9824,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Remove Streams</source>
- <translation>Usuń strumienie</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Remove selected streams from the list</source>
@@ -9432,15 +9900,15 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Prepare &amp;Filter</source>
- <translation>Przygotuj &amp;filtr</translation>
+ <translation type="unfinished">Przygotuj filtr</translation>
</message>
<message>
<source>Prepare a filter matching the selected stream(s).</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Przygotuj filtr dla zaznaczonych strumieni.</translation>
</message>
<message>
<source>R&amp;efresh streams</source>
- <translation>&amp;Odśwież strumienie</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Read captured packets from capture in progress to player</source>
@@ -9496,7 +9964,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Play the stream</source>
- <translation type="unfinished"></translation>
+ <translation>Odtwórz strumień</translation>
</message>
<message>
<source>To Left</source>
@@ -9528,7 +9996,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>&amp;Play Streams</source>
- <translation>&amp;Odtwarzaj strumienie</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Open RTP player dialog</source>
@@ -9560,7 +10028,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>No Audio</source>
- <translation>Brak audio</translation>
+ <translation>Brak Audio</translation>
</message>
<message>
<source>Decoding streams...</source>
@@ -9608,7 +10076,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Playback of stream %1 failed!</source>
- <translation>Odtwarzanie strumienia %1 nie powiodło się!</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Automatic</source>
@@ -9767,7 +10235,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Prepare &amp;Filter</source>
- <translation type="unfinished">Przygotuj &amp;filtr</translation>
+ <translation type="unfinished">Przygotuj filtr</translation>
</message>
<message>
<source>&amp;Export</source>
@@ -9947,7 +10415,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Save RTPDump As…</source>
- <translation type="unfinished"></translation>
+ <translation>Zapisz RTPDump jako</translation>
</message>
</context>
<context>
@@ -10410,6 +10878,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Bajty pakietu</translation>
</message>
<message>
+ <source>&lt;b&gt;Options:&lt;/b&gt;</source>
+ <translation>&lt;b&gt;Opcje:&lt;/b&gt;</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for strings containing narrow (UTF-8 and ASCII) or wide (UTF-16) characters.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Szukaj ciągu znaków w kodowanie wąskim (UTF-8 i ASCII) lub szerokim (UTF-16).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -10430,6 +10902,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Rozróżniaj wielkość znaków</translation>
</message>
<message>
+ <source>Backwards</source>
+ <translation>Wstecz</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for a subsequent occurrence in the current packet before advancing to the next packet.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Multiple occurrences</source>
+ <translation>Wiele wystąpień</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5), a plain string (e.g. My String) or a regular expression (e.g. colou?r).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<oldsource>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5) or a plain string (e.g. My String).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</oldsource>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Szukaj używając składni filtru wyświetlania (np. ip.addr==10.1.1.1), szesnastkowo (np. fffffda5), ciągu znaków (np. &quot;My String&quot;) lub wyrażenia regularnego (np. colou?r).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
@@ -10467,6 +10951,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Błędny filtr.</translation>
</message>
<message>
+ <source>Event List</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Event Details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Event Bytes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search the Info column of the event list (summary pane), decoded event display labels (tree view pane) or the ASCII-converted event data (hex view pane).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>That filter doesn&apos;t test anything.</source>
<translation>Ten filtr nie sprawdza niczego.</translation>
</message>
@@ -10531,18 +11031,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message numerus="yes">
<source>%Ln node(s)</source>
- <translation>
- <numerusform>%Ln węzeł</numerusform>
- <numerusform>%Ln węzły</numerusform>
- <numerusform>%Ln węzłów</numerusform>
+ <translation type="unfinished">
+ <numerusform>%Ln node</numerusform>
+ <numerusform>%Ln nodes</numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message numerus="yes">
<source>%Ln item(s)</source>
- <translation>
- <numerusform>%Ln obiekt</numerusform>
- <numerusform>%Ln obiekty</numerusform>
- <numerusform>%Ln obiektów</numerusform>
+ <translation type="unfinished">
+ <numerusform>%Ln item</numerusform>
+ <numerusform>%Ln items</numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message>
@@ -10912,15 +11412,19 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Znajdź:</translation>
</message>
<message>
+ <source>Case sensitive</source>
+ <translation>Rozróżniaj wielkość znaków</translation>
+ </message>
+ <message>
<source>Find &amp;Next</source>
<translation>Znajdź &amp;następny</translation>
</message>
<message numerus="yes">
<source>Frame %1, %2, %Ln byte(s).</source>
- <translation>
- <numerusform>Ramka %1, %2, %Ln bajt.</numerusform>
- <numerusform>Ramka %1, %2, %Ln bajty.</numerusform>
- <numerusform>Ramka %1, %2, %Ln bajtów.</numerusform>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message>
@@ -11008,15 +11512,23 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Zapisz jako…</translation>
</message>
<message>
+ <source>Decoded as %1.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Save Selected Packet Bytes As…</source>
<translation>Zapisz zaznaczone bajty pakietu jako</translation>
</message>
+ <message>
+ <source>compressed %1</source>
+ <translation type="unfinished"></translation>
+ </message>
<message numerus="yes">
- <source>Displaying %Ln byte(s).</source>
- <translation>
- <numerusform>Wyświetlanych %Ln bajt.</numerusform>
- <numerusform>Wyświetlane bajty: %Ln.</numerusform>
- <numerusform>Wyświetlanych bajtów: %Ln.</numerusform>
+ <source>Using %Ln byte(s).</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message>
@@ -11116,6 +11628,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Display filter:</source>
<translation>Filtr wyświetlania:</translation>
</message>
+ <message>
+ <source>Strip Headers</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>SupportedProtocolsDialog</name>
@@ -11171,7 +11687,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>&quot;%1&quot; is deprecated in favour of &quot;%2&quot;. See Help section 6.4.8 for details.</source>
- <translation>&quot;%1&quot; jest przestarzałe na rzecz &quot;%2&quot;.. Aby uzyskać szczegółowe informacje, zobacz sekcję Pomocy 6.4.8.</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>%1</source>
@@ -12016,7 +12532,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Copy all values of this page to the clipboard in CSV (Comma Separated Values) format.</source>
- <translation>Kopiuj wszystkie wartości z tej strony w CSV (Comma Separated Values) do schowka.</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>as YAML</source>
@@ -12024,7 +12540,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Copy all values of this page to the clipboard in the YAML data serialization format.</source>
- <translation>Kopiuj wszystkie wartości z tej strony w formacie YAML do schowka.</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>as JSON</source>
@@ -12032,7 +12548,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Copy all values of this page to the clipboard in the JSON data serialization format.</source>
- <translation>Kopiuj wszystkie wartości z tej strony w formacie JSON do schowka.</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Save data as raw</source>
@@ -12084,22 +12600,20 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Stwórz nowy wpis.</translation>
</message>
<message>
- <source>Remove this entry.</source>
- <oldsource>Remove this profile.</oldsource>
- <translation>Usuń wpis.</translation>
+ <source>Remove the selected entry(ies).</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Copy this entry.</source>
- <oldsource>Copy this profile.</oldsource>
- <translation>Kopiuj wpis.</translation>
+ <source>Copy the selected entry(ies).</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry up.</source>
- <translation>Przesuń wpis w górę.</translation>
+ <source>Move the selected entry(ies) up.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry down.</source>
- <translation>Przesuń wpis w dół.</translation>
+ <source>Move the selected entry(ies) down.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Clear all entries.</source>
@@ -12125,20 +12639,20 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Stwórz nowy wpis.</translation>
</message>
<message>
- <source>Remove this entry.</source>
- <translation>Usuń wpis.</translation>
+ <source>Remove the selected entry(ies).</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Copy this entry.</source>
- <translation>Kopiuj wpis.</translation>
+ <source>Copy the selected entry(ies).</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry up.</source>
- <translation>Przesuń wpis w górę.</translation>
+ <source>Move the selected entry(ies) up.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry down.</source>
- <translation>Przesuń wpis w dół.</translation>
+ <source>Move the selected entry(ies) down.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Clear all entries.</source>
@@ -12189,7 +12703,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Prepare &amp;Filter</source>
- <translation>Przygotuj &amp;filtr</translation>
+ <translation type="unfinished">Przygotuj filtr</translation>
</message>
<message>
<source>Prepare a filter matching the selected calls(s).</source>
@@ -12285,7 +12799,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Select</source>
- <translation>&amp;Wybrane</translation>
+ <translation>Wybrane</translation>
</message>
</context>
<context>
@@ -12499,10 +13013,10 @@ a:hover {
</message>
<message numerus="yes">
<source>%n interface(s) shown, %1 hidden</source>
- <translation>
- <numerusform>%n wyświetlany interfejs, %1 ukrytych</numerusform>
- <numerusform>%n wyświetlane interfejsy, %1 ukrytych</numerusform>
- <numerusform>%n wyświetlanych interfejsów, %1 ukrytych</numerusform>
+ <translation type="unfinished">
+ <numerusform>%n interface shown, %1 hidden</numerusform>
+ <numerusform>%n interfaces shown, %1 hidden</numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message>
@@ -12510,10 +13024,18 @@ a:hover {
<translation>Dzięki Wiresharkowi podglądasz fundamenty współczesnego Internetu.</translation>
</message>
<message>
+ <source>You are sniffing the glue that holds your system together using Logray </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>You are running Wireshark </source>
<translation>Używasz Wireshark </translation>
</message>
<message>
+ <source>You are running Logray </source>
+ <translation>Logray uruchomiony</translation>
+ </message>
+ <message>
<source> You receive automatic updates.</source>
<translation> Automatyczne aktualizacje są włączone.</translation>
</message>
@@ -12671,7 +13193,7 @@ a:hover {
</message>
<message>
<source>Prepare as Filter</source>
- <translation>Przygotuj jako filtr</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>SCTP</source>
@@ -12711,7 +13233,7 @@ a:hover {
</message>
<message>
<source>&amp;Analyze</source>
- <translation>&amp;Analiza</translation>
+ <translation>Analizuj</translation>
</message>
<message>
<source>Follow</source>
@@ -12790,20 +13312,12 @@ a:hover {
<translation>Nie znaleziono pliku</translation>
</message>
<message>
- <source>&amp;Contents</source>
- <translation>Podrę&amp;cznik</translation>
- </message>
- <message>
- <source>Wireshark Filter</source>
- <translation>Filtr</translation>
- </message>
- <message>
<source>TShark</source>
<translation>TShark</translation>
</message>
<message>
<source>Rawshark</source>
- <translation>RawShark</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Dumpcap</source>
@@ -13047,7 +13561,7 @@ a:hover {
</message>
<message>
<source>&amp;DTN</source>
- <translation>&amp;DTN</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Osmux</source>
@@ -13063,10 +13577,6 @@ a:hover {
<translation>Pasek sniffera WiFi</translation>
</message>
<message>
- <source>Help contents</source>
- <translation>Pomoc</translation>
- </message>
- <message>
<source>FAQs</source>
<translation>FAQ</translation>
</message>
@@ -13187,11 +13697,6 @@ a:hover {
<translation>Znajdź poprzedni pakiet</translation>
</message>
<message>
- <source>&amp;Mark/Unmark Packet(s)</source>
- <oldsource>&amp;Mark/Unmark Packet</oldsource>
- <translation>&amp;Zaznacz/odznacz pakiet</translation>
- </message>
- <message>
<source>Mark All Displayed</source>
<translation>Zaznacz wszystkie wyświetlane</translation>
</message>
@@ -13220,11 +13725,6 @@ a:hover {
<translation>Idź do poprzedniego zaznaczonego pakietu</translation>
</message>
<message>
- <source>&amp;Ignore/Unignore Packet(s)</source>
- <oldsource>&amp;Ignore/Unignore Packet</oldsource>
- <translation>&amp;Ignoruj/odignoruj pakiet</translation>
- </message>
- <message>
<source>Ignore All Displayed</source>
<translation>Ignoruj wszystkie wyświetlane</translation>
</message>
@@ -13530,7 +14030,7 @@ a:hover {
</message>
<message>
<source>Osmux packet counts</source>
- <translation>Liczba pakietów Osmux</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>RTSP packet counts</source>
@@ -13642,7 +14142,7 @@ a:hover {
</message>
<message>
<source>&amp;I/O Graphs</source>
- <translation>&amp;Wykresy wej./wyj.</translation>
+ <translation>&amp;Wykresy we./wy.</translation>
</message>
<message>
<source>&amp;Conversations</source>
@@ -13662,11 +14162,7 @@ a:hover {
</message>
<message>
<source>Reset Layout</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Reset appearance layout to default size</source>
- <translation>Resetuje układ do rozmiarów domyślnych</translation>
+ <translation>Resetuj wygląd</translation>
</message>
<message>
<source>Seconds Since First Captured Packet</source>
@@ -13754,7 +14250,7 @@ a:hover {
</message>
<message>
<source>Display Filter Expression…</source>
- <translation>Wyrażenie filtru wyświetlania...</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>REGISTER_STAT_GROUP_RSERPOOL</source>
@@ -13829,20 +14325,28 @@ a:hover {
<translation>Bloki adresów MAC</translation>
</message>
<message>
- <source>TLS Keylog Launcher</source>
+ <source>&amp;Options…</source>
+ <translation>&amp;Opcje…</translation>
+ </message>
+ <message>
+ <source>&amp;3GPP Uu</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Release Notes</source>
- <translation>Informacje o wydaniu</translation>
+ <source>&amp;Wireless</source>
+ <translation>Bezprze&amp;wodowe</translation>
</message>
<message>
- <source>&amp;Options…</source>
- <translation>&amp;Opcje…</translation>
+ <source>&amp;User&apos;s Guide</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Wireless</source>
- <translation>Bezprze&amp;wodowe</translation>
+ <source>Wireshark User&apos;s Guide</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Display Filters</source>
+ <translation>Filtry wyświetlania</translation>
</message>
<message>
<source>Capture &amp;Filters…</source>
@@ -13889,10 +14393,18 @@ a:hover {
<translation>Znajdź poprzedni…</translation>
</message>
<message>
+ <source>&amp;Mark/Unmark Selected</source>
+ <translation>&amp;Zaznacz/Odznacz wybrane</translation>
+ </message>
+ <message>
<source>Mark or unmark each selected packet</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <source>&amp;Ignore/Unignore Selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Ignore or unignore each selected packet</source>
<translation type="unfinished"></translation>
</message>
@@ -13933,6 +14445,18 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
+ <source>General</source>
+ <translation>Ogólne</translation>
+ </message>
+ <message>
+ <source>Query-Response</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>DNS Query-Response Statistics</source>
+ <translation>Statystyki odpowiedzi na zapytania DNS</translation>
+ </message>
+ <message>
<source>Request Sequences</source>
<translation type="unfinished"></translation>
</message>
@@ -13941,6 +14465,14 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
+ <source>E2AP</source>
+ <translation>E2AP</translation>
+ </message>
+ <message>
+ <source>E2AP Messages</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Decode &amp;As…</source>
<translation>Dekoduj jako…</translation>
</message>
@@ -14001,6 +14533,10 @@ a:hover {
<translation>Normalny rozmiar</translation>
</message>
<message>
+ <source>Reset layout to default size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Resize Columns</source>
<translation>Zmień rozmiar kolumn</translation>
</message>
@@ -14223,7 +14759,7 @@ a:hover {
</message>
<message>
<source>RTP Player</source>
- <translation>Odtwarzacz RTP</translation>
+ <translation type="unfinished">Odtwarzacz RTP</translation>
</message>
<message>
<source>Play selected stream. Press CTRL key for playing reverse stream too.</source>
@@ -14259,6 +14795,14 @@ a:hover {
<translation>Idź do pakietu do którego odwołuje się zaznaczone pole.</translation>
</message>
<message>
+ <source>TLS Keylog Launcher</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Release Notes</source>
+ <translation>Informacje o wydaniu</translation>
+ </message>
+ <message>
<source>&amp;VoIP Calls</source>
<translation>Połączenia VoIP</translation>
</message>
@@ -14291,10 +14835,6 @@ a:hover {
<translation>&amp;GSM</translation>
</message>
<message>
- <source>&amp;LTE</source>
- <translation>&amp;LTE</translation>
- </message>
- <message>
<source>&amp;MTP3</source>
<translation>&amp;MTP3</translation>
</message>
@@ -14538,11 +15078,11 @@ a:hover {
</message>
<message>
<source>Unable to drop files during capture.</source>
- <translation>Nie można porzucić pliku podczas przechwytywania.</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Unknown file type returned by merge dialog.</source>
- <translation>Nieznany typ pliku zwrócony przez okno dialogowe łączenia plików.</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Please report this as a Wireshark issue at https://gitlab.com/wireshark/wireshark/-/issues.</source>
@@ -14550,7 +15090,7 @@ a:hover {
</message>
<message>
<source>Unknown file type returned by export dialog.</source>
- <translation>Nieznany typ pliku zwrócony przez okno dialogowe eksportu.</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Do you want to stop the capture and save the captured packets%1?</source>
@@ -14579,8 +15119,12 @@ a:hover {
<translation>Wyjdź bez zapisy&amp;wania</translation>
</message>
<message>
+ <source>USB CDC Data</source>
+ <translation>Dane USB CDC</translation>
+ </message>
+ <message>
<source>There is no &quot;rtp.ssrc&quot; field in this version of Wireshark.</source>
- <translation>Brak pola &quot;rtp.ssrc&quot; w tej wersji programu Wireshark.</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Please select an RTPv2 packet with an SSRC value</source>
@@ -14640,15 +15184,6 @@ a:hover {
<source>No Keys</source>
<translation>Brak kluczy</translation>
</message>
- <message numerus="yes">
- <source>Export SSL Session Keys (%Ln key(s))</source>
- <oldsource>Export SSL Session Keys (%1 key%2</oldsource>
- <translation type="vanished">
- <numerusform>Eksportuj klucze sesji SSL (%Ln klucz)</numerusform>
- <numerusform>Eksportuj klucze sesji SSL (%Ln klucze)</numerusform>
- <numerusform>Eksportuj klucze sesji SSL (%Ln kluczy)</numerusform>
- </translation>
- </message>
<message>
<source>Raw data (*.bin *.dat *.raw);;All Files (</source>
<translation>Surowe dane (*.bin *.dat *.raw);;Dowolny plik (</translation>
@@ -14679,7 +15214,7 @@ a:hover {
</message>
<message>
<source>No interface selected.</source>
- <translation>Nie wybrano interfejsu.</translation>
+ <translation>Nie wybrano interfejsu</translation>
</message>
<message>
<source>Saving %1…</source>
@@ -14718,10 +15253,10 @@ a:hover {
</message>
<message numerus="yes">
<source>Delete comments from %n packet(s)</source>
- <translation>
- <numerusform>Usuń komentarze z %n pakietu</numerusform>
- <numerusform>Usuń komentarze z %n pakietów</numerusform>
- <numerusform>Usuń komentarze z %n pakietów</numerusform>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message>
@@ -14742,14 +15277,14 @@ a:hover {
</message>
<message>
<source>There are no TLS Session Keys to save.</source>
- <translation>Nie ma żadnych kluczy sesji SSL do zapisu.</translation>
+ <translation>Nie ma żadnych kluczy sesji TLS do zapisu.</translation>
</message>
<message numerus="yes">
<source>Export TLS Session Keys (%Ln key(s))</source>
- <translation>
- <numerusform>Eksportuj klucze sesji TLS (%Ln klucz)</numerusform>
- <numerusform>Eksportuj klucze sesji TLS (%Ln klucze)</numerusform>
- <numerusform>Eksportuj klucze sesji TLS (%Ln kluczy)</numerusform>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message>
@@ -14794,7 +15329,7 @@ a:hover {
</message>
<message>
<source>No Interface Selected.</source>
- <translation>Nie wybrano interfejsu.</translation>
+ <translation>Nie wybrano interfejsu</translation>
</message>
<message>
<source> before restarting the capture</source>
diff --git a/ui/qt/wireshark_ru.ts b/ui/qt/wireshark_ru.ts
index 20dc0e3a..2bd5d309 100644
--- a/ui/qt/wireshark_ru.ts
+++ b/ui/qt/wireshark_ru.ts
@@ -44,8 +44,8 @@
<translation>Папки</translation>
</message>
<message>
- <source>Filter by path</source>
- <translation>Фильтр по пути размещения</translation>
+ <source>Search Folders</source>
+ <translation>Поиск папок</translation>
</message>
<message>
<source>Plugins</source>
@@ -80,6 +80,14 @@
<translation>Лицензия</translation>
</message>
<message>
+ <source>About Logray</source>
+ <translation>О Logray</translation>
+ </message>
+ <message>
+ <source>Logray</source>
+ <translation>Журнал</translation>
+ </message>
+ <message>
<source>The directory does not exist</source>
<translation>Каталог отсутствует</translation>
</message>
@@ -109,10 +117,10 @@
</message>
<message numerus="yes">
<source>Copy Row(s)</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>Копировать строку</numerusform>
+ <numerusform>Копировать строки</numerusform>
+ <numerusform>Копировать строки</numerusform>
</translation>
</message>
</context>
@@ -732,11 +740,11 @@
</message>
<message>
<source>…as decimal</source>
- <translation type="unfinished"></translation>
+ <translation>... как десятичный</translation>
</message>
<message>
<source>…as octal</source>
- <translation type="unfinished"></translation>
+ <translation>...как восьмеричный</translation>
</message>
<message>
<source>…as bits</source>
@@ -756,6 +764,28 @@
</message>
</context>
<context>
+ <name>CaptureCommentDialog</name>
+ <message>
+ <source>Edit Capture Comments</source>
+ <translation>Редактирование комментариев к захвату</translation>
+ </message>
+ <message>
+ <source>Add Comment</source>
+ <translation>Добавить комментарий</translation>
+ </message>
+ <message>
+ <source>Section %1</source>
+ <translation>Раздел %1</translation>
+ </message>
+</context>
+<context>
+ <name>CaptureCommentTabWidget</name>
+ <message>
+ <source>Comment %1</source>
+ <translation>Комментарий %1</translation>
+ </message>
+</context>
+<context>
<name>CaptureFile</name>
<message>
<source> [closing]</source>
@@ -812,6 +842,32 @@
<source>Automatically detect file type</source>
<translation>Автоматически определить тип файла</translation>
</message>
+ <message numerus="yes">
+ <source>%1, error after %Ln packet(s)</source>
+ <oldsource>%1, error after %2 packets</oldsource>
+ <translation type="vanished">
+ <numerusform>%1, ошибка после %Ln пакета</numerusform>
+ <numerusform>%1, ошибка после %Ln пакетов</numerusform>
+ <numerusform>%1, ошибка после %Ln пакетов</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1, timed out at %Ln packet(s)</source>
+ <oldsource>%1, timed out at %2 packets</oldsource>
+ <translation type="vanished">
+ <numerusform>%1, таймер прерван на %Ln пакете</numerusform>
+ <numerusform>%1, таймер прерван на %Ln пакетах</numerusform>
+ <numerusform>%1, таймер прерван на %Ln пакетах</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%1, %Ln packet(s)</source>
+ <translation type="vanished">
+ <numerusform>%1, %Ln пакет</numerusform>
+ <numerusform>%1, %Ln пакета</numerusform>
+ <numerusform>%1, %Ln пакетов</numerusform>
+ </translation>
+ </message>
<message>
<source>Prepend packets</source>
<translation>Добавить пакеты к началу файла</translation>
@@ -841,10 +897,6 @@
<translation>Фильтр чтения:</translation>
</message>
<message>
- <source>Compress with g&amp;zip</source>
- <translation>Сжать с помощью g&amp;zip</translation>
- </message>
- <message>
<source>Open Capture File</source>
<oldsource>Wireshark: Open Capture File</oldsource>
<translation>Открытие файла захвата</translation>
@@ -895,26 +947,26 @@
<message numerus="yes">
<source>%1, error after %Ln data record(s)</source>
<oldsource>%1, error after %Ln record(s)</oldsource>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%1, ошибка после %Ln записи данных</numerusform>
+ <numerusform>%1, ошибка после %Ln записей данных</numerusform>
+ <numerusform>%1, ошибка после %Ln записей данных</numerusform>
</translation>
</message>
<message numerus="yes">
<source>%1, timed out at %Ln data record(s)</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%1, таймер прерван на %Ln записи данных</numerusform>
+ <numerusform>%1, таймер прерван на %Ln записи данных</numerusform>
+ <numerusform>%1, таймер прерван на %Ln записях данных</numerusform>
</translation>
</message>
<message numerus="yes">
<source>%1, %Ln data record(s)</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%1, %Ln запись данных</numerusform>
+ <numerusform>%1, %Ln записи данных</numerusform>
+ <numerusform>%1, %Ln записей данных</numerusform>
</translation>
</message>
<message>
@@ -929,8 +981,8 @@
<translation>Подробности</translation>
</message>
<message>
- <source>Capture file comments</source>
- <translation>Комментарии в файле захвата</translation>
+ <source>Edit Comments</source>
+ <translation>Редактировать комментарии</translation>
</message>
<message>
<source>Refresh</source>
@@ -941,10 +993,6 @@
<translation>Копировать в буфер обмена</translation>
</message>
<message>
- <source>Save Comments</source>
- <translation>Сохранить комментарии</translation>
- </message>
- <message>
<source>Capture File Properties</source>
<translation>Свойства файла захвата</translation>
</message>
@@ -993,10 +1041,18 @@
<translation>Первый пакет</translation>
</message>
<message>
+ <source>First event</source>
+ <translation>Первое событие</translation>
+ </message>
+ <message>
<source>Last packet</source>
<translation>Последний пакет</translation>
</message>
<message>
+ <source>Last event</source>
+ <translation>Последнее событие</translation>
+ </message>
+ <message>
<source>Elapsed</source>
<translation>Прошло</translation>
</message>
@@ -1033,6 +1089,10 @@
<translation>Потерянные пакеты</translation>
</message>
<message>
+ <source>Dropped events</source>
+ <translation>Отмененные события</translation>
+ </message>
+ <message>
<source>Capture filter</source>
<translation>Фильтр захвата</translation>
</message>
@@ -1045,6 +1105,10 @@
<translation>Ограничение на размер пакета (snaplen)</translation>
</message>
<message>
+ <source>Event size limit (snaplen)</source>
+ <translation>Ограничение размера события (оснастка)</translation>
+ </message>
+ <message>
<source>none</source>
<translation>нет</translation>
</message>
@@ -1053,6 +1117,26 @@
<translation>%1 Б</translation>
</message>
<message>
+ <source>Comments</source>
+ <translation>Комментарии</translation>
+ </message>
+ <message>
+ <source>Comment %1: </source>
+ <translation>Комментарий %1: </translation>
+ </message>
+ <message>
+ <source>Decryption Secrets</source>
+ <translation>Секреты расшифровки</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Тип</translation>
+ </message>
+ <message>
+ <source>Size</source>
+ <translation>Размер</translation>
+ </message>
+ <message>
<source>Statistics</source>
<translation>Статистика</translation>
</message>
@@ -1077,18 +1161,26 @@
<translation>Пакеты</translation>
</message>
<message>
+ <source>Events</source>
+ <translation>События</translation>
+ </message>
+ <message>
<source>Time span, s</source>
<translation>Временной промежуток, с</translation>
</message>
<message>
<source>Average pps</source>
- <translation>В среднем, пакетов/с </translation>
+ <translation>В среднем, пакетов/с</translation>
</message>
<message>
<source>Average packet size, B</source>
<translation>Средний размер пакета, Б</translation>
</message>
<message>
+ <source>Average event size, B</source>
+ <translation>Средний размер события, B</translation>
+ </message>
+ <message>
<source>Bytes</source>
<translation>Байты</translation>
</message>
@@ -1101,14 +1193,14 @@
<translation>В среднем бит/с</translation>
</message>
<message>
- <source>Section Comment</source>
- <translation>Комментарий к разделу</translation>
- </message>
- <message>
<source>Packet Comments</source>
<translation>Комментарии к пакету</translation>
</message>
<message>
+ <source>Event Comments</source>
+ <translation>Комментарии к событию</translation>
+ </message>
+ <message>
<source>&lt;p&gt;Frame %1: </source>
<translation>&lt;p&gt;Кадр %1: </translation>
</message>
@@ -1120,6 +1212,14 @@
</translation>
</message>
+ <message>
+ <source>Created by Logray %1
+
+</source>
+ <translation>Создано Logray %1
+
+</translation>
+ </message>
</context>
<context>
<name>CaptureFilterCombo</name>
@@ -1347,6 +1447,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
Например, если указать 1 час, то каждый час будет создаваться новый файл.</translation>
</message>
<message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for some more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Обычно беспроводная сетевая карта перехватывает только трафик, отправленный на ее собственный сетевой адрес и с него, а также трафик пользовательских данных&lt;em&gt; с &amp;quot;поддельными&lt;/em&gt;&amp;quot; заголовками Ethernet. Если вы хотите перехватывать весь трафик, который могут &amp;quot;видеть&amp;quot; беспроводные сетевые карты, или вас интересуют пакеты управления или контроля 802.11, или информация радиоуровня, отметьте этот параметр. Доступность режима мониторинга зависит от беспроводной карты и драйвера. Дополнительные сведения о перехвате пакетов в сетях WLAN см. в Wiki.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>Enable monitor mode on all 802.11 interfaces</source>
+ <translation>Включите режим монитора на всех интерфейсах 802.11</translation>
+ </message>
+ <message>
<source>compression</source>
<translation>сжатие</translation>
</message>
@@ -1359,6 +1467,30 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>gzip</translation>
</message>
<message>
+ <source>File infix pattern</source>
+ <translation>Инфиксный шаблон файла</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;In multiple file mode, the date and time and file index number are inserted between filename template and any suffix. Select their order.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;В режиме нескольких файлов дата и время, а также индексный номер файла вставляются между шаблоном имени файла и любым суффиксом. Выберите их порядок.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>YYYYmmDDHHMMSS_NNNNN</source>
+ <translation>YYYYmmDDHHMMSS_NNNNN</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Date and time before the file index number. This causes files to sort in creation time order, and keeps files from the same batch closely ordered.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;p&gt;Дата и время перед индексным номером файла. В результате файлы сортируются в порядке времени создания, а файлы из одной партии располагаются в строгом порядке.&lt;/p&gt;&lt;body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>NNNNN_YYYYmmDDHHMMSS</source>
+ <translation>NNNNN_YYYYmmDDHHMMSS</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;File index number before the date and time. This is the historic Wireshark ordering.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Номер индекса файла перед датой и временем. Это исторический заказ Wireshark.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;After capturing has switched to the next file and the given number of files has exceeded, the oldest file will be removed.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;При переходе записи данных на следующий файл превышение указанного здесь числа файлов приведёт к удалению самого старого из них.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1447,6 +1579,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Останавливать захват после создания указанного числа файлов.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
+ <source>Stop capturing after the specified number of files have been created.</source>
+ <translation>Остановка захвата после создания указанного количества файлов.</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Stop capturing after the specified amount of data has been captured.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Остановить захват при достижении указанного объёма захваченных данных.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1507,8 +1643,8 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Ошибка</translation>
</message>
<message>
- <source>Multiple files: Requested filesize too large. The filesize cannot be greater than 2 GiB.</source>
- <translation>Несколько файлов: Указан слишком большой размер файла. Размер файла не может превышать 2 ГиБ.</translation>
+ <source>Multiple files: Requested filesize too large. The filesize cannot be greater than 2 TB.</source>
+ <translation>Несколько файлов: Запрашиваемый размер файлов слишком велик. Размер файлов не может превышать 2 ТБ.</translation>
</message>
<message>
<source>Multiple files: No capture file name given. You must specify a filename if you want to use multiple files.</source>
@@ -1538,6 +1674,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Захватывать пакеты в смешанном режиме</translation>
</message>
<message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Обычно беспроводная сетевая карта перехватывает только трафик, отправленный на ее собственный сетевой адрес и с него,&lt;em&gt; а также трафик пользовательских данных с &amp;quot;поддельными&lt;/em&gt;&amp;quot; заголовками Ethernet. Если вы хотите перехватывать весь трафик, который могут &amp;quot;видеть&amp;quot; беспроводные сетевые карты, или вас интересуют пакеты управления или контроля 802.11, или информация радиоуровня, отметьте этот параметр. Доступность режима мониторинга зависит от беспроводной карты и драйвера. Дополнительные сведения о перехвате пакетов в сетях WLAN см. в Wiki.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>Capture packets in monitor mode on 802.11 devices</source>
+ <translation>Захват пакетов в режиме монитора на устройствах 802.11</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Capture packets in the next-generation capture file format.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Выполнять захват пакетов в формате файла захвата следующего поколения «pcapng».&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1555,15 +1699,15 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Interval between updates (ms)</source>
- <translation type="unfinished"></translation>
+ <translation>Интервал между обновлениями (мс)</translation>
</message>
<message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;How often the capture notifies the GUI of new packets. Affects how often the GUI updates and the granularity of timers.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Как часто захват уведомляет графический интерфейс о новых пакетах. Влияет на частоту обновления графического интерфейса и гранулярность таймеров.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The interval between new packet updates. Affects how often the GUI updates and the granularity of timers.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;head/&gt;&lt;body&gt;&lt;p&gt;Интервал между новыми обновлениями пакетов. Влияет на частоту обновления графического интерфейса и гранулярность таймеров.&lt;/p&gt;&lt;/body&gt;&lt;html&gt;</translation>
</message>
<message>
<source>Don&apos;t load interfaces on startup</source>
@@ -1657,7 +1801,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Open </source>
- <translation>Открыть</translation>
+ <translation>Открыть </translation>
</message>
<message>
<source>Double click to edit. Drag to move. Rules are processed in order until a match is found.</source>
@@ -1765,6 +1909,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Разрешено</translation>
</message>
<message>
+ <source>Width</source>
+ <translation>Ширина</translation>
+ </message>
+ <message>
+ <source>Alignment</source>
+ <translation>Выравнивание</translation>
+ </message>
+ <message>
<source>&lt;html&gt;Show human-readable strings instead of raw values for fields. Only applicable to custom columns with fields that have value strings.&lt;/html&gt;</source>
<translation>&lt;html&gt;Показывать человекочитаемые строки вместо необработанных значений полей. Может применяться только к дополнительным столбцам с полями, содержащими строки значений.&lt;/html&gt;</translation>
</message>
@@ -1812,6 +1964,25 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>CompressionGroupBox</name>
+ <message>
+ <source>Compression options</source>
+ <translation>Опции сжатия</translation>
+ </message>
+ <message>
+ <source>&amp;Uncompressed</source>
+ <translation>&amp;Не сжатый</translation>
+ </message>
+ <message>
+ <source>Compress with g&amp;zip</source>
+ <translation>Сжатие с помощью g&amp;zip</translation>
+ </message>
+ <message>
+ <source>Compress with &amp;LZ4</source>
+ <translation>Сжатие с помощью &amp;LZ4</translation>
+ </message>
+</context>
+<context>
<name>ConversationDataModel</name>
<message>
<source>Address A</source>
@@ -1878,6 +2049,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Бит/с B </translation>
</message>
<message>
+ <source>Flows</source>
+ <translation>Потоки</translation>
+ </message>
+ <message>
<source>Total Packets</source>
<translation>Всего пакетов</translation>
</message>
@@ -1992,30 +2167,54 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Копировать байты пакета в виде шестнадцатеричного дампа.</translation>
</message>
<message>
- <source>…as Printable Text</source>
- <translation type="unfinished"></translation>
+ <source>…as MIME Data</source>
+ <translation>...как данные MIME</translation>
</message>
<message>
- <source>Copy only the printable text in the packet.</source>
- <translation type="unfinished"></translation>
+ <source>…as C String</source>
+ <translation>...как строка C</translation>
</message>
<message>
- <source>…as MIME Data</source>
- <translation type="unfinished"></translation>
+ <source>Copy packet bytes as printable ASCII characters and escape sequences.</source>
+ <translation>Копирование байтов пакета в виде печатаемых символов ASCII и управляющих последовательностей.</translation>
</message>
<message>
- <source>…as C String</source>
- <translation type="unfinished"></translation>
+ <source>…as Go literal</source>
+ <translation>...как буквальный го</translation>
</message>
<message>
- <source>Copy packet bytes as printable ASCII characters and escape sequences.</source>
- <translation type="unfinished"></translation>
+ <source>Copy packet bytes as Go literal.</source>
+ <translation>Скопируйте байты пакета как литерал Go.</translation>
+ </message>
+ <message>
+ <source>…as C Array</source>
+ <translation>...как массив C</translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as C Array.</source>
+ <translation>Скопируйте байты пакета в массив C.</translation>
</message>
<message>
<source>…as a Hex Stream</source>
<translation>…в виде шестнадцатеричного потока</translation>
</message>
<message>
+ <source>…as UTF-8 Text</source>
+ <translation>...как текст UTF-8</translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as text, treating as UTF-8.</source>
+ <translation>Копирование байтов пакета в виде текста с обработкой в формате UTF-8.</translation>
+ </message>
+ <message>
+ <source>…as ASCII Text</source>
+ <translation>... как текст ASCII</translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as text, treating as ASCII.</source>
+ <translation>Копирование байтов пакета в виде текста с обработкой в формате ASCII.</translation>
+ </message>
+ <message>
<source>Copy packet bytes as a stream of hex.</source>
<translation>Копировать байты пакета в виде шестнадцатеричного потока.</translation>
</message>
@@ -2056,7 +2255,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Open </source>
- <translation>Открыть</translation>
+ <translation>Открыть </translation>
</message>
</context>
<context>
@@ -2295,11 +2494,11 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<name>DissectorSyntaxLineEdit</name>
<message>
<source>Dissector entry</source>
- <translation type="unfinished"></translation>
+ <translation>Вход в диссектор</translation>
</message>
<message>
<source>Enter a dissector %1</source>
- <translation type="unfinished"></translation>
+ <translation>Введите рассекатель %1</translation>
</message>
</context>
<context>
@@ -2811,6 +3010,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Display filter:</source>
<translation>Фильтр отображения:</translation>
</message>
+ <message>
+ <source>Export PDUs</source>
+ <translation>Экспорт PDU</translation>
+ </message>
</context>
<context>
<name>ExtArgSelector</name>
@@ -2850,10 +3053,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Старт</translation>
</message>
<message>
- <source>Save</source>
- <translation>Сохранить</translation>
- </message>
- <message>
<source>Default</source>
<translation>По умолчанию</translation>
</message>
@@ -2910,10 +3109,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<message numerus="yes">
<source>%Ln File(s) in Set</source>
<oldsource>%1 File%2 in Set</oldsource>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%Ln Файл в Наборе</numerusform>
+ <numerusform>%Ln Файла в Наборе</numerusform>
+ <numerusform>%Ln Файлов в Наборе</numerusform>
</translation>
</message>
</context>
@@ -2996,8 +3195,16 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Фильтры отображения</translation>
</message>
<message>
+ <source>Display Filter Macros</source>
+ <translation>Макросы фильтров отображения</translation>
+ </message>
+ <message>
+ <source>New macro</source>
+ <translation>Новый макрос</translation>
+ </message>
+ <message>
<source>Open </source>
- <translation>Открыть</translation>
+ <translation>Открыть </translation>
</message>
<message>
<source>New capture filter</source>
@@ -3079,10 +3286,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>FilterListModel</name>
<message>
+ <source>Macro Name</source>
+ <translation>Название макроса</translation>
+ </message>
+ <message>
<source>Filter Name</source>
<translation>Имя фильтра</translation>
</message>
<message>
+ <source>Macro Expression</source>
+ <translation>Макро выражение</translation>
+ </message>
+ <message>
<source>Filter Expression</source>
<translation>Выражение фильтра</translation>
</message>
@@ -3168,22 +3383,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>FolderListModel</name>
<message>
- <source>&quot;File&quot; dialogs</source>
- <translation>Диалоговые окна открытия файлов</translation>
- </message>
- <message>
- <source>capture files</source>
- <translation>Файлы захвата</translation>
- </message>
- <message>
<source>Temp</source>
<translation>Временные файлы</translation>
</message>
<message>
- <source>untitled capture files</source>
- <translation>Безымянные файлы захвата</translation>
- </message>
- <message>
<source>Personal configuration</source>
<translation>Персональная конфигурация</translation>
</message>
@@ -3192,14 +3395,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Глобальная конфигурация</translation>
</message>
<message>
- <source>dfilters, preferences, ethers, …</source>
- <translation>dfilters, preferences, ethers, …</translation>
- </message>
- <message>
- <source>dfilters, preferences, manuf, …</source>
- <translation>dfilters, preferences, manuf, …</translation>
- </message>
- <message>
<source>System</source>
<translation>Конфигурация системы</translation>
</message>
@@ -3212,18 +3407,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Программы</translation>
</message>
<message>
- <source>program files</source>
- <translation>Файлы программ</translation>
- </message>
- <message>
<source>Personal Plugins</source>
<translation>Пользовательские подключаемые модули</translation>
</message>
<message>
- <source>binary plugins</source>
- <translation>Исполняемые файлы подключаемых модулей</translation>
- </message>
- <message>
<source>Global Plugins</source>
<translation>Глобальные подключаемые модули</translation>
</message>
@@ -3240,12 +3427,36 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Сценарии Lua</translation>
</message>
<message>
+ <source>&quot;File&quot; dialog location</source>
+ <translation>Местонахождение диалога &quot;Файл&quot;</translation>
+ </message>
+ <message>
+ <source>Capture files</source>
+ <translation>Захват файлов</translation>
+ </message>
+ <message>
+ <source>Untitled capture files</source>
+ <translation>Файлы захвата без названия</translation>
+ </message>
+ <message>
+ <source>Preferences, profiles, manuf, …</source>
+ <translation>Предпочтения, профили, производство, ...</translation>
+ </message>
+ <message>
+ <source>Program files</source>
+ <translation>Программные файлы</translation>
+ </message>
+ <message>
+ <source>Binary plugins</source>
+ <translation>Бинарные плагины</translation>
+ </message>
+ <message>
<source>Personal Extcap path</source>
<translation>Пользовательский путь Extcap</translation>
</message>
<message>
- <source>external capture (extcap) plugins</source>
- <translation>модули внешненго захвата (extcap)</translation>
+ <source>External capture (extcap) plugins</source>
+ <translation>Плагины для внешнего захвата (extcap)</translation>
</message>
<message>
<source>Global Extcap path</source>
@@ -3292,7 +3503,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<name>FollowStreamAction</name>
<message>
<source>%1 Stream</source>
- <translation type="unfinished"></translation>
+ <translation>%1 Поток</translation>
</message>
</context>
<context>
@@ -3306,6 +3517,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Print</source>
<translation>Печать</translation>
</message>
+ <message numerus="yes">
+ <source>%Ln client pkt(s), </source>
+ <translation type="vanished">
+ <numerusform>%Ln клиентский пакет,</numerusform>
+ <numerusform>%Ln клиентских пакета,</numerusform>
+ <numerusform>%Ln клиентских пакетах,</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln server pkt(s), </source>
+ <translation type="vanished">
+ <numerusform>%Ln серверный пакет, </numerusform>
+ <numerusform>%Ln серверных пакета, </numerusform>
+ <numerusform>%Ln серверных пакетов, </numerusform>
+ </translation>
+ </message>
<message>
<source>ASCII</source>
<translation>ASCII</translation>
@@ -3348,26 +3575,46 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message numerus="yes">
<source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;client&lt;/span&gt; pkt(s), </source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;клиентский&lt;/span&gt; пакет,</numerusform>
+ <numerusform>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;клиентских&lt;/span&gt; пакета,</numerusform>
+ <numerusform>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;клиентских&lt;/span&gt; пакетов,</numerusform>
</translation>
</message>
<message numerus="yes">
<source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;server&lt;/span&gt; pkt(s), </source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;серверный&lt;/span&gt; пакет, </numerusform>
+ <numerusform>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;серверных&lt;/span&gt; пакета, </numerusform>
+ <numerusform>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;серверных&lt;/span&gt; пакетов, </numerusform>
</translation>
</message>
<message numerus="yes">
<source>%Ln turn(s).</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%Ln поворот.</numerusform>
+ <numerusform>%Ln поворота.</numerusform>
+ <numerusform>%Ln поворотов.</numerusform>
+ </translation>
+ </message>
+ <message>
+ <source>Event %1. </source>
+ <translation>Событие %1. </translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;reads&lt;/span&gt;, </source>
+ <translation>
+ <numerusform>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;чтение&lt;/span&gt;, </numerusform>
+ <numerusform>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;чтения&lt;/span&gt;, </numerusform>
+ <numerusform>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;чтений&lt;/span&gt;, </numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;writes&lt;/span&gt;, </source>
+ <translation>
+ <numerusform>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;запись&lt;/span&gt;, </numerusform>
+ <numerusform>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;записи&lt;/span&gt;, </numerusform>
+ <numerusform>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;записей&lt;/span&gt;, </numerusform>
</translation>
</message>
<message>
@@ -3403,6 +3650,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Поток %1 не найден в выбранном пакете.</translation>
</message>
<message>
+ <source>Read activity(%6)</source>
+ <translation>Активность чтения(%6)</translation>
+ </message>
+ <message>
+ <source>Write activity(%6)</source>
+ <translation>Письменная активность(%6)</translation>
+ </message>
+ <message>
+ <source>Entire I/O activity (%1)</source>
+ <translation>Вся активность ввода/вывода (%1)</translation>
+ </message>
+ <message>
<source>Entire conversation (%1)</source>
<translation>Весь диалог (%1)</translation>
</message>
@@ -3418,24 +3677,20 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Save Stream Content As…</source>
<translation>Сохранить содержимое потока как…</translation>
</message>
- <message>
- <source>[Stream output truncated]</source>
- <translation>[Вывод потока усечён]</translation>
- </message>
<message numerus="yes">
<source>%Ln total stream(s).</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%Ln всего поток.</numerusform>
+ <numerusform>%Ln всех потоков.</numerusform>
+ <numerusform>%Ln всех потоков.</numerusform>
</translation>
</message>
<message numerus="yes">
<source>Max sub stream ID for the selected stream: %Ln</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>Максимальный идентификатор подпотока для выбранного потока: %Ln</numerusform>
+ <numerusform>Максимальный идентификатор подпотока для выбранных потоков: %Ln</numerusform>
+ <numerusform>Максимальный идентификатор подпотока для выбранных потоков: %Ln</numerusform>
</translation>
</message>
<message>
@@ -3451,9 +3706,20 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Подсказка.</translation>
</message>
<message>
- <source>Show data as</source>
- <oldsource>Show and save data as</oldsource>
- <translation>Отобразить данные в виде</translation>
+ <source>Show as</source>
+ <translation>Показать как</translation>
+ </message>
+ <message>
+ <source>No delta times</source>
+ <translation>Нет дельты времени</translation>
+ </message>
+ <message>
+ <source>Turn delta times</source>
+ <translation>Дельта времени поворота</translation>
+ </message>
+ <message>
+ <source>All delta times</source>
+ <translation>Все дельта-время</translation>
</message>
<message>
<source>Stream</source>
@@ -3468,11 +3734,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Найти:</translation>
</message>
<message>
+ <source>Case sensitive</source>
+ <translation>С учетом регистра</translation>
+ </message>
+ <message>
<source>Find &amp;Next</source>
<translation>Найти &amp;далее</translation>
</message>
</context>
<context>
+ <name>FollowStreamText</name>
+ <message>
+ <source>[Stream output truncated]</source>
+ <translation>[Вывод потока усечен]</translation>
+ </message>
+</context>
+<context>
<name>FontColorPreferencesFrame</name>
<message>
<source>Frame</source>
@@ -3546,11 +3823,11 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<message>
<source>Example GIF query packets have jumbo window sizes</source>
<extracomment>These are pangrams. Feel free to replace with nonsense text that spans your alphabet. https://en.wikipedia.org/wiki/Pangram</extracomment>
- <translation>Любя, съешь щипцы,&#xa0;— вздохнёт мэр,&#xa0;— кайф жгуч.</translation>
+ <translation>Любя, съешь щипцы,&#xa0;— вздохнёт мэр,&#xa0;— кайф жгуч</translation>
</message>
<message>
<source>Lazy badgers move unique waxy jellyfish packets</source>
- <translation>Съешь же ещё этих мягких французских булок да выпей чаю.</translation>
+ <translation>Съешь же ещё этих мягких французских булок да выпей чаю</translation>
</message>
<message>
<source>Font</source>
@@ -3694,23 +3971,23 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<name>IOConsoleDialog</name>
<message>
<source>Dialog</source>
- <translation type="unfinished"></translation>
+ <translation>Диалог</translation>
</message>
<message>
<source>Enter code</source>
- <translation type="unfinished"></translation>
+ <translation>Введите код</translation>
</message>
<message>
<source>Evaluate</source>
- <translation type="unfinished"></translation>
+ <translation>Оценить</translation>
</message>
<message>
<source>Clear</source>
- <translation type="unfinished">Очистить</translation>
+ <translation>Очистить</translation>
</message>
<message>
<source>Use %1 to evaluate.</source>
- <translation type="unfinished"></translation>
+ <translation>Используйте %1 для оценки.</translation>
</message>
</context>
<context>
@@ -3808,29 +4085,28 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <source>Remove this graph.</source>
- <oldsource>Remove this dissection behavior.</oldsource>
- <translation>Удалить этот график.</translation>
- </message>
- <message>
<source>Add a new graph.</source>
<translation>Добавить новый график.</translation>
</message>
<message>
- <source>Duplicate this graph.</source>
- <translation>Дублировать этот график.</translation>
- </message>
- <message>
<source>Clear all graphs.</source>
<translation>Очистить все графики.</translation>
</message>
<message>
- <source>Move this graph upwards.</source>
- <translation>Переместить этот график вверх.</translation>
+ <source>Remove the selected graph(s).</source>
+ <translation>Удалить выбранный график(ы).</translation>
</message>
<message>
- <source>Move this graph downwards.</source>
- <translation>Переместить этот график вниз.</translation>
+ <source>Duplicate the selected graph(s).</source>
+ <translation>Дублирование выбранного графика (графиков).</translation>
+ </message>
+ <message>
+ <source>Move the selected graph(s) upwards.</source>
+ <translation>Переместите выбранный график(ы) вверх.</translation>
+ </message>
+ <message>
+ <source>Move the selected graph(s) downwards.</source>
+ <translation>Переместите выбранный график(ы) вниз.</translation>
</message>
<message>
<source>Mouse</source>
@@ -3866,15 +4142,11 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Automatic update</source>
- <translation type="unfinished"></translation>
+ <translation>Автоматическое обновление</translation>
</message>
<message>
<source>Enable legend</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Reset</source>
- <translation>Сброс</translation>
+ <translation>Включить легенду</translation>
</message>
<message>
<source>Reset Graph</source>
@@ -4090,6 +4362,42 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Копировать графики из другого профиля.</translation>
</message>
<message>
+ <source>1 μs</source>
+ <translation>1 мкс</translation>
+ </message>
+ <message>
+ <source>2 μs</source>
+ <translation>2 мкс</translation>
+ </message>
+ <message>
+ <source>5 μs</source>
+ <translation>5 мкс</translation>
+ </message>
+ <message>
+ <source>10 μs</source>
+ <translation>10 мкс</translation>
+ </message>
+ <message>
+ <source>20 μs</source>
+ <translation>20 мкс</translation>
+ </message>
+ <message>
+ <source>50 μs</source>
+ <translation>50 мкс</translation>
+ </message>
+ <message>
+ <source>100 μs</source>
+ <translation>100 мкс</translation>
+ </message>
+ <message>
+ <source>200 μs</source>
+ <translation>200 мкс</translation>
+ </message>
+ <message>
+ <source>500 μs</source>
+ <translation>500 мкс</translation>
+ </message>
+ <message>
<source>1 ms</source>
<translation>1 мс</translation>
</message>
@@ -4134,6 +4442,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>5 сек</translation>
</message>
<message>
+ <source>2 min</source>
+ <translation>2 минуты</translation>
+ </message>
+ <message>
+ <source>5 min</source>
+ <translation>5 минут</translation>
+ </message>
+ <message>
<source>Wireshark I/O Graphs: %1</source>
<translation>Графики ввода/вывода Wireshark: %1</translation>
</message>
@@ -4143,7 +4459,15 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Filtered events</source>
- <translation type="unfinished"></translation>
+ <translation>Отфильтрованные события</translation>
+ </message>
+ <message>
+ <source>All packets</source>
+ <translation>Все пакеты</translation>
+ </message>
+ <message>
+ <source>All events</source>
+ <translation>Все события</translation>
</message>
<message>
<source>All Packets</source>
@@ -4155,11 +4479,11 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>All Events</source>
- <translation type="unfinished"></translation>
+ <translation>Все события</translation>
</message>
<message>
- <source>Access Denied</source>
- <translation type="unfinished"></translation>
+ <source>All Execs</source>
+ <translation>Все руководители</translation>
</message>
<message>
<source>Hover over the graph for details.</source>
@@ -4171,7 +4495,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>No events in interval</source>
- <translation type="unfinished"></translation>
+ <translation>Нет событий в интервале</translation>
</message>
<message>
<source>Click to select packet</source>
@@ -4183,11 +4507,11 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Click to select event</source>
- <translation type="unfinished"></translation>
+ <translation>Нажмите, чтобы выбрать событие</translation>
</message>
<message>
<source>Event</source>
- <translation type="unfinished">Событие</translation>
+ <translation>Событие</translation>
</message>
<message>
<source>%1 (%2s%3).</source>
@@ -4206,6 +4530,34 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Щёлкните для выбора участка графика.</translation>
</message>
<message>
+ <source>%1 Intervals </source>
+ <translation>%1 Интервалы </translation>
+ </message>
+ <message>
+ <source>Move to top left</source>
+ <translation>Переместить в левый верхний угол</translation>
+ </message>
+ <message>
+ <source>Move to top center</source>
+ <translation>Переместить в верхний центр</translation>
+ </message>
+ <message>
+ <source>Move to top right</source>
+ <translation>Переместить в правый верхний угол</translation>
+ </message>
+ <message>
+ <source>Move to bottom left</source>
+ <translation>Переместить в левый нижний угол</translation>
+ </message>
+ <message>
+ <source>Move to bottom center</source>
+ <translation>Переместить в нижний центр</translation>
+ </message>
+ <message>
+ <source>Move to bottom right</source>
+ <translation>Перемещение в правый нижний угол</translation>
+ </message>
+ <message>
<source>Portable Document Format (*.pdf)</source>
<translation>Portable Document Format (*.pdf)</translation>
</message>
@@ -4958,6 +5310,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>InterfaceTreeDelegate</name>
+ <message>
+ <source>default</source>
+ <translation>по умолчанию</translation>
+ </message>
+</context>
+<context>
<name>InterfaceTreeModel</name>
<message>
<source>Show</source>
@@ -5936,8 +6295,8 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>LteMacStatisticsDialog</name>
<message>
- <source>LTE Mac Statistics</source>
- <translation>Статистика LTE Mac</translation>
+ <source>LTE/NR Mac Statistics</source>
+ <translation>Статистика LTE/NR Mac</translation>
</message>
<message>
<source>Include SR frames in filter</source>
@@ -5949,7 +6308,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>MAC Statistics</source>
- <translation>Статистика MAC </translation>
+ <translation>Статистика MAC</translation>
</message>
</context>
<context>
@@ -6241,12 +6600,12 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Номер последовательности</translation>
</message>
<message>
- <source>LTE RLC Graph (UE=%1 chan=%2%3 %4 - %5)</source>
- <translation>График LTE RLC (UE=%1 канал=%2%3 %4 - %5)</translation>
+ <source>%1 RLC Graph (UE=%2 chan=%3%4 %5 - %6)</source>
+ <translation>%1 График RLC (UE=%2 канал=%3%4 %5 - %6)</translation>
</message>
<message>
- <source>LTE RLC Graph - no channel selected</source>
- <translation>График LTE RLC — канал не выбран</translation>
+ <source>3GPP RLC Graph - no channel selected</source>
+ <translation>3GPP RLC График - канал не выбран</translation>
</message>
<message>
<source>Save As…</source>
@@ -6300,8 +6659,8 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>LteRlcStatisticsDialog</name>
<message>
- <source>LTE RLC Statistics</source>
- <translation>Статистика LTE RLC</translation>
+ <source>3GPP RLC Statistics</source>
+ <translation>Статистика 3GPP RLC</translation>
</message>
<message>
<source>Include SR frames in filter</source>
@@ -6387,6 +6746,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Профиль: %1</translation>
</message>
<message>
+ <source> %1 Displayed: %2 (%3%)</source>
+ <translation> %1 Отображено: %2 (%3%)</translation>
+ </message>
+ <message>
<source>Manage Profiles…</source>
<translation>Управление профилями…</translation>
</message>
@@ -6443,10 +6806,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<message numerus="yes">
<source>%Ln byte(s)</source>
<oldsource>, %1 bytes</oldsource>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%Ln байт</numerusform>
+ <numerusform>%Ln байта</numerusform>
+ <numerusform>%Ln байтов</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln bit(s)</source>
+ <translation>
+ <numerusform>%Ln бит</numerusform>
+ <numerusform>%Ln бита</numerusform>
+ <numerusform>%Ln битов</numerusform>
</translation>
</message>
<message>
@@ -6462,9 +6833,12 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Выбран пакет: %1 %2 </translation>
</message>
<message>
- <source>Packets: %1 %4 Displayed: %2 (%3%)</source>
- <oldsource>Packets: %1 %4 Displayed: %2 %4 Marked: %3</oldsource>
- <translation>Пакеты: %1 %4 Отображаются: %2 (%3%)</translation>
+ <source>Selected Event: %1 %2 </source>
+ <translation>Выбранное событие: %1 %2 </translation>
+ </message>
+ <message>
+ <source>Events: %1</source>
+ <translation>События: %1</translation>
</message>
<message>
<source> %1 Selected: %2 (%3%)</source>
@@ -6496,6 +6870,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Пакеты отсутствуют</translation>
</message>
<message>
+ <source>No Events</source>
+ <translation>Нет событий</translation>
+ </message>
+ <message>
<source>From Zip File...</source>
<translation>Из zip-фйла…</translation>
</message>
@@ -6529,6 +6907,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>MainWindow</name>
+ <message>
+ <source>Display filter as %1</source>
+ <translation>Отображение фильтра как %1</translation>
+ </message>
+</context>
+<context>
<name>MainWindowPreferencesFrame</name>
<message>
<source>Frame</source>
@@ -6560,6 +6945,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Последняя использованная папка</translation>
</message>
<message>
+ <source>The current working directory</source>
+ <translation>Текущий рабочий каталог</translation>
+ </message>
+ <message>
<source>Show up to</source>
<translation>Показывать до</translation>
</message>
@@ -6703,62 +7092,62 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<name>ManufDialog</name>
<message>
<source>MAC Address Blocks</source>
- <translation type="unfinished"></translation>
+ <translation>Блокировка MAC-адресов</translation>
</message>
<message>
<source>Search MAC address or address prefix. Special purpose bits are masked.</source>
- <translation type="unfinished"></translation>
+ <translation>Поиск MAC-адреса или префикса адреса. Биты специального назначения маскируются.</translation>
</message>
<message>
<source>MAC Address</source>
- <translation type="unfinished"></translation>
+ <translation>MAC-адрес</translation>
</message>
<message>
<source>Search vendor name using a case-insentitive regular expression.</source>
- <translation type="unfinished"></translation>
+ <translation>Поиск названия поставщика с помощью регулярного выражения, не зависящего от регистра.</translation>
</message>
<message>
<source>Vendor Name</source>
- <translation type="unfinished"></translation>
+ <translation>Название поставщика</translation>
</message>
<message>
<source>Show short name column.</source>
- <translation type="unfinished"></translation>
+ <translation>Показать колонку с короткими названиями.</translation>
</message>
<message>
<source>Short name</source>
- <translation type="unfinished"></translation>
+ <translation>Краткое название</translation>
</message>
<message>
<source>Select all</source>
- <translation type="unfinished">Выбрать все</translation>
+ <translation>Выбрать все</translation>
</message>
<message>
<source>Copy</source>
- <translation type="unfinished">Копировать</translation>
+ <translation>Копировать</translation>
</message>
<message>
<source>Find</source>
- <translation type="unfinished">Найти</translation>
+ <translation>Найти</translation>
</message>
<message>
<source>Clear</source>
- <translation type="unfinished">Очистить</translation>
+ <translation>Очистить</translation>
</message>
</context>
<context>
<name>ManufTableModel</name>
<message>
<source>Address Block</source>
- <translation type="unfinished"></translation>
+ <translation>Адресный блокиратор</translation>
</message>
<message>
<source>Short Name</source>
- <translation type="unfinished">Короткое имя</translation>
+ <translation>Краткое название</translation>
</message>
<message>
<source>Vendor Name</source>
- <translation type="unfinished"></translation>
+ <translation>Название поставщика</translation>
</message>
</context>
<context>
@@ -6990,6 +7379,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Показать значения полей</translation>
</message>
<message>
+ <source>Refresh</source>
+ <translation>Обновить</translation>
+ </message>
+ <message>
<source>Save Diagram As…</source>
<translation>Сохранить диаграмму как…</translation>
</message>
@@ -7037,6 +7430,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Показывать байты пакета</translation>
</message>
<message>
+ <source>Layout:</source>
+ <translation>Макет:</translation>
+ </message>
+ <message>
<source>Packet %1</source>
<translation>Пакет %1</translation>
</message>
@@ -7054,10 +7451,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message numerus="yes">
<source>%Ln byte(s)</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%Ln байт</numerusform>
+ <numerusform>%Ln байта</numerusform>
+ <numerusform>%Ln байтов</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln bit(s)</source>
+ <translation>
+ <numerusform>%Ln бит</numerusform>
+ <numerusform>%Ln бита</numerusform>
+ <numerusform>%Ln битов</numerusform>
</translation>
</message>
</context>
@@ -7230,7 +7635,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Sorting …</source>
- <translation type="unfinished"></translation>
+ <translation>Сортировка …</translation>
</message>
</context>
<context>
@@ -7265,11 +7670,11 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Include &amp;depended upon packets</source>
- <translation type="unfinished"></translation>
+ <translation>Включать и зависеть от пакетов</translation>
</message>
<message>
<source>Also include packets depended upon, such as those used to reassemble displayed packets</source>
- <translation type="unfinished"></translation>
+ <translation>Включите также пакеты, от которых зависят, например, пакеты, используемые для повторной сборки отображаемых пакетов.</translation>
</message>
<message>
<source>First &amp;to last marked</source>
@@ -7395,11 +7800,11 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Checking this will show only changed preferences.</source>
- <translation type="unfinished"></translation>
+ <translation>Если установить этот флажок, будут показаны только измененные настройки.</translation>
</message>
<message>
<source>Show changed values</source>
- <translation type="unfinished"></translation>
+ <translation>Показать измененные значения</translation>
</message>
<message>
<source>Preferences</source>
@@ -7519,10 +7924,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Копировать данный профиль.</translation>
</message>
<message>
+ <source>The number of packets or events to check for automatic profile switching.</source>
+ <translation>Количество пакетов или событий, которые необходимо проверить для автоматического переключения профиля.</translation>
+ </message>
+ <message>
+ <source>Auto switch packet limit</source>
+ <translation>Ограничение пакетов автоматического переключения</translation>
+ </message>
+ <message>
<source>Configuration Profiles</source>
<translation>Профили конфигурации</translation>
</message>
<message>
+ <source>Auto switch event limit</source>
+ <translation>Предел события автоматического переключения</translation>
+ </message>
+ <message>
<source>Import</source>
<comment>noun</comment>
<translation>Импорт</translation>
@@ -7542,10 +7959,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message numerus="yes">
<source>%Ln Selected Personal Profile(s)...</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%Ln Выбранный персональный профиль...</numerusform>
+ <numerusform>%Ln Выбранный персональный профиля...</numerusform>
+ <numerusform>%Ln Выбранный персональный профилей...</numerusform>
</translation>
</message>
<message>
@@ -7572,6 +7989,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Select zip file for export</source>
<translation>Выбрать zip-файл для экспорта</translation>
</message>
+ <message numerus="yes">
+ <source>… %Ln selected personal profile(s)</source>
+ <translation type="vanished">
+ <numerusform>... %Ln выбранный личный профиль</numerusform>
+ <numerusform>... %Ln выбранных личных профиля</numerusform>
+ <numerusform>... %Ln выбранных личных профилей</numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln selected personal profile(s)</source>
+ <translation type="vanished">
+ <numerusform>%Ln выбранный личный профиль</numerusform>
+ <numerusform>%Ln выбранных личных профиля</numerusform>
+ <numerusform>%Ln выбранных личных профилей</numerusform>
+ </translation>
+ </message>
<message>
<source>An import of profiles is not allowed, while changes are pending</source>
<translation>Импорт профилей при наличии ожидающих сохранения изменений не допускается</translation>
@@ -7590,10 +8023,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message numerus="yes">
<source>%Ln profile(s) exported</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%Ln профиль экспортирован</numerusform>
+ <numerusform>%Ln профиля экспортировано</numerusform>
+ <numerusform>%Ln профилей экспортировано</numerusform>
</translation>
</message>
<message>
@@ -7622,18 +8055,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message numerus="yes">
<source>%Ln profile(s) imported</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%Ln профиль импортирован</numerusform>
+ <numerusform>%Ln профиля импортировано</numerusform>
+ <numerusform>%Ln профилей импортировано</numerusform>
</translation>
</message>
<message numerus="yes">
<source>, %Ln profile(s) skipped</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%Ln профиль пропущен</numerusform>
+ <numerusform>%Ln профиля пропущено</numerusform>
+ <numerusform>%Ln профилей пропущено</numerusform>
</translation>
</message>
<message>
@@ -7696,6 +8129,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>удалённый</translation>
</message>
<message>
+ <source>Auto Switch Filter</source>
+ <translation>Автоматический переключатель фильтра</translation>
+ </message>
+ <message>
<source>copy</source>
<comment>noun</comment>
<translation>копия</translation>
@@ -7934,27 +8371,27 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Copy short names</source>
- <translation type="unfinished"></translation>
+ <translation>Копирование коротких названий</translation>
</message>
<message>
<source>Copy short protocol names in use.</source>
- <translation type="unfinished"></translation>
+ <translation>Скопируйте используемые короткие названия протоколов.</translation>
</message>
<message>
<source>Disable unused protocols</source>
- <translation type="unfinished"></translation>
+ <translation>Отключите неиспользуемые протоколы</translation>
</message>
<message>
<source>Disable all protocols but those listed.</source>
- <translation type="unfinished"></translation>
+ <translation>Отключите все протоколы, кроме перечисленных.</translation>
</message>
<message>
<source>Re-enable unused protocols</source>
- <translation type="unfinished"></translation>
+ <translation>Повторное включение неиспользуемых протоколов</translation>
</message>
<message>
<source>Re-enable protocols that were disabled in this dialog.</source>
- <translation type="unfinished"></translation>
+ <translation>Повторное включение протоколов, которые были отключены в этом диалоговом окне.</translation>
</message>
<message>
<source>Protocol Hierarchy Statistics</source>
@@ -7974,19 +8411,19 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>protocol short names</source>
- <translation type="unfinished"></translation>
+ <translation>краткие названия протоколов</translation>
</message>
<message>
<source>Protocols</source>
- <translation type="unfinished"></translation>
+ <translation>Протоколы</translation>
</message>
<message>
<source>Disable unused</source>
- <translation type="unfinished"></translation>
+ <translation>Отключить неиспользуемые</translation>
</message>
<message>
<source>Revert changes</source>
- <translation type="unfinished"></translation>
+ <translation>Отмена изменений</translation>
</message>
<message>
<source>No display filter.</source>
@@ -7998,11 +8435,11 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Unused protocols have been disabled.</source>
- <translation type="unfinished"></translation>
+ <translation>Неиспользуемые протоколы были отключены.</translation>
</message>
<message>
<source>Protocol changes have been reverted.</source>
- <translation type="unfinished"></translation>
+ <translation>Изменения протокола были отменены.</translation>
</message>
</context>
<context>
@@ -8055,6 +8492,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Размер окна (Б)</translation>
</message>
<message>
+ <source>Unacked (Outstanding) Bytes (B)</source>
+ <translation>Нераспакованные (выданные) байты (B)</translation>
+ </message>
+ <message>
<source>[no capture file]</source>
<translation>[нет файла захвата]</translation>
</message>
@@ -8215,6 +8656,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Отсутствует маркер?</translation>
</message>
<message>
+ <source>LTE</source>
+ <translation>LTE</translation>
+ </message>
+ <message>
+ <source>NR</source>
+ <translation>NR</translation>
+ </message>
+ <message>
<source>C-RNTI</source>
<translation>C-RNTI</translation>
</message>
@@ -8235,6 +8684,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>UEId</translation>
</message>
<message>
+ <source>RAT</source>
+ <translation>КРЫСА</translation>
+ </message>
+ <message>
<source>UL Frames</source>
<translation>Кадры UL</translation>
</message>
@@ -8458,9 +8911,69 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Browse…</source>
<translation>Обзор…</translation>
</message>
+ <message>
+ <source>PACKETS</source>
+ <translation>ПАКЕТЫ</translation>
+ </message>
+ <message>
+ <source>EVENTS</source>
+ <translation>СОБЫТИЯ</translation>
+ </message>
+ <message>
+ <source>BYTES</source>
+ <translation>БАЙТЫ</translation>
+ </message>
+ <message>
+ <source>BITS</source>
+ <translation>БИТЫ</translation>
+ </message>
+ <message>
+ <source>COUNT FRAMES</source>
+ <translation>СЧЁТНЫЕ РАМКИ</translation>
+ </message>
+ <message>
+ <source>COUNT FIELDS</source>
+ <translation>СЧЕТНЫЕ ПОЛЯ</translation>
+ </message>
+ <message>
+ <source>SUM</source>
+ <translation>СУММА</translation>
+ </message>
+ <message>
+ <source>MAX</source>
+ <translation>МАКСИМАЛЬНО</translation>
+ </message>
+ <message>
+ <source>MIN</source>
+ <translation>МИНИМАЛЬНО</translation>
+ </message>
+ <message>
+ <source>AVERAGE</source>
+ <translation>СРЕДНИЙ</translation>
+ </message>
+ <message>
+ <source>THROUGHPUT</source>
+ <translation>ТРЕУГОЛЬНИК</translation>
+ </message>
+ <message>
+ <source>LOAD</source>
+ <translation>ЗАГРУЗКА</translation>
+ </message>
+ <message>
+ <source>Left</source>
+ <translation>Левый</translation>
+ </message>
+ <message>
+ <source>Center</source>
+ <translation>Центр</translation>
+ </message>
+ <message>
+ <source>Right</source>
+ <translation>Правый</translation>
+ </message>
</context>
<context>
- <name>QObject::QObject</name>
+ <name>QObject::QObject::QObject</name>
<message>
<source>CCCH</source>
<translation>CCCH</translation>
@@ -8561,6 +9074,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>ResizeHeaderView</name>
+ <message>
+ <source>Resize all %1 to contents</source>
+ <translation>Изменить размер всех %1 по содержимому</translation>
+ </message>
+</context>
+<context>
<name>ResolvedAddressesDialog</name>
<message>
<source>Dialog</source>
@@ -8676,6 +9196,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Разрешённые адреса</translation>
</message>
<message>
+ <source>Copy</source>
+ <translation>Копировать</translation>
+ </message>
+ <message>
+ <source>Save as…</source>
+ <translation>Сохранить как...</translation>
+ </message>
+ <message>
<source># Resolved addresses found in %1</source>
<translation># Разрешённые адреса найденные в %1</translation>
</message>
@@ -8689,6 +9217,61 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>ResolvedAddressesView</name>
+ <message>
+ <source>as Plain Text</source>
+ <translation>как обычный текст</translation>
+ </message>
+ <message>
+ <source>Copy selected rows</source>
+ <translation>Копирование выбранных строк</translation>
+ </message>
+ <message>
+ <source>Copy table</source>
+ <translation>Копирование таблицы</translation>
+ </message>
+ <message>
+ <source>as CSV</source>
+ <translation>как CSV</translation>
+ </message>
+ <message>
+ <source>as JSON</source>
+ <translation>как JSON</translation>
+ </message>
+ <message>
+ <source>Save selected rows as…</source>
+ <translation>Сохранить выбранные строки как...</translation>
+ </message>
+ <message>
+ <source>Save table as…</source>
+ <translation>Сохраните таблицу как...</translation>
+ </message>
+ <message>
+ <source>Save Resolved Addresses As…</source>
+ <translation>Сохранить решенные адреса как...</translation>
+ </message>
+ <message>
+ <source>Plain text (*.txt)</source>
+ <translation>Обычный текст (*.txt)</translation>
+ </message>
+ <message>
+ <source>CSV Document (*.csv)</source>
+ <translation>Документ CSV (*.csv)</translation>
+ </message>
+ <message>
+ <source>JSON Document (*.json)</source>
+ <translation>Документ JSON (*.json)</translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation>Внимание</translation>
+ </message>
+ <message>
+ <source>Unable to save %1: %2</source>
+ <translation>Невозможно сохранить %1: %2</translation>
+ </message>
+</context>
+<context>
<name>ResponseTimeDelayDialog</name>
<message>
<source>%1 Response Time Delay Statistics</source>
@@ -10014,11 +10597,11 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>-</source>
- <translation type="unfinished">-</translation>
+ <translation>-</translation>
</message>
<message>
<source>&lt;small&gt;&lt;i&gt;For complete analysis check SCTP preference Enable Association indexing&lt;/i&gt;&lt;/small&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;small&gt;Для полного анализа проверьте предпочтение SCTP Включить индексирование ассоциаций&lt;i&gt;&lt;/small&gt;</translation>
</message>
<message>
<source>Complete List of IP addresses from INIT Chunk:</source>
@@ -10363,6 +10946,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Байты пакета</translation>
</message>
<message>
+ <source>&lt;b&gt;Options:&lt;/b&gt;</source>
+ <translation>&lt;b&gt;Опции:&lt;/b&gt;</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for strings containing narrow (UTF-8 and ASCII) or wide (UTF-16) characters.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Поиск строк, содержащих символы в обычной (UTF-8 и ASCII) или многобайтовой (UTF-16) кодировке.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -10383,6 +10970,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Чувствительность к регистру</translation>
</message>
<message>
+ <source>Backwards</source>
+ <translation>Назад</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for a subsequent occurrence in the current packet before advancing to the next packet.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Поиск последующего вхождения в текущем пакете перед переходом к следующему пакету.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>Multiple occurrences</source>
+ <translation>Множественные случаи</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5), a plain string (e.g. My String) or a regular expression (e.g. colou?r).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<oldsource>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5) or a plain string (e.g. My String).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</oldsource>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Поиск данных можно выполнять с использованием фильтров отображения (например, «ip.addr==10.1.1.1»), шестнадцатеричных строк (например, «fffffda5»), обычных текстовых строк (например, «Моя строка») и регулярных выражений (например, «colou?r»).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
@@ -10420,6 +11019,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Недопустимый фильтр.</translation>
</message>
<message>
+ <source>Event List</source>
+ <translation>Список событий</translation>
+ </message>
+ <message>
+ <source>Event Details</source>
+ <translation>Подробности события</translation>
+ </message>
+ <message>
+ <source>Event Bytes</source>
+ <translation>Байты событий</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search the Info column of the event list (summary pane), decoded event display labels (tree view pane) or the ASCII-converted event data (hex view pane).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Поиск в колонке &quot;Информация&quot; списка событий (панель сводки), в декодированных метках отображения событий (панель древовидного представления) или в преобразованных в ASCII данных события (панель шестнадцатеричного представления).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
<source>That filter doesn&apos;t test anything.</source>
<translation>Этот фильтр не производит тестирование.</translation>
</message>
@@ -10484,18 +11099,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message numerus="yes">
<source>%Ln node(s)</source>
- <translation type="unfinished">
- <numerusform>%Ln node</numerusform>
- <numerusform>%Ln nodes</numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%Ln узел</numerusform>
+ <numerusform>%Ln узла</numerusform>
+ <numerusform>%Ln узлов</numerusform>
</translation>
</message>
<message numerus="yes">
<source>%Ln item(s)</source>
- <translation type="unfinished">
- <numerusform>%Ln item</numerusform>
- <numerusform>%Ln items</numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%Ln элемент</numerusform>
+ <numerusform>%Ln элемента</numerusform>
+ <numerusform>%Ln элементов</numerusform>
</translation>
</message>
<message>
@@ -10865,15 +11480,19 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Найти:</translation>
</message>
<message>
+ <source>Case sensitive</source>
+ <translation>С учетом регистра</translation>
+ </message>
+ <message>
<source>Find &amp;Next</source>
<translation>Найти &amp;следующий</translation>
</message>
<message numerus="yes">
<source>Frame %1, %2, %Ln byte(s).</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>Кадр %1, %2, %Ln байт.</numerusform>
+ <numerusform>Кадров %1, %2, %Ln байт.</numerusform>
+ <numerusform>Кадров %1, %2, %Ln байт.</numerusform>
</translation>
</message>
<message>
@@ -10961,15 +11580,23 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Сохранить как…</translation>
</message>
<message>
+ <source>Decoded as %1.</source>
+ <translation>Расшифровано как %1.</translation>
+ </message>
+ <message>
<source>Save Selected Packet Bytes As…</source>
<translation>Сохранение выбранных байтов пакета как…</translation>
</message>
+ <message>
+ <source>compressed %1</source>
+ <translation>сжато %1</translation>
+ </message>
<message numerus="yes">
- <source>Displaying %Ln byte(s).</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <source>Using %Ln byte(s).</source>
+ <translation>
+ <numerusform>Использование %Ln байта.</numerusform>
+ <numerusform>Использование %Ln байта.</numerusform>
+ <numerusform>Использование %Ln байт.</numerusform>
</translation>
</message>
<message>
@@ -11041,7 +11668,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Applying changed preferences</source>
- <translation type="unfinished"></translation>
+ <translation>Применение измененных предпочтений</translation>
</message>
<message>
<source>(Unknown action)</source>
@@ -11069,6 +11696,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Display filter:</source>
<translation>Фильтр отображения:</translation>
</message>
+ <message>
+ <source>Strip Headers</source>
+ <translation>Полосатые заголовки</translation>
+ </message>
</context>
<context>
<name>SupportedProtocolsDialog</name>
@@ -11721,51 +12352,51 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<name>TLSKeylogDialog</name>
<message>
<source>Dialog</source>
- <translation type="unfinished"></translation>
+ <translation>Диалог</translation>
</message>
<message>
<source>Browse…</source>
- <translation type="unfinished">Обзор…</translation>
+ <translation>Просмотреть...</translation>
</message>
<message>
<source>Command line</source>
- <translation type="unfinished"></translation>
+ <translation>Командная строка</translation>
</message>
<message>
<source>Run an application with the SSLKEYLOGFILE environment variable set to the file specified by the TLS key log filename preference. This enables TLS decryption in Wireshark. Set the key log file and start the capture before launching the application to ensure that the initial TLS handshakes are captured.</source>
- <translation type="unfinished"></translation>
+ <translation>Запустите приложение с переменной окружения SSLKEYLOGFILE, установленной на файл, указанный в параметре &quot;Имя файла журнала ключей TLS&quot;. Это позволяет расшифровать TLS в Wireshark. Установите файл журнала ключей и запустите захват перед запуском приложения, чтобы обеспечить захват начальных рукопожатий TLS.</translation>
</message>
<message>
<source>&lt;span style=&quot; font-size:small;&quot;&gt;Firefox and Chrome are known to work. If your desired browser is currently running, close it first before launching it below. Command line options are supported.&lt;/span&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;span style=&quot; font-size:small;&quot;&gt;Известно, что Firefox и Chrome работают. Если нужный вам браузер запущен, закройте его, прежде чем запускать ниже. Поддерживаются параметры командной строки.&lt;/span&gt;</translation>
</message>
<message>
<source>TLS (Pre)-Master-Secret log file path (tls.keylog_file)</source>
- <translation type="unfinished"></translation>
+ <translation>Путь к файлу журнала TLS (Предварительный) - Мастер-секрет (tls.keylog_file)</translation>
</message>
<message>
<source>&lt;span style=&quot; font-size:small;&quot;&gt;TLS session secrets will be logged to this file. If you change this field, hit the Save button to update the TLS protocol preferences.&lt;/span&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;span style=&quot; font-size:small;&quot;&gt;В этот файл будут записываться секреты сеанса TLS. Если вы измените это поле, нажмите кнопку Сохранить, чтобы обновить настройки протокола TLS.&lt;/span&gt;</translation>
</message>
<message>
<source>Launch application with SSLKEYLOGFILE</source>
- <translation type="unfinished"></translation>
+ <translation>Запуск приложения с SSLKEYLOGFILE</translation>
</message>
<message>
<source>Launch</source>
- <translation type="unfinished"></translation>
+ <translation>Запуск</translation>
</message>
<message>
<source>Save</source>
- <translation type="unfinished">Сохранить</translation>
+ <translation>Сохранить</translation>
</message>
<message>
<source>TLS Keylog file</source>
- <translation type="unfinished"></translation>
+ <translation>Файл журнала ключей TLS</translation>
</message>
<message>
<source>Program to start with SSLKEYLOGFILE</source>
- <translation type="unfinished"></translation>
+ <translation>Программа для запуска с SSLKEYLOGFILE</translation>
</message>
</context>
<context>
@@ -11885,7 +12516,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Time shifting is not available while capturing packets.</source>
- <translation type="unfinished"></translation>
+ <translation>Перемещение по времени при захвате пакетов недоступно.</translation>
</message>
</context>
<context>
@@ -12042,22 +12673,20 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Создать новую запись.</translation>
</message>
<message>
- <source>Remove this entry.</source>
- <oldsource>Remove this profile.</oldsource>
- <translation>Удалить эту запись.</translation>
+ <source>Remove the selected entry(ies).</source>
+ <translation>Удалить выбранную запись(и).</translation>
</message>
<message>
- <source>Copy this entry.</source>
- <oldsource>Copy this profile.</oldsource>
- <translation>Копировать эту запись.</translation>
+ <source>Copy the selected entry(ies).</source>
+ <translation>Копирование выбранной записи (записей).</translation>
</message>
<message>
- <source>Move entry up.</source>
- <translation>Переместить запись выше.</translation>
+ <source>Move the selected entry(ies) up.</source>
+ <translation>Переместите выбранную запись(и) вверх.</translation>
</message>
<message>
- <source>Move entry down.</source>
- <translation>Переместить запись ниже.</translation>
+ <source>Move the selected entry(ies) down.</source>
+ <translation>Переместите выбранную запись(и) вниз.</translation>
</message>
<message>
<source>Clear all entries.</source>
@@ -12083,20 +12712,20 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Создать новую запись.</translation>
</message>
<message>
- <source>Remove this entry.</source>
- <translation>Удалить эту запись.</translation>
+ <source>Remove the selected entry(ies).</source>
+ <translation>Удалите выбранную запись(и).</translation>
</message>
<message>
- <source>Copy this entry.</source>
- <translation>Копировать эту запись.</translation>
+ <source>Copy the selected entry(ies).</source>
+ <translation>Копирование выбранной записи (записей).</translation>
</message>
<message>
- <source>Move entry up.</source>
- <translation>Переместить запись выше.</translation>
+ <source>Move the selected entry(ies) up.</source>
+ <translation>Переместите выбранную запись(и) вверх.</translation>
</message>
<message>
- <source>Move entry down.</source>
- <translation>Переместить запись ниже.</translation>
+ <source>Move the selected entry(ies) down.</source>
+ <translation>Переместите выбранную запись(и) вниз.</translation>
</message>
<message>
<source>Clear all entries.</source>
@@ -12457,10 +13086,10 @@ a:hover {
</message>
<message numerus="yes">
<source>%n interface(s) shown, %1 hidden</source>
- <translation type="unfinished">
- <numerusform>%n interface shown, %1 hidden</numerusform>
- <numerusform>%n interfaces shown, %1 hidden</numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%n интерфейсов показано, %1 скрыт</numerusform>
+ <numerusform>%n интерфейсов показано, %1 скрыто</numerusform>
+ <numerusform>%n интерфейсов показано, %1 скрыто</numerusform>
</translation>
</message>
<message>
@@ -12468,10 +13097,18 @@ a:hover {
<translation>Все составные звенья Интернета анализировать поможет Wireshark </translation>
</message>
<message>
+ <source>You are sniffing the glue that holds your system together using Logray </source>
+ <translation>Вы нюхаете клей, который держит вашу систему вместе, используя Logray. </translation>
+ </message>
+ <message>
<source>You are running Wireshark </source>
<translation>Работа производится в Wireshark </translation>
</message>
<message>
+ <source>You are running Logray </source>
+ <translation>Вы используете Logray </translation>
+ </message>
+ <message>
<source> You receive automatic updates.</source>
<translation> Обновления выполняются автоматически.</translation>
</message>
@@ -12748,14 +13385,6 @@ a:hover {
<translation>Файлы не найдены</translation>
</message>
<message>
- <source>&amp;Contents</source>
- <translation>&amp;Содержание</translation>
- </message>
- <message>
- <source>Wireshark Filter</source>
- <translation>Фильтр Wireshark</translation>
- </message>
- <message>
<source>TShark</source>
<translation>TShark</translation>
</message>
@@ -13021,10 +13650,6 @@ a:hover {
<translation>Панель инструментов беспроводного соединения</translation>
</message>
<message>
- <source>Help contents</source>
- <translation>Содержание справки</translation>
- </message>
- <message>
<source>FAQs</source>
<translation>Вопросы и ответы</translation>
</message>
@@ -13145,11 +13770,6 @@ a:hover {
<translation>Найти предыдущий пакет</translation>
</message>
<message>
- <source>&amp;Mark/Unmark Packet(s)</source>
- <oldsource>&amp;Mark/Unmark Packet</oldsource>
- <translation>&amp;Установить/снять отметку пакета (пакетов)</translation>
- </message>
- <message>
<source>Mark All Displayed</source>
<translation>Отметить всё отображаемое</translation>
</message>
@@ -13178,11 +13798,6 @@ a:hover {
<translation>Перейти к предыдущему отмеченному пакету</translation>
</message>
<message>
- <source>&amp;Ignore/Unignore Packet(s)</source>
- <oldsource>&amp;Ignore/Unignore Packet</oldsource>
- <translation>&amp;Игнорировать/отменить игнорирование пакета</translation>
- </message>
- <message>
<source>Ignore All Displayed</source>
<translation>Игнорировать всё отображаемое</translation>
</message>
@@ -13623,32 +14238,28 @@ a:hover {
<translation>Сбросить разметку</translation>
</message>
<message>
- <source>Reset appearance layout to default size</source>
- <translation>Сбросить внешний вид разметки к размеру по умолчанию</translation>
- </message>
- <message>
<source>Seconds Since First Captured Packet</source>
<translation>Количество секунд с момента захвата первого пакета</translation>
</message>
<message>
<source>Show packet times as the seconds since the first captured packet.</source>
- <translation type="unfinished"></translation>
+ <translation>Показывает время прохождения пакетов в секундах с момента первого захваченного пакета.</translation>
</message>
<message>
<source>Tenths of a millisecond</source>
- <translation type="unfinished"></translation>
+ <translation>Десятые доли миллисекунды</translation>
</message>
<message>
<source>Hundredths of a millisecond</source>
- <translation type="unfinished"></translation>
+ <translation>Сотые доли миллисекунды</translation>
</message>
<message>
<source>Tenths of a microsecond</source>
- <translation type="unfinished"></translation>
+ <translation>Десятые доли микросекунды</translation>
</message>
<message>
<source>Hundredths of a microsecond</source>
- <translation type="unfinished"></translation>
+ <translation>Сотые доли микросекунды</translation>
</message>
<message>
<source>Packet &amp;Diagram</source>
@@ -13784,25 +14395,33 @@ a:hover {
</message>
<message>
<source>MAC Address Blocks</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>TLS Keylog Launcher</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Release Notes</source>
- <translation type="unfinished"></translation>
+ <translation>Блокировка MAC-адресов</translation>
</message>
<message>
<source>&amp;Options…</source>
<translation>&amp;Опции…</translation>
</message>
<message>
+ <source>&amp;3GPP Uu</source>
+ <translation>&amp;3GPP Uu</translation>
+ </message>
+ <message>
<source>&amp;Wireless</source>
<translation>&amp;Беспроводная связь</translation>
</message>
<message>
+ <source>&amp;User&apos;s Guide</source>
+ <translation>&amp;Руководство пользователя</translation>
+ </message>
+ <message>
+ <source>Wireshark User&apos;s Guide</source>
+ <translation>Руководство пользователя Wireshark</translation>
+ </message>
+ <message>
+ <source>Display Filters</source>
+ <translation>Фильтры дисплея</translation>
+ </message>
+ <message>
<source>Capture &amp;Filters…</source>
<translation>Фильтры &amp;захвата…</translation>
</message>
@@ -13847,10 +14466,18 @@ a:hover {
<translation>Найти пр&amp;едыдущий</translation>
</message>
<message>
+ <source>&amp;Mark/Unmark Selected</source>
+ <translation>&amp;Маркировать/немаркировать выбранное</translation>
+ </message>
+ <message>
<source>Mark or unmark each selected packet</source>
<translation>Установить или снять отметку всех выбранных пакетов</translation>
</message>
<message>
+ <source>&amp;Ignore/Unignore Selected</source>
+ <translation>&amp;Игнорировать/Неигнорировать выбранное</translation>
+ </message>
+ <message>
<source>Ignore or unignore each selected packet</source>
<translation>Игнорировать или отменить игнорирование всех выбранных пакетов</translation>
</message>
@@ -13868,19 +14495,19 @@ a:hover {
</message>
<message>
<source>Inject TLS Secrets</source>
- <translation type="unfinished"></translation>
+ <translation>Инъекция секретов TLS</translation>
</message>
<message>
<source>Embed used TLS secrets in the capture file</source>
- <translation type="unfinished"></translation>
+ <translation>Встраивание используемых секретов TLS в файл захвата</translation>
</message>
<message>
<source>Discard All Secrets</source>
- <translation type="unfinished"></translation>
+ <translation>Выбросить все секреты</translation>
</message>
<message>
<source>Discard all decryption secrets in the capture file</source>
- <translation type="unfinished"></translation>
+ <translation>Отбросьте все секреты расшифровки в файле захвата</translation>
</message>
<message>
<source>&amp;Preferences…</source>
@@ -13891,6 +14518,18 @@ a:hover {
<translation>Пропускная способность TCP</translation>
</message>
<message>
+ <source>General</source>
+ <translation>Общий</translation>
+ </message>
+ <message>
+ <source>Query-Response</source>
+ <translation>Запрос-ответ</translation>
+ </message>
+ <message>
+ <source>DNS Query-Response Statistics</source>
+ <translation>Статистика DNS-запросов-ответов</translation>
+ </message>
+ <message>
<source>Request Sequences</source>
<translation>Последовательности запросов</translation>
</message>
@@ -13899,6 +14538,14 @@ a:hover {
<translation>Последовательности HTTP-запросов</translation>
</message>
<message>
+ <source>E2AP</source>
+ <translation>E2AP</translation>
+ </message>
+ <message>
+ <source>E2AP Messages</source>
+ <translation>Сообщения E2AP</translation>
+ </message>
+ <message>
<source>Decode &amp;As…</source>
<translation>Декодировать &amp;как…</translation>
</message>
@@ -13959,6 +14606,10 @@ a:hover {
<translation>Обычный размер</translation>
</message>
<message>
+ <source>Reset layout to default size</source>
+ <translation>Сброс макета до размера по умолчанию</translation>
+ </message>
+ <message>
<source>Resize Columns</source>
<translation>Изменить размер столбцов</translation>
</message>
@@ -14217,6 +14868,14 @@ a:hover {
<translation>Перейти к пакету по ссылке из выбранного поля.</translation>
</message>
<message>
+ <source>TLS Keylog Launcher</source>
+ <translation>Запускатель TLS Keylog</translation>
+ </message>
+ <message>
+ <source>Release Notes</source>
+ <translation>Примечания к выпуску</translation>
+ </message>
+ <message>
<source>&amp;VoIP Calls</source>
<translation>Вызовы &amp;VoIP</translation>
</message>
@@ -14249,10 +14908,6 @@ a:hover {
<translation>&amp;GSM</translation>
</message>
<message>
- <source>&amp;LTE</source>
- <translation>&amp;LTE</translation>
- </message>
- <message>
<source>&amp;MTP3</source>
<translation>&amp;MTP3</translation>
</message>
@@ -14537,6 +15192,10 @@ a:hover {
<translation>Выйти &amp;без сохранения</translation>
</message>
<message>
+ <source>USB CDC Data</source>
+ <translation>Данные USB CDC</translation>
+ </message>
+ <message>
<source>There is no &quot;rtp.ssrc&quot; field in this version of Wireshark.</source>
<translation>В этой версии Wireshark отсутствует поле «rtp.ssrc».</translation>
</message>
@@ -14598,6 +15257,15 @@ a:hover {
<source>No Keys</source>
<translation>Отсутствуют ключи</translation>
</message>
+ <message numerus="yes">
+ <source>Export SSL Session Keys (%Ln key(s))</source>
+ <oldsource>Export SSL Session Keys (%1 key%2</oldsource>
+ <translation type="vanished">
+ <numerusform>Экспорт ключей сеансов SSL (%Ln ключа)</numerusform>
+ <numerusform>Экспорт ключей сеансов SSL (%Ln ключа)</numerusform>
+ <numerusform>Экспорт ключей сеансов SSL (%Ln ключей)</numerusform>
+ </translation>
+ </message>
<message>
<source>Raw data (*.bin *.dat *.raw);;All Files (</source>
<translation>Необработанные данные (*.bin *.dat *.raw);;Все Файлы (</translation>
@@ -14667,10 +15335,10 @@ a:hover {
</message>
<message numerus="yes">
<source>Delete comments from %n packet(s)</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>Удалить комментарии из %n пакета(ов)</numerusform>
+ <numerusform>Удалить комментарии из %n пакета(ов)</numerusform>
+ <numerusform>Удалить комментарии из %n пакета(ов)</numerusform>
</translation>
</message>
<message>
@@ -14687,7 +15355,7 @@ a:hover {
</message>
<message>
<source> before updating</source>
- <translation type="unfinished"></translation>
+ <translation> перед обновлением</translation>
</message>
<message>
<source>There are no TLS Session Keys to save.</source>
@@ -14695,10 +15363,10 @@ a:hover {
</message>
<message numerus="yes">
<source>Export TLS Session Keys (%Ln key(s))</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>Экспорт ключей сеанса TLS (%Ln ключ)</numerusform>
+ <numerusform>Экспорт ключей сеанса TLS (%Ln ключа)</numerusform>
+ <numerusform>Экспорт ключей сеанса TLS (%Ln ключей)</numerusform>
</translation>
</message>
<message>
@@ -14707,15 +15375,15 @@ a:hover {
</message>
<message>
<source>No TLS Secrets</source>
- <translation type="unfinished"></translation>
+ <translation>Нет секретов TLS</translation>
</message>
<message>
<source>There are no available secrets used to decrypt TLS traffic in the capture file. Would you like to view information about how to decrypt TLS traffic on the wiki?</source>
- <translation type="unfinished"></translation>
+ <translation>В файле захвата нет доступных секретов, используемых для расшифровки трафика TLS. Вы хотите просмотреть информацию о расшифровке трафика TLS в вики?</translation>
</message>
<message>
<source>Are you sure you want to discard all decryption secrets?</source>
- <translation type="unfinished"></translation>
+ <translation>Вы уверены, что хотите выбросить все секреты расшифровки?</translation>
</message>
<message>
<source>No filter available. Try another %1.</source>
diff --git a/ui/qt/wireshark_sv.ts b/ui/qt/wireshark_sv.ts
index abe7fef8..a12781ae 100644
--- a/ui/qt/wireshark_sv.ts
+++ b/ui/qt/wireshark_sv.ts
@@ -44,8 +44,8 @@
<translation>Mappar</translation>
</message>
<message>
- <source>Filter by path</source>
- <translation>Filtrera efter sökväg</translation>
+ <source>Search Folders</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Plugins</source>
@@ -80,6 +80,14 @@
<translation>Licens</translation>
</message>
<message>
+ <source>About Logray</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Logray</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>The directory does not exist</source>
<translation>Katalogen finns inte</translation>
</message>
@@ -755,6 +763,28 @@
</message>
</context>
<context>
+ <name>CaptureCommentDialog</name>
+ <message>
+ <source>Edit Capture Comments</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add Comment</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Section %1</source>
+ <translation type="unfinished">Avsnitt %1</translation>
+ </message>
+</context>
+<context>
+ <name>CaptureCommentTabWidget</name>
+ <message>
+ <source>Comment %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>CaptureFile</name>
<message>
<source> [closing]</source>
@@ -840,10 +870,6 @@
<translation>Läsfilter:</translation>
</message>
<message>
- <source>Compress with g&amp;zip</source>
- <translation>Komprimera med g&amp;zip</translation>
- </message>
- <message>
<source>Open Capture File</source>
<oldsource>Wireshark: Open Capture File</oldsource>
<translation>Öppna fångstfil</translation>
@@ -925,8 +951,8 @@
<translation>Detaljer</translation>
</message>
<message>
- <source>Capture file comments</source>
- <translation>Fångstfilkommentarer</translation>
+ <source>Edit Comments</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Refresh</source>
@@ -937,10 +963,6 @@
<translation>Kopiera till urklipp</translation>
</message>
<message>
- <source>Save Comments</source>
- <translation>Spara kommentarer</translation>
- </message>
- <message>
<source>Capture File Properties</source>
<translation>Fångstfilegenskaper</translation>
</message>
@@ -989,10 +1011,18 @@
<translation>Första paket</translation>
</message>
<message>
+ <source>First event</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Last packet</source>
<translation>Sista paket</translation>
</message>
<message>
+ <source>Last event</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Elapsed</source>
<translation>Förflutet</translation>
</message>
@@ -1029,6 +1059,10 @@
<translation>Släppta paket</translation>
</message>
<message>
+ <source>Dropped events</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Capture filter</source>
<translation>Fångstfilter</translation>
</message>
@@ -1041,6 +1075,10 @@
<translation>Storleksgräns på paket (snaplen)</translation>
</message>
<message>
+ <source>Event size limit (snaplen)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>none</source>
<translation>ingen</translation>
</message>
@@ -1049,6 +1087,26 @@
<translation>%1 byte</translation>
</message>
<message>
+ <source>Comments</source>
+ <translation type="unfinished">Kommentarer</translation>
+ </message>
+ <message>
+ <source>Comment %1: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Decryption Secrets</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation type="unfinished">Typ</translation>
+ </message>
+ <message>
+ <source>Size</source>
+ <translation type="unfinished">Storlek</translation>
+ </message>
+ <message>
<source>Statistics</source>
<translation>Statistik</translation>
</message>
@@ -1073,6 +1131,10 @@
<translation>Paket</translation>
</message>
<message>
+ <source>Events</source>
+ <translation type="unfinished">Händelser</translation>
+ </message>
+ <message>
<source>Time span, s</source>
<translation>Tidsintervall, s</translation>
</message>
@@ -1085,6 +1147,10 @@
<translation>Genomsnittlig paketstorlek, B</translation>
</message>
<message>
+ <source>Average event size, B</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Bytes</source>
<translation>Byte</translation>
</message>
@@ -1097,14 +1163,14 @@
<translation>Genomsnittligt bitar/s</translation>
</message>
<message>
- <source>Section Comment</source>
- <translation>Avsnittskommentar</translation>
- </message>
- <message>
<source>Packet Comments</source>
<translation>Paketkommentarer</translation>
</message>
<message>
+ <source>Event Comments</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;p&gt;Frame %1: </source>
<translation>&lt;p&gt;Ram %1:</translation>
</message>
@@ -1116,6 +1182,12 @@
</translation>
</message>
+ <message>
+ <source>Created by Logray %1
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>CaptureFilterCombo</name>
@@ -1343,6 +1415,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid hel timma.</translation>
</message>
<message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for some more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enable monitor mode on all 802.11 interfaces</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>compression</source>
<translation>komprimering</translation>
</message>
@@ -1355,6 +1435,30 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>gzip</translation>
</message>
<message>
+ <source>File infix pattern</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;In multiple file mode, the date and time and file index number are inserted between filename template and any suffix. Select their order.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>YYYYmmDDHHMMSS_NNNNN</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Date and time before the file index number. This causes files to sort in creation time order, and keeps files from the same batch closely ordered.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>NNNNN_YYYYmmDDHHMMSS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;File index number before the date and time. This is the historic Wireshark ordering.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;After capturing has switched to the next file and the given number of files has exceeded, the oldest file will be removed.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Efter att infångandet har bytt till nästa fil och det angivna antalet filer har överskridits tas den äldsta filen bort.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1443,6 +1547,10 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sluta fånga efter att det angivna antalet filer har skapats.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
+ <source>Stop capturing after the specified number of files have been created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Stop capturing after the specified amount of data has been captured.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sluta fånga efter att den angivna mängden data har infångats.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1503,8 +1611,8 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Fel</translation>
</message>
<message>
- <source>Multiple files: Requested filesize too large. The filesize cannot be greater than 2 GiB.</source>
- <translation>Flera filer: den begärda filstorleken är för stor. Filstorleken får inte vara större än 2 GiB.</translation>
+ <source>Multiple files: Requested filesize too large. The filesize cannot be greater than 2 TB.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Multiple files: No capture file name given. You must specify a filename if you want to use multiple files.</source>
@@ -1534,6 +1642,14 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Fånga paket i promiskuöst läge</translation>
</message>
<message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Capture packets in monitor mode on 802.11 devices</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Capture packets in the next-generation capture file format.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Fånga paket i nästa generations format för fångstfiler.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1761,6 +1877,14 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Uppslagen</translation>
</message>
<message>
+ <source>Width</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Alignment</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;Show human-readable strings instead of raw values for fields. Only applicable to custom columns with fields that have value strings.&lt;/html&gt;</source>
<translation>&lt;html&gt;Visa mänskligt läsbara strängar istället för råa värden för fält. Endast tillämpligt på anpassade kolumner med fält som har värdesträngar.&lt;/html&gt;</translation>
</message>
@@ -1808,6 +1932,25 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
</message>
</context>
<context>
+ <name>CompressionGroupBox</name>
+ <message>
+ <source>Compression options</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Uncompressed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Compress with g&amp;zip</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Compress with &amp;LZ4</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>ConversationDataModel</name>
<message>
<source>Address A</source>
@@ -1847,7 +1990,7 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
</message>
<message>
<source>Packets B </source>
- <translation type="unfinished"></translation>
+ <translation>Paket B</translation>
</message>
<message>
<source>Bytes B </source>
@@ -1874,6 +2017,10 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Bitar/s B</translation>
</message>
<message>
+ <source>Flows</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Total Packets</source>
<translation>Totalt antal paket</translation>
</message>
@@ -1988,23 +2135,31 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Kopiera paketbyte som en hex-dump.</translation>
</message>
<message>
- <source>…as Printable Text</source>
+ <source>…as MIME Data</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Copy only the printable text in the packet.</source>
+ <source>…as C String</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>…as MIME Data</source>
+ <source>Copy packet bytes as printable ASCII characters and escape sequences.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>…as C String</source>
+ <source>…as Go literal</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Copy packet bytes as printable ASCII characters and escape sequences.</source>
+ <source>Copy packet bytes as Go literal.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>…as C Array</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as C Array.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2012,16 +2167,32 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>… som en hex-ström</translation>
</message>
<message>
+ <source>…as UTF-8 Text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as text, treating as UTF-8.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>…as ASCII Text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as text, treating as ASCII.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Copy packet bytes as a stream of hex.</source>
<translation>Kopiera paketbyte som en ström av hex.</translation>
</message>
<message>
<source>…as a Base64 String</source>
- <translation type="unfinished"></translation>
+ <translation>… som en Base64-sträng</translation>
</message>
<message>
<source>Copy packet bytes as a base64 encoded string.</source>
- <translation type="unfinished"></translation>
+ <translation>Kopiera paketbyte som en Base64-kodad sträng.</translation>
</message>
<message>
<source>Copy packet bytes as application/octet-stream MIME data.</source>
@@ -2173,7 +2344,7 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
</message>
<message>
<source>Invalid filter: </source>
- <translation type="unfinished">Felaktigt filter: </translation>
+ <translation>Felaktigt filter: </translation>
</message>
<message>
<source>Save this filter</source>
@@ -2325,7 +2496,7 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
</message>
<message>
<source>Dissector Description</source>
- <translation type="unfinished"></translation>
+ <translation>Dissekeringsbeskrivning</translation>
</message>
<message>
<source>Integer</source>
@@ -2470,11 +2641,11 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
</message>
<message>
<source>Latitude</source>
- <translation type="unfinished"></translation>
+ <translation>Latitud</translation>
</message>
<message>
<source>Longitude</source>
- <translation type="unfinished"></translation>
+ <translation>Longitud</translation>
</message>
<message>
<source>AS Number</source>
@@ -2807,6 +2978,10 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<source>Display filter:</source>
<translation>Visningsfilter:</translation>
</message>
+ <message>
+ <source>Export PDUs</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>ExtArgSelector</name>
@@ -2846,10 +3021,6 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Starta</translation>
</message>
<message>
- <source>Save</source>
- <translation>Spara</translation>
- </message>
- <message>
<source>Default</source>
<translation>Standard</translation>
</message>
@@ -2991,6 +3162,14 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Visningsfilter</translation>
</message>
<message>
+ <source>Display Filter Macros</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>New macro</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Open </source>
<translation>Öppna </translation>
</message>
@@ -3074,10 +3253,18 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<context>
<name>FilterListModel</name>
<message>
+ <source>Macro Name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Filter Name</source>
<translation>Filternamn</translation>
</message>
<message>
+ <source>Macro Expression</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Filter Expression</source>
<translation>Filteruttryck</translation>
</message>
@@ -3163,22 +3350,10 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<context>
<name>FolderListModel</name>
<message>
- <source>&quot;File&quot; dialogs</source>
- <translation>”Arkiv”-dialoger</translation>
- </message>
- <message>
- <source>capture files</source>
- <translation>fångstfiler</translation>
- </message>
- <message>
<source>Temp</source>
<translation>Temp</translation>
</message>
<message>
- <source>untitled capture files</source>
- <translation>namnlösa fångstfiler</translation>
- </message>
- <message>
<source>Personal configuration</source>
<translation>Personlig konfiguration</translation>
</message>
@@ -3187,14 +3362,6 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Global konfiguration</translation>
</message>
<message>
- <source>dfilters, preferences, ethers, …</source>
- <translation>dfilter, inställningar, ether:ar, …</translation>
- </message>
- <message>
- <source>dfilters, preferences, manuf, …</source>
- <translation>dfilter, inställningar, manuf, …</translation>
- </message>
- <message>
<source>System</source>
<translation>System</translation>
</message>
@@ -3207,18 +3374,10 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Program</translation>
</message>
<message>
- <source>program files</source>
- <translation>programfiler</translation>
- </message>
- <message>
<source>Personal Plugins</source>
<translation>Personliga insticksmoduler</translation>
</message>
<message>
- <source>binary plugins</source>
- <translation>binära insticksmoduler</translation>
- </message>
- <message>
<source>Global Plugins</source>
<translation>Globala insticksmoduler</translation>
</message>
@@ -3232,6 +3391,30 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
</message>
<message>
<source>Lua scripts</source>
+ <translation>Lua-skript</translation>
+ </message>
+ <message>
+ <source>&quot;File&quot; dialog location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Capture files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Untitled capture files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Preferences, profiles, manuf, …</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Program files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Binary plugins</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -3239,7 +3422,7 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Personlig extcap-sökväg</translation>
</message>
<message>
- <source>external capture (extcap) plugins</source>
+ <source>External capture (extcap) plugins</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -3363,6 +3546,24 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
</translation>
</message>
<message>
+ <source>Event %1. </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;reads&lt;/span&gt;, </source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;writes&lt;/span&gt;, </source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
<source> Click to select.</source>
<translation>Klicka för att välja.</translation>
</message>
@@ -3392,6 +3593,18 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
</message>
<message>
<source>%1 stream not found on the selected packet.</source>
+ <translation>%1-strömmar fanns inte i det valda paketet.</translation>
+ </message>
+ <message>
+ <source>Read activity(%6)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Write activity(%6)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Entire I/O activity (%1)</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -3410,10 +3623,6 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<source>Save Stream Content As…</source>
<translation>Spara ströminnehållet som …</translation>
</message>
- <message>
- <source>[Stream output truncated]</source>
- <translation>[Strömutdatan avhuggen]</translation>
- </message>
<message numerus="yes">
<source>%Ln total stream(s).</source>
<translation>
@@ -3423,9 +3632,9 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
</message>
<message numerus="yes">
<source>Max sub stream ID for the selected stream: %Ln</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>Maximalt underströms-ID för den valda strömmen: %Ln</numerusform>
+ <numerusform>Maximalt underströms-ID för den valda strömmen: %Ln</numerusform>
</translation>
</message>
<message>
@@ -3441,9 +3650,20 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Tips.</translation>
</message>
<message>
- <source>Show data as</source>
- <oldsource>Show and save data as</oldsource>
- <translation>Visa data som</translation>
+ <source>Show as</source>
+ <translation type="unfinished">Visa som</translation>
+ </message>
+ <message>
+ <source>No delta times</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Turn delta times</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All delta times</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Stream</source>
@@ -3458,11 +3678,22 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Sök:</translation>
</message>
<message>
+ <source>Case sensitive</source>
+ <translation type="unfinished">Skiftlägeskänsligt</translation>
+ </message>
+ <message>
<source>Find &amp;Next</source>
<translation>Sök &amp;nästa</translation>
</message>
</context>
<context>
+ <name>FollowStreamText</name>
+ <message>
+ <source>[Stream output truncated]</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FontColorPreferencesFrame</name>
<message>
<source>Frame</source>
@@ -3798,28 +4029,27 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <source>Remove this graph.</source>
- <oldsource>Remove this dissection behavior.</oldsource>
- <translation>Ta bort denna graf.</translation>
- </message>
- <message>
<source>Add a new graph.</source>
<translation>Lägg till en ny graf.</translation>
</message>
<message>
- <source>Duplicate this graph.</source>
- <translation>Dubblera denna graf.</translation>
- </message>
- <message>
<source>Clear all graphs.</source>
<translation>Nollställ alla grafer.</translation>
</message>
<message>
- <source>Move this graph upwards.</source>
+ <source>Remove the selected graph(s).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Duplicate the selected graph(s).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move the selected graph(s) upwards.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Move this graph downwards.</source>
+ <source>Move the selected graph(s) downwards.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -3863,10 +4093,6 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation type="unfinished"></translation>
</message>
<message>
- <source>Reset</source>
- <translation>Återställ</translation>
- </message>
- <message>
<source>Reset Graph</source>
<translation>Återställ grafen</translation>
</message>
@@ -4080,6 +4306,42 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Kopiera grafer från en annan profil.</translation>
</message>
<message>
+ <source>1 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>2 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>5 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>10 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>20 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>50 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>100 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>200 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>500 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>1 ms</source>
<translation>1 ms</translation>
</message>
@@ -4124,6 +4386,14 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>5 s</translation>
</message>
<message>
+ <source>2 min</source>
+ <translation type="unfinished">10 min {2 ?}</translation>
+ </message>
+ <message>
+ <source>5 min</source>
+ <translation type="unfinished">10 min {5 ?}</translation>
+ </message>
+ <message>
<source>Wireshark I/O Graphs: %1</source>
<translation>Wireshark I/O-grafer: %1</translation>
</message>
@@ -4136,6 +4406,14 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation type="unfinished"></translation>
</message>
<message>
+ <source>All packets</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All events</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>All Packets</source>
<translation>Alla paket</translation>
</message>
@@ -4148,7 +4426,7 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation type="unfinished"></translation>
</message>
<message>
- <source>Access Denied</source>
+ <source>All Execs</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -4196,6 +4474,34 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Klicka för att välja en del av grafen.</translation>
</message>
<message>
+ <source>%1 Intervals </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to top left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to top center</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to top right</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to bottom left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to bottom center</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to bottom right</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Portable Document Format (*.pdf)</source>
<translation>Portable Document Format (*.pdf)</translation>
</message>
@@ -4948,6 +5254,13 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
</message>
</context>
<context>
+ <name>InterfaceTreeDelegate</name>
+ <message>
+ <source>default</source>
+ <translation type="unfinished">standard</translation>
+ </message>
+</context>
+<context>
<name>InterfaceTreeModel</name>
<message>
<source>Show</source>
@@ -5898,11 +6211,11 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
</message>
<message>
<source>Maximum number of cached rows (affects sorting)</source>
- <translation type="unfinished"></translation>
+ <translation>Maximalt antal cachade rader (påverkar sortering)</translation>
</message>
<message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;If more than this many rows are displayed, then sorting by columns that require packet dissection will be disabled. Increasing this number increases memory consumption by caching column values.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Om mer än så här många rader visas kommer sortering enligt kolumner som kräver paketdissekering att avaktiveras. Att öka detta tal ökar minnesförbrukningen genom att kolumnvärden cachas.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<source>Enable mouse-over colorization</source>
@@ -5924,8 +6237,8 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<context>
<name>LteMacStatisticsDialog</name>
<message>
- <source>LTE Mac Statistics</source>
- <translation>LTE Mac-statistik</translation>
+ <source>LTE/NR Mac Statistics</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Include SR frames in filter</source>
@@ -6229,12 +6542,12 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Sekvensnummer</translation>
</message>
<message>
- <source>LTE RLC Graph (UE=%1 chan=%2%3 %4 - %5)</source>
- <translation>LTE RLC-graf (UE=%1 kan=%2%3 %4 - %5)</translation>
+ <source>%1 RLC Graph (UE=%2 chan=%3%4 %5 - %6)</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>LTE RLC Graph - no channel selected</source>
- <translation>LTE RLC-graf – ingen kanal vald</translation>
+ <source>3GPP RLC Graph - no channel selected</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Save As…</source>
@@ -6288,8 +6601,8 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<context>
<name>LteRlcStatisticsDialog</name>
<message>
- <source>LTE RLC Statistics</source>
- <translation>LTE RLC-statistik</translation>
+ <source>3GPP RLC Statistics</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Include SR frames in filter</source>
@@ -6375,6 +6688,10 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Profil: %1</translation>
</message>
<message>
+ <source> %1 Displayed: %2 (%3%)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Manage Profiles…</source>
<translation>Hantera profiler …</translation>
</message>
@@ -6436,6 +6753,13 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<numerusform>%Ln byte</numerusform>
</translation>
</message>
+ <message numerus="yes">
+ <source>%Ln bit(s)</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
<message>
<source>Byte %1</source>
<translation>Byte %1</translation>
@@ -6449,9 +6773,12 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Välj paket: %1 %2</translation>
</message>
<message>
- <source>Packets: %1 %4 Displayed: %2 (%3%)</source>
- <oldsource>Packets: %1 %4 Displayed: %2 %4 Marked: %3</oldsource>
- <translation>Paket: %1 %4 Visat: %2 (%3 %)</translation>
+ <source>Selected Event: %1 %2 </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Events: %1</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source> %1 Selected: %2 (%3%)</source>
@@ -6483,20 +6810,24 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Inga paket</translation>
</message>
<message>
- <source>From Zip File...</source>
+ <source>No Events</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <source>From Zip File...</source>
+ <translation>Från en zip-fil …</translation>
+ </message>
+ <message>
<source>From Directory...</source>
- <translation type="unfinished"></translation>
+ <translation>Från en katalog …</translation>
</message>
<message>
<source>Selected Personal Profile...</source>
- <translation type="unfinished"></translation>
+ <translation>Vald personlig profil …</translation>
</message>
<message>
<source>All Personal Profiles...</source>
- <translation type="unfinished"></translation>
+ <translation>Alla personliga profiler …</translation>
</message>
<message>
<source>Packets: %1</source>
@@ -6515,6 +6846,13 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
</message>
</context>
<context>
+ <name>MainWindow</name>
+ <message>
+ <source>Display filter as %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>MainWindowPreferencesFrame</name>
<message>
<source>Frame</source>
@@ -6546,6 +6884,10 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Den senast använda mappen</translation>
</message>
<message>
+ <source>The current working directory</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Show up to</source>
<translation>Visa upp till</translation>
</message>
@@ -6976,6 +7318,10 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Visa fältvärden</translation>
</message>
<message>
+ <source>Refresh</source>
+ <translation type="unfinished">Uppdatera</translation>
+ </message>
+ <message>
<source>Save Diagram As…</source>
<translation>Spara diagrammet som …</translation>
</message>
@@ -7023,6 +7369,10 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Visa paketbyte</translation>
</message>
<message>
+ <source>Layout:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Packet %1</source>
<translation>Paket %1</translation>
</message>
@@ -7045,6 +7395,13 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<numerusform>%Ln byte</numerusform>
</translation>
</message>
+ <message numerus="yes">
+ <source>%Ln bit(s)</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
</context>
<context>
<name>PacketFormatGroupBox</name>
@@ -7203,11 +7560,11 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<name>PacketListModel</name>
<message>
<source>Column</source>
- <translation type="unfinished"></translation>
+ <translation>Kolumn</translation>
</message>
<message>
<source>%1 can only be sorted with %2 or fewer visible rows; increase cache size in Layout preferences</source>
- <translation type="unfinished"></translation>
+ <translation>%1 kan bara sorteras med %2 eller färre synliga rader; öka cachestorleken i inställningarna av layout</translation>
</message>
<message>
<source>Sorting &quot;%1&quot;…</source>
@@ -7215,7 +7572,7 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
</message>
<message>
<source>Sorting …</source>
- <translation type="unfinished"></translation>
+ <translation>Sortering …</translation>
</message>
</context>
<context>
@@ -7504,10 +7861,22 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Kopiera denna profil.</translation>
</message>
<message>
+ <source>The number of packets or events to check for automatic profile switching.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Auto switch packet limit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Configuration Profiles</source>
<translation>Konfigurationsprofiler</translation>
</message>
<message>
+ <source>Auto switch event limit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Import</source>
<comment>noun</comment>
<translation>Import</translation>
@@ -7519,22 +7888,22 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
</message>
<message>
<source>From Zip File...</source>
- <translation type="unfinished"></translation>
+ <translation>Från en zip-fil …</translation>
</message>
<message>
<source>From Directory...</source>
- <translation type="unfinished"></translation>
+ <translation>Från en katalog …</translation>
</message>
<message numerus="yes">
<source>%Ln Selected Personal Profile(s)...</source>
- <translation type="unfinished">
- <numerusform></numerusform>
- <numerusform></numerusform>
+ <translation>
+ <numerusform>%Ln vald personlig profil …</numerusform>
+ <numerusform>%Ln valda personliga profiler …</numerusform>
</translation>
</message>
<message>
<source>All Personal Profiles...</source>
- <translation type="unfinished"></translation>
+ <translation>Alla personliga profiler …</translation>
</message>
<message>
<source>New profile</source>
@@ -7676,6 +8045,10 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>borttagen</translation>
</message>
<message>
+ <source>Auto Switch Filter</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>copy</source>
<comment>noun</comment>
<translation>kopia</translation>
@@ -8035,6 +8408,10 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Fönsterstorlek (B)</translation>
</message>
<message>
+ <source>Unacked (Outstanding) Bytes (B)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>[no capture file]</source>
<translation>[ingen fångstfil]</translation>
</message>
@@ -8195,6 +8572,14 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Saknad markör?</translation>
</message>
<message>
+ <source>LTE</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>NR</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>C-RNTI</source>
<translation>C-RNTI</translation>
</message>
@@ -8215,6 +8600,10 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>UEId</translation>
</message>
<message>
+ <source>RAT</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>UL Frames</source>
<translation>UL-ramar</translation>
</message>
@@ -8438,12 +8827,72 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<source>Browse…</source>
<translation>Bläddra…</translation>
</message>
+ <message>
+ <source>PACKETS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>EVENTS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>BYTES</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>BITS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>COUNT FRAMES</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>COUNT FIELDS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>SUM</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>MAX</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>MIN</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>AVERAGE</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>THROUGHPUT</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>LOAD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Left</source>
+ <translation type="unfinished">Vänster</translation>
+ </message>
+ <message>
+ <source>Center</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Right</source>
+ <translation type="unfinished">Höger</translation>
+ </message>
</context>
<context>
- <name>QObject::QObject</name>
+ <name>QObject::QObject::QObject</name>
<message>
<source>CCCH</source>
- <translation>CCCH</translation>
+ <translation type="unfinished">CCCH</translation>
</message>
</context>
<context>
@@ -8541,6 +8990,13 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
</message>
</context>
<context>
+ <name>ResizeHeaderView</name>
+ <message>
+ <source>Resize all %1 to contents</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>ResolvedAddressesDialog</name>
<message>
<source>Dialog</source>
@@ -8656,6 +9112,14 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Uppslagna adresser</translation>
</message>
<message>
+ <source>Copy</source>
+ <translation type="unfinished">Kopiera</translation>
+ </message>
+ <message>
+ <source>Save as…</source>
+ <translation type="unfinished">Spara som …</translation>
+ </message>
+ <message>
<source># Resolved addresses found in %1</source>
<translation># Uppslagna adresser hittade i %1</translation>
</message>
@@ -8669,6 +9133,61 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
</message>
</context>
<context>
+ <name>ResolvedAddressesView</name>
+ <message>
+ <source>as Plain Text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy selected rows</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy table</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>as CSV</source>
+ <translation type="unfinished">som CSV</translation>
+ </message>
+ <message>
+ <source>as JSON</source>
+ <translation type="unfinished">som JSON</translation>
+ </message>
+ <message>
+ <source>Save selected rows as…</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save table as…</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save Resolved Addresses As…</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Plain text (*.txt)</source>
+ <translation type="unfinished">Vanlig text (*.txt)</translation>
+ </message>
+ <message>
+ <source>CSV Document (*.csv)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>JSON Document (*.json)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation type="unfinished">Varning</translation>
+ </message>
+ <message>
+ <source>Unable to save %1: %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>ResponseTimeDelayDialog</name>
<message>
<source>%1 Response Time Delay Statistics</source>
@@ -10343,6 +10862,10 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Paketbyte</translation>
</message>
<message>
+ <source>&lt;b&gt;Options:&lt;/b&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for strings containing narrow (UTF-8 and ASCII) or wide (UTF-16) characters.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sök efter strängar som innehåller smala (UTF-8 och ASCII) eller breda (UTF-16) tecken.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -10363,6 +10886,18 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Skiftlägeskänsligt</translation>
</message>
<message>
+ <source>Backwards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for a subsequent occurrence in the current packet before advancing to the next packet.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Multiple occurrences</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5), a plain string (e.g. My String) or a regular expression (e.g. colou?r).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<oldsource>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5) or a plain string (e.g. My String).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</oldsource>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Sök efter data med användning av visningsfiltersyntax (t.ex. ip.addr==10.1.1.1), en hexadecimal sträng (t.ex. fffffda5), en enkel sträng (t.ex. Min Sträng) eller ett reguljärt uttryck (t.ex. schyss?t).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
@@ -10400,6 +10935,22 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Felaktigt filter.</translation>
</message>
<message>
+ <source>Event List</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Event Details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Event Bytes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search the Info column of the event list (summary pane), decoded event display labels (tree view pane) or the ASCII-converted event data (hex view pane).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>That filter doesn&apos;t test anything.</source>
<translation>Det filtret testar inte någonting.</translation>
</message>
@@ -10843,6 +11394,10 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Sök:</translation>
</message>
<message>
+ <source>Case sensitive</source>
+ <translation type="unfinished">Skiftlägeskänsligt</translation>
+ </message>
+ <message>
<source>Find &amp;Next</source>
<translation>Sök &amp;nästa</translation>
</message>
@@ -10871,7 +11426,7 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
</message>
<message>
<source>Percent-Encoding</source>
- <translation type="unfinished"></translation>
+ <translation>Procentkodning</translation>
</message>
<message>
<source>Quoted-Printable</source>
@@ -10938,14 +11493,22 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Spara som …</translation>
</message>
<message>
+ <source>Decoded as %1.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Save Selected Packet Bytes As…</source>
<translation>Spara valda paketbyte som …</translation>
</message>
+ <message>
+ <source>compressed %1</source>
+ <translation type="unfinished"></translation>
+ </message>
<message numerus="yes">
- <source>Displaying %Ln byte(s).</source>
- <translation>
- <numerusform>Visar %Ln byte.</numerusform>
- <numerusform>Visar %Ln byte.</numerusform>
+ <source>Using %Ln byte(s).</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
</translation>
</message>
<message>
@@ -11045,6 +11608,10 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<source>Display filter:</source>
<translation>Visningsfilter:</translation>
</message>
+ <message>
+ <source>Strip Headers</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>SupportedProtocolsDialog</name>
@@ -11096,7 +11663,7 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<name>SyntaxLineEdit</name>
<message>
<source>Invalid filter: %1</source>
- <translation type="unfinished"></translation>
+ <translation>Felaktigt filter: %1</translation>
</message>
<message>
<source>&quot;%1&quot; is deprecated in favour of &quot;%2&quot;. See Help section 6.4.8 for details.</source>
@@ -11733,7 +12300,7 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
</message>
<message>
<source>Save</source>
- <translation type="unfinished">Spara</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>TLS Keylog file</source>
@@ -12018,22 +12585,20 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Skapa en ny post.</translation>
</message>
<message>
- <source>Remove this entry.</source>
- <oldsource>Remove this profile.</oldsource>
- <translation>Ta bort denna post.</translation>
+ <source>Remove the selected entry(ies).</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Copy this entry.</source>
- <oldsource>Copy this profile.</oldsource>
- <translation>Kopiera denna post.</translation>
+ <source>Copy the selected entry(ies).</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry up.</source>
- <translation>Flytta upp posten.</translation>
+ <source>Move the selected entry(ies) up.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry down.</source>
- <translation>Flytta ned posten.</translation>
+ <source>Move the selected entry(ies) down.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Clear all entries.</source>
@@ -12059,20 +12624,20 @@ Till exempel, använd 1 timma för att en ny fil skall skapas varje timma vid he
<translation>Skapa en ny post.</translation>
</message>
<message>
- <source>Remove this entry.</source>
- <translation>Ta bort denna post.</translation>
+ <source>Remove the selected entry(ies).</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Copy this entry.</source>
- <translation>Kopiera denna post.</translation>
+ <source>Copy the selected entry(ies).</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry up.</source>
- <translation>Flytta upp posten.</translation>
+ <source>Move the selected entry(ies) up.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry down.</source>
- <translation>Flytta ned posten.</translation>
+ <source>Move the selected entry(ies) down.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Clear all entries.</source>
@@ -12371,7 +12936,49 @@ a:hover {
&lt;/tr&gt;&lt;/table&gt;
&lt;/body&gt;&lt;/html&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;html&gt;&lt;head&gt;
+&lt;style&gt;
+a:link {
+ color: palette(text);
+ text-decoration: none;
+}
+a:hover {
+ color: palette(text);
+ text-decoration: underline;
+}
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+
+&lt;table&gt;&lt;tr&gt;
+&lt;th&gt;&lt;a href=&quot;https://www.wireshark.org/docs/wsug_html_chunked/&quot;&gt;Användarguide&lt;/a&gt;&lt;/th&gt;
+
+&lt;td style=&quot;padding-left: 8px; padding-right: 8px;&quot;&gt;·&lt;/td&gt;
+
+&lt;th&gt;&lt;a href=&quot;https://gitlab.com/wireshark/wireshark/-/wikis/&quot;&gt;Wiki&lt;/a&gt;&lt;/th&gt;
+
+&lt;td style=&quot;padding-left: 8px; padding-right: 8px;&quot;&gt;·&lt;/td&gt;
+
+&lt;th&gt;&lt;a href=&quot;https://ask.wireshark.org/&quot;&gt;Frågor och svar&lt;/a&gt;&lt;/th&gt;
+
+&lt;td style=&quot;padding-left: 8px; padding-right: 8px;&quot;&gt;·&lt;/td&gt;
+
+&lt;th&gt;&lt;a href=&quot;https://www.wireshark.org/lists/&quot;&gt;Sändlistor&lt;/a&gt;&lt;/th&gt;
+
+&lt;td style=&quot;padding-left: 8px; padding-right: 8px;&quot;&gt;·&lt;/td&gt;
+
+&lt;th&gt;&lt;a href=&quot;https://sharkfest.wireshark.org/&quot;&gt;SharkFest&lt;/a&gt;&lt;/th&gt;
+
+&lt;td style=&quot;padding-left: 8px; padding-right: 8px;&quot;&gt;·&lt;/td&gt;
+
+&lt;th&gt;&lt;a href=&quot;https://discord.com/invite/ts9GZCjGj5&quot;&gt;Wireshark Discord&lt;/a&gt;&lt;/th&gt;
+
+&lt;td style=&quot;padding-left: 8px; padding-right: 8px;&quot;&gt;·&lt;/td&gt;
+
+&lt;th&gt;&lt;a href=&quot;https://wiresharkfoundation.org/donate/&quot;&gt;Donate&lt;/a&gt;&lt;/th&gt;
+
+&lt;/tr&gt;&lt;/table&gt;
+&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<source>Show in Finder</source>
@@ -12401,10 +13008,18 @@ a:hover {
<translation>Du luktar på limmet som håller samman Internet med Wireshark</translation>
</message>
<message>
+ <source>You are sniffing the glue that holds your system together using Logray </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>You are running Wireshark </source>
<translation>Du kör Wireshark</translation>
</message>
<message>
+ <source>You are running Logray </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source> You receive automatic updates.</source>
<translation>Du får automatiska uppdateringar.</translation>
</message>
@@ -12681,14 +13296,6 @@ a:hover {
<translation>Inga filer hittades</translation>
</message>
<message>
- <source>&amp;Contents</source>
- <translation>&amp;Innehåll</translation>
- </message>
- <message>
- <source>Wireshark Filter</source>
- <translation>Wireshark-filter</translation>
- </message>
- <message>
<source>TShark</source>
<translation>TShark</translation>
</message>
@@ -12938,7 +13545,7 @@ a:hover {
</message>
<message>
<source>&amp;DTN</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;DTN</translation>
</message>
<message>
<source>Osmux</source>
@@ -12954,10 +13561,6 @@ a:hover {
<translation>Verktygsrad för trådlöst</translation>
</message>
<message>
- <source>Help contents</source>
- <translation>Hjälpinnehåll</translation>
- </message>
- <message>
<source>FAQs</source>
<translation>Frågor och svar</translation>
</message>
@@ -13078,11 +13681,6 @@ a:hover {
<translation>Sök efter föregående paket</translation>
</message>
<message>
- <source>&amp;Mark/Unmark Packet(s)</source>
- <oldsource>&amp;Mark/Unmark Packet</oldsource>
- <translation>&amp;Markera/avmarkera paket</translation>
- </message>
- <message>
<source>Mark All Displayed</source>
<translation>Markera alla visade</translation>
</message>
@@ -13111,11 +13709,6 @@ a:hover {
<translation>Gå till föregående märkta paket</translation>
</message>
<message>
- <source>&amp;Ignore/Unignore Packet(s)</source>
- <oldsource>&amp;Ignore/Unignore Packet</oldsource>
- <translation>&amp;Ignorera/avignorera paket</translation>
- </message>
- <message>
<source>Ignore All Displayed</source>
<translation>Ignorera alla visade</translation>
</message>
@@ -13405,11 +13998,11 @@ a:hover {
</message>
<message>
<source>&amp;LTP</source>
- <translation type="unfinished"></translation>
+ <translation>&amp;LTP</translation>
</message>
<message>
<source>LTP segment and block statistics</source>
- <translation type="unfinished"></translation>
+ <translation>LTP-segment- och blockstatistik</translation>
</message>
<message>
<source>&amp;ISUP Messages</source>
@@ -13556,10 +14149,6 @@ a:hover {
<translation>Återställ layouten</translation>
</message>
<message>
- <source>Reset appearance layout to default size</source>
- <translation>Återställ utseendelayouten till sin standardstorlek</translation>
- </message>
- <message>
<source>Seconds Since First Captured Packet</source>
<translation>Sekunder sedan första fångade paket</translation>
</message>
@@ -13720,20 +14309,28 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
- <source>TLS Keylog Launcher</source>
+ <source>&amp;Options…</source>
+ <translation>&amp;Alternativ …</translation>
+ </message>
+ <message>
+ <source>&amp;3GPP Uu</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Release Notes</source>
+ <source>&amp;Wireless</source>
+ <translation>&amp;Trådlöst</translation>
+ </message>
+ <message>
+ <source>&amp;User&apos;s Guide</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Options…</source>
- <translation>&amp;Alternativ …</translation>
+ <source>Wireshark User&apos;s Guide</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Wireless</source>
- <translation>&amp;Trådlöst</translation>
+ <source>Display Filters</source>
+ <translation type="unfinished">Visningsfilter</translation>
</message>
<message>
<source>Capture &amp;Filters…</source>
@@ -13780,10 +14377,18 @@ a:hover {
<translation>Sök f&amp;öregående</translation>
</message>
<message>
+ <source>&amp;Mark/Unmark Selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Mark or unmark each selected packet</source>
<translation>Markera eller avmarkera varje valt paket</translation>
</message>
<message>
+ <source>&amp;Ignore/Unignore Selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Ignore or unignore each selected packet</source>
<translation>Ignorera eller avignorera varje valt paket</translation>
</message>
@@ -13824,6 +14429,18 @@ a:hover {
<translation>TCP-genomströmning</translation>
</message>
<message>
+ <source>General</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Query-Response</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>DNS Query-Response Statistics</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Request Sequences</source>
<translation>Begärandesekvenser</translation>
</message>
@@ -13832,6 +14449,14 @@ a:hover {
<translation>HTTP-begärandesekvenser</translation>
</message>
<message>
+ <source>E2AP</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>E2AP Messages</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Decode &amp;As…</source>
<translation>Avkoda &amp;som …</translation>
</message>
@@ -13892,6 +14517,10 @@ a:hover {
<translation>Normal storlek</translation>
</message>
<message>
+ <source>Reset layout to default size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Resize Columns</source>
<translation>Ändra storlek på kolumner</translation>
</message>
@@ -14150,6 +14779,14 @@ a:hover {
<translation>Gå till paketet refererat av det valda fältet.</translation>
</message>
<message>
+ <source>TLS Keylog Launcher</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Release Notes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&amp;VoIP Calls</source>
<translation>&amp;VoIP-anrop</translation>
</message>
@@ -14182,10 +14819,6 @@ a:hover {
<translation>&amp;GSM</translation>
</message>
<message>
- <source>&amp;LTE</source>
- <translation>&amp;LTE</translation>
- </message>
- <message>
<source>&amp;MTP3</source>
<translation>&amp;MTP3</translation>
</message>
@@ -14470,6 +15103,10 @@ a:hover {
<translation>Avsluta &amp;utan att spara</translation>
</message>
<message>
+ <source>USB CDC Data</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>There is no &quot;rtp.ssrc&quot; field in this version of Wireshark.</source>
<translation>Det finns inget &quot;rtp.ssrc&quot;-fält i denna version av Wireshark.</translation>
</message>
diff --git a/ui/qt/wireshark_tr_TR.ts b/ui/qt/wireshark_tr_TR.ts
index 06f0cafa..85e0e3aa 100644
--- a/ui/qt/wireshark_tr_TR.ts
+++ b/ui/qt/wireshark_tr_TR.ts
@@ -44,8 +44,8 @@
<translation>Klasörler</translation>
</message>
<message>
- <source>Filter by path</source>
- <translation>Yola göre filtrele</translation>
+ <source>Search Folders</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Plugins</source>
@@ -80,6 +80,14 @@
<translation>Lisans</translation>
</message>
<message>
+ <source>About Logray</source>
+ <translation>Logray Hakkında</translation>
+ </message>
+ <message>
+ <source>Logray</source>
+ <translation>Logray</translation>
+ </message>
+ <message>
<source>The directory does not exist</source>
<translation>Dizin mevcut değil</translation>
</message>
@@ -730,11 +738,11 @@
</message>
<message>
<source>…as decimal</source>
- <translation type="unfinished"></translation>
+ <translation>…ondalık sayı olarak</translation>
</message>
<message>
<source>…as octal</source>
- <translation type="unfinished"></translation>
+ <translation>…sekizli olarak</translation>
</message>
<message>
<source>…as bits</source>
@@ -754,6 +762,28 @@
</message>
</context>
<context>
+ <name>CaptureCommentDialog</name>
+ <message>
+ <source>Edit Capture Comments</source>
+ <translation>Yakalama Yorumlarını Düzenle</translation>
+ </message>
+ <message>
+ <source>Add Comment</source>
+ <translation>Yorum Ekle</translation>
+ </message>
+ <message>
+ <source>Section %1</source>
+ <translation>Bölüm %1</translation>
+ </message>
+</context>
+<context>
+ <name>CaptureCommentTabWidget</name>
+ <message>
+ <source>Comment %1</source>
+ <translation>Yorum %1</translation>
+ </message>
+</context>
+<context>
<name>CaptureFile</name>
<message>
<source> [closing]</source>
@@ -839,10 +869,6 @@
<translation>Filtreyi oku:</translation>
</message>
<message>
- <source>Compress with g&amp;zip</source>
- <translation>G&amp;zip ile sıkıştır</translation>
- </message>
- <message>
<source>Open Capture File</source>
<oldsource>Wireshark: Open Capture File</oldsource>
<translation>Yakalama Dosyasını Aç</translation>
@@ -921,8 +947,8 @@
<translation>Detaylar</translation>
</message>
<message>
- <source>Capture file comments</source>
- <translation>Dosya yorumlarını yakala</translation>
+ <source>Edit Comments</source>
+ <translation>Yorumları Düzenle</translation>
</message>
<message>
<source>Refresh</source>
@@ -933,10 +959,6 @@
<translation>Panoya Kopyala</translation>
</message>
<message>
- <source>Save Comments</source>
- <translation>Yorumları Kaydet</translation>
- </message>
- <message>
<source>Capture File Properties</source>
<translation>Yakalama Dosyası Özellikleri</translation>
</message>
@@ -985,10 +1007,18 @@
<translation>İlk paket</translation>
</message>
<message>
+ <source>First event</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Last packet</source>
<translation>Son paket</translation>
</message>
<message>
+ <source>Last event</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Elapsed</source>
<translation>Geçen</translation>
</message>
@@ -1025,6 +1055,10 @@
<translation>Bırakılan paketler</translation>
</message>
<message>
+ <source>Dropped events</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Capture filter</source>
<translation>Yakalama filtresi</translation>
</message>
@@ -1037,6 +1071,10 @@
<translation>Paket boyutu sınırı (snaplen)</translation>
</message>
<message>
+ <source>Event size limit (snaplen)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>none</source>
<translation>yok</translation>
</message>
@@ -1045,6 +1083,26 @@
<translation>%1 bayt</translation>
</message>
<message>
+ <source>Comments</source>
+ <translation>Yorumlar</translation>
+ </message>
+ <message>
+ <source>Comment %1: </source>
+ <translation>Yorum %1:</translation>
+ </message>
+ <message>
+ <source>Decryption Secrets</source>
+ <translation>Şifre Çözme Sırları</translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation>Tür</translation>
+ </message>
+ <message>
+ <source>Size</source>
+ <translation>Boyut</translation>
+ </message>
+ <message>
<source>Statistics</source>
<translation>İstatistikler</translation>
</message>
@@ -1069,6 +1127,10 @@
<translation>Paketler</translation>
</message>
<message>
+ <source>Events</source>
+ <translation type="unfinished">Etkinlikler</translation>
+ </message>
+ <message>
<source>Time span, s</source>
<translation>Zaman aralığı, s</translation>
</message>
@@ -1081,6 +1143,10 @@
<translation>Ortalama paket boyutu, B</translation>
</message>
<message>
+ <source>Average event size, B</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Bytes</source>
<translation>Bayt</translation>
</message>
@@ -1093,14 +1159,14 @@
<translation>Ortalama bit/sn</translation>
</message>
<message>
- <source>Section Comment</source>
- <translation>Bölüm Yorumu</translation>
- </message>
- <message>
<source>Packet Comments</source>
<translation>Paket Yorumları</translation>
</message>
<message>
+ <source>Event Comments</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;p&gt;Frame %1: </source>
<translation>&lt;p&gt;Çerçeve %1: </translation>
</message>
@@ -1112,6 +1178,14 @@
</translation>
</message>
+ <message>
+ <source>Created by Logray %1
+
+</source>
+ <translation>Logray %1 tarafından oluşturuldu
+
+</translation>
+ </message>
</context>
<context>
<name>CaptureFilterCombo</name>
@@ -1339,6 +1413,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
Örneğin, her saat başı yeni bir dosyanın oluşturulması için 1 saat kullanın.</translation>
</message>
<message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for some more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;/html&gt;&lt;head/&gt;&lt;/body&gt;&lt;/p&gt;Genellikle bir kablosuz ağ kartı, yalnızca kendi ağ adresine gönderilen ve ondan gelen trafiği yakalar ve yalnızca &quot;sahte&quot; Ethernet başlıklarıyla &lt;em&gt;kullanıcı verisi&lt;/em&gt; trafiğini yakalar. Kablosuz ağ kartlarının &quot;görebildiği&quot; tüm trafiği yakalamak istiyorsanız veya 802.11 yönetim veya kontrol paketleri veya radyo katmanı bilgileriyle ilgileniyorsanız, bu seçeneği işaretleyin. Monitor modu, kablosuz kart ve sürücüye bağlıdır. WLAN ağlarında paket yakalama hakkında daha fazla ayrıntı için Wiki&apos;ye bakın.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>Enable monitor mode on all 802.11 interfaces</source>
+ <translation>Tüm 802.11 arayüzlerinde monitör modunu etkinleştirin</translation>
+ </message>
+ <message>
<source>compression</source>
<translation>sıkıştırma</translation>
</message>
@@ -1351,6 +1433,30 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>gzip</translation>
</message>
<message>
+ <source>File infix pattern</source>
+ <translation>Dosya ek deseni</translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;In multiple file mode, the date and time and file index number are inserted between filename template and any suffix. Select their order.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Çoklu dosya modunda, tarih ve saat ile dosya dizin numarası, dosya adı şablonu ve herhangi bir ek arasına yerleştirilir. Sıralamayı seçin.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>YYYYmmDDHHMMSS_NNNNN</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Date and time before the file index number. This causes files to sort in creation time order, and keeps files from the same batch closely ordered.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Tarih ve saat, dosya dizin numarasından önce gelir. Bu, dosyaların oluşturma zamanına göre sıralanmasına ve aynı grup dosyaların yakın bir şekilde sıralanmasına neden olur.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>NNNNN_YYYYmmDDHHMMSS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;File index number before the date and time. This is the historic Wireshark ordering.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Dosya dizin numarası tarih ve saat öncesinde. Bu, tarihsel Wireshark sıralamasıdır.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;After capturing has switched to the next file and the given number of files has exceeded, the oldest file will be removed.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Yakalama bir sonraki dosyaya geçtikten ve verilen dosya sayısı aşıldıktan sonra, en eski dosya kaldırılacaktır.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1439,6 +1545,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Belirtilen sayıda dosya oluşturulduktan sonra yakalamayı durdurun.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
+ <source>Stop capturing after the specified number of files have been created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Stop capturing after the specified amount of data has been captured.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Belirtilen miktarda veri yakalandıktan sonra yakalamayı durdurun.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1499,8 +1609,8 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Hata</translation>
</message>
<message>
- <source>Multiple files: Requested filesize too large. The filesize cannot be greater than 2 GiB.</source>
- <translation>Birden çok dosya: İstenen dosya boyutu çok büyük. Dosya boyutu 2 GiB&apos;den büyük olamaz.</translation>
+ <source>Multiple files: Requested filesize too large. The filesize cannot be greater than 2 TB.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Multiple files: No capture file name given. You must specify a filename if you want to use multiple files.</source>
@@ -1530,6 +1640,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Paketleri karışık modda yakalayın</translation>
</message>
<message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Genellikle bir kablosuz ağ kartı, yalnızca kendi ağ adresine gönderilen ve ondan gelen trafiği yakalar ve yalnızca &quot;sahte&quot; Ethernet başlıklarıyla &lt;em&gt;kullanıcı verisi&lt;/em&gt; trafiğini yakalar. Kablosuz ağ kartlarının &quot;görebildiği&quot; tüm trafiği yakalamak istiyorsanız veya 802.11 yönetim veya kontrol paketleri veya radyo katmanı bilgileriyle ilgileniyorsanız, bu seçeneği işaretleyin. Monitor modu, kablosuz kart ve sürücüye bağlıdır. WLAN ağlarında paket yakalama hakkında daha fazla ayrıntı için Wiki&apos;ye bakın.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
+ </message>
+ <message>
+ <source>Capture packets in monitor mode on 802.11 devices</source>
+ <translation>802.11 cihazlarda monitör modunda paketleri yakalayın.</translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Capture packets in the next-generation capture file format.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Paketleri yeni nesil yakalama dosyası biçiminde yakalayın.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1547,15 +1665,15 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Interval between updates (ms)</source>
- <translation type="unfinished"></translation>
+ <translation>Güncellemeler arasındaki süre (ms)</translation>
</message>
<message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;How often the capture notifies the GUI of new packets. Affects how often the GUI updates and the granularity of timers.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Yakalamanın Arayüz`e yeni paketler hakkında ne sıklıkta bildirimde bulunduğu. Arayüz`ün ne sıklıkta güncellendiğini ve zamanlayıcıların ayrıntı düzeyini etkiler.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;The interval between new packet updates. Affects how often the GUI updates and the granularity of timers.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
- <translation type="unfinished"></translation>
+ <translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Yeni paket güncellemeleri arasındaki süre. Arayüz&apos;ün ne sıklıkla güncellendiğini ve zamanlayıcıların ayrıntısını etkiler.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
<source>Don&apos;t load interfaces on startup</source>
@@ -1757,6 +1875,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Çözüldü</translation>
</message>
<message>
+ <source>Width</source>
+ <translation>Genişlik</translation>
+ </message>
+ <message>
+ <source>Alignment</source>
+ <translation>Hizalama</translation>
+ </message>
+ <message>
<source>&lt;html&gt;Show human-readable strings instead of raw values for fields. Only applicable to custom columns with fields that have value strings.&lt;/html&gt;</source>
<translation>&lt;html&gt;Alanlar için ham değerler yerine insan tarafından okunabilir dizeleri gösterin. Yalnızca değer dizeleri olan alanlara sahip özel sütunlar için geçerlidir.&lt;/html&gt;</translation>
</message>
@@ -1804,6 +1930,25 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>CompressionGroupBox</name>
+ <message>
+ <source>Compression options</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Uncompressed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Compress with g&amp;zip</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Compress with &amp;LZ4</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>ConversationDataModel</name>
<message>
<source>Address A</source>
@@ -1870,6 +2015,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Bit/s B </translation>
</message>
<message>
+ <source>Flows</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Total Packets</source>
<translation>Toplam Paket</translation>
</message>
@@ -1984,28 +2133,52 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Paket baytlarını hex dökümü olarak kopyalayın.</translation>
</message>
<message>
- <source>…as Printable Text</source>
+ <source>…as MIME Data</source>
+ <translation>…MIME Verisi</translation>
+ </message>
+ <message>
+ <source>…as C String</source>
+ <translation>…C Dizesi olarak</translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as printable ASCII characters and escape sequences.</source>
+ <translation>Paket baytlarını yazdırılabilir ASCII karakterleri ve kaçış dizilerini kopyala.</translation>
+ </message>
+ <message>
+ <source>…as Go literal</source>
+ <translation>…Go literali olarak</translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as Go literal.</source>
+ <translation>Paket baytlarını Go literali olarak kopyala.</translation>
+ </message>
+ <message>
+ <source>…as C Array</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Copy only the printable text in the packet.</source>
+ <source>Copy packet bytes as C Array.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>…as MIME Data</source>
+ <source>…as a Hex Stream</source>
+ <translation>…Hex Akışı olarak</translation>
+ </message>
+ <message>
+ <source>…as UTF-8 Text</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>…as C String</source>
+ <source>Copy packet bytes as text, treating as UTF-8.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Copy packet bytes as printable ASCII characters and escape sequences.</source>
+ <source>…as ASCII Text</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>…as a Hex Stream</source>
- <translation>…Hex Akışı olarak</translation>
+ <source>Copy packet bytes as text, treating as ASCII.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Copy packet bytes as a stream of hex.</source>
@@ -2287,11 +2460,11 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<name>DissectorSyntaxLineEdit</name>
<message>
<source>Dissector entry</source>
- <translation type="unfinished"></translation>
+ <translation>Dissektör girişi</translation>
</message>
<message>
<source>Enter a dissector %1</source>
- <translation type="unfinished"></translation>
+ <translation>Bir dissector %1 girin.</translation>
</message>
</context>
<context>
@@ -2803,6 +2976,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Display filter:</source>
<translation>Ekran filtresi:</translation>
</message>
+ <message>
+ <source>Export PDUs</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>ExtArgSelector</name>
@@ -2842,10 +3019,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Başla</translation>
</message>
<message>
- <source>Save</source>
- <translation>Kaydet</translation>
- </message>
- <message>
<source>Default</source>
<translation>Ön tanımlı</translation>
</message>
@@ -2986,6 +3159,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Ekran Filtreleri</translation>
</message>
<message>
+ <source>Display Filter Macros</source>
+ <translation>Filtre Makrolarını Görüntüle</translation>
+ </message>
+ <message>
+ <source>New macro</source>
+ <translation>Yeni makro</translation>
+ </message>
+ <message>
<source>Open </source>
<translation>Aç </translation>
</message>
@@ -3069,10 +3250,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>FilterListModel</name>
<message>
+ <source>Macro Name</source>
+ <translation>Macro Adı</translation>
+ </message>
+ <message>
<source>Filter Name</source>
<translation>Filtre Adı</translation>
</message>
<message>
+ <source>Macro Expression</source>
+ <translation>Makro İfade</translation>
+ </message>
+ <message>
<source>Filter Expression</source>
<translation>Filtre İfadesi</translation>
</message>
@@ -3158,22 +3347,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>FolderListModel</name>
<message>
- <source>&quot;File&quot; dialogs</source>
- <translation>&quot;Dosya&quot; diyalogları</translation>
- </message>
- <message>
- <source>capture files</source>
- <translation>yakalama dosyaları</translation>
- </message>
- <message>
<source>Temp</source>
<translation>Geçici</translation>
</message>
<message>
- <source>untitled capture files</source>
- <translation>başlıksız yakalama dosyaları</translation>
- </message>
- <message>
<source>Personal configuration</source>
<translation>Kişisel yapılandırma</translation>
</message>
@@ -3182,14 +3359,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Genel yapılandırma</translation>
</message>
<message>
- <source>dfilters, preferences, ethers, …</source>
- <translation>filtreler, tercihler, eterler, …</translation>
- </message>
- <message>
- <source>dfilters, preferences, manuf, …</source>
- <translation>filtreler, tercihler, üretici, …</translation>
- </message>
- <message>
<source>System</source>
<translation>Sistem</translation>
</message>
@@ -3202,18 +3371,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Uygulama</translation>
</message>
<message>
- <source>program files</source>
- <translation>program dosyaları</translation>
- </message>
- <message>
<source>Personal Plugins</source>
<translation>Kişisel Eklentiler</translation>
</message>
<message>
- <source>binary plugins</source>
- <translation>ikili eklentiler</translation>
- </message>
- <message>
<source>Global Plugins</source>
<translation>Genel Eklentiler</translation>
</message>
@@ -3230,12 +3391,36 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Lua betikleri</translation>
</message>
<message>
+ <source>&quot;File&quot; dialog location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Capture files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Untitled capture files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Preferences, profiles, manuf, …</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Program files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Binary plugins</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Personal Extcap path</source>
<translation>Kişisel Excap yolu</translation>
</message>
<message>
- <source>external capture (extcap) plugins</source>
- <translation>harici yakalama (extcap) eklentileri</translation>
+ <source>External capture (extcap) plugins</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Global Extcap path</source>
@@ -3282,7 +3467,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<name>FollowStreamAction</name>
<message>
<source>%1 Stream</source>
- <translation type="unfinished"></translation>
+ <translation>%1 Akış</translation>
</message>
</context>
<context>
@@ -3355,6 +3540,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</translation>
</message>
<message>
+ <source>Event %1. </source>
+ <translation>Etkinlik %1.</translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;reads&lt;/span&gt;, </source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;writes&lt;/span&gt;, </source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
<source> Click to select.</source>
<translation> Seçmek için tıkla.</translation>
</message>
@@ -3387,6 +3588,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Seçili pakette %1 akışı bulunamadı.</translation>
</message>
<message>
+ <source>Read activity(%6)</source>
+ <translation>Etkinliği oku(%6)</translation>
+ </message>
+ <message>
+ <source>Write activity(%6)</source>
+ <translation>Etkinlik yaz (%6)</translation>
+ </message>
+ <message>
+ <source>Entire I/O activity (%1)</source>
+ <translation>Tüm G/Ç etkinliği (%1)</translation>
+ </message>
+ <message>
<source>Entire conversation (%1)</source>
<translation>Tüm konuşma (%1)</translation>
</message>
@@ -3402,10 +3615,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Save Stream Content As…</source>
<translation>Akış İçeriğini Farklı Kaydet…</translation>
</message>
- <message>
- <source>[Stream output truncated]</source>
- <translation>[Akış çıkışı kesildi]</translation>
- </message>
<message numerus="yes">
<source>%Ln total stream(s).</source>
<translation type="unfinished">
@@ -3431,9 +3640,20 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>İpucu.</translation>
</message>
<message>
- <source>Show data as</source>
- <oldsource>Show and save data as</oldsource>
- <translation>Verileri şu şekilde göster</translation>
+ <source>Show as</source>
+ <translation>Olarak göster</translation>
+ </message>
+ <message>
+ <source>No delta times</source>
+ <translation>Delta zamanları yok</translation>
+ </message>
+ <message>
+ <source>Turn delta times</source>
+ <translation>Delta zamanlarını çevirin</translation>
+ </message>
+ <message>
+ <source>All delta times</source>
+ <translation>Tüm delta süreleri</translation>
</message>
<message>
<source>Stream</source>
@@ -3448,11 +3668,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Bul:</translation>
</message>
<message>
+ <source>Case sensitive</source>
+ <translation type="unfinished">Büyük küçük harf duyarlı</translation>
+ </message>
+ <message>
<source>Find &amp;Next</source>
<translation>Sonrakini &amp;Bul</translation>
</message>
</context>
<context>
+ <name>FollowStreamText</name>
+ <message>
+ <source>[Stream output truncated]</source>
+ <translation>[Akış çıkışı kesildi]</translation>
+ </message>
+</context>
+<context>
<name>FontColorPreferencesFrame</name>
<message>
<source>Frame</source>
@@ -3674,23 +3905,23 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<name>IOConsoleDialog</name>
<message>
<source>Dialog</source>
- <translation type="unfinished"></translation>
+ <translation>İletişim</translation>
</message>
<message>
<source>Enter code</source>
- <translation type="unfinished"></translation>
+ <translation>Kod girin</translation>
</message>
<message>
<source>Evaluate</source>
- <translation type="unfinished"></translation>
+ <translation>Değerlendir</translation>
</message>
<message>
<source>Clear</source>
- <translation type="unfinished">Temiz</translation>
+ <translation>Temizle</translation>
</message>
<message>
<source>Use %1 to evaluate.</source>
- <translation type="unfinished"></translation>
+ <translation>%1 &apos;i değerlendirmek için kullanın.</translation>
</message>
</context>
<context>
@@ -3788,29 +4019,28 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <source>Remove this graph.</source>
- <oldsource>Remove this dissection behavior.</oldsource>
- <translation>Bu grafiği kaldırın.</translation>
- </message>
- <message>
<source>Add a new graph.</source>
<translation>Yeni bir grafik ekleyin.</translation>
</message>
<message>
- <source>Duplicate this graph.</source>
- <translation>Bu grafiği çoğaltın.</translation>
- </message>
- <message>
<source>Clear all graphs.</source>
<translation>Tüm grafikleri temizle.</translation>
</message>
<message>
- <source>Move this graph upwards.</source>
- <translation>Bu grafiği yukarı doğru götür.</translation>
+ <source>Remove the selected graph(s).</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Move this graph downwards.</source>
- <translation>Bu grafiği aşağı doğru götür.</translation>
+ <source>Duplicate the selected graph(s).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move the selected graph(s) upwards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move the selected graph(s) downwards.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Mouse</source>
@@ -3853,10 +4083,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
- <source>Reset</source>
- <translation>Sıfırla</translation>
- </message>
- <message>
<source>Reset Graph</source>
<translation>Grafiği Sıfırla</translation>
</message>
@@ -4070,6 +4296,42 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Grafikleri başka bir profilden kopyalayın.</translation>
</message>
<message>
+ <source>1 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>2 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>5 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>10 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>20 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>50 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>100 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>200 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>500 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>1 ms</source>
<translation>1 ms</translation>
</message>
@@ -4114,6 +4376,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>5 san</translation>
</message>
<message>
+ <source>2 min</source>
+ <translation type="unfinished">10 dakika {2 ?}</translation>
+ </message>
+ <message>
+ <source>5 min</source>
+ <translation type="unfinished">10 dakika {5 ?}</translation>
+ </message>
+ <message>
<source>Wireshark I/O Graphs: %1</source>
<translation>Wireshark G/Ç Grafikleri: %1</translation>
</message>
@@ -4126,6 +4396,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>All packets</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All events</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>All Packets</source>
<translation>Tüm Paketler</translation>
</message>
@@ -4138,7 +4416,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
- <source>Access Denied</source>
+ <source>All Execs</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -4186,6 +4464,34 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Grafiğin bir bölümünü seçmek için tıklayın.</translation>
</message>
<message>
+ <source>%1 Intervals </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to top left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to top center</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to top right</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to bottom left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to bottom center</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to bottom right</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Portable Document Format (*.pdf)</source>
<translation>Taşınabilir Belge Formatı (*.pdf)</translation>
</message>
@@ -4938,6 +5244,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>InterfaceTreeDelegate</name>
+ <message>
+ <source>default</source>
+ <translation type="unfinished">öntanımlı</translation>
+ </message>
+</context>
+<context>
<name>InterfaceTreeModel</name>
<message>
<source>Show</source>
@@ -5912,8 +6225,8 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>LteMacStatisticsDialog</name>
<message>
- <source>LTE Mac Statistics</source>
- <translation>LTE Mac İstatistikleri</translation>
+ <source>LTE/NR Mac Statistics</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Include SR frames in filter</source>
@@ -6217,12 +6530,12 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Sıra Numarası</translation>
</message>
<message>
- <source>LTE RLC Graph (UE=%1 chan=%2%3 %4 - %5)</source>
- <translation>LTE RLC Grafiği (UE=%1 chan=%2%3 %4 - %5)</translation>
+ <source>%1 RLC Graph (UE=%2 chan=%3%4 %5 - %6)</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>LTE RLC Graph - no channel selected</source>
- <translation>LTE RLC Grafiği - kanal seçilmedi</translation>
+ <source>3GPP RLC Graph - no channel selected</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Save As…</source>
@@ -6276,8 +6589,8 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>LteRlcStatisticsDialog</name>
<message>
- <source>LTE RLC Statistics</source>
- <translation>LTE RLC İstatistikleri</translation>
+ <source>3GPP RLC Statistics</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Include SR frames in filter</source>
@@ -6363,6 +6676,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Profil: %1</translation>
</message>
<message>
+ <source> %1 Displayed: %2 (%3%)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Manage Profiles…</source>
<translation>Profilleri Yönet…</translation>
</message>
@@ -6423,6 +6740,12 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<numerusform></numerusform>
</translation>
</message>
+ <message numerus="yes">
+ <source>%Ln bit(s)</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
<message>
<source>Byte %1</source>
<translation>Bayt %1</translation>
@@ -6436,9 +6759,12 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Seçilen Paket: %1 %2 </translation>
</message>
<message>
- <source>Packets: %1 %4 Displayed: %2 (%3%)</source>
- <oldsource>Packets: %1 %4 Displayed: %2 %4 Marked: %3</oldsource>
- <translation>Paketler: %1 %4 Görüntülenen: %2 (%3%)</translation>
+ <source>Selected Event: %1 %2 </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Events: %1</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source> %1 Selected: %2 (%3%)</source>
@@ -6470,6 +6796,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Paket Yok</translation>
</message>
<message>
+ <source>No Events</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>From Zip File...</source>
<translation>Zip Dosyasından...</translation>
</message>
@@ -6501,6 +6831,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>MainWindow</name>
+ <message>
+ <source>Display filter as %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>MainWindowPreferencesFrame</name>
<message>
<source>Frame</source>
@@ -6532,6 +6869,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>En son kullanılan klasör</translation>
</message>
<message>
+ <source>The current working directory</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Show up to</source>
<translation>Kadar göster</translation>
</message>
@@ -6715,7 +7056,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Clear</source>
- <translation type="unfinished">Temiz</translation>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -6962,6 +7303,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Alan Değerlerini Göster</translation>
</message>
<message>
+ <source>Refresh</source>
+ <translation type="unfinished">Yenile</translation>
+ </message>
+ <message>
<source>Save Diagram As…</source>
<translation>Şemayı Farklı Kaydet…</translation>
</message>
@@ -7009,6 +7354,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Paket baytlarını göster</translation>
</message>
<message>
+ <source>Layout:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Packet %1</source>
<translation>Paket %1</translation>
</message>
@@ -7030,6 +7379,12 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<numerusform></numerusform>
</translation>
</message>
+ <message numerus="yes">
+ <source>%Ln bit(s)</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
</context>
<context>
<name>PacketFormatGroupBox</name>
@@ -7200,7 +7555,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Sorting …</source>
- <translation type="unfinished"></translation>
+ <translation>Sıralanıyor ...</translation>
</message>
</context>
<context>
@@ -7489,10 +7844,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Bu profili kopyalayın.</translation>
</message>
<message>
+ <source>The number of packets or events to check for automatic profile switching.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Auto switch packet limit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Configuration Profiles</source>
<translation>Yapılandırma Profilleri</translation>
</message>
<message>
+ <source>Auto switch event limit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Import</source>
<comment>noun</comment>
<translation>İçe Aktar</translation>
@@ -7656,6 +8023,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>silindi</translation>
</message>
<message>
+ <source>Auto Switch Filter</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>copy</source>
<comment>noun</comment>
<translation>kopyala</translation>
@@ -8015,6 +8386,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Pencere Boyutu (B)</translation>
</message>
<message>
+ <source>Unacked (Outstanding) Bytes (B)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>[no capture file]</source>
<translation>[yakalama dosyası yok]</translation>
</message>
@@ -8175,6 +8550,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>İşaretçi eksik mi?</translation>
</message>
<message>
+ <source>LTE</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>NR</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>C-RNTI</source>
<translation>C-RNTI</translation>
</message>
@@ -8195,6 +8578,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>UEId</translation>
</message>
<message>
+ <source>RAT</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>UL Frames</source>
<translation>YÜ Çerçeveler</translation>
</message>
@@ -8418,12 +8805,72 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Browse…</source>
<translation>Gözat…</translation>
</message>
+ <message>
+ <source>PACKETS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>EVENTS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>BYTES</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>BITS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>COUNT FRAMES</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>COUNT FIELDS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>SUM</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>MAX</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>MIN</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>AVERAGE</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>THROUGHPUT</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>LOAD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Left</source>
+ <translation type="unfinished">Sol</translation>
+ </message>
+ <message>
+ <source>Center</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Right</source>
+ <translation type="unfinished">Sağa</translation>
+ </message>
</context>
<context>
- <name>QObject::QObject</name>
+ <name>QObject::QObject::QObject</name>
<message>
<source>CCCH</source>
- <translation>CCCH</translation>
+ <translation type="unfinished">CCCH</translation>
</message>
</context>
<context>
@@ -8521,6 +8968,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>ResizeHeaderView</name>
+ <message>
+ <source>Resize all %1 to contents</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>ResolvedAddressesDialog</name>
<message>
<source>Dialog</source>
@@ -8636,6 +9090,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Çözümlenen Adresler</translation>
</message>
<message>
+ <source>Copy</source>
+ <translation type="unfinished">Kopyala</translation>
+ </message>
+ <message>
+ <source>Save as…</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source># Resolved addresses found in %1</source>
<translation># Çözülmüş adresler %1&apos;de bulundu</translation>
</message>
@@ -8649,6 +9111,61 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>ResolvedAddressesView</name>
+ <message>
+ <source>as Plain Text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy selected rows</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy table</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>as CSV</source>
+ <translation type="unfinished">CSV olarak</translation>
+ </message>
+ <message>
+ <source>as JSON</source>
+ <translation type="unfinished">JSON olarak</translation>
+ </message>
+ <message>
+ <source>Save selected rows as…</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save table as…</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save Resolved Addresses As…</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Plain text (*.txt)</source>
+ <translation type="unfinished">Düz metin (*.txt)</translation>
+ </message>
+ <message>
+ <source>CSV Document (*.csv)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>JSON Document (*.json)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation type="unfinished">Uyarı</translation>
+ </message>
+ <message>
+ <source>Unable to save %1: %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>ResponseTimeDelayDialog</name>
<message>
<source>%1 Response Time Delay Statistics</source>
@@ -10323,6 +10840,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Paket bayt</translation>
</message>
<message>
+ <source>&lt;b&gt;Options:&lt;/b&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for strings containing narrow (UTF-8 and ASCII) or wide (UTF-16) characters.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Dar (UTF-8 ve ASCII) veya geniş (UTF-16) karakterler içeren dizeleri arayın.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -10343,6 +10864,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Büyük küçük harf duyarlı</translation>
</message>
<message>
+ <source>Backwards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for a subsequent occurrence in the current packet before advancing to the next packet.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Multiple occurrences</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5), a plain string (e.g. My String) or a regular expression (e.g. colou?r).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<oldsource>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5) or a plain string (e.g. My String).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</oldsource>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Görüntü filtresi sözdizimini (ör. ip.addr==10.1.1.1), onaltılık bir dizeyi (ör. fffffda5), düz bir dizeyi (ör. My Dize) veya normal bir ifadeyi (ör. colou?r) kullanarak veri arayın.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
@@ -10380,6 +10913,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Geçersiz filtre.</translation>
</message>
<message>
+ <source>Event List</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Event Details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Event Bytes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search the Info column of the event list (summary pane), decoded event display labels (tree view pane) or the ASCII-converted event data (hex view pane).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>That filter doesn&apos;t test anything.</source>
<translation>O filtre hiçbir şeyi test etmez.</translation>
</message>
@@ -10821,6 +11370,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Bul:</translation>
</message>
<message>
+ <source>Case sensitive</source>
+ <translation type="unfinished">Büyük küçük harf duyarlı</translation>
+ </message>
+ <message>
<source>Find &amp;Next</source>
<translation>Sonrakini &amp;Bul</translation>
</message>
@@ -10915,11 +11468,19 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Farklı kaydet…</translation>
</message>
<message>
+ <source>Decoded as %1.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Save Selected Packet Bytes As…</source>
<translation>Seçili Paket Baytlarını Farklı Kaydet…</translation>
</message>
+ <message>
+ <source>compressed %1</source>
+ <translation type="unfinished"></translation>
+ </message>
<message numerus="yes">
- <source>Displaying %Ln byte(s).</source>
+ <source>Using %Ln byte(s).</source>
<translation type="unfinished">
<numerusform></numerusform>
</translation>
@@ -11021,6 +11582,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Display filter:</source>
<translation>Görüntüleme filtresi:</translation>
</message>
+ <message>
+ <source>Strip Headers</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>SupportedProtocolsDialog</name>
@@ -11709,7 +12274,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Save</source>
- <translation type="unfinished">Kaydet</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>TLS Keylog file</source>
@@ -11994,22 +12559,20 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Yeni bir giriş oluşturun.</translation>
</message>
<message>
- <source>Remove this entry.</source>
- <oldsource>Remove this profile.</oldsource>
- <translation>Bu girişi kaldırın.</translation>
+ <source>Remove the selected entry(ies).</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Copy this entry.</source>
- <oldsource>Copy this profile.</oldsource>
- <translation>Bu girişi kopyalayın.</translation>
+ <source>Copy the selected entry(ies).</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry up.</source>
- <translation>Girişi yukarı taşı.</translation>
+ <source>Move the selected entry(ies) up.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry down.</source>
- <translation>Girişi aşağı taşı.</translation>
+ <source>Move the selected entry(ies) down.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Clear all entries.</source>
@@ -12035,20 +12598,20 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Yeni bir giriş oluşturun.</translation>
</message>
<message>
- <source>Remove this entry.</source>
- <translation>Bu girişi kaldırın.</translation>
+ <source>Remove the selected entry(ies).</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Copy this entry.</source>
- <translation>Bu girişi kopyalayın.</translation>
+ <source>Copy the selected entry(ies).</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry up.</source>
- <translation>Girişi yukarı taşı.</translation>
+ <source>Move the selected entry(ies) up.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry down.</source>
- <translation>Girişi aşağı taşı.</translation>
+ <source>Move the selected entry(ies) down.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Clear all entries.</source>
@@ -12418,10 +12981,18 @@ a:üzerine gelin{
<translation>Wireshark kullanarak interneti bir arada tutan yapıştırıcıyı kokluyorsunuz </translation>
</message>
<message>
+ <source>You are sniffing the glue that holds your system together using Logray </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>You are running Wireshark </source>
<translation>Wireshark&apos;ı çalıştırıyorsunuz </translation>
</message>
<message>
+ <source>You are running Logray </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source> You receive automatic updates.</source>
<translation> Otomatik güncelleme alıyorsunuz.</translation>
</message>
@@ -12698,14 +13269,6 @@ a:üzerine gelin{
<translation>Dosya bulunamadı</translation>
</message>
<message>
- <source>&amp;Contents</source>
- <translation>&amp;İçerik</translation>
- </message>
- <message>
- <source>Wireshark Filter</source>
- <translation>Wireshark Filtresi</translation>
- </message>
- <message>
<source>TShark</source>
<translation>TShark</translation>
</message>
@@ -12971,10 +13534,6 @@ a:üzerine gelin{
<translation>Kablosuz Araç Çubuğu</translation>
</message>
<message>
- <source>Help contents</source>
- <translation>Yardım içeriği</translation>
- </message>
- <message>
<source>FAQs</source>
<translation>SSS</translation>
</message>
@@ -13095,11 +13654,6 @@ a:üzerine gelin{
<translation>Önceki paketi bul</translation>
</message>
<message>
- <source>&amp;Mark/Unmark Packet(s)</source>
- <oldsource>&amp;Mark/Unmark Packet</oldsource>
- <translation>&amp;Paketi İşaretle/İşaretini Kaldır</translation>
- </message>
- <message>
<source>Mark All Displayed</source>
<translation>Tüm Görüntülenenleri İşaretle</translation>
</message>
@@ -13128,11 +13682,6 @@ a:üzerine gelin{
<translation>Önceki işaretli pakete git</translation>
</message>
<message>
- <source>&amp;Ignore/Unignore Packet(s)</source>
- <oldsource>&amp;Ignore/Unignore Packet</oldsource>
- <translation>&amp;Paketi Yoksay/Yoksaymaktan vazgeç</translation>
- </message>
- <message>
<source>Ignore All Displayed</source>
<translation>Tüm Görüntülenenleri Yoksay</translation>
</message>
@@ -13573,10 +14122,6 @@ a:üzerine gelin{
<translation>Düzeni Sıfırla</translation>
</message>
<message>
- <source>Reset appearance layout to default size</source>
- <translation>Görünüm düzenini varsayılan boyuta sıfırla</translation>
- </message>
- <message>
<source>Seconds Since First Captured Packet</source>
<translation>İlk Yakalanan Paketten Beri Saniye</translation>
</message>
@@ -13737,20 +14282,28 @@ a:üzerine gelin{
<translation type="unfinished"></translation>
</message>
<message>
- <source>TLS Keylog Launcher</source>
+ <source>&amp;Options…</source>
+ <translation>&amp;Seçenekler…</translation>
+ </message>
+ <message>
+ <source>&amp;3GPP Uu</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Release Notes</source>
+ <source>&amp;Wireless</source>
+ <translation>&amp;Kablosuz</translation>
+ </message>
+ <message>
+ <source>&amp;User&apos;s Guide</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Options…</source>
- <translation>&amp;Seçenekler…</translation>
+ <source>Wireshark User&apos;s Guide</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Wireless</source>
- <translation>&amp;Kablosuz</translation>
+ <source>Display Filters</source>
+ <translation type="unfinished">Ekran Filtreleri</translation>
</message>
<message>
<source>Capture &amp;Filters…</source>
@@ -13797,10 +14350,18 @@ a:üzerine gelin{
<translation>Öncekini Bu&amp;l</translation>
</message>
<message>
+ <source>&amp;Mark/Unmark Selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Mark or unmark each selected packet</source>
<translation>Seçilen her paketi işaretleyin veya işaretini kaldırın</translation>
</message>
<message>
+ <source>&amp;Ignore/Unignore Selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Ignore or unignore each selected packet</source>
<translation>Seçilen her paketi yoksay veya yoksay</translation>
</message>
@@ -13841,6 +14402,18 @@ a:üzerine gelin{
<translation>TCP verimi</translation>
</message>
<message>
+ <source>General</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Query-Response</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>DNS Query-Response Statistics</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Request Sequences</source>
<translation>İstek Dizileri</translation>
</message>
@@ -13849,6 +14422,14 @@ a:üzerine gelin{
<translation>HTTP İstek Dizileri</translation>
</message>
<message>
+ <source>E2AP</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>E2AP Messages</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Decode &amp;As…</source>
<translation>Kodu &amp;Çöz…</translation>
</message>
@@ -13909,6 +14490,10 @@ a:üzerine gelin{
<translation>Normal Boyut</translation>
</message>
<message>
+ <source>Reset layout to default size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Resize Columns</source>
<translation>Sütunları Yeniden Boyutlandır</translation>
</message>
@@ -14167,6 +14752,14 @@ a:üzerine gelin{
<translation>Seçili alan tarafından başvurulan pakete gidin.</translation>
</message>
<message>
+ <source>TLS Keylog Launcher</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Release Notes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&amp;VoIP Calls</source>
<translation>&amp;VoIP Aramaları</translation>
</message>
@@ -14199,10 +14792,6 @@ a:üzerine gelin{
<translation>&amp;GSM</translation>
</message>
<message>
- <source>&amp;LTE</source>
- <translation>&amp;LTE</translation>
- </message>
- <message>
<source>&amp;MTP3</source>
<translation>&amp;MTP3</translation>
</message>
@@ -14487,6 +15076,10 @@ a:üzerine gelin{
<translation>Kaydetmeden &amp;çık</translation>
</message>
<message>
+ <source>USB CDC Data</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>There is no &quot;rtp.ssrc&quot; field in this version of Wireshark.</source>
<translation>Wireshark&apos;ın bu sürümünde &quot;rtp.ssrc&quot; alanı yoktur.</translation>
</message>
diff --git a/ui/qt/wireshark_uk.ts b/ui/qt/wireshark_uk.ts
index 12517ff4..f95322a1 100644
--- a/ui/qt/wireshark_uk.ts
+++ b/ui/qt/wireshark_uk.ts
@@ -29,7 +29,7 @@
</message>
<message>
<source>Copy to Clipboard</source>
- <translation type="unfinished"></translation>
+ <translation>Скопіювати до буферу обміну</translation>
</message>
<message>
<source>Authors</source>
@@ -44,8 +44,8 @@
<translation>Каталоги</translation>
</message>
<message>
- <source>Filter by path</source>
- <translation>Фільтр за шляхом</translation>
+ <source>Search Folders</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Plugins</source>
@@ -80,6 +80,14 @@
<translation>Ліцензія</translation>
</message>
<message>
+ <source>About Logray</source>
+ <translation>Про Logray</translation>
+ </message>
+ <message>
+ <source>Logray</source>
+ <translation>Logray</translation>
+ </message>
+ <message>
<source>The directory does not exist</source>
<translation>Директорія не існує</translation>
</message>
@@ -137,14 +145,14 @@
</message>
<message>
<source>Can&apos;t assign %1 to %2.</source>
- <translation type="unfinished"></translation>
+ <translation>Неможливо призначити %1 до %2.</translation>
</message>
</context>
<context>
<name>AdvancedPrefsModel</name>
<message>
<source>Name</source>
- <translation type="unfinished"></translation>
+ <translation>Ім&apos;я</translation>
</message>
<message>
<source>Status</source>
@@ -170,7 +178,7 @@
<name>AuthorListModel</name>
<message>
<source>Name</source>
- <translation type="unfinished"></translation>
+ <translation>Ім&apos;я</translation>
</message>
<message>
<source>Email</source>
@@ -225,15 +233,15 @@
</message>
<message>
<source>Mark/Unmark Row</source>
- <translation type="unfinished"></translation>
+ <translation>Позначити/Зняти позначку з рядка</translation>
</message>
<message>
<source>Ctrl-M</source>
- <translation type="unfinished"></translation>
+ <translation>Ctrl-M</translation>
</message>
<message>
<source>Mark/Unmark Cell</source>
- <translation type="unfinished"></translation>
+ <translation>Позначити/зняти позначку з клітинки</translation>
</message>
<message>
<source>Save Table Image</source>
@@ -248,171 +256,171 @@
<name>BluetoothDeviceDialog</name>
<message>
<source>Bluetooth Device</source>
- <translation type="unfinished"></translation>
+ <translation>Пристрій Bluetooth</translation>
</message>
<message>
<source>BD_ADDR</source>
- <translation type="unfinished">BD_ADDR</translation>
+ <translation>BD_ADDR</translation>
</message>
<message>
<source>OUI</source>
- <translation type="unfinished">УІО (OUI)</translation>
+ <translation>OUI</translation>
</message>
<message>
<source>Name</source>
- <translation type="unfinished"></translation>
+ <translation>Ім&apos;я</translation>
</message>
<message>
<source>Class of Device</source>
- <translation type="unfinished"></translation>
+ <translation>Клас пристрою</translation>
</message>
<message>
<source>LMP Version</source>
- <translation type="unfinished">Версія LMP</translation>
+ <translation>Версія LMP</translation>
</message>
<message>
<source>LMP Subversion</source>
- <translation type="unfinished">Підверсія LMP</translation>
+ <translation>Підверсія LMP</translation>
</message>
<message>
<source>Manufacturer</source>
- <translation type="unfinished">Виробник</translation>
+ <translation>Виробник</translation>
</message>
<message>
<source>HCI Version</source>
- <translation type="unfinished">Версія HCI</translation>
+ <translation>Версія HCI</translation>
</message>
<message>
<source>HCI Revision</source>
- <translation type="unfinished">Ревізія HCI</translation>
+ <translation>Ревізія HCI</translation>
</message>
<message>
<source>Scan</source>
- <translation type="unfinished"></translation>
+ <translation>Сканувати</translation>
</message>
<message>
<source>Authentication</source>
- <translation type="unfinished"></translation>
+ <translation>Аутентифікація</translation>
</message>
<message>
<source>Encryption</source>
- <translation type="unfinished"></translation>
+ <translation>Шифрування</translation>
</message>
<message>
<source>ACL MTU</source>
- <translation type="unfinished"></translation>
+ <translation>ACL MTU</translation>
</message>
<message>
<source>ACL Total Packets</source>
- <translation type="unfinished"></translation>
+ <translation>Всього пакетів ACL</translation>
</message>
<message>
<source>SCO MTU</source>
- <translation type="unfinished"></translation>
+ <translation>SCO MTU</translation>
</message>
<message>
<source>SCO Total Packets</source>
- <translation type="unfinished"></translation>
+ <translation>Всього пакетів SCO</translation>
</message>
<message>
<source>LE ACL MTU</source>
- <translation type="unfinished"></translation>
+ <translation>LE ACL MTU</translation>
</message>
<message>
<source>LE ACL Total Packets</source>
- <translation type="unfinished"></translation>
+ <translation>Всього пакетів LE ACL</translation>
</message>
<message>
<source>LE ISO MTU</source>
- <translation type="unfinished"></translation>
+ <translation>LE ISO MTU</translation>
</message>
<message>
<source>LE ISO Total Packets</source>
- <translation type="unfinished"></translation>
+ <translation>Всього пакетів LE ISO</translation>
</message>
<message>
<source>Inquiry Mode</source>
- <translation type="unfinished"></translation>
+ <translation>Режим запитів</translation>
</message>
<message>
<source>Page Timeout</source>
- <translation type="unfinished"></translation>
+ <translation>Таймаут сторінки</translation>
</message>
<message>
<source>Simple Pairing Mode</source>
- <translation type="unfinished"></translation>
+ <translation>Простий режим парування</translation>
</message>
<message>
<source>Voice Setting</source>
- <translation type="unfinished"></translation>
+ <translation>Налаштування голосу</translation>
</message>
<message>
<source>Value</source>
- <translation type="unfinished">Значення</translation>
+ <translation>Значення</translation>
</message>
<message>
<source>Changes</source>
- <translation type="unfinished"></translation>
+ <translation>Зміни</translation>
</message>
<message>
<source>%1 changes</source>
- <translation type="unfinished"></translation>
+ <translation>%1 зміни</translation>
</message>
<message>
<source>Copy Cell</source>
- <translation type="unfinished">Скопіювати Клітинку</translation>
+ <translation>Копіювати клітинку</translation>
</message>
<message>
<source>Copy Rows</source>
- <translation type="unfinished">Скопіювати Рядки</translation>
+ <translation>Копіювати рядки</translation>
</message>
<message>
<source>Copy All</source>
- <translation type="unfinished">Скопіювати Все</translation>
+ <translation>Копіювати все</translation>
</message>
<message>
<source>Save as image</source>
- <translation type="unfinished">Зберегти як зображення</translation>
+ <translation>Зберегти як зображення</translation>
</message>
<message>
<source>Mark/Unmark Row</source>
- <translation type="unfinished"></translation>
+ <translation>Позначити/Зняти позначку з рядка</translation>
</message>
<message>
<source>Ctrl+M</source>
- <translation type="unfinished"></translation>
+ <translation>Ctrl+M</translation>
</message>
<message>
<source>Mark/Unmark Cell</source>
- <translation type="unfinished"></translation>
+ <translation>Позначити/зняти позначку з клітинки</translation>
</message>
<message>
<source>Unknown</source>
- <translation type="unfinished">Невідомо</translation>
+ <translation>Невідомий</translation>
</message>
<message>
<source>Bluetooth Device - %1%2</source>
- <translation type="unfinished"></translation>
+ <translation>Пристрій Bluetooth - %1%2</translation>
</message>
<message>
<source>enabled</source>
- <translation type="unfinished"></translation>
+ <translation>ввімкнено</translation>
</message>
<message>
<source>disabled</source>
- <translation type="unfinished"></translation>
+ <translation>вимкнено</translation>
</message>
<message>
<source>%1 ms (%2 slots)</source>
- <translation type="unfinished"></translation>
+ <translation>%1 мс (%2 слоти)</translation>
</message>
<message>
<source>Save Table Image</source>
- <translation type="unfinished">Зберегти Зображення Таблиці</translation>
+ <translation>Зберегти зображення таблиці</translation>
</message>
<message>
<source>PNG Image (*.png)</source>
- <translation type="unfinished">Зображення PNG (*.png)</translation>
+ <translation>Зображення PNG (*.png)</translation>
</message>
</context>
<context>
@@ -463,11 +471,11 @@
</message>
<message>
<source>Show information steps</source>
- <translation type="unfinished"></translation>
+ <translation>Показати кроки інформації</translation>
</message>
<message>
<source>%1 items; Right click for more option; Double click for device details</source>
- <translation type="unfinished"></translation>
+ <translation>%1 елементів; Клацніть правою кнопкою миші для отримання додаткових опцій; Подвійний клік для отримання деталей пристрою</translation>
</message>
<message>
<source>Copy Cell</source>
@@ -487,19 +495,19 @@
</message>
<message>
<source>Mark/Unmark Row</source>
- <translation type="unfinished"></translation>
+ <translation>Позначити/Зняти позначку з рядка</translation>
</message>
<message>
<source>Ctrl-M</source>
- <translation type="unfinished"></translation>
+ <translation>Ctrl-M</translation>
</message>
<message>
<source>Mark/Unmark Cell</source>
- <translation type="unfinished"></translation>
+ <translation>Позначити/зняти позначку з клітинки</translation>
</message>
<message>
<source>true</source>
- <translation type="unfinished"></translation>
+ <translation>істина</translation>
</message>
<message>
<source>Save Table Image</source>
@@ -538,7 +546,7 @@
</message>
<message>
<source>Subevent</source>
- <translation type="unfinished"></translation>
+ <translation>Підподія</translation>
</message>
<message>
<source>Status</source>
@@ -554,7 +562,7 @@
</message>
<message>
<source>Occurrence</source>
- <translation type="unfinished"></translation>
+ <translation>Випадок</translation>
</message>
<message>
<source>Link Control Commands</source>
@@ -646,11 +654,11 @@
</message>
<message>
<source>Results filter:</source>
- <translation type="unfinished"></translation>
+ <translation>Фільтр результатів:</translation>
</message>
<message>
<source>Display filter:</source>
- <translation type="unfinished">Фільтр відображення:</translation>
+ <translation>Фільтр відображення:</translation>
</message>
<message>
<source>All Interfaces</source>
@@ -678,19 +686,19 @@
</message>
<message>
<source>Mark/Unmark Row</source>
- <translation type="unfinished"></translation>
+ <translation>Позначити/Зняти позначку з рядка</translation>
</message>
<message>
<source>Ctrl+M</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Ctrl+M</translation>
</message>
<message>
<source>Mark/Unmark Cell</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Позначити/зняти позначку з клітинки</translation>
</message>
<message>
<source>Unknown</source>
- <translation type="unfinished">Невідомо</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Adapter %1</source>
@@ -756,6 +764,28 @@
</message>
</context>
<context>
+ <name>CaptureCommentDialog</name>
+ <message>
+ <source>Edit Capture Comments</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add Comment</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Section %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>CaptureCommentTabWidget</name>
+ <message>
+ <source>Comment %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>CaptureFile</name>
<message>
<source> [closing]</source>
@@ -841,10 +871,6 @@
<translation type="unfinished"></translation>
</message>
<message>
- <source>Compress with g&amp;zip</source>
- <translation>&amp;Стиснути gzip&apos;ом</translation>
- </message>
- <message>
<source>Open Capture File</source>
<oldsource>Wireshark: Open Capture File</oldsource>
<translation>Відкрити Файл Захоплення</translation>
@@ -929,8 +955,8 @@
<translation>Подробиці</translation>
</message>
<message>
- <source>Capture file comments</source>
- <translation>Коментарі файлу захоплення</translation>
+ <source>Edit Comments</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Refresh</source>
@@ -941,10 +967,6 @@
<translation>Скопіювати До Буферу Обміну</translation>
</message>
<message>
- <source>Save Comments</source>
- <translation>Зберегти Коментарі</translation>
- </message>
- <message>
<source>Capture File Properties</source>
<translation>Властивості Файлу Захоплення</translation>
</message>
@@ -993,10 +1015,18 @@
<translation>Перший пакет</translation>
</message>
<message>
+ <source>First event</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Last packet</source>
<translation>Останній пакет</translation>
</message>
<message>
+ <source>Last event</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Elapsed</source>
<translation>Витрачено</translation>
</message>
@@ -1033,6 +1063,10 @@
<translation>Відкинуті пакети</translation>
</message>
<message>
+ <source>Dropped events</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Capture filter</source>
<translation>Фільтр захоплення</translation>
</message>
@@ -1045,6 +1079,10 @@
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Event size limit (snaplen)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>none</source>
<translation>відсутній</translation>
</message>
@@ -1053,6 +1091,26 @@
<translation>%1 байтів</translation>
</message>
<message>
+ <source>Comments</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Comment %1: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Decryption Secrets</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation type="unfinished">Тип</translation>
+ </message>
+ <message>
+ <source>Size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Statistics</source>
<translation>Статистика</translation>
</message>
@@ -1077,6 +1135,10 @@
<translation>Пакетів</translation>
</message>
<message>
+ <source>Events</source>
+ <translation type="unfinished">Події</translation>
+ </message>
+ <message>
<source>Time span, s</source>
<translation>Проміжок часу, с</translation>
</message>
@@ -1089,6 +1151,10 @@
<translation>Середній розмір пакету, Б</translation>
</message>
<message>
+ <source>Average event size, B</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Bytes</source>
<translation>Байтів</translation>
</message>
@@ -1101,11 +1167,11 @@
<translation>біт/с (середнє значення)</translation>
</message>
<message>
- <source>Section Comment</source>
+ <source>Packet Comments</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Packet Comments</source>
+ <source>Event Comments</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1120,6 +1186,12 @@
</translation>
</message>
+ <message>
+ <source>Created by Logray %1
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>CaptureFilterCombo</name>
@@ -1346,6 +1418,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for some more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enable monitor mode on all 802.11 interfaces</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>compression</source>
<translation type="unfinished"></translation>
</message>
@@ -1358,6 +1438,30 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>File infix pattern</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;In multiple file mode, the date and time and file index number are inserted between filename template and any suffix. Select their order.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>YYYYmmDDHHMMSS_NNNNN</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Date and time before the file index number. This causes files to sort in creation time order, and keeps files from the same batch closely ordered.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>NNNNN_YYYYmmDDHHMMSS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;File index number before the date and time. This is the historic Wireshark ordering.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;After capturing has switched to the next file and the given number of files has exceeded, the oldest file will be removed.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
@@ -1446,6 +1550,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Stop capturing after the specified number of files have been created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Stop capturing after the specified amount of data has been captured.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
@@ -1506,7 +1614,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished">Помилка</translation>
</message>
<message>
- <source>Multiple files: Requested filesize too large. The filesize cannot be greater than 2 GiB.</source>
+ <source>Multiple files: Requested filesize too large. The filesize cannot be greater than 2 TB.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1537,6 +1645,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Захоплювати пакети в нерозбірливому режимі</translation>
</message>
<message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Capture packets in monitor mode on 802.11 devices</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Capture packets in the next-generation capture file format.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Захоплювати пакети в форматі файлу захоплення наступного покоління.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1764,6 +1880,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Width</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Alignment</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;Show human-readable strings instead of raw values for fields. Only applicable to custom columns with fields that have value strings.&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
@@ -1811,6 +1935,25 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>CompressionGroupBox</name>
+ <message>
+ <source>Compression options</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Uncompressed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Compress with g&amp;zip</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Compress with &amp;LZ4</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>ConversationDataModel</name>
<message>
<source>Address A</source>
@@ -1877,6 +2020,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Flows</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Total Packets</source>
<translation type="unfinished"></translation>
</message>
@@ -1991,23 +2138,31 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
- <source>…as Printable Text</source>
+ <source>…as MIME Data</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Copy only the printable text in the packet.</source>
+ <source>…as C String</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>…as MIME Data</source>
+ <source>Copy packet bytes as printable ASCII characters and escape sequences.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>…as C String</source>
+ <source>…as Go literal</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Copy packet bytes as printable ASCII characters and escape sequences.</source>
+ <source>Copy packet bytes as Go literal.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>…as C Array</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as C Array.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2015,6 +2170,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>…as UTF-8 Text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as text, treating as UTF-8.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>…as ASCII Text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as text, treating as ASCII.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Copy packet bytes as a stream of hex.</source>
<translation type="unfinished"></translation>
</message>
@@ -2808,6 +2979,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Display filter:</source>
<translation>Фільтр відображення:</translation>
</message>
+ <message>
+ <source>Export PDUs</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>ExtArgSelector</name>
@@ -2847,10 +3022,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
- <source>Save</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Default</source>
<translation type="unfinished"></translation>
</message>
@@ -2993,6 +3164,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Display Filter Macros</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>New macro</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Open </source>
<translation type="unfinished">Відкрити </translation>
</message>
@@ -3076,10 +3255,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>FilterListModel</name>
<message>
+ <source>Macro Name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Filter Name</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Macro Expression</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Filter Expression</source>
<translation type="unfinished"></translation>
</message>
@@ -3165,75 +3352,71 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>FolderListModel</name>
<message>
- <source>&quot;File&quot; dialogs</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>capture files</source>
+ <source>Temp</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Temp</source>
+ <source>Personal configuration</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>untitled capture files</source>
+ <source>Global configuration</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Personal configuration</source>
+ <source>System</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Global configuration</source>
+ <source>ethers, ipxnets</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>dfilters, preferences, ethers, …</source>
+ <source>Program</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>dfilters, preferences, manuf, …</source>
+ <source>Personal Plugins</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>System</source>
+ <source>Global Plugins</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>ethers, ipxnets</source>
+ <source>Personal Lua Plugins</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Program</source>
+ <source>Global Lua Plugins</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>program files</source>
+ <source>Lua scripts</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Personal Plugins</source>
+ <source>&quot;File&quot; dialog location</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>binary plugins</source>
+ <source>Capture files</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Global Plugins</source>
+ <source>Untitled capture files</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Personal Lua Plugins</source>
+ <source>Preferences, profiles, manuf, …</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Global Lua Plugins</source>
+ <source>Program files</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Lua scripts</source>
+ <source>Binary plugins</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -3241,7 +3424,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
- <source>external capture (extcap) plugins</source>
+ <source>External capture (extcap) plugins</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -3368,6 +3551,26 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</translation>
</message>
<message>
+ <source>Event %1. </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;reads&lt;/span&gt;, </source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;writes&lt;/span&gt;, </source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
<source> Click to select.</source>
<translation>Клікніть для вибору.</translation>
</message>
@@ -3400,6 +3603,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Read activity(%6)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Write activity(%6)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Entire I/O activity (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Entire conversation (%1)</source>
<translation type="unfinished"></translation>
</message>
@@ -3415,10 +3630,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Save Stream Content As…</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <source>[Stream output truncated]</source>
- <translation type="unfinished"></translation>
- </message>
<message numerus="yes">
<source>%Ln total stream(s).</source>
<translation type="unfinished">
@@ -3448,8 +3659,19 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Підказка.</translation>
</message>
<message>
- <source>Show data as</source>
- <oldsource>Show and save data as</oldsource>
+ <source>Show as</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>No delta times</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Turn delta times</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All delta times</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -3465,11 +3687,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Знайти:</translation>
</message>
<message>
+ <source>Case sensitive</source>
+ <translation type="unfinished">Враховувати регістр</translation>
+ </message>
+ <message>
<source>Find &amp;Next</source>
<translation>Знайти &amp;Наступний</translation>
</message>
</context>
<context>
+ <name>FollowStreamText</name>
+ <message>
+ <source>[Stream output truncated]</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FontColorPreferencesFrame</name>
<message>
<source>Frame</source>
@@ -3776,28 +4009,27 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
- <source>Remove this graph.</source>
- <oldsource>Remove this dissection behavior.</oldsource>
- <translation>Видалити цей графік.</translation>
- </message>
- <message>
<source>Add a new graph.</source>
<translation>Додати новий графік.</translation>
</message>
<message>
- <source>Duplicate this graph.</source>
- <translation>Продублювати цей графік.</translation>
+ <source>Clear all graphs.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Clear all graphs.</source>
+ <source>Remove the selected graph(s).</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Move this graph upwards.</source>
+ <source>Duplicate the selected graph(s).</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Move this graph downwards.</source>
+ <source>Move the selected graph(s) upwards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move the selected graph(s) downwards.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -3841,10 +4073,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
- <source>Reset</source>
- <translation>Скинути</translation>
- </message>
- <message>
<source>Reset Graph</source>
<translation>Скинути Зміни До Діаграми</translation>
</message>
@@ -4058,6 +4286,42 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>1 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>2 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>5 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>10 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>20 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>50 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>100 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>200 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>500 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>1 ms</source>
<translation type="unfinished"></translation>
</message>
@@ -4102,6 +4366,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished">10 сек {5 ?}</translation>
</message>
<message>
+ <source>2 min</source>
+ <translation type="unfinished">10 хв {2 ?}</translation>
+ </message>
+ <message>
+ <source>5 min</source>
+ <translation type="unfinished">10 хв {5 ?}</translation>
+ </message>
+ <message>
<source>Wireshark I/O Graphs: %1</source>
<translation type="unfinished"></translation>
</message>
@@ -4114,6 +4386,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>All packets</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All events</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>All Packets</source>
<translation type="unfinished"></translation>
</message>
@@ -4126,7 +4406,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
- <source>Access Denied</source>
+ <source>All Execs</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -4174,6 +4454,34 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Клікніть, щоб виділити частину графіку.</translation>
</message>
<message>
+ <source>%1 Intervals </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to top left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to top center</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to top right</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to bottom left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to bottom center</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to bottom right</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Portable Document Format (*.pdf)</source>
<translation>Формат Переносних Документів (*.pdf)</translation>
</message>
@@ -4926,6 +5234,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>InterfaceTreeDelegate</name>
+ <message>
+ <source>default</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>InterfaceTreeModel</name>
<message>
<source>Show</source>
@@ -5904,7 +6219,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>LteMacStatisticsDialog</name>
<message>
- <source>LTE Mac Statistics</source>
+ <source>LTE/NR Mac Statistics</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -6184,11 +6499,11 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
- <source>LTE RLC Graph (UE=%1 chan=%2%3 %4 - %5)</source>
+ <source>%1 RLC Graph (UE=%2 chan=%3%4 %5 - %6)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>LTE RLC Graph - no channel selected</source>
+ <source>3GPP RLC Graph - no channel selected</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -6243,7 +6558,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>LteRlcStatisticsDialog</name>
<message>
- <source>LTE RLC Statistics</source>
+ <source>3GPP RLC Statistics</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -6330,6 +6645,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source> %1 Displayed: %2 (%3%)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Manage Profiles…</source>
<translation type="unfinished"></translation>
</message>
@@ -6392,6 +6711,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<numerusform></numerusform>
</translation>
</message>
+ <message numerus="yes">
+ <source>%Ln bit(s)</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
<message>
<source>Byte %1</source>
<translation type="unfinished"></translation>
@@ -6405,8 +6732,11 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
- <source>Packets: %1 %4 Displayed: %2 (%3%)</source>
- <oldsource>Packets: %1 %4 Displayed: %2 %4 Marked: %3</oldsource>
+ <source>Selected Event: %1 %2 </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Events: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -6439,6 +6769,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Пакети відсутні</translation>
</message>
<message>
+ <source>No Events</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>From Zip File...</source>
<translation type="unfinished"></translation>
</message>
@@ -6472,6 +6806,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>MainWindow</name>
+ <message>
+ <source>Display filter as %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>MainWindowPreferencesFrame</name>
<message>
<source>Frame</source>
@@ -6503,6 +6844,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>The current working directory</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Show up to</source>
<translation type="unfinished"></translation>
</message>
@@ -6933,6 +7278,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Refresh</source>
+ <translation type="unfinished">Оновити</translation>
+ </message>
+ <message>
<source>Save Diagram As…</source>
<translation type="unfinished"></translation>
</message>
@@ -6980,6 +7329,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Layout:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Packet %1</source>
<translation type="unfinished"></translation>
</message>
@@ -7003,6 +7356,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<numerusform></numerusform>
</translation>
</message>
+ <message numerus="yes">
+ <source>%Ln bit(s)</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ <numerusform></numerusform>
+ </translation>
+ </message>
</context>
<context>
<name>PacketFormatGroupBox</name>
@@ -7460,10 +7821,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Скопіювати цей профіль.</translation>
</message>
<message>
+ <source>The number of packets or events to check for automatic profile switching.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Auto switch packet limit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Configuration Profiles</source>
<translation>Профілі Конфігурації</translation>
</message>
<message>
+ <source>Auto switch event limit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Import</source>
<comment>noun</comment>
<translation type="unfinished"></translation>
@@ -7637,6 +8010,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Auto Switch Filter</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>copy</source>
<comment>noun</comment>
<translation type="unfinished"></translation>
@@ -7996,6 +8373,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Розмір Вікна (Б)</translation>
</message>
<message>
+ <source>Unacked (Outstanding) Bytes (B)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>[no capture file]</source>
<translation type="unfinished"></translation>
</message>
@@ -8156,6 +8537,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>LTE</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>NR</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>C-RNTI</source>
<translation type="unfinished"></translation>
</message>
@@ -8176,6 +8565,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>RAT</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>UL Frames</source>
<translation type="unfinished"></translation>
</message>
@@ -8321,7 +8714,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Unknown</source>
- <translation type="unfinished">Невідомо</translation>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>UE Id</source>
@@ -8399,9 +8792,69 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Browse…</source>
<translation type="unfinished">Перегляд...</translation>
</message>
+ <message>
+ <source>PACKETS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>EVENTS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>BYTES</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>BITS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>COUNT FRAMES</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>COUNT FIELDS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>SUM</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>MAX</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>MIN</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>AVERAGE</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>THROUGHPUT</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>LOAD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Left</source>
+ <translation type="unfinished">Вліво</translation>
+ </message>
+ <message>
+ <source>Center</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Right</source>
+ <translation type="unfinished">Вправо</translation>
+ </message>
</context>
<context>
- <name>QObject::QObject</name>
+ <name>QObject::QObject::QObject</name>
<message>
<source>CCCH</source>
<translation type="unfinished"></translation>
@@ -8423,7 +8876,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Authentication</source>
- <translation type="unfinished"></translation>
+ <translation type="unfinished">Аутентифікація</translation>
</message>
<message>
<source>Null authentication</source>
@@ -8502,6 +8955,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>ResizeHeaderView</name>
+ <message>
+ <source>Resize all %1 to contents</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>ResolvedAddressesDialog</name>
<message>
<source>Dialog</source>
@@ -8617,6 +9077,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Визначені Адреси</translation>
</message>
<message>
+ <source>Copy</source>
+ <translation type="unfinished">Скопіювати</translation>
+ </message>
+ <message>
+ <source>Save as…</source>
+ <translation type="unfinished">Зберегти як...</translation>
+ </message>
+ <message>
<source># Resolved addresses found in %1</source>
<translation type="unfinished"></translation>
</message>
@@ -8628,6 +9096,61 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>ResolvedAddressesView</name>
+ <message>
+ <source>as Plain Text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy selected rows</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy table</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>as CSV</source>
+ <translation type="unfinished">як CSV</translation>
+ </message>
+ <message>
+ <source>as JSON</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save selected rows as…</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save table as…</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save Resolved Addresses As…</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Plain text (*.txt)</source>
+ <translation type="unfinished">Звичайний текст (*.txt)</translation>
+ </message>
+ <message>
+ <source>CSV Document (*.csv)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>JSON Document (*.json)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation type="unfinished">Попередження</translation>
+ </message>
+ <message>
+ <source>Unable to save %1: %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>ResponseTimeDelayDialog</name>
<message>
<source>%1 Response Time Delay Statistics</source>
@@ -9568,7 +10091,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Unknown</source>
- <translation type="unfinished">Невідомо</translation>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -10298,6 +10821,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Байти пакету</translation>
</message>
<message>
+ <source>&lt;b&gt;Options:&lt;/b&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for strings containing narrow (UTF-8 and ASCII) or wide (UTF-16) characters.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Шукати рядки, що містять звичайні (UTF-8 та ASCII) або розширені (UTF-16) символи.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -10318,6 +10845,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Враховувати регістр</translation>
</message>
<message>
+ <source>Backwards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for a subsequent occurrence in the current packet before advancing to the next packet.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Multiple occurrences</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5), a plain string (e.g. My String) or a regular expression (e.g. colou?r).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<oldsource>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5) or a plain string (e.g. My String).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</oldsource>
<translation type="unfinished"></translation>
@@ -10355,6 +10894,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>Некоректний фільтр.</translation>
</message>
<message>
+ <source>Event List</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Event Details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Event Bytes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search the Info column of the event list (summary pane), decoded event display labels (tree view pane) or the ASCII-converted event data (hex view pane).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>That filter doesn&apos;t test anything.</source>
<translation>Цей фільтр нічого не перевіряє.</translation>
</message>
@@ -10777,6 +11332,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished">Знайти:</translation>
</message>
<message>
+ <source>Case sensitive</source>
+ <translation type="unfinished">Враховувати регістр</translation>
+ </message>
+ <message>
<source>Find &amp;Next</source>
<translation type="unfinished">Знайти &amp;Наступний</translation>
</message>
@@ -10873,11 +11432,19 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished">Зберегти як...</translation>
</message>
<message>
+ <source>Decoded as %1.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Save Selected Packet Bytes As…</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>compressed %1</source>
+ <translation type="unfinished"></translation>
+ </message>
<message numerus="yes">
- <source>Displaying %Ln byte(s).</source>
+ <source>Using %Ln byte(s).</source>
<translation type="unfinished">
<numerusform></numerusform>
<numerusform></numerusform>
@@ -10981,6 +11548,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Display filter:</source>
<translation type="unfinished">Фільтр відображення:</translation>
</message>
+ <message>
+ <source>Strip Headers</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>SupportedProtocolsDialog</name>
@@ -11824,7 +12395,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Unknown</source>
- <translation type="unfinished">Невідомо</translation>
+ <translation type="unfinished"></translation>
</message>
</context>
<context>
@@ -11915,21 +12486,19 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
- <source>Remove this entry.</source>
- <oldsource>Remove this profile.</oldsource>
+ <source>Remove the selected entry(ies).</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Copy this entry.</source>
- <oldsource>Copy this profile.</oldsource>
+ <source>Copy the selected entry(ies).</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry up.</source>
+ <source>Move the selected entry(ies) up.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry down.</source>
+ <source>Move the selected entry(ies) down.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -11956,19 +12525,19 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
- <source>Remove this entry.</source>
+ <source>Remove the selected entry(ies).</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Copy this entry.</source>
+ <source>Copy the selected entry(ies).</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry up.</source>
+ <source>Move the selected entry(ies) up.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry down.</source>
+ <source>Move the selected entry(ies) down.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -12299,10 +12868,18 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
+ <source>You are sniffing the glue that holds your system together using Logray </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>You are running Wireshark </source>
<translation type="unfinished"></translation>
</message>
<message>
+ <source>You are running Logray </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source> You receive automatic updates.</source>
<translation type="unfinished"></translation>
</message>
@@ -12579,14 +13156,6 @@ a:hover {
<translation>Не знайдено жодного файлу</translation>
</message>
<message>
- <source>&amp;Contents</source>
- <translation>&amp;Зміст</translation>
- </message>
- <message>
- <source>Wireshark Filter</source>
- <translation>Фільтр Wireshark’а</translation>
- </message>
- <message>
<source>TShark</source>
<translation>TShark</translation>
</message>
@@ -12852,10 +13421,6 @@ a:hover {
<translation>Панель Бездротової Мережі</translation>
</message>
<message>
- <source>Help contents</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>FAQs</source>
<translation type="unfinished"></translation>
</message>
@@ -12976,11 +13541,6 @@ a:hover {
<translation>Знайти попередній пакет</translation>
</message>
<message>
- <source>&amp;Mark/Unmark Packet(s)</source>
- <oldsource>&amp;Mark/Unmark Packet</oldsource>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Mark All Displayed</source>
<translation>Позначити Всі Відображені</translation>
</message>
@@ -13009,11 +13569,6 @@ a:hover {
<translation>Перейти до попереднього позначеного пакету</translation>
</message>
<message>
- <source>&amp;Ignore/Unignore Packet(s)</source>
- <oldsource>&amp;Ignore/Unignore Packet</oldsource>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Ignore All Displayed</source>
<translation>Прибрати Всі Відображені</translation>
</message>
@@ -13454,10 +14009,6 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
- <source>Reset appearance layout to default size</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Seconds Since First Captured Packet</source>
<translation type="unfinished"></translation>
</message>
@@ -13618,19 +14169,27 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
- <source>TLS Keylog Launcher</source>
+ <source>&amp;Options…</source>
+ <translation>&amp;Опції...</translation>
+ </message>
+ <message>
+ <source>&amp;3GPP Uu</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Release Notes</source>
+ <source>&amp;Wireless</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Options…</source>
- <translation>&amp;Опції...</translation>
+ <source>&amp;User&apos;s Guide</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Wireless</source>
+ <source>Wireshark User&apos;s Guide</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Display Filters</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -13678,10 +14237,18 @@ a:hover {
<translation>Знайти Поп&amp;ередній</translation>
</message>
<message>
+ <source>&amp;Mark/Unmark Selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Mark or unmark each selected packet</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <source>&amp;Ignore/Unignore Selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Ignore or unignore each selected packet</source>
<translation type="unfinished"></translation>
</message>
@@ -13722,6 +14289,18 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
+ <source>General</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Query-Response</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>DNS Query-Response Statistics</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Request Sequences</source>
<translation type="unfinished"></translation>
</message>
@@ -13730,6 +14309,14 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
+ <source>E2AP</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>E2AP Messages</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Decode &amp;As…</source>
<translation>Декодувати &amp;Як...</translation>
</message>
@@ -13790,6 +14377,10 @@ a:hover {
<translation>Нормальний Розмір</translation>
</message>
<message>
+ <source>Reset layout to default size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Resize Columns</source>
<translation>Змінити Розмір Колонок</translation>
</message>
@@ -14048,6 +14639,14 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
+ <source>TLS Keylog Launcher</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Release Notes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&amp;VoIP Calls</source>
<translation>&amp;Виклики VoIP</translation>
</message>
@@ -14080,10 +14679,6 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;LTE</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>&amp;MTP3</source>
<translation type="unfinished"></translation>
</message>
@@ -14368,6 +14963,10 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
+ <source>USB CDC Data</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>There is no &quot;rtp.ssrc&quot; field in this version of Wireshark.</source>
<translation type="unfinished"></translation>
</message>
diff --git a/ui/qt/wireshark_zh_CN.ts b/ui/qt/wireshark_zh_CN.ts
index 38dfcbbd..b2bf81cb 100644
--- a/ui/qt/wireshark_zh_CN.ts
+++ b/ui/qt/wireshark_zh_CN.ts
@@ -29,7 +29,7 @@
</message>
<message>
<source>Copy to Clipboard</source>
- <translation type="unfinished"></translation>
+ <translation>复制到剪贴板</translation>
</message>
<message>
<source>Authors</source>
@@ -44,8 +44,8 @@
<translation>文件夹</translation>
</message>
<message>
- <source>Filter by path</source>
- <translation>按路径过滤</translation>
+ <source>Search Folders</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Plugins</source>
@@ -80,6 +80,14 @@
<translation>许可</translation>
</message>
<message>
+ <source>About Logray</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Logray</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>The directory does not exist</source>
<translation>该目录不存在</translation>
</message>
@@ -270,7 +278,7 @@
</message>
<message>
<source>LMP Subversion</source>
- <translation type="unfinished">LMP 子版本</translation>
+ <translation>LMP 子版本</translation>
</message>
<message>
<source>Manufacturer</source>
@@ -378,7 +386,7 @@
</message>
<message>
<source>Ctrl+M</source>
- <translation type="unfinished">Ctrl+M</translation>
+ <translation>Ctrl+M</translation>
</message>
<message>
<source>Mark/Unmark Cell</source>
@@ -754,6 +762,28 @@
</message>
</context>
<context>
+ <name>CaptureCommentDialog</name>
+ <message>
+ <source>Edit Capture Comments</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Add Comment</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Section %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>CaptureCommentTabWidget</name>
+ <message>
+ <source>Comment %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>CaptureFile</name>
<message>
<source> [closing]</source>
@@ -839,10 +869,6 @@
<translation>读取过滤器:</translation>
</message>
<message>
- <source>Compress with g&amp;zip</source>
- <translation>用 gzip 压缩(&amp;Z)</translation>
- </message>
- <message>
<source>Open Capture File</source>
<oldsource>Wireshark: Open Capture File</oldsource>
<translation>打开捕获文件</translation>
@@ -921,8 +947,8 @@
<translation>细节</translation>
</message>
<message>
- <source>Capture file comments</source>
- <translation>捕获文件描述</translation>
+ <source>Edit Comments</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Refresh</source>
@@ -933,10 +959,6 @@
<translation>复制到剪贴板</translation>
</message>
<message>
- <source>Save Comments</source>
- <translation>保存注释</translation>
- </message>
- <message>
<source>Capture File Properties</source>
<translation>捕获文件属性</translation>
</message>
@@ -985,10 +1007,18 @@
<translation>第一个分组</translation>
</message>
<message>
+ <source>First event</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Last packet</source>
<translation>最后分组</translation>
</message>
<message>
+ <source>Last event</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Elapsed</source>
<translation>经过时间</translation>
</message>
@@ -1025,6 +1055,10 @@
<translation>丢弃分组</translation>
</message>
<message>
+ <source>Dropped events</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Capture filter</source>
<translation>捕获过滤器</translation>
</message>
@@ -1037,6 +1071,10 @@
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Event size limit (snaplen)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>none</source>
<translation>无</translation>
</message>
@@ -1045,6 +1083,26 @@
<translation>%1 字节</translation>
</message>
<message>
+ <source>Comments</source>
+ <translation type="unfinished">注释</translation>
+ </message>
+ <message>
+ <source>Comment %1: </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Decryption Secrets</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Type</source>
+ <translation type="unfinished">类型</translation>
+ </message>
+ <message>
+ <source>Size</source>
+ <translation type="unfinished">大小</translation>
+ </message>
+ <message>
<source>Statistics</source>
<translation>统计</translation>
</message>
@@ -1069,6 +1127,10 @@
<translation>分组</translation>
</message>
<message>
+ <source>Events</source>
+ <translation type="unfinished">事件</translation>
+ </message>
+ <message>
<source>Time span, s</source>
<translation>时间跨度,s</translation>
</message>
@@ -1081,6 +1143,10 @@
<translation>平均分组大小,B</translation>
</message>
<message>
+ <source>Average event size, B</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Bytes</source>
<translation>字节</translation>
</message>
@@ -1093,14 +1159,14 @@
<translation>平均 比特/秒</translation>
</message>
<message>
- <source>Section Comment</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Packet Comments</source>
<translation>分组注释</translation>
</message>
<message>
+ <source>Event Comments</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;p&gt;Frame %1: </source>
<translation>&lt;p&gt;帧 %1: </translation>
</message>
@@ -1110,6 +1176,12 @@
</source>
<translation>通过 Wireshark 创建 %1</translation>
</message>
+ <message>
+ <source>Created by Logray %1
+
+</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>CaptureFilterCombo</name>
@@ -1337,6 +1409,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
例如,如果设置成1小时,则每个整点将创建一个文件。</translation>
</message>
<message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for some more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Enable monitor mode on all 802.11 interfaces</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>compression</source>
<translation>压缩</translation>
</message>
@@ -1349,6 +1429,30 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>gzip</translation>
</message>
<message>
+ <source>File infix pattern</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;In multiple file mode, the date and time and file index number are inserted between filename template and any suffix. Select their order.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>YYYYmmDDHHMMSS_NNNNN</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Date and time before the file index number. This causes files to sort in creation time order, and keeps files from the same batch closely ordered.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>NNNNN_YYYYmmDDHHMMSS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;File index number before the date and time. This is the historic Wireshark ordering.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;After capturing has switched to the next file and the given number of files has exceeded, the oldest file will be removed.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;当捕获切换到下一个文件并且给定的文件数已经达到时,则最早的文件将会被删除。&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1437,6 +1541,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Stop capturing after the specified number of files have been created.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Stop capturing after the specified amount of data has been captured.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
@@ -1497,7 +1605,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished">错误</translation>
</message>
<message>
- <source>Multiple files: Requested filesize too large. The filesize cannot be greater than 2 GiB.</source>
+ <source>Multiple files: Requested filesize too large. The filesize cannot be greater than 2 TB.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -1528,6 +1636,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>使用混杂模式捕获分组</translation>
</message>
<message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Usually a wireless network card will only capture the traffic sent to and from its own network address, and only captures &lt;em&gt;user data&lt;/em&gt; traffic with &amp;quot;fake&amp;quot; Ethernet headers. If you want to capture all traffic that wireless network cards can &amp;quot;see&amp;quot;, or are interested in 802.11 management or control packets, or radio-layer information, mark this option. Monitor mode availability depends on the wireless card and driver. See the Wiki for more details of capturing packets on WLAN networks.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Capture packets in monitor mode on 802.11 devices</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Capture packets in the next-generation capture file format.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;使用下一代捕获文件格式来捕获分组。&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -1755,6 +1871,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Width</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Alignment</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;Show human-readable strings instead of raw values for fields. Only applicable to custom columns with fields that have value strings.&lt;/html&gt;</source>
<translation type="unfinished"></translation>
</message>
@@ -1802,6 +1926,25 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>CompressionGroupBox</name>
+ <message>
+ <source>Compression options</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&amp;Uncompressed</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Compress with g&amp;zip</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Compress with &amp;LZ4</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>ConversationDataModel</name>
<message>
<source>Address A</source>
@@ -1868,6 +2011,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Flows</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Total Packets</source>
<translation type="unfinished"></translation>
</message>
@@ -1982,23 +2129,31 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>将分组字节复制为十六进制转储。</translation>
</message>
<message>
- <source>…as Printable Text</source>
+ <source>…as MIME Data</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Copy only the printable text in the packet.</source>
+ <source>…as C String</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>…as MIME Data</source>
+ <source>Copy packet bytes as printable ASCII characters and escape sequences.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>…as C String</source>
+ <source>…as Go literal</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Copy packet bytes as printable ASCII characters and escape sequences.</source>
+ <source>Copy packet bytes as Go literal.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>…as C Array</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as C Array.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -2006,6 +2161,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>…as UTF-8 Text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as text, treating as UTF-8.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>…as ASCII Text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy packet bytes as text, treating as ASCII.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Copy packet bytes as a stream of hex.</source>
<translation>将分组字节复制为十六进制流。</translation>
</message>
@@ -2799,6 +2970,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Display filter:</source>
<translation>显示过滤器:</translation>
</message>
+ <message>
+ <source>Export PDUs</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>ExtArgSelector</name>
@@ -2838,10 +3013,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>开始</translation>
</message>
<message>
- <source>Save</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>Default</source>
<translation>默认</translation>
</message>
@@ -2982,6 +3153,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>显示过滤器</translation>
</message>
<message>
+ <source>Display Filter Macros</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>New macro</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Open </source>
<translation>打开 </translation>
</message>
@@ -3065,10 +3244,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>FilterListModel</name>
<message>
+ <source>Macro Name</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Filter Name</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Macro Expression</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Filter Expression</source>
<translation type="unfinished"></translation>
</message>
@@ -3154,22 +3341,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>FolderListModel</name>
<message>
- <source>&quot;File&quot; dialogs</source>
- <translation>“文件”对话框</translation>
- </message>
- <message>
- <source>capture files</source>
- <translation>捕获文件</translation>
- </message>
- <message>
<source>Temp</source>
<translation>临时</translation>
</message>
<message>
- <source>untitled capture files</source>
- <translation>无标题捕获文件</translation>
- </message>
- <message>
<source>Personal configuration</source>
<translation>个人配置</translation>
</message>
@@ -3178,14 +3353,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>全局配置</translation>
</message>
<message>
- <source>dfilters, preferences, ethers, …</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>dfilters, preferences, manuf, …</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>System</source>
<translation>系统</translation>
</message>
@@ -3198,18 +3365,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>程序</translation>
</message>
<message>
- <source>program files</source>
- <translation>程序文件</translation>
- </message>
- <message>
<source>Personal Plugins</source>
<translation>个人插件</translation>
</message>
<message>
- <source>binary plugins</source>
- <translation>二进制插件</translation>
- </message>
- <message>
<source>Global Plugins</source>
<translation>全局插件</translation>
</message>
@@ -3226,11 +3385,35 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>&quot;File&quot; dialog location</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Capture files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Untitled capture files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Preferences, profiles, manuf, …</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Program files</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Binary plugins</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Personal Extcap path</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>external capture (extcap) plugins</source>
+ <source>External capture (extcap) plugins</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -3351,6 +3534,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</translation>
</message>
<message>
+ <source>Event %1. </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;reads&lt;/span&gt;, </source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message numerus="yes">
+ <source>%Ln &lt;span style=&quot;color: %1; background-color:%2&quot;&gt;writes&lt;/span&gt;, </source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
+ <message>
<source> Click to select.</source>
<translation>点击选择。</translation>
</message>
@@ -3383,6 +3582,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Read activity(%6)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Write activity(%6)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Entire I/O activity (%1)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Entire conversation (%1)</source>
<translation>整个对话(%1)</translation>
</message>
@@ -3398,10 +3609,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Save Stream Content As…</source>
<translation type="unfinished"></translation>
</message>
- <message>
- <source>[Stream output truncated]</source>
- <translation>[流输出被截断]</translation>
- </message>
<message numerus="yes">
<source>%Ln total stream(s).</source>
<translation>
@@ -3427,8 +3634,19 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>提示。</translation>
</message>
<message>
- <source>Show data as</source>
- <oldsource>Show and save data as</oldsource>
+ <source>Show as</source>
+ <translation type="unfinished">显示为</translation>
+ </message>
+ <message>
+ <source>No delta times</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Turn delta times</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All delta times</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -3444,11 +3662,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>查找:</translation>
</message>
<message>
+ <source>Case sensitive</source>
+ <translation type="unfinished">区分大小写</translation>
+ </message>
+ <message>
<source>Find &amp;Next</source>
<translation>查找下一个(&amp;N)</translation>
</message>
</context>
<context>
+ <name>FollowStreamText</name>
+ <message>
+ <source>[Stream output truncated]</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>FontColorPreferencesFrame</name>
<message>
<source>Frame</source>
@@ -3784,28 +4013,27 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
&lt;/body&gt;&lt;/html&gt;</translation>
</message>
<message>
- <source>Remove this graph.</source>
- <oldsource>Remove this dissection behavior.</oldsource>
- <translation>删除图形。</translation>
- </message>
- <message>
<source>Add a new graph.</source>
<translation>增加新图形。</translation>
</message>
<message>
- <source>Duplicate this graph.</source>
- <translation>复制图形。</translation>
- </message>
- <message>
<source>Clear all graphs.</source>
<translation>清除所有图形。</translation>
</message>
<message>
- <source>Move this graph upwards.</source>
+ <source>Remove the selected graph(s).</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Move this graph downwards.</source>
+ <source>Duplicate the selected graph(s).</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move the selected graph(s) upwards.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move the selected graph(s) downwards.</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -3849,10 +4077,6 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
- <source>Reset</source>
- <translation>复位</translation>
- </message>
- <message>
<source>Reset Graph</source>
<translation>复位图形</translation>
</message>
@@ -4066,6 +4290,42 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>从另一个配置文件复制图形。</translation>
</message>
<message>
+ <source>1 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>2 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>5 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>10 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>20 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>50 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>100 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>200 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>500 μs</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>1 ms</source>
<translation>1毫秒</translation>
</message>
@@ -4110,6 +4370,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished">10秒 {5 ?}</translation>
</message>
<message>
+ <source>2 min</source>
+ <translation type="unfinished">10分钟 {2 ?}</translation>
+ </message>
+ <message>
+ <source>5 min</source>
+ <translation type="unfinished">10分钟 {5 ?}</translation>
+ </message>
+ <message>
<source>Wireshark I/O Graphs: %1</source>
<translation type="unfinished"></translation>
</message>
@@ -4122,6 +4390,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>All packets</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>All events</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>All Packets</source>
<translation type="unfinished"></translation>
</message>
@@ -4134,7 +4410,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
- <source>Access Denied</source>
+ <source>All Execs</source>
<translation type="unfinished"></translation>
</message>
<message>
@@ -4182,6 +4458,34 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>点击选择图形的一部分。</translation>
</message>
<message>
+ <source>%1 Intervals </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to top left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to top center</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to top right</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to bottom left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to bottom center</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Move to bottom right</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Portable Document Format (*.pdf)</source>
<translation>便携式文档格式 (*.pdf)</translation>
</message>
@@ -4934,6 +5238,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>InterfaceTreeDelegate</name>
+ <message>
+ <source>default</source>
+ <translation type="unfinished">默认</translation>
+ </message>
+</context>
+<context>
<name>InterfaceTreeModel</name>
<message>
<source>Show</source>
@@ -5908,8 +6219,8 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>LteMacStatisticsDialog</name>
<message>
- <source>LTE Mac Statistics</source>
- <translation>LTE MAC 统计</translation>
+ <source>LTE/NR Mac Statistics</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Include SR frames in filter</source>
@@ -6213,12 +6524,12 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>序列号</translation>
</message>
<message>
- <source>LTE RLC Graph (UE=%1 chan=%2%3 %4 - %5)</source>
- <translation>LTE RLC 图表 (UE=%1 chan=%2%3 %4 - %5)</translation>
+ <source>%1 RLC Graph (UE=%2 chan=%3%4 %5 - %6)</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>LTE RLC Graph - no channel selected</source>
- <translation>LTE RLC 图表 - 没有选择信道</translation>
+ <source>3GPP RLC Graph - no channel selected</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Save As…</source>
@@ -6272,8 +6583,8 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<context>
<name>LteRlcStatisticsDialog</name>
<message>
- <source>LTE RLC Statistics</source>
- <translation>LTE RLC 统计</translation>
+ <source>3GPP RLC Statistics</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Include SR frames in filter</source>
@@ -6359,6 +6670,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>配置:%1</translation>
</message>
<message>
+ <source> %1 Displayed: %2 (%3%)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Manage Profiles…</source>
<translation type="unfinished"></translation>
</message>
@@ -6419,6 +6734,12 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<numerusform></numerusform>
</translation>
</message>
+ <message numerus="yes">
+ <source>%Ln bit(s)</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
<message>
<source>Byte %1</source>
<translation>字节 %1</translation>
@@ -6432,9 +6753,12 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>所选分组:%1 %2 </translation>
</message>
<message>
- <source>Packets: %1 %4 Displayed: %2 (%3%)</source>
- <oldsource>Packets: %1 %4 Displayed: %2 %4 Marked: %3</oldsource>
- <translation>分组: %1 %4 已显示: %2 (%3%)</translation>
+ <source>Selected Event: %1 %2 </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Events: %1</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source> %1 Selected: %2 (%3%)</source>
@@ -6466,6 +6790,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>无分组</translation>
</message>
<message>
+ <source>No Events</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>From Zip File...</source>
<translation type="unfinished"></translation>
</message>
@@ -6497,6 +6825,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>MainWindow</name>
+ <message>
+ <source>Display filter as %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>MainWindowPreferencesFrame</name>
<message>
<source>Frame</source>
@@ -6528,6 +6863,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>最近使用的文件夹</translation>
</message>
<message>
+ <source>The current working directory</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Show up to</source>
<translation>显示最多</translation>
</message>
@@ -6958,6 +7297,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Refresh</source>
+ <translation type="unfinished">刷新</translation>
+ </message>
+ <message>
<source>Save Diagram As…</source>
<translation type="unfinished"></translation>
</message>
@@ -7005,6 +7348,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Layout:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Packet %1</source>
<translation>分组 %1</translation>
</message>
@@ -7026,6 +7373,12 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<numerusform></numerusform>
</translation>
</message>
+ <message numerus="yes">
+ <source>%Ln bit(s)</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
+ </translation>
+ </message>
</context>
<context>
<name>PacketFormatGroupBox</name>
@@ -7484,10 +7837,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>复制该配置文件。</translation>
</message>
<message>
+ <source>The number of packets or events to check for automatic profile switching.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Auto switch packet limit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Configuration Profiles</source>
<translation>配置文件</translation>
</message>
<message>
+ <source>Auto switch event limit</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Import</source>
<comment>noun</comment>
<translation type="unfinished">导入</translation>
@@ -7651,6 +8016,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished"></translation>
</message>
<message>
+ <source>Auto Switch Filter</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>copy</source>
<comment>noun</comment>
<translation type="unfinished"></translation>
@@ -8010,6 +8379,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>窗口大小 (B)</translation>
</message>
<message>
+ <source>Unacked (Outstanding) Bytes (B)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>[no capture file]</source>
<translation>[无捕获文件]</translation>
</message>
@@ -8170,6 +8543,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>标记缺失?</translation>
</message>
<message>
+ <source>LTE</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>NR</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>C-RNTI</source>
<translation>C-RNTI</translation>
</message>
@@ -8190,6 +8571,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>UEId</translation>
</message>
<message>
+ <source>RAT</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>UL Frames</source>
<translation>UL 帧</translation>
</message>
@@ -8413,12 +8798,72 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Browse…</source>
<translation type="unfinished">浏览…</translation>
</message>
+ <message>
+ <source>PACKETS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>EVENTS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>BYTES</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>BITS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>COUNT FRAMES</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>COUNT FIELDS</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>SUM</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>MAX</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>MIN</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>AVERAGE</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>THROUGHPUT</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>LOAD</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Left</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Center</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Right</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
- <name>QObject::QObject</name>
+ <name>QObject::QObject::QObject</name>
<message>
<source>CCCH</source>
- <translation>CCCH</translation>
+ <translation type="unfinished">CCCH</translation>
</message>
</context>
<context>
@@ -8516,6 +8961,13 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>ResizeHeaderView</name>
+ <message>
+ <source>Resize all %1 to contents</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>ResolvedAddressesDialog</name>
<message>
<source>Dialog</source>
@@ -8631,6 +9083,14 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>解析后的地址</translation>
</message>
<message>
+ <source>Copy</source>
+ <translation type="unfinished">复制</translation>
+ </message>
+ <message>
+ <source>Save as…</source>
+ <translation type="unfinished">另存为…</translation>
+ </message>
+ <message>
<source># Resolved addresses found in %1</source>
<translation># 在 %1 中找到的解析后的地址</translation>
</message>
@@ -8644,6 +9104,61 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
</context>
<context>
+ <name>ResolvedAddressesView</name>
+ <message>
+ <source>as Plain Text</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy selected rows</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy table</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>as CSV</source>
+ <translation type="unfinished">作为 CSV</translation>
+ </message>
+ <message>
+ <source>as JSON</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save selected rows as…</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save table as…</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Save Resolved Addresses As…</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Plain text (*.txt)</source>
+ <translation type="unfinished">纯文本 (*.txt)</translation>
+ </message>
+ <message>
+ <source>CSV Document (*.csv)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>JSON Document (*.json)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Warning</source>
+ <translation type="unfinished">警告</translation>
+ </message>
+ <message>
+ <source>Unable to save %1: %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
<name>ResponseTimeDelayDialog</name>
<message>
<source>%1 Response Time Delay Statistics</source>
@@ -9412,7 +9927,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Left + Right</source>
- <translation type="unfinished"></translation>
+ <translation>左 + 右</translation>
</message>
<message>
<source>To Right</source>
@@ -9723,7 +10238,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Shift+R</source>
- <translation type="unfinished"></translation>
+ <translation>Shift+R</translation>
</message>
<message>
<source>Find Only &amp;Singles</source>
@@ -9735,7 +10250,7 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
</message>
<message>
<source>Ctrl+R</source>
- <translation type="unfinished"></translation>
+ <translation>Ctrl+R</translation>
</message>
<message>
<source>Mark Packets</source>
@@ -10318,6 +10833,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>分组字节流</translation>
</message>
<message>
+ <source>&lt;b&gt;Options:&lt;/b&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for strings containing narrow (UTF-8 and ASCII) or wide (UTF-16) characters.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;搜索包含窄字符集 (UTF-8 与 ASCII) 或宽字符集 (UTF-16) 的字符串。&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
</message>
@@ -10338,6 +10857,18 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>区分大小写</translation>
</message>
<message>
+ <source>Backwards</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for a subsequent occurrence in the current packet before advancing to the next packet.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Multiple occurrences</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5), a plain string (e.g. My String) or a regular expression (e.g. colou?r).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
<oldsource>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search for data using display filter syntax (e.g. ip.addr==10.1.1.1), a hexadecimal string (e.g. fffffda5) or a plain string (e.g. My String).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</oldsource>
<translation>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;以“显示过滤器”语法 (如 ip.addr==10.1.1.1)、十六进制字符串 (如 fffffda5) 或纯字符串 (如 My String) 搜索数据。&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</translation>
@@ -10375,6 +10906,22 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>无效过滤器。</translation>
</message>
<message>
+ <source>Event List</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Event Details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Event Bytes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Search the Info column of the event list (summary pane), decoded event display labels (tree view pane) or the ASCII-converted event data (hex view pane).&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>That filter doesn&apos;t test anything.</source>
<translation>该过滤器未测试任何项目。</translation>
</message>
@@ -10816,6 +11363,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>查找:</translation>
</message>
<message>
+ <source>Case sensitive</source>
+ <translation type="unfinished">区分大小写</translation>
+ </message>
+ <message>
<source>Find &amp;Next</source>
<translation>查找下一个(&amp;N)</translation>
</message>
@@ -10910,13 +11461,21 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation type="unfinished">另存为…</translation>
</message>
<message>
+ <source>Decoded as %1.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Save Selected Packet Bytes As…</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>compressed %1</source>
+ <translation type="unfinished"></translation>
+ </message>
<message numerus="yes">
- <source>Displaying %Ln byte(s).</source>
- <translation>
- <numerusform>已显示 %Ln 字节。</numerusform>
+ <source>Using %Ln byte(s).</source>
+ <translation type="unfinished">
+ <numerusform></numerusform>
</translation>
</message>
<message>
@@ -11016,6 +11575,10 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<source>Display filter:</source>
<translation type="unfinished"></translation>
</message>
+ <message>
+ <source>Strip Headers</source>
+ <translation type="unfinished"></translation>
+ </message>
</context>
<context>
<name>SupportedProtocolsDialog</name>
@@ -11985,22 +12548,20 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>创建一个新项。</translation>
</message>
<message>
- <source>Remove this entry.</source>
- <oldsource>Remove this profile.</oldsource>
- <translation>移除此项。</translation>
+ <source>Remove the selected entry(ies).</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Copy this entry.</source>
- <oldsource>Copy this profile.</oldsource>
- <translation>复制此项。</translation>
+ <source>Copy the selected entry(ies).</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry up.</source>
- <translation>向上移动条目。</translation>
+ <source>Move the selected entry(ies) up.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry down.</source>
- <translation>向下移动条目。</translation>
+ <source>Move the selected entry(ies) down.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Clear all entries.</source>
@@ -12026,20 +12587,20 @@ For example, use 1 hour to have a new file created every hour on the hour.</sour
<translation>创建一个新条目。</translation>
</message>
<message>
- <source>Remove this entry.</source>
- <translation>删除此条目。</translation>
+ <source>Remove the selected entry(ies).</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Copy this entry.</source>
- <translation>复制此条目。</translation>
+ <source>Copy the selected entry(ies).</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry up.</source>
- <translation>向上移动条目。</translation>
+ <source>Move the selected entry(ies) up.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>Move entry down.</source>
- <translation>向下移动条目。</translation>
+ <source>Move the selected entry(ies) down.</source>
+ <translation type="unfinished"></translation>
</message>
<message>
<source>Clear all entries.</source>
@@ -12367,10 +12928,18 @@ a:hover {
<translation>你正在使用 Wireshark 嗅探互联网的联机</translation>
</message>
<message>
+ <source>You are sniffing the glue that holds your system together using Logray </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>You are running Wireshark </source>
<translation>正在运行 Wireshark</translation>
</message>
<message>
+ <source>You are running Logray </source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source> You receive automatic updates.</source>
<translation>接受自动更新。</translation>
</message>
@@ -12647,14 +13216,6 @@ a:hover {
<translation>未找到文件</translation>
</message>
<message>
- <source>&amp;Contents</source>
- <translation>内容(&amp;C)</translation>
- </message>
- <message>
- <source>Wireshark Filter</source>
- <translation>Wireshark 过滤器</translation>
- </message>
- <message>
<source>TShark</source>
<translation>TShark</translation>
</message>
@@ -12920,10 +13481,6 @@ a:hover {
<translation>无线工具栏</translation>
</message>
<message>
- <source>Help contents</source>
- <translation>帮助内容</translation>
- </message>
- <message>
<source>FAQs</source>
<translation type="unfinished"></translation>
</message>
@@ -13044,11 +13601,6 @@ a:hover {
<translation>查找上一分组</translation>
</message>
<message>
- <source>&amp;Mark/Unmark Packet(s)</source>
- <oldsource>&amp;Mark/Unmark Packet</oldsource>
- <translation>标记/取消标记 分组(&amp;M)</translation>
- </message>
- <message>
<source>Mark All Displayed</source>
<translation>标记所有显示的分组</translation>
</message>
@@ -13077,11 +13629,6 @@ a:hover {
<translation>转到前一个已标记的分组</translation>
</message>
<message>
- <source>&amp;Ignore/Unignore Packet(s)</source>
- <oldsource>&amp;Ignore/Unignore Packet</oldsource>
- <translation>忽略/取消忽略 分组(&amp;I)</translation>
- </message>
- <message>
<source>Ignore All Displayed</source>
<translation>忽略所有显示的分组</translation>
</message>
@@ -13522,10 +14069,6 @@ a:hover {
<translation>重置布局</translation>
</message>
<message>
- <source>Reset appearance layout to default size</source>
- <translation>重置外观布局为默认尺寸</translation>
- </message>
- <message>
<source>Seconds Since First Captured Packet</source>
<translation type="unfinished"></translation>
</message>
@@ -13686,20 +14229,28 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
- <source>TLS Keylog Launcher</source>
+ <source>&amp;Options…</source>
+ <translation>选项(&amp;O)…</translation>
+ </message>
+ <message>
+ <source>&amp;3GPP Uu</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>Release Notes</source>
+ <source>&amp;Wireless</source>
+ <translation>无线(&amp;W)</translation>
+ </message>
+ <message>
+ <source>&amp;User&apos;s Guide</source>
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Options…</source>
- <translation>选项(&amp;O)…</translation>
+ <source>Wireshark User&apos;s Guide</source>
+ <translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;Wireless</source>
- <translation>无线(&amp;W)</translation>
+ <source>Display Filters</source>
+ <translation type="unfinished">显示过滤器</translation>
</message>
<message>
<source>Capture &amp;Filters…</source>
@@ -13746,10 +14297,18 @@ a:hover {
<translation>查找上一个(&amp;v)</translation>
</message>
<message>
+ <source>&amp;Mark/Unmark Selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Mark or unmark each selected packet</source>
<translation type="unfinished"></translation>
</message>
<message>
+ <source>&amp;Ignore/Unignore Selected</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Ignore or unignore each selected packet</source>
<translation type="unfinished"></translation>
</message>
@@ -13790,6 +14349,18 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
+ <source>General</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Query-Response</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>DNS Query-Response Statistics</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Request Sequences</source>
<translation>请求序列</translation>
</message>
@@ -13798,6 +14369,14 @@ a:hover {
<translation>HTTP 请求序列</translation>
</message>
<message>
+ <source>E2AP</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>E2AP Messages</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Decode &amp;As…</source>
<translation>解码为(&amp;A)…</translation>
</message>
@@ -13858,6 +14437,10 @@ a:hover {
<translation>普通大小</translation>
</message>
<message>
+ <source>Reset layout to default size</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>Resize Columns</source>
<translation>调整列宽</translation>
</message>
@@ -14116,6 +14699,14 @@ a:hover {
<translation>转至选定字段引用的分组。</translation>
</message>
<message>
+ <source>TLS Keylog Launcher</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Release Notes</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>&amp;VoIP Calls</source>
<translation>&amp;VoIP 通话</translation>
</message>
@@ -14148,10 +14739,6 @@ a:hover {
<translation type="unfinished"></translation>
</message>
<message>
- <source>&amp;LTE</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
<source>&amp;MTP3</source>
<translation type="unfinished"></translation>
</message>
@@ -14436,6 +15023,10 @@ a:hover {
<translation>直接退出,不保存(&amp;W)</translation>
</message>
<message>
+ <source>USB CDC Data</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
<source>There is no &quot;rtp.ssrc&quot; field in this version of Wireshark.</source>
<translation type="unfinished"></translation>
</message>
diff --git a/ui/qt/wlan_statistics_dialog.cpp b/ui/qt/wlan_statistics_dialog.cpp
index 0fc529ea..7166cbab 100644
--- a/ui/qt/wlan_statistics_dialog.cpp
+++ b/ui/qt/wlan_statistics_dialog.cpp
@@ -222,7 +222,7 @@ public:
} else if (wlan_hdr->stats.ssid_len == 1 && wlan_hdr->stats.ssid[0] == 0) {
ssid_text = QObject::tr("<Hidden>");
} else {
- gchar *str = format_text(NULL, (const char *)wlan_hdr->stats.ssid, wlan_hdr->stats.ssid_len);
+ char *str = format_text(NULL, (const char *)wlan_hdr->stats.ssid, wlan_hdr->stats.ssid_len);
ssid_text = str;
wmem_free(NULL, str);
}
@@ -293,7 +293,7 @@ public:
}
if (update_ssid) {
- gchar* str;
+ char* str;
ssid_ = QByteArray::fromRawData((const char *)wlan_hdr->stats.ssid, wlan_hdr->stats.ssid_len);
str = format_text(NULL, (const char *)wlan_hdr->stats.ssid, wlan_hdr->stats.ssid_len);
setText(col_ssid_, str);
@@ -571,7 +571,7 @@ tap_packet_status WlanStatisticsDialog::tapPacket(void *ws_dlg_ptr, _packet_info
const wlan_hdr_t *wlan_hdr = (const wlan_hdr_t *)wlan_hdr_ptr;
if (!ws_dlg || !wlan_hdr) return TAP_PACKET_DONT_REDRAW;
- guint16 frame_type = wlan_hdr->type & 0xff0;
+ uint16_t frame_type = wlan_hdr->type & 0xff0;
if (!((frame_type == 0x0) || (frame_type == 0x20) || (frame_type == 0x30))
|| ((frame_type == 0x20) && DATA_FRAME_IS_NULL(wlan_hdr->type))) {
/* Not a management or non null data or extension frame; let's skip it */