1 /* main_window_slots.cpp
3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
7 * SPDX-License-Identifier: GPL-2.0-or-later
12 // Qt 5.5.0 + Visual C++ 2013
15 #pragma warning(disable:4996)
18 #include "wireshark_main_window.h"
21 * The generated Ui_WiresharkMainWindow::setupUi() can grow larger than our configured limit,
22 * so turn off -Wframe-larger-than= for ui_wireshark_main_window.h.
24 DIAG_OFF(frame
-larger
-than
=)
25 #include <ui_wireshark_main_window.h>
26 DIAG_ON(frame
-larger
-than
=)
32 #include "ui/dissect_opts.h"
35 #include "ui/capture.h"
38 #include "ui/commandline.h"
42 #include "epan/color_filters.h"
43 #include "epan/export_object.h"
45 #include "wsutil/file_util.h"
46 #include "wsutil/filesystem.h"
47 #include <wsutil/wslog.h>
48 #include <wsutil/ws_assert.h>
50 #include "epan/addr_resolv.h"
51 #include "epan/column.h"
52 #include "epan/dfilter/dfilter-macro.h"
53 #include "epan/conversation_filter.h"
54 #include "epan/epan_dissect.h"
55 #include "epan/filter_expressions.h"
56 #include "epan/prefs.h"
57 #include "epan/plugin_if.h"
59 #include "epan/uat-int.h"
60 #include "epan/value_string.h"
63 #include <epan/wslua/init_wslua.h>
66 #include "ui/alert_box.h"
68 #include "ui/capture_ui_utils.h"
71 #include "ui/capture_globals.h"
72 #include "ui/help_url.h"
73 #include "ui/main_statusbar.h"
74 #include "ui/preference_utils.h"
75 #include "ui/recent.h"
76 #include "ui/recent_utils.h"
77 #include "ui/ssl_key_export.h"
78 #include "ui/ws_ui_util.h"
79 #include "ui/all_files_wildcard.h"
80 #include "ui/qt/simple_dialog.h"
82 #include <ui/qt/utils/variant_pointer.h>
83 #include <ui/qt/widgets/drag_drop_toolbar.h>
84 #include "ui/qt/widgets/wireshark_file_dialog.h"
86 #ifdef HAVE_SOFTWARE_UPDATE
87 #include "ui/software_update.h"
90 #include "about_dialog.h"
91 #include "bluetooth_att_server_attributes_dialog.h"
92 #include "bluetooth_devices_dialog.h"
93 #include "bluetooth_hci_summary_dialog.h"
94 #include "capture_file_dialog.h"
95 #include "capture_file_properties_dialog.h"
97 #include "capture_options_dialog.h"
99 #include <ui/qt/utils/color_utils.h>
100 #include "coloring_rules_dialog.h"
101 #include "conversation_dialog.h"
102 #include "conversation_colorize_action.h"
103 #include "conversation_hash_tables_dialog.h"
104 #include "enabled_protocols_dialog.h"
105 #include "decode_as_dialog.h"
106 #include <ui/qt/widgets/display_filter_edit.h>
107 #include "display_filter_expression_dialog.h"
108 #include "dissector_tables_dialog.h"
109 #include "endpoint_dialog.h"
110 #include "expert_info_dialog.h"
111 #include "export_object_action.h"
112 #include "export_object_dialog.h"
113 #include "export_pdu_dialog.h"
114 #include "extcap_options_dialog.h"
115 #include "file_set_dialog.h"
116 #include "filter_action.h"
117 #include "filter_dialog.h"
118 #include "firewall_rules_dialog.h"
119 #include "follow_stream_action.h"
120 #include "follow_stream_dialog.h"
121 #include "funnel_statistics.h"
122 #include "gsm_map_summary_dialog.h"
123 #include "iax2_analysis_dialog.h"
124 #include "interface_toolbar.h"
125 #include "io_graph_dialog.h"
126 #include <ui/qt/widgets/additional_toolbar.h>
127 #include "lbm_stream_dialog.h"
128 #include "lbm_lbtrm_transport_dialog.h"
129 #include "lbm_lbtru_transport_dialog.h"
130 #include "lte_mac_statistics_dialog.h"
131 #include "lte_rlc_statistics_dialog.h"
132 #include "lte_rlc_graph_dialog.h"
133 #include "main_application.h"
134 #include "manuf_dialog.h"
135 #include "mtp3_summary_dialog.h"
136 #include "multicast_statistics_dialog.h"
137 #include "packet_comment_dialog.h"
138 #include "packet_diagram.h"
139 #include "packet_dialog.h"
140 #include "packet_list.h"
141 #include "credentials_dialog.h"
142 #include "preferences_dialog.h"
143 #include "print_dialog.h"
144 #include "profile_dialog.h"
145 #include "protocol_hierarchy_dialog.h"
146 #include <ui/qt/utils/qt_ui_utils.h>
147 #include "resolved_addresses_dialog.h"
148 #include "rpc_service_response_time_dialog.h"
149 #include "rtp_stream_dialog.h"
150 #include "rtp_analysis_dialog.h"
151 #include "sctp_all_assocs_dialog.h"
152 #include "sctp_assoc_analyse_dialog.h"
153 #include "sctp_graph_dialog.h"
154 #include "sequence_dialog.h"
155 #include "show_packet_bytes_dialog.h"
156 #include "tlskeylog_launcher_dialog.h"
157 #include "stats_tree_dialog.h"
158 #include "strip_headers_dialog.h"
159 #include <ui/qt/utils/stock_icon.h>
160 #include "supported_protocols_dialog.h"
161 #include "tap_parameter_dialog.h"
162 #include "tcp_stream_dialog.h"
163 #include "time_shift_dialog.h"
164 #include "uat_dialog.h"
165 #include "voip_calls_dialog.h"
166 #include "wlan_statistics_dialog.h"
167 #include <ui/qt/widgets/wireless_timeline.h>
169 #include <functional>
170 #include <QClipboard>
172 #include <QMessageBox>
173 #include <QMetaObject>
175 #include <QDesktopServices>
179 // XXX You must uncomment QT_WINEXTRAS_LIB lines in CMakeList.txt and
181 // #if defined(QT_WINEXTRAS_LIB)
182 // #include <QWinJumpList>
183 // #include <QWinJumpListCategory>
184 // #include <QWinJumpListItem>
191 bool WiresharkMainWindow::openCaptureFile(QString cf_path
, QString read_filter
, unsigned int type
, bool is_tempfile
)
193 QString file_name
= "";
194 dfilter_t
*rfcode
= NULL
;
195 df_error_t
*df_err
= NULL
;
200 // was a file name given as function parameter?
201 name_param
= !cf_path
.isEmpty();
205 if (cf_path
.isEmpty()) {
206 CaptureFileDialog
open_dlg(this, capture_file_
.capFile());
208 if (open_dlg
.open(file_name
, type
, read_filter
)) {
215 this->welcome_page_
->getInterfaceFrame()->showRunOnFile();
218 // TODO detect call from "cf_read" -> "update_progress_dlg"
219 // ("capture_file_.capFile()->read_lock"), possibly queue opening the
220 // file and return early to avoid the warning in testCaptureFileClose.
222 QString
before_what(tr(" before opening another file"));
223 if (!testCaptureFileClose(before_what
)) {
228 if (dfilter_compile(qUtf8Printable(read_filter
), &rfcode
, &df_err
)) {
229 cf_set_rfcode(CaptureFile::globalCapFile(), rfcode
);
231 /* Not valid. Tell the user, and go back and run the file
232 selection box again once they dismiss the alert. */
233 //bad_dfilter_alert_box(top_level, read_filter->str);
234 QMessageBox::warning(this, tr("Invalid Display Filter"),
235 QStringLiteral("The filter expression ") +
237 QStringLiteral(" isn't a valid display filter. (") +
238 df_err
->msg
+ QStringLiteral(")."),
240 df_error_free(&df_err
);
242 // go back to the selection dialogue only if the file
243 // was selected from this dialogue
249 /* Make the file name available via MainWindow */
250 setMwFileName(cf_path
);
252 /* Try to open the capture file. This closes the current file if it succeeds. */
253 CaptureFile::globalCapFile()->window
= this;
254 if (cf_open(CaptureFile::globalCapFile(), qUtf8Printable(cf_path
), type
, is_tempfile
, &err
) != CF_OK
) {
255 /* We couldn't open it; don't dismiss the open dialog box,
256 just leave it around so that the user can, after they
257 dismiss the alert box popped up for the open error,
259 CaptureFile::globalCapFile()->window
= NULL
;
260 dfilter_free(rfcode
);
265 switch (cf_read(CaptureFile::globalCapFile(), /*reloading=*/false)) {
268 /* Just because we got an error, that doesn't mean we were unable
269 to read any of the file; we handle what we could get from the
273 case CF_READ_ABORTED
:
274 /* The user bailed out of re-reading the capture file; the
275 capture file has been closed - just free the capture file name
276 string and return (without changing the last containing
278 capture_file_
.setCapFile(NULL
);
286 mainApp
->setLastOpenDirFromFilename(cf_path
);
289 main_ui_
->statusBar
->showExpert();
293 if (global_commandline_info
.quit_after_cap
)
299 void WiresharkMainWindow::filterPackets(QString new_filter
, bool force
)
301 cf_status_t cf_status
;
303 cf_status
= cf_filter_packets(CaptureFile::globalCapFile(), new_filter
.toUtf8().data(), force
);
305 if (cf_status
== CF_OK
) {
306 if (new_filter
.length() > 0) {
307 int index
= df_combo_box_
->findText(new_filter
);
309 df_combo_box_
->insertItem(0, new_filter
);
310 df_combo_box_
->setCurrentIndex(0);
312 df_combo_box_
->setCurrentIndex(index
);
315 df_combo_box_
->lineEdit()->clear();
317 // Only after the display filter has been updated,
318 // disable the arrow button
319 emit
displayFilterSuccess(true);
321 emit
displayFilterSuccess(false);
325 void WiresharkMainWindow::layoutToolbars()
327 Qt::ToolButtonStyle tbstyle
= Qt::ToolButtonIconOnly
;
328 switch (prefs
.gui_toolbar_main_style
) {
330 tbstyle
= Qt::ToolButtonTextOnly
;
333 tbstyle
= Qt::ToolButtonTextUnderIcon
;
337 main_ui_
->mainToolBar
->setToolButtonStyle(tbstyle
);
339 main_ui_
->mainToolBar
->setVisible(recent
.main_toolbar_show
);
340 main_ui_
->displayFilterToolBar
->setVisible(recent
.filter_toolbar_show
);
341 #if defined(HAVE_LIBNL) && defined(HAVE_NL80211)
342 main_ui_
->wirelessToolBar
->setVisible(recent
.wireless_toolbar_show
);
344 main_ui_
->statusBar
->setVisible(recent
.statusbar_show
);
346 foreach(QAction
*action
, main_ui_
->menuInterfaceToolbars
->actions()) {
347 QToolBar
*toolbar
= action
->data().value
<QToolBar
*>();
348 if (g_list_find_custom(recent
.interface_toolbars
, action
->text().toUtf8(), (GCompareFunc
)strcmp
)) {
349 toolbar
->setVisible(true);
351 toolbar
->setVisible(false);
355 QList
<QToolBar
*> toolbars
= findChildren
<QToolBar
*>();
356 foreach(QToolBar
*bar
, toolbars
) {
357 AdditionalToolBar
*iftoolbar
= dynamic_cast<AdditionalToolBar
*>(bar
);
359 bool visible
= false;
360 if (g_list_find_custom(recent
.gui_additional_toolbars
, qUtf8Printable(iftoolbar
->menuName()), (GCompareFunc
)strcmp
))
363 iftoolbar
->setVisible(visible
);
369 static const char* layout_icons
[] = {
379 void WiresharkMainWindow::updatePreferenceActions()
381 main_ui_
->actionViewPacketList
->setEnabled(prefs_has_layout_pane_content(layout_pane_content_plist
));
382 main_ui_
->actionViewPacketDetails
->setEnabled(prefs_has_layout_pane_content(layout_pane_content_pdetails
));
383 main_ui_
->actionViewPacketBytes
->setEnabled(prefs_has_layout_pane_content(layout_pane_content_pbytes
));
384 main_ui_
->actionViewPacketDiagram
->setEnabled(prefs_has_layout_pane_content(layout_pane_content_pdiagram
));
386 main_ui_
->actionViewNameResolutionPhysical
->setChecked(gbl_resolv_flags
.mac_name
);
387 main_ui_
->actionViewNameResolutionNetwork
->setChecked(gbl_resolv_flags
.network_name
);
388 main_ui_
->actionViewNameResolutionTransport
->setChecked(gbl_resolv_flags
.transport_name
);
390 if (prefs
.gui_layout_type
> 0)
391 main_ui_
->actionViewResetLayout
->setIcon(StockIcon(layout_icons
[prefs
.gui_layout_type
]));
394 void WiresharkMainWindow::updateRecentActions()
396 main_ui_
->actionViewMainToolbar
->setChecked(recent
.main_toolbar_show
);
397 main_ui_
->actionViewFilterToolbar
->setChecked(recent
.filter_toolbar_show
);
398 main_ui_
->actionViewWirelessToolbar
->setChecked(recent
.wireless_toolbar_show
);
399 main_ui_
->actionViewStatusBar
->setChecked(recent
.statusbar_show
);
400 main_ui_
->actionViewPacketList
->setChecked(recent
.packet_list_show
&& prefs_has_layout_pane_content(layout_pane_content_plist
));
401 main_ui_
->actionViewPacketDetails
->setChecked(recent
.tree_view_show
&& prefs_has_layout_pane_content(layout_pane_content_pdetails
));
402 main_ui_
->actionViewPacketBytes
->setChecked(recent
.byte_view_show
&& prefs_has_layout_pane_content(layout_pane_content_pbytes
));
403 main_ui_
->actionViewPacketDiagram
->setChecked(recent
.packet_diagram_show
&& prefs_has_layout_pane_content(layout_pane_content_pdiagram
));
405 foreach(QAction
*action
, main_ui_
->menuInterfaceToolbars
->actions()) {
406 if (g_list_find_custom(recent
.interface_toolbars
, action
->text().toUtf8(), (GCompareFunc
)strcmp
)) {
407 action
->setChecked(true);
409 action
->setChecked(false);
413 foreach(QAction
* action
, main_ui_
->menuAdditionalToolbars
->actions()) {
414 ext_toolbar_t
* toolbar
= VariantPointer
<ext_toolbar_t
>::asPtr(action
->data());
415 bool checked
= false;
416 if (toolbar
&& g_list_find_custom(recent
.gui_additional_toolbars
, toolbar
->name
, (GCompareFunc
)strcmp
))
419 action
->setChecked(checked
);
422 foreach(QAction
* tda
, td_actions
.keys()) {
423 if (recent
.gui_time_format
== td_actions
[tda
]) {
424 tda
->setChecked(true);
427 foreach(QAction
* tpa
, tp_actions
.keys()) {
428 if (recent
.gui_time_precision
== tp_actions
[tpa
]) {
429 tpa
->setChecked(true);
433 main_ui_
->actionViewTimeDisplaySecondsWithHoursAndMinutes
->setChecked(recent
.gui_seconds_format
== TS_SECONDS_HOUR_MIN_SEC
);
435 main_ui_
->actionViewColorizePacketList
->setChecked(recent
.packet_list_colorize
);
437 main_ui_
->actionGoAutoScroll
->setChecked(recent
.capture_auto_scroll
);
440 // Don't connect to this directly. Connect to or emit filterAction(...) instead.
441 void WiresharkMainWindow::queuedFilterAction(QString action_filter
, FilterAction::Action action
, FilterAction::ActionType type
)
443 QString cur_filter
, new_filter
;
445 if (!df_combo_box_
) return;
446 cur_filter
= df_combo_box_
->lineEdit()->text();
449 case FilterAction::ActionTypePlain
:
450 new_filter
= action_filter
;
452 case FilterAction::ActionTypeAnd
:
453 if (cur_filter
.length()) {
454 new_filter
= "(" + cur_filter
+ ") && (" + action_filter
+ ")";
457 new_filter
= action_filter
;
460 case FilterAction::ActionTypeOr
:
461 if (cur_filter
.length()) {
462 new_filter
= "(" + cur_filter
+ ") || (" + action_filter
+ ")";
464 new_filter
= action_filter
;
467 case FilterAction::ActionTypeNot
:
468 new_filter
= "!(" + action_filter
+ ")";
470 case FilterAction::ActionTypeAndNot
:
471 if (cur_filter
.length()) {
472 new_filter
= "(" + cur_filter
+ ") && !(" + action_filter
+ ")";
474 new_filter
= "!(" + action_filter
+ ")";
477 case FilterAction::ActionTypeOrNot
:
478 if (cur_filter
.length()) {
479 new_filter
= "(" + cur_filter
+ ") || !(" + action_filter
+ ")";
481 new_filter
= "!(" + action_filter
+ ")";
485 ws_assert_not_reached();
490 case FilterAction::ActionApply
:
491 df_combo_box_
->lineEdit()->setText(new_filter
);
492 df_combo_box_
->applyDisplayFilter();
494 case FilterAction::ActionColorize
:
495 colorizeWithFilter(new_filter
.toUtf8());
497 case FilterAction::ActionCopy
:
498 mainApp
->clipboard()->setText(new_filter
);
500 case FilterAction::ActionFind
:
501 main_ui_
->searchFrame
->findFrameWithFilter(new_filter
);
503 case FilterAction::ActionPrepare
:
504 df_combo_box_
->lineEdit()->setText(new_filter
);
505 df_combo_box_
->lineEdit()->setFocus();
507 case FilterAction::ActionWebLookup
:
509 QString url
= QStringLiteral("https://www.google.com/search?q=") + new_filter
;
510 QDesktopServices::openUrl(QUrl(url
));
514 ws_assert_not_reached();
522 void WiresharkMainWindow::captureCapturePrepared(capture_session
*session
) {
523 setTitlebarForCaptureInProgress();
524 setWindowIcon(mainApp
->captureIcon());
525 pushLiveCaptureInProgress();
527 /* Disable menu items that make no sense if you're currently running
529 bool handle_toolbars
= (session
->session_will_restart
? false : true);
530 setForCaptureInProgress(true, handle_toolbars
, session
->capture_opts
->ifaces
);
531 // set_capture_if_dialog_for_capture_in_progress(true);
533 // /* Don't set up main window for a capture file. */
534 // main_set_for_capture_file(false);
538 void WiresharkMainWindow::captureCaptureUpdateStarted(capture_session
*session
) {
540 /* We've done this in "prepared" above, but it will be cleared while
541 switching to the next multiple file. */
542 setTitlebarForCaptureInProgress();
543 setWindowIcon(mainApp
->captureIcon());
544 pushLiveCaptureInProgress();
546 bool handle_toolbars
= (session
->session_will_restart
? false : true);
547 setForCaptureInProgress(true, handle_toolbars
, session
->capture_opts
->ifaces
);
549 setForCapturedPackets(true);
552 void WiresharkMainWindow::captureCaptureUpdateFinished(capture_session
*session
) {
554 /* The capture isn't stopping any more - it's stopped. */
555 capture_stopping_
= false;
557 /* Update the main window as appropriate */
558 updateForUnsavedChanges();
559 setTitlebarForCaptureFile();
561 /* Enable menu items that make sense if you're not currently running
563 bool handle_toolbars
= (session
->session_will_restart
? false : true);
564 setForCaptureInProgress(false, handle_toolbars
);
565 setMenusForCaptureFile();
567 setWindowIcon(mainApp
->normalIcon());
568 popLiveCaptureInProgress();
570 if (global_commandline_info
.quit_after_cap
) {
571 // Command line asked us to quit after capturing.
572 // Don't pop up a dialog to ask for unsaved files etc.
577 void WiresharkMainWindow::captureCaptureFixedFinished(capture_session
*) {
579 /* The capture isn't stopping any more - it's stopped. */
580 capture_stopping_
= false;
581 setTitlebarForCaptureFile();
583 /* Enable menu items that make sense if you're not currently running
585 setForCaptureInProgress(false);
586 /* There isn't a real capture_file structure yet, so just force disabling
587 menu options. They will "refresh" when the capture file is reloaded to
589 setMenusForCaptureFile(true);
591 setWindowIcon(mainApp
->normalIcon());
592 popLiveCaptureInProgress();
594 if (global_commandline_info
.quit_after_cap
) {
595 // Command line asked us to quit after capturing.
596 // Don't pop up a dialog to ask for unsaved files etc.
601 void WiresharkMainWindow::captureCaptureFailed(capture_session
*) {
602 /* Capture isn't stopping any more. */
603 capture_stopping_
= false;
604 setTitlebarForCaptureFile();
605 setForCaptureInProgress(false);
608 // Reset expert information indicator
609 main_ui_
->statusBar
->captureFileClosing();
610 mainApp
->popStatus(WiresharkApplication::FileStatus
);
612 setWindowIcon(mainApp
->normalIcon());
613 popLiveCaptureInProgress();
615 if (global_commandline_info
.quit_after_cap
) {
616 // Command line asked us to quit after capturing.
617 // Don't pop up a dialog to ask for unsaved files etc.
621 #endif // HAVE_LIBPCAP
623 // Callbacks from cfile.c and file.c via CaptureFile::captureFileCallback
625 void WiresharkMainWindow::captureEventHandler(CaptureEvent ev
)
627 switch (ev
.captureContext()) {
629 case CaptureEvent::File
:
630 switch (ev
.eventType()) {
631 case CaptureEvent::Opened
:
634 case CaptureEvent::Closing
:
635 captureFileClosing();
637 case CaptureEvent::Closed
:
640 case CaptureEvent::Started
:
641 captureFileReadStarted(tr("Loading"));
643 case CaptureEvent::Finished
:
644 captureFileReadFinished();
651 case CaptureEvent::Reload
:
652 switch (ev
.eventType()) {
653 case CaptureEvent::Started
:
654 captureFileReadStarted(tr("Reloading"));
656 case CaptureEvent::Finished
:
657 captureFileReadFinished();
664 case CaptureEvent::Rescan
:
665 switch (ev
.eventType()) {
666 case CaptureEvent::Started
:
667 setMenusForCaptureFile(true);
668 captureFileReadStarted(tr("Rescanning"));
670 case CaptureEvent::Finished
:
671 captureFileReadFinished();
678 case CaptureEvent::Retap
:
679 switch (ev
.eventType()) {
680 case CaptureEvent::Started
:
683 case CaptureEvent::Finished
:
686 case CaptureEvent::Flushed
:
687 draw_tap_listeners(false);
694 case CaptureEvent::Merge
:
695 switch (ev
.eventType()) {
696 case CaptureEvent::Started
:
697 mainApp
->popStatus(WiresharkApplication::FileStatus
);
698 mainApp
->pushStatus(WiresharkApplication::FileStatus
, tr("Merging files."), QString());
700 case CaptureEvent::Finished
:
701 mainApp
->popStatus(WiresharkApplication::FileStatus
);
708 case CaptureEvent::Save
:
709 switch (ev
.eventType()) {
710 case CaptureEvent::Started
:
712 QFileInfo
file_info(ev
.filePath());
713 mainApp
->popStatus(WiresharkApplication::FileStatus
);
714 mainApp
->pushStatus(WiresharkApplication::FileStatus
, tr("Saving %1…").arg(file_info
.fileName()));
723 case CaptureEvent::Capture
:
724 switch (ev
.eventType()) {
725 case CaptureEvent::Prepared
:
726 captureCapturePrepared(ev
.capSession());
728 case CaptureEvent::Stopping
:
729 capture_stopping_
= true;
730 setMenusForCaptureStopping();
732 case CaptureEvent::Failed
:
733 captureCaptureFailed(ev
.capSession());
739 case CaptureEvent::Update
:
740 switch (ev
.eventType()) {
741 case CaptureEvent::Started
:
742 captureCaptureUpdateStarted(ev
.capSession());
744 case CaptureEvent::Finished
:
745 captureCaptureUpdateFinished(ev
.capSession());
752 case CaptureEvent::Fixed
:
753 switch (ev
.eventType()) {
754 case CaptureEvent::Finished
:
755 captureCaptureFixedFinished(ev
.capSession());
765 void WiresharkMainWindow::captureFileOpened() {
766 if (capture_file_
.window() != this) return;
768 file_set_dialog_
->fileOpened(capture_file_
.capFile());
769 setMenusForFileSet(true);
770 emit
setCaptureFile(capture_file_
.capFile());
773 void WiresharkMainWindow::captureFileReadStarted(const QString
&action
) {
774 // tap_param_dlg_update();
776 /* Set up main window for a capture file. */
777 // main_set_for_capture_file(true);
779 mainApp
->popStatus(WiresharkApplication::FileStatus
);
780 QString msg
= tr("%1: %2").arg(action
).arg(capture_file_
.fileName());
781 QString msgtip
= QString();
782 mainApp
->pushStatus(WiresharkApplication::FileStatus
, msg
, msgtip
);
784 main_ui_
->actionAnalyzeReloadLuaPlugins
->setEnabled(false);
785 main_ui_
->wirelessTimelineWidget
->captureFileReadStarted(capture_file_
.capFile());
788 void WiresharkMainWindow::captureFileReadFinished() {
789 if (!capture_file_
.capFile()->is_tempfile
&& capture_file_
.capFile()->filename
) {
790 /* Add this filename to the list of recent files in the "Recent Files" submenu */
791 add_menu_recent_capture_file(capture_file_
.capFile()->filename
, false);
793 /* Remember folder for next Open dialog and save it in recent */
794 mainApp
->setLastOpenDirFromFilename(capture_file_
.capFile()->filename
);
797 /* Update the appropriate parts of the main window. */
798 updateForUnsavedChanges();
800 /* enable wireless timeline if capture allows it */
801 main_ui_
->wirelessTimelineWidget
->captureFileReadFinished();
803 /* Enable menu items that make sense if you have some captured packets. */
804 setForCapturedPackets(true);
806 main_ui_
->statusBar
->setFileName(capture_file_
);
807 main_ui_
->actionAnalyzeReloadLuaPlugins
->setEnabled(true);
809 packet_list_
->captureFileReadFinished();
811 emit
setDissectedCaptureFile(capture_file_
.capFile());
814 void WiresharkMainWindow::captureFileClosing() {
815 setMenusForCaptureFile(true);
816 setTitlebarForCaptureFile();
817 setForCapturedPackets(false);
818 setForCaptureInProgress(false);
820 // Reset expert information indicator
821 main_ui_
->statusBar
->captureFileClosing();
822 main_ui_
->searchFrame
->animatedHide();
823 main_ui_
->goToFrame
->animatedHide();
824 // gtk_widget_show(expert_info_none);
825 emit
setCaptureFile(NULL
);
826 emit
setDissectedCaptureFile(NULL
);
829 void WiresharkMainWindow::captureFileClosed() {
830 packets_bar_update();
832 file_set_dialog_
->fileClosed();
833 setMenusForFileSet(false);
834 setWindowModified(false);
836 // Reset expert information indicator
837 main_ui_
->statusBar
->captureFileClosing();
838 mainApp
->popStatus(WiresharkApplication::FileStatus
);
841 setWindowIcon(mainApp
->normalIcon());
842 setMenusForSelectedPacket();
843 setMenusForSelectedTreeRow();
846 if (!global_capture_opts
.multi_files_on
)
855 // ui/gtk/capture_dlg.c:start_capture_confirmed
857 void WiresharkMainWindow::startCapture() {
858 startCapture(QStringList());
861 void WiresharkMainWindow::startCapture(QStringList interfaces
) {
863 interface_options
*interface_opts
;
866 bool can_start_capture
= true;
868 if (interfaces
.count() > 0) {
869 global_capture_opts
.num_selected
= 0;
870 for (i
= 0; i
< global_capture_opts
.all_ifaces
->len
; i
++) {
871 device
= &g_array_index(global_capture_opts
.all_ifaces
, interface_t
, i
);
873 if (interfaces
.contains(device
->name
)) {
874 device
->selected
= true;
875 global_capture_opts
.num_selected
++;
878 device
->selected
= false;
883 /* did the user ever select a capture interface before? */
884 if (global_capture_opts
.num_selected
== 0) {
885 QString msg
= tr("No interface selected.");
886 mainApp
->pushStatus(WiresharkApplication::TemporaryStatus
, msg
);
887 main_ui_
->actionCaptureStart
->setChecked(false);
891 for (i
= 0; i
< global_capture_opts
.all_ifaces
->len
; i
++) {
892 device
= &g_array_index(global_capture_opts
.all_ifaces
, interface_t
, i
);
893 if (device
->selected
&& (device
->if_info
.type
== IF_EXTCAP
)) {
894 /* device is EXTCAP and is selected. Check if all mandatory
897 if (extcap_requires_configuration(device
->name
))
899 /* Request opening of extcap options dialog */
900 QString
device_name(device
->name
);
901 emit
showExtcapOptions(device_name
, false);
902 /* Cancel start of capture */
903 can_start_capture
= false;
908 /* If some of extcap was not configured, do not start with the capture */
909 if (!can_start_capture
) {
910 QString msg
= tr("Configure all extcaps before start of capture.");
911 mainApp
->pushStatus(WiresharkApplication::TemporaryStatus
, msg
);
912 main_ui_
->actionCaptureStart
->setChecked(false);
916 // Ideally we should have disabled the start capture
917 // toolbar buttons and menu items. This may not be the
918 // case, e.g. with QtMacExtras.
919 if (!capture_filter_valid_
) {
920 QString msg
= tr("Invalid capture filter.");
921 mainApp
->pushStatus(WiresharkApplication::TemporaryStatus
, msg
);
922 main_ui_
->actionCaptureStart
->setChecked(false);
928 /* XXX - we might need to init other pref data as well... */
929 main_ui_
->actionGoAutoScroll
->setChecked(recent
.capture_auto_scroll
);
931 /* XXX - can this ever happen? */
932 if (cap_session_
.state
!= CAPTURE_STOPPED
)
935 /* close the currently loaded capture file */
936 cf_close((capture_file
*)cap_session_
.cf
);
938 /* Copy the selected interfaces to the set of interfaces to use for
940 collect_ifaces(&global_capture_opts
);
942 CaptureFile::globalCapFile()->window
= this;
943 info_data_
.ui
.ui
= this;
944 if (capture_start(&global_capture_opts
, NULL
, &cap_session_
, &info_data_
,
945 main_window_update
)) {
946 /* The capture succeeded, which means the capture filter syntax is
947 valid; add this capture filter to the recent capture filter list. */
948 QByteArray filter_ba
;
949 for (i
= 0; i
< global_capture_opts
.ifaces
->len
; i
++) {
950 interface_opts
= &g_array_index(global_capture_opts
.ifaces
, interface_options
, i
);
951 if (interface_opts
->cfilter
) {
952 recent_add_cfilter(interface_opts
->name
, interface_opts
->cfilter
);
953 if (filter_ba
.isEmpty()) {
954 filter_ba
= interface_opts
->cfilter
;
956 /* Not the first selected interface; is its capture filter
957 the same as the one the other interfaces we've looked
959 /* XXX: GCC 12.1 has a bogus warning at -O2 and higher
960 * even though the isEmpty() check guarantees that
961 * filter_ba.constData() is never NULL or empty.
963 #if WS_IS_AT_LEAST_GNUC_VERSION(12,1)
964 DIAG_OFF(stringop
-overread
)
966 if (strcmp(interface_opts
->cfilter
, filter_ba
.constData()) != 0) {
967 #if WS_IS_AT_LEAST_GNUC_VERSION(12,1)
968 DIAG_ON(stringop
-overread
)
970 /* No, so not all selected interfaces have the same capture
977 if (!filter_ba
.isEmpty()) {
978 recent_add_cfilter(NULL
, filter_ba
.constData());
981 CaptureFile::globalCapFile()->window
= NULL
;
983 #else // HAVE_LIBPCAP
985 #endif // HAVE_LIBPCAP
988 void WiresharkMainWindow::pushLiveCaptureInProgress() {
990 capture_options
*capture_opts
= cap_session_
.capture_opts
;
991 GString
*interface_names
;
993 /* Add "interface name<live capture in progress>" on main status bar */
994 interface_names
= get_iface_list_string(capture_opts
, 0);
995 if (strlen(interface_names
->str
) > 0) {
996 g_string_append(interface_names
, ":");
998 g_string_append(interface_names
, " ");
1000 mainApp
->popStatus(WiresharkApplication::FileStatus
);
1001 QString msg
= QStringLiteral("%1<live capture in progress>").arg(interface_names
->str
);
1002 QString msgtip
= QStringLiteral("to file: ");
1003 if (capture_opts
->save_file
)
1004 msgtip
+= capture_opts
->save_file
;
1005 mainApp
->pushStatus(WiresharkApplication::FileStatus
, msg
, msgtip
);
1006 g_string_free(interface_names
, TRUE
);
1007 #endif // HAVE_LIBPCAP
1010 void WiresharkMainWindow::popLiveCaptureInProgress() {
1011 /* Pop the "<live capture in progress>" message off the status bar. */
1012 main_ui_
->statusBar
->setFileName(capture_file_
);
1015 void WiresharkMainWindow::stopCapture() {
1018 capture_stop(&cap_session_
);
1019 #endif // HAVE_LIBPCAP
1023 // Keep focus rects from showing through the welcome screen. Primarily for
1025 void WiresharkMainWindow::mainStackChanged(int)
1027 for (int i
= 0; i
< main_ui_
->mainStack
->count(); i
++) {
1028 main_ui_
->mainStack
->widget(i
)->setEnabled(i
== main_ui_
->mainStack
->currentIndex());
1032 // XXX - Copied from ui/gtk/menus.c
1035 * Add the capture filename (with an absolute path) to the "Recent Files" menu.
1037 // XXX - We should probably create a RecentFile class.
1038 void WiresharkMainWindow::updateRecentCaptures() {
1040 QMenu
*recentMenu
= main_ui_
->menuOpenRecentCaptureFile
;
1041 QString action_cf_name
;
1046 recentMenu
->clear();
1049 #if defined(QT_WINEXTRAS_LIB)
1050 QWinJumpList
recent_jl(this);
1051 QWinJumpListCategory
*recent_jlc
= recent_jl
.recent();
1053 recent_jlc
->clear();
1054 recent_jlc
->setVisible(true);
1058 #if defined(Q_OS_MAC)
1060 dock_menu_
= new QMenu();
1061 dock_menu_
->setAsDockMenu();
1063 dock_menu_
->clear();
1066 /* Iterate through the actions in menuOpenRecentCaptureFile,
1067 * removing special items, a maybe duplicate entry and every item above count_max */
1068 #if defined(Q_OS_MAC)
1069 int shortcut
= Qt::Key_0
;
1071 foreach(recent_item_status
*ri
, mainApp
->recentItems()) {
1073 ra
= new QAction(recentMenu
);
1074 ra
->setData(ri
->filename
);
1075 // XXX - Needs get_recent_item_status or equivalent
1076 ra
->setEnabled(ri
->accessible
);
1077 recentMenu
->insertAction(NULL
, ra
);
1078 action_cf_name
= ra
->data().toString();
1079 #if defined(Q_OS_MAC)
1080 if (shortcut
<= Qt::Key_9
) {
1081 ra
->setShortcut(Qt::META
| (Qt::Key
)shortcut
);
1085 ra
->setText(action_cf_name
);
1086 connect(ra
, &QAction::triggered
, this, &WiresharkMainWindow::recentActionTriggered
);
1088 /* This is slow, at least on my VM here. The added links also open Wireshark
1089 * in a new window. It might make more sense to add a recent item when we
1090 * open a capture file. */
1092 #if defined(QT_WINEXTRAS_LIB)
1094 QFileInfo
fi(ri
->filename
);
1095 QWinJumpListItem
*jli
= recent_jlc
->addLink(
1097 QApplication::applicationFilePath(),
1098 QStringList() << "-r" << ri
->filename
1101 jli
->setWorkingDirectory(QDir::toNativeSeparators(QApplication::applicationDirPath()));
1105 #if defined(Q_OS_MAC)
1106 QAction
*rda
= new QAction(dock_menu_
);
1107 QFileInfo
fi(ri
->filename
);
1108 rda
->setText(fi
.fileName());
1109 dock_menu_
->insertAction(NULL
, rda
);
1110 connect(rda
, &QAction::triggered
, ra
, &QAction::trigger
);
1112 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
1113 if (recentMenu
->actions().count() == static_cast<int>(prefs
.gui_recent_files_count_max
)) {
1115 if (recentMenu
->actions().count() == static_cast<qsizetype
>(prefs
.gui_recent_files_count_max
)) {
1121 if (recentMenu
->actions().count() > 0) {
1122 // Separator + "Clear"
1123 // XXX - Do we really need this?
1124 ra
= new QAction(recentMenu
);
1125 ra
->setSeparator(true);
1126 recentMenu
->insertAction(NULL
, ra
);
1128 ra
= new QAction(recentMenu
);
1129 ra
->setText(tr("Clear Menu"));
1130 recentMenu
->insertAction(NULL
, ra
);
1131 connect(ra
, &QAction::triggered
, mainApp
, &MainApplication::clearRecentCaptures
);
1133 if (main_ui_
->actionDummyNoFilesFound
) {
1134 recentMenu
->addAction(main_ui_
->actionDummyNoFilesFound
);
1139 void WiresharkMainWindow::recentActionTriggered() {
1140 QAction
*ra
= qobject_cast
<QAction
*>(sender());
1143 QString cfPath
= ra
->data().toString();
1144 openCaptureFile(cfPath
);
1148 QString
WiresharkMainWindow::commentToMenuText(QString text
, int max_len
)
1150 text
= text
.trimmed().replace(QRegularExpression("(\\r?\\n|\\r\\n?)+"), " ");
1151 if (text
.size() > 0) {
1152 if (text
.size() > max_len
) {
1153 text
.truncate(max_len
);
1158 text
= tr("(empty comment)", "placeholder for empty comment");
1163 void WiresharkMainWindow::setEditCommentsMenu()
1165 main_ui_
->menuPacketComment
->clear();
1166 QAction
*action
= main_ui_
->menuPacketComment
->addAction(tr("Add New Comment…"));
1167 connect(action
, &QAction::triggered
, this, &WiresharkMainWindow::addPacketComment
);
1168 action
->setShortcut(QKeySequence(Qt::CTRL
| Qt::ALT
| Qt::Key_C
));
1169 if (selectedRows().count() == 1) {
1170 const int thisRow
= selectedRows().first();
1171 frame_data
* current_frame
= frameDataForRow(thisRow
);
1172 wtap_block_t pkt_block
= cf_get_packet_block(capture_file_
.capFile(), current_frame
);
1173 unsigned nComments
= wtap_block_count_option(pkt_block
, OPT_COMMENT
);
1174 if (nComments
> 0) {
1175 main_ui_
->menuPacketComment
->addSeparator();
1176 for (unsigned i
= 0; i
< nComments
; i
++) {
1177 QString comment
= packet_list_
->getPacketComment(i
);
1178 comment
= this->commentToMenuText(comment
);
1179 action
= main_ui_
->menuPacketComment
->addAction(tr("Edit \"%1\"", "edit packet comment").arg(comment
));
1180 connect(action
, &QAction::triggered
, this, &WiresharkMainWindow::editPacketComment
);
1184 main_ui_
->menuPacketComment
->addSeparator();
1185 for (unsigned i
= 0; i
< nComments
; i
++) {
1186 QString comment
= packet_list_
->getPacketComment(i
);
1187 comment
= this->commentToMenuText(comment
);
1188 action
= main_ui_
->menuPacketComment
->addAction(tr("Delete \"%1\"", "delete packet comment").arg(comment
));
1189 connect(action
, &QAction::triggered
, this, &WiresharkMainWindow::deletePacketComment
);
1192 main_ui_
->menuPacketComment
->addSeparator();
1193 action
= main_ui_
->menuPacketComment
->addAction(tr("Delete packet comments"));
1194 connect(action
, &QAction::triggered
, this, &WiresharkMainWindow::deleteCommentsFromPackets
);
1196 wtap_block_unref(pkt_block
);
1198 if (selectedRows().count() > 1) {
1199 main_ui_
->menuPacketComment
->addSeparator();
1200 action
= main_ui_
->menuPacketComment
->addAction(tr("Delete comments from %n packet(s)", nullptr, static_cast<int>(selectedRows().count())));
1201 connect(action
, &QAction::triggered
, this, &WiresharkMainWindow::deleteCommentsFromPackets
);
1205 void WiresharkMainWindow::setMenusForSelectedPacket()
1207 bool is_ip
= false, is_tcp
= false, is_udp
= false, is_sctp
= false, is_tls
= false, is_rtp
= false, is_lte_rlc
= false,
1208 is_quic
= false, is_exported_pdu
= false;
1210 /* Making the menu context-sensitive allows for easier selection of the
1211 desired item and has the added benefit, with large captures, of
1212 avoiding needless looping through huge lists for marked, ignored,
1213 or time-referenced packets. */
1215 /* We have one or more items in the packet list */
1216 bool have_frames
= false;
1217 /* A frame is selected */
1218 bool frame_selected
= false;
1219 bool multi_selection
= false;
1220 /* A visible packet comes after this one in the selection history */
1221 bool next_selection_history
= false;
1222 /* A visible packet comes before this one in the selection history */
1223 bool previous_selection_history
= false;
1224 /* We have marked frames. (XXX - why check frame_selected?) */
1225 bool have_marked
= false;
1226 /* We have a marked frame other than the current frame (i.e.,
1227 we have at least one marked frame, and either there's more
1228 than one marked frame or the current frame isn't marked). */
1229 bool another_is_marked
= false;
1230 /* One or more frames are hidden by a display filter */
1231 bool have_filtered
= false;
1232 /* One or more frames have been ignored */
1233 bool have_ignored
= false;
1234 bool have_time_ref
= false;
1235 /* We have a time reference frame other than the current frame (i.e.,
1236 we have at least one time reference frame, and either there's more
1237 than one time reference frame or the current frame isn't a
1238 time reference frame). (XXX - why check frame_selected?) */
1239 bool another_is_time_ref
= false;
1241 QList
<QAction
*> cc_actions
= QList
<QAction
*>()
1242 << main_ui_
->actionViewColorizeConversation1
<< main_ui_
->actionViewColorizeConversation2
1243 << main_ui_
->actionViewColorizeConversation3
<< main_ui_
->actionViewColorizeConversation4
1244 << main_ui_
->actionViewColorizeConversation5
<< main_ui_
->actionViewColorizeConversation6
1245 << main_ui_
->actionViewColorizeConversation7
<< main_ui_
->actionViewColorizeConversation8
1246 << main_ui_
->actionViewColorizeConversation9
<< main_ui_
->actionViewColorizeConversation10
;
1248 if (capture_file_
.capFile()) {
1249 QList
<int> rows
= selectedRows();
1250 frame_data
* current_frame
= 0;
1251 if (rows
.count() > 0)
1252 current_frame
= frameDataForRow(rows
.at(0));
1254 frame_selected
= rows
.count() == 1;
1255 if (packet_list_
->multiSelectActive())
1257 frame_selected
= false;
1258 multi_selection
= true;
1260 next_selection_history
= packet_list_
->haveNextHistory();
1261 previous_selection_history
= packet_list_
->havePreviousHistory();
1262 have_frames
= capture_file_
.capFile()->count
> 0;
1263 have_marked
= capture_file_
.capFile()->marked_count
> 0;
1264 another_is_marked
= have_marked
&& rows
.count() <= 1 &&
1265 !(capture_file_
.capFile()->marked_count
== 1 && frame_selected
&&
1266 current_frame
&& current_frame
->marked
);
1267 have_filtered
= capture_file_
.capFile()->displayed_count
> 0 && capture_file_
.capFile()->displayed_count
!= capture_file_
.capFile()->count
;
1268 have_ignored
= capture_file_
.capFile()->ignored_count
> 0;
1269 have_time_ref
= capture_file_
.capFile()->ref_time_count
> 0;
1270 another_is_time_ref
= have_time_ref
&& rows
.count() <= 1 &&
1271 !(capture_file_
.capFile()->ref_time_count
== 1 && frame_selected
&&
1272 current_frame
&& current_frame
->ref_time
);
1274 if (capture_file_
.capFile()->edt
&& ! multi_selection
&& frame_selected
)
1276 proto_get_frame_protocols(capture_file_
.capFile()->edt
->pi
.layers
,
1277 &is_ip
, &is_tcp
, &is_udp
, &is_sctp
,
1278 &is_tls
, &is_rtp
, &is_lte_rlc
);
1279 /* TODO: to follow a QUIC stream we need a *decrypted* QUIC connection, i.e. checking for "quic" in the protocol stack is not enough */
1280 is_quic
= proto_is_frame_protocol(capture_file_
.capFile()->edt
->pi
.layers
, "quic");
1281 is_exported_pdu
= proto_is_frame_protocol(capture_file_
.capFile()->edt
->pi
.layers
, "exported_pdu");
1282 /* For Exported PDU there is a tag inserting IP addresses into the SRC and DST columns */
1283 if (is_exported_pdu
&&
1284 (capture_file_
.capFile()->edt
->pi
.net_src
.type
== AT_IPv4
|| capture_file_
.capFile()->edt
->pi
.net_src
.type
== AT_IPv6
) &&
1285 (capture_file_
.capFile()->edt
->pi
.net_dst
.type
== AT_IPv4
|| capture_file_
.capFile()->edt
->pi
.net_dst
.type
== AT_IPv6
)) {
1288 foreach (FollowStreamAction
*follow_action
, main_ui_
->menuFollow
->findChildren
<FollowStreamAction
*>()) {
1289 /* QUIC has TLS handshakes; don't enabled Follow TLS Stream if
1292 bool is_frame
= proto_is_frame_protocol(capture_file_
.capFile()->edt
->pi
.layers
, follow_action
->filterName());
1293 if (g_strcmp0(follow_action
->filterName(), "tls") == 0) {
1294 follow_action
->setEnabled(is_frame
&& !is_quic
);
1296 follow_action
->setEnabled(is_frame
);
1300 foreach (FollowStreamAction
*follow_action
, main_ui_
->menuFollow
->findChildren
<FollowStreamAction
*>()) {
1301 follow_action
->setEnabled(false);
1306 main_ui_
->actionCopyListAsText
->setEnabled(selectedRows().count() > 0);
1307 main_ui_
->actionCopyListAsCSV
->setEnabled(selectedRows().count() > 0);
1308 main_ui_
->actionCopyListAsYAML
->setEnabled(selectedRows().count() > 0);
1309 main_ui_
->actionCopyListAsHTML
->setEnabled(selectedRows().count() > 0);
1311 main_ui_
->actionEditMarkSelected
->setEnabled(frame_selected
|| multi_selection
);
1312 main_ui_
->actionEditMarkAllDisplayed
->setEnabled(have_frames
);
1313 /* Unlike un-ignore, do not allow unmark of all frames when no frames are displayed */
1314 main_ui_
->actionEditUnmarkAllDisplayed
->setEnabled(have_marked
);
1315 main_ui_
->actionEditNextMark
->setEnabled(another_is_marked
);
1316 main_ui_
->actionEditPreviousMark
->setEnabled(another_is_marked
);
1318 GArray
* linkTypes
= Q_NULLPTR
;
1319 if (capture_file_
.capFile() && capture_file_
.capFile()->linktypes
)
1320 linkTypes
= capture_file_
.capFile()->linktypes
;
1322 bool enableEditComments
= linkTypes
&& wtap_dump_can_write(capture_file_
.capFile()->linktypes
, WTAP_COMMENT_PER_PACKET
);
1323 main_ui_
->menuPacketComment
->setEnabled(enableEditComments
&& selectedRows().count() > 0);
1324 main_ui_
->actionDeleteAllPacketComments
->setEnabled(enableEditComments
);
1326 main_ui_
->actionEditIgnoreSelected
->setEnabled(frame_selected
|| multi_selection
);
1327 main_ui_
->actionEditIgnoreAllDisplayed
->setEnabled(have_filtered
);
1328 /* Allow un-ignore of all frames even with no frames currently displayed */
1329 main_ui_
->actionEditUnignoreAllDisplayed
->setEnabled(have_ignored
);
1331 // XXX: Should we allow frames that don't have a time stamp to be
1332 // set as time references? "Time" references are also used to reset
1333 // the "Cumulative Bytes", so it's not entirely useless.
1334 main_ui_
->actionEditSetTimeReference
->setEnabled(frame_selected
);
1335 main_ui_
->actionEditUnsetAllTimeReferences
->setEnabled(have_time_ref
);
1336 main_ui_
->actionEditNextTimeReference
->setEnabled(another_is_time_ref
);
1337 main_ui_
->actionEditPreviousTimeReference
->setEnabled(another_is_time_ref
);
1338 main_ui_
->actionEditTimeShift
->setEnabled(have_frames
);
1340 main_ui_
->actionGoGoToLinkedPacket
->setEnabled(false);
1341 main_ui_
->actionGoNextHistoryPacket
->setEnabled(next_selection_history
);
1342 main_ui_
->actionGoPreviousHistoryPacket
->setEnabled(previous_selection_history
);
1344 foreach(QAction
*cc_action
, cc_actions
) {
1345 cc_action
->setEnabled(frame_selected
);
1347 main_ui_
->actionViewColorizeNewColoringRule
->setEnabled(frame_selected
);
1349 main_ui_
->actionViewColorizeResetColorization
->setEnabled(tmp_color_filters_used());
1351 main_ui_
->actionViewShowPacketInNewWindow
->setEnabled(frame_selected
);
1352 main_ui_
->actionViewEditResolvedName
->setEnabled(frame_selected
&& is_ip
);
1354 emit
packetInfoChanged(capture_file_
.packetInfo());
1356 // set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/ViewMenu/NameResolution/ResolveName",
1357 // frame_selected && (gbl_resolv_flags.mac_name || gbl_resolv_flags.network_name ||
1358 // gbl_resolv_flags.transport_name));
1360 main_ui_
->actionToolsFirewallAclRules
->setEnabled(frame_selected
);
1362 main_ui_
->actionStatisticsTcpStreamRoundTripTime
->setEnabled(is_tcp
);
1363 main_ui_
->actionStatisticsTcpStreamStevens
->setEnabled(is_tcp
);
1364 main_ui_
->actionStatisticsTcpStreamTcptrace
->setEnabled(is_tcp
);
1365 main_ui_
->actionStatisticsTcpStreamThroughput
->setEnabled(is_tcp
);
1366 main_ui_
->actionStatisticsTcpStreamWindowScaling
->setEnabled(is_tcp
);
1368 main_ui_
->actionSCTPAnalyseThisAssociation
->setEnabled(is_sctp
);
1369 main_ui_
->actionSCTPShowAllAssociations
->setEnabled(is_sctp
);
1370 main_ui_
->actionSCTPFilterThisAssociation
->setEnabled(is_sctp
);
1371 main_ui_
->actionTelephonyRtpStreamAnalysis
->setEnabled(is_rtp
);
1372 main_ui_
->actionTelephonyRtpPlayer
->setEnabled(is_rtp
);
1373 main_ui_
->actionTelephonyLteRlcGraph
->setEnabled(is_lte_rlc
);
1376 void WiresharkMainWindow::setMenusForSelectedTreeRow(FieldInformation
*finfo
) {
1378 bool can_match_selected
= false;
1379 bool is_framenum
= false;
1380 bool have_subtree
= false;
1381 bool can_open_url
= false;
1382 bool have_packet_bytes
= false;
1383 QByteArray field_filter
;
1386 field_info
* fi
= 0;
1388 fi
= finfo
->fieldInfo();
1390 if (capture_file_
.capFile()) {
1391 capture_file_
.capFile()->finfo_selected
= fi
;
1393 if (fi
&& fi
->tree_type
!= -1) {
1394 have_subtree
= true;
1397 if (fi
&& fi
->ds_tvb
&& (fi
->length
> 0)) {
1398 have_packet_bytes
= true;
1401 if (!(capture_file_
.capFile()->search_in_progress
&& (capture_file_
.capFile()->hex
|| (capture_file_
.capFile()->string
&& capture_file_
.capFile()->packet_data
)))) {
1402 // If we're not in the middle of a packet bytes search, then set
1403 // search_pos and search_len so that we can start a new search
1404 // from this point. (If we are, then we already set it.)
1405 if (fi
&& capture_file_
.capFile()->edt
&& (fi
->ds_tvb
== capture_file_
.capFile()->edt
->tvb
)) {
1406 // We can only do a Packet Bytes search in the main bytes from
1407 // the frame, not from any secondary data sources. (XXX: This
1408 // might be surprising to users, though.)
1409 capture_file_
.capFile()->search_pos
= (uint32_t)(finfo
->position().start
+ finfo
->position().length
- 1);
1410 capture_file_
.capFile()->search_len
= (uint32_t)finfo
->position().length
;
1412 capture_file_
.capFile()->search_pos
= 0;
1413 capture_file_
.capFile()->search_len
= 0;
1418 if (capture_file_
.capFile() != NULL
&& fi
!= NULL
) {
1419 const header_field_info
*hfinfo
= fi
->hfinfo
;
1420 int linked_frame
= -1;
1422 can_match_selected
= proto_can_match_selected(capture_file_
.capFile()->finfo_selected
, capture_file_
.capFile()->edt
);
1423 if (hfinfo
&& hfinfo
->type
== FT_FRAMENUM
) {
1425 linked_frame
= fvalue_get_uinteger(fi
->value
);
1428 char *tmp_field
= proto_construct_match_selected_string(fi
, capture_file_
.capFile()->edt
);
1429 field_filter
= tmp_field
;
1430 wmem_free(NULL
, tmp_field
);
1431 emit
fieldFilterChanged(field_filter
);
1433 field_id
= fi
->hfinfo
->id
;
1434 /* if the selected field isn't a protocol, get its parent */
1435 if (!proto_registrar_is_protocol(field_id
)) {
1436 field_id
= proto_registrar_get_parent(fi
->hfinfo
->id
);
1439 if (field_id
>= 0) {
1440 can_open_url
= true;
1441 main_ui_
->actionContextWikiProtocolPage
->setData(field_id
);
1442 main_ui_
->actionContextFilterFieldReference
->setData(field_id
);
1444 main_ui_
->actionContextWikiProtocolPage
->setData(QVariant());
1445 main_ui_
->actionContextFilterFieldReference
->setData(QVariant());
1448 if (linked_frame
> 0) {
1449 main_ui_
->actionGoGoToLinkedPacket
->setData(linked_frame
);
1451 main_ui_
->actionGoGoToLinkedPacket
->setData(QVariant());
1455 // Always enable / disable the following items.
1456 main_ui_
->actionCopyAllVisibleItems
->setEnabled(capture_file_
.capFile() != NULL
&& ! packet_list_
->multiSelectActive());
1457 main_ui_
->actionCopyAllVisibleSelectedTreeItems
->setEnabled(can_match_selected
);
1458 main_ui_
->actionEditCopyDescription
->setEnabled(can_match_selected
);
1459 main_ui_
->actionEditCopyFieldName
->setEnabled(can_match_selected
);
1460 main_ui_
->actionEditCopyValue
->setEnabled(can_match_selected
);
1461 main_ui_
->actionEditCopyAsFilter
->setEnabled(can_match_selected
);
1463 main_ui_
->actionAnalyzeShowPacketBytes
->setEnabled(have_packet_bytes
);
1464 main_ui_
->actionFileExportPacketBytes
->setEnabled(have_packet_bytes
);
1466 main_ui_
->actionViewExpandSubtrees
->setEnabled(have_subtree
);
1467 main_ui_
->actionViewCollapseSubtrees
->setEnabled(have_subtree
);
1469 main_ui_
->actionGoGoToLinkedPacket
->setEnabled(is_framenum
);
1471 main_ui_
->actionAnalyzeApplyAsColumn
->setEnabled(can_match_selected
);
1473 main_ui_
->actionContextShowLinkedPacketInNewWindow
->setEnabled(is_framenum
);
1475 main_ui_
->actionContextWikiProtocolPage
->setEnabled(can_open_url
);
1476 main_ui_
->actionContextFilterFieldReference
->setEnabled(can_open_url
);
1479 // Only enable / disable the following items if we have focus so that we
1480 // don't clobber anything we may have set in setMenusForSelectedPacket.
1481 if (!proto_tree_
|| !proto_tree_
->hasFocus()) return;
1483 emit
packetInfoChanged(capture_file_
.packetInfo());
1485 // set_menu_sensitivity(ui_manager_tree_view_menu, "/TreeViewPopup/ResolveName",
1486 // frame_selected && (gbl_resolv_flags.mac_name || gbl_resolv_flags.network_name ||
1487 // gbl_resolv_flags.transport_name));
1491 void WiresharkMainWindow::interfaceSelectionChanged()
1494 // XXX This doesn't disable the toolbar button when using
1496 if (global_capture_opts
.num_selected
> 0 && capture_filter_valid_
) {
1497 main_ui_
->actionCaptureStart
->setEnabled(true);
1499 main_ui_
->actionCaptureStart
->setEnabled(false);
1501 #endif // HAVE_LIBPCAP
1504 void WiresharkMainWindow::captureFilterSyntaxChanged(bool valid
)
1506 capture_filter_valid_
= valid
;
1507 interfaceSelectionChanged();
1510 void WiresharkMainWindow::startInterfaceCapture(bool valid
, const QString capture_filter
)
1512 capture_filter_valid_
= valid
;
1513 welcome_page_
->setCaptureFilter(capture_filter
);
1514 QString
before_what(tr(" before starting a new capture"));
1515 if (testCaptureFileClose(before_what
)) {
1516 // The interface tree will update the selected interfaces via its timer
1517 // so no need to do anything here.
1518 startCapture(QStringList());
1522 void WiresharkMainWindow::applyGlobalCommandLineOptions()
1524 if (global_dissect_options
.time_format
!= TS_NOT_SET
) {
1525 foreach(QAction
* tda
, td_actions
.keys()) {
1526 if (global_dissect_options
.time_format
== td_actions
[tda
]) {
1527 tda
->setChecked(true);
1528 // XXX - this means that if the user sets the
1529 // time stamp format with the -t flag, that
1530 // setting will persist and will be used as
1531 // the default the next time Wireshark is run.
1532 recent
.gui_time_format
= global_dissect_options
.time_format
;
1533 timestamp_set_type(global_dissect_options
.time_format
);
1538 if (global_dissect_options
.time_precision
!= TS_PREC_NOT_SET
) {
1539 foreach(QAction
* tpa
, tp_actions
.keys()) {
1540 if (global_dissect_options
.time_precision
== tp_actions
[tpa
]) {
1541 tpa
->setChecked(true);
1542 // XXX - this means that if the user sets the
1543 // time stamp precision with the -t flag, that
1544 // setting will persist and will be used as
1545 // the default the next time Wireshark is run.
1546 recent
.gui_time_precision
= global_dissect_options
.time_precision
;
1547 timestamp_set_precision(global_dissect_options
.time_precision
);
1552 if (global_commandline_info
.full_screen
) {
1553 this->showFullScreen();
1557 void WiresharkMainWindow::redissectPackets()
1559 if (capture_file_
.capFile()) {
1560 cf_redissect_packets(capture_file_
.capFile());
1561 main_ui_
->statusBar
->expertUpdate();
1564 proto_free_deregistered_fields();
1567 void WiresharkMainWindow::checkDisplayFilter()
1569 if (!df_combo_box_
->checkDisplayFilter()) {
1570 g_free(CaptureFile::globalCapFile()->dfilter
);
1571 CaptureFile::globalCapFile()->dfilter
= NULL
;
1575 void WiresharkMainWindow::fieldsChanged()
1577 char *err_msg
= NULL
;
1578 if (!color_filters_reload(&err_msg
, color_filter_add_cb
)) {
1579 simple_dialog(ESD_TYPE_ERROR
, ESD_BTN_OK
, "%s", err_msg
);
1582 tap_listeners_dfilter_recompile();
1584 emit
checkDisplayFilter();
1586 if (have_custom_cols(&CaptureFile::globalCapFile()->cinfo
)) {
1587 // Recreate packet list columns according to new/changed/deleted fields
1588 packet_list_
->fieldsChanged(CaptureFile::globalCapFile());
1591 emit
reloadFields();
1594 void WiresharkMainWindow::reloadLuaPlugins()
1597 if (mainApp
->isReloadingLua())
1600 bool uses_lua_filehandler
= false;
1602 if (capture_file_
.capFile()) {
1603 // Check if the current capture file is opened with a Lua FileHandler
1604 capture_file
*cf
= capture_file_
.capFile();
1605 uses_lua_filehandler
= wtap_uses_lua_filehandler(cf
->provider
.wth
);
1607 if (uses_lua_filehandler
&& cf
->unsaved_changes
) {
1608 // Prompt to save the file before reloading, in case the FileHandler has changed
1609 QString
before_what(tr(" before reloading Lua plugins"));
1610 if (!testCaptureFileClose(before_what
, Reload
)) {
1616 mainApp
->setReloadingLua(true);
1618 wslua_reload_plugins(NULL
, NULL
);
1619 this->clearAddedPacketMenus();
1620 funnel_statistics_reload_menus();
1621 reloadDynamicMenus();
1622 closePacketDialogs();
1624 // Preferences may have been deleted so close all widgets using prefs
1625 main_ui_
->preferenceEditorFrame
->animatedHide();
1627 mainApp
->readConfigurationFiles(true);
1628 commandline_options_reapply();
1633 if (uses_lua_filehandler
) {
1634 // Reload the file in case the FileHandler has changed
1635 if (cf_reload(capture_file_
.capFile()) != CF_OK
) {
1636 cf_close(capture_file_
.capFile());
1638 proto_free_deregistered_fields();
1643 mainApp
->setReloadingLua(false);
1644 SimpleDialog::displayQueuedMessages();
1648 void WiresharkMainWindow::showAccordionFrame(AccordionFrame
*show_frame
, bool toggle
)
1650 QList
<AccordionFrame
*>frame_list
= QList
<AccordionFrame
*>()
1651 << main_ui_
->goToFrame
<< main_ui_
->searchFrame
1652 << main_ui_
->addressEditorFrame
<< main_ui_
->columnEditorFrame
1653 << main_ui_
->preferenceEditorFrame
<< main_ui_
->filterExpressionFrame
;
1655 frame_list
.removeAll(show_frame
);
1656 foreach(AccordionFrame
*af
, frame_list
) af
->animatedHide();
1659 if (show_frame
->isVisible()) {
1660 show_frame
->animatedHide();
1664 show_frame
->animatedShow();
1667 void WiresharkMainWindow::showColumnEditor(int column
)
1670 main_ui_
->columnEditorFrame
->editColumn(column
);
1671 showAccordionFrame(main_ui_
->columnEditorFrame
);
1674 void WiresharkMainWindow::showPreferenceEditor()
1676 showAccordionFrame(main_ui_
->preferenceEditorFrame
);
1679 void WiresharkMainWindow::initViewColorizeMenu()
1681 QList
<QAction
*> cc_actions
= QList
<QAction
*>()
1682 << main_ui_
->actionViewColorizeConversation1
<< main_ui_
->actionViewColorizeConversation2
1683 << main_ui_
->actionViewColorizeConversation3
<< main_ui_
->actionViewColorizeConversation4
1684 << main_ui_
->actionViewColorizeConversation5
<< main_ui_
->actionViewColorizeConversation6
1685 << main_ui_
->actionViewColorizeConversation7
<< main_ui_
->actionViewColorizeConversation8
1686 << main_ui_
->actionViewColorizeConversation9
<< main_ui_
->actionViewColorizeConversation10
;
1688 uint8_t color_num
= 1;
1690 foreach(QAction
*cc_action
, cc_actions
) {
1691 cc_action
->setData(color_num
);
1692 connect(cc_action
, &QAction::triggered
, this, &WiresharkMainWindow::colorizeConversation
);
1694 const color_filter_t
*colorf
= color_filters_tmp_color(color_num
);
1696 QColor bg
= ColorUtils::fromColorT(colorf
->bg_color
);
1697 QColor fg
= ColorUtils::fromColorT(colorf
->fg_color
);
1698 cc_action
->setIcon(StockIcon::colorIcon(bg
.rgb(), fg
.rgb(), QString::number(color_num
)));
1704 // Spotlight uses Cmd+Space
1705 main_ui_
->actionViewColorizeResetColorization
->setShortcut(QKeySequence("Meta+Space"));
1709 void WiresharkMainWindow::addStatsPluginsToMenu() {
1710 GList
*cfg_list
= stats_tree_get_cfg_list();
1711 QAction
*stats_tree_action
;
1713 bool first_item
= true;
1715 for (GList
*iter
= g_list_first(cfg_list
); iter
; iter
= gxx_list_next(iter
)) {
1716 stats_tree_cfg
*cfg
= gxx_list_data(stats_tree_cfg
*, iter
);
1717 if (!menu_groups_
.contains(cfg
->stat_group
)) {
1722 main_ui_
->menuStatistics
->addSeparator();
1726 parent_menu
= main_ui_
->menuStatistics
;
1727 // gtk/main_menubar.c compresses double slashes, hence SkipEmptyParts
1728 QStringList cfg_name_parts
= QString(cfg
->path
).split(STATS_TREE_MENU_SEPARATOR
, Qt::SkipEmptyParts
);
1729 if (cfg_name_parts
.isEmpty()) continue;
1731 QString stat_name
= cfg_name_parts
.takeLast().trimmed();
1732 if (!cfg_name_parts
.isEmpty()) {
1733 parent_menu
= findOrAddMenu(parent_menu
, cfg_name_parts
);
1736 stats_tree_action
= new QAction(stat_name
, this);
1737 stats_tree_action
->setData(QString::fromUtf8(cfg
->abbr
));
1738 parent_menu
->addAction(stats_tree_action
);
1739 connect(stats_tree_action
, &QAction::triggered
, this, [this]() {
1740 QAction
* action
= qobject_cast
<QAction
*>(sender());
1742 openStatisticsTreeDialog(action
->data().toString().toUtf8());
1747 g_list_free(cfg_list
);
1750 void WiresharkMainWindow::setFeaturesEnabled(bool enabled
)
1752 main_ui_
->menuBar
->setEnabled(enabled
);
1753 main_ui_
->mainToolBar
->setEnabled(enabled
);
1754 main_ui_
->displayFilterToolBar
->setEnabled(enabled
);
1757 main_ui_
->statusBar
->clearMessage();
1759 main_ui_
->actionGoAutoScroll
->setChecked(recent
.capture_auto_scroll
);
1764 main_ui_
->statusBar
->showMessage(tr("Please wait while Wireshark is initializing…"));
1768 // Display Filter Toolbar
1770 void WiresharkMainWindow::on_actionNewDisplayFilterExpression_triggered()
1772 main_ui_
->filterExpressionFrame
->addExpression(df_combo_box_
->lineEdit()->text());
1775 void WiresharkMainWindow::onFilterSelected(QString filterText
, bool prepare
)
1777 if (filterText
.length() <= 0)
1780 df_combo_box_
->setDisplayFilter(filterText
);
1781 // Holding down the Shift key will only prepare filter.
1783 df_combo_box_
->applyDisplayFilter();
1786 void WiresharkMainWindow::onFilterPreferences()
1788 emit
showPreferencesDialog(PrefsModel::typeToString(PrefsModel::FilterButtons
));
1791 void WiresharkMainWindow::onFilterEdit(int uatIndex
)
1793 main_ui_
->filterExpressionFrame
->editExpression(uatIndex
);
1796 void WiresharkMainWindow::openStatCommandDialog(const QString
&menu_path
, const char *arg
, void *userdata
)
1798 QString slot
= QStringLiteral("statCommand%1").arg(menu_path
);
1799 QMetaObject::invokeMethod(this, slot
.toLatin1().constData(), Q_ARG(const char *, arg
), Q_ARG(void *, userdata
));
1802 void WiresharkMainWindow::openTapParameterDialog(const QString cfg_str
, const QString arg
, void *userdata
)
1804 TapParameterDialog
*tp_dialog
= TapParameterDialog::showTapParameterStatistics(*this, capture_file_
, cfg_str
, arg
, userdata
);
1805 if (!tp_dialog
) return;
1807 connect(tp_dialog
, &TapParameterDialog::filterAction
, this, &WiresharkMainWindow::filterAction
);
1808 connect(tp_dialog
, &TapParameterDialog::updateFilter
, df_combo_box_
->lineEdit(), &QLineEdit::setText
);
1812 void WiresharkMainWindow::openTapParameterDialog()
1814 QAction
*tpa
= qobject_cast
<QAction
*>(QObject::sender());
1817 const QString cfg_str
= tpa
->data().toString();
1818 openTapParameterDialog(cfg_str
, NULL
, NULL
);
1821 #if defined(HAVE_SOFTWARE_UPDATE) && defined(Q_OS_WIN)
1822 void WiresharkMainWindow::softwareUpdateRequested() {
1823 // testCaptureFileClose doesn't use this string because we aren't
1824 // going to launch another dialog, but maybe we'll change that.
1825 QString
before_what(tr(" before updating"));
1826 if (!testCaptureFileClose(before_what
, Update
)) {
1827 mainApp
->rejectSoftwareUpdate();
1834 void WiresharkMainWindow::connectFileMenuActions()
1836 connect(main_ui_
->actionFileOpen
, &QAction::triggered
, this,
1837 [this]() { openCaptureFile(); });
1839 connect(main_ui_
->actionFileMerge
, &QAction::triggered
, this,
1840 [this]() { mergeCaptureFile(); });
1842 connect(main_ui_
->actionFileImportFromHexDump
, &QAction::triggered
, this,
1843 [this]() { importCaptureFile(); });
1845 connect(main_ui_
->actionFileClose
, &QAction::triggered
, this, [this]() {
1846 QString
before_what(tr(" before closing the file"));
1847 if (testCaptureFileClose(before_what
)) {
1852 connect(main_ui_
->actionFileSave
, &QAction::triggered
, this,
1853 [this]() { saveCaptureFile(capture_file_
.capFile(), false); });
1855 connect(main_ui_
->actionFileSaveAs
, &QAction::triggered
, this,
1856 [this]() { saveAsCaptureFile(capture_file_
.capFile()); });
1858 connect(main_ui_
->actionFileSetListFiles
, &QAction::triggered
, this,
1859 [this]() { file_set_dialog_
->show(); });
1861 connect(main_ui_
->actionFileSetNextFile
, &QAction::triggered
, this, [this]() {
1862 fileset_entry
*entry
= fileset_get_next();
1865 QString new_cf_path
= entry
->fullname
;
1866 openCaptureFile(new_cf_path
);
1870 connect(main_ui_
->actionFileSetPreviousFile
, &QAction::triggered
, this, [this]() {
1871 fileset_entry
*entry
= fileset_get_previous();
1874 QString new_cf_path
= entry
->fullname
;
1875 openCaptureFile(new_cf_path
);
1879 connect(main_ui_
->actionFileExportPackets
, &QAction::triggered
, this,
1880 [this]() { exportSelectedPackets(); });
1882 connect(main_ui_
->actionFileExportAsPlainText
, &QAction::triggered
, this,
1883 [this]() { exportDissections(export_type_text
); });
1885 connect(main_ui_
->actionFileExportAsCSV
, &QAction::triggered
, this,
1886 [this]() { exportDissections(export_type_csv
); });
1888 connect(main_ui_
->actionFileExportAsCArrays
, &QAction::triggered
, this,
1889 [this]() { exportDissections(export_type_carrays
); });
1891 connect(main_ui_
->actionFileExportAsPSML
, &QAction::triggered
, this,
1892 [this]() { exportDissections(export_type_psml
); });
1894 connect(main_ui_
->actionFileExportAsPDML
, &QAction::triggered
, this,
1895 [this]() { exportDissections(export_type_pdml
); });
1897 connect(main_ui_
->actionFileExportAsJSON
, &QAction::triggered
, this,
1898 [this]() { exportDissections(export_type_json
); });
1900 connect(main_ui_
->actionFileExportPacketBytes
, &QAction::triggered
, this,
1901 [this]() { exportPacketBytes(); }, Qt::QueuedConnection
);
1903 connect(main_ui_
->actionFileExportPDU
, &QAction::triggered
, this,
1904 [this]() { exportPDU(); });
1906 connect(main_ui_
->actionFileStripHeaders
, &QAction::triggered
, this,
1907 [this]() { stripPacketHeaders(); });
1909 connect(main_ui_
->actionFileExportTLSSessionKeys
, &QAction::triggered
, this,
1910 [this]() { exportTLSSessionKeys(); });
1912 connect(main_ui_
->actionFilePrint
, &QAction::triggered
, this,
1913 [this]() { printFile(); });
1916 void WiresharkMainWindow::exportPacketBytes()
1920 if (!capture_file_
.capFile() || !capture_file_
.capFile()->finfo_selected
) return;
1922 file_name
= WiresharkFileDialog::getSaveFileName(this,
1923 mainApp
->windowTitleString(tr("Export Selected Packet Bytes")),
1924 mainApp
->openDialogInitialDir().canonicalPath(),
1925 tr("Raw data (*.bin *.dat *.raw);;All Files (" ALL_FILES_WILDCARD
")")
1928 if (file_name
.length() > 0) {
1929 const uint8_t *data_p
;
1931 data_p
= tvb_get_ptr(capture_file_
.capFile()->finfo_selected
->ds_tvb
, 0, -1) +
1932 capture_file_
.capFile()->finfo_selected
->start
;
1933 write_file_binary_mode(qUtf8Printable(file_name
), data_p
, capture_file_
.capFile()->finfo_selected
->length
);
1935 /* Save the directory name for future file dialogs. */
1936 mainApp
->setLastOpenDirFromFilename(file_name
);
1940 void WiresharkMainWindow::exportPDU()
1942 ExportPDUDialog
*exportpdu_dialog
= new ExportPDUDialog(this);
1944 if (exportpdu_dialog
->isMinimized() == true)
1946 exportpdu_dialog
->showNormal();
1950 exportpdu_dialog
->show();
1953 exportpdu_dialog
->raise();
1954 exportpdu_dialog
->activateWindow();
1957 void WiresharkMainWindow::stripPacketHeaders()
1959 StripHeadersDialog
*stripheaders_dialog
= new StripHeadersDialog(this);
1961 if (stripheaders_dialog
->isMinimized() == true)
1963 stripheaders_dialog
->showNormal();
1967 stripheaders_dialog
->show();
1970 stripheaders_dialog
->raise();
1971 stripheaders_dialog
->activateWindow();
1975 void WiresharkMainWindow::exportTLSSessionKeys()
1981 keylist_len
= ssl_session_key_count();
1982 /* don't show up the dialog, if no data has to be saved */
1983 if (keylist_len
< 1) {
1984 /* shouldn't happen as the menu item should have been greyed out */
1985 QMessageBox::warning(
1988 tr("There are no TLS Session Keys to save."),
1994 save_title
.append(mainApp
->windowTitleString(tr("Export TLS Session Keys (%Ln key(s))", "", keylist_len
)));
1995 file_name
= WiresharkFileDialog::getSaveFileName(this,
1997 mainApp
->openDialogInitialDir().canonicalPath(),
1998 tr("TLS Session Keys (*.keys *.txt);;All Files (" ALL_FILES_WILDCARD
")")
2000 if (file_name
.length() > 0) {
2001 size_t keylist_length
;
2002 char *keylist
= ssl_export_sessions(&keylist_length
);
2003 write_file_binary_mode(qUtf8Printable(file_name
), keylist
, keylist_length
);
2005 /* Save the directory name for future file dialogs. */
2006 mainApp
->setLastOpenDirFromFilename(file_name
);
2011 void WiresharkMainWindow::printFile()
2013 capture_file
*cf
= capture_file_
.capFile();
2014 g_return_if_fail(cf
);
2016 QList
<int> rows
= packet_list_
->selectedRows(true);
2018 QStringList entries
;
2019 foreach (int row
, rows
)
2020 entries
<< QString::number(row
);
2021 QString selRange
= entries
.join(",");
2023 PrintDialog
* pdlg_
= new PrintDialog(this, cf
, selRange
);
2024 pdlg_
->setWindowModality(Qt::ApplicationModal
);
2030 void WiresharkMainWindow::connectEditMenuActions()
2032 connect(main_ui_
->actionCopyAllVisibleItems
, &QAction::triggered
, this,
2033 [this]() { copySelectedItems(CopyAllVisibleItems
); });
2035 connect(main_ui_
->actionCopyListAsText
, &QAction::triggered
, this,
2036 [this]() { copySelectedItems(CopyListAsText
); });
2038 connect(main_ui_
->actionCopyListAsCSV
, &QAction::triggered
, this,
2039 [this]() { copySelectedItems(CopyListAsCSV
); });
2041 connect(main_ui_
->actionCopyListAsYAML
, &QAction::triggered
, this,
2042 [this]() { copySelectedItems(CopyListAsYAML
); });
2044 connect(main_ui_
->actionCopyListAsHTML
, &QAction::triggered
, this,
2045 [this]() { copySelectedItems(CopyListAsHTML
); });
2047 connect(main_ui_
->actionCopyAllVisibleSelectedTreeItems
, &QAction::triggered
, this,
2048 [this]() { copySelectedItems(CopyAllVisibleSelectedTreeItems
); });
2050 connect(main_ui_
->actionEditCopyDescription
, &QAction::triggered
, this,
2051 [this]() { copySelectedItems(CopySelectedDescription
); });
2053 connect(main_ui_
->actionEditCopyFieldName
, &QAction::triggered
, this,
2054 [this]() { copySelectedItems(CopySelectedFieldName
); });
2056 connect(main_ui_
->actionEditCopyValue
, &QAction::triggered
, this,
2057 [this]() { copySelectedItems(CopySelectedValue
); });
2059 connect(main_ui_
->actionEditCopyAsFilter
, &QAction::triggered
, this,
2060 [this]() { matchFieldFilter(FilterAction::ActionCopy
, FilterAction::ActionTypePlain
); });
2062 connect(main_ui_
->actionEditFindPacket
, &QAction::triggered
, this,
2063 [this]() { findPacket(); });
2065 connect(main_ui_
->actionEditFindNext
, &QAction::triggered
, this,
2066 [this]() { main_ui_
->searchFrame
->findNext(); });
2068 connect(main_ui_
->actionEditFindPrevious
, &QAction::triggered
, this,
2069 [this]() { main_ui_
->searchFrame
->findPrevious(); });
2071 // The items below are used in the packet list and detail context menus.
2072 // Use QueuedConnections so that the context menus aren't destroyed
2074 connect(main_ui_
->actionEditMarkSelected
, &QAction::triggered
, this, [this]() {
2076 packet_list_
->markFrame();
2078 setMenusForSelectedPacket();
2079 }, Qt::QueuedConnection
);
2081 connect(main_ui_
->actionEditMarkAllDisplayed
, &QAction::triggered
, this, [this]() {
2083 packet_list_
->markAllDisplayedFrames(true);
2085 setMenusForSelectedPacket();
2086 }, Qt::QueuedConnection
);
2088 connect(main_ui_
->actionEditUnmarkAllDisplayed
, &QAction::triggered
, this, [this]() {
2090 packet_list_
->markAllDisplayedFrames(false);
2092 setMenusForSelectedPacket();
2093 }, Qt::QueuedConnection
);
2095 connect(main_ui_
->actionEditNextMark
, &QAction::triggered
, this, [this]() {
2096 if (capture_file_
.capFile()) {
2097 cf_find_packet_marked(capture_file_
.capFile(), SD_FORWARD
);
2099 }, Qt::QueuedConnection
);
2101 connect(main_ui_
->actionEditPreviousMark
, &QAction::triggered
, this, [this]() {
2102 if (capture_file_
.capFile()) {
2103 cf_find_packet_marked(capture_file_
.capFile(), SD_BACKWARD
);
2105 }, Qt::QueuedConnection
);
2107 connect(main_ui_
->actionEditIgnoreSelected
, &QAction::triggered
, this, [this]() {
2109 packet_list_
->ignoreFrame();
2111 setMenusForSelectedPacket();
2112 }, Qt::QueuedConnection
);
2114 connect(main_ui_
->actionEditIgnoreAllDisplayed
, &QAction::triggered
, this, [this]() {
2116 packet_list_
->ignoreAllDisplayedFrames(true);
2118 setMenusForSelectedPacket();
2119 }, Qt::QueuedConnection
);
2121 connect(main_ui_
->actionEditUnignoreAllDisplayed
, &QAction::triggered
, this, [this]() {
2123 packet_list_
->ignoreAllDisplayedFrames(false);
2125 setMenusForSelectedPacket();
2126 }, Qt::QueuedConnection
);
2128 connect(main_ui_
->actionEditSetTimeReference
, &QAction::triggered
, this, [this]() {
2129 packet_list_
->setTimeReference();
2130 setMenusForSelectedPacket();
2131 }, Qt::QueuedConnection
);
2133 connect(main_ui_
->actionEditUnsetAllTimeReferences
, &QAction::triggered
, this, [this]() {
2134 packet_list_
->unsetAllTimeReferences();
2135 setMenusForSelectedPacket();
2136 }, Qt::QueuedConnection
);
2138 connect(main_ui_
->actionEditNextTimeReference
, &QAction::triggered
, this, [this]() {
2139 if (!capture_file_
.capFile()) return;
2140 cf_find_packet_time_reference(capture_file_
.capFile(), SD_FORWARD
);
2141 }, Qt::QueuedConnection
);
2143 connect(main_ui_
->actionEditPreviousTimeReference
, &QAction::triggered
, this, [this]() {
2144 if (!capture_file_
.capFile()) return;
2145 cf_find_packet_time_reference(capture_file_
.capFile(), SD_BACKWARD
);
2146 }, Qt::QueuedConnection
);
2148 connect(main_ui_
->actionEditTimeShift
, &QAction::triggered
, this,
2149 [this]() { editTimeShift(); }, Qt::QueuedConnection
);
2151 connect(main_ui_
->actionDeleteAllPacketComments
, &QAction::triggered
, this,
2152 [this]() { deleteAllPacketComments(); }, Qt::QueuedConnection
);
2154 connect(main_ui_
->actionEditInjectSecrets
, &QAction::triggered
, this,
2155 [this]() { injectSecrets(); }, Qt::QueuedConnection
);
2157 connect(main_ui_
->actionEditDiscardAllSecrets
, &QAction::triggered
, this,
2158 [this]() { discardAllSecrets(); }, Qt::QueuedConnection
);
2160 connect(main_ui_
->actionEditConfigurationProfiles
, &QAction::triggered
, this,
2161 [this]() { editConfigurationProfiles(); }, Qt::QueuedConnection
);
2163 connect(main_ui_
->actionEditPreferences
, &QAction::triggered
, this,
2164 [this]() { showPreferencesDialog(PrefsModel::typeToString(PrefsModel::Appearance
)); }, Qt::QueuedConnection
);
2167 // XXX This should probably be somewhere else.
2168 void WiresharkMainWindow::copySelectedItems(WiresharkMainWindow::CopySelected selection_type
)
2170 char label_str
[ITEM_LABEL_LENGTH
];
2173 if (!capture_file_
.capFile()) return;
2175 field_info
*finfo_selected
= capture_file_
.capFile()->finfo_selected
;
2177 switch (selection_type
) {
2178 case CopySelectedDescription
:
2179 if (proto_tree_
->selectionModel()->hasSelection()) {
2180 QModelIndex idx
= proto_tree_
->selectionModel()->selectedIndexes().first();
2181 clip
= idx
.data(Qt::DisplayRole
).toString();
2184 case CopySelectedFieldName
:
2185 if (finfo_selected
&& finfo_selected
->hfinfo
->abbrev
!= 0) {
2186 clip
.append(finfo_selected
->hfinfo
->abbrev
);
2189 case CopySelectedValue
:
2190 if (finfo_selected
&& capture_file_
.capFile()->edt
!= 0) {
2191 char* field_str
= get_node_field_value(finfo_selected
, capture_file_
.capFile()->edt
);
2192 clip
.append(field_str
[0] ? field_str
: "(null)");
2196 case CopyAllVisibleItems
:
2197 clip
= proto_tree_
->toString();
2199 case CopyAllVisibleSelectedTreeItems
:
2200 if (proto_tree_
->selectionModel()->hasSelection()) {
2201 clip
= proto_tree_
->toString(proto_tree_
->selectionModel()->selectedIndexes().first());
2204 case CopyListAsText
:
2206 case CopyListAsYAML
:
2207 case CopyListAsHTML
:
2209 if (packet_list_
->selectedRows().count() > 0)
2211 QList
<int> rows
= packet_list_
->selectedRows();
2212 QStringList content
, htmlContent
;
2214 PacketList::SummaryCopyType copyType
= PacketList::CopyAsText
;
2215 if (selection_type
== CopyListAsCSV
)
2216 copyType
= PacketList::CopyAsCSV
;
2217 else if (selection_type
== CopyListAsYAML
)
2218 copyType
= PacketList::CopyAsYAML
;
2219 else if (selection_type
== CopyListAsHTML
)
2220 copyType
= PacketList::CopyAsHTML
;
2222 QStringList hdr_parts
;
2223 QList
<int> align_parts
, size_parts
;
2225 if (copyType
== PacketList::CopyAsText
|| copyType
== PacketList::CopyAsHTML
) {
2226 if (prefs
.gui_packet_list_copy_text_with_aligned_columns
) {
2227 hdr_parts
= packet_list_
->createHeaderPartsForAligned();
2228 align_parts
= packet_list_
->createAlignmentPartsForAligned();
2229 size_parts
= packet_list_
->createSizePartsForAligned(true, hdr_parts
, rows
);
2230 content
<< packet_list_
->createHeaderSummaryForAligned(hdr_parts
, align_parts
, size_parts
);
2233 content
<< packet_list_
->createHeaderSummaryText(PacketList::CopyAsText
);
2235 if (copyType
== PacketList::CopyAsHTML
) {
2236 htmlContent
<< packet_list_
->createDefaultStyleForHtml();
2237 htmlContent
<< packet_list_
->createOpeningTagForHtml();
2238 htmlContent
<< packet_list_
->createHeaderSummaryForHtml();
2241 else if (copyType
== PacketList::CopyAsCSV
) {
2242 content
<< packet_list_
->createHeaderSummaryText(copyType
);
2245 foreach (int row
, rows
)
2247 QModelIndex idx
= packet_list_
->model()->index(row
, 0);
2248 if (! idx
.isValid())
2251 if (copyType
== PacketList::CopyAsText
|| copyType
== PacketList::CopyAsHTML
) {
2252 if (prefs
.gui_packet_list_copy_text_with_aligned_columns
)
2253 content
<< packet_list_
->createSummaryForAligned(idx
, align_parts
, size_parts
);
2255 content
<< packet_list_
->createSummaryText(idx
, PacketList::CopyAsText
);
2256 if (copyType
== PacketList::CopyAsHTML
)
2257 htmlContent
<< packet_list_
->createSummaryForHtml(idx
);
2260 content
<< packet_list_
->createSummaryText(idx
, copyType
);
2264 if (selection_type
== CopyListAsHTML
) {
2265 // htmlContent will never be empty as they will always have style and table tags
2266 QMimeData
*mimeData
= new QMimeData
;
2267 htmlContent
<< packet_list_
->createClosingTagForHtml();
2268 mimeData
->setHtml(htmlContent
.join('\n'));
2269 mimeData
->setText(content
.join('\n').append("\n"));
2270 mainApp
->clipboard()->setMimeData(mimeData
, QClipboard::Clipboard
);
2273 if (content
.count() > 0) {
2275 // Each YAML item ends with a newline, hence it is not
2276 // joined with a newline else a blank line is created
2277 // before start of entry (or ---) from second packet
2278 // when multiple packets are copied.
2280 // Each YAML item ends with a newline, so the string
2281 // ends with a newline already if it's CopyListAsYAML.
2282 // If we add a newline, there'd be an extra blank
2285 // Otherwise, we've used newlines as separators, not
2286 // terminators, so there's no final newline. Add it.
2288 if (selection_type
== CopyListAsYAML
) {
2289 clip
= content
.join("");
2292 clip
= content
.join("\n");
2302 if (selection_type
!= CopyListAsHTML
)
2304 if (clip
.length() == 0) {
2305 /* If no representation then... Try to read the value */
2306 proto_item_fill_label(capture_file_
.capFile()->finfo_selected
, label_str
, NULL
);
2307 clip
.append(label_str
);
2310 if (clip
.length()) {
2311 mainApp
->clipboard()->setText(clip
);
2313 QString err
= tr("Couldn't copy text. Try another item.");
2314 mainApp
->pushStatus(WiresharkApplication::TemporaryStatus
, err
);
2319 void WiresharkMainWindow::findPacket()
2321 if (! packet_list_
->model() || packet_list_
->model()->rowCount() < 1) {
2325 if (!main_ui_
->searchFrame
->isVisible()) {
2326 showAccordionFrame(main_ui_
->searchFrame
, true);
2328 main_ui_
->searchFrame
->animatedHide();
2330 main_ui_
->searchFrame
->setFocus();
2333 void WiresharkMainWindow::editTimeShift()
2335 TimeShiftDialog
*ts_dialog
= new TimeShiftDialog(this, capture_file_
.capFile());
2336 connect(ts_dialog
, &TimeShiftDialog::finished
, this, &WiresharkMainWindow::editTimeShiftFinished
);
2338 connect(this, &WiresharkMainWindow::setCaptureFile
, ts_dialog
, &TimeShiftDialog::setCaptureFile
);
2339 connect(ts_dialog
, &TimeShiftDialog::timeShifted
, packet_list_
, &PacketList::applyTimeShift
, Qt::QueuedConnection
);
2341 ts_dialog
->setWindowModality(Qt::ApplicationModal
);
2342 ts_dialog
->setAttribute(Qt::WA_DeleteOnClose
);
2346 void WiresharkMainWindow::editTimeShiftFinished(int)
2348 if (capture_file_
.capFile()->unsaved_changes
) {
2349 updateForUnsavedChanges();
2353 void WiresharkMainWindow::addPacketComment()
2355 QList
<int> rows
= selectedRows();
2356 if (rows
.count() == 0)
2359 frame_data
* fdata
= frameDataForRow(rows
.at(0));
2363 PacketCommentDialog
* pc_dialog
;
2364 pc_dialog
= new PacketCommentDialog(false, this, NULL
);
2365 connect(pc_dialog
, &QDialog::finished
, std::bind(&WiresharkMainWindow::addPacketCommentFinished
, this, pc_dialog
, std::placeholders::_1
));
2366 pc_dialog
->setWindowModality(Qt::ApplicationModal
);
2367 pc_dialog
->setAttribute(Qt::WA_DeleteOnClose
);
2371 void WiresharkMainWindow::addPacketCommentFinished(PacketCommentDialog
* pc_dialog _U_
, int result _U_
)
2373 if (result
== QDialog::Accepted
) {
2374 packet_list_
->addPacketComment(pc_dialog
->text());
2375 updateForUnsavedChanges();
2379 void WiresharkMainWindow::editPacketComment()
2381 QList
<int> rows
= selectedRows();
2382 if (rows
.count() != 1)
2385 QAction
*ra
= qobject_cast
<QAction
*>(sender());
2386 unsigned nComment
= ra
->data().toUInt();
2387 PacketCommentDialog
* pc_dialog
;
2388 pc_dialog
= new PacketCommentDialog(true, this, packet_list_
->getPacketComment(nComment
));
2389 connect(pc_dialog
, &QDialog::finished
, std::bind(&WiresharkMainWindow::editPacketCommentFinished
, this, pc_dialog
, std::placeholders::_1
, nComment
));
2390 pc_dialog
->setWindowModality(Qt::ApplicationModal
);
2391 pc_dialog
->setAttribute(Qt::WA_DeleteOnClose
);
2395 void WiresharkMainWindow::editPacketCommentFinished(PacketCommentDialog
* pc_dialog _U_
, int result _U_
, unsigned nComment
)
2397 if (result
== QDialog::Accepted
) {
2398 packet_list_
->setPacketComment(nComment
, pc_dialog
->text());
2399 updateForUnsavedChanges();
2403 void WiresharkMainWindow::deletePacketComment()
2405 QAction
*ra
= qobject_cast
<QAction
*>(sender());
2406 unsigned nComment
= ra
->data().toUInt();
2407 packet_list_
->setPacketComment(nComment
, QString(""));
2408 updateForUnsavedChanges();
2411 void WiresharkMainWindow::deleteCommentsFromPackets()
2413 packet_list_
->deleteCommentsFromPackets();
2414 updateForUnsavedChanges();
2417 void WiresharkMainWindow::deleteAllPacketComments()
2419 QMessageBox
*msg_dialog
= new QMessageBox(this);
2420 connect(msg_dialog
, &QMessageBox::finished
, this, &WiresharkMainWindow::deleteAllPacketCommentsFinished
);
2422 msg_dialog
->setIcon(QMessageBox::Question
);
2423 msg_dialog
->setText(tr("Are you sure you want to remove all packet comments?"));
2425 msg_dialog
->setStandardButtons(QMessageBox::Ok
| QMessageBox::Cancel
);
2426 msg_dialog
->setDefaultButton(QMessageBox::Ok
);
2428 msg_dialog
->setWindowModality(Qt::ApplicationModal
);
2429 msg_dialog
->setAttribute(Qt::WA_DeleteOnClose
);
2433 void WiresharkMainWindow::deleteAllPacketCommentsFinished(int result
)
2435 if (result
== QMessageBox::Ok
) {
2436 /* XXX Do we need a wait/hourglass for large files? */
2437 packet_list_
->deleteAllPacketComments();
2438 updateForUnsavedChanges();
2442 void WiresharkMainWindow::injectSecrets()
2446 keylist_len
= ssl_session_key_count();
2447 /* don't do anything if no data has to be saved */
2448 if (keylist_len
< 1) {
2449 QMessageBox::Button ret
= QMessageBox::warning(
2451 tr("No TLS Secrets"),
2452 tr("There are no available secrets used to decrypt TLS traffic in the capture file.\
2453 Would you like to view information about how to decrypt TLS traffic on the wiki?"),
2454 QMessageBox::Yes
| QMessageBox::No
,
2457 if (ret
!= QMessageBox::Yes
) return;
2459 QUrl wiki_url
= QString(WS_WIKI_URL("TLS#tls-decryption"));
2460 QDesktopServices::openUrl(wiki_url
);
2464 if (!capture_file_
.isValid())
2467 /* XXX: It would be nice to handle other types of secrets that
2468 * can be written to a DSB, maybe have a proper dialog.
2470 capture_file
*cf
= capture_file_
.capFile();
2472 updateForUnsavedChanges();
2475 void WiresharkMainWindow::discardAllSecrets()
2477 if (!capture_file_
.isValid())
2480 QMessageBox
* msg_dialog
= new QMessageBox(this);
2481 connect(msg_dialog
, &QMessageBox::finished
, this, &WiresharkMainWindow::discardAllSecretsFinished
);
2483 msg_dialog
->setIcon(QMessageBox::Question
);
2484 msg_dialog
->setText(tr("Are you sure you want to discard all decryption secrets?"));
2486 msg_dialog
->setStandardButtons(QMessageBox::Ok
| QMessageBox::Cancel
);
2487 msg_dialog
->setDefaultButton(QMessageBox::Ok
);
2489 msg_dialog
->setWindowModality(Qt::ApplicationModal
);
2490 msg_dialog
->setAttribute(Qt::WA_DeleteOnClose
);
2494 void WiresharkMainWindow::discardAllSecretsFinished(int result
)
2496 if (result
== QMessageBox::Ok
) {
2497 /* XXX: It would be nice to handle other types of secrets that
2498 * can be written to a DSB, maybe have a proper dialog.
2500 capture_file
* cf
= capture_file_
.capFile();
2501 if (wtap_file_discard_decryption_secrets(cf
->provider
.wth
)) {
2502 cf
->unsaved_changes
= true;
2503 updateForUnsavedChanges();
2508 void WiresharkMainWindow::editConfigurationProfiles()
2510 ProfileDialog
*cp_dialog
= new ProfileDialog(this);
2511 cp_dialog
->setWindowModality(Qt::ApplicationModal
);
2512 cp_dialog
->setAttribute(Qt::WA_DeleteOnClose
);
2516 void WiresharkMainWindow::showPreferencesDialog(QString module_name
)
2518 PreferencesDialog
*pref_dialog
= new PreferencesDialog(this);
2519 connect(pref_dialog
, &PreferencesDialog::destroyed
, mainApp
, &MainApplication::flushAppSignals
);
2520 saveWindowGeometry(); // Save in case the layout panes are rearranged
2522 pref_dialog
->setPane(module_name
);
2523 pref_dialog
->setWindowModality(Qt::ApplicationModal
);
2524 pref_dialog
->setAttribute(Qt::WA_DeleteOnClose
);
2525 pref_dialog
->show();
2530 void WiresharkMainWindow::connectViewMenuActions()
2532 connect(main_ui_
->actionViewFullScreen
, &QAction::triggered
, this, [this](bool checked
) {
2534 // Save the state for future restore
2535 was_maximized_
= this->isMaximized();
2536 this->showFullScreen();
2538 // Restore the previous state
2539 if (was_maximized_
) {
2540 this->showMaximized();
2547 connect(main_ui_
->actionViewTimeDisplaySecondsWithHoursAndMinutes
, &QAction::triggered
, this,
2548 [this](bool checked
) { setTimeDisplaySecondsWithHoursAndMinutes(checked
); });
2550 connect(main_ui_
->actionViewEditResolvedName
, &QAction::triggered
, this,
2551 [this]() { editResolvedName(); });
2553 connect(main_ui_
->actionViewNameResolutionPhysical
, &QAction::triggered
, this,
2554 [this]() { setNameResolution(); });
2556 connect(main_ui_
->actionViewNameResolutionNetwork
, &QAction::triggered
, this,
2557 [this]() { setNameResolution(); });
2559 connect(main_ui_
->actionViewNameResolutionTransport
, &QAction::triggered
, this,
2560 [this]() { setNameResolution(); });
2562 connect(main_ui_
->actionViewZoomIn
, &QAction::triggered
, this, [this]() {
2563 recent
.gui_zoom_level
++;
2567 connect(main_ui_
->actionViewZoomOut
, &QAction::triggered
, this, [this]() {
2568 recent
.gui_zoom_level
--;
2572 connect(main_ui_
->actionViewNormalSize
, &QAction::triggered
, this, [this]() {
2573 recent
.gui_zoom_level
= 0;
2577 connect(main_ui_
->actionViewExpandSubtrees
, &QAction::triggered
,
2578 proto_tree_
, &ProtoTree::expandSubtrees
);
2580 connect(main_ui_
->actionViewCollapseSubtrees
, &QAction::triggered
,
2581 proto_tree_
, &ProtoTree::collapseSubtrees
);
2583 connect(main_ui_
->actionViewExpandAll
, &QAction::triggered
,
2584 proto_tree_
, &ProtoTree::expandAll
);
2586 connect(main_ui_
->actionViewCollapseAll
, &QAction::triggered
,
2587 proto_tree_
, &ProtoTree::collapseAll
);
2589 connect(main_ui_
->actionViewColorizePacketList
, &QAction::triggered
, this, [this](bool checked
) {
2590 recent
.packet_list_colorize
= checked
;
2591 packet_list_
->recolorPackets();
2594 connect(main_ui_
->actionViewColoringRules
, &QAction::triggered
, this,
2595 [this]() { showColoringRulesDialog(); });
2597 connect(main_ui_
->actionViewColorizeResetColorization
, &QAction::triggered
, this, [this]() {
2598 char *err_msg
= NULL
;
2599 if (!color_filters_reset_tmp(&err_msg
)) {
2600 simple_dialog(ESD_TYPE_ERROR
, ESD_BTN_OK
, "%s", err_msg
);
2603 packet_list_
->recolorPackets();
2604 setMenusForSelectedPacket();
2607 connect(main_ui_
->actionViewColorizeNewColoringRule
, &QAction::triggered
, this,
2608 [this]() { colorizeConversation(true); });
2610 connect(main_ui_
->actionViewResetLayout
, &QAction::triggered
, this, [this]() {
2611 recent
.gui_geometry_main_upper_pane
= 0;
2612 recent
.gui_geometry_main_lower_pane
= 0;
2613 g_free(recent
.gui_geometry_main_master_split
);
2614 g_free(recent
.gui_geometry_main_extra_split
);
2615 recent
.gui_geometry_main_master_split
= NULL
;
2616 recent
.gui_geometry_main_extra_split
= NULL
;
2617 applyRecentPaneGeometry();
2620 connect(main_ui_
->actionViewResizeColumns
, &QAction::triggered
, this, [this]() {
2621 if (! packet_list_
->model())
2623 for (int col
= 0; col
< packet_list_
->model()->columnCount(); col
++) {
2624 packet_list_
->resizeColumnToContents(col
);
2625 recent_set_column_width(col
, packet_list_
->columnWidth(col
));
2629 connect(main_ui_
->actionViewInternalsConversationHashTables
, &QAction::triggered
, this, [this]() {
2630 ConversationHashTablesDialog
*conversation_hash_tables_dlg
= new ConversationHashTablesDialog(this);
2631 conversation_hash_tables_dlg
->show();
2634 connect(main_ui_
->actionViewInternalsDissectorTables
, &QAction::triggered
, this, [this]() {
2635 DissectorTablesDialog
*dissector_tables_dlg
= new DissectorTablesDialog(this);
2636 dissector_tables_dlg
->show();
2639 connect(main_ui_
->actionViewInternalsSupportedProtocols
, &QAction::triggered
, this, [this]() {
2640 SupportedProtocolsDialog
*supported_protocols_dlg
= new SupportedProtocolsDialog(this);
2641 supported_protocols_dlg
->show();
2644 connect(main_ui_
->actionViewShowPacketInNewWindow
, &QAction::triggered
, this,
2645 [this]() { openPacketDialog(); });
2647 // This is only used in ProtoTree. Defining it here makes more sense.
2648 connect(main_ui_
->actionContextShowLinkedPacketInNewWindow
, &QAction::triggered
, this,
2649 [this]() { openPacketDialog(true); });
2651 connect(main_ui_
->actionViewReload_as_File_Format_or_Capture
, &QAction::triggered
, this,
2652 [this]() { reloadCaptureFileAsFormatOrCapture(); });
2654 connect(main_ui_
->actionViewReload
, &QAction::triggered
, this,
2655 [this]() { reloadCaptureFile(); });
2658 void WiresharkMainWindow::showHideMainWidgets(QAction
*action
)
2663 bool show
= action
->isChecked();
2664 QWidget
*widget
= action
->data().value
<QWidget
*>();
2666 // We may have come from the toolbar context menu, so check/uncheck each
2668 if (widget
== main_ui_
->mainToolBar
) {
2669 recent
.main_toolbar_show
= show
;
2670 main_ui_
->actionViewMainToolbar
->setChecked(show
);
2671 } else if (widget
== main_ui_
->displayFilterToolBar
) {
2672 recent
.filter_toolbar_show
= show
;
2673 main_ui_
->actionViewFilterToolbar
->setChecked(show
);
2674 #if defined(HAVE_LIBNL) && defined(HAVE_NL80211)
2675 } else if (widget
== main_ui_
->wirelessToolBar
) {
2676 recent
.wireless_toolbar_show
= show
;
2677 main_ui_
->actionViewWirelessToolbar
->setChecked(show
);
2679 } else if (widget
== main_ui_
->statusBar
) {
2680 recent
.statusbar_show
= show
;
2681 main_ui_
->actionViewStatusBar
->setChecked(show
);
2682 } else if (widget
== packet_list_
) {
2683 recent
.packet_list_show
= show
;
2684 main_ui_
->actionViewPacketList
->setChecked(show
);
2685 } else if (widget
== proto_tree_
) {
2686 recent
.tree_view_show
= show
;
2687 main_ui_
->actionViewPacketDetails
->setChecked(show
);
2688 } else if (widget
== byte_view_tab_
) {
2689 recent
.byte_view_show
= show
;
2690 main_ui_
->actionViewPacketBytes
->setChecked(show
);
2691 } else if (widget
== packet_diagram_
) {
2692 recent
.packet_diagram_show
= show
;
2693 main_ui_
->actionViewPacketDiagram
->setChecked(show
);
2695 foreach(QAction
*action
, main_ui_
->menuInterfaceToolbars
->actions()) {
2696 QToolBar
*toolbar
= action
->data().value
<QToolBar
*>();
2697 if (widget
== toolbar
) {
2698 GList
*entry
= g_list_find_custom(recent
.interface_toolbars
, action
->text().toUtf8(), (GCompareFunc
)strcmp
);
2699 if (show
&& !entry
) {
2700 recent
.interface_toolbars
= g_list_append(recent
.interface_toolbars
, qstring_strdup(action
->text()));
2701 } else if (!show
&& entry
) {
2702 recent
.interface_toolbars
= g_list_remove(recent
.interface_toolbars
, entry
->data
);
2704 action
->setChecked(show
);
2708 ext_toolbar_t
* toolbar
= VariantPointer
<ext_toolbar_t
>::asPtr(action
->data());
2710 GList
*entry
= g_list_find_custom(recent
.gui_additional_toolbars
, toolbar
->name
, (GCompareFunc
)strcmp
);
2711 if (show
&& !entry
) {
2712 recent
.gui_additional_toolbars
= g_list_append(recent
.gui_additional_toolbars
, g_strdup(toolbar
->name
));
2713 } else if (!show
&& entry
) {
2714 recent
.gui_additional_toolbars
= g_list_remove(recent
.gui_additional_toolbars
, entry
->data
);
2716 action
->setChecked(show
);
2718 QList
<QToolBar
*> toolbars
= findChildren
<QToolBar
*>();
2719 foreach(QToolBar
*bar
, toolbars
) {
2720 AdditionalToolBar
*iftoolbar
= dynamic_cast<AdditionalToolBar
*>(bar
);
2721 if (iftoolbar
&& iftoolbar
->menuName().compare(toolbar
->name
) == 0) {
2722 iftoolbar
->setVisible(show
);
2729 widget
->setVisible(show
);
2733 void WiresharkMainWindow::setTimestampFormat(QAction
*action
)
2738 ts_type tsf
= action
->data().value
<ts_type
>();
2739 if (recent
.gui_time_format
!= tsf
) {
2740 timestamp_set_type(tsf
);
2741 recent
.gui_time_format
= tsf
;
2744 packet_list_
->resetColumns();
2745 packet_list_
->resizeAllColumns(true);
2750 void WiresharkMainWindow::setTimestampPrecision(QAction
*action
)
2755 ts_precision tsp
= action
->data().value
<ts_precision
>();
2756 if (recent
.gui_time_precision
!= tsp
) {
2757 timestamp_set_precision(tsp
);
2758 recent
.gui_time_precision
= tsp
;
2761 packet_list_
->resetColumns();
2762 packet_list_
->resizeAllColumns(true);
2767 void WiresharkMainWindow::setTimeDisplaySecondsWithHoursAndMinutes(bool checked
)
2770 recent
.gui_seconds_format
= TS_SECONDS_HOUR_MIN_SEC
;
2772 recent
.gui_seconds_format
= TS_SECONDS_DEFAULT
;
2774 timestamp_set_seconds_type(recent
.gui_seconds_format
);
2777 packet_list_
->resetColumns();
2778 packet_list_
->resizeAllColumns(true);
2782 void WiresharkMainWindow::editResolvedName()
2784 //int column = packet_list_->selectedColumn();
2787 if (packet_list_
->contextMenuActive() || packet_list_
->hasFocus()) {
2788 if (packet_list_
->currentIndex().isValid()) {
2789 column
= packet_list_
->currentIndex().column();
2793 main_ui_
->addressEditorFrame
->editAddresses(capture_file_
, column
);
2794 showAccordionFrame(main_ui_
->addressEditorFrame
);
2797 void WiresharkMainWindow::setNameResolution()
2799 gbl_resolv_flags
.mac_name
= main_ui_
->actionViewNameResolutionPhysical
->isChecked() ? true : false;
2800 gbl_resolv_flags
.network_name
= main_ui_
->actionViewNameResolutionNetwork
->isChecked() ? true : false;
2801 gbl_resolv_flags
.transport_name
= main_ui_
->actionViewNameResolutionTransport
->isChecked() ? true : false;
2804 packet_list_
->resetColumns();
2806 mainApp
->emitAppSignal(WiresharkApplication::NameResolutionChanged
);
2809 void WiresharkMainWindow::zoomText()
2811 mainApp
->zoomTextFont(recent
.gui_zoom_level
);
2814 void WiresharkMainWindow::showColoringRulesDialog()
2816 ColoringRulesDialog
*coloring_rules_dialog
= new ColoringRulesDialog(this);
2817 connect(coloring_rules_dialog
, &ColoringRulesDialog::accepted
,
2818 packet_list_
, &PacketList::recolorPackets
);
2819 connect(coloring_rules_dialog
, &ColoringRulesDialog::filterAction
,
2820 this, &WiresharkMainWindow::filterAction
);
2822 coloring_rules_dialog
->setWindowModality(Qt::ApplicationModal
);
2823 coloring_rules_dialog
->setAttribute(Qt::WA_DeleteOnClose
);
2824 coloring_rules_dialog
->show();
2827 // actionViewColorizeConversation1 - 10
2828 void WiresharkMainWindow::colorizeConversation(bool create_rule
)
2830 QAction
*colorize_action
= qobject_cast
<QAction
*>(sender());
2831 if (!colorize_action
) return;
2833 if (capture_file_
.capFile() && selectedRows().count() > 0) {
2834 packet_info
*pi
= capture_file_
.packetInfo();
2835 uint8_t cc_num
= colorize_action
->data().toUInt();
2836 char *filter
= conversation_filter_from_packet(pi
);
2837 if (filter
== NULL
) {
2838 mainApp
->pushStatus(WiresharkApplication::TemporaryStatus
, tr("Unable to build conversation filter."));
2843 ColoringRulesDialog
coloring_rules_dialog(this, filter
);
2844 connect(&coloring_rules_dialog
, &ColoringRulesDialog::accepted
,
2845 packet_list_
, &PacketList::recolorPackets
);
2846 connect(&coloring_rules_dialog
, &ColoringRulesDialog::filterAction
,
2847 this, &WiresharkMainWindow::filterAction
);
2848 coloring_rules_dialog
.exec();
2850 char *err_msg
= NULL
;
2851 char *prev_filter
= color_filters_get_tmp(cc_num
);
2852 if (!color_filters_set_tmp(cc_num
, filter
, prev_filter
&& (strcmp(prev_filter
,filter
)==0), &err_msg
)) {
2853 simple_dialog(ESD_TYPE_ERROR
, ESD_BTN_OK
, "%s", err_msg
);
2856 g_free(prev_filter
);
2857 packet_list_
->recolorPackets();
2860 setMenusForSelectedPacket();
2863 void WiresharkMainWindow::colorizeActionTriggered()
2866 int color_number
= -1;
2868 ConversationAction
*conv_action
= qobject_cast
<ConversationAction
*>(sender());
2870 filter
= conv_action
->filter();
2871 color_number
= conv_action
->colorNumber();
2873 ColorizeAction
*colorize_action
= qobject_cast
<ColorizeAction
*>(sender());
2874 if (colorize_action
) {
2875 filter
= colorize_action
->filter();
2876 color_number
= colorize_action
->colorNumber();
2880 colorizeWithFilter(filter
, color_number
);
2883 void WiresharkMainWindow::colorizeWithFilter(QByteArray filter
, int color_number
)
2885 if (filter
.isEmpty()) return;
2887 if (color_number
> 0) {
2889 char *err_msg
= NULL
;
2890 char *prev_filter
= color_filters_get_tmp(color_number
);
2891 if (!color_filters_set_tmp(color_number
, filter
.constData(), prev_filter
&& (strcmp(prev_filter
,filter
.constData())==0), &err_msg
)) {
2892 simple_dialog(ESD_TYPE_ERROR
, ESD_BTN_OK
, "%s", err_msg
);
2895 g_free(prev_filter
);
2896 packet_list_
->recolorPackets();
2898 // New coloring rule
2899 ColoringRulesDialog
coloring_rules_dialog(window(), filter
);
2900 connect(&coloring_rules_dialog
, &ColoringRulesDialog::accepted
,
2901 packet_list_
, &PacketList::recolorPackets
);
2902 connect(&coloring_rules_dialog
, &ColoringRulesDialog::filterAction
,
2903 this, &WiresharkMainWindow::filterAction
);
2904 coloring_rules_dialog
.exec();
2906 main_ui_
->actionViewColorizeResetColorization
->setEnabled(tmp_color_filters_used());
2909 void WiresharkMainWindow::openPacketDialog(bool from_reference
)
2911 frame_data
* fdata
= Q_NULLPTR
;
2913 /* Find the frame for which we're popping up a dialog */
2914 if (from_reference
) {
2915 uint32_t framenum
= fvalue_get_uinteger(capture_file_
.capFile()->finfo_selected
->value
);
2919 fdata
= frame_data_sequence_find(capture_file_
.capFile()->provider
.frames
, framenum
);
2920 } else if (selectedRows().count() == 1) {
2921 fdata
= frameDataForRow(selectedRows().at(0));
2922 } else if (selectedRows().count() > 1)
2925 /* If we have a frame, pop up the dialog */
2927 PacketDialog
*packet_dialog
= new PacketDialog(*this, capture_file_
, fdata
);
2929 connect(packet_dialog
, &PacketDialog::showProtocolPreferences
,
2930 this, &WiresharkMainWindow::showPreferencesDialog
);
2931 connect(packet_dialog
, SIGNAL(editProtocolPreference(preference
*, pref_module
*)),
2932 main_ui_
->preferenceEditorFrame
, SLOT(editPreference(preference
*, pref_module
*)));
2934 connect(this, &WiresharkMainWindow::closePacketDialogs
, packet_dialog
, &PacketDialog::close
);
2935 zoomText(); // Emits mainApp->zoomMonospaceFont(QFont)
2937 packet_dialog
->show();
2941 void WiresharkMainWindow::reloadCaptureFileAsFormatOrCapture()
2943 capture_file
*cf
= CaptureFile::globalCapFile();
2945 if (cf
->unsaved_changes
) {
2946 QString
before_what(tr(" before reloading the file"));
2947 if (!testCaptureFileClose(before_what
, Reload
))
2951 if (cf
->open_type
== WTAP_TYPE_AUTO
)
2952 cf
->open_type
= open_info_name_to_type("MIME Files Format");
2953 else /* TODO: This should be latest format chosen by user */
2954 cf
->open_type
= WTAP_TYPE_AUTO
;
2959 void WiresharkMainWindow::reloadCaptureFile()
2961 capture_file
*cf
= CaptureFile::globalCapFile();
2963 if (cf
->unsaved_changes
) {
2964 QString
before_what(tr(" before reloading the file"));
2965 if (!testCaptureFileClose(before_what
, Reload
))
2973 // Expand / collapse slots in proto_tree
2977 void WiresharkMainWindow::connectGoMenuActions()
2979 connect(main_ui_
->actionGoGoToPacket
, &QAction::triggered
, this, [this]() {
2980 if (! packet_list_
->model() || packet_list_
->model()->rowCount() < 1) {
2985 showAccordionFrame(main_ui_
->goToFrame
, true);
2986 if (main_ui_
->goToFrame
->isVisible()) {
2987 main_ui_
->goToLineEdit
->clear();
2988 main_ui_
->goToLineEdit
->setFocus();
2992 connect(main_ui_
->actionGoGoToLinkedPacket
, &QAction::triggered
, this, [this]() {
2993 QAction
*gta
= qobject_cast
<QAction
*>(sender());
2997 int packet_num
= gta
->data().toInt(&ok
);
3000 packet_list_
->goToPacket(packet_num
);
3003 connect(main_ui_
->actionGoNextPacket
, &QAction::triggered
,
3004 packet_list_
, &PacketList::goNextPacket
);
3006 connect(main_ui_
->actionGoPreviousPacket
, &QAction::triggered
,
3007 packet_list_
, &PacketList::goPreviousPacket
);
3009 connect(main_ui_
->actionGoFirstPacket
, &QAction::triggered
,
3010 packet_list_
, &PacketList::goFirstPacket
);
3012 connect(main_ui_
->actionGoLastPacket
, &QAction::triggered
,
3013 packet_list_
, &PacketList::goLastPacket
);
3015 connect(main_ui_
->actionGoNextConversationPacket
, &QAction::triggered
, this,
3016 [this]() { goToConversationFrame(true); });
3018 connect(main_ui_
->actionGoPreviousConversationPacket
, &QAction::triggered
, this,
3019 [this]() { goToConversationFrame(false); });
3021 connect(main_ui_
->actionGoNextHistoryPacket
, &QAction::triggered
,
3022 packet_list_
, &PacketList::goNextHistoryPacket
);
3024 connect(main_ui_
->actionGoPreviousHistoryPacket
, &QAction::triggered
,
3025 packet_list_
, &PacketList::goPreviousHistoryPacket
);
3027 // triggered is whenever the user clicks the button; save that as
3028 // the new recent value
3029 connect(main_ui_
->actionGoAutoScroll
, &QAction::triggered
, this,
3030 [](bool checked
) { recent
.capture_auto_scroll
= checked
; });
3032 // toggled is whenever the value changes; if it changes programmatically
3033 // (e.g., the user scrolls upwards so we stop auto scrolling) change
3034 // whether the button is checked but don't save value to recent (it's
3035 // a temporary change)
3036 connect(main_ui_
->actionGoAutoScroll
, &QAction::toggled
, this,
3037 [this](bool checked
) { packet_list_
->setVerticalAutoScroll(checked
); });
3040 void WiresharkMainWindow::goToConversationFrame(bool go_next
) {
3041 char *filter
= NULL
;
3042 dfilter_t
*dfcode
= NULL
;
3043 bool found_packet
= false;
3044 packet_info
*pi
= capture_file_
.packetInfo();
3047 // No packet was selected, or multiple packets were selected.
3051 /* Try to build a conversation
3052 * filter in the order TCP, UDP, IP, Ethernet and apply the
3054 filter
= conversation_filter_from_packet(pi
);
3055 if (filter
== NULL
) {
3056 mainApp
->pushStatus(WiresharkApplication::TemporaryStatus
, tr("Unable to build conversation filter."));
3061 if (!dfilter_compile(filter
, &dfcode
, NULL
)) {
3062 /* The attempt failed; report an error. */
3063 mainApp
->pushStatus(WiresharkApplication::TemporaryStatus
, tr("Error compiling filter for this conversation."));
3068 found_packet
= cf_find_packet_dfilter(capture_file_
.capFile(), dfcode
, go_next
? SD_FORWARD
: SD_BACKWARD
);
3070 if (!found_packet
) {
3071 /* We didn't find a packet */
3072 mainApp
->pushStatus(WiresharkApplication::TemporaryStatus
, tr("No previous/next packet in conversation."));
3075 dfilter_free(dfcode
);
3081 void WiresharkMainWindow::connectCaptureMenuActions()
3084 connect(main_ui_
->actionCaptureOptions
, &QAction::triggered
, this,
3085 [this]() { showCaptureOptionsDialog(); });
3088 connect(main_ui_
->actionCaptureStart
, &QAction::triggered
, this,
3089 [this]() { startCaptureTriggered(); });
3091 connect(main_ui_
->actionCaptureStop
, &QAction::triggered
, this,
3092 [this]() { stopCapture(); });
3095 connect(main_ui_
->actionCaptureRestart
, &QAction::triggered
, this, [this]() {
3096 QString
before_what(tr(" before restarting the capture"));
3097 cap_session_
.capture_opts
->restart
= true;
3098 if (!testCaptureFileClose(before_what
, Restart
)) {
3101 startCapture(QStringList());
3103 #endif // HAVE_LIBPCAP
3105 connect(main_ui_
->actionCaptureCaptureFilters
, &QAction::triggered
, this, [this]() {
3106 FilterDialog
*capture_filter_dlg
= new FilterDialog(window(), FilterDialog::CaptureFilter
);
3107 capture_filter_dlg
->setWindowModality(Qt::ApplicationModal
);
3108 capture_filter_dlg
->setAttribute(Qt::WA_DeleteOnClose
);
3109 capture_filter_dlg
->show();
3113 connect(main_ui_
->actionCaptureRefreshInterfaces
, &QAction::triggered
, this, [this]() {
3114 main_ui_
->actionCaptureRefreshInterfaces
->setEnabled(false);
3115 mainApp
->refreshLocalInterfaces();
3116 main_ui_
->actionCaptureRefreshInterfaces
->setEnabled(true);
3121 void WiresharkMainWindow::showCaptureOptionsDialog()
3124 if (!capture_options_dialog_
) {
3125 capture_options_dialog_
= new CaptureOptionsDialog(this);
3127 connect(capture_options_dialog_
, &CaptureOptionsDialog::startCapture
, this, [this]() { startCapture(); });
3128 connect(capture_options_dialog_
, &CaptureOptionsDialog::stopCapture
, this, &WiresharkMainWindow::stopCapture
);
3130 connect(capture_options_dialog_
, &CaptureOptionsDialog::interfacesChanged
,
3131 this->welcome_page_
, &WelcomePage::interfaceSelected
);
3132 connect(capture_options_dialog_
, &CaptureOptionsDialog::interfacesChanged
,
3133 this->welcome_page_
->getInterfaceFrame(), &InterfaceFrame::updateSelectedInterfaces
);
3134 connect(capture_options_dialog_
, &CaptureOptionsDialog::interfaceListChanged
,
3135 this->welcome_page_
->getInterfaceFrame(), &InterfaceFrame::interfaceListChanged
);
3136 connect(capture_options_dialog_
, &CaptureOptionsDialog::captureFilterTextEdited
,
3137 this->welcome_page_
, &WelcomePage::setCaptureFilterText
);
3138 // Propagate selection changes from main UI to dialog.
3139 connect(this->welcome_page_
, &WelcomePage::interfacesChanged
,
3140 capture_options_dialog_
, &CaptureOptionsDialog::interfaceSelected
);
3142 connect(capture_options_dialog_
, &CaptureOptionsDialog::setFilterValid
,
3143 this, &WiresharkMainWindow::startInterfaceCapture
);
3145 connect(capture_options_dialog_
, &CaptureOptionsDialog::showExtcapOptions
,
3146 this, &WiresharkMainWindow::showExtcapOptionsDialog
);
3148 capture_options_dialog_
->updateInterfaces();
3150 if (capture_options_dialog_
->isMinimized()) {
3151 capture_options_dialog_
->showNormal();
3153 capture_options_dialog_
->show();
3156 capture_options_dialog_
->raise();
3157 capture_options_dialog_
->activateWindow();
3161 void WiresharkMainWindow::startCaptureTriggered()
3164 // if (cap_open_w) {
3166 // * There's an options dialog; get the values from it and close it.
3170 // /* Determine if "capture start" while building of the "capture options" window */
3171 // /* is in progress. If so, ignore the "capture start. */
3172 // /* XXX: Would it be better/cleaner for the "capture options" window code to */
3173 // /* disable the capture start button temporarily ? */
3174 // if (cap_open_complete == false) {
3175 // return; /* Building options window: ignore "capture start" */
3177 // success = capture_dlg_prep(cap_open_w);
3178 // window_destroy(GTK_WIDGET(cap_open_w));
3180 // return; /* error in options dialog */
3184 if (global_capture_opts
.num_selected
== 0) {
3185 QString err_msg
= tr("No Interface Selected.");
3186 mainApp
->pushStatus(WiresharkApplication::TemporaryStatus
, err_msg
);
3187 main_ui_
->actionCaptureStart
->setChecked(false);
3191 /* XXX - will closing this remove a temporary file? */
3192 QString
before_what(tr(" before starting a new capture"));
3193 if (testCaptureFileClose(before_what
)) {
3194 startCapture(QStringList());
3196 // simply clicking the button sets it to 'checked' even though we've
3197 // decided to do nothing, so undo that
3198 main_ui_
->actionCaptureStart
->setChecked(false);
3200 #endif // HAVE_LIBPCAP
3207 void WiresharkMainWindow::connectAnalyzeMenuActions()
3209 connect(main_ui_
->actionAnalyzeDisplayFilters
, &QAction::triggered
, this, [=]() {
3210 FilterDialog
*display_filter_dlg
= new FilterDialog(window(), FilterDialog::DisplayFilter
);
3211 display_filter_dlg
->setWindowModality(Qt::ApplicationModal
);
3212 display_filter_dlg
->setAttribute(Qt::WA_DeleteOnClose
);
3213 display_filter_dlg
->show();
3216 connect(main_ui_
->actionAnalyzeDisplayFilterMacros
, &QAction::triggered
, this, [=]() {
3217 FilterDialog
*display_filter_dlg
= new FilterDialog(window(), FilterDialog::DisplayMacro
);
3218 display_filter_dlg
->setWindowModality(Qt::ApplicationModal
);
3219 display_filter_dlg
->setAttribute(Qt::WA_DeleteOnClose
);
3220 display_filter_dlg
->show();
3223 connect(main_ui_
->actionDisplayFilterExpression
, &QAction::triggered
, this, [=]() {
3224 DisplayFilterExpressionDialog
*dfe_dialog
= new DisplayFilterExpressionDialog(this);
3226 connect(dfe_dialog
, &DisplayFilterExpressionDialog::insertDisplayFilter
,
3227 qobject_cast
<SyntaxLineEdit
*>(df_combo_box_
->lineEdit()), &SyntaxLineEdit::insertFilter
);
3232 connect(main_ui_
->actionAnalyzeApplyAsColumn
, &QAction::triggered
, this, &WiresharkMainWindow::applyFieldAsColumn
);
3234 connect(main_ui_
->actionAnalyzeEnabledProtocols
, &QAction::triggered
, this, [=]() {
3235 EnabledProtocolsDialog
*enable_proto_dialog
= new EnabledProtocolsDialog(this);
3236 connect(enable_proto_dialog
, &EnabledProtocolsDialog::destroyed
, mainApp
, &MainApplication::flushAppSignals
);
3238 enable_proto_dialog
->setWindowModality(Qt::ApplicationModal
);
3239 enable_proto_dialog
->setAttribute(Qt::WA_DeleteOnClose
);
3240 enable_proto_dialog
->show();
3243 connect(main_ui_
->actionAnalyzeDecodeAs
, &QAction::triggered
, this, [=]() {
3244 QAction
*da_action
= qobject_cast
<QAction
*>(sender());
3245 bool create_new
= da_action
&& da_action
->property("create_new").toBool();
3247 DecodeAsDialog
*da_dialog
= new DecodeAsDialog(this, capture_file_
.capFile(), create_new
);
3248 connect(da_dialog
, &DecodeAsDialog::destroyed
, mainApp
, &MainApplication::flushAppSignals
);
3250 da_dialog
->setWindowModality(Qt::ApplicationModal
);
3251 da_dialog
->setAttribute(Qt::WA_DeleteOnClose
);
3255 connect(main_ui_
->actionAnalyzeReloadLuaPlugins
, &QAction::triggered
, this, &WiresharkMainWindow::reloadLuaPlugins
);
3257 connect(main_ui_
->actionAnalyzeShowPacketBytes
, &QAction::triggered
, this, [=]() {
3258 ShowPacketBytesDialog
*spbd
= new ShowPacketBytesDialog(*this, capture_file_
);
3259 spbd
->addCodecs(text_codec_map_
);
3263 connect(main_ui_
->actionAnalyzeExpertInfo
, &QAction::triggered
, this, [=]() {
3264 statCommandExpertInfo(NULL
, NULL
);
3268 void WiresharkMainWindow::filterMenuAboutToShow()
3270 QMenu
* menu
= qobject_cast
<QMenu
*>(sender());
3271 QString field_filter
;
3273 if (capture_file_
.capFile() && capture_file_
.capFile()->finfo_selected
) {
3274 char *tmp_field
= proto_construct_match_selected_string(capture_file_
.capFile()->finfo_selected
,
3275 capture_file_
.capFile()->edt
);
3276 field_filter
= QString(tmp_field
);
3277 wmem_free(NULL
, tmp_field
);
3279 bool enable
= ! field_filter
.isEmpty();
3280 bool prepare
= menu
->objectName().compare("menuPrepareAFilter") == 0;
3283 QActionGroup
* group
= FilterAction::createFilterGroup(field_filter
, prepare
, enable
, menu
);
3284 menu
->addActions(group
->actions());
3287 void WiresharkMainWindow::matchFieldFilter(FilterAction::Action action
, FilterAction::ActionType filter_type
)
3289 QString field_filter
;
3291 if (packet_list_
->contextMenuActive() || packet_list_
->hasFocus()) {
3292 field_filter
= packet_list_
->getFilterFromRowAndColumn(packet_list_
->currentIndex());
3293 } else if (capture_file_
.capFile() && capture_file_
.capFile()->finfo_selected
) {
3294 char *tmp_field
= proto_construct_match_selected_string(capture_file_
.capFile()->finfo_selected
,
3295 capture_file_
.capFile()->edt
);
3296 field_filter
= QString(tmp_field
);
3297 wmem_free(NULL
, tmp_field
);
3300 if (field_filter
.isEmpty()) {
3301 QString err
= tr("No filter available. Try another %1.").arg(packet_list_
->contextMenuActive() ? tr("column") : tr("item"));
3302 mainApp
->pushStatus(WiresharkApplication::TemporaryStatus
, err
);
3306 setDisplayFilter(field_filter
, action
, filter_type
);
3309 void WiresharkMainWindow::applyFieldAsColumn()
3311 if (capture_file_
.capFile() != 0 && capture_file_
.capFile()->finfo_selected
!= 0) {
3312 const header_field_info
*hfinfo
= capture_file_
.capFile()->finfo_selected
->hfinfo
;
3313 int col
= column_prefs_has_custom(hfinfo
->abbrev
);
3315 insertColumn(hfinfo
->name
, hfinfo
->abbrev
);
3318 if (QString(hfinfo
->name
) == get_column_title(col
)) {
3319 status
= tr("The \"%1\" column already exists.").arg(hfinfo
->name
);
3321 status
= tr("The \"%1\" column already exists as \"%2\".").arg(hfinfo
->name
).arg(get_column_title(col
));
3323 mainApp
->pushStatus(WiresharkApplication::TemporaryStatus
, status
);
3325 if (!get_column_visible(col
)) {
3326 packet_list_
->setColumnHidden(col
, false);
3327 set_column_visible(col
, true);
3334 void WiresharkMainWindow::applyConversationFilter()
3336 ConversationAction
*conv_action
= qobject_cast
<ConversationAction
*>(sender());
3337 if (!conv_action
) return;
3339 packet_info
*pinfo
= capture_file_
.packetInfo();
3342 QByteArray conv_filter
= conv_action
->filter();
3343 if (conv_filter
.isEmpty()) return;
3345 if (conv_action
->isFilterValid(pinfo
)) {
3347 df_combo_box_
->lineEdit()->setText(conv_filter
);
3348 df_combo_box_
->applyDisplayFilter();
3352 void WiresharkMainWindow::applyExportObject()
3354 ExportObjectAction
*export_action
= qobject_cast
<ExportObjectAction
*>(sender());
3358 ExportObjectDialog
* export_dialog
= new ExportObjectDialog(*this, capture_file_
, export_action
->exportObject());
3359 export_dialog
->setWindowModality(Qt::ApplicationModal
);
3360 export_dialog
->setAttribute(Qt::WA_DeleteOnClose
);
3361 export_dialog
->show();
3364 void WiresharkMainWindow::openFollowStreamDialog(int proto_id
, unsigned stream_num
, unsigned sub_stream_num
, bool use_stream_index
) {
3365 FollowStreamDialog
*fsd
= new FollowStreamDialog(*this, capture_file_
, proto_id
);
3366 connect(fsd
, &FollowStreamDialog::updateFilter
, this, &WiresharkMainWindow::filterPackets
);
3367 connect(fsd
, &FollowStreamDialog::goToPacket
, this, [=](int packet_num
) {packet_list_
->goToPacket(packet_num
);});
3368 fsd
->addCodecs(text_codec_map_
);
3370 if (use_stream_index
) {
3371 // If a specific conversation was requested, then ignore any previous
3372 // display filters and display all related packets.
3373 fsd
->follow("", true, stream_num
, sub_stream_num
);
3375 fsd
->follow(getFilter());
3379 void WiresharkMainWindow::openFollowStreamDialog(int proto_id
) {
3380 openFollowStreamDialog(proto_id
, 0, 0, false);
3383 void WiresharkMainWindow::openSCTPAllAssocsDialog()
3385 SCTPAllAssocsDialog
*sctp_dialog
= new SCTPAllAssocsDialog(this, capture_file_
.capFile());
3386 connect(sctp_dialog
, &SCTPAllAssocsDialog::filterPackets
, this, &WiresharkMainWindow::filterPackets
);
3387 connect(this, &WiresharkMainWindow::setCaptureFile
, sctp_dialog
, &SCTPAllAssocsDialog::setCaptureFile
);
3388 sctp_dialog
->fillTable();
3390 if (sctp_dialog
->isMinimized() == true)
3392 sctp_dialog
->showNormal();
3396 sctp_dialog
->show();
3399 sctp_dialog
->raise();
3400 sctp_dialog
->activateWindow();
3403 void WiresharkMainWindow::on_actionSCTPShowAllAssociations_triggered()
3405 openSCTPAllAssocsDialog();
3408 void WiresharkMainWindow::on_actionSCTPAnalyseThisAssociation_triggered()
3410 const sctp_assoc_info_t
* assoc
= SCTPAssocAnalyseDialog::findAssocForPacket(capture_file_
.capFile());
3414 SCTPAssocAnalyseDialog
*sctp_analyse
= new SCTPAssocAnalyseDialog(this, assoc
, capture_file_
.capFile());
3415 connect(sctp_analyse
, &SCTPAssocAnalyseDialog::filterPackets
, this, &WiresharkMainWindow::filterPackets
);
3417 if (sctp_analyse
->isMinimized() == true)
3419 sctp_analyse
->showNormal();
3423 sctp_analyse
->show();
3426 sctp_analyse
->raise();
3427 sctp_analyse
->activateWindow();
3430 void WiresharkMainWindow::on_actionSCTPFilterThisAssociation_triggered()
3432 const sctp_assoc_info_t
* assoc
= SCTPAssocAnalyseDialog::findAssocForPacket(capture_file_
.capFile());
3434 QString newFilter
= QStringLiteral("sctp.assoc_index==%1").arg(assoc
->assoc_id
);
3436 emit
filterPackets(newFilter
, false);
3441 void WiresharkMainWindow::statCommandWlanStatistics(const char *arg
, void *)
3443 WlanStatisticsDialog
*wlan_stats_dlg
= new WlanStatisticsDialog(*this, capture_file_
, arg
);
3444 wlan_stats_dlg
->show();
3445 connect(wlan_stats_dlg
, &WlanStatisticsDialog::filterAction
, this, &WiresharkMainWindow::filterAction
);
3449 void WiresharkMainWindow::statCommandExpertInfo(const char *, void *)
3451 const DisplayFilterEdit
*df_edit
= dynamic_cast<DisplayFilterEdit
*>(df_combo_box_
->lineEdit());
3452 ExpertInfoDialog
*expert_dialog
= new ExpertInfoDialog(*this, capture_file_
, df_edit
->text());
3454 connect(expert_dialog
->getExpertInfoView(), &ExpertInfoTreeView::goToPacket
,
3455 this, [=](int packet_num
) {packet_list_
->goToPacket(packet_num
);});
3456 connect(expert_dialog
, &ExpertInfoDialog::filterAction
, this, &WiresharkMainWindow::filterAction
);
3458 expert_dialog
->show();
3462 // Next / previous / first / last slots in packet_list
3466 void WiresharkMainWindow::connectStatisticsMenuActions()
3468 connect(main_ui_
->actionStatisticsCaptureFileProperties
, &QAction::triggered
, this, [=]() {
3469 CaptureFilePropertiesDialog
*capture_file_properties_dialog
= new CaptureFilePropertiesDialog(*this, capture_file_
);
3470 connect(capture_file_properties_dialog
, &CaptureFilePropertiesDialog::captureCommentChanged
,
3471 this, &WiresharkMainWindow::updateForUnsavedChanges
);
3472 capture_file_properties_dialog
->show();
3475 connect(main_ui_
->actionStatisticsResolvedAddresses
, &QAction::triggered
, this, &WiresharkMainWindow::showResolvedAddressesDialog
);
3477 connect(main_ui_
->actionStatisticsProtocolHierarchy
, &QAction::triggered
, this, [=]() {
3478 ProtocolHierarchyDialog
*phd
= new ProtocolHierarchyDialog(*this, capture_file_
);
3479 connect(phd
, &ProtocolHierarchyDialog::filterAction
, this, &WiresharkMainWindow::filterAction
);
3483 connect(main_ui_
->actionStatisticsConversations
, &QAction::triggered
, this, &WiresharkMainWindow::showConversationsDialog
);
3484 connect(main_ui_
->actionStatisticsEndpoints
, &QAction::triggered
, this, &WiresharkMainWindow::showEndpointsDialog
);
3486 connect(main_ui_
->actionStatisticsPacketLengths
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("plen"); });
3488 connect(main_ui_
->actionStatisticsIOGraph
, &QAction::triggered
, this, [=]() { statCommandIOGraph(NULL
, NULL
); });
3490 connect(main_ui_
->actionStatisticsFlowGraph
, &QAction::triggered
, this, [=]() {
3491 SequenceDialog
*sequence_dialog
= new SequenceDialog(*this, capture_file_
);
3492 sequence_dialog
->show();
3495 connect(main_ui_
->actionStatisticsCollectd
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("collectd"); });
3496 connect(main_ui_
->actionStatisticsDNS
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("dns"); });
3497 connect(main_ui_
->actionStatisticsDNS_QR
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("dns_qr"); });
3498 connect(main_ui_
->actionStatisticsHART_IP
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("hart_ip"); });
3499 connect(main_ui_
->actionStatisticsHpfeeds
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("hpfeeds"); });
3500 connect(main_ui_
->actionStatisticsHTTP2
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("http2"); });
3501 connect(main_ui_
->actionStatisticsUdpMulticastStreams
, &QAction::triggered
, this, [=]() { statCommandMulticastStatistics(NULL
, NULL
); });
3503 connect(main_ui_
->actionStatistics29WestTopics_Advertisements_by_Topic
, &QAction::triggered
, this, [=]() {
3504 openStatisticsTreeDialog("lbmr_topic_ads_topic");
3507 connect(main_ui_
->actionStatistics29WestTopics_Advertisements_by_Source
, &QAction::triggered
, this, [=]() {
3508 openStatisticsTreeDialog("lbmr_topic_ads_source");
3511 connect(main_ui_
->actionStatistics29WestTopics_Advertisements_by_Transport
, &QAction::triggered
, this, [=]() {
3512 openStatisticsTreeDialog("lbmr_topic_ads_transport");
3515 connect(main_ui_
->actionStatistics29WestTopics_Queries_by_Topic
, &QAction::triggered
, this, [=]() {
3516 openStatisticsTreeDialog("lbmr_topic_queries_topic");
3519 connect(main_ui_
->actionStatistics29WestTopics_Queries_by_Receiver
, &QAction::triggered
, this, [=]() {
3520 openStatisticsTreeDialog("lbmr_topic_queries_receiver");
3523 connect(main_ui_
->actionStatistics29WestTopics_Wildcard_Queries_by_Pattern
, &QAction::triggered
, this, [=]() {
3524 openStatisticsTreeDialog("lbmr_topic_queries_pattern");
3527 connect(main_ui_
->actionStatistics29WestTopics_Wildcard_Queries_by_Receiver
, &QAction::triggered
, this, [=]() {
3528 openStatisticsTreeDialog("lbmr_topic_queries_pattern_receiver");
3531 connect(main_ui_
->actionStatistics29WestQueues_Advertisements_by_Queue
, &QAction::triggered
, this, [=]() {
3532 openStatisticsTreeDialog("lbmr_queue_ads_queue");
3535 connect(main_ui_
->actionStatistics29WestQueues_Advertisements_by_Source
, &QAction::triggered
, this, [=]() {
3536 openStatisticsTreeDialog("lbmr_queue_ads_source");
3539 connect(main_ui_
->actionStatistics29WestQueues_Queries_by_Queue
, &QAction::triggered
, this, [=]() {
3540 openStatisticsTreeDialog("lbmr_queue_queries_queue");
3543 connect(main_ui_
->actionStatistics29WestQueues_Queries_by_Receiver
, &QAction::triggered
, this, [=]() {
3544 openStatisticsTreeDialog("lbmr_queue_queries_receiver");
3547 connect(main_ui_
->actionStatistics29WestUIM_Streams
, &QAction::triggered
, this, [=]() {
3548 LBMStreamDialog
*stream_dialog
= new LBMStreamDialog(this, capture_file_
.capFile());
3549 // connect(stream_dialog, &LBMStreamDialog::goToPacket, packet_list_, &PacketList::goToPacket);
3550 connect(this, &WiresharkMainWindow::setCaptureFile
, stream_dialog
, &LBMStreamDialog::setCaptureFile
);
3551 stream_dialog
->show();
3554 connect(main_ui_
->actionStatistics29WestLBTRM
, &QAction::triggered
, this, [=]() {
3555 LBMLBTRMTransportDialog
* lbtrm_dialog
= new LBMLBTRMTransportDialog(this, capture_file_
.capFile());
3556 connect(lbtrm_dialog
, &LBMLBTRMTransportDialog::goToPacket
, this, [=](int packet_num
) {packet_list_
->goToPacket(packet_num
);});
3557 connect(this, &WiresharkMainWindow::setCaptureFile
, lbtrm_dialog
, &LBMLBTRMTransportDialog::setCaptureFile
);
3558 lbtrm_dialog
->show();
3561 connect(main_ui_
->actionStatistics29WestLBTRU
, &QAction::triggered
, this, [=]() {
3562 LBMLBTRUTransportDialog
* lbtru_dialog
= new LBMLBTRUTransportDialog(this, capture_file_
.capFile());
3563 connect(lbtru_dialog
, &LBMLBTRUTransportDialog::goToPacket
, this, [=](int packet_num
) {packet_list_
->goToPacket(packet_num
);});
3564 connect(this, &WiresharkMainWindow::setCaptureFile
, lbtru_dialog
, &LBMLBTRUTransportDialog::setCaptureFile
);
3565 lbtru_dialog
->show();
3568 connect(main_ui_
->actionStatisticsTcpStreamStevens
, &QAction::triggered
, this, [=]() { openTcpStreamDialog(GRAPH_TSEQ_STEVENS
); });
3569 connect(main_ui_
->actionStatisticsTcpStreamTcptrace
, &QAction::triggered
, this, [=]() { openTcpStreamDialog(GRAPH_TSEQ_TCPTRACE
); });
3570 connect(main_ui_
->actionStatisticsTcpStreamThroughput
, &QAction::triggered
, this, [=]() { openTcpStreamDialog(GRAPH_THROUGHPUT
); });
3571 connect(main_ui_
->actionStatisticsTcpStreamRoundTripTime
, &QAction::triggered
, this, [=]() { openTcpStreamDialog(GRAPH_RTT
); });
3572 connect(main_ui_
->actionStatisticsTcpStreamWindowScaling
, &QAction::triggered
, this, [=]() { openTcpStreamDialog(GRAPH_WSCALE
); });
3574 connect(main_ui_
->actionStatisticsANCP
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("ancp"); });
3576 connect(main_ui_
->actionStatisticsBACappInstanceId
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("bacapp_instanceid"); });
3577 connect(main_ui_
->actionStatisticsBACappIP
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("bacapp_ip"); });
3578 connect(main_ui_
->actionStatisticsBACappObjectId
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("bacapp_objectid"); });
3579 connect(main_ui_
->actionStatisticsBACappService
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("bacapp_service"); });
3581 connect(main_ui_
->actionStatisticsHTTPPacketCounter
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("http"); });
3582 connect(main_ui_
->actionStatisticsHTTPRequests
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("http_req"); });
3583 connect(main_ui_
->actionStatisticsHTTPLoadDistribution
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("http_srv"); });
3584 connect(main_ui_
->actionStatisticsHTTPRequestSequences
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("http_seq"); });
3586 connect(main_ui_
->actionStatisticsSametime
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("sametime"); });
3588 connect(main_ui_
->actionStatisticsSOMEIPmessages
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("someip_messages"); });
3589 connect(main_ui_
->actionStatisticsSOMEIPSDentries
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("someipsd_entries"); });
3591 connect(main_ui_
->actionStatisticsLTP
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("ltp"); });
3594 void WiresharkMainWindow::openTcpStreamDialog(int graph_type
)
3596 TCPStreamDialog
*stream_dialog
= new TCPStreamDialog(this, capture_file_
.capFile(), (tcp_graph_type
)graph_type
);
3597 connect(stream_dialog
, &TCPStreamDialog::goToPacket
, this, [=](int packet_num
) {packet_list_
->goToPacket(packet_num
);});
3598 connect(this, &WiresharkMainWindow::setCaptureFile
, stream_dialog
, &TCPStreamDialog::setCaptureFile
);
3599 if (stream_dialog
->result() == QDialog::Accepted
) {
3600 stream_dialog
->show();
3605 void WiresharkMainWindow::statCommandMulticastStatistics(const char *arg
, void *)
3607 MulticastStatisticsDialog
*mcast_stats_dlg
= new MulticastStatisticsDialog(*this, capture_file_
, arg
);
3608 connect(mcast_stats_dlg
, &MulticastStatisticsDialog::filterAction
, this, &WiresharkMainWindow::filterAction
);
3609 mcast_stats_dlg
->show();
3612 void WiresharkMainWindow::openStatisticsTreeDialog(const char *abbr
)
3614 StatsTreeDialog
*st_dialog
= new StatsTreeDialog(*this, capture_file_
, abbr
);
3615 // connect(st_dialog, &StatsTreeDialog::goToPacket, packet_list_, &PacketList::goToPacket);
3620 void WiresharkMainWindow::statCommandIOGraph(const char *, void *)
3622 showIOGraphDialog(IOG_ITEM_UNIT_PACKETS
, QString());
3625 void WiresharkMainWindow::showIOGraphDialog(io_graph_item_unit_t value_units
, QString yfield
)
3627 const DisplayFilterEdit
*df_edit
= qobject_cast
<DisplayFilterEdit
*>(df_combo_box_
->lineEdit());
3628 IOGraphDialog
*iog_dialog
= nullptr;
3629 QString displayFilter
;
3631 displayFilter
= df_edit
->text();
3633 if (!yfield
.isEmpty()) {
3634 QList
<IOGraphDialog
*> iographdialogs
= findChildren
<IOGraphDialog
*>();
3635 // GeometryStateDialogs aren't parented on Linux and Windows
3636 // (see geometry_state_dialog.h), so we search for an
3637 // I/O Dialog in all the top level widgets.
3638 if (iographdialogs
.isEmpty()) {
3639 foreach(QWidget
*topLevelWidget
, mainApp
->topLevelWidgets()) {
3640 if (qobject_cast
<IOGraphDialog
*>(topLevelWidget
)) {
3641 iographdialogs
<< qobject_cast
<IOGraphDialog
*>(topLevelWidget
);
3645 bool iog_found
= false;
3646 foreach(iog_dialog
, iographdialogs
) {
3647 if (!iog_dialog
->fileClosed()) {
3649 iog_dialog
->addGraph(true, false, displayFilter
, value_units
, yfield
);
3654 iog_dialog
= nullptr;
3658 if (iog_dialog
== nullptr) {
3659 iog_dialog
= new IOGraphDialog(*this, capture_file_
, displayFilter
, value_units
, yfield
);
3660 connect(iog_dialog
, &IOGraphDialog::goToPacket
, this, [=](int packet_num
) {packet_list_
->goToPacket(packet_num
);});
3661 connect(this, &WiresharkMainWindow::reloadFields
, iog_dialog
, &IOGraphDialog::reloadFields
);
3663 if (iog_dialog
->isMinimized()) {
3664 iog_dialog
->showNormal();
3668 iog_dialog
->raise();
3669 iog_dialog
->activateWindow();
3674 void WiresharkMainWindow::connectTelephonyMenuActions()
3676 connect(main_ui_
->actionTelephonyVoipCalls
, &QAction::triggered
, this, [=]() {
3677 VoipCallsDialog
*dialog
= VoipCallsDialog::openVoipCallsDialogVoip(*this, capture_file_
, packet_list_
);
3681 connect(main_ui_
->actionTelephonyIax2StreamAnalysis
, &QAction::triggered
, this, [=]() {
3682 Iax2AnalysisDialog
*iax2_analysis_dialog
= new Iax2AnalysisDialog(*this, capture_file_
);
3683 connect(iax2_analysis_dialog
, &Iax2AnalysisDialog::goToPacket
, this, [=](int packet
) { packet_list_
->goToPacket(packet
); });
3684 iax2_analysis_dialog
->show();
3687 connect(main_ui_
->actionTelephonyISUPMessages
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("isup_msg"); });
3689 connect(main_ui_
->actionTelephonyGsmMapSummary
, &QAction::triggered
, this, [=]() {
3690 GsmMapSummaryDialog
*gms_dialog
= new GsmMapSummaryDialog(*this, capture_file_
);
3694 connect(main_ui_
->actionTelephonyLteMacStatistics
, &QAction::triggered
, this, [=]() { statCommandLteMacStatistics(NULL
, NULL
); });
3695 connect(main_ui_
->actionTelephonyLteRlcGraph
, &QAction::triggered
, this, [=]() {
3696 // We don't yet know the channel.
3697 launchRLCGraph(false, RLC_RAT_LTE
, 0, 0, 0, 0, 0);
3699 connect(main_ui_
->actionTelephonyLteRlcStatistics
, &QAction::triggered
, this, [=]() { statCommandLteRlcStatistics(NULL
, NULL
); });
3701 connect(main_ui_
->actionTelephonyMtp3Summary
, &QAction::triggered
, this, [=]() {
3702 Mtp3SummaryDialog
*mtp3s_dialog
= new Mtp3SummaryDialog(*this, capture_file_
);
3703 mtp3s_dialog
->show();
3706 connect(main_ui_
->actionTelephonyOsmuxPacketCounter
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("osmux"); });
3708 connect(main_ui_
->actionTelephonyRtpStreams
, &QAction::triggered
, this, &WiresharkMainWindow::openTelephonyRtpStreamsDialog
);
3709 connect(main_ui_
->actionTelephonyRtpStreamAnalysis
, &QAction::triggered
, this, &WiresharkMainWindow::openRtpStreamAnalysisDialog
);
3710 connect(main_ui_
->actionTelephonyRtpPlayer
, &QAction::triggered
, this, &WiresharkMainWindow::openRtpPlayerDialog
);
3712 connect(main_ui_
->actionTelephonyRTSPPacketCounter
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("rtsp"); });
3714 connect(main_ui_
->actionTelephonySMPPOperations
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("smpp_commands"); });
3716 connect(main_ui_
->actionTelephonyUCPMessages
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("ucp_messages"); });
3718 connect(main_ui_
->actionTelephonyF1APMessages
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("f1ap"); });
3720 connect(main_ui_
->actionTelephonyNGAPMessages
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("ngap"); });
3722 connect(main_ui_
->actionTelephonyE2APMessages
, &QAction::triggered
, this, [=]() { openStatisticsTreeDialog("e2ap"); });
3724 connect(main_ui_
->actionTelephonySipFlows
, &QAction::triggered
, this, [=]() {
3725 VoipCallsDialog
*dialog
= VoipCallsDialog::openVoipCallsDialogSip(*this, capture_file_
, packet_list_
);
3730 RtpPlayerDialog
*WiresharkMainWindow::openTelephonyRtpPlayerDialog()
3732 RtpPlayerDialog
*dialog
;
3735 dialog
= RtpPlayerDialog::openRtpPlayerDialog(*this, capture_file_
, packet_list_
, captureSession()->state
!= CAPTURE_STOPPED
);
3737 dialog
= RtpPlayerDialog::openRtpPlayerDialog(*this, capture_file_
, packet_list_
, false);
3745 RtpAnalysisDialog
*WiresharkMainWindow::openTelephonyRtpAnalysisDialog()
3747 RtpAnalysisDialog
*dialog
;
3749 dialog
= RtpAnalysisDialog::openRtpAnalysisDialog(*this, capture_file_
, packet_list_
);
3756 void WiresharkMainWindow::statCommandLteMacStatistics(const char *arg
, void *)
3758 LteMacStatisticsDialog
*lte_mac_stats_dlg
= new LteMacStatisticsDialog(*this, capture_file_
, arg
);
3759 connect(lte_mac_stats_dlg
, &LteMacStatisticsDialog::filterAction
, this, &WiresharkMainWindow::filterAction
);
3760 lte_mac_stats_dlg
->show();
3763 void WiresharkMainWindow::statCommandLteRlcStatistics(const char *arg
, void *)
3765 LteRlcStatisticsDialog
*lte_rlc_stats_dlg
= new LteRlcStatisticsDialog(*this, capture_file_
, arg
);
3766 connect(lte_rlc_stats_dlg
, &LteRlcStatisticsDialog::filterAction
, this, &WiresharkMainWindow::filterAction
);
3767 // N.B. It is necessary for the RLC Statistics window to launch the RLC graph in this way, to ensure
3768 // that the goToPacket() signal/slot connection gets set up...
3769 connect(lte_rlc_stats_dlg
, &LteRlcStatisticsDialog::launchRLCGraph
, this, &WiresharkMainWindow::launchRLCGraph
);
3771 lte_rlc_stats_dlg
->show();
3774 void WiresharkMainWindow::launchRLCGraph(bool channelKnown
,
3775 uint8_t RAT
, uint16_t ueid
, uint8_t rlcMode
,
3776 uint16_t channelType
, uint16_t channelId
, uint8_t direction
)
3778 LteRlcGraphDialog
*lrg_dialog
= new LteRlcGraphDialog(*this, capture_file_
, channelKnown
);
3779 connect(lrg_dialog
, &LteRlcGraphDialog::goToPacket
, this, [=](int packet_num
) {packet_list_
->goToPacket(packet_num
);});
3780 // This is a bit messy, but wanted to hide these parameters from users of
3781 // on_actionTelephonyLteRlcGraph_triggered().
3783 lrg_dialog
->setChannelInfo(RAT
, ueid
, rlcMode
, channelType
, channelId
, direction
);
3788 RtpStreamDialog
*WiresharkMainWindow::openTelephonyRtpStreamsDialog()
3790 RtpStreamDialog
*dialog
= RtpStreamDialog::openRtpStreamDialog(*this, capture_file_
, packet_list_
);
3796 void WiresharkMainWindow::openRtpStreamAnalysisDialog()
3798 QVector
<rtpstream_id_t
*> stream_ids
;
3801 if (QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier
)) {
3802 err
= findRtpStreams(&stream_ids
, true);
3804 err
= findRtpStreams(&stream_ids
, false);
3806 if (!err
.isNull()) {
3807 QMessageBox::warning(this, tr("RTP packet search failed"),
3811 openTelephonyRtpAnalysisDialog()->addRtpStreams(stream_ids
);
3813 foreach(rtpstream_id_t
*id
, stream_ids
) {
3814 rtpstream_id_free(id
);
3819 void WiresharkMainWindow::openRtpPlayerDialog()
3821 QVector
<rtpstream_id_t
*> stream_ids
;
3824 if (QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier
)) {
3825 err
= findRtpStreams(&stream_ids
, true);
3827 err
= findRtpStreams(&stream_ids
, false);
3829 if (!err
.isNull()) {
3830 QMessageBox::warning(this, tr("RTP packet search failed"),
3833 #ifdef QT_MULTIMEDIA_LIB
3835 openTelephonyRtpPlayerDialog()->addRtpStreams(stream_ids
);
3836 #endif // QT_MULTIMEDIA_LIB
3838 foreach(rtpstream_id_t
*id
, stream_ids
) {
3839 rtpstream_id_free(id
);
3846 void WiresharkMainWindow::connectWirelessMenuActions()
3848 connect(main_ui_
->actionBluetoothATT_Server_Attributes
, &QAction::triggered
, this, [=]() {
3849 BluetoothAttServerAttributesDialog
*bluetooth_att_sever_attributes_dialog
= new BluetoothAttServerAttributesDialog(*this, capture_file_
);
3850 connect(bluetooth_att_sever_attributes_dialog
, &BluetoothAttServerAttributesDialog::goToPacket
,
3851 this, [=](int packet_num
) {packet_list_
->goToPacket(packet_num
);});
3852 connect(bluetooth_att_sever_attributes_dialog
, &BluetoothAttServerAttributesDialog::updateFilter
,
3853 this, &WiresharkMainWindow::filterPackets
);
3854 bluetooth_att_sever_attributes_dialog
->show();
3857 connect(main_ui_
->actionBluetoothDevices
, &QAction::triggered
, this, [=]() {
3858 BluetoothDevicesDialog
*bluetooth_devices_dialog
= new BluetoothDevicesDialog(*this, capture_file_
, packet_list_
);
3859 connect(bluetooth_devices_dialog
, &BluetoothDevicesDialog::goToPacket
, this, [=](int packet_num
) {packet_list_
->goToPacket(packet_num
);});
3860 connect(bluetooth_devices_dialog
, &BluetoothDevicesDialog::updateFilter
,
3861 this, &WiresharkMainWindow::filterPackets
);
3862 bluetooth_devices_dialog
->show();
3865 connect(main_ui_
->actionBluetoothHCI_Summary
, &QAction::triggered
, this, [=]() {
3866 BluetoothHciSummaryDialog
*bluetooth_hci_summary_dialog
= new BluetoothHciSummaryDialog(*this, capture_file_
);
3867 connect(bluetooth_hci_summary_dialog
, &BluetoothHciSummaryDialog::goToPacket
,
3868 this, [=](int packet_num
) {packet_list_
->goToPacket(packet_num
);});
3869 connect(bluetooth_hci_summary_dialog
, &BluetoothHciSummaryDialog::updateFilter
,
3870 this, &WiresharkMainWindow::filterPackets
);
3871 bluetooth_hci_summary_dialog
->show();
3874 connect(main_ui_
->actionWirelessWlanStatistics
, &QAction::triggered
, this, [=]() { statCommandWlanStatistics(NULL
, NULL
); });
3879 void WiresharkMainWindow::connectToolsMenuActions()
3881 connect(main_ui_
->actionToolsFirewallAclRules
, &QAction::triggered
, this, [=]() {
3882 FirewallRulesDialog
*firewall_rules_dialog
= new FirewallRulesDialog(*this, capture_file_
);
3883 firewall_rules_dialog
->show();
3886 connect(main_ui_
->actionToolsCredentials
, &QAction::triggered
, this, [=]() {
3887 CredentialsDialog
*credentials_dialog
= new CredentialsDialog(*this, capture_file_
, packet_list_
);
3888 credentials_dialog
->show();
3891 connect(main_ui_
->actionToolsMacLookup
, &QAction::triggered
, this, [=]() {
3892 ManufDialog
*manuf_dialog
= new ManufDialog(*this, capture_file_
);
3893 manuf_dialog
->show();
3896 connect(main_ui_
->actionToolsTLSKeylog
, &QAction::triggered
, this, &WiresharkMainWindow::openTLSKeylogDialog
);
3900 void WiresharkMainWindow::connectHelpMenuActions()
3903 connect(main_ui_
->actionHelpAbout
, &QAction::triggered
, this, [=]() {
3904 AboutDialog
*about_dialog
= new AboutDialog(this);
3906 if (about_dialog
->isMinimized() == true)
3908 about_dialog
->showNormal();
3912 about_dialog
->show();
3915 about_dialog
->raise();
3916 about_dialog
->activateWindow();
3919 connect(main_ui_
->actionHelpContents
, &QAction::triggered
, this, [=]() { mainApp
->helpTopicAction(HELP_CONTENT
); });
3920 connect(main_ui_
->actionHelpMPWireshark
, &QAction::triggered
, this, [=]() { mainApp
->helpTopicAction(LOCALPAGE_MAN_WIRESHARK
); });
3921 connect(main_ui_
->actionHelpMPWireshark_Filter
, &QAction::triggered
, this, [=]() { mainApp
->helpTopicAction(LOCALPAGE_MAN_WIRESHARK_FILTER
); });
3922 connect(main_ui_
->actionHelpMPWireshark_FilterReference
, &QAction::triggered
, this, [=]() { mainApp
->helpTopicAction(ONLINEPAGE_DFILTER_REF
); });
3923 connect(main_ui_
->actionHelpMPCapinfos
, &QAction::triggered
, this, [=]() { mainApp
->helpTopicAction(LOCALPAGE_MAN_CAPINFOS
); });
3924 connect(main_ui_
->actionHelpMPDumpcap
, &QAction::triggered
, this, [=]() { mainApp
->helpTopicAction(LOCALPAGE_MAN_DUMPCAP
); });
3925 connect(main_ui_
->actionHelpMPEditcap
, &QAction::triggered
, this, [=]() { mainApp
->helpTopicAction(LOCALPAGE_MAN_EDITCAP
); });
3926 connect(main_ui_
->actionHelpMPMergecap
, &QAction::triggered
, this, [=]() { mainApp
->helpTopicAction(LOCALPAGE_MAN_MERGECAP
); });
3927 connect(main_ui_
->actionHelpMPRawshark
, &QAction::triggered
, this, [=]() { mainApp
->helpTopicAction(LOCALPAGE_MAN_RAWSHARK
); });
3928 connect(main_ui_
->actionHelpMPReordercap
, &QAction::triggered
, this, [=]() { mainApp
->helpTopicAction(LOCALPAGE_MAN_REORDERCAP
); });
3929 connect(main_ui_
->actionHelpMPText2pcap
, &QAction::triggered
, this, [=]() { mainApp
->helpTopicAction(LOCALPAGE_MAN_TEXT2PCAP
); });
3930 connect(main_ui_
->actionHelpMPTShark
, &QAction::triggered
, this, [=]() { mainApp
->helpTopicAction(LOCALPAGE_MAN_TSHARK
); });
3931 connect(main_ui_
->actionHelpWebsite
, &QAction::triggered
, this, [=]() { mainApp
->helpTopicAction(ONLINEPAGE_HOME
); });
3932 connect(main_ui_
->actionHelpFAQ
, &QAction::triggered
, this, [=]() { mainApp
->helpTopicAction(ONLINEPAGE_FAQ
); });
3933 connect(main_ui_
->actionHelpAsk
, &QAction::triggered
, this, [=]() { mainApp
->helpTopicAction(ONLINEPAGE_ASK
); });
3934 connect(main_ui_
->actionHelpDownloads
, &QAction::triggered
, this, [=]() { mainApp
->helpTopicAction(ONLINEPAGE_DOWNLOAD
); });
3935 connect(main_ui_
->actionHelpWiki
, &QAction::triggered
, this, [=]() { mainApp
->helpTopicAction(ONLINEPAGE_WIKI
); });
3936 connect(main_ui_
->actionHelpSampleCaptures
, &QAction::triggered
, this, [=]() { mainApp
->helpTopicAction(ONLINEPAGE_SAMPLE_FILES
); });
3937 connect(main_ui_
->actionHelpReleaseNotes
, &QAction::triggered
, this, [=]() { mainApp
->helpTopicAction(LOCALPAGE_RELEASE_NOTES
); });
3940 #ifdef HAVE_SOFTWARE_UPDATE
3941 void WiresharkMainWindow::checkForUpdates()
3943 software_update_check();
3947 void WiresharkMainWindow::setPreviousFocus() {
3948 previous_focus_
= mainApp
->focusWidget();
3949 if (previous_focus_
!= nullptr) {
3950 connect(previous_focus_
, &QWidget::destroyed
, this, &WiresharkMainWindow::resetPreviousFocus
);
3954 void WiresharkMainWindow::resetPreviousFocus() {
3955 previous_focus_
= nullptr;
3958 void WiresharkMainWindow::goToCancelClicked()
3960 main_ui_
->goToFrame
->animatedHide();
3961 if (previous_focus_
) {
3962 disconnect(previous_focus_
, &QWidget::destroyed
, this, &WiresharkMainWindow::resetPreviousFocus
);
3963 previous_focus_
->setFocus();
3964 resetPreviousFocus();
3968 void WiresharkMainWindow::goToGoClicked()
3970 gotoFrame(main_ui_
->goToLineEdit
->text().toInt());
3972 goToCancelClicked();
3975 void WiresharkMainWindow::goToLineEditReturnPressed()
3980 void WiresharkMainWindow::showResolvedAddressesDialog()
3982 QString capFileName
;
3983 wtap
* wth
= Q_NULLPTR
;
3984 if (capture_file_
.isValid())
3986 capFileName
= capture_file_
.capFile()->filename
;
3987 wth
= capture_file_
.capFile()->provider
.wth
;
3989 ResolvedAddressesDialog
*resolved_addresses_dialog
=
3990 new ResolvedAddressesDialog(this, capFileName
, wth
);
3991 resolved_addresses_dialog
->show();
3994 void WiresharkMainWindow::showConversationsDialog()
3996 ConversationDialog
*conv_dialog
= new ConversationDialog(*this, capture_file_
);
3997 connect(conv_dialog
, &ConversationDialog::filterAction
, this, &WiresharkMainWindow::filterAction
);
3998 connect(conv_dialog
, &ConversationDialog::openFollowStreamDialog
, this,
3999 [=](int proto_id
, unsigned stream_num
, unsigned sub_stream_num
) {
4000 openFollowStreamDialog(proto_id
, stream_num
, sub_stream_num
);
4002 connect(conv_dialog
, &ConversationDialog::openTcpStreamGraph
, this, &WiresharkMainWindow::openTcpStreamDialog
);
4003 conv_dialog
->show();
4006 void WiresharkMainWindow::showEndpointsDialog()
4008 EndpointDialog
*endp_dialog
= new EndpointDialog(*this, capture_file_
);
4009 connect(endp_dialog
, &EndpointDialog::filterAction
, this, &WiresharkMainWindow::filterAction
);
4010 connect(endp_dialog
, &EndpointDialog::openFollowStreamDialog
, this,
4011 [=](int proto_id
) {openFollowStreamDialog(proto_id
);
4013 connect(endp_dialog
, &EndpointDialog::openTcpStreamGraph
, this, &WiresharkMainWindow::openTcpStreamDialog
);
4014 endp_dialog
->show();
4017 void WiresharkMainWindow::externalMenuItemTriggered()
4019 QAction
* triggerAction
= NULL
;
4021 ext_menubar_t
* entry
= NULL
;
4023 if (QObject::sender()) {
4024 triggerAction
= (QAction
*)QObject::sender();
4025 v
= triggerAction
->data();
4027 if (v
.canConvert
<void *>()) {
4028 entry
= (ext_menubar_t
*)v
.value
<void *>();
4030 if (entry
->type
== EXT_MENUBAR_ITEM
) {
4031 entry
->callback(EXT_MENUBAR_QT_GUI
, (void *)((void *)main_ui_
), entry
->user_data
);
4033 QDesktopServices::openUrl(QUrl(QString((char *)entry
->user_data
)));
4039 void WiresharkMainWindow::extcap_options_finished(int result
)
4041 if (result
== QDialog::Accepted
) {
4042 QString
before_what(tr(" before starting a new capture"));
4043 if (testCaptureFileClose(before_what
)) {
4044 startCapture(QStringList());
4047 this->welcome_page_
->getInterfaceFrame()->interfaceListChanged();
4050 void WiresharkMainWindow::showExtcapOptionsDialog(QString
&device_name
, bool startCaptureOnClose
)
4052 ExtcapOptionsDialog
* extcap_options_dialog
= ExtcapOptionsDialog::createForDevice(device_name
, startCaptureOnClose
, this);
4053 /* The dialog returns null, if the given device name is not a valid extcap device */
4054 if (extcap_options_dialog
) {
4055 extcap_options_dialog
->setModal(true);
4056 extcap_options_dialog
->setAttribute(Qt::WA_DeleteOnClose
);
4057 connect(extcap_options_dialog
, &ExtcapOptionsDialog::finished
, this, &WiresharkMainWindow::extcap_options_finished
);
4059 if (capture_options_dialog_
) {
4060 /* Allow capture options dialog to close */
4061 connect(extcap_options_dialog
, &ExtcapOptionsDialog::accepted
, capture_options_dialog_
, &CaptureOptionsDialog::accept
);
4064 extcap_options_dialog
->show();
4068 void WiresharkMainWindow::on_actionContextWikiProtocolPage_triggered()
4070 QAction
*wa
= qobject_cast
<QAction
*>(sender());
4074 int field_id
= wa
->data().toInt(&ok
);
4077 const QString proto_abbrev
= proto_registrar_get_abbrev(field_id
);
4079 int ret
= QMessageBox::question(this, mainApp
->windowTitleString(tr("Wiki Page for %1").arg(proto_abbrev
)),
4080 tr("<p>The Wireshark Wiki is maintained by the community.</p>"
4081 "<p>The page you are about to load might be wonderful, "
4082 "incomplete, wrong, or nonexistent.</p>"
4083 "<p>Proceed to the wiki?</p>"),
4084 QMessageBox::Yes
| QMessageBox::No
, QMessageBox::Yes
);
4086 if (ret
!= QMessageBox::Yes
) return;
4088 QUrl wiki_url
= QString(WS_WIKI_URL("Protocols/%1")).arg(proto_abbrev
);
4089 QDesktopServices::openUrl(wiki_url
);
4092 void WiresharkMainWindow::on_actionContextFilterFieldReference_triggered()
4094 QAction
*wa
= qobject_cast
<QAction
*>(sender());
4098 int field_id
= wa
->data().toInt(&ok
);
4101 const QString proto_abbrev
= proto_registrar_get_abbrev(field_id
);
4103 QUrl dfref_url
= QString(WS_DOCS_URL
"/dfref/%1/%2")
4104 .arg(proto_abbrev
[0])
4106 QDesktopServices::openUrl(dfref_url
);
4109 void WiresharkMainWindow::activatePluginIFToolbar(bool)
4111 QAction
*sendingAction
= dynamic_cast<QAction
*>(sender());
4112 if (!sendingAction
|| !sendingAction
->data().isValid())
4115 ext_toolbar_t
*toolbar
= VariantPointer
<ext_toolbar_t
>::asPtr(sendingAction
->data());
4117 QList
<QToolBar
*> toolbars
= findChildren
<QToolBar
*>();
4118 foreach(QToolBar
*bar
, toolbars
) {
4119 AdditionalToolBar
*iftoolbar
= dynamic_cast<AdditionalToolBar
*>(bar
);
4120 if (iftoolbar
&& iftoolbar
->menuName().compare(toolbar
->name
) == 0) {
4121 if (iftoolbar
->isVisible()) {
4122 iftoolbar
->setVisible(false);
4123 sendingAction
->setChecked(true);
4125 iftoolbar
->setVisible(true);
4126 sendingAction
->setChecked(true);
4132 void WiresharkMainWindow::rtpPlayerDialogReplaceRtpStreams(QVector
<rtpstream_id_t
*> stream_ids _U_
)
4134 #ifdef QT_MULTIMEDIA_LIB
4135 openTelephonyRtpPlayerDialog()->replaceRtpStreams(stream_ids
);
4139 void WiresharkMainWindow::rtpPlayerDialogAddRtpStreams(QVector
<rtpstream_id_t
*> stream_ids _U_
)
4141 #ifdef QT_MULTIMEDIA_LIB
4142 openTelephonyRtpPlayerDialog()->addRtpStreams(stream_ids
);
4146 void WiresharkMainWindow::rtpPlayerDialogRemoveRtpStreams(QVector
<rtpstream_id_t
*> stream_ids _U_
)
4148 #ifdef QT_MULTIMEDIA_LIB
4149 openTelephonyRtpPlayerDialog()->removeRtpStreams(stream_ids
);
4153 void WiresharkMainWindow::rtpAnalysisDialogReplaceRtpStreams(QVector
<rtpstream_id_t
*> stream_ids
)
4155 openTelephonyRtpAnalysisDialog()->replaceRtpStreams(stream_ids
);
4158 void WiresharkMainWindow::rtpAnalysisDialogAddRtpStreams(QVector
<rtpstream_id_t
*> stream_ids
)
4160 openTelephonyRtpAnalysisDialog()->addRtpStreams(stream_ids
);
4163 void WiresharkMainWindow::rtpAnalysisDialogRemoveRtpStreams(QVector
<rtpstream_id_t
*> stream_ids
)
4165 openTelephonyRtpAnalysisDialog()->removeRtpStreams(stream_ids
);
4168 void WiresharkMainWindow::rtpStreamsDialogSelectRtpStreams(QVector
<rtpstream_id_t
*> stream_ids
)
4170 openTelephonyRtpStreamsDialog()->selectRtpStream(stream_ids
);
4173 void WiresharkMainWindow::rtpStreamsDialogDeselectRtpStreams(QVector
<rtpstream_id_t
*> stream_ids
)
4175 openTelephonyRtpStreamsDialog()->deselectRtpStream(stream_ids
);
4179 #pragma warning(pop)