1 /* main_window_slots.cpp
2 *
3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9
10 #include <config.h>
11
12 // Qt 5.5.0 + Visual C++ 2013
13 #ifdef _MSC_VER
14 #pragma warning(push)
15 #pragma warning(disable:4996)
16 #endif
17
18 #include "main_window.h"
19
20 /*
21 * The generated Ui_MainWindow::setupUi() can grow larger than our configured limit,
22 * so turn off -Wframe-larger-than= for ui_main_window.h.
23 */
24 DIAG_OFF(frame-larger-than=)
25 #include <ui_main_window.h>
26 DIAG_ON(frame-larger-than=)
27
28 #ifdef _WIN32
29 #include <windows.h>
30 #endif
31
32 #include "ui/dissect_opts.h"
33
34 #ifdef HAVE_LIBPCAP
35 #include "ui/capture.h"
36 #endif
37
38 #include "ui/commandline.h"
39
40 #include "ui/urls.h"
41
42 #include "epan/color_filters.h"
43 #include "epan/export_object.h"
44
45 #include "wsutil/file_util.h"
46 #include "wsutil/filesystem.h"
47 #include <wsutil/wslog.h>
48 #include <wsutil/ws_assert.h>
49
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"
58 #include "epan/uat.h"
59 #include "epan/uat-int.h"
60 #include "epan/value_string.h"
61
62 #ifdef HAVE_LUA
63 #include <epan/wslua/init_wslua.h>
64 #endif
65
66 #include "ui/alert_box.h"
67 #ifdef HAVE_LIBPCAP
68 #include "ui/capture_ui_utils.h"
69 #endif
70
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"
81
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"
85
86 #ifdef HAVE_SOFTWARE_UPDATE
87 #include "ui/software_update.h"
88 #endif
89
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"
96 #ifdef HAVE_LIBPCAP
97 #include "capture_options_dialog.h"
98 #endif
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 "funnel_statistics.h"
120 #include "gsm_map_summary_dialog.h"
121 #include "iax2_analysis_dialog.h"
122 #include "interface_toolbar.h"
123 #include "io_graph_dialog.h"
124 #include <ui/qt/widgets/additional_toolbar.h>
125 #include "lbm_stream_dialog.h"
126 #include "lbm_lbtrm_transport_dialog.h"
127 #include "lbm_lbtru_transport_dialog.h"
128 #include "lte_mac_statistics_dialog.h"
129 #include "lte_rlc_statistics_dialog.h"
130 #include "lte_rlc_graph_dialog.h"
131 #include "mtp3_summary_dialog.h"
132 #include "multicast_statistics_dialog.h"
133 #include "packet_comment_dialog.h"
134 #include "packet_diagram.h"
135 #include "packet_dialog.h"
136 #include "packet_list.h"
137 #include "credentials_dialog.h"
138 #include "preferences_dialog.h"
139 #include "print_dialog.h"
140 #include "profile_dialog.h"
141 #include "protocol_hierarchy_dialog.h"
142 #include <ui/qt/utils/qt_ui_utils.h>
143 #include "resolved_addresses_dialog.h"
144 #include "rpc_service_response_time_dialog.h"
145 #include "rtp_stream_dialog.h"
146 #include "rtp_analysis_dialog.h"
147 #include "sctp_all_assocs_dialog.h"
148 #include "sctp_assoc_analyse_dialog.h"
149 #include "sctp_graph_dialog.h"
150 #include "sequence_dialog.h"
151 #include "show_packet_bytes_dialog.h"
152 #include "stats_tree_dialog.h"
153 #include <ui/qt/utils/stock_icon.h>
154 #include "supported_protocols_dialog.h"
155 #include "tap_parameter_dialog.h"
156 #include "tcp_stream_dialog.h"
157 #include "time_shift_dialog.h"
158 #include "uat_dialog.h"
159 #include "voip_calls_dialog.h"
160 #include "wireshark_application.h"
161 #include "wlan_statistics_dialog.h"
162 #include <ui/qt/widgets/wireless_timeline.h>
163
164 #include <functional>
165 #include <QClipboard>
166 #include <QFileInfo>
167 #include <QMessageBox>
168 #include <QMetaObject>
169 #include <QToolBar>
170 #include <QDesktopServices>
171 #include <QUrl>
172 #include <QMutex>
173
174 // XXX You must uncomment QT_WINEXTRAS_LIB lines in CMakeList.txt and
175 // cmakeconfig.h.in.
176 // #if defined(QT_WINEXTRAS_LIB)
177 // #include <QWinJumpList>
178 // #include <QWinJumpListCategory>
179 // #include <QWinJumpListItem>
180 // #endif
181
182 //
183 // Public slots
184 //
185
openCaptureFile(QString cf_path,QString read_filter,unsigned int type,gboolean is_tempfile)186 bool MainWindow::openCaptureFile(QString cf_path, QString read_filter, unsigned int type, gboolean is_tempfile)
187 {
188 QString file_name = "";
189 dfilter_t *rfcode = NULL;
190 gchar *err_msg;
191 int err;
192 gboolean name_param;
193 gboolean ret = true;
194
195 // was a file name given as function parameter?
196 name_param = !cf_path.isEmpty();
197
198 for (;;) {
199
200 if (cf_path.isEmpty()) {
201 CaptureFileDialog open_dlg(this, capture_file_.capFile(), read_filter);
202
203 if (open_dlg.open(file_name, type)) {
204 cf_path = file_name;
205 } else {
206 ret = false;
207 goto finish;
208 }
209 } else {
210 this->welcome_page_->getInterfaceFrame()->showRunOnFile();
211 }
212
213 // TODO detect call from "cf_read" -> "update_progress_dlg"
214 // ("capture_file_.capFile()->read_lock"), possibly queue opening the
215 // file and return early to avoid the warning in testCaptureFileClose.
216
217 QString before_what(tr(" before opening another file"));
218 if (!testCaptureFileClose(before_what)) {
219 ret = false;
220 goto finish;
221 }
222
223 if (dfilter_compile(qUtf8Printable(read_filter), &rfcode, &err_msg)) {
224 cf_set_rfcode(CaptureFile::globalCapFile(), rfcode);
225 } else {
226 /* Not valid. Tell the user, and go back and run the file
227 selection box again once they dismiss the alert. */
228 //bad_dfilter_alert_box(top_level, read_filter->str);
229 QMessageBox::warning(this, tr("Invalid Display Filter"),
230 QString("The filter expression ") +
231 read_filter +
232 QString(" isn't a valid display filter. (") +
233 err_msg + QString(")."),
234 QMessageBox::Ok);
235
236 if (!name_param) {
237 // go back to the selection dialogue only if the file
238 // was selected from this dialogue
239 cf_path.clear();
240 continue;
241 }
242 }
243
244 /* Make the file name available via MainWindow */
245 setMwFileName(cf_path);
246
247 /* Try to open the capture file. This closes the current file if it succeeds. */
248 CaptureFile::globalCapFile()->window = this;
249 if (cf_open(CaptureFile::globalCapFile(), qUtf8Printable(cf_path), type, is_tempfile, &err) != CF_OK) {
250 /* We couldn't open it; don't dismiss the open dialog box,
251 just leave it around so that the user can, after they
252 dismiss the alert box popped up for the open error,
253 try again. */
254 CaptureFile::globalCapFile()->window = NULL;
255 dfilter_free(rfcode);
256 cf_path.clear();
257 continue;
258 }
259
260 switch (cf_read(CaptureFile::globalCapFile(), FALSE)) {
261 case CF_READ_OK:
262 case CF_READ_ERROR:
263 /* Just because we got an error, that doesn't mean we were unable
264 to read any of the file; we handle what we could get from the
265 file. */
266 break;
267
268 case CF_READ_ABORTED:
269 /* The user bailed out of re-reading the capture file; the
270 capture file has been closed - just free the capture file name
271 string and return (without changing the last containing
272 directory). */
273 capture_file_.setCapFile(NULL);
274 ret = false;
275 goto finish;
276 }
277 break;
278 }
279
280 wsApp->setLastOpenDirFromFilename(cf_path);
281
282 main_ui_->statusBar->showExpert();
283
284 finish:
285 #ifdef HAVE_LIBPCAP
286 if (global_commandline_info.quit_after_cap)
287 exit(0);
288 #endif
289 return ret;
290 }
291
filterPackets(QString new_filter,bool force)292 void MainWindow::filterPackets(QString new_filter, bool force)
293 {
294 cf_status_t cf_status;
295
296 cf_status = cf_filter_packets(CaptureFile::globalCapFile(), new_filter.toUtf8().data(), force);
297
298 if (cf_status == CF_OK) {
299 emit displayFilterSuccess(true);
300 if (new_filter.length() > 0) {
301 int index = df_combo_box_->findText(new_filter);
302 if (index == -1) {
303 df_combo_box_->insertItem(0, new_filter);
304 df_combo_box_->setCurrentIndex(0);
305 } else {
306 df_combo_box_->setCurrentIndex(index);
307 }
308 } else {
309 df_combo_box_->lineEdit()->clear();
310 }
311 } else {
312 emit displayFilterSuccess(false);
313 }
314 if (packet_list_) {
315 packet_list_->resetColumns();
316 }
317 }
318
layoutToolbars()319 void MainWindow::layoutToolbars()
320 {
321 Qt::ToolButtonStyle tbstyle = Qt::ToolButtonIconOnly;
322 switch (prefs.gui_toolbar_main_style) {
323 case TB_STYLE_TEXT:
324 tbstyle = Qt::ToolButtonTextOnly;
325 break;
326 case TB_STYLE_BOTH:
327 tbstyle = Qt::ToolButtonTextUnderIcon;
328 break;
329 }
330
331 main_ui_->mainToolBar->setToolButtonStyle(tbstyle);
332
333 main_ui_->mainToolBar->setVisible(recent.main_toolbar_show);
334 main_ui_->displayFilterToolBar->setVisible(recent.filter_toolbar_show);
335 #if defined(HAVE_LIBNL) && defined(HAVE_NL80211)
336 main_ui_->wirelessToolBar->setVisible(recent.wireless_toolbar_show);
337 #endif
338 main_ui_->statusBar->setVisible(recent.statusbar_show);
339
340 foreach(QAction *action, main_ui_->menuInterfaceToolbars->actions()) {
341 QToolBar *toolbar = action->data().value<QToolBar *>();
342 if (g_list_find_custom(recent.interface_toolbars, action->text().toUtf8(), (GCompareFunc)strcmp)) {
343 toolbar->setVisible(true);
344 } else {
345 toolbar->setVisible(false);
346 }
347 }
348
349 QList<QToolBar *> toolbars = findChildren<QToolBar *>();
350 foreach(QToolBar *bar, toolbars) {
351 AdditionalToolBar *iftoolbar = dynamic_cast<AdditionalToolBar *>(bar);
352 if (iftoolbar) {
353 bool visible = false;
354 if (g_list_find_custom(recent.gui_additional_toolbars, qUtf8Printable(iftoolbar->menuName()), (GCompareFunc)strcmp))
355 visible = true;
356
357 iftoolbar->setVisible(visible);
358
359 }
360 }
361 }
362
updatePreferenceActions()363 void MainWindow::updatePreferenceActions()
364 {
365 main_ui_->actionViewPacketList->setEnabled(prefs_has_layout_pane_content(layout_pane_content_plist));
366 main_ui_->actionViewPacketDetails->setEnabled(prefs_has_layout_pane_content(layout_pane_content_pdetails));
367 main_ui_->actionViewPacketBytes->setEnabled(prefs_has_layout_pane_content(layout_pane_content_pbytes));
368 main_ui_->actionViewPacketDiagram->setEnabled(prefs_has_layout_pane_content(layout_pane_content_pdiagram));
369
370 main_ui_->actionViewNameResolutionPhysical->setChecked(gbl_resolv_flags.mac_name);
371 main_ui_->actionViewNameResolutionNetwork->setChecked(gbl_resolv_flags.network_name);
372 main_ui_->actionViewNameResolutionTransport->setChecked(gbl_resolv_flags.transport_name);
373
374 // Should this be a "recent" setting?
375 main_ui_->actionGoAutoScroll->setChecked(prefs.capture_auto_scroll);
376 }
377
updateRecentActions()378 void MainWindow::updateRecentActions()
379 {
380 main_ui_->actionViewMainToolbar->setChecked(recent.main_toolbar_show);
381 main_ui_->actionViewFilterToolbar->setChecked(recent.filter_toolbar_show);
382 main_ui_->actionViewWirelessToolbar->setChecked(recent.wireless_toolbar_show);
383 main_ui_->actionViewStatusBar->setChecked(recent.statusbar_show);
384 main_ui_->actionViewPacketList->setChecked(recent.packet_list_show && prefs_has_layout_pane_content(layout_pane_content_plist));
385 main_ui_->actionViewPacketDetails->setChecked(recent.tree_view_show && prefs_has_layout_pane_content(layout_pane_content_pdetails));
386 main_ui_->actionViewPacketBytes->setChecked(recent.byte_view_show && prefs_has_layout_pane_content(layout_pane_content_pbytes));
387 main_ui_->actionViewPacketDiagram->setChecked(recent.packet_diagram_show && prefs_has_layout_pane_content(layout_pane_content_pdiagram));
388
389 foreach(QAction *action, main_ui_->menuInterfaceToolbars->actions()) {
390 if (g_list_find_custom(recent.interface_toolbars, action->text().toUtf8(), (GCompareFunc)strcmp)) {
391 action->setChecked(true);
392 } else {
393 action->setChecked(false);
394 }
395 }
396
397 foreach(QAction * action, main_ui_->menuAdditionalToolbars->actions()) {
398 ext_toolbar_t * toolbar = VariantPointer<ext_toolbar_t>::asPtr(action->data());
399 bool checked = false;
400 if (toolbar && g_list_find_custom(recent.gui_additional_toolbars, toolbar->name, (GCompareFunc)strcmp))
401 checked = true;
402
403 action->setChecked(checked);
404 }
405
406 foreach(QAction* tda, td_actions.keys()) {
407 if (recent.gui_time_format == td_actions[tda]) {
408 tda->setChecked(true);
409 }
410 }
411 foreach(QAction* tpa, tp_actions.keys()) {
412 if (recent.gui_time_precision == tp_actions[tpa]) {
413 tpa->setChecked(true);
414 break;
415 }
416 }
417 main_ui_->actionViewTimeDisplaySecondsWithHoursAndMinutes->setChecked(recent.gui_seconds_format == TS_SECONDS_HOUR_MIN_SEC);
418
419 main_ui_->actionViewColorizePacketList->setChecked(recent.packet_list_colorize);
420 }
421
422 // Don't connect to this directly. Connect to or emit fiterAction(...) instead.
queuedFilterAction(QString action_filter,FilterAction::Action action,FilterAction::ActionType type)423 void MainWindow::queuedFilterAction(QString action_filter, FilterAction::Action action, FilterAction::ActionType type)
424 {
425 QString cur_filter, new_filter;
426
427 if (!df_combo_box_) return;
428 cur_filter = df_combo_box_->lineEdit()->text();
429
430 switch (type) {
431 case FilterAction::ActionTypePlain:
432 new_filter = action_filter;
433 break;
434 case FilterAction::ActionTypeAnd:
435 if (cur_filter.length()) {
436 new_filter = "(" + cur_filter + ") && (" + action_filter + ")";
437 }
438 else {
439 new_filter = action_filter;
440 }
441 break;
442 case FilterAction::ActionTypeOr:
443 if (cur_filter.length()) {
444 new_filter = "(" + cur_filter + ") || (" + action_filter + ")";
445 } else {
446 new_filter = action_filter;
447 }
448 break;
449 case FilterAction::ActionTypeNot:
450 new_filter = "!(" + action_filter + ")";
451 break;
452 case FilterAction::ActionTypeAndNot:
453 if (cur_filter.length()) {
454 new_filter = "(" + cur_filter + ") && !(" + action_filter + ")";
455 } else {
456 new_filter = "!(" + action_filter + ")";
457 }
458 break;
459 case FilterAction::ActionTypeOrNot:
460 if (cur_filter.length()) {
461 new_filter = "(" + cur_filter + ") || !(" + action_filter + ")";
462 } else {
463 new_filter = "!(" + action_filter + ")";
464 }
465 break;
466 default:
467 ws_assert_not_reached();
468 break;
469 }
470
471 switch (action) {
472 case FilterAction::ActionApply:
473 df_combo_box_->lineEdit()->setText(new_filter);
474 df_combo_box_->applyDisplayFilter();
475 break;
476 case FilterAction::ActionColorize:
477 colorizeWithFilter(new_filter.toUtf8());
478 break;
479 case FilterAction::ActionCopy:
480 wsApp->clipboard()->setText(new_filter);
481 break;
482 case FilterAction::ActionFind:
483 main_ui_->searchFrame->findFrameWithFilter(new_filter);
484 break;
485 case FilterAction::ActionPrepare:
486 df_combo_box_->lineEdit()->setText(new_filter);
487 df_combo_box_->lineEdit()->setFocus();
488 break;
489 case FilterAction::ActionWebLookup:
490 {
491 QString url = QString("https://www.google.com/search?q=") + new_filter;
492 QDesktopServices::openUrl(QUrl(url));
493 break;
494 }
495 default:
496 ws_assert_not_reached();
497 break;
498 }
499 }
500
501 // Capture callbacks
502
503 #ifdef HAVE_LIBPCAP
captureCapturePrepared(capture_session * session)504 void MainWindow::captureCapturePrepared(capture_session *session) {
505 setTitlebarForCaptureInProgress();
506
507 setWindowIcon(wsApp->captureIcon());
508
509 /* Disable menu items that make no sense if you're currently running
510 a capture. */
511 bool handle_toolbars = (session->session_will_restart ? false : true);
512 setForCaptureInProgress(true, handle_toolbars, session->capture_opts->ifaces);
513 // set_capture_if_dialog_for_capture_in_progress(TRUE);
514
515 // /* Don't set up main window for a capture file. */
516 // main_set_for_capture_file(FALSE);
517 showCapture();
518 }
519
captureCaptureUpdateStarted(capture_session * session)520 void MainWindow::captureCaptureUpdateStarted(capture_session *session) {
521
522 /* We've done this in "prepared" above, but it will be cleared while
523 switching to the next multiple file. */
524 setTitlebarForCaptureInProgress();
525
526 bool handle_toolbars = (session->session_will_restart ? false : true);
527 setForCaptureInProgress(true, handle_toolbars, session->capture_opts->ifaces);
528
529 setForCapturedPackets(true);
530 }
531
captureCaptureUpdateFinished(capture_session * session)532 void MainWindow::captureCaptureUpdateFinished(capture_session *session) {
533
534 /* The capture isn't stopping any more - it's stopped. */
535 capture_stopping_ = false;
536
537 /* Update the main window as appropriate */
538 updateForUnsavedChanges();
539
540 /* Enable menu items that make sense if you're not currently running
541 a capture. */
542 bool handle_toolbars = (session->session_will_restart ? false : true);
543 setForCaptureInProgress(false, handle_toolbars);
544 setMenusForCaptureFile();
545
546 setWindowIcon(wsApp->normalIcon());
547
548 if (global_commandline_info.quit_after_cap) {
549 // Command line asked us to quit after capturing.
550 // Don't pop up a dialog to ask for unsaved files etc.
551 exit(0);
552 }
553 }
554
captureCaptureFixedFinished(capture_session *)555 void MainWindow::captureCaptureFixedFinished(capture_session *) {
556
557 /* The capture isn't stopping any more - it's stopped. */
558 capture_stopping_ = false;
559
560 /* Enable menu items that make sense if you're not currently running
561 a capture. */
562 setForCaptureInProgress(false);
563 /* There isn't a real capture_file structure yet, so just force disabling
564 menu options. They will "refresh" when the capture file is reloaded to
565 display packets */
566 setMenusForCaptureFile(true);
567
568 setWindowIcon(wsApp->normalIcon());
569
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.
573 exit(0);
574 }
575 }
576
captureCaptureFailed(capture_session *)577 void MainWindow::captureCaptureFailed(capture_session *) {
578 /* Capture isn't stopping any more. */
579 capture_stopping_ = false;
580
581 setForCaptureInProgress(false);
582 showWelcome();
583
584 // Reset expert information indicator
585 main_ui_->statusBar->captureFileClosing();
586 wsApp->popStatus(WiresharkApplication::FileStatus);
587
588 setWindowIcon(wsApp->normalIcon());
589
590 if (global_commandline_info.quit_after_cap) {
591 // Command line asked us to quit after capturing.
592 // Don't pop up a dialog to ask for unsaved files etc.
593 exit(0);
594 }
595 }
596 #endif // HAVE_LIBPCAP
597
598 // Callbacks from cfile.c and file.c via CaptureFile::captureFileCallback
599
captureEventHandler(CaptureEvent ev)600 void MainWindow::captureEventHandler(CaptureEvent ev)
601 {
602 switch (ev.captureContext()) {
603
604 case CaptureEvent::File:
605 switch (ev.eventType()) {
606 case CaptureEvent::Opened:
607 captureFileOpened();
608 break;
609 case CaptureEvent::Closing:
610 captureFileClosing();
611 break;
612 case CaptureEvent::Closed:
613 captureFileClosed();
614 break;
615 case CaptureEvent::Started:
616 captureFileReadStarted(tr("Loading"));
617 break;
618 case CaptureEvent::Finished:
619 captureFileReadFinished();
620 break;
621 default:
622 break;
623 }
624 break;
625
626 case CaptureEvent::Reload:
627 switch (ev.eventType()) {
628 case CaptureEvent::Started:
629 captureFileReadStarted(tr("Reloading"));
630 break;
631 case CaptureEvent::Finished:
632 captureFileReadFinished();
633 break;
634 default:
635 break;
636 }
637 break;
638
639 case CaptureEvent::Rescan:
640 switch (ev.eventType()) {
641 case CaptureEvent::Started:
642 setMenusForCaptureFile(true);
643 captureFileReadStarted(tr("Rescanning"));
644 break;
645 case CaptureEvent::Finished:
646 captureFileReadFinished();
647 break;
648 default:
649 break;
650 }
651 break;
652
653 case CaptureEvent::Retap:
654 switch (ev.eventType()) {
655 case CaptureEvent::Started:
656 freeze();
657 break;
658 case CaptureEvent::Finished:
659 thaw();
660 break;
661 case CaptureEvent::Flushed:
662 draw_tap_listeners(FALSE);
663 break;
664 default:
665 break;
666 }
667 break;
668
669 case CaptureEvent::Merge:
670 switch (ev.eventType()) {
671 case CaptureEvent::Started:
672 wsApp->popStatus(WiresharkApplication::FileStatus);
673 wsApp->pushStatus(WiresharkApplication::FileStatus, tr("Merging files."), QString());
674 break;
675 case CaptureEvent::Finished:
676 wsApp->popStatus(WiresharkApplication::FileStatus);
677 break;
678 default:
679 break;
680 }
681 break;
682
683 case CaptureEvent::Save:
684 switch (ev.eventType()) {
685 case CaptureEvent::Started:
686 {
687 QFileInfo file_info(ev.filePath());
688 wsApp->popStatus(WiresharkApplication::FileStatus);
689 wsApp->pushStatus(WiresharkApplication::FileStatus, tr("Saving %1…").arg(file_info.fileName()));
690 break;
691 }
692 default:
693 break;
694 }
695 break;
696
697 #ifdef HAVE_LIBPCAP
698 case CaptureEvent::Capture:
699 switch (ev.eventType()) {
700 case CaptureEvent::Prepared:
701 captureCapturePrepared(ev.capSession());
702 break;
703 case CaptureEvent::Stopping:
704 capture_stopping_ = true;
705 setMenusForCaptureStopping();
706 break;
707 case CaptureEvent::Failed:
708 captureCaptureFailed(ev.capSession());
709 default:
710 break;
711 }
712 break;
713
714 case CaptureEvent::Update:
715 switch (ev.eventType()) {
716 case CaptureEvent::Started:
717 captureCaptureUpdateStarted(ev.capSession());
718 break;
719 case CaptureEvent::Finished:
720 captureCaptureUpdateFinished(ev.capSession());
721 break;
722 default:
723 break;
724 }
725 break;
726
727 case CaptureEvent::Fixed:
728 switch (ev.eventType()) {
729 case CaptureEvent::Finished:
730 captureCaptureFixedFinished(ev.capSession());
731 break;
732 default:
733 break;
734 }
735 break;
736 #endif
737 }
738 }
739
captureFileOpened()740 void MainWindow::captureFileOpened() {
741 if (capture_file_.window() != this) return;
742
743 file_set_dialog_->fileOpened(capture_file_.capFile());
744 setMenusForFileSet(true);
745 emit setCaptureFile(capture_file_.capFile());
746 }
747
captureFileReadStarted(const QString & action)748 void MainWindow::captureFileReadStarted(const QString &action) {
749 // tap_param_dlg_update();
750
751 /* Set up main window for a capture file. */
752 // main_set_for_capture_file(TRUE);
753
754 wsApp->popStatus(WiresharkApplication::FileStatus);
755 QString msg = QString(tr("%1: %2")).arg(action).arg(capture_file_.fileName());
756 QString msgtip = QString();
757 wsApp->pushStatus(WiresharkApplication::FileStatus, msg, msgtip);
758 showCapture();
759 main_ui_->actionAnalyzeReloadLuaPlugins->setEnabled(false);
760 main_ui_->wirelessTimelineWidget->captureFileReadStarted(capture_file_.capFile());
761 }
762
captureFileReadFinished()763 void MainWindow::captureFileReadFinished() {
764 if (!capture_file_.capFile()->is_tempfile && capture_file_.capFile()->filename) {
765 /* Add this filename to the list of recent files in the "Recent Files" submenu */
766 add_menu_recent_capture_file(capture_file_.capFile()->filename);
767
768 /* Remember folder for next Open dialog and save it in recent */
769 wsApp->setLastOpenDirFromFilename(capture_file_.capFile()->filename);
770 }
771
772 /* Update the appropriate parts of the main window. */
773 updateForUnsavedChanges();
774
775 /* enable wireless timeline if capture allows it */
776 main_ui_->wirelessTimelineWidget->captureFileReadFinished();
777
778 /* Enable menu items that make sense if you have some captured packets. */
779 setForCapturedPackets(true);
780
781 main_ui_->statusBar->setFileName(capture_file_);
782 main_ui_->actionAnalyzeReloadLuaPlugins->setEnabled(true);
783
784 packet_list_->captureFileReadFinished();
785
786 emit setDissectedCaptureFile(capture_file_.capFile());
787 }
788
captureFileClosing()789 void MainWindow::captureFileClosing() {
790 setMenusForCaptureFile(true);
791 setForCapturedPackets(false);
792 setForCaptureInProgress(false);
793
794 // Reset expert information indicator
795 main_ui_->statusBar->captureFileClosing();
796 main_ui_->searchFrame->animatedHide();
797 main_ui_->goToFrame->animatedHide();
798 // gtk_widget_show(expert_info_none);
799 emit setCaptureFile(NULL);
800 emit setDissectedCaptureFile(NULL);
801 }
802
captureFileClosed()803 void MainWindow::captureFileClosed() {
804 packets_bar_update();
805
806 file_set_dialog_->fileClosed();
807 setMenusForFileSet(false);
808 setWindowModified(false);
809
810 // Reset expert information indicator
811 main_ui_->statusBar->captureFileClosing();
812 wsApp->popStatus(WiresharkApplication::FileStatus);
813
814 setWSWindowTitle();
815 setWindowIcon(wsApp->normalIcon());
816 setMenusForSelectedPacket();
817 setMenusForSelectedTreeRow();
818
819 #ifdef HAVE_LIBPCAP
820 if (!global_capture_opts.multi_files_on)
821 showWelcome();
822 #endif
823 }
824
825 //
826 // Private slots
827 //
828
829 // ui/gtk/capture_dlg.c:start_capture_confirmed
830
startCapture()831 void MainWindow::startCapture() {
832 #ifdef HAVE_LIBPCAP
833 interface_options *interface_opts;
834 guint i;
835
836 /* did the user ever select a capture interface before? */
837 if (global_capture_opts.num_selected == 0) {
838 QString msg = QString(tr("No interface selected."));
839 wsApp->pushStatus(WiresharkApplication::TemporaryStatus, msg);
840 main_ui_->actionCaptureStart->setChecked(false);
841 return;
842 }
843
844 // Ideally we should have disabled the start capture
845 // toolbar buttons and menu items. This may not be the
846 // case, e.g. with QtMacExtras.
847 if (!capture_filter_valid_) {
848 QString msg = QString(tr("Invalid capture filter."));
849 wsApp->pushStatus(WiresharkApplication::TemporaryStatus, msg);
850 main_ui_->actionCaptureStart->setChecked(false);
851 return;
852 }
853
854 showCapture();
855
856 /* XXX - we might need to init other pref data as well... */
857
858 /* XXX - can this ever happen? */
859 if (cap_session_.state != CAPTURE_STOPPED)
860 return;
861
862 /* close the currently loaded capture file */
863 cf_close((capture_file *)cap_session_.cf);
864
865 /* Copy the selected interfaces to the set of interfaces to use for
866 this capture. */
867 collect_ifaces(&global_capture_opts);
868
869 CaptureFile::globalCapFile()->window = this;
870 info_data_.ui.ui = this;
871 if (capture_start(&global_capture_opts, NULL, &cap_session_, &info_data_,
872 main_window_update)) {
873 capture_options *capture_opts = cap_session_.capture_opts;
874 GString *interface_names;
875
876 /* Add "interface name<live capture in progress>" on main status bar */
877 interface_names = get_iface_list_string(capture_opts, 0);
878 if (strlen(interface_names->str) > 0) {
879 g_string_append(interface_names, ":");
880 }
881 g_string_append(interface_names, " ");
882
883 wsApp->popStatus(WiresharkApplication::FileStatus);
884 QString msg = QString("%1<live capture in progress>").arg(interface_names->str);
885 QString msgtip = QString("to file: ");
886 if (capture_opts->save_file)
887 msgtip += capture_opts->save_file;
888 wsApp->pushStatus(WiresharkApplication::FileStatus, msg, msgtip);
889 g_string_free(interface_names, TRUE);
890
891 /* The capture succeeded, which means the capture filter syntax is
892 valid; add this capture filter to the recent capture filter list. */
893 QByteArray filter_ba;
894 for (i = 0; i < global_capture_opts.ifaces->len; i++) {
895 interface_opts = &g_array_index(global_capture_opts.ifaces, interface_options, i);
896 if (interface_opts->cfilter) {
897 recent_add_cfilter(interface_opts->name, interface_opts->cfilter);
898 if (filter_ba.isEmpty()) {
899 filter_ba = interface_opts->cfilter;
900 } else {
901 /* Not the first selected interface; is its capture filter
902 the same as the one the other interfaces we've looked
903 at have? */
904 if (strcmp(interface_opts->cfilter, filter_ba.constData()) != 0) {
905 /* No, so not all selected interfaces have the same capture
906 filter. */
907 filter_ba.clear();
908 }
909 }
910 }
911 }
912 if (!filter_ba.isEmpty()) {
913 recent_add_cfilter(NULL, filter_ba.constData());
914 }
915 } else {
916 CaptureFile::globalCapFile()->window = NULL;
917 }
918 #endif // HAVE_LIBPCAP
919 }
920
921 // Copied from ui/gtk/gui_utils.c
pipeTimeout()922 void MainWindow::pipeTimeout() {
923 #ifdef _WIN32
924 HANDLE handle;
925 DWORD avail = 0;
926 gboolean result, result1;
927 DWORD childstatus;
928 gint iterations = 0;
929
930
931 /* try to read data from the pipe only 5 times, to avoid blocking */
932 while (iterations < 5) {
933 /* Oddly enough although Named pipes don't work on win9x,
934 PeekNamedPipe does !!! */
935 handle = (HANDLE)_get_osfhandle(pipe_source_);
936 result = PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL);
937
938 /* Get the child process exit status */
939 result1 = GetExitCodeProcess((HANDLE)*(pipe_child_process_),
940 &childstatus);
941
942 /* If the Peek returned an error, or there are bytes to be read
943 or the childwatcher thread has terminated then call the normal
944 callback */
945 if (!result || avail > 0 || childstatus != STILL_ACTIVE) {
946
947 /* And call the real handler */
948 if (!pipe_input_cb_(pipe_source_, pipe_user_data_)) {
949 ws_log(LOG_DOMAIN_MAIN, LOG_LEVEL_DEBUG, "pipe_timer_cb: input pipe closed, iterations: %u", iterations);
950 /* pipe closed, return false so that the old timer is not run again */
951 delete pipe_timer_;
952 return;
953 }
954 } else {
955 /* No data, stop now */
956 break;
957 }
958
959 iterations++;
960 }
961 #endif // _WIN32
962 }
963
pipeActivated(int source)964 void MainWindow::pipeActivated(int source) {
965 Q_UNUSED(source)
966
967 #ifndef _WIN32
968 ws_assert(source == pipe_source_);
969
970 pipe_notifier_->setEnabled(false);
971 if (pipe_input_cb_(pipe_source_, pipe_user_data_)) {
972 pipe_notifier_->setEnabled(true);
973 }
974 else {
975 delete pipe_notifier_;
976 }
977 #endif // _WIN32
978 }
979
pipeNotifierDestroyed()980 void MainWindow::pipeNotifierDestroyed()
981 {
982 /* Pop the "<live capture in progress>" message off the status bar. */
983 main_ui_->statusBar->setFileName(capture_file_);
984
985 #ifdef _WIN32
986 pipe_timer_ = NULL;
987 #else
988 pipe_notifier_ = NULL;
989 #endif // _WIN32
990 }
991
stopCapture()992 void MainWindow::stopCapture() {
993 //#ifdef HAVE_AIRPCAP
994 // if (airpcap_if_active)
995 // airpcap_set_toolbar_stop_capture(airpcap_if_active);
996 //#endif
997
998 #ifdef HAVE_LIBPCAP
999 capture_stop(&cap_session_);
1000 #endif // HAVE_LIBPCAP
1001
1002 }
1003
1004 // Keep focus rects from showing through the welcome screen. Primarily for
1005 // macOS.
mainStackChanged(int)1006 void MainWindow::mainStackChanged(int)
1007 {
1008 for (int i = 0; i < main_ui_->mainStack->count(); i++) {
1009 main_ui_->mainStack->widget(i)->setEnabled(i == main_ui_->mainStack->currentIndex());
1010 }
1011 }
1012
1013 // XXX - Copied from ui/gtk/menus.c
1014
1015 /**
1016 * Add the capture filename (with an absolute path) to the "Recent Files" menu.
1017 */
1018 // XXX - We should probably create a RecentFile class.
updateRecentCaptures()1019 void MainWindow::updateRecentCaptures() {
1020 QAction *ra;
1021 QMenu *recentMenu = main_ui_->menuOpenRecentCaptureFile;
1022 QString action_cf_name;
1023
1024 if (!recentMenu) {
1025 return;
1026 }
1027 recentMenu->clear();
1028
1029 #if 0
1030 #if defined(QT_WINEXTRAS_LIB)
1031 QWinJumpList recent_jl(this);
1032 QWinJumpListCategory *recent_jlc = recent_jl.recent();
1033 if (recent_jlc) {
1034 recent_jlc->clear();
1035 recent_jlc->setVisible(true);
1036 }
1037 #endif
1038 #endif
1039 #if defined(Q_OS_MAC)
1040 if (!dock_menu_) {
1041 dock_menu_ = new QMenu();
1042 dock_menu_->setAsDockMenu();
1043 }
1044 dock_menu_->clear();
1045 #endif
1046
1047 /* Iterate through the actions in menuOpenRecentCaptureFile,
1048 * removing special items, a maybe duplicate entry and every item above count_max */
1049 int shortcut = Qt::Key_0;
1050 foreach(recent_item_status *ri, wsApp->recentItems()) {
1051 // Add the new item
1052 ra = new QAction(recentMenu);
1053 ra->setData(ri->filename);
1054 // XXX - Needs get_recent_item_status or equivalent
1055 ra->setEnabled(ri->accessible);
1056 recentMenu->insertAction(NULL, ra);
1057 action_cf_name = ra->data().toString();
1058 if (shortcut <= Qt::Key_9) {
1059 ra->setShortcut(Qt::META | shortcut);
1060 shortcut++;
1061 }
1062 ra->setText(action_cf_name);
1063 connect(ra, SIGNAL(triggered()), this, SLOT(recentActionTriggered()));
1064
1065 /* This is slow, at least on my VM here. The added links also open Wireshark
1066 * in a new window. It might make more sense to add a recent item when we
1067 * open a capture file. */
1068 #if 0
1069 #if defined(QT_WINEXTRAS_LIB)
1070 if (recent_jlc) {
1071 QFileInfo fi(ri->filename);
1072 QWinJumpListItem *jli = recent_jlc->addLink(
1073 fi.fileName(),
1074 QApplication::applicationFilePath(),
1075 QStringList() << "-r" << ri->filename
1076 );
1077 // XXX set icon
1078 jli->setWorkingDirectory(QDir::toNativeSeparators(QApplication::applicationDirPath()));
1079 }
1080 #endif
1081 #endif
1082 #if defined(Q_OS_MAC)
1083 QAction *rda = new QAction(dock_menu_);
1084 QFileInfo fi(ri->filename);
1085 rda->setText(fi.fileName());
1086 dock_menu_->insertAction(NULL, rda);
1087 connect(rda, SIGNAL(triggered()), ra, SLOT(trigger()));
1088 #endif
1089 }
1090
1091 if (recentMenu->actions().count() > 0) {
1092 // Separator + "Clear"
1093 // XXX - Do we really need this?
1094 ra = new QAction(recentMenu);
1095 ra->setSeparator(true);
1096 recentMenu->insertAction(NULL, ra);
1097
1098 ra = new QAction(recentMenu);
1099 ra->setText(tr("Clear Menu"));
1100 recentMenu->insertAction(NULL, ra);
1101 connect(ra, SIGNAL(triggered()), wsApp, SLOT(clearRecentCaptures()));
1102 } else {
1103 if (main_ui_->actionDummyNoFilesFound) {
1104 recentMenu->addAction(main_ui_->actionDummyNoFilesFound);
1105 }
1106 }
1107 }
1108
recentActionTriggered()1109 void MainWindow::recentActionTriggered() {
1110 QAction *ra = qobject_cast<QAction*>(sender());
1111
1112 if (ra) {
1113 QString cfPath = ra->data().toString();
1114 openCaptureFile(cfPath);
1115 }
1116 }
1117
commentToMenuText(QString text,int max_len)1118 QString MainWindow::commentToMenuText(QString text, int max_len)
1119 {
1120 text = text.trimmed().replace(QRegExp("(\\r?\\n|\\r\\n?)+"), " ");
1121 if (text.size() > 0) {
1122 if (text.size() > max_len) {
1123 text.truncate(max_len);
1124 text += "…";
1125 }
1126 }
1127 else {
1128 text = tr("(empty comment)", "placeholder for empty comment");
1129 }
1130 return text;
1131 }
1132
setEditCommentsMenu()1133 void MainWindow::setEditCommentsMenu()
1134 {
1135 main_ui_->menuPacketComment->clear();
1136 main_ui_->menuPacketComment->addAction(tr("Add New Comment…"), this, SLOT(actionAddPacketComment()), QKeySequence(Qt::CTRL + Qt::ALT + Qt::Key_C));
1137 if (selectedRows().count() == 1) {
1138 const int thisRow = selectedRows().first();
1139 frame_data * current_frame = frameDataForRow(thisRow);
1140 wtap_block_t pkt_block = cf_get_packet_block(capture_file_.capFile(), current_frame);
1141 guint nComments = wtap_block_count_option(pkt_block, OPT_COMMENT);
1142 if (nComments > 0) {
1143 QAction *aPtr;
1144 main_ui_->menuPacketComment->addSeparator();
1145 for (guint i = 0; i < nComments; i++) {
1146 QString comment = packet_list_->getPacketComment(i);
1147 comment = this->commentToMenuText(comment);
1148 aPtr = main_ui_->menuPacketComment->addAction(tr("Edit \"%1\"", "edit packet comment").arg(comment),
1149 this, SLOT(actionEditPacketComment()));
1150 aPtr->setData(i);
1151 }
1152
1153 main_ui_->menuPacketComment->addSeparator();
1154 for (guint i = 0; i < nComments; i++) {
1155 QString comment = packet_list_->getPacketComment(i);
1156 comment = this->commentToMenuText(comment);
1157 aPtr = main_ui_->menuPacketComment->addAction(tr("Delete \"%1\"", "delete packet comment").arg(comment),
1158 this, SLOT(actionDeletePacketComment()));
1159 aPtr->setData(i);
1160 }
1161 main_ui_->menuPacketComment->addSeparator();
1162 main_ui_->menuPacketComment->addAction(tr("Delete packet comments"), this, SLOT(actionDeleteCommentsFromPackets()));
1163 }
1164 wtap_block_unref(pkt_block);
1165 }
1166 if (selectedRows().count() > 1) {
1167 main_ui_->menuPacketComment->addSeparator();
1168 main_ui_->menuPacketComment->addAction(tr("Delete comments from %n packet(s)", nullptr, selectedRows().count()), this, SLOT(actionDeleteCommentsFromPackets()));
1169 }
1170 }
1171
setMenusForSelectedPacket()1172 void MainWindow::setMenusForSelectedPacket()
1173 {
1174 gboolean is_ip = FALSE, is_tcp = FALSE, is_udp = FALSE, is_dccp = FALSE, is_sctp = FALSE, is_tls = FALSE, is_rtp = FALSE, is_lte_rlc = FALSE,
1175 is_http = FALSE, is_http2 = FALSE, is_quic = FALSE, is_sip = FALSE, is_exported_pdu = FALSE;
1176
1177 /* Making the menu context-sensitive allows for easier selection of the
1178 desired item and has the added benefit, with large captures, of
1179 avoiding needless looping through huge lists for marked, ignored,
1180 or time-referenced packets. */
1181
1182 /* We have one or more items in the packet list */
1183 bool have_frames = false;
1184 /* A frame is selected */
1185 bool frame_selected = false;
1186 bool multi_selection = false;
1187 /* A visible packet comes after this one in the selection history */
1188 bool next_selection_history = false;
1189 /* A visible packet comes before this one in the selection history */
1190 bool previous_selection_history = false;
1191 /* We have marked frames. (XXX - why check frame_selected?) */
1192 bool have_marked = false;
1193 /* We have a marked frame other than the current frame (i.e.,
1194 we have at least one marked frame, and either there's more
1195 than one marked frame or the current frame isn't marked). */
1196 bool another_is_marked = false;
1197 /* One or more frames are hidden by a display filter */
1198 bool have_filtered = false;
1199 /* One or more frames have been ignored */
1200 bool have_ignored = false;
1201 bool have_time_ref = false;
1202 /* We have a time reference frame other than the current frame (i.e.,
1203 we have at least one time reference frame, and either there's more
1204 than one time reference frame or the current frame isn't a
1205 time reference frame). (XXX - why check frame_selected?) */
1206 bool another_is_time_ref = false;
1207
1208 QList<QAction *> cc_actions = QList<QAction *>()
1209 << main_ui_->actionViewColorizeConversation1 << main_ui_->actionViewColorizeConversation2
1210 << main_ui_->actionViewColorizeConversation3 << main_ui_->actionViewColorizeConversation4
1211 << main_ui_->actionViewColorizeConversation5 << main_ui_->actionViewColorizeConversation6
1212 << main_ui_->actionViewColorizeConversation7 << main_ui_->actionViewColorizeConversation8
1213 << main_ui_->actionViewColorizeConversation9 << main_ui_->actionViewColorizeConversation10;
1214
1215 if (capture_file_.capFile()) {
1216 QList<int> rows = selectedRows();
1217 frame_data * current_frame = 0;
1218 if (rows.count() > 0)
1219 current_frame = frameDataForRow(rows.at(0));
1220
1221 frame_selected = rows.count() == 1;
1222 if (packet_list_->multiSelectActive())
1223 {
1224 frame_selected = false;
1225 multi_selection = true;
1226 }
1227 next_selection_history = packet_list_->haveNextHistory();
1228 previous_selection_history = packet_list_->havePreviousHistory();
1229 have_frames = capture_file_.capFile()->count > 0;
1230 have_marked = capture_file_.capFile()->marked_count > 0;
1231 another_is_marked = have_marked && rows.count() <= 1 &&
1232 !(capture_file_.capFile()->marked_count == 1 && frame_selected && current_frame->marked);
1233 have_filtered = capture_file_.capFile()->displayed_count > 0 && capture_file_.capFile()->displayed_count != capture_file_.capFile()->count;
1234 have_ignored = capture_file_.capFile()->ignored_count > 0;
1235 have_time_ref = capture_file_.capFile()->ref_time_count > 0;
1236 another_is_time_ref = have_time_ref && rows.count() <= 1 &&
1237 !(capture_file_.capFile()->ref_time_count == 1 && frame_selected && current_frame->ref_time);
1238
1239 if (capture_file_.capFile()->edt && ! multi_selection)
1240 {
1241 proto_get_frame_protocols(capture_file_.capFile()->edt->pi.layers,
1242 &is_ip, &is_tcp, &is_udp, &is_sctp,
1243 &is_tls, &is_rtp, &is_lte_rlc);
1244 is_dccp = proto_is_frame_protocol(capture_file_.capFile()->edt->pi.layers, "dccp");
1245 is_http = proto_is_frame_protocol(capture_file_.capFile()->edt->pi.layers, "http");
1246 is_http2 = proto_is_frame_protocol(capture_file_.capFile()->edt->pi.layers, "http2");
1247 /* TODO: to follow a QUIC stream we need a *decrypted* QUIC connection, i.e. checking for "quic" in the protocol stack is not enough */
1248 is_quic = proto_is_frame_protocol(capture_file_.capFile()->edt->pi.layers, "quic");
1249 is_sip = proto_is_frame_protocol(capture_file_.capFile()->edt->pi.layers, "sip");
1250 is_exported_pdu = proto_is_frame_protocol(capture_file_.capFile()->edt->pi.layers, "exported_pdu");
1251 /* For Exported PDU there is a tag inserting IP addresses into the SRC and DST columns */
1252 if (is_exported_pdu &&
1253 (capture_file_.capFile()->edt->pi.net_src.type == AT_IPv4 || capture_file_.capFile()->edt->pi.net_src.type == AT_IPv6) &&
1254 (capture_file_.capFile()->edt->pi.net_dst.type == AT_IPv4 || capture_file_.capFile()->edt->pi.net_dst.type == AT_IPv6)) {
1255 is_ip = TRUE;
1256 }
1257 }
1258 }
1259
1260 main_ui_->actionEditMarkPacket->setText(tr("&Mark/Unmark Packet(s)", "", selectedRows().count()));
1261 main_ui_->actionEditIgnorePacket->setText(tr("&Ignore/Unignore Packet(s)", "", selectedRows().count()));
1262
1263 main_ui_->actionCopyListAsText->setEnabled(selectedRows().count() > 0);
1264 main_ui_->actionCopyListAsCSV->setEnabled(selectedRows().count() > 0);
1265 main_ui_->actionCopyListAsYAML->setEnabled(selectedRows().count() > 0);
1266
1267 main_ui_->actionEditMarkPacket->setEnabled(frame_selected || multi_selection);
1268 main_ui_->actionEditMarkAllDisplayed->setEnabled(have_frames);
1269 /* Unlike un-ignore, do not allow unmark of all frames when no frames are displayed */
1270 main_ui_->actionEditUnmarkAllDisplayed->setEnabled(have_marked);
1271 main_ui_->actionEditNextMark->setEnabled(another_is_marked);
1272 main_ui_->actionEditPreviousMark->setEnabled(another_is_marked);
1273
1274 GArray * linkTypes = Q_NULLPTR;
1275 if (capture_file_.capFile() && capture_file_.capFile()->linktypes)
1276 linkTypes = capture_file_.capFile()->linktypes;
1277
1278 bool enableEditComments = linkTypes && wtap_dump_can_write(capture_file_.capFile()->linktypes, WTAP_COMMENT_PER_PACKET);
1279 main_ui_->menuPacketComment->setEnabled(enableEditComments && selectedRows().count() > 0);
1280 main_ui_->actionDeleteAllPacketComments->setEnabled(enableEditComments);
1281
1282 main_ui_->actionEditIgnorePacket->setEnabled(frame_selected || multi_selection);
1283 main_ui_->actionEditIgnoreAllDisplayed->setEnabled(have_filtered);
1284 /* Allow un-ignore of all frames even with no frames currently displayed */
1285 main_ui_->actionEditUnignoreAllDisplayed->setEnabled(have_ignored);
1286
1287 main_ui_->actionEditSetTimeReference->setEnabled(frame_selected);
1288 main_ui_->actionEditUnsetAllTimeReferences->setEnabled(have_time_ref);
1289 main_ui_->actionEditNextTimeReference->setEnabled(another_is_time_ref);
1290 main_ui_->actionEditPreviousTimeReference->setEnabled(another_is_time_ref);
1291 main_ui_->actionEditTimeShift->setEnabled(have_frames);
1292
1293 main_ui_->actionGoGoToLinkedPacket->setEnabled(false);
1294 main_ui_->actionGoNextHistoryPacket->setEnabled(next_selection_history);
1295 main_ui_->actionGoPreviousHistoryPacket->setEnabled(previous_selection_history);
1296
1297 main_ui_->actionAnalyzeFollowTCPStream->setEnabled(is_tcp);
1298 main_ui_->actionAnalyzeFollowUDPStream->setEnabled(is_udp);
1299 main_ui_->actionAnalyzeFollowDCCPStream->setEnabled(is_dccp);
1300 main_ui_->actionAnalyzeFollowTLSStream->setEnabled(is_tls && !is_quic);
1301 main_ui_->actionAnalyzeFollowHTTPStream->setEnabled(is_http);
1302 main_ui_->actionAnalyzeFollowHTTP2Stream->setEnabled(is_http2);
1303 main_ui_->actionAnalyzeFollowQUICStream->setEnabled(is_quic);
1304 main_ui_->actionAnalyzeFollowSIPCall->setEnabled(is_sip);
1305
1306 foreach(QAction *cc_action, cc_actions) {
1307 cc_action->setEnabled(frame_selected);
1308 }
1309 main_ui_->actionViewColorizeNewColoringRule->setEnabled(frame_selected);
1310
1311 main_ui_->actionViewColorizeResetColorization->setEnabled(tmp_color_filters_used());
1312
1313 main_ui_->actionViewShowPacketInNewWindow->setEnabled(frame_selected);
1314 main_ui_->actionViewEditResolvedName->setEnabled(frame_selected && is_ip);
1315
1316 emit packetInfoChanged(capture_file_.packetInfo());
1317
1318 // set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/ViewMenu/NameResolution/ResolveName",
1319 // frame_selected && (gbl_resolv_flags.mac_name || gbl_resolv_flags.network_name ||
1320 // gbl_resolv_flags.transport_name));
1321
1322 main_ui_->actionToolsFirewallAclRules->setEnabled(frame_selected);
1323
1324 main_ui_->actionStatisticsTcpStreamRoundTripTime->setEnabled(is_tcp);
1325 main_ui_->actionStatisticsTcpStreamStevens->setEnabled(is_tcp);
1326 main_ui_->actionStatisticsTcpStreamTcptrace->setEnabled(is_tcp);
1327 main_ui_->actionStatisticsTcpStreamThroughput->setEnabled(is_tcp);
1328 main_ui_->actionStatisticsTcpStreamWindowScaling->setEnabled(is_tcp);
1329
1330 main_ui_->actionSCTPAnalyseThisAssociation->setEnabled(is_sctp);
1331 main_ui_->actionSCTPShowAllAssociations->setEnabled(is_sctp);
1332 main_ui_->actionSCTPFilterThisAssociation->setEnabled(is_sctp);
1333 main_ui_->actionTelephonyRtpStreamAnalysis->setEnabled(is_rtp);
1334 main_ui_->actionTelephonyRtpPlayer->setEnabled(is_rtp);
1335 main_ui_->actionTelephonyLteRlcGraph->setEnabled(is_lte_rlc);
1336 }
1337
setMenusForSelectedTreeRow(FieldInformation * finfo)1338 void MainWindow::setMenusForSelectedTreeRow(FieldInformation *finfo) {
1339
1340 bool can_match_selected = false;
1341 bool is_framenum = false;
1342 bool have_field_info = false;
1343 bool have_subtree = false;
1344 bool can_open_url = false;
1345 bool have_packet_bytes = false;
1346 QByteArray field_filter;
1347 int field_id = -1;
1348
1349 field_info * fi = 0;
1350 if (finfo)
1351 fi = finfo->fieldInfo();
1352
1353 if (capture_file_.capFile()) {
1354 capture_file_.capFile()->finfo_selected = fi;
1355
1356 if (fi && fi->tree_type != -1) {
1357 have_subtree = true;
1358 }
1359
1360 if (fi && fi->ds_tvb) {
1361 have_packet_bytes = true;
1362 }
1363 }
1364
1365 if (capture_file_.capFile() != NULL && fi != NULL) {
1366 header_field_info *hfinfo = fi->hfinfo;
1367 int linked_frame = -1;
1368
1369 have_field_info = true;
1370 can_match_selected = proto_can_match_selected(capture_file_.capFile()->finfo_selected, capture_file_.capFile()->edt);
1371 if (hfinfo && hfinfo->type == FT_FRAMENUM) {
1372 is_framenum = true;
1373 linked_frame = fvalue_get_uinteger(&fi->value);
1374 }
1375
1376 char *tmp_field = proto_construct_match_selected_string(fi, capture_file_.capFile()->edt);
1377 field_filter = tmp_field;
1378 wmem_free(NULL, tmp_field);
1379
1380 field_id = fi->hfinfo->id;
1381 /* if the selected field isn't a protocol, get its parent */
1382 if (!proto_registrar_is_protocol(field_id)) {
1383 field_id = proto_registrar_get_parent(fi->hfinfo->id);
1384 }
1385
1386 if (field_id >= 0) {
1387 can_open_url = true;
1388 main_ui_->actionContextWikiProtocolPage->setData(field_id);
1389 main_ui_->actionContextFilterFieldReference->setData(field_id);
1390 } else {
1391 main_ui_->actionContextWikiProtocolPage->setData(QVariant());
1392 main_ui_->actionContextFilterFieldReference->setData(QVariant());
1393 }
1394
1395 if (linked_frame > 0) {
1396 main_ui_->actionGoGoToLinkedPacket->setData(linked_frame);
1397 } else {
1398 main_ui_->actionGoGoToLinkedPacket->setData(QVariant());
1399 }
1400 }
1401
1402 // Always enable / disable the following items.
1403 main_ui_->actionFileExportPacketBytes->setEnabled(have_field_info);
1404
1405 main_ui_->actionCopyAllVisibleItems->setEnabled(capture_file_.capFile() != NULL && ! packet_list_->multiSelectActive());
1406 main_ui_->actionCopyAllVisibleSelectedTreeItems->setEnabled(can_match_selected);
1407 main_ui_->actionEditCopyDescription->setEnabled(can_match_selected);
1408 main_ui_->actionEditCopyFieldName->setEnabled(can_match_selected);
1409 main_ui_->actionEditCopyValue->setEnabled(can_match_selected);
1410 main_ui_->actionEditCopyAsFilter->setEnabled(can_match_selected);
1411
1412 main_ui_->actionAnalyzeShowPacketBytes->setEnabled(have_packet_bytes);
1413 main_ui_->actionFileExportPacketBytes->setEnabled(have_packet_bytes);
1414
1415 main_ui_->actionViewExpandSubtrees->setEnabled(have_subtree);
1416 main_ui_->actionViewCollapseSubtrees->setEnabled(have_subtree);
1417
1418 main_ui_->actionGoGoToLinkedPacket->setEnabled(is_framenum);
1419
1420 main_ui_->actionAnalyzeCreateAColumn->setEnabled(can_match_selected);
1421
1422 main_ui_->actionContextShowLinkedPacketInNewWindow->setEnabled(is_framenum);
1423
1424 main_ui_->actionContextWikiProtocolPage->setEnabled(can_open_url);
1425 main_ui_->actionContextFilterFieldReference->setEnabled(can_open_url);
1426
1427
1428 // Only enable / disable the following items if we have focus so that we
1429 // don't clobber anything we may have set in setMenusForSelectedPacket.
1430 if (!proto_tree_ || !proto_tree_->hasFocus()) return;
1431
1432 emit packetInfoChanged(capture_file_.packetInfo());
1433 emit fieldFilterChanged(field_filter);
1434
1435 // set_menu_sensitivity(ui_manager_tree_view_menu, "/TreeViewPopup/ResolveName",
1436 // frame_selected && (gbl_resolv_flags.mac_name || gbl_resolv_flags.network_name ||
1437 // gbl_resolv_flags.transport_name));
1438
1439 }
1440
interfaceSelectionChanged()1441 void MainWindow::interfaceSelectionChanged()
1442 {
1443 #ifdef HAVE_LIBPCAP
1444 // XXX This doesn't disable the toolbar button when using
1445 // QtMacExtras.
1446 if (global_capture_opts.num_selected > 0 && capture_filter_valid_) {
1447 main_ui_->actionCaptureStart->setEnabled(true);
1448 } else {
1449 main_ui_->actionCaptureStart->setEnabled(false);
1450 }
1451 #endif // HAVE_LIBPCAP
1452 }
1453
captureFilterSyntaxChanged(bool valid)1454 void MainWindow::captureFilterSyntaxChanged(bool valid)
1455 {
1456 capture_filter_valid_ = valid;
1457 interfaceSelectionChanged();
1458 }
1459
startInterfaceCapture(bool valid,const QString capture_filter)1460 void MainWindow::startInterfaceCapture(bool valid, const QString capture_filter)
1461 {
1462 capture_filter_valid_ = valid;
1463 welcome_page_->setCaptureFilter(capture_filter);
1464 QString before_what(tr(" before starting a new capture"));
1465 if (testCaptureFileClose(before_what)) {
1466 // The interface tree will update the selected interfaces via its timer
1467 // so no need to do anything here.
1468 startCapture();
1469 }
1470 }
1471
applyGlobalCommandLineOptions()1472 void MainWindow::applyGlobalCommandLineOptions()
1473 {
1474 if (global_dissect_options.time_format != TS_NOT_SET) {
1475 foreach(QAction* tda, td_actions.keys()) {
1476 if (global_dissect_options.time_format == td_actions[tda]) {
1477 tda->setChecked(true);
1478 recent.gui_time_format = global_dissect_options.time_format;
1479 timestamp_set_type(global_dissect_options.time_format);
1480 break;
1481 }
1482 }
1483 }
1484 if (global_commandline_info.full_screen) {
1485 this->showFullScreen();
1486 }
1487 }
1488
redissectPackets()1489 void MainWindow::redissectPackets()
1490 {
1491 if (capture_file_.capFile()) {
1492 cf_redissect_packets(capture_file_.capFile());
1493 main_ui_->statusBar->expertUpdate();
1494 }
1495
1496 proto_free_deregistered_fields();
1497 }
1498
checkDisplayFilter()1499 void MainWindow::checkDisplayFilter()
1500 {
1501 if (!df_combo_box_->checkDisplayFilter()) {
1502 g_free(CaptureFile::globalCapFile()->dfilter);
1503 CaptureFile::globalCapFile()->dfilter = NULL;
1504 }
1505 }
1506
fieldsChanged()1507 void MainWindow::fieldsChanged()
1508 {
1509 gchar *err_msg = NULL;
1510 if (!color_filters_reload(&err_msg, color_filter_add_cb)) {
1511 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
1512 g_free(err_msg);
1513 }
1514 tap_listeners_dfilter_recompile();
1515
1516 emit checkDisplayFilter();
1517
1518 if (have_custom_cols(&CaptureFile::globalCapFile()->cinfo)) {
1519 // Recreate packet list columns according to new/changed/deleted fields
1520 packet_list_->fieldsChanged(CaptureFile::globalCapFile());
1521 }
1522
1523 emit reloadFields();
1524 }
1525
reloadLuaPlugins()1526 void MainWindow::reloadLuaPlugins()
1527 {
1528 #ifdef HAVE_LUA
1529 if (wsApp->isReloadingLua())
1530 return;
1531
1532 gboolean uses_lua_filehandler = FALSE;
1533
1534 if (capture_file_.capFile()) {
1535 // Check if the current capture file is opened with a Lua FileHandler
1536 capture_file *cf = capture_file_.capFile();
1537 uses_lua_filehandler = wtap_uses_lua_filehandler(cf->provider.wth);
1538
1539 if (uses_lua_filehandler && cf->unsaved_changes) {
1540 // Prompt to save the file before reloading, in case the FileHandler has changed
1541 QString before_what(tr(" before reloading Lua plugins"));
1542 if (!testCaptureFileClose(before_what, Reload)) {
1543 return;
1544 }
1545 }
1546 }
1547
1548 wsApp->setReloadingLua(true);
1549
1550 wslua_reload_plugins(NULL, NULL);
1551 funnel_statistics_reload_menus();
1552 reloadDynamicMenus();
1553 closePacketDialogs();
1554
1555 // Preferences may have been deleted so close all widgets using prefs
1556 main_ui_->preferenceEditorFrame->animatedHide();
1557
1558 wsApp->readConfigurationFiles(true);
1559 commandline_options_reapply();
1560
1561 fieldsChanged();
1562 prefs_apply_all();
1563
1564 if (uses_lua_filehandler) {
1565 // Reload the file in case the FileHandler has changed
1566 if (cf_reload(capture_file_.capFile()) != CF_OK) {
1567 cf_close(capture_file_.capFile());
1568 }
1569 proto_free_deregistered_fields();
1570 } else {
1571 redissectPackets();
1572 }
1573
1574 wsApp->setReloadingLua(false);
1575 SimpleDialog::displayQueuedMessages();
1576 #endif
1577 }
1578
showAccordionFrame(AccordionFrame * show_frame,bool toggle)1579 void MainWindow::showAccordionFrame(AccordionFrame *show_frame, bool toggle)
1580 {
1581 QList<AccordionFrame *>frame_list = QList<AccordionFrame *>()
1582 << main_ui_->goToFrame << main_ui_->searchFrame
1583 << main_ui_->addressEditorFrame << main_ui_->columnEditorFrame
1584 << main_ui_->preferenceEditorFrame << main_ui_->filterExpressionFrame;
1585
1586 frame_list.removeAll(show_frame);
1587 foreach(AccordionFrame *af, frame_list) af->animatedHide();
1588
1589 if (toggle) {
1590 if (show_frame->isVisible()) {
1591 show_frame->animatedHide();
1592 return;
1593 }
1594 }
1595 show_frame->animatedShow();
1596 }
1597
showColumnEditor(int column)1598 void MainWindow::showColumnEditor(int column)
1599 {
1600 previous_focus_ = wsApp->focusWidget();
1601 connect(previous_focus_, SIGNAL(destroyed()), this, SLOT(resetPreviousFocus()));
1602 main_ui_->columnEditorFrame->editColumn(column);
1603 showAccordionFrame(main_ui_->columnEditorFrame);
1604 }
1605
showPreferenceEditor()1606 void MainWindow::showPreferenceEditor()
1607 {
1608 showAccordionFrame(main_ui_->preferenceEditorFrame);
1609 }
1610
initViewColorizeMenu()1611 void MainWindow::initViewColorizeMenu()
1612 {
1613 QList<QAction *> cc_actions = QList<QAction *>()
1614 << main_ui_->actionViewColorizeConversation1 << main_ui_->actionViewColorizeConversation2
1615 << main_ui_->actionViewColorizeConversation3 << main_ui_->actionViewColorizeConversation4
1616 << main_ui_->actionViewColorizeConversation5 << main_ui_->actionViewColorizeConversation6
1617 << main_ui_->actionViewColorizeConversation7 << main_ui_->actionViewColorizeConversation8
1618 << main_ui_->actionViewColorizeConversation9 << main_ui_->actionViewColorizeConversation10;
1619
1620 guint8 color_num = 1;
1621
1622 foreach(QAction *cc_action, cc_actions) {
1623 cc_action->setData(color_num);
1624 connect(cc_action, SIGNAL(triggered()), this, SLOT(colorizeConversation()));
1625
1626 const color_filter_t *colorf = color_filters_tmp_color(color_num);
1627 if (colorf) {
1628 QColor bg = ColorUtils::fromColorT(colorf->bg_color);
1629 QColor fg = ColorUtils::fromColorT(colorf->fg_color);
1630 cc_action->setIcon(StockIcon::colorIcon(bg.rgb(), fg.rgb(), QString::number(color_num)));
1631 }
1632 color_num++;
1633 }
1634
1635 #ifdef Q_OS_MAC
1636 // Spotlight uses Cmd+Space
1637 main_ui_->actionViewColorizeResetColorization->setShortcut(QKeySequence("Meta+Space"));
1638 #endif
1639 }
1640
addStatsPluginsToMenu()1641 void MainWindow::addStatsPluginsToMenu() {
1642 GList *cfg_list = stats_tree_get_cfg_list();
1643 GList *iter = g_list_first(cfg_list);
1644 QAction *stats_tree_action;
1645 QMenu *parent_menu;
1646 bool first_item = true;
1647
1648 while (iter) {
1649 stats_tree_cfg *cfg = gxx_list_data(stats_tree_cfg *, iter);
1650 if (cfg->plugin) {
1651 if (first_item) {
1652 main_ui_->menuStatistics->addSeparator();
1653 first_item = false;
1654 }
1655
1656 parent_menu = main_ui_->menuStatistics;
1657 // gtk/main_menubar.c compresses double slashes, hence SkipEmptyParts
1658 #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
1659 QStringList cfg_name_parts = QString(cfg->name).split("/", Qt::SkipEmptyParts);
1660 #else
1661 QStringList cfg_name_parts = QString(cfg->name).split("/", QString::SkipEmptyParts);
1662 #endif
1663 if (cfg_name_parts.isEmpty()) continue;
1664
1665 QString stat_name = cfg_name_parts.takeLast();
1666 if (!cfg_name_parts.isEmpty()) {
1667 QString menu_name = cfg_name_parts.join("/");
1668 parent_menu = findOrAddMenu(parent_menu, menu_name);
1669 }
1670
1671 stats_tree_action = new QAction(stat_name, this);
1672 stats_tree_action->setData(cfg->abbr);
1673 parent_menu->addAction(stats_tree_action);
1674 connect(stats_tree_action, SIGNAL(triggered()), this, SLOT(actionStatisticsPlugin_triggered()));
1675 }
1676 iter = gxx_list_next(iter);
1677 }
1678 g_list_free(cfg_list);
1679 }
1680
setFeaturesEnabled(bool enabled)1681 void MainWindow::setFeaturesEnabled(bool enabled)
1682 {
1683 main_ui_->menuBar->setEnabled(enabled);
1684 main_ui_->mainToolBar->setEnabled(enabled);
1685 main_ui_->displayFilterToolBar->setEnabled(enabled);
1686 if (enabled)
1687 {
1688 main_ui_->statusBar->clearMessage();
1689 #ifdef HAVE_LIBPCAP
1690 main_ui_->actionGoAutoScroll->setChecked(auto_scroll_live);
1691 #endif
1692 }
1693 else
1694 {
1695 main_ui_->statusBar->showMessage(tr("Please wait while Wireshark is initializing…"));
1696 }
1697 }
1698
1699 // Display Filter Toolbar
1700
on_actionDisplayFilterExpression_triggered()1701 void MainWindow::on_actionDisplayFilterExpression_triggered()
1702 {
1703 DisplayFilterExpressionDialog *dfe_dialog = new DisplayFilterExpressionDialog(this);
1704
1705 connect(dfe_dialog, SIGNAL(insertDisplayFilter(QString)),
1706 df_combo_box_->lineEdit(), SLOT(insertFilter(const QString &)));
1707
1708 dfe_dialog->show();
1709 }
1710
on_actionNewDisplayFilterExpression_triggered()1711 void MainWindow::on_actionNewDisplayFilterExpression_triggered()
1712 {
1713 main_ui_->filterExpressionFrame->addExpression(df_combo_box_->lineEdit()->text());
1714 }
1715
onFilterSelected(QString filterText,bool prepare)1716 void MainWindow::onFilterSelected(QString filterText, bool prepare)
1717 {
1718 if (filterText.length() <= 0)
1719 return;
1720
1721 df_combo_box_->setDisplayFilter(filterText);
1722 // Holding down the Shift key will only prepare filter.
1723 if (!prepare)
1724 df_combo_box_->applyDisplayFilter();
1725 }
1726
onFilterPreferences()1727 void MainWindow::onFilterPreferences()
1728 {
1729 emit showPreferencesDialog(PrefsModel::typeToString(PrefsModel::FilterButtons));
1730 }
1731
onFilterEdit(int uatIndex)1732 void MainWindow::onFilterEdit(int uatIndex)
1733 {
1734 main_ui_->filterExpressionFrame->editExpression(uatIndex);
1735 }
1736
openStatCommandDialog(const QString & menu_path,const char * arg,void * userdata)1737 void MainWindow::openStatCommandDialog(const QString &menu_path, const char *arg, void *userdata)
1738 {
1739 QString slot = QString("statCommand%1").arg(menu_path);
1740 QMetaObject::invokeMethod(this, slot.toLatin1().constData(), Q_ARG(const char *, arg), Q_ARG(void *, userdata));
1741 }
1742
openTapParameterDialog(const QString cfg_str,const QString arg,void * userdata)1743 void MainWindow::openTapParameterDialog(const QString cfg_str, const QString arg, void *userdata)
1744 {
1745 TapParameterDialog *tp_dialog = TapParameterDialog::showTapParameterStatistics(*this, capture_file_, cfg_str, arg, userdata);
1746 if (!tp_dialog) return;
1747
1748 connect(tp_dialog, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)),
1749 this, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)));
1750 connect(tp_dialog, SIGNAL(updateFilter(QString)),
1751 df_combo_box_->lineEdit(), SLOT(setText(QString)));
1752 tp_dialog->show();
1753 }
1754
openTapParameterDialog()1755 void MainWindow::openTapParameterDialog()
1756 {
1757 QAction *tpa = qobject_cast<QAction *>(QObject::sender());
1758 if (!tpa) return;
1759
1760 const QString cfg_str = tpa->data().toString();
1761 openTapParameterDialog(cfg_str, NULL, NULL);
1762 }
1763
1764 #if defined(HAVE_SOFTWARE_UPDATE) && defined(Q_OS_WIN)
softwareUpdateRequested()1765 void MainWindow::softwareUpdateRequested() {
1766 // We could call testCaptureFileClose here, but that would give us yet
1767 // another dialog. Just try again later.
1768 if (capture_file_.capFile() && capture_file_.capFile()->state != FILE_CLOSED) {
1769 wsApp->rejectSoftwareUpdate();
1770 }
1771 }
1772 #endif
1773
1774 // File Menu
1775
on_actionFileOpen_triggered()1776 void MainWindow::on_actionFileOpen_triggered()
1777 {
1778 openCaptureFile();
1779 }
1780
on_actionFileMerge_triggered()1781 void MainWindow::on_actionFileMerge_triggered()
1782 {
1783 mergeCaptureFile();
1784 }
1785
on_actionFileImportFromHexDump_triggered()1786 void MainWindow::on_actionFileImportFromHexDump_triggered()
1787 {
1788 importCaptureFile();
1789 }
1790
on_actionFileClose_triggered()1791 void MainWindow::on_actionFileClose_triggered() {
1792 QString before_what(tr(" before closing the file"));
1793 if (testCaptureFileClose(before_what))
1794 showWelcome();
1795 }
1796
on_actionFileSave_triggered()1797 void MainWindow::on_actionFileSave_triggered()
1798 {
1799 saveCaptureFile(capture_file_.capFile(), false);
1800 }
1801
on_actionFileSaveAs_triggered()1802 void MainWindow::on_actionFileSaveAs_triggered()
1803 {
1804 saveAsCaptureFile(capture_file_.capFile());
1805 }
1806
on_actionFileSetListFiles_triggered()1807 void MainWindow::on_actionFileSetListFiles_triggered()
1808 {
1809 file_set_dialog_->show();
1810 }
1811
on_actionFileSetNextFile_triggered()1812 void MainWindow::on_actionFileSetNextFile_triggered()
1813 {
1814 fileset_entry *entry = fileset_get_next();
1815
1816 if (entry) {
1817 QString new_cf_path = entry->fullname;
1818 openCaptureFile(new_cf_path);
1819 }
1820 }
1821
on_actionFileSetPreviousFile_triggered()1822 void MainWindow::on_actionFileSetPreviousFile_triggered()
1823 {
1824 fileset_entry *entry = fileset_get_previous();
1825
1826 if (entry) {
1827 QString new_cf_path = entry->fullname;
1828 openCaptureFile(new_cf_path);
1829 }
1830 }
1831
on_actionFileExportPackets_triggered()1832 void MainWindow::on_actionFileExportPackets_triggered()
1833 {
1834 exportSelectedPackets();
1835 }
1836
on_actionFileExportAsPlainText_triggered()1837 void MainWindow::on_actionFileExportAsPlainText_triggered()
1838 {
1839 exportDissections(export_type_text);
1840 }
1841
on_actionFileExportAsCSV_triggered()1842 void MainWindow::on_actionFileExportAsCSV_triggered()
1843 {
1844 exportDissections(export_type_csv);
1845 }
1846
on_actionFileExportAsCArrays_triggered()1847 void MainWindow::on_actionFileExportAsCArrays_triggered()
1848 {
1849 exportDissections(export_type_carrays);
1850 }
1851
on_actionFileExportAsPSML_triggered()1852 void MainWindow::on_actionFileExportAsPSML_triggered()
1853 {
1854 exportDissections(export_type_psml);
1855 }
1856
on_actionFileExportAsPDML_triggered()1857 void MainWindow::on_actionFileExportAsPDML_triggered()
1858 {
1859 exportDissections(export_type_pdml);
1860 }
1861
on_actionFileExportAsJSON_triggered()1862 void MainWindow::on_actionFileExportAsJSON_triggered()
1863 {
1864 exportDissections(export_type_json);
1865 }
1866
on_actionFileExportPacketBytes_triggered()1867 void MainWindow::on_actionFileExportPacketBytes_triggered()
1868 {
1869 QString file_name;
1870
1871 if (!capture_file_.capFile() || !capture_file_.capFile()->finfo_selected) return;
1872
1873 file_name = WiresharkFileDialog::getSaveFileName(this,
1874 wsApp->windowTitleString(tr("Export Selected Packet Bytes")),
1875 wsApp->lastOpenDir().canonicalPath(),
1876 tr("Raw data (*.bin *.dat *.raw);;All Files (" ALL_FILES_WILDCARD ")")
1877 );
1878
1879 if (file_name.length() > 0) {
1880 const guint8 *data_p;
1881
1882 data_p = tvb_get_ptr(capture_file_.capFile()->finfo_selected->ds_tvb, 0, -1) +
1883 capture_file_.capFile()->finfo_selected->start;
1884 write_file_binary_mode(qUtf8Printable(file_name), data_p, capture_file_.capFile()->finfo_selected->length);
1885
1886 /* Save the directory name for future file dialogs. */
1887 wsApp->setLastOpenDirFromFilename(file_name);
1888 }
1889 }
1890
on_actionAnalyzeShowPacketBytes_triggered()1891 void MainWindow::on_actionAnalyzeShowPacketBytes_triggered()
1892 {
1893 ShowPacketBytesDialog *spbd = new ShowPacketBytesDialog(*this, capture_file_);
1894 spbd->addCodecs(text_codec_map_);
1895 spbd->show();
1896 }
1897
on_actionFileExportPDU_triggered()1898 void MainWindow::on_actionFileExportPDU_triggered()
1899 {
1900 ExportPDUDialog *exportpdu_dialog = new ExportPDUDialog(this);
1901
1902 if (exportpdu_dialog->isMinimized() == true)
1903 {
1904 exportpdu_dialog->showNormal();
1905 }
1906 else
1907 {
1908 exportpdu_dialog->show();
1909 }
1910
1911 exportpdu_dialog->raise();
1912 exportpdu_dialog->activateWindow();
1913 }
1914
on_actionFileExportTLSSessionKeys_triggered()1915 void MainWindow::on_actionFileExportTLSSessionKeys_triggered()
1916 {
1917 QString file_name;
1918 QString save_title;
1919 int keylist_len;
1920
1921 keylist_len = ssl_session_key_count();
1922 /* don't show up the dialog, if no data has to be saved */
1923 if (keylist_len < 1) {
1924 /* shouldn't happen as the menu item should have been greyed out */
1925 QMessageBox::warning(
1926 this,
1927 tr("No Keys"),
1928 tr("There are no TLS Session Keys to save."),
1929 QMessageBox::Ok
1930 );
1931 return;
1932 }
1933
1934 save_title.append(wsApp->windowTitleString(tr("Export TLS Session Keys (%Ln key(s))", "", keylist_len)));
1935 file_name = WiresharkFileDialog::getSaveFileName(this,
1936 save_title,
1937 wsApp->lastOpenDir().canonicalPath(),
1938 tr("TLS Session Keys (*.keys *.txt);;All Files (" ALL_FILES_WILDCARD ")")
1939 );
1940 if (file_name.length() > 0) {
1941 gsize keylist_length;
1942 gchar *keylist = ssl_export_sessions(&keylist_length);
1943 write_file_binary_mode(qUtf8Printable(file_name), keylist, keylist_length);
1944
1945 /* Save the directory name for future file dialogs. */
1946 wsApp->setLastOpenDirFromFilename(file_name);
1947 g_free(keylist);
1948 }
1949 }
1950
on_actionStatisticsHpfeeds_triggered()1951 void MainWindow::on_actionStatisticsHpfeeds_triggered()
1952 {
1953 openStatisticsTreeDialog("hpfeeds");
1954 }
1955
on_actionFilePrint_triggered()1956 void MainWindow::on_actionFilePrint_triggered()
1957 {
1958 capture_file *cf = capture_file_.capFile();
1959 g_return_if_fail(cf);
1960
1961 QList<int> rows = packet_list_->selectedRows(true);
1962
1963 QStringList entries;
1964 foreach (int row, rows)
1965 entries << QString::number(row);
1966 QString selRange = entries.join(",");
1967
1968 PrintDialog * pdlg_ = new PrintDialog(this, cf, selRange);
1969 pdlg_->setWindowModality(Qt::ApplicationModal);
1970 pdlg_->show();
1971 }
1972
1973 // Edit Menu
1974
1975 // XXX This should probably be somewhere else.
actionEditCopyTriggered(MainWindow::CopySelected selection_type)1976 void MainWindow::actionEditCopyTriggered(MainWindow::CopySelected selection_type)
1977 {
1978 char label_str[ITEM_LABEL_LENGTH];
1979 QString clip;
1980
1981 if (!capture_file_.capFile()) return;
1982
1983 field_info *finfo_selected = capture_file_.capFile()->finfo_selected;
1984
1985 switch (selection_type) {
1986 case CopySelectedDescription:
1987 if (proto_tree_->selectionModel()->hasSelection()) {
1988 QModelIndex idx = proto_tree_->selectionModel()->selectedIndexes().first();
1989 clip = idx.data(Qt::DisplayRole).toString();
1990 }
1991 break;
1992 case CopySelectedFieldName:
1993 if (finfo_selected && finfo_selected->hfinfo->abbrev != 0) {
1994 clip.append(finfo_selected->hfinfo->abbrev);
1995 }
1996 break;
1997 case CopySelectedValue:
1998 if (finfo_selected && capture_file_.capFile()->edt != 0) {
1999 gchar* field_str = get_node_field_value(finfo_selected, capture_file_.capFile()->edt);
2000 clip.append(field_str);
2001 g_free(field_str);
2002 }
2003 break;
2004 case CopyAllVisibleItems:
2005 clip = proto_tree_->toString();
2006 break;
2007 case CopyAllVisibleSelectedTreeItems:
2008 if (proto_tree_->selectionModel()->hasSelection()) {
2009 clip = proto_tree_->toString(proto_tree_->selectionModel()->selectedIndexes().first());
2010 }
2011 break;
2012 case CopyListAsText:
2013 case CopyListAsCSV:
2014 case CopyListAsYAML:
2015 if (packet_list_->selectedRows().count() > 0)
2016 {
2017 QList<int> rows = packet_list_->selectedRows();
2018 QStringList content;
2019
2020 PacketList::SummaryCopyType copyType = PacketList::CopyAsText;
2021 if (selection_type == CopyListAsCSV)
2022 copyType = PacketList::CopyAsCSV;
2023 else if (selection_type == CopyListAsYAML)
2024 copyType = PacketList::CopyAsYAML;
2025
2026 if ((copyType == PacketList::CopyAsText) ||
2027 (copyType == PacketList::CopyAsCSV)) {
2028 QString headerEntry = packet_list_->createHeaderSummaryText(copyType);
2029 content << headerEntry;
2030 }
2031 foreach (int row, rows)
2032 {
2033 QModelIndex idx = packet_list_->model()->index(row, 0);
2034 if (! idx.isValid())
2035 continue;
2036
2037 QString entry = packet_list_->createSummaryText(idx, copyType);
2038 content << entry;
2039 }
2040
2041 if (content.count() > 0) {
2042 clip = content.join("\n");
2043 //
2044 // Each YAML item ends with a newline, so the string
2045 // ends with a newline already if it's CopyListAsYAML.
2046 // If we add a newline, there'd be an extra blank
2047 // line.
2048 //
2049 // Otherwise, we've used newlines as separators, not
2050 // terminators, so there's no final newline. Add it.
2051 //
2052 if (selection_type != CopyListAsYAML)
2053 clip += "\n";
2054 }
2055 }
2056 break;
2057 }
2058
2059 if (clip.length() == 0) {
2060 /* If no representation then... Try to read the value */
2061 proto_item_fill_label(capture_file_.capFile()->finfo_selected, label_str);
2062 clip.append(label_str);
2063 }
2064
2065 if (clip.length()) {
2066 wsApp->clipboard()->setText(clip);
2067 } else {
2068 QString err = tr("Couldn't copy text. Try another item.");
2069 wsApp->pushStatus(WiresharkApplication::TemporaryStatus, err);
2070 }
2071 }
2072
on_actionCopyAllVisibleItems_triggered()2073 void MainWindow::on_actionCopyAllVisibleItems_triggered()
2074 {
2075 actionEditCopyTriggered(CopyAllVisibleItems);
2076 }
2077
on_actionCopyListAsText_triggered()2078 void MainWindow::on_actionCopyListAsText_triggered()
2079 {
2080 actionEditCopyTriggered(CopyListAsText);
2081 }
2082
on_actionCopyListAsCSV_triggered()2083 void MainWindow::on_actionCopyListAsCSV_triggered()
2084 {
2085 actionEditCopyTriggered(CopyListAsCSV);
2086 }
2087
on_actionCopyListAsYAML_triggered()2088 void MainWindow::on_actionCopyListAsYAML_triggered()
2089 {
2090 actionEditCopyTriggered(CopyListAsYAML);
2091 }
2092
on_actionCopyAllVisibleSelectedTreeItems_triggered()2093 void MainWindow::on_actionCopyAllVisibleSelectedTreeItems_triggered()
2094 {
2095 actionEditCopyTriggered(CopyAllVisibleSelectedTreeItems);
2096 }
2097
on_actionEditCopyDescription_triggered()2098 void MainWindow::on_actionEditCopyDescription_triggered()
2099 {
2100 actionEditCopyTriggered(CopySelectedDescription);
2101 }
2102
on_actionEditCopyFieldName_triggered()2103 void MainWindow::on_actionEditCopyFieldName_triggered()
2104 {
2105 actionEditCopyTriggered(CopySelectedFieldName);
2106 }
2107
on_actionEditCopyValue_triggered()2108 void MainWindow::on_actionEditCopyValue_triggered()
2109 {
2110 actionEditCopyTriggered(CopySelectedValue);
2111 }
2112
on_actionEditCopyAsFilter_triggered()2113 void MainWindow::on_actionEditCopyAsFilter_triggered()
2114 {
2115 matchFieldFilter(FilterAction::ActionCopy, FilterAction::ActionTypePlain);
2116 }
2117
on_actionEditFindPacket_triggered()2118 void MainWindow::on_actionEditFindPacket_triggered()
2119 {
2120 if (! packet_list_->model() || packet_list_->model()->rowCount() < 1) {
2121 return;
2122 }
2123 previous_focus_ = wsApp->focusWidget();
2124 connect(previous_focus_, SIGNAL(destroyed()), this, SLOT(resetPreviousFocus()));
2125 if (!main_ui_->searchFrame->isVisible()) {
2126 showAccordionFrame(main_ui_->searchFrame, true);
2127 } else {
2128 main_ui_->searchFrame->animatedHide();
2129 }
2130 main_ui_->searchFrame->setFocus();
2131 }
2132
on_actionEditFindNext_triggered()2133 void MainWindow::on_actionEditFindNext_triggered()
2134 {
2135 main_ui_->searchFrame->findNext();
2136 }
2137
on_actionEditFindPrevious_triggered()2138 void MainWindow::on_actionEditFindPrevious_triggered()
2139 {
2140 main_ui_->searchFrame->findPrevious();
2141 }
2142
on_actionEditMarkPacket_triggered()2143 void MainWindow::on_actionEditMarkPacket_triggered()
2144 {
2145 freeze();
2146 packet_list_->markFrame();
2147 thaw();
2148 setMenusForSelectedPacket();
2149 }
2150
on_actionEditMarkAllDisplayed_triggered()2151 void MainWindow::on_actionEditMarkAllDisplayed_triggered()
2152 {
2153 freeze();
2154 packet_list_->markAllDisplayedFrames(true);
2155 thaw();
2156 setMenusForSelectedPacket();
2157 }
2158
on_actionEditUnmarkAllDisplayed_triggered()2159 void MainWindow::on_actionEditUnmarkAllDisplayed_triggered()
2160 {
2161 freeze();
2162 packet_list_->markAllDisplayedFrames(false);
2163 thaw();
2164 setMenusForSelectedPacket();
2165 }
2166
on_actionEditNextMark_triggered()2167 void MainWindow::on_actionEditNextMark_triggered()
2168 {
2169 if (capture_file_.capFile())
2170 cf_find_packet_marked(capture_file_.capFile(), SD_FORWARD);
2171 }
2172
on_actionEditPreviousMark_triggered()2173 void MainWindow::on_actionEditPreviousMark_triggered()
2174 {
2175 if (capture_file_.capFile())
2176 cf_find_packet_marked(capture_file_.capFile(), SD_BACKWARD);
2177 }
2178
on_actionEditIgnorePacket_triggered()2179 void MainWindow::on_actionEditIgnorePacket_triggered()
2180 {
2181 freeze();
2182 packet_list_->ignoreFrame();
2183 thaw();
2184 setMenusForSelectedPacket();
2185 }
2186
on_actionEditIgnoreAllDisplayed_triggered()2187 void MainWindow::on_actionEditIgnoreAllDisplayed_triggered()
2188 {
2189 freeze();
2190 packet_list_->ignoreAllDisplayedFrames(true);
2191 thaw();
2192 setMenusForSelectedPacket();
2193 }
2194
on_actionEditUnignoreAllDisplayed_triggered()2195 void MainWindow::on_actionEditUnignoreAllDisplayed_triggered()
2196 {
2197 freeze();
2198 packet_list_->ignoreAllDisplayedFrames(false);
2199 thaw();
2200 setMenusForSelectedPacket();
2201 }
2202
on_actionEditSetTimeReference_triggered()2203 void MainWindow::on_actionEditSetTimeReference_triggered()
2204 {
2205 packet_list_->setTimeReference();
2206 setMenusForSelectedPacket();
2207 }
2208
on_actionEditUnsetAllTimeReferences_triggered()2209 void MainWindow::on_actionEditUnsetAllTimeReferences_triggered()
2210 {
2211 packet_list_->unsetAllTimeReferences();
2212 setMenusForSelectedPacket();
2213 }
2214
on_actionEditNextTimeReference_triggered()2215 void MainWindow::on_actionEditNextTimeReference_triggered()
2216 {
2217 if (!capture_file_.capFile()) return;
2218 cf_find_packet_time_reference(capture_file_.capFile(), SD_FORWARD);
2219 }
2220
on_actionEditPreviousTimeReference_triggered()2221 void MainWindow::on_actionEditPreviousTimeReference_triggered()
2222 {
2223 if (!capture_file_.capFile()) return;
2224 cf_find_packet_time_reference(capture_file_.capFile(), SD_BACKWARD);
2225 }
2226
on_actionEditTimeShift_triggered()2227 void MainWindow::on_actionEditTimeShift_triggered()
2228 {
2229 TimeShiftDialog *ts_dialog = new TimeShiftDialog(this, capture_file_.capFile());
2230 connect(ts_dialog, SIGNAL(finished(int)), this, SLOT(editTimeShiftFinished(int)));
2231
2232 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2233 ts_dialog, SLOT(setCaptureFile(capture_file*)));
2234 connect(ts_dialog, SIGNAL(timeShifted()), packet_list_, SLOT(applyTimeShift()));
2235
2236 ts_dialog->setWindowModality(Qt::ApplicationModal);
2237 ts_dialog->setAttribute(Qt::WA_DeleteOnClose);
2238 ts_dialog->show();
2239 }
2240
editTimeShiftFinished(int)2241 void MainWindow::editTimeShiftFinished(int)
2242 {
2243 if (capture_file_.capFile()->unsaved_changes) {
2244 updateForUnsavedChanges();
2245 }
2246 }
2247
actionAddPacketComment()2248 void MainWindow::actionAddPacketComment()
2249 {
2250 QList<int> rows = selectedRows();
2251 if (rows.count() == 0)
2252 return;
2253
2254 frame_data * fdata = frameDataForRow(rows.at(0));
2255 if (! fdata)
2256 return;
2257
2258 PacketCommentDialog* pc_dialog;
2259 pc_dialog = new PacketCommentDialog(false, this, NULL);
2260 connect(pc_dialog, &QDialog::finished, std::bind(&MainWindow::addPacketCommentFinished, this, pc_dialog, std::placeholders::_1));
2261 pc_dialog->setWindowModality(Qt::ApplicationModal);
2262 pc_dialog->setAttribute(Qt::WA_DeleteOnClose);
2263 pc_dialog->show();
2264 }
2265
addPacketCommentFinished(PacketCommentDialog * pc_dialog _U_,int result _U_)2266 void MainWindow::addPacketCommentFinished(PacketCommentDialog* pc_dialog _U_, int result _U_)
2267 {
2268 if (result == QDialog::Accepted) {
2269 packet_list_->addPacketComment(pc_dialog->text());
2270 updateForUnsavedChanges();
2271 }
2272 }
2273
actionEditPacketComment()2274 void MainWindow::actionEditPacketComment()
2275 {
2276 QList<int> rows = selectedRows();
2277 if (rows.count() != 1)
2278 return;
2279
2280 QAction *ra = qobject_cast<QAction*>(sender());
2281 guint nComment = ra->data().toUInt();
2282 PacketCommentDialog* pc_dialog;
2283 pc_dialog = new PacketCommentDialog(true, this, packet_list_->getPacketComment(nComment));
2284 connect(pc_dialog, &QDialog::finished, std::bind(&MainWindow::editPacketCommentFinished, this, pc_dialog, std::placeholders::_1, nComment));
2285 pc_dialog->setWindowModality(Qt::ApplicationModal);
2286 pc_dialog->setAttribute(Qt::WA_DeleteOnClose);
2287 pc_dialog->show();
2288 }
2289
editPacketCommentFinished(PacketCommentDialog * pc_dialog _U_,int result _U_,guint nComment)2290 void MainWindow::editPacketCommentFinished(PacketCommentDialog* pc_dialog _U_, int result _U_, guint nComment)
2291 {
2292 if (result == QDialog::Accepted) {
2293 packet_list_->setPacketComment(nComment, pc_dialog->text());
2294 updateForUnsavedChanges();
2295 }
2296 }
2297
actionDeletePacketComment()2298 void MainWindow::actionDeletePacketComment()
2299 {
2300 QAction *ra = qobject_cast<QAction*>(sender());
2301 guint nComment = ra->data().toUInt();
2302 packet_list_->setPacketComment(nComment, QString(""));
2303 updateForUnsavedChanges();
2304 }
2305
actionDeleteCommentsFromPackets()2306 void MainWindow::actionDeleteCommentsFromPackets()
2307 {
2308 packet_list_->deleteCommentsFromPackets();
2309 updateForUnsavedChanges();
2310 }
2311
on_actionDeleteAllPacketComments_triggered()2312 void MainWindow::on_actionDeleteAllPacketComments_triggered()
2313 {
2314 QMessageBox *msg_dialog = new QMessageBox();
2315 connect(msg_dialog, SIGNAL(finished(int)), this, SLOT(deleteAllPacketCommentsFinished(int)));
2316
2317 msg_dialog->setIcon(QMessageBox::Question);
2318 msg_dialog->setText(tr("Are you sure you want to remove all packet comments?"));
2319
2320 msg_dialog->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
2321 msg_dialog->setDefaultButton(QMessageBox::Ok);
2322
2323 msg_dialog->setWindowModality(Qt::ApplicationModal);
2324 msg_dialog->setAttribute(Qt::WA_DeleteOnClose);
2325 msg_dialog->show();
2326 }
2327
deleteAllPacketCommentsFinished(int result)2328 void MainWindow::deleteAllPacketCommentsFinished(int result)
2329 {
2330 if (result == QMessageBox::Ok) {
2331 /* XXX Do we need a wait/hourglass for large files? */
2332 packet_list_->deleteAllPacketComments();
2333 updateForUnsavedChanges();
2334 }
2335 }
2336
on_actionEditConfigurationProfiles_triggered()2337 void MainWindow::on_actionEditConfigurationProfiles_triggered()
2338 {
2339 ProfileDialog *cp_dialog = new ProfileDialog();
2340 cp_dialog->setWindowModality(Qt::ApplicationModal);
2341 cp_dialog->setAttribute(Qt::WA_DeleteOnClose);
2342 cp_dialog->show();
2343 }
2344
showPreferencesDialog(QString module_name)2345 void MainWindow::showPreferencesDialog(QString module_name)
2346 {
2347 PreferencesDialog *pref_dialog = new PreferencesDialog(this);
2348 connect(pref_dialog, SIGNAL(destroyed(QObject*)), wsApp, SLOT(flushAppSignals()));
2349 saveWindowGeometry(); // Save in case the layout panes are rearranged
2350
2351 pref_dialog->setPane(module_name);
2352 pref_dialog->setWindowModality(Qt::ApplicationModal);
2353 pref_dialog->setAttribute(Qt::WA_DeleteOnClose);
2354 pref_dialog->show();
2355 }
2356
on_actionEditPreferences_triggered()2357 void MainWindow::on_actionEditPreferences_triggered()
2358 {
2359 showPreferencesDialog(PrefsModel::typeToString(PrefsModel::Appearance));
2360 }
2361
2362 // View Menu
2363
showHideMainWidgets(QAction * action)2364 void MainWindow::showHideMainWidgets(QAction *action)
2365 {
2366 if (!action) {
2367 return;
2368 }
2369 bool show = action->isChecked();
2370 QWidget *widget = action->data().value<QWidget*>();
2371
2372 // We may have come from the toolbar context menu, so check/uncheck each
2373 // action as well.
2374 if (widget == main_ui_->mainToolBar) {
2375 recent.main_toolbar_show = show;
2376 main_ui_->actionViewMainToolbar->setChecked(show);
2377 } else if (widget == main_ui_->displayFilterToolBar) {
2378 recent.filter_toolbar_show = show;
2379 main_ui_->actionViewFilterToolbar->setChecked(show);
2380 #if defined(HAVE_LIBNL) && defined(HAVE_NL80211)
2381 } else if (widget == main_ui_->wirelessToolBar) {
2382 recent.wireless_toolbar_show = show;
2383 main_ui_->actionViewWirelessToolbar->setChecked(show);
2384 #endif
2385 } else if (widget == main_ui_->statusBar) {
2386 recent.statusbar_show = show;
2387 main_ui_->actionViewStatusBar->setChecked(show);
2388 } else if (widget == packet_list_) {
2389 recent.packet_list_show = show;
2390 main_ui_->actionViewPacketList->setChecked(show);
2391 } else if (widget == proto_tree_) {
2392 recent.tree_view_show = show;
2393 main_ui_->actionViewPacketDetails->setChecked(show);
2394 } else if (widget == byte_view_tab_) {
2395 recent.byte_view_show = show;
2396 main_ui_->actionViewPacketBytes->setChecked(show);
2397 } else if (widget == packet_diagram_) {
2398 recent.packet_diagram_show = show;
2399 main_ui_->actionViewPacketDiagram->setChecked(show);
2400 } else {
2401 foreach(QAction *action, main_ui_->menuInterfaceToolbars->actions()) {
2402 QToolBar *toolbar = action->data().value<QToolBar *>();
2403 if (widget == toolbar) {
2404 GList *entry = g_list_find_custom(recent.interface_toolbars, action->text().toUtf8(), (GCompareFunc)strcmp);
2405 if (show && !entry) {
2406 recent.interface_toolbars = g_list_append(recent.interface_toolbars, g_strdup(action->text().toUtf8()));
2407 } else if (!show && entry) {
2408 recent.interface_toolbars = g_list_remove(recent.interface_toolbars, entry->data);
2409 }
2410 action->setChecked(show);
2411 }
2412 }
2413
2414 ext_toolbar_t * toolbar = VariantPointer<ext_toolbar_t>::asPtr(action->data());
2415 if (toolbar) {
2416 GList *entry = g_list_find_custom(recent.gui_additional_toolbars, toolbar->name, (GCompareFunc)strcmp);
2417 if (show && !entry) {
2418 recent.gui_additional_toolbars = g_list_append(recent.gui_additional_toolbars, g_strdup(toolbar->name));
2419 } else if (!show && entry) {
2420 recent.gui_additional_toolbars = g_list_remove(recent.gui_additional_toolbars, entry->data);
2421 }
2422 action->setChecked(show);
2423
2424 QList<QToolBar *> toolbars = findChildren<QToolBar *>();
2425 foreach(QToolBar *bar, toolbars) {
2426 AdditionalToolBar *iftoolbar = dynamic_cast<AdditionalToolBar *>(bar);
2427 if (iftoolbar && iftoolbar->menuName().compare(toolbar->name) == 0) {
2428 iftoolbar->setVisible(show);
2429 }
2430 }
2431 }
2432 }
2433
2434 if (widget) {
2435 widget->setVisible(show);
2436 }
2437 }
2438
setTimestampFormat(QAction * action)2439 void MainWindow::setTimestampFormat(QAction *action)
2440 {
2441 if (!action) {
2442 return;
2443 }
2444 ts_type tsf = action->data().value<ts_type>();
2445 if (recent.gui_time_format != tsf) {
2446 timestamp_set_type(tsf);
2447 recent.gui_time_format = tsf;
2448
2449 if (packet_list_) {
2450 packet_list_->resetColumns();
2451 }
2452 if (capture_file_.capFile()) {
2453 /* This call adjusts column width */
2454 cf_timestamp_auto_precision(capture_file_.capFile());
2455 }
2456 }
2457 }
2458
setTimestampPrecision(QAction * action)2459 void MainWindow::setTimestampPrecision(QAction *action)
2460 {
2461 if (!action) {
2462 return;
2463 }
2464 ts_precision tsp = action->data().value<ts_precision>();
2465 if (recent.gui_time_precision != tsp) {
2466 /* the actual precision will be set in packet_list_queue_draw() below */
2467 timestamp_set_precision(tsp);
2468 recent.gui_time_precision = tsp;
2469
2470 if (packet_list_) {
2471 packet_list_->resetColumns();
2472 }
2473 if (capture_file_.capFile()) {
2474 /* This call adjusts column width */
2475 cf_timestamp_auto_precision(capture_file_.capFile());
2476 }
2477 }
2478 }
2479
on_actionViewTimeDisplaySecondsWithHoursAndMinutes_triggered(bool checked)2480 void MainWindow::on_actionViewTimeDisplaySecondsWithHoursAndMinutes_triggered(bool checked)
2481 {
2482 if (checked) {
2483 recent.gui_seconds_format = TS_SECONDS_HOUR_MIN_SEC;
2484 } else {
2485 recent.gui_seconds_format = TS_SECONDS_DEFAULT;
2486 }
2487 timestamp_set_seconds_type(recent.gui_seconds_format);
2488
2489 if (packet_list_) {
2490 packet_list_->resetColumns();
2491 }
2492 if (capture_file_.capFile()) {
2493 /* This call adjusts column width */
2494 cf_timestamp_auto_precision(capture_file_.capFile());
2495 }
2496 }
2497
on_actionViewEditResolvedName_triggered()2498 void MainWindow::on_actionViewEditResolvedName_triggered()
2499 {
2500 //int column = packet_list_->selectedColumn();
2501 int column = -1;
2502
2503 if (packet_list_->currentIndex().isValid()) {
2504 column = packet_list_->currentIndex().column();
2505 }
2506
2507 main_ui_->addressEditorFrame->editAddresses(capture_file_, column);
2508 showAccordionFrame(main_ui_->addressEditorFrame);
2509 }
2510
setNameResolution()2511 void MainWindow::setNameResolution()
2512 {
2513 gbl_resolv_flags.mac_name = main_ui_->actionViewNameResolutionPhysical->isChecked() ? TRUE : FALSE;
2514 gbl_resolv_flags.network_name = main_ui_->actionViewNameResolutionNetwork->isChecked() ? TRUE : FALSE;
2515 gbl_resolv_flags.transport_name = main_ui_->actionViewNameResolutionTransport->isChecked() ? TRUE : FALSE;
2516
2517 if (packet_list_) {
2518 packet_list_->resetColumns();
2519 }
2520 wsApp->emitAppSignal(WiresharkApplication::NameResolutionChanged);
2521 }
2522
on_actionViewNameResolutionPhysical_triggered()2523 void MainWindow::on_actionViewNameResolutionPhysical_triggered()
2524 {
2525 setNameResolution();
2526 }
2527
on_actionViewNameResolutionNetwork_triggered()2528 void MainWindow::on_actionViewNameResolutionNetwork_triggered()
2529 {
2530 setNameResolution();
2531 }
2532
on_actionViewNameResolutionTransport_triggered()2533 void MainWindow::on_actionViewNameResolutionTransport_triggered()
2534 {
2535 setNameResolution();
2536 }
2537
zoomText()2538 void MainWindow::zoomText()
2539 {
2540 wsApp->zoomTextFont(recent.gui_zoom_level);
2541 }
2542
on_actionViewZoomIn_triggered()2543 void MainWindow::on_actionViewZoomIn_triggered()
2544 {
2545 recent.gui_zoom_level++;
2546 zoomText();
2547 }
2548
on_actionViewZoomOut_triggered()2549 void MainWindow::on_actionViewZoomOut_triggered()
2550 {
2551 recent.gui_zoom_level--;
2552 zoomText();
2553 }
2554
on_actionViewNormalSize_triggered()2555 void MainWindow::on_actionViewNormalSize_triggered()
2556 {
2557 recent.gui_zoom_level = 0;
2558 zoomText();
2559 }
2560
on_actionViewColorizePacketList_triggered(bool checked)2561 void MainWindow::on_actionViewColorizePacketList_triggered(bool checked) {
2562 recent.packet_list_colorize = checked;
2563 packet_list_recolor_packets();
2564 packet_list_->resetColorized();
2565 }
2566
on_actionViewColoringRules_triggered()2567 void MainWindow::on_actionViewColoringRules_triggered()
2568 {
2569 ColoringRulesDialog *coloring_rules_dialog = new ColoringRulesDialog(this);
2570 connect(coloring_rules_dialog, SIGNAL(accepted()),
2571 packet_list_, SLOT(recolorPackets()));
2572 connect(coloring_rules_dialog, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)),
2573 this, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)));
2574
2575 coloring_rules_dialog->setWindowModality(Qt::ApplicationModal);
2576 coloring_rules_dialog->setAttribute(Qt::WA_DeleteOnClose);
2577 coloring_rules_dialog->show();
2578 }
2579
2580 // actionViewColorizeConversation1 - 10
colorizeConversation(bool create_rule)2581 void MainWindow::colorizeConversation(bool create_rule)
2582 {
2583 QAction *colorize_action = qobject_cast<QAction *>(sender());
2584 if (!colorize_action) return;
2585
2586 if (capture_file_.capFile() && selectedRows().count() > 0) {
2587 packet_info *pi = capture_file_.packetInfo();
2588 guint8 cc_num = colorize_action->data().toUInt();
2589 gchar *filter = conversation_filter_from_packet(pi);
2590 if (filter == NULL) {
2591 wsApp->pushStatus(WiresharkApplication::TemporaryStatus, tr("Unable to build conversation filter."));
2592 return;
2593 }
2594
2595 if (create_rule) {
2596 ColoringRulesDialog coloring_rules_dialog(this, filter);
2597 connect(&coloring_rules_dialog, SIGNAL(accepted()),
2598 packet_list_, SLOT(recolorPackets()));
2599 connect(&coloring_rules_dialog, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)),
2600 this, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)));
2601 coloring_rules_dialog.exec();
2602 } else {
2603 gchar *err_msg = NULL;
2604 if (!color_filters_set_tmp(cc_num, filter, FALSE, &err_msg)) {
2605 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
2606 g_free(err_msg);
2607 }
2608 packet_list_->recolorPackets();
2609 }
2610 }
2611 setMenusForSelectedPacket();
2612 }
2613
colorizeActionTriggered()2614 void MainWindow::colorizeActionTriggered()
2615 {
2616 QByteArray filter;
2617 int color_number = -1;
2618
2619 ConversationAction *conv_action = qobject_cast<ConversationAction *>(sender());
2620 if (conv_action) {
2621 filter = conv_action->filter();
2622 color_number = conv_action->colorNumber();
2623 } else {
2624 ColorizeAction *colorize_action = qobject_cast<ColorizeAction *>(sender());
2625 if (colorize_action) {
2626 filter = colorize_action->filter();
2627 color_number = colorize_action->colorNumber();
2628 }
2629 }
2630
2631 colorizeWithFilter(filter, color_number);
2632 }
2633
colorizeWithFilter(QByteArray filter,int color_number)2634 void MainWindow::colorizeWithFilter(QByteArray filter, int color_number)
2635 {
2636 if (filter.isEmpty()) return;
2637
2638 if (color_number > 0) {
2639 // Assume "Color X"
2640 gchar *err_msg = NULL;
2641 if (!color_filters_set_tmp(color_number, filter.constData(), FALSE, &err_msg)) {
2642 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
2643 g_free(err_msg);
2644 }
2645 packet_list_->recolorPackets();
2646 } else {
2647 // New coloring rule
2648 ColoringRulesDialog coloring_rules_dialog(window(), filter);
2649 connect(&coloring_rules_dialog, SIGNAL(accepted()),
2650 packet_list_, SLOT(recolorPackets()));
2651 connect(&coloring_rules_dialog, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)),
2652 this, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)));
2653 coloring_rules_dialog.exec();
2654 }
2655 main_ui_->actionViewColorizeResetColorization->setEnabled(tmp_color_filters_used());
2656 }
2657
on_actionViewColorizeResetColorization_triggered()2658 void MainWindow::on_actionViewColorizeResetColorization_triggered()
2659 {
2660 gchar *err_msg = NULL;
2661 if (!color_filters_reset_tmp(&err_msg)) {
2662 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
2663 g_free(err_msg);
2664 }
2665 packet_list_->recolorPackets();
2666 setMenusForSelectedPacket();
2667 }
2668
on_actionViewColorizeNewColoringRule_triggered()2669 void MainWindow::on_actionViewColorizeNewColoringRule_triggered()
2670 {
2671 colorizeConversation(true);
2672 }
2673
on_actionViewResetLayout_triggered()2674 void MainWindow::on_actionViewResetLayout_triggered()
2675 {
2676 recent.gui_geometry_main_upper_pane = 0;
2677 recent.gui_geometry_main_lower_pane = 0;
2678
2679 applyRecentPaneGeometry();
2680 }
2681
on_actionViewResizeColumns_triggered()2682 void MainWindow::on_actionViewResizeColumns_triggered()
2683 {
2684 if (! packet_list_->model())
2685 return;
2686 for (int col = 0; col < packet_list_->model()->columnCount(); col++) {
2687 packet_list_->resizeColumnToContents(col);
2688 recent_set_column_width(col, packet_list_->columnWidth(col));
2689 }
2690 }
2691
openPacketDialog(bool from_reference)2692 void MainWindow::openPacketDialog(bool from_reference)
2693 {
2694 frame_data * fdata = Q_NULLPTR;
2695
2696 /* Find the frame for which we're popping up a dialog */
2697 if (from_reference) {
2698 guint32 framenum = fvalue_get_uinteger(&(capture_file_.capFile()->finfo_selected->value));
2699 if (framenum == 0)
2700 return;
2701
2702 fdata = frame_data_sequence_find(capture_file_.capFile()->provider.frames, framenum);
2703 } else if (selectedRows().count() == 1) {
2704 fdata = frameDataForRow(selectedRows().at(0));
2705 } else if (selectedRows().count() > 1)
2706 return;
2707
2708 /* If we have a frame, pop up the dialog */
2709 if (fdata) {
2710 PacketDialog *packet_dialog = new PacketDialog(*this, capture_file_, fdata);
2711
2712 connect(packet_dialog, SIGNAL(showProtocolPreferences(QString)),
2713 this, SLOT(showPreferencesDialog(QString)));
2714 connect(packet_dialog, SIGNAL(editProtocolPreference(preference*, pref_module*)),
2715 main_ui_->preferenceEditorFrame, SLOT(editPreference(preference*, pref_module*)));
2716
2717 connect(this, SIGNAL(closePacketDialogs()),
2718 packet_dialog, SLOT(close()));
2719 zoomText(); // Emits wsApp->zoomMonospaceFont(QFont)
2720
2721 packet_dialog->show();
2722 }
2723 }
2724
on_actionViewInternalsConversationHashTables_triggered()2725 void MainWindow::on_actionViewInternalsConversationHashTables_triggered()
2726 {
2727 ConversationHashTablesDialog *conversation_hash_tables_dlg = new ConversationHashTablesDialog(this);
2728 conversation_hash_tables_dlg->show();
2729 }
2730
on_actionViewInternalsDissectorTables_triggered()2731 void MainWindow::on_actionViewInternalsDissectorTables_triggered()
2732 {
2733 DissectorTablesDialog *dissector_tables_dlg = new DissectorTablesDialog(this);
2734 dissector_tables_dlg->show();
2735 }
2736
on_actionViewInternalsSupportedProtocols_triggered()2737 void MainWindow::on_actionViewInternalsSupportedProtocols_triggered()
2738 {
2739 SupportedProtocolsDialog *supported_protocols_dlg = new SupportedProtocolsDialog(this);
2740 supported_protocols_dlg->show();
2741 }
2742
on_actionViewShowPacketInNewWindow_triggered()2743 void MainWindow::on_actionViewShowPacketInNewWindow_triggered()
2744 {
2745 openPacketDialog();
2746 }
2747
2748 // This is only used in ProtoTree. Defining it here makes more sense.
on_actionContextShowLinkedPacketInNewWindow_triggered()2749 void MainWindow::on_actionContextShowLinkedPacketInNewWindow_triggered()
2750 {
2751 openPacketDialog(true);
2752 }
2753
on_actionViewReload_triggered()2754 void MainWindow::on_actionViewReload_triggered()
2755 {
2756 capture_file *cf = CaptureFile::globalCapFile();
2757
2758 if (cf->unsaved_changes) {
2759 QString before_what(tr(" before reloading the file"));
2760 if (!testCaptureFileClose(before_what, Reload))
2761 return;
2762 }
2763
2764 cf_reload(cf);
2765 }
2766
on_actionViewReload_as_File_Format_or_Capture_triggered()2767 void MainWindow::on_actionViewReload_as_File_Format_or_Capture_triggered()
2768 {
2769 capture_file *cf = CaptureFile::globalCapFile();
2770
2771 if (cf->unsaved_changes) {
2772 QString before_what(tr(" before reloading the file"));
2773 if (!testCaptureFileClose(before_what, Reload))
2774 return;
2775 }
2776
2777 if (cf->open_type == WTAP_TYPE_AUTO)
2778 cf->open_type = open_info_name_to_type("MIME Files Format");
2779 else /* TODO: This should be latest format chosen by user */
2780 cf->open_type = WTAP_TYPE_AUTO;
2781
2782 cf_reload(cf);
2783 }
2784
2785
2786 // Expand / collapse slots in proto_tree
2787
2788 // Go Menu
2789
2790 // Analyze Menu
2791
filterMenuAboutToShow()2792 void MainWindow::filterMenuAboutToShow()
2793 {
2794 QMenu * menu = qobject_cast<QMenu *>(sender());
2795 QString field_filter;
2796
2797 if (capture_file_.capFile() && capture_file_.capFile()->finfo_selected) {
2798 char *tmp_field = proto_construct_match_selected_string(capture_file_.capFile()->finfo_selected,
2799 capture_file_.capFile()->edt);
2800 field_filter = QString(tmp_field);
2801 wmem_free(NULL, tmp_field);
2802 }
2803 bool enable = ! field_filter.isEmpty();
2804 bool prepare = menu->objectName().compare("menuPrepareAFilter") == 0;
2805
2806 menu->clear();
2807 QActionGroup * group = FilterAction::createFilterGroup(field_filter, prepare, enable, menu);
2808 menu->addActions(group->actions());
2809 }
2810
matchFieldFilter(FilterAction::Action action,FilterAction::ActionType filter_type)2811 void MainWindow::matchFieldFilter(FilterAction::Action action, FilterAction::ActionType filter_type)
2812 {
2813 QString field_filter;
2814
2815 if (packet_list_->contextMenuActive() || packet_list_->hasFocus()) {
2816 field_filter = packet_list_->getFilterFromRowAndColumn(packet_list_->currentIndex());
2817 } else if (capture_file_.capFile() && capture_file_.capFile()->finfo_selected) {
2818 char *tmp_field = proto_construct_match_selected_string(capture_file_.capFile()->finfo_selected,
2819 capture_file_.capFile()->edt);
2820 field_filter = QString(tmp_field);
2821 wmem_free(NULL, tmp_field);
2822 }
2823
2824 if (field_filter.isEmpty()) {
2825 QString err = tr("No filter available. Try another %1.").arg(packet_list_->contextMenuActive() ? tr("column") : tr("item"));
2826 wsApp->pushStatus(WiresharkApplication::TemporaryStatus, err);
2827 return;
2828 }
2829
2830 setDisplayFilter(field_filter, action, filter_type);
2831 }
2832
setDisplayFilter(QString filter,FilterAction::Action action,FilterAction::ActionType filterType)2833 void MainWindow::setDisplayFilter(QString filter, FilterAction::Action action, FilterAction::ActionType filterType)
2834 {
2835 emit filterAction(filter, action, filterType);
2836 }
2837
on_actionAnalyzeDisplayFilters_triggered()2838 void MainWindow::on_actionAnalyzeDisplayFilters_triggered()
2839 {
2840 if (!display_filter_dlg_) {
2841 display_filter_dlg_ = new FilterDialog(this, FilterDialog::DisplayFilter);
2842 }
2843 display_filter_dlg_->show();
2844 display_filter_dlg_->raise();
2845 display_filter_dlg_->activateWindow();
2846 }
2847
2848 struct epan_uat;
on_actionAnalyzeDisplayFilterMacros_triggered()2849 void MainWindow::on_actionAnalyzeDisplayFilterMacros_triggered()
2850 {
2851 struct epan_uat* dfm_uat;
2852 dfilter_macro_get_uat(&dfm_uat);
2853 UatDialog *uat_dlg = new UatDialog(parentWidget(), dfm_uat);
2854 connect(uat_dlg, SIGNAL(destroyed(QObject*)), wsApp, SLOT(flushAppSignals()));
2855
2856 uat_dlg->setWindowModality(Qt::ApplicationModal);
2857 uat_dlg->setAttribute(Qt::WA_DeleteOnClose);
2858 uat_dlg->show();
2859 }
2860
on_actionAnalyzeCreateAColumn_triggered()2861 void MainWindow::on_actionAnalyzeCreateAColumn_triggered()
2862 {
2863 if (capture_file_.capFile() != 0 && capture_file_.capFile()->finfo_selected != 0) {
2864 header_field_info *hfinfo = capture_file_.capFile()->finfo_selected->hfinfo;
2865 int col = column_prefs_has_custom(hfinfo->abbrev);
2866 if (col == -1) {
2867 insertColumn(hfinfo->name, hfinfo->abbrev);
2868 } else {
2869 QString status;
2870 if (QString(hfinfo->name) == get_column_title(col)) {
2871 status = tr("The \"%1\" column already exists.").arg(hfinfo->name);
2872 } else {
2873 status = tr("The \"%1\" column already exists as \"%2\".").arg(hfinfo->name).arg(get_column_title(col));
2874 }
2875 wsApp->pushStatus(WiresharkApplication::TemporaryStatus, status);
2876
2877 if (!get_column_visible(col)) {
2878 packet_list_->setColumnHidden(col, false);
2879 set_column_visible(col, TRUE);
2880 prefs_main_write();
2881 }
2882 }
2883 }
2884 }
2885
applyConversationFilter()2886 void MainWindow::applyConversationFilter()
2887 {
2888 ConversationAction *conv_action = qobject_cast<ConversationAction*>(sender());
2889 if (!conv_action) return;
2890
2891 packet_info *pinfo = capture_file_.packetInfo();
2892 if (!pinfo) return;
2893
2894 QByteArray conv_filter = conv_action->filter();
2895 if (conv_filter.isEmpty()) return;
2896
2897 if (conv_action->isFilterValid(pinfo)) {
2898
2899 df_combo_box_->lineEdit()->setText(conv_filter);
2900 df_combo_box_->applyDisplayFilter();
2901 }
2902 }
2903
applyExportObject()2904 void MainWindow::applyExportObject()
2905 {
2906 ExportObjectAction *export_action = qobject_cast<ExportObjectAction*>(sender());
2907 if (!export_action)
2908 return;
2909
2910 ExportObjectDialog* export_dialog = new ExportObjectDialog(*this, capture_file_, export_action->exportObject());
2911 export_dialog->setWindowModality(Qt::ApplicationModal);
2912 export_dialog->setAttribute(Qt::WA_DeleteOnClose);
2913 export_dialog->show();
2914 }
2915
on_actionAnalyzeEnabledProtocols_triggered()2916 void MainWindow::on_actionAnalyzeEnabledProtocols_triggered()
2917 {
2918 EnabledProtocolsDialog *enable_proto_dialog = new EnabledProtocolsDialog(this);
2919 connect(enable_proto_dialog, SIGNAL(destroyed(QObject*)), wsApp, SLOT(flushAppSignals()));
2920
2921 enable_proto_dialog->setWindowModality(Qt::ApplicationModal);
2922 enable_proto_dialog->setAttribute(Qt::WA_DeleteOnClose);
2923 enable_proto_dialog->show();
2924 }
2925
on_actionAnalyzeDecodeAs_triggered()2926 void MainWindow::on_actionAnalyzeDecodeAs_triggered()
2927 {
2928 QAction *da_action = qobject_cast<QAction*>(sender());
2929 bool create_new = da_action && da_action->property("create_new").toBool();
2930
2931 DecodeAsDialog *da_dialog = new DecodeAsDialog(this, capture_file_.capFile(), create_new);
2932 connect(da_dialog, SIGNAL(destroyed(QObject*)), wsApp, SLOT(flushAppSignals()));
2933
2934 da_dialog->setWindowModality(Qt::ApplicationModal);
2935 da_dialog->setAttribute(Qt::WA_DeleteOnClose);
2936 da_dialog->show();
2937 }
2938
on_actionAnalyzeReloadLuaPlugins_triggered()2939 void MainWindow::on_actionAnalyzeReloadLuaPlugins_triggered()
2940 {
2941 reloadLuaPlugins();
2942 }
2943
openFollowStreamDialog(follow_type_t type,guint stream_num,guint sub_stream_num,bool use_stream_index)2944 void MainWindow::openFollowStreamDialog(follow_type_t type, guint stream_num, guint sub_stream_num, bool use_stream_index) {
2945 FollowStreamDialog *fsd = new FollowStreamDialog(*this, capture_file_, type);
2946 connect(fsd, SIGNAL(updateFilter(QString, bool)), this, SLOT(filterPackets(QString, bool)));
2947 connect(fsd, SIGNAL(goToPacket(int)), packet_list_, SLOT(goToPacket(int)));
2948 fsd->addCodecs(text_codec_map_);
2949 fsd->show();
2950 if (use_stream_index) {
2951 // If a specific conversation was requested, then ignore any previous
2952 // display filters and display all related packets.
2953 fsd->follow("", true, stream_num, sub_stream_num);
2954 } else {
2955 fsd->follow(getFilter());
2956 }
2957 }
2958
openFollowStreamDialogForType(follow_type_t type)2959 void MainWindow::openFollowStreamDialogForType(follow_type_t type) {
2960 openFollowStreamDialog(type, 0, 0, false);
2961 }
2962
on_actionAnalyzeFollowTCPStream_triggered()2963 void MainWindow::on_actionAnalyzeFollowTCPStream_triggered()
2964 {
2965 openFollowStreamDialogForType(FOLLOW_TCP);
2966 }
2967
on_actionAnalyzeFollowUDPStream_triggered()2968 void MainWindow::on_actionAnalyzeFollowUDPStream_triggered()
2969 {
2970 openFollowStreamDialogForType(FOLLOW_UDP);
2971 }
2972
on_actionAnalyzeFollowDCCPStream_triggered()2973 void MainWindow::on_actionAnalyzeFollowDCCPStream_triggered()
2974 {
2975 openFollowStreamDialogForType(FOLLOW_DCCP);
2976 }
2977
on_actionAnalyzeFollowTLSStream_triggered()2978 void MainWindow::on_actionAnalyzeFollowTLSStream_triggered()
2979 {
2980 openFollowStreamDialogForType(FOLLOW_TLS);
2981 }
2982
on_actionAnalyzeFollowHTTPStream_triggered()2983 void MainWindow::on_actionAnalyzeFollowHTTPStream_triggered()
2984 {
2985 openFollowStreamDialogForType(FOLLOW_HTTP);
2986 }
2987
on_actionAnalyzeFollowHTTP2Stream_triggered()2988 void MainWindow::on_actionAnalyzeFollowHTTP2Stream_triggered()
2989 {
2990 openFollowStreamDialogForType(FOLLOW_HTTP2);
2991 }
2992
on_actionAnalyzeFollowQUICStream_triggered()2993 void MainWindow::on_actionAnalyzeFollowQUICStream_triggered()
2994 {
2995 openFollowStreamDialogForType(FOLLOW_QUIC);
2996 }
2997
on_actionAnalyzeFollowSIPCall_triggered()2998 void MainWindow::on_actionAnalyzeFollowSIPCall_triggered()
2999 {
3000 openFollowStreamDialogForType(FOLLOW_SIP);
3001 }
3002
openSCTPAllAssocsDialog()3003 void MainWindow::openSCTPAllAssocsDialog()
3004 {
3005 SCTPAllAssocsDialog *sctp_dialog = new SCTPAllAssocsDialog(this, capture_file_.capFile());
3006 connect(sctp_dialog, SIGNAL(filterPackets(QString, bool)),
3007 this, SLOT(filterPackets(QString, bool)));
3008 connect(this, SIGNAL(setCaptureFile(capture_file*)),
3009 sctp_dialog, SLOT(setCaptureFile(capture_file*)));
3010 sctp_dialog->fillTable();
3011
3012 if (sctp_dialog->isMinimized() == true)
3013 {
3014 sctp_dialog->showNormal();
3015 }
3016 else
3017 {
3018 sctp_dialog->show();
3019 }
3020
3021 sctp_dialog->raise();
3022 sctp_dialog->activateWindow();
3023 }
3024
on_actionSCTPShowAllAssociations_triggered()3025 void MainWindow::on_actionSCTPShowAllAssociations_triggered()
3026 {
3027 openSCTPAllAssocsDialog();
3028 }
3029
on_actionSCTPAnalyseThisAssociation_triggered()3030 void MainWindow::on_actionSCTPAnalyseThisAssociation_triggered()
3031 {
3032 const sctp_assoc_info_t* assoc = SCTPAssocAnalyseDialog::findAssocForPacket(capture_file_.capFile());
3033 if (!assoc) {
3034 return;
3035 }
3036 SCTPAssocAnalyseDialog *sctp_analyse = new SCTPAssocAnalyseDialog(this, assoc, capture_file_.capFile());
3037 connect(sctp_analyse, SIGNAL(filterPackets(QString, bool)),
3038 this, SLOT(filterPackets(QString, bool)));
3039
3040 if (sctp_analyse->isMinimized() == true)
3041 {
3042 sctp_analyse->showNormal();
3043 }
3044 else
3045 {
3046 sctp_analyse->show();
3047 }
3048
3049 sctp_analyse->raise();
3050 sctp_analyse->activateWindow();
3051 }
3052
on_actionSCTPFilterThisAssociation_triggered()3053 void MainWindow::on_actionSCTPFilterThisAssociation_triggered()
3054 {
3055 const sctp_assoc_info_t* assoc = SCTPAssocAnalyseDialog::findAssocForPacket(capture_file_.capFile());
3056 if (assoc) {
3057 QString newFilter = QString("sctp.assoc_index==%1").arg(assoc->assoc_id);
3058 assoc = NULL;
3059 emit filterPackets(newFilter, false);
3060 }
3061 }
3062
3063 // -z wlan,stat
statCommandWlanStatistics(const char * arg,void *)3064 void MainWindow::statCommandWlanStatistics(const char *arg, void *)
3065 {
3066 WlanStatisticsDialog *wlan_stats_dlg = new WlanStatisticsDialog(*this, capture_file_, arg);
3067 connect(wlan_stats_dlg, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)),
3068 this, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)));
3069 wlan_stats_dlg->show();
3070 }
3071
on_actionWirelessWlanStatistics_triggered()3072 void MainWindow::on_actionWirelessWlanStatistics_triggered()
3073 {
3074 statCommandWlanStatistics(NULL, NULL);
3075 }
3076
3077 // -z expert
statCommandExpertInfo(const char *,void *)3078 void MainWindow::statCommandExpertInfo(const char *, void *)
3079 {
3080 ExpertInfoDialog *expert_dialog = new ExpertInfoDialog(*this, capture_file_);
3081 const DisplayFilterEdit *df_edit = dynamic_cast<DisplayFilterEdit *>(df_combo_box_->lineEdit());
3082
3083 expert_dialog->setDisplayFilter(df_edit->text());
3084
3085 connect(expert_dialog->getExpertInfoView(), SIGNAL(goToPacket(int, int)),
3086 packet_list_, SLOT(goToPacket(int, int)));
3087 connect(expert_dialog, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)),
3088 this, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)));
3089
3090 expert_dialog->show();
3091 }
3092
on_actionAnalyzeExpertInfo_triggered()3093 void MainWindow::on_actionAnalyzeExpertInfo_triggered()
3094 {
3095 statCommandExpertInfo(NULL, NULL);
3096 }
3097
3098
3099 // Next / previous / first / last slots in packet_list
3100
3101 // Statistics Menu
3102
on_actionStatisticsFlowGraph_triggered()3103 void MainWindow::on_actionStatisticsFlowGraph_triggered()
3104 {
3105 SequenceDialog *sequence_dialog = new SequenceDialog(*this, capture_file_);
3106 sequence_dialog->show();
3107 }
3108
openTcpStreamDialog(int graph_type)3109 void MainWindow::openTcpStreamDialog(int graph_type)
3110 {
3111 TCPStreamDialog *stream_dialog = new TCPStreamDialog(this, capture_file_.capFile(), (tcp_graph_type)graph_type);
3112 connect(stream_dialog, SIGNAL(goToPacket(int)),
3113 packet_list_, SLOT(goToPacket(int)));
3114 connect(this, SIGNAL(setCaptureFile(capture_file*)),
3115 stream_dialog, SLOT(setCaptureFile(capture_file*)));
3116 if (stream_dialog->result() == QDialog::Accepted) {
3117 stream_dialog->show();
3118 }
3119 }
3120
on_actionStatisticsTcpStreamStevens_triggered()3121 void MainWindow::on_actionStatisticsTcpStreamStevens_triggered()
3122 {
3123 openTcpStreamDialog(GRAPH_TSEQ_STEVENS);
3124 }
3125
on_actionStatisticsTcpStreamTcptrace_triggered()3126 void MainWindow::on_actionStatisticsTcpStreamTcptrace_triggered()
3127 {
3128 openTcpStreamDialog(GRAPH_TSEQ_TCPTRACE);
3129 }
3130
on_actionStatisticsTcpStreamThroughput_triggered()3131 void MainWindow::on_actionStatisticsTcpStreamThroughput_triggered()
3132 {
3133 openTcpStreamDialog(GRAPH_THROUGHPUT);
3134 }
3135
on_actionStatisticsTcpStreamRoundTripTime_triggered()3136 void MainWindow::on_actionStatisticsTcpStreamRoundTripTime_triggered()
3137 {
3138 openTcpStreamDialog(GRAPH_RTT);
3139 }
3140
on_actionStatisticsTcpStreamWindowScaling_triggered()3141 void MainWindow::on_actionStatisticsTcpStreamWindowScaling_triggered()
3142 {
3143 openTcpStreamDialog(GRAPH_WSCALE);
3144 }
3145
3146 // -z mcast,stat
statCommandMulticastStatistics(const char * arg,void *)3147 void MainWindow::statCommandMulticastStatistics(const char *arg, void *)
3148 {
3149 MulticastStatisticsDialog *mcast_stats_dlg = new MulticastStatisticsDialog(*this, capture_file_, arg);
3150 connect(mcast_stats_dlg, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)),
3151 this, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)));
3152 mcast_stats_dlg->show();
3153 }
3154
on_actionStatisticsUdpMulticastStreams_triggered()3155 void MainWindow::on_actionStatisticsUdpMulticastStreams_triggered()
3156 {
3157 statCommandMulticastStatistics(NULL, NULL);
3158 }
3159
openStatisticsTreeDialog(const gchar * abbr)3160 void MainWindow::openStatisticsTreeDialog(const gchar *abbr)
3161 {
3162 StatsTreeDialog *st_dialog = new StatsTreeDialog(*this, capture_file_, abbr);
3163 // connect(st_dialog, SIGNAL(goToPacket(int)),
3164 // packet_list_, SLOT(goToPacket(int)));
3165 st_dialog->show();
3166 }
3167
on_actionStatistics29WestTopics_Advertisements_by_Topic_triggered()3168 void MainWindow::on_actionStatistics29WestTopics_Advertisements_by_Topic_triggered()
3169 {
3170 openStatisticsTreeDialog("lbmr_topic_ads_topic");
3171 }
3172
on_actionStatistics29WestTopics_Advertisements_by_Source_triggered()3173 void MainWindow::on_actionStatistics29WestTopics_Advertisements_by_Source_triggered()
3174 {
3175 openStatisticsTreeDialog("lbmr_topic_ads_source");
3176 }
3177
on_actionStatistics29WestTopics_Advertisements_by_Transport_triggered()3178 void MainWindow::on_actionStatistics29WestTopics_Advertisements_by_Transport_triggered()
3179 {
3180 openStatisticsTreeDialog("lbmr_topic_ads_transport");
3181 }
3182
on_actionStatistics29WestTopics_Queries_by_Topic_triggered()3183 void MainWindow::on_actionStatistics29WestTopics_Queries_by_Topic_triggered()
3184 {
3185 openStatisticsTreeDialog("lbmr_topic_queries_topic");
3186 }
3187
on_actionStatistics29WestTopics_Queries_by_Receiver_triggered()3188 void MainWindow::on_actionStatistics29WestTopics_Queries_by_Receiver_triggered()
3189 {
3190 openStatisticsTreeDialog("lbmr_topic_queries_receiver");
3191 }
3192
on_actionStatistics29WestTopics_Wildcard_Queries_by_Pattern_triggered()3193 void MainWindow::on_actionStatistics29WestTopics_Wildcard_Queries_by_Pattern_triggered()
3194 {
3195 openStatisticsTreeDialog("lbmr_topic_queries_pattern");
3196 }
3197
on_actionStatistics29WestTopics_Wildcard_Queries_by_Receiver_triggered()3198 void MainWindow::on_actionStatistics29WestTopics_Wildcard_Queries_by_Receiver_triggered()
3199 {
3200 openStatisticsTreeDialog("lbmr_topic_queries_pattern_receiver");
3201 }
3202
on_actionStatistics29WestQueues_Advertisements_by_Queue_triggered()3203 void MainWindow::on_actionStatistics29WestQueues_Advertisements_by_Queue_triggered()
3204 {
3205 openStatisticsTreeDialog("lbmr_queue_ads_queue");
3206 }
3207
on_actionStatistics29WestQueues_Advertisements_by_Source_triggered()3208 void MainWindow::on_actionStatistics29WestQueues_Advertisements_by_Source_triggered()
3209 {
3210 openStatisticsTreeDialog("lbmr_queue_ads_source");
3211 }
3212
on_actionStatistics29WestQueues_Queries_by_Queue_triggered()3213 void MainWindow::on_actionStatistics29WestQueues_Queries_by_Queue_triggered()
3214 {
3215 openStatisticsTreeDialog("lbmr_queue_queries_queue");
3216 }
3217
on_actionStatistics29WestQueues_Queries_by_Receiver_triggered()3218 void MainWindow::on_actionStatistics29WestQueues_Queries_by_Receiver_triggered()
3219 {
3220 openStatisticsTreeDialog("lbmr_queue_queries_receiver");
3221 }
3222
on_actionStatistics29WestUIM_Streams_triggered()3223 void MainWindow::on_actionStatistics29WestUIM_Streams_triggered()
3224 {
3225 LBMStreamDialog *stream_dialog = new LBMStreamDialog(this, capture_file_.capFile());
3226 // connect(stream_dialog, SIGNAL(goToPacket(int)),
3227 // packet_list_, SLOT(goToPacket(int)));
3228 connect(this, SIGNAL(setCaptureFile(capture_file*)),
3229 stream_dialog, SLOT(setCaptureFile(capture_file*)));
3230 stream_dialog->show();
3231 }
3232
on_actionStatistics29WestLBTRM_triggered()3233 void MainWindow::on_actionStatistics29WestLBTRM_triggered()
3234 {
3235 LBMLBTRMTransportDialog * lbtrm_dialog = new LBMLBTRMTransportDialog(this, capture_file_.capFile());
3236 connect(lbtrm_dialog, SIGNAL(goToPacket(int)),
3237 packet_list_, SLOT(goToPacket(int)));
3238 connect(this, SIGNAL(setCaptureFile(capture_file*)),
3239 lbtrm_dialog, SLOT(setCaptureFile(capture_file*)));
3240 lbtrm_dialog->show();
3241 }
on_actionStatistics29WestLBTRU_triggered()3242 void MainWindow::on_actionStatistics29WestLBTRU_triggered()
3243 {
3244 LBMLBTRUTransportDialog * lbtru_dialog = new LBMLBTRUTransportDialog(this, capture_file_.capFile());
3245 connect(lbtru_dialog, SIGNAL(goToPacket(int)),
3246 packet_list_, SLOT(goToPacket(int)));
3247 connect(this, SIGNAL(setCaptureFile(capture_file*)),
3248 lbtru_dialog, SLOT(setCaptureFile(capture_file*)));
3249 lbtru_dialog->show();
3250 }
3251
on_actionStatisticsANCP_triggered()3252 void MainWindow::on_actionStatisticsANCP_triggered()
3253 {
3254 openStatisticsTreeDialog("ancp");
3255 }
3256
3257
on_actionStatisticsBACappInstanceId_triggered()3258 void MainWindow::on_actionStatisticsBACappInstanceId_triggered()
3259 {
3260 openStatisticsTreeDialog("bacapp_instanceid");
3261 }
3262
on_actionStatisticsBACappIP_triggered()3263 void MainWindow::on_actionStatisticsBACappIP_triggered()
3264 {
3265 openStatisticsTreeDialog("bacapp_ip");
3266 }
3267
on_actionStatisticsBACappObjectId_triggered()3268 void MainWindow::on_actionStatisticsBACappObjectId_triggered()
3269 {
3270 openStatisticsTreeDialog("bacapp_objectid");
3271 }
3272
on_actionStatisticsBACappService_triggered()3273 void MainWindow::on_actionStatisticsBACappService_triggered()
3274 {
3275 openStatisticsTreeDialog("bacapp_service");
3276 }
3277
on_actionStatisticsCollectd_triggered()3278 void MainWindow::on_actionStatisticsCollectd_triggered()
3279 {
3280 openStatisticsTreeDialog("collectd");
3281 }
3282
3283 // -z conv,...
statCommandConversations(const char * arg,void * userdata)3284 void MainWindow::statCommandConversations(const char *arg, void *userdata)
3285 {
3286 ConversationDialog *conv_dialog = new ConversationDialog(*this, capture_file_, GPOINTER_TO_INT(userdata), arg);
3287 connect(conv_dialog, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)),
3288 this, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)));
3289 connect(conv_dialog, SIGNAL(openFollowStreamDialog(follow_type_t, guint, guint)),
3290 this, SLOT(openFollowStreamDialog(follow_type_t, guint, guint)));
3291 connect(conv_dialog, SIGNAL(openTcpStreamGraph(int)),
3292 this, SLOT(openTcpStreamDialog(int)));
3293 conv_dialog->show();
3294 }
3295
on_actionStatisticsConversations_triggered()3296 void MainWindow::on_actionStatisticsConversations_triggered()
3297 {
3298 statCommandConversations(NULL, NULL);
3299 }
3300
3301 // -z endpoints,...
statCommandEndpoints(const char * arg,void * userdata)3302 void MainWindow::statCommandEndpoints(const char *arg, void *userdata)
3303 {
3304 EndpointDialog *endp_dialog = new EndpointDialog(*this, capture_file_, GPOINTER_TO_INT(userdata), arg);
3305 connect(endp_dialog, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)),
3306 this, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)));
3307 connect(endp_dialog, SIGNAL(openFollowStreamDialog(follow_type_t)),
3308 this, SLOT(openFollowStreamDialogForType(follow_type_t)));
3309 connect(endp_dialog, SIGNAL(openTcpStreamGraph(int)),
3310 this, SLOT(openTcpStreamDialog(int)));
3311 endp_dialog->show();
3312 }
3313
on_actionStatisticsEndpoints_triggered()3314 void MainWindow::on_actionStatisticsEndpoints_triggered()
3315 {
3316 statCommandEndpoints(NULL, NULL);
3317 }
3318
on_actionStatisticsHART_IP_triggered()3319 void MainWindow::on_actionStatisticsHART_IP_triggered()
3320 {
3321 openStatisticsTreeDialog("hart_ip");
3322 }
3323
on_actionStatisticsHTTPPacketCounter_triggered()3324 void MainWindow::on_actionStatisticsHTTPPacketCounter_triggered()
3325 {
3326 openStatisticsTreeDialog("http");
3327 }
3328
on_actionStatisticsHTTPRequests_triggered()3329 void MainWindow::on_actionStatisticsHTTPRequests_triggered()
3330 {
3331 openStatisticsTreeDialog("http_req");
3332 }
3333
on_actionStatisticsHTTPLoadDistribution_triggered()3334 void MainWindow::on_actionStatisticsHTTPLoadDistribution_triggered()
3335 {
3336 openStatisticsTreeDialog("http_srv");
3337 }
3338
on_actionStatisticsHTTPRequestSequences_triggered()3339 void MainWindow::on_actionStatisticsHTTPRequestSequences_triggered()
3340 {
3341 openStatisticsTreeDialog("http_seq");
3342 }
3343
on_actionStatisticsPacketLengths_triggered()3344 void MainWindow::on_actionStatisticsPacketLengths_triggered()
3345 {
3346 openStatisticsTreeDialog("plen");
3347 }
3348
3349 // -z io,stat
statCommandIOGraph(const char *,void *)3350 void MainWindow::statCommandIOGraph(const char *, void *)
3351 {
3352 const DisplayFilterEdit *df_edit = qobject_cast<DisplayFilterEdit *>(df_combo_box_->lineEdit());
3353 QString displayFilter;
3354 if (df_edit)
3355 displayFilter = df_edit->text();
3356
3357 IOGraphDialog *iog_dialog = new IOGraphDialog(*this, capture_file_, displayFilter);
3358 connect(iog_dialog, SIGNAL(goToPacket(int)), packet_list_, SLOT(goToPacket(int)));
3359 connect(this, SIGNAL(reloadFields()), iog_dialog, SLOT(reloadFields()));
3360 iog_dialog->show();
3361 }
3362
on_actionStatisticsIOGraph_triggered()3363 void MainWindow::on_actionStatisticsIOGraph_triggered()
3364 {
3365 statCommandIOGraph(NULL, NULL);
3366 }
3367
on_actionStatisticsSametime_triggered()3368 void MainWindow::on_actionStatisticsSametime_triggered()
3369 {
3370 openStatisticsTreeDialog("sametime");
3371 }
3372
on_actionStatisticsDNS_triggered()3373 void MainWindow::on_actionStatisticsDNS_triggered()
3374 {
3375 openStatisticsTreeDialog("dns");
3376 }
3377
actionStatisticsPlugin_triggered()3378 void MainWindow::actionStatisticsPlugin_triggered()
3379 {
3380 QAction* action = qobject_cast<QAction*>(sender());
3381 if (action) {
3382 openStatisticsTreeDialog(action->data().toString().toUtf8());
3383 }
3384 }
3385
on_actionStatisticsHTTP2_triggered()3386 void MainWindow::on_actionStatisticsHTTP2_triggered()
3387 {
3388 openStatisticsTreeDialog("http2");
3389
3390 }
3391
3392 // Telephony Menu
3393
openTelephonyRtpPlayerDialog()3394 RtpPlayerDialog *MainWindow::openTelephonyRtpPlayerDialog()
3395 {
3396 RtpPlayerDialog *dialog;
3397
3398 #ifdef HAVE_LIBPCAP
3399 dialog = RtpPlayerDialog::openRtpPlayerDialog(*this, capture_file_, packet_list_, captureSession()->state != CAPTURE_STOPPED);
3400 #else
3401 dialog = RtpPlayerDialog::openRtpPlayerDialog(*this, capture_file_, packet_list_, false);
3402 #endif
3403
3404 dialog->show();
3405
3406 return dialog;
3407 }
3408
openTelephonyVoipCallsDialogVoip()3409 VoipCallsDialog *MainWindow::openTelephonyVoipCallsDialogVoip()
3410 {
3411 VoipCallsDialog *dialog;
3412
3413 dialog = VoipCallsDialog::openVoipCallsDialogVoip(*this, capture_file_, packet_list_);
3414 dialog->show();
3415
3416 return dialog;
3417 }
3418
openTelephonyVoipCallsDialogSip()3419 VoipCallsDialog *MainWindow::openTelephonyVoipCallsDialogSip()
3420 {
3421 VoipCallsDialog *dialog;
3422
3423 dialog = VoipCallsDialog::openVoipCallsDialogSip(*this, capture_file_, packet_list_);
3424 dialog->show();
3425
3426 return dialog;
3427 }
3428
openTelephonyRtpAnalysisDialog()3429 RtpAnalysisDialog *MainWindow::openTelephonyRtpAnalysisDialog()
3430 {
3431 RtpAnalysisDialog *dialog;
3432
3433 dialog = RtpAnalysisDialog::openRtpAnalysisDialog(*this, capture_file_, packet_list_);
3434 dialog->show();
3435
3436 return dialog;
3437 }
3438
on_actionTelephonyVoipCalls_triggered()3439 void MainWindow::on_actionTelephonyVoipCalls_triggered()
3440 {
3441 openTelephonyVoipCallsDialogVoip();
3442 }
3443
on_actionTelephonyGsmMapSummary_triggered()3444 void MainWindow::on_actionTelephonyGsmMapSummary_triggered()
3445 {
3446 GsmMapSummaryDialog *gms_dialog = new GsmMapSummaryDialog(*this, capture_file_);
3447 gms_dialog->show();
3448 }
3449
on_actionTelephonyIax2StreamAnalysis_triggered()3450 void MainWindow::on_actionTelephonyIax2StreamAnalysis_triggered()
3451 {
3452 Iax2AnalysisDialog *iax2_analysis_dialog = new Iax2AnalysisDialog(*this, capture_file_);
3453 connect(iax2_analysis_dialog, SIGNAL(goToPacket(int)),
3454 packet_list_, SLOT(goToPacket(int)));
3455 iax2_analysis_dialog->show();
3456 }
3457
on_actionTelephonyISUPMessages_triggered()3458 void MainWindow::on_actionTelephonyISUPMessages_triggered()
3459 {
3460 openStatisticsTreeDialog("isup_msg");
3461 }
3462
3463 // -z mac-lte,stat
statCommandLteMacStatistics(const char * arg,void *)3464 void MainWindow::statCommandLteMacStatistics(const char *arg, void *)
3465 {
3466 LteMacStatisticsDialog *lte_mac_stats_dlg = new LteMacStatisticsDialog(*this, capture_file_, arg);
3467 connect(lte_mac_stats_dlg, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)),
3468 this, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)));
3469 lte_mac_stats_dlg->show();
3470 }
3471
on_actionTelephonyLteMacStatistics_triggered()3472 void MainWindow::on_actionTelephonyLteMacStatistics_triggered()
3473 {
3474 statCommandLteMacStatistics(NULL, NULL);
3475 }
3476
statCommandLteRlcStatistics(const char * arg,void *)3477 void MainWindow::statCommandLteRlcStatistics(const char *arg, void *)
3478 {
3479 LteRlcStatisticsDialog *lte_rlc_stats_dlg = new LteRlcStatisticsDialog(*this, capture_file_, arg);
3480 connect(lte_rlc_stats_dlg, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)),
3481 this, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)));
3482 // N.B. It is necessary for the RLC Statistics window to launch the RLC graph in this way, to ensure
3483 // that the goToPacket() signal/slot connection gets set up...
3484 connect(lte_rlc_stats_dlg, SIGNAL(launchRLCGraph(bool, guint16, guint8, guint16, guint16, guint8)),
3485 this, SLOT(launchRLCGraph(bool, guint16, guint8, guint16, guint16, guint8)));
3486
3487 lte_rlc_stats_dlg->show();
3488 }
3489
on_actionTelephonyLteRlcStatistics_triggered()3490 void MainWindow::on_actionTelephonyLteRlcStatistics_triggered()
3491 {
3492 statCommandLteRlcStatistics(NULL, NULL);
3493 }
3494
launchRLCGraph(bool channelKnown,guint16 ueid,guint8 rlcMode,guint16 channelType,guint16 channelId,guint8 direction)3495 void MainWindow::launchRLCGraph(bool channelKnown,
3496 guint16 ueid, guint8 rlcMode,
3497 guint16 channelType, guint16 channelId, guint8 direction)
3498 {
3499 LteRlcGraphDialog *lrg_dialog = new LteRlcGraphDialog(*this, capture_file_, channelKnown);
3500 connect(lrg_dialog, SIGNAL(goToPacket(int)), packet_list_, SLOT(goToPacket(int)));
3501 // This is a bit messy, but wanted to hide these parameters from users of
3502 // on_actionTelephonyLteRlcGraph_triggered().
3503 if (channelKnown) {
3504 lrg_dialog->setChannelInfo(ueid, rlcMode, channelType, channelId, direction);
3505 }
3506 lrg_dialog->show();
3507 }
3508
on_actionTelephonyLteRlcGraph_triggered()3509 void MainWindow::on_actionTelephonyLteRlcGraph_triggered()
3510 {
3511 // We don't yet know the channel.
3512 launchRLCGraph(false, 0, 0, 0, 0, 0);
3513 }
3514
on_actionTelephonyMtp3Summary_triggered()3515 void MainWindow::on_actionTelephonyMtp3Summary_triggered()
3516 {
3517 Mtp3SummaryDialog *mtp3s_dialog = new Mtp3SummaryDialog(*this, capture_file_);
3518 mtp3s_dialog->show();
3519 }
3520
on_actionTelephonyOsmuxPacketCounter_triggered()3521 void MainWindow::on_actionTelephonyOsmuxPacketCounter_triggered()
3522 {
3523 openStatisticsTreeDialog("osmux");
3524 }
3525
openTelephonyRtpStreamsDialog()3526 RtpStreamDialog *MainWindow::openTelephonyRtpStreamsDialog()
3527 {
3528 RtpStreamDialog *dialog;
3529
3530 dialog = RtpStreamDialog::openRtpStreamDialog(*this, capture_file_, packet_list_);
3531 dialog->show();
3532
3533 return dialog;
3534 }
3535
on_actionTelephonyRtpStreams_triggered()3536 void MainWindow::on_actionTelephonyRtpStreams_triggered()
3537 {
3538 openTelephonyRtpStreamsDialog();
3539 }
3540
on_actionTelephonyRtpStreamAnalysis_triggered()3541 void MainWindow::on_actionTelephonyRtpStreamAnalysis_triggered()
3542 {
3543 QVector<rtpstream_id_t *> stream_ids;
3544 QString err;
3545
3546 if (QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier)) {
3547 err = findRtpStreams(&stream_ids, true);
3548 } else {
3549 err = findRtpStreams(&stream_ids, false);
3550 }
3551 if (err != NULL) {
3552 QMessageBox::warning(this, tr("RTP packet search failed"),
3553 err,
3554 QMessageBox::Ok);
3555 } else {
3556 openTelephonyRtpAnalysisDialog()->addRtpStreams(stream_ids);
3557 }
3558 foreach(rtpstream_id_t *id, stream_ids) {
3559 rtpstream_id_free(id);
3560 }
3561 }
3562
on_actionTelephonyRtpPlayer_triggered()3563 void MainWindow::on_actionTelephonyRtpPlayer_triggered()
3564 {
3565 QVector<rtpstream_id_t *> stream_ids;
3566 QString err;
3567
3568 if (QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier)) {
3569 err = findRtpStreams(&stream_ids, true);
3570 } else {
3571 err = findRtpStreams(&stream_ids, false);
3572 }
3573 if (err != NULL) {
3574 QMessageBox::warning(this, tr("RTP packet search failed"),
3575 err,
3576 QMessageBox::Ok);
3577 } else {
3578 openTelephonyRtpPlayerDialog()->addRtpStreams(stream_ids);
3579 }
3580 foreach(rtpstream_id_t *id, stream_ids) {
3581 rtpstream_id_free(id);
3582 }
3583 }
3584
on_actionTelephonyRTSPPacketCounter_triggered()3585 void MainWindow::on_actionTelephonyRTSPPacketCounter_triggered()
3586 {
3587 openStatisticsTreeDialog("rtsp");
3588 }
3589
on_actionTelephonySMPPOperations_triggered()3590 void MainWindow::on_actionTelephonySMPPOperations_triggered()
3591 {
3592 openStatisticsTreeDialog("smpp_commands");
3593 }
3594
on_actionTelephonyUCPMessages_triggered()3595 void MainWindow::on_actionTelephonyUCPMessages_triggered()
3596 {
3597 openStatisticsTreeDialog("ucp_messages");
3598 }
3599
on_actionTelephonyF1APMessages_triggered()3600 void MainWindow::on_actionTelephonyF1APMessages_triggered()
3601 {
3602 openStatisticsTreeDialog("f1ap");
3603 }
3604
on_actionTelephonyNGAPMessages_triggered()3605 void MainWindow::on_actionTelephonyNGAPMessages_triggered()
3606 {
3607 openStatisticsTreeDialog("ngap");
3608 }
3609
on_actionTelephonySipFlows_triggered()3610 void MainWindow::on_actionTelephonySipFlows_triggered()
3611 {
3612 openTelephonyVoipCallsDialogSip();
3613 }
3614
3615 // Wireless Menu
3616
on_actionBluetoothATT_Server_Attributes_triggered()3617 void MainWindow::on_actionBluetoothATT_Server_Attributes_triggered()
3618 {
3619 BluetoothAttServerAttributesDialog *bluetooth_att_sever_attributes_dialog = new BluetoothAttServerAttributesDialog(*this, capture_file_);
3620 connect(bluetooth_att_sever_attributes_dialog, SIGNAL(goToPacket(int)),
3621 packet_list_, SLOT(goToPacket(int)));
3622 connect(bluetooth_att_sever_attributes_dialog, SIGNAL(updateFilter(QString, bool)),
3623 this, SLOT(filterPackets(QString, bool)));
3624 bluetooth_att_sever_attributes_dialog->show();
3625 }
3626
on_actionBluetoothDevices_triggered()3627 void MainWindow::on_actionBluetoothDevices_triggered()
3628 {
3629 BluetoothDevicesDialog *bluetooth_devices_dialog = new BluetoothDevicesDialog(*this, capture_file_, packet_list_);
3630 connect(bluetooth_devices_dialog, SIGNAL(goToPacket(int)),
3631 packet_list_, SLOT(goToPacket(int)));
3632 connect(bluetooth_devices_dialog, SIGNAL(updateFilter(QString, bool)),
3633 this, SLOT(filterPackets(QString, bool)));
3634 bluetooth_devices_dialog->show();
3635 }
3636
on_actionBluetoothHCI_Summary_triggered()3637 void MainWindow::on_actionBluetoothHCI_Summary_triggered()
3638 {
3639 BluetoothHciSummaryDialog *bluetooth_hci_summary_dialog = new BluetoothHciSummaryDialog(*this, capture_file_);
3640 connect(bluetooth_hci_summary_dialog, SIGNAL(goToPacket(int)),
3641 packet_list_, SLOT(goToPacket(int)));
3642 connect(bluetooth_hci_summary_dialog, SIGNAL(updateFilter(QString, bool)),
3643 this, SLOT(filterPackets(QString, bool)));
3644 bluetooth_hci_summary_dialog->show();
3645 }
3646
3647 // Tools Menu
3648
on_actionToolsFirewallAclRules_triggered()3649 void MainWindow::on_actionToolsFirewallAclRules_triggered()
3650 {
3651 FirewallRulesDialog *firewall_rules_dialog = new FirewallRulesDialog(*this, capture_file_);
3652 firewall_rules_dialog->show();
3653 }
3654
on_actionToolsCredentials_triggered()3655 void MainWindow::on_actionToolsCredentials_triggered()
3656 {
3657 CredentialsDialog *credentials_dialog = new CredentialsDialog(*this, capture_file_, packet_list_);
3658 credentials_dialog->show();
3659 }
3660
3661 // Help Menu
on_actionHelpContents_triggered()3662 void MainWindow::on_actionHelpContents_triggered() {
3663
3664 wsApp->helpTopicAction(HELP_CONTENT);
3665 }
3666
on_actionHelpMPWireshark_triggered()3667 void MainWindow::on_actionHelpMPWireshark_triggered() {
3668
3669 wsApp->helpTopicAction(LOCALPAGE_MAN_WIRESHARK);
3670 }
3671
on_actionHelpMPWireshark_Filter_triggered()3672 void MainWindow::on_actionHelpMPWireshark_Filter_triggered() {
3673 wsApp->helpTopicAction(LOCALPAGE_MAN_WIRESHARK_FILTER);
3674 }
3675
on_actionHelpMPCapinfos_triggered()3676 void MainWindow::on_actionHelpMPCapinfos_triggered() {
3677 wsApp->helpTopicAction(LOCALPAGE_MAN_CAPINFOS);
3678 }
3679
on_actionHelpMPDumpcap_triggered()3680 void MainWindow::on_actionHelpMPDumpcap_triggered() {
3681 wsApp->helpTopicAction(LOCALPAGE_MAN_DUMPCAP);
3682 }
3683
on_actionHelpMPEditcap_triggered()3684 void MainWindow::on_actionHelpMPEditcap_triggered() {
3685 wsApp->helpTopicAction(LOCALPAGE_MAN_EDITCAP);
3686 }
3687
on_actionHelpMPMergecap_triggered()3688 void MainWindow::on_actionHelpMPMergecap_triggered() {
3689 wsApp->helpTopicAction(LOCALPAGE_MAN_MERGECAP);
3690 }
3691
on_actionHelpMPRawShark_triggered()3692 void MainWindow::on_actionHelpMPRawShark_triggered() {
3693 wsApp->helpTopicAction(LOCALPAGE_MAN_RAWSHARK);
3694 }
3695
on_actionHelpMPReordercap_triggered()3696 void MainWindow::on_actionHelpMPReordercap_triggered() {
3697 wsApp->helpTopicAction(LOCALPAGE_MAN_REORDERCAP);
3698 }
3699
on_actionHelpMPText2cap_triggered()3700 void MainWindow::on_actionHelpMPText2cap_triggered() {
3701 wsApp->helpTopicAction(LOCALPAGE_MAN_TEXT2PCAP);
3702 }
3703
on_actionHelpMPTShark_triggered()3704 void MainWindow::on_actionHelpMPTShark_triggered() {
3705 wsApp->helpTopicAction(LOCALPAGE_MAN_TSHARK);
3706 }
3707
on_actionHelpWebsite_triggered()3708 void MainWindow::on_actionHelpWebsite_triggered() {
3709
3710 wsApp->helpTopicAction(ONLINEPAGE_HOME);
3711 }
3712
on_actionHelpFAQ_triggered()3713 void MainWindow::on_actionHelpFAQ_triggered() {
3714
3715 wsApp->helpTopicAction(ONLINEPAGE_FAQ);
3716 }
3717
on_actionHelpAsk_triggered()3718 void MainWindow::on_actionHelpAsk_triggered() {
3719
3720 wsApp->helpTopicAction(ONLINEPAGE_ASK);
3721 }
3722
on_actionHelpDownloads_triggered()3723 void MainWindow::on_actionHelpDownloads_triggered() {
3724
3725 wsApp->helpTopicAction(ONLINEPAGE_DOWNLOAD);
3726 }
3727
on_actionHelpWiki_triggered()3728 void MainWindow::on_actionHelpWiki_triggered() {
3729
3730 wsApp->helpTopicAction(ONLINEPAGE_WIKI);
3731 }
3732
on_actionHelpSampleCaptures_triggered()3733 void MainWindow::on_actionHelpSampleCaptures_triggered() {
3734
3735 wsApp->helpTopicAction(ONLINEPAGE_SAMPLE_FILES);
3736 }
3737
3738 #ifdef HAVE_SOFTWARE_UPDATE
checkForUpdates()3739 void MainWindow::checkForUpdates()
3740 {
3741 software_update_check();
3742 }
3743 #endif
3744
on_actionHelpAbout_triggered()3745 void MainWindow::on_actionHelpAbout_triggered()
3746 {
3747 AboutDialog *about_dialog = new AboutDialog(this);
3748
3749 if (about_dialog->isMinimized() == true)
3750 {
3751 about_dialog->showNormal();
3752 }
3753 else
3754 {
3755 about_dialog->show();
3756 }
3757
3758 about_dialog->raise();
3759 about_dialog->activateWindow();
3760 }
3761
on_actionGoGoToPacket_triggered()3762 void MainWindow::on_actionGoGoToPacket_triggered() {
3763 if (! packet_list_->model() || packet_list_->model()->rowCount() < 1) {
3764 return;
3765 }
3766 previous_focus_ = wsApp->focusWidget();
3767 connect(previous_focus_, SIGNAL(destroyed()), this, SLOT(resetPreviousFocus()));
3768
3769 showAccordionFrame(main_ui_->goToFrame, true);
3770 if (main_ui_->goToFrame->isVisible()) {
3771 main_ui_->goToLineEdit->clear();
3772 main_ui_->goToLineEdit->setFocus();
3773 }
3774 }
3775
on_actionGoGoToLinkedPacket_triggered()3776 void MainWindow::on_actionGoGoToLinkedPacket_triggered()
3777 {
3778 QAction *gta = qobject_cast<QAction*>(sender());
3779 if (!gta) return;
3780
3781 bool ok = false;
3782 int packet_num = gta->data().toInt(&ok);
3783 if (!ok) return;
3784
3785 packet_list_->goToPacket(packet_num);
3786 }
3787
3788 // gtk/main_menubar.c:goto_conversation_frame
goToConversationFrame(bool go_next)3789 void MainWindow::goToConversationFrame(bool go_next) {
3790 gchar *filter = NULL;
3791 dfilter_t *dfcode = NULL;
3792 gboolean found_packet = FALSE;
3793 packet_info *pi = capture_file_.packetInfo();
3794
3795 if (!pi) {
3796 // No packet was selected, or multiple packets were selected.
3797 return;
3798 }
3799
3800 /* Try to build a conversation
3801 * filter in the order TCP, UDP, IP, Ethernet and apply the
3802 * coloring */
3803 filter = conversation_filter_from_packet(pi);
3804 if (filter == NULL) {
3805 wsApp->pushStatus(WiresharkApplication::TemporaryStatus, tr("Unable to build conversation filter."));
3806 g_free(filter);
3807 return;
3808 }
3809
3810 if (!dfilter_compile(filter, &dfcode, NULL)) {
3811 /* The attempt failed; report an error. */
3812 wsApp->pushStatus(WiresharkApplication::TemporaryStatus, tr("Error compiling filter for this conversation."));
3813 g_free(filter);
3814 return;
3815 }
3816
3817 found_packet = cf_find_packet_dfilter(capture_file_.capFile(), dfcode, go_next ? SD_FORWARD : SD_BACKWARD);
3818
3819 if (!found_packet) {
3820 /* We didn't find a packet */
3821 wsApp->pushStatus(WiresharkApplication::TemporaryStatus, tr("No previous/next packet in conversation."));
3822 }
3823
3824 dfilter_free(dfcode);
3825 g_free(filter);
3826 }
3827
on_actionGoNextConversationPacket_triggered()3828 void MainWindow::on_actionGoNextConversationPacket_triggered()
3829 {
3830 goToConversationFrame(true);
3831 }
3832
on_actionGoPreviousConversationPacket_triggered()3833 void MainWindow::on_actionGoPreviousConversationPacket_triggered()
3834 {
3835 goToConversationFrame(false);
3836 }
3837
on_actionGoAutoScroll_toggled(bool checked)3838 void MainWindow::on_actionGoAutoScroll_toggled(bool checked)
3839 {
3840 packet_list_->setVerticalAutoScroll(checked);
3841 }
3842
resetPreviousFocus()3843 void MainWindow::resetPreviousFocus() {
3844 previous_focus_ = NULL;
3845 }
3846
on_goToCancel_clicked()3847 void MainWindow::on_goToCancel_clicked()
3848 {
3849 main_ui_->goToFrame->animatedHide();
3850 if (previous_focus_) {
3851 disconnect(previous_focus_, SIGNAL(destroyed()), this, SLOT(resetPreviousFocus()));
3852 previous_focus_->setFocus();
3853 resetPreviousFocus();
3854 }
3855 }
3856
on_goToGo_clicked()3857 void MainWindow::on_goToGo_clicked()
3858 {
3859 gotoFrame(main_ui_->goToLineEdit->text().toInt());
3860
3861 on_goToCancel_clicked();
3862 }
3863
on_goToLineEdit_returnPressed()3864 void MainWindow::on_goToLineEdit_returnPressed()
3865 {
3866 on_goToGo_clicked();
3867 }
3868
on_actionCaptureStart_triggered()3869 void MainWindow::on_actionCaptureStart_triggered()
3870 {
3871 //#ifdef HAVE_AIRPCAP
3872 // airpcap_if_active = airpcap_if_selected;
3873 // if (airpcap_if_active)
3874 // airpcap_set_toolbar_start_capture(airpcap_if_active);
3875 //#endif
3876
3877 // if (cap_open_w) {
3878 // /*
3879 // * There's an options dialog; get the values from it and close it.
3880 // */
3881 // gboolean success;
3882
3883 // /* Determine if "capture start" while building of the "capture options" window */
3884 // /* is in progress. If so, ignore the "capture start. */
3885 // /* XXX: Would it be better/cleaner for the "capture options" window code to */
3886 // /* disable the capture start button temporarily ? */
3887 // if (cap_open_complete == FALSE) {
3888 // return; /* Building options window: ignore "capture start" */
3889 // }
3890 // success = capture_dlg_prep(cap_open_w);
3891 // window_destroy(GTK_WIDGET(cap_open_w));
3892 // if (!success)
3893 // return; /* error in options dialog */
3894 // }
3895
3896 #ifdef HAVE_LIBPCAP
3897 if (global_capture_opts.num_selected == 0) {
3898 QString err_msg = tr("No Interface Selected.");
3899 wsApp->pushStatus(WiresharkApplication::TemporaryStatus, err_msg);
3900 main_ui_->actionCaptureStart->setChecked(false);
3901 return;
3902 }
3903
3904 /* XXX - will closing this remove a temporary file? */
3905 QString before_what(tr(" before starting a new capture"));
3906 if (testCaptureFileClose(before_what)) {
3907 startCapture();
3908 } else {
3909 // simply clicking the button sets it to 'checked' even though we've
3910 // decided to do nothing, so undo that
3911 main_ui_->actionCaptureStart->setChecked(false);
3912 }
3913 #endif // HAVE_LIBPCAP
3914 }
3915
on_actionCaptureStop_triggered()3916 void MainWindow::on_actionCaptureStop_triggered()
3917 {
3918 stopCapture();
3919 }
3920
on_actionCaptureRestart_triggered()3921 void MainWindow::on_actionCaptureRestart_triggered()
3922 {
3923 #ifdef HAVE_LIBPCAP
3924 QString before_what(tr(" before restarting the capture"));
3925 cap_session_.capture_opts->restart = TRUE;
3926 if (!testCaptureFileClose(before_what, Restart))
3927 return;
3928
3929 startCapture();
3930 #endif // HAVE_LIBPCAP
3931 }
3932
on_actionCaptureCaptureFilters_triggered()3933 void MainWindow::on_actionCaptureCaptureFilters_triggered()
3934 {
3935 if (!capture_filter_dlg_) {
3936 capture_filter_dlg_ = new FilterDialog(this, FilterDialog::CaptureFilter);
3937 }
3938 capture_filter_dlg_->show();
3939 capture_filter_dlg_->raise();
3940 capture_filter_dlg_->activateWindow();
3941 }
3942
on_actionStatisticsCaptureFileProperties_triggered()3943 void MainWindow::on_actionStatisticsCaptureFileProperties_triggered()
3944 {
3945 CaptureFilePropertiesDialog *capture_file_properties_dialog = new CaptureFilePropertiesDialog(*this, capture_file_);
3946 connect(capture_file_properties_dialog, SIGNAL(captureCommentChanged()),
3947 this, SLOT(updateForUnsavedChanges()));
3948 capture_file_properties_dialog->show();
3949 }
3950
on_actionStatisticsResolvedAddresses_triggered()3951 void MainWindow::on_actionStatisticsResolvedAddresses_triggered()
3952 {
3953 QString capFileName;
3954 wtap* wth = Q_NULLPTR;
3955 if (capture_file_.isValid())
3956 {
3957 capFileName = capture_file_.capFile()->filename;
3958 wth = capture_file_.capFile()->provider.wth;
3959 }
3960 ResolvedAddressesDialog *resolved_addresses_dialog =
3961 new ResolvedAddressesDialog(this, capFileName, wth);
3962 resolved_addresses_dialog->show();
3963 }
3964
on_actionStatisticsProtocolHierarchy_triggered()3965 void MainWindow::on_actionStatisticsProtocolHierarchy_triggered()
3966 {
3967 ProtocolHierarchyDialog *phd = new ProtocolHierarchyDialog(*this, capture_file_);
3968 connect(phd, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)),
3969 this, SIGNAL(filterAction(QString, FilterAction::Action, FilterAction::ActionType)));
3970 phd->show();
3971 }
3972
on_actionCaptureOptions_triggered()3973 void MainWindow::on_actionCaptureOptions_triggered()
3974 {
3975 #ifdef HAVE_LIBPCAP
3976 if (!capture_options_dialog_) {
3977 capture_options_dialog_ = new CaptureOptionsDialog(this);
3978
3979 connect(capture_options_dialog_, SIGNAL(startCapture()), this, SLOT(startCapture()));
3980 connect(capture_options_dialog_, SIGNAL(stopCapture()), this, SLOT(stopCapture()));
3981
3982 connect(capture_options_dialog_, SIGNAL(getPoints(int, PointList*)),
3983 this->welcome_page_->getInterfaceFrame(), SLOT(getPoints(int, PointList*)));
3984 connect(capture_options_dialog_, SIGNAL(interfacesChanged()),
3985 this->welcome_page_, SLOT(interfaceSelected()));
3986 connect(capture_options_dialog_, SIGNAL(interfacesChanged()),
3987 this->welcome_page_->getInterfaceFrame(), SLOT(updateSelectedInterfaces()));
3988 connect(capture_options_dialog_, SIGNAL(interfaceListChanged()),
3989 this->welcome_page_->getInterfaceFrame(), SLOT(interfaceListChanged()));
3990 connect(capture_options_dialog_, SIGNAL(captureFilterTextEdited(QString)),
3991 this->welcome_page_, SLOT(setCaptureFilterText(QString)));
3992 // Propagate selection changes from main UI to dialog.
3993 connect(this->welcome_page_, SIGNAL(interfacesChanged()),
3994 capture_options_dialog_, SLOT(interfaceSelected()));
3995
3996 connect(capture_options_dialog_, SIGNAL(setFilterValid(bool, const QString)),
3997 this, SLOT(startInterfaceCapture(bool, const QString)));
3998 }
3999 capture_options_dialog_->setTab(0);
4000 capture_options_dialog_->updateInterfaces();
4001
4002 if (capture_options_dialog_->isMinimized()) {
4003 capture_options_dialog_->showNormal();
4004 } else {
4005 capture_options_dialog_->show();
4006 }
4007
4008 capture_options_dialog_->raise();
4009 capture_options_dialog_->activateWindow();
4010 #endif
4011 }
4012
4013 #ifdef HAVE_LIBPCAP
on_actionCaptureRefreshInterfaces_triggered()4014 void MainWindow::on_actionCaptureRefreshInterfaces_triggered()
4015 {
4016 main_ui_->actionCaptureRefreshInterfaces->setEnabled(false);
4017 wsApp->refreshLocalInterfaces();
4018 main_ui_->actionCaptureRefreshInterfaces->setEnabled(true);
4019 }
4020 #endif
4021
externalMenuItem_triggered()4022 void MainWindow::externalMenuItem_triggered()
4023 {
4024 QAction * triggerAction = NULL;
4025 QVariant v;
4026 ext_menubar_t * entry = NULL;
4027
4028 if (QObject::sender()) {
4029 triggerAction = (QAction *)QObject::sender();
4030 v = triggerAction->data();
4031
4032 if (v.canConvert<void *>()) {
4033 entry = (ext_menubar_t *)v.value<void *>();
4034
4035 if (entry->type == EXT_MENUBAR_ITEM) {
4036 entry->callback(EXT_MENUBAR_QT_GUI, (gpointer)((void *)main_ui_), entry->user_data);
4037 } else {
4038 QDesktopServices::openUrl(QUrl(QString((gchar *)entry->user_data)));
4039 }
4040 }
4041 }
4042 }
4043
gotoFrame(int packet_num)4044 void MainWindow::gotoFrame(int packet_num)
4045 {
4046 if (packet_num > 0) {
4047 packet_list_->goToPacket(packet_num);
4048 }
4049 }
4050
extcap_options_finished(int result)4051 void MainWindow::extcap_options_finished(int result)
4052 {
4053 if (result == QDialog::Accepted) {
4054 QString before_what(tr(" before starting a new capture"));
4055 if (testCaptureFileClose(before_what)) {
4056 startCapture();
4057 }
4058 }
4059 this->welcome_page_->getInterfaceFrame()->interfaceListChanged();
4060 }
4061
showExtcapOptionsDialog(QString & device_name)4062 void MainWindow::showExtcapOptionsDialog(QString &device_name)
4063 {
4064 ExtcapOptionsDialog * extcap_options_dialog = ExtcapOptionsDialog::createForDevice(device_name, this);
4065 /* The dialog returns null, if the given device name is not a valid extcap device */
4066 if (extcap_options_dialog) {
4067 extcap_options_dialog->setModal(true);
4068 extcap_options_dialog->setAttribute(Qt::WA_DeleteOnClose);
4069 connect(extcap_options_dialog, SIGNAL(finished(int)),
4070 this, SLOT(extcap_options_finished(int)));
4071 extcap_options_dialog->show();
4072 }
4073 }
4074
insertColumn(QString name,QString abbrev,gint pos)4075 void MainWindow::insertColumn(QString name, QString abbrev, gint pos)
4076 {
4077 gint colnr = 0;
4078 if (name.length() > 0 && abbrev.length() > 0)
4079 {
4080 colnr = column_prefs_add_custom(COL_CUSTOM, name.toStdString().c_str(), abbrev.toStdString().c_str(), pos);
4081 packet_list_->columnsChanged();
4082 packet_list_->resizeColumnToContents(colnr);
4083 prefs_main_write();
4084 }
4085 }
4086
on_actionContextWikiProtocolPage_triggered()4087 void MainWindow::on_actionContextWikiProtocolPage_triggered()
4088 {
4089 QAction *wa = qobject_cast<QAction*>(sender());
4090 if (!wa) return;
4091
4092 bool ok = false;
4093 int field_id = wa->data().toInt(&ok);
4094 if (!ok) return;
4095
4096 const QString proto_abbrev = proto_registrar_get_abbrev(field_id);
4097
4098 int ret = QMessageBox::question(this, wsApp->windowTitleString(tr("Wiki Page for %1").arg(proto_abbrev)),
4099 tr("<p>The Wireshark Wiki is maintained by the community.</p>"
4100 "<p>The page you are about to load might be wonderful, "
4101 "incomplete, wrong, or nonexistent.</p>"
4102 "<p>Proceed to the wiki?</p>"),
4103 QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
4104
4105 if (ret != QMessageBox::Yes) return;
4106
4107 QUrl wiki_url = QString(WS_WIKI_URL("Protocols/%1")).arg(proto_abbrev);
4108 QDesktopServices::openUrl(wiki_url);
4109 }
4110
on_actionContextFilterFieldReference_triggered()4111 void MainWindow::on_actionContextFilterFieldReference_triggered()
4112 {
4113 QAction *wa = qobject_cast<QAction*>(sender());
4114 if (!wa) return;
4115
4116 bool ok = false;
4117 int field_id = wa->data().toInt(&ok);
4118 if (!ok) return;
4119
4120 const QString proto_abbrev = proto_registrar_get_abbrev(field_id);
4121
4122 QUrl dfref_url = QString(WS_DOCS_URL "/dfref/%1/%2")
4123 .arg(proto_abbrev[0])
4124 .arg(proto_abbrev);
4125 QDesktopServices::openUrl(dfref_url);
4126 }
4127
on_actionViewFullScreen_triggered(bool checked)4128 void MainWindow::on_actionViewFullScreen_triggered(bool checked)
4129 {
4130 if (checked) {
4131 // Save the state for future restore
4132 was_maximized_ = this->isMaximized();
4133 this->showFullScreen();
4134 } else {
4135 // Restore the previous state
4136 if (was_maximized_)
4137 this->showMaximized();
4138 else
4139 this->showNormal();
4140 }
4141 }
4142
activatePluginIFToolbar(bool)4143 void MainWindow::activatePluginIFToolbar(bool)
4144 {
4145 QAction *sendingAction = dynamic_cast<QAction *>(sender());
4146 if (!sendingAction || !sendingAction->data().isValid())
4147 return;
4148
4149 ext_toolbar_t *toolbar = VariantPointer<ext_toolbar_t>::asPtr(sendingAction->data());
4150
4151 QList<QToolBar *> toolbars = findChildren<QToolBar *>();
4152 foreach(QToolBar *bar, toolbars) {
4153 AdditionalToolBar *iftoolbar = dynamic_cast<AdditionalToolBar *>(bar);
4154 if (iftoolbar && iftoolbar->menuName().compare(toolbar->name) == 0) {
4155 if (iftoolbar->isVisible()) {
4156 iftoolbar->setVisible(false);
4157 sendingAction->setChecked(true);
4158 } else {
4159 iftoolbar->setVisible(true);
4160 sendingAction->setChecked(true);
4161 }
4162 }
4163 }
4164 }
4165
rtpPlayerDialogReplaceRtpStreams(QVector<rtpstream_id_t * > stream_ids)4166 void MainWindow::rtpPlayerDialogReplaceRtpStreams(QVector<rtpstream_id_t *> stream_ids)
4167 {
4168 openTelephonyRtpPlayerDialog()->replaceRtpStreams(stream_ids);
4169 }
4170
rtpPlayerDialogAddRtpStreams(QVector<rtpstream_id_t * > stream_ids)4171 void MainWindow::rtpPlayerDialogAddRtpStreams(QVector<rtpstream_id_t *> stream_ids)
4172 {
4173 openTelephonyRtpPlayerDialog()->addRtpStreams(stream_ids);
4174 }
4175
rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_id_t * > stream_ids)4176 void MainWindow::rtpPlayerDialogRemoveRtpStreams(QVector<rtpstream_id_t *> stream_ids)
4177 {
4178 openTelephonyRtpPlayerDialog()->removeRtpStreams(stream_ids);
4179 }
4180
rtpAnalysisDialogReplaceRtpStreams(QVector<rtpstream_id_t * > stream_ids)4181 void MainWindow::rtpAnalysisDialogReplaceRtpStreams(QVector<rtpstream_id_t *> stream_ids)
4182 {
4183 openTelephonyRtpAnalysisDialog()->replaceRtpStreams(stream_ids);
4184 }
4185
rtpAnalysisDialogAddRtpStreams(QVector<rtpstream_id_t * > stream_ids)4186 void MainWindow::rtpAnalysisDialogAddRtpStreams(QVector<rtpstream_id_t *> stream_ids)
4187 {
4188 openTelephonyRtpAnalysisDialog()->addRtpStreams(stream_ids);
4189 }
4190
rtpAnalysisDialogRemoveRtpStreams(QVector<rtpstream_id_t * > stream_ids)4191 void MainWindow::rtpAnalysisDialogRemoveRtpStreams(QVector<rtpstream_id_t *> stream_ids)
4192 {
4193 openTelephonyRtpAnalysisDialog()->removeRtpStreams(stream_ids);
4194 }
4195
rtpStreamsDialogSelectRtpStreams(QVector<rtpstream_id_t * > stream_ids)4196 void MainWindow::rtpStreamsDialogSelectRtpStreams(QVector<rtpstream_id_t *> stream_ids)
4197 {
4198 openTelephonyRtpStreamsDialog()->selectRtpStream(stream_ids);
4199 }
4200
rtpStreamsDialogDeselectRtpStreams(QVector<rtpstream_id_t * > stream_ids)4201 void MainWindow::rtpStreamsDialogDeselectRtpStreams(QVector<rtpstream_id_t *> stream_ids)
4202 {
4203 openTelephonyRtpStreamsDialog()->deselectRtpStream(stream_ids);
4204 }
4205
4206 #ifdef _MSC_VER
4207 #pragma warning(pop)
4208 #endif
4209