1 /* main_window_slots.cpp
3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 // Qt 5.5.0 + Visual C++ 2013
27 #pragma warning(disable:4996)
30 #include "main_window.h"
31 #include <ui_main_window.h>
38 #include "ui/capture.h"
41 #include "color_filters.h"
43 #include "wsutil/file_util.h"
44 #include "wsutil/filesystem.h"
45 #include <wsutil/str_util.h>
47 #include "epan/addr_resolv.h"
48 #include "epan/dissector_filters.h"
49 #include "epan/column.h"
50 #include "epan/dfilter/dfilter-macro.h"
51 #include "epan/epan_dissect.h"
52 #include "epan/filter_expressions.h"
53 #include "epan/prefs.h"
55 #include "epan/value_string.h"
58 #include <epan/wslua/init_wslua.h>
61 #include "ui/alert_box.h"
63 #include "ui/capture_ui_utils.h"
66 #include "ui/capture_globals.h"
67 #include "ui/help_url.h"
68 #include "ui/main_statusbar.h"
69 #include "ui/preference_utils.h"
70 #include "ui/recent.h"
71 #include "ui/recent_utils.h"
72 #include "ui/ssl_key_export.h"
73 #include "ui/ui_util.h"
74 #include "ui/qt/simple_dialog.h"
76 #ifdef HAVE_SOFTWARE_UPDATE
77 #include "ui/software_update.h"
80 #include "about_dialog.h"
81 #include "bluetooth_att_server_attributes_dialog.h"
82 #include "bluetooth_devices_dialog.h"
83 #include "bluetooth_hci_summary_dialog.h"
84 #include "capture_file_dialog.h"
85 #include "capture_file_properties_dialog.h"
86 #include "color_utils.h"
87 #include "coloring_rules_dialog.h"
88 #include "conversation_dialog.h"
89 #include "conversation_hash_tables_dialog.h"
90 #include "enabled_protocols_dialog.h"
91 #include "decode_as_dialog.h"
92 #include "display_filter_edit.h"
93 #include "display_filter_expression_dialog.h"
94 #include "dissector_tables_dialog.h"
95 #include "endpoint_dialog.h"
96 #include "expert_info_dialog.h"
97 #include "export_object_dialog.h"
98 #include "export_pdu_dialog.h"
100 #include "extcap_options_dialog.h"
102 #include "filter_action.h"
103 #include "filter_dialog.h"
104 #include "funnel_statistics.h"
105 #include "gsm_map_summary_dialog.h"
106 #include "iax2_analysis_dialog.h"
107 #include "io_graph_dialog.h"
108 #include "lbm_stream_dialog.h"
109 #include "lbm_uimflow_dialog.h"
110 #include "lbm_lbtrm_transport_dialog.h"
111 #include "lbm_lbtru_transport_dialog.h"
112 #include "lte_mac_statistics_dialog.h"
113 #include "lte_rlc_statistics_dialog.h"
114 #include "lte_rlc_graph_dialog.h"
115 #include "mtp3_summary_dialog.h"
116 #include "multicast_statistics_dialog.h"
117 #include "packet_comment_dialog.h"
118 #include "packet_dialog.h"
119 #include "packet_list.h"
120 #include "preferences_dialog.h"
121 #include "print_dialog.h"
122 #include "profile_dialog.h"
123 #include "protocol_hierarchy_dialog.h"
124 #include "qt_ui_utils.h"
125 #include "resolved_addresses_dialog.h"
126 #include "rpc_service_response_time_dialog.h"
127 #include "rtp_stream_dialog.h"
128 #include "rtp_analysis_dialog.h"
129 #include "sctp_all_assocs_dialog.h"
130 #include "sctp_assoc_analyse_dialog.h"
131 #include "sctp_graph_dialog.h"
132 #include "sequence_dialog.h"
133 #include "stats_tree_dialog.h"
134 #include "stock_icon.h"
135 #include "supported_protocols_dialog.h"
136 #include "tap_parameter_dialog.h"
137 #include "tcp_stream_dialog.h"
138 #include "time_shift_dialog.h"
139 #include "uat_dialog.h"
140 #include "voip_calls_dialog.h"
141 #include "wireshark_application.h"
142 #include "wlan_statistics_dialog.h"
144 #include <QClipboard>
146 #include <QMessageBox>
147 #include <QMetaObject>
149 #include <QDesktopServices>
157 static const char *dfe_property_ = "display filter expression"; //TODO : Fix Translate
159 // We're too lazy to sublcass QAction.
160 static const char *color_number_property_ = "color number";
162 bool MainWindow::openCaptureFile(QString cf_path, QString read_filter, unsigned int type)
164 QString file_name = "";
165 dfilter_t *rfcode = NULL;
170 // was a file name given as function parameter?
171 name_param = !cf_path.isEmpty();
175 if (cf_path.isEmpty()) {
176 CaptureFileDialog open_dlg(this, capture_file_.capFile(), read_filter);
178 switch (prefs.gui_fileopen_style) {
180 case FO_STYLE_LAST_OPENED:
181 /* The user has specified that we should start out in the last directory
182 we looked in. If we've already opened a file, use its containing
183 directory, if we could determine it, as the directory, otherwise
184 use the "last opened" directory saved in the preferences file if
186 /* This is now the default behaviour in file_selection_new() */
189 case FO_STYLE_SPECIFIED:
190 /* The user has specified that we should always start out in a
191 specified directory; if they've specified that directory,
192 start out by showing the files in that dir. */
193 if (prefs.gui_fileopen_dir[0] != '\0')
194 open_dlg.setDirectory(prefs.gui_fileopen_dir);
198 if (open_dlg.open(file_name, type)) {
205 if (!testCaptureFileClose(false)) {
209 if (dfilter_compile(read_filter.toUtf8().constData(), &rfcode, &err_msg)) {
210 cf_set_rfcode(CaptureFile::globalCapFile(), rfcode);
212 /* Not valid. Tell the user, and go back and run the file
213 selection box again once they dismiss the alert. */
214 //bad_dfilter_alert_box(top_level, read_filter->str);
215 QMessageBox::warning(this, tr("Invalid Display Filter"),
216 QString("The filter expression ") +
218 QString(" isn't a valid display filter. (") +
219 err_msg + QString(")."),
223 // go back to the selection dialogue only if the file
224 // was selected from this dialogue
230 /* Try to open the capture file. This closes the current file if it succeeds. */
231 CaptureFile::globalCapFile()->window = this;
232 if (cf_open(CaptureFile::globalCapFile(), cf_path.toUtf8().constData(), type, FALSE, &err) != CF_OK) {
233 /* We couldn't open it; don't dismiss the open dialog box,
234 just leave it around so that the user can, after they
235 dismiss the alert box popped up for the open error,
237 CaptureFile::globalCapFile()->window = NULL;
239 dfilter_free(rfcode);
244 switch (cf_read(CaptureFile::globalCapFile(), FALSE)) {
248 /* Just because we got an error, that doesn't mean we were unable
249 to read any of the file; we handle what we could get from the
253 case CF_READ_ABORTED:
254 /* The user bailed out of re-reading the capture file; the
255 capture file has been closed - just free the capture file name
256 string and return (without changing the last containing
258 capture_file_.setCapFile(NULL);
263 // get_dirname overwrites its path. Hopefully this isn't a problem.
264 wsApp->setLastOpenDir(get_dirname(cf_path.toUtf8().data()));
266 main_ui_->statusBar->showExpert();
271 void MainWindow::filterPackets(QString new_filter, bool force)
273 cf_status_t cf_status;
275 cf_status = cf_filter_packets(CaptureFile::globalCapFile(), new_filter.toUtf8().data(), force);
277 if (cf_status == CF_OK) {
278 emit displayFilterSuccess(true);
279 if (new_filter.length() > 0) {
280 int index = df_combo_box_->findText(new_filter);
282 df_combo_box_->insertItem(0, new_filter);
283 df_combo_box_->setCurrentIndex(0);
285 df_combo_box_->setCurrentIndex(index);
288 df_combo_box_->lineEdit()->clear();
291 emit displayFilterSuccess(false);
295 // A new layout should be applied when it differs from the old layout AND
296 // at the following times:
298 // - When the preferences change
299 // - When the profile changes
300 void MainWindow::layoutPanes()
302 QVector<unsigned> new_layout = QVector<unsigned>() << prefs.gui_layout_type
303 << prefs.gui_layout_content_1
304 << prefs.gui_layout_content_2
305 << prefs.gui_layout_content_3;
306 if (cur_layout_ == new_layout) return;
308 QSplitter *parents[3];
309 int current_row = capture_file_.currentRow();
311 // Reparent all widgets and add them back in the proper order below.
312 // This hides each widget as well.
313 packet_list_->freeze(); // Clears tree and byte view tabs.
314 packet_list_->setParent(main_ui_->mainStack);
315 proto_tree_->setParent(main_ui_->mainStack);
316 byte_view_tab_->setParent(main_ui_->mainStack);
317 empty_pane_.setParent(main_ui_->mainStack);
318 extra_split_.setParent(main_ui_->mainStack);
320 // XXX We should try to preserve geometries if we can, e.g. by
321 // checking to see if the layout type is the same.
322 switch(prefs.gui_layout_type) {
325 extra_split_.setOrientation(Qt::Horizontal);
328 master_split_.setOrientation(Qt::Vertical);
333 extra_split_.setOrientation(Qt::Vertical);
336 master_split_.setOrientation(Qt::Horizontal);
340 g_assert_not_reached();
343 switch(prefs.gui_layout_type) {
346 parents[0] = &master_split_;
347 parents[1] = &master_split_;
348 parents[2] = &master_split_;
352 parents[0] = &master_split_;
353 parents[1] = &extra_split_;
354 parents[2] = &extra_split_;
358 parents[0] = &extra_split_;
359 parents[1] = &extra_split_;
360 parents[2] = &master_split_;
363 g_assert_not_reached();
366 if (parents[0] == &extra_split_) {
367 master_split_.addWidget(&extra_split_);
370 parents[0]->addWidget(getLayoutWidget(prefs.gui_layout_content_1));
372 if (parents[2] == &extra_split_) {
373 master_split_.addWidget(&extra_split_);
376 parents[1]->addWidget(getLayoutWidget(prefs.gui_layout_content_2));
377 parents[2]->addWidget(getLayoutWidget(prefs.gui_layout_content_3));
379 const QList<QWidget *> ms_children = master_split_.findChildren<QWidget *>();
381 extra_split_.setVisible(ms_children.contains(&extra_split_));
382 packet_list_->setVisible(ms_children.contains(packet_list_) && recent.packet_list_show);
383 proto_tree_->setVisible(ms_children.contains(proto_tree_) && recent.tree_view_show);
384 byte_view_tab_->setVisible(ms_children.contains(byte_view_tab_) && recent.byte_view_show);
386 packet_list_->thaw();
387 cf_select_packet(capture_file_.capFile(), current_row); // XXX Doesn't work for row 0?
388 cur_layout_ = new_layout;
391 // The recent layout geometry should be applied after the layout has been
392 // applied AND at the following times:
394 // - When the profile changes
395 void MainWindow::applyRecentPaneGeometry()
397 // XXX This shrinks slightly each time the application is run. For some
398 // reason the master_split_ geometry is two pixels shorter when
399 // saveWindowGeometry is invoked.
401 // This is also an awful lot of trouble to go through to reuse the GTK+
402 // pane settings. We might want to add gui.geometry_main_master_sizes
403 // and gui.geometry_main_extra_sizes and save QSplitter::saveState in
406 // Force a geometry recalculation
407 QWidget *cur_w = main_ui_->mainStack->currentWidget();
408 main_ui_->mainStack->setCurrentWidget(&master_split_);
409 QRect geom = master_split_.geometry();
410 QList<int> master_sizes = master_split_.sizes();
411 QList<int> extra_sizes = extra_split_.sizes();
412 main_ui_->mainStack->setCurrentWidget(cur_w);
414 int master_last_size = master_split_.orientation() == Qt::Vertical ? geom.height() : geom.width();
415 int extra_last_size = extra_split_.orientation() == Qt::Vertical ? geom.height() : geom.width();
417 if (recent.gui_geometry_main_upper_pane > 0) {
418 master_sizes[0] = recent.gui_geometry_main_upper_pane + 1; // Add back mystery pixel
419 master_last_size -= recent.gui_geometry_main_upper_pane + master_split_.handleWidth();
422 if (recent.gui_geometry_main_lower_pane > 0) {
423 if (master_sizes.length() > 2) {
424 master_sizes[1] = recent.gui_geometry_main_lower_pane + 1; // Add back mystery pixel
425 master_last_size -= recent.gui_geometry_main_lower_pane + master_split_.handleWidth();
426 } else if (extra_sizes.length() > 0) {
427 extra_sizes[0] = recent.gui_geometry_main_lower_pane; // No mystery pixel
428 extra_last_size -= recent.gui_geometry_main_lower_pane + extra_split_.handleWidth();
429 extra_sizes.last() = extra_last_size;
433 master_sizes.last() = master_last_size;
435 master_split_.setSizes(master_sizes);
436 extra_split_.setSizes(extra_sizes);
439 void MainWindow::layoutToolbars()
441 Qt::ToolButtonStyle tbstyle = Qt::ToolButtonIconOnly;
442 switch (prefs.gui_toolbar_main_style) {
444 tbstyle = Qt::ToolButtonTextOnly;
447 tbstyle = Qt::ToolButtonTextUnderIcon;
451 main_ui_->mainToolBar->setToolButtonStyle(tbstyle);
454 void MainWindow::updatePreferenceActions()
456 main_ui_->actionViewNameResolutionPhysical->setChecked(gbl_resolv_flags.mac_name);
457 main_ui_->actionViewNameResolutionNetwork->setChecked(gbl_resolv_flags.network_name);
458 main_ui_->actionViewNameResolutionTransport->setChecked(gbl_resolv_flags.transport_name);
460 // Should this be a "recent" setting?
461 main_ui_->actionGoAutoScroll->setChecked(prefs.capture_auto_scroll);
464 void MainWindow::filterAction(QString &action_filter, FilterAction::Action action, FilterAction::ActionType type)
466 QString cur_filter, new_filter;
468 if (!df_combo_box_) return;
469 cur_filter = df_combo_box_->lineEdit()->text();
472 case FilterAction::ActionTypePlain:
473 new_filter = action_filter;
475 case FilterAction::ActionTypeAnd:
476 if (cur_filter.length()) {
477 new_filter = "(" + cur_filter + ") && (" + action_filter + ")";
479 new_filter = action_filter;
482 case FilterAction::ActionTypeOr:
483 if (cur_filter.length()) {
484 new_filter = "(" + cur_filter + ") || (" + action_filter + ")";
486 new_filter = action_filter;
489 case FilterAction::ActionTypeNot:
490 new_filter = "!(" + action_filter + ")";
492 case FilterAction::ActionTypeAndNot:
493 if (cur_filter.length()) {
494 new_filter = "(" + cur_filter + ") && !(" + action_filter + ")";
496 new_filter = "!(" + action_filter + ")";
499 case FilterAction::ActionTypeOrNot:
500 if (cur_filter.length()) {
501 new_filter = "(" + cur_filter + ") || !(" + action_filter + ")";
503 new_filter = "!(" + action_filter + ")";
507 g_assert_not_reached();
512 case FilterAction::ActionApply:
513 df_combo_box_->lineEdit()->setText(new_filter);
514 df_combo_box_->applyDisplayFilter();
516 case FilterAction::ActionPrepare:
517 df_combo_box_->lineEdit()->setText(new_filter);
518 df_combo_box_->lineEdit()->setFocus();
520 case FilterAction::ActionWebLookup:
522 QString url = QString("https://www.google.com/search?q=") + new_filter;
523 QDesktopServices::openUrl(QUrl(url));
526 case FilterAction::ActionCopy:
527 wsApp->clipboard()->setText(new_filter);
530 qDebug() << "FIX FilterAction::Action" << action << "not implemented";
537 void MainWindow::captureCapturePrepared(capture_session *) {
539 setTitlebarForCaptureInProgress();
541 setWindowIcon(wsApp->captureIcon());
543 /* Disable menu items that make no sense if you're currently running
545 setForCaptureInProgress(true);
546 // set_capture_if_dialog_for_capture_in_progress(TRUE);
548 // /* Don't set up main window for a capture file. */
549 // main_set_for_capture_file(FALSE);
550 main_ui_->mainStack->setCurrentWidget(&master_split_);
551 #endif // HAVE_LIBPCAP
554 void MainWindow::captureCaptureUpdateStarted(capture_session *) {
557 /* We've done this in "prepared" above, but it will be cleared while
558 switching to the next multiple file. */
559 setTitlebarForCaptureInProgress();
561 setForCaptureInProgress(true);
563 setForCapturedPackets(true);
564 #endif // HAVE_LIBPCAP
566 void MainWindow::captureCaptureUpdateFinished(capture_session *) {
569 /* The capture isn't stopping any more - it's stopped. */
570 capture_stopping_ = false;
572 /* Update the main window as appropriate */
573 updateForUnsavedChanges();
575 /* Enable menu items that make sense if you're not currently running
577 setForCaptureInProgress(false);
579 setWindowIcon(wsApp->normalIcon());
581 if (global_capture_opts.quit_after_cap) {
582 // Command line asked us to quit after capturing.
583 // Don't pop up a dialog to ask for unsaved files etc.
586 #endif // HAVE_LIBPCAP
588 void MainWindow::captureCaptureFixedStarted(capture_session *) {
590 #endif // HAVE_LIBPCAP
592 void MainWindow::captureCaptureFixedFinished(capture_session *) {
595 /* The capture isn't stopping any more - it's stopped. */
596 capture_stopping_ = false;
598 /* Enable menu items that make sense if you're not currently running
600 setForCaptureInProgress(false);
602 setWindowIcon(wsApp->normalIcon());
604 if (global_capture_opts.quit_after_cap) {
605 // Command line asked us to quit after capturing.
606 // Don't pop up a dialog to ask for unsaved files etc.
609 #endif // HAVE_LIBPCAP
611 void MainWindow::captureCaptureStopping(capture_session *) {
614 capture_stopping_ = true;
615 setMenusForCaptureStopping();
616 #endif // HAVE_LIBPCAP
618 void MainWindow::captureCaptureFailed(capture_session *) {
620 /* Capture isn't stopping any more. */
621 capture_stopping_ = false;
623 setForCaptureInProgress(false);
624 main_ui_->mainStack->setCurrentWidget(main_welcome_);
626 setWindowIcon(wsApp->normalIcon());
628 if (global_capture_opts.quit_after_cap) {
629 // Command line asked us to quit after capturing.
630 // Don't pop up a dialog to ask for unsaved files etc.
633 #endif // HAVE_LIBPCAP
637 // Callbacks from cfile.c and file.c via CaptureFile::captureFileCallback
639 void MainWindow::captureFileOpened() {
640 if (capture_file_.window() != this) return;
642 file_set_dialog_.fileOpened(capture_file_.capFile());
643 setMenusForFileSet(true);
644 emit setCaptureFile(capture_file_.capFile());
647 void MainWindow::captureFileReadStarted(const QString &action) {
648 // tap_param_dlg_update();
650 /* Set up main window for a capture file. */
651 // main_set_for_capture_file(TRUE);
653 main_ui_->statusBar->popFileStatus();
654 QString msg = QString(tr("%1: %2")).arg(action).arg(capture_file_.fileName());
655 QString msgtip = QString();
656 main_ui_->statusBar->pushFileStatus(msg, msgtip);
657 main_ui_->mainStack->setCurrentWidget(&master_split_);
658 WiresharkApplication::processEvents();
661 void MainWindow::captureFileReadFinished() {
664 if (!capture_file_.capFile()->is_tempfile && capture_file_.capFile()->filename) {
665 /* Add this filename to the list of recent files in the "Recent Files" submenu */
666 add_menu_recent_capture_file(capture_file_.capFile()->filename);
668 /* Remember folder for next Open dialog and save it in recent */
669 dir_path = get_dirname(g_strdup(capture_file_.capFile()->filename));
670 wsApp->setLastOpenDir(dir_path);
674 /* Update the appropriate parts of the main window. */
675 updateForUnsavedChanges();
677 /* Enable menu items that make sense if you have some captured packets. */
678 setForCapturedPackets(true);
680 main_ui_->statusBar->setFileName(capture_file_);
682 packet_list_->captureFileReadFinished();
684 emit setDissectedCaptureFile(capture_file_.capFile());
687 void MainWindow::captureFileRetapStarted()
689 // XXX Push a status message?
693 void MainWindow::captureFileRetapFinished()
698 void MainWindow::captureFileClosing() {
699 setMenusForCaptureFile(true);
700 setForCapturedPackets(false);
701 setMenusForSelectedPacket();
702 setForCaptureInProgress(false);
704 // Reset expert information indicator
705 main_ui_->statusBar->captureFileClosing();
706 main_ui_->searchFrame->animatedHide();
707 // gtk_widget_show(expert_info_none);
708 emit setCaptureFile(NULL);
709 emit setDissectedCaptureFile(NULL);
712 void MainWindow::captureFileClosed() {
713 packets_bar_update();
715 file_set_dialog_.fileClosed();
716 setMenusForFileSet(false);
717 setWindowModified(false);
719 // Reset expert information indicator
720 main_ui_->statusBar->captureFileClosing();
722 main_ui_->statusBar->popFileStatus();
724 setTitlebarForSelectedTreeRow();
725 setMenusForSelectedTreeRow();
727 if (!global_capture_opts.multi_files_on)
728 main_ui_->mainStack->setCurrentWidget(main_welcome_);
731 void MainWindow::captureFileSaveStarted(const QString &file_path)
733 QFileInfo file_info(file_path);
734 main_ui_->statusBar->popFileStatus();
735 main_ui_->statusBar->pushFileStatus(tr("Saving %1" UTF8_HORIZONTAL_ELLIPSIS).arg(file_info.baseName()));
738 void MainWindow::filterExpressionsChanged()
740 // Recreate filter buttons
741 foreach (QAction *act, main_ui_->displayFilterToolBar->actions()) {
742 // Permanent actions shouldn't have data
743 if (act->property(dfe_property_).isValid()) {
744 main_ui_->displayFilterToolBar->removeAction(act);
749 // XXX Add a context menu for removing and changing buttons.
750 for (struct filter_expression *fe = *pfilter_expression_head; fe != NULL; fe = fe->next) {
751 if (!fe->enabled) continue;
752 QAction *dfb_action = new QAction(fe->label, main_ui_->displayFilterToolBar);
753 dfb_action->setToolTip(fe->expression);
754 dfb_action->setData(fe->expression);
755 dfb_action->setProperty(dfe_property_, true);
756 main_ui_->displayFilterToolBar->addAction(dfb_action);
757 connect(dfb_action, SIGNAL(triggered()), this, SLOT(displayFilterButtonClicked()));
765 // ui/gtk/capture_dlg.c:start_capture_confirmed
767 void MainWindow::startCapture() {
769 interface_options interface_opts;
772 /* did the user ever select a capture interface before? */
773 if(global_capture_opts.num_selected == 0) {
774 QString msg = QString(tr("No interface selected"));
775 main_ui_->statusBar->pushTemporaryStatus(msg);
776 main_ui_->actionCaptureStart->setChecked(false);
780 main_ui_->mainStack->setCurrentWidget(&master_split_);
782 // Ideally we should have disabled the start capture
783 // toolbar buttons and menu items. This may not be the
784 // case, e.g. with QtMacExtras.
785 if(!capture_filter_valid_) {
786 QString msg = QString(tr("Invalid capture filter"));
787 main_ui_->statusBar->pushTemporaryStatus(msg);
788 main_ui_->actionCaptureStart->setChecked(false);
792 /* XXX - we might need to init other pref data as well... */
794 /* XXX - can this ever happen? */
795 if (cap_session_.state != CAPTURE_STOPPED)
798 /* close the currently loaded capture file */
799 cf_close((capture_file *) cap_session_.cf);
801 /* Copy the selected interfaces to the set of interfaces to use for
803 collect_ifaces(&global_capture_opts);
805 CaptureFile::globalCapFile()->window = this;
806 if (capture_start(&global_capture_opts, &cap_session_, main_window_update)) {
807 capture_options *capture_opts = cap_session_.capture_opts;
808 GString *interface_names;
810 /* enable autoscroll timer as needed. */
811 packet_list_->setAutoScroll(main_ui_->actionGoAutoScroll->isChecked());
813 /* Add "interface name<live capture in progress>" on main status bar */
814 interface_names = get_iface_list_string(capture_opts, 0);
815 if (strlen (interface_names->str) > 0) {
816 g_string_append(interface_names, ":");
818 g_string_append(interface_names, " ");
820 main_ui_->statusBar->popFileStatus();
821 QString msg = QString().sprintf("%s<live capture in progress>", interface_names->str);
822 QString msgtip = QString().sprintf("to file: %s", (capture_opts->save_file) ? capture_opts->save_file : "");
823 main_ui_->statusBar->pushFileStatus(msg, msgtip);
824 g_string_free(interface_names, TRUE);
826 /* The capture succeeded, which means the capture filter syntax is
827 valid; add this capture filter to the recent capture filter list. */
828 for (i = 0; i < global_capture_opts.ifaces->len; i++) {
829 interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
830 if (interface_opts.cfilter) {
831 // cfilter_combo_add_recent(interface_opts.cfilter);
835 CaptureFile::globalCapFile()->window = NULL;
837 #endif // HAVE_LIBPCAP
840 // Copied from ui/gtk/gui_utils.c
841 void MainWindow::pipeTimeout() {
845 gboolean result, result1;
850 /* try to read data from the pipe only 5 times, to avoid blocking */
851 while(iterations < 5) {
852 /*g_log(NULL, G_LOG_LEVEL_DEBUG, "pipe_timer_cb: new iteration");*/
854 /* Oddly enough although Named pipes don't work on win9x,
855 PeekNamedPipe does !!! */
856 handle = (HANDLE) _get_osfhandle (pipe_source_);
857 result = PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL);
859 /* Get the child process exit status */
860 result1 = GetExitCodeProcess((HANDLE)*(pipe_child_process_),
863 /* If the Peek returned an error, or there are bytes to be read
864 or the childwatcher thread has terminated then call the normal
866 if (!result || avail > 0 || childstatus != STILL_ACTIVE) {
868 /*g_log(NULL, G_LOG_LEVEL_DEBUG, "pipe_timer_cb: data avail");*/
870 /* And call the real handler */
871 if (!pipe_input_cb_(pipe_source_, pipe_user_data_)) {
872 g_log(NULL, G_LOG_LEVEL_DEBUG, "pipe_timer_cb: input pipe closed, iterations: %u", iterations);
873 /* pipe closed, return false so that the old timer is not run again */
879 /*g_log(NULL, G_LOG_LEVEL_DEBUG, "pipe_timer_cb: no data avail");*/
880 /* No data, stop now */
889 void MainWindow::pipeActivated(int source) {
893 g_assert(source == pipe_source_);
895 pipe_notifier_->setEnabled(false);
896 if (pipe_input_cb_(pipe_source_, pipe_user_data_)) {
897 pipe_notifier_->setEnabled(true);
899 delete pipe_notifier_;
904 void MainWindow::pipeNotifierDestroyed() {
908 pipe_notifier_ = NULL;
912 void MainWindow::stopCapture() {
913 //#ifdef HAVE_AIRPCAP
914 // if (airpcap_if_active)
915 // airpcap_set_toolbar_stop_capture(airpcap_if_active);
919 capture_stop(&cap_session_);
920 #endif // HAVE_LIBPCAP
922 /* Pop the "<live capture in progress>" message off the status bar. */
923 main_ui_->statusBar->setFileName(capture_file_);
925 /* disable autoscroll timer if any. */
926 packet_list_->setAutoScroll(false);
929 // Keep focus rects from showing through the welcome screen. Primarily for
931 void MainWindow::mainStackChanged(int)
933 for (int i = 0; i < main_ui_->mainStack->count(); i++) {
934 main_ui_->mainStack->widget(i)->setEnabled(i == main_ui_->mainStack->currentIndex());
938 // XXX - Copied from ui/gtk/menus.c
941 * Add the capture filename (with an absolute path) to the "Recent Files" menu.
943 // XXX - We should probably create a RecentFile class.
944 void MainWindow::updateRecentFiles() {
946 QMenu *recentMenu = main_ui_->menuOpenRecentCaptureFile;
947 QString action_cf_name;
955 /* Iterate through the actions in menuOpenRecentCaptureFile,
956 * removing special items, a maybe duplicate entry and every item above count_max */
957 int shortcut = Qt::Key_0;
958 foreach (recent_item_status *ri, wsApp->recentItems()) {
960 ra = new QAction(recentMenu);
961 ra->setData(ri->filename);
962 // XXX - Needs get_recent_item_status or equivalent
963 ra->setEnabled(ri->accessible);
964 recentMenu->insertAction(NULL, ra);
965 action_cf_name = ra->data().toString();
966 if (shortcut <= Qt::Key_9) {
967 ra->setShortcut(Qt::META | shortcut);
970 ra->setText(action_cf_name);
971 connect(ra, SIGNAL(triggered()), this, SLOT(recentActionTriggered()));
974 if (recentMenu->actions().count() > 0) {
975 // Separator + "Clear"
976 // XXX - Do we really need this?
977 ra = new QAction(recentMenu);
978 ra->setSeparator(true);
979 recentMenu->insertAction(NULL, ra);
981 ra = new QAction(recentMenu);
982 ra->setText(tr("Clear Menu"));
983 recentMenu->insertAction(NULL, ra);
984 connect(ra, SIGNAL(triggered()), wsApp, SLOT(clearRecentItems()));
986 if (main_ui_->actionDummyNoFilesFound) {
987 recentMenu->addAction(main_ui_->actionDummyNoFilesFound);
992 void MainWindow::recentActionTriggered() {
993 QAction *ra = qobject_cast<QAction*>(sender());
996 QString cfPath = ra->data().toString();
997 openCaptureFile(cfPath);
1001 void MainWindow::setMenusForSelectedPacket()
1003 gboolean is_ip = FALSE, is_tcp = FALSE, is_udp = FALSE, is_sctp = FALSE, is_ssl = FALSE, is_rtp = FALSE, is_lte_rlc = FALSE;
1005 /* Making the menu context-sensitive allows for easier selection of the
1006 desired item and has the added benefit, with large captures, of
1007 avoiding needless looping through huge lists for marked, ignored,
1008 or time-referenced packets. */
1010 /* We have one or more items in the packet list */
1011 bool have_frames = false;
1012 /* A frame is selected */
1013 bool frame_selected = false;
1014 /* We have marked frames. (XXX - why check frame_selected?) */
1015 bool have_marked = false;
1016 /* We have a marked frame other than the current frame (i.e.,
1017 we have at least one marked frame, and either there's more
1018 than one marked frame or the current frame isn't marked). */
1019 bool another_is_marked = false;
1020 /* One or more frames are hidden by a display filter */
1021 bool have_filtered = false;
1022 /* One or more frames have been ignored */
1023 bool have_ignored = false;
1024 bool have_time_ref = false;
1025 /* We have a time reference frame other than the current frame (i.e.,
1026 we have at least one time reference frame, and either there's more
1027 than one time reference frame or the current frame isn't a
1028 time reference frame). (XXX - why check frame_selected?) */
1029 bool another_is_time_ref = false;
1030 /* We have a valid filter expression */
1031 bool have_filter_expr = false;
1033 QList<QAction *> cc_actions = QList<QAction *>()
1034 << main_ui_->actionViewColorizeConversation1 << main_ui_->actionViewColorizeConversation2
1035 << main_ui_->actionViewColorizeConversation3 << main_ui_->actionViewColorizeConversation4
1036 << main_ui_->actionViewColorizeConversation5 << main_ui_->actionViewColorizeConversation6
1037 << main_ui_->actionViewColorizeConversation7 << main_ui_->actionViewColorizeConversation8
1038 << main_ui_->actionViewColorizeConversation9 << main_ui_->actionViewColorizeConversation10;
1040 if (capture_file_.capFile()) {
1041 frame_selected = capture_file_.capFile()->current_frame != NULL;
1042 have_frames = capture_file_.capFile()->count > 0;
1043 have_marked = frame_selected && capture_file_.capFile()->marked_count > 0;
1044 another_is_marked = have_marked &&
1045 !(capture_file_.capFile()->marked_count == 1 && capture_file_.capFile()->current_frame->flags.marked);
1046 have_filtered = capture_file_.capFile()->displayed_count > 0 && capture_file_.capFile()->displayed_count != capture_file_.capFile()->count;
1047 have_ignored = capture_file_.capFile()->ignored_count > 0;
1048 have_time_ref = capture_file_.capFile()->ref_time_count > 0;
1049 another_is_time_ref = frame_selected && have_time_ref &&
1050 !(capture_file_.capFile()->ref_time_count == 1 && capture_file_.capFile()->current_frame->flags.ref_time);
1052 if (capture_file_.capFile()->edt)
1054 proto_get_frame_protocols(capture_file_.capFile()->edt->pi.layers,
1055 &is_ip, &is_tcp, &is_udp, &is_sctp,
1056 &is_ssl, &is_rtp, &is_lte_rlc);
1060 have_filter_expr = !packet_list_->getFilterFromRowAndColumn().isEmpty();
1062 main_ui_->actionEditMarkPacket->setEnabled(frame_selected);
1063 main_ui_->actionEditMarkAllDisplayed->setEnabled(have_frames);
1064 /* Unlike un-ignore, do not allow unmark of all frames when no frames are displayed */
1065 main_ui_->actionEditUnmarkAllDisplayed->setEnabled(have_marked);
1066 main_ui_->actionEditNextMark->setEnabled(another_is_marked);
1067 main_ui_->actionEditPreviousMark->setEnabled(another_is_marked);
1069 #ifdef WANT_PACKET_EDITOR
1070 // set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/EditMenu/EditPacket",
1072 #endif // WANT_PACKET_EDITOR
1073 main_ui_->actionEditPacketComment->setEnabled(frame_selected && wtap_dump_can_write(capture_file_.capFile()->linktypes, WTAP_COMMENT_PER_PACKET));
1075 main_ui_->actionEditIgnorePacket->setEnabled(frame_selected);
1076 main_ui_->actionEditIgnoreAllDisplayed->setEnabled(have_filtered);
1077 /* Allow un-ignore of all frames even with no frames currently displayed */
1078 main_ui_->actionEditUnignoreAllDisplayed->setEnabled(have_ignored);
1080 main_ui_->actionEditSetTimeReference->setEnabled(frame_selected);
1081 main_ui_->actionEditUnsetAllTimeReferences->setEnabled(have_time_ref);
1082 main_ui_->actionEditNextTimeReference->setEnabled(another_is_time_ref);
1083 main_ui_->actionEditPreviousTimeReference->setEnabled(another_is_time_ref);
1084 main_ui_->actionEditTimeShift->setEnabled(have_frames);
1086 main_ui_->actionGoGoToLinkedPacket->setEnabled(false);
1088 main_ui_->actionAnalyzeAAFSelected->setEnabled(have_filter_expr);
1089 main_ui_->actionAnalyzeAAFNotSelected->setEnabled(have_filter_expr);
1090 main_ui_->actionAnalyzeAAFAndSelected->setEnabled(have_filter_expr);
1091 main_ui_->actionAnalyzeAAFOrSelected->setEnabled(have_filter_expr);
1092 main_ui_->actionAnalyzeAAFAndNotSelected->setEnabled(have_filter_expr);
1093 main_ui_->actionAnalyzeAAFOrNotSelected->setEnabled(have_filter_expr);
1095 main_ui_->actionAnalyzePAFSelected->setEnabled(have_filter_expr);
1096 main_ui_->actionAnalyzePAFNotSelected->setEnabled(have_filter_expr);
1097 main_ui_->actionAnalyzePAFAndSelected->setEnabled(have_filter_expr);
1098 main_ui_->actionAnalyzePAFOrSelected->setEnabled(have_filter_expr);
1099 main_ui_->actionAnalyzePAFAndNotSelected->setEnabled(have_filter_expr);
1100 main_ui_->actionAnalyzePAFOrNotSelected->setEnabled(have_filter_expr);
1102 main_ui_->actionAnalyzeFollowTCPStream->setEnabled(is_tcp);
1103 main_ui_->actionAnalyzeFollowUDPStream->setEnabled(is_udp);
1104 main_ui_->actionAnalyzeFollowSSLStream->setEnabled(is_ssl);
1106 foreach (QAction *cc_action, cc_actions) {
1107 cc_action->setEnabled(frame_selected);
1109 main_ui_->actionViewColorizeNewConversationRule->setEnabled(frame_selected);
1111 main_ui_->actionViewColorizeResetColorization->setEnabled(tmp_color_filters_used());
1113 main_ui_->actionViewColorizeNewConversationRule->setEnabled(frame_selected);
1115 main_ui_->actionViewShowPacketInNewWindow->setEnabled(frame_selected);
1116 main_ui_->actionViewEditResolvedName->setEnabled(frame_selected && is_ip);
1118 main_ui_->menuConversationFilter->clear();
1120 packet_list_->conversationMenu()->clear();
1121 packet_list_->colorizeMenu()->clear();
1123 for (GList *conv_filter_list_entry = conv_filter_list; conv_filter_list_entry; conv_filter_list_entry = g_list_next(conv_filter_list_entry)) {
1125 conversation_filter_t* conv_filter = (conversation_filter_t *)conv_filter_list_entry->data;
1126 QAction *conv_action = main_ui_->menuConversationFilter->addAction(conv_filter->display_name);
1128 bool enable = false;
1130 if (capture_file_.capFile()->edt) {
1131 enable = conv_filter->is_filter_valid(&capture_file_.capFile()->edt->pi);
1132 filter = gchar_free_to_qstring(conv_filter->build_filter_string(&capture_file_.capFile()->edt->pi));
1134 conv_action->setEnabled(enable);
1135 conv_action->setData(filter);
1136 connect(conv_action, SIGNAL(triggered()), this, SLOT(applyConversationFilter()));
1138 // Packet list context menu items
1139 packet_list_->conversationMenu()->addAction(conv_action);
1141 QMenu *submenu = packet_list_->colorizeMenu()->addMenu(conv_action->text());
1143 foreach (QAction *cc_action, cc_actions) {
1144 QAction *colorize_action = submenu->addAction(cc_action->icon(), cc_action->text());
1145 colorize_action->setProperty(color_number_property_, i++);
1146 colorize_action->setData(filter);
1147 colorize_action->setEnabled(enable);
1148 connect(colorize_action, SIGNAL(triggered()), this, SLOT(colorizeWithFilter()));
1151 QAction *conv_rule_action = submenu->addAction(main_ui_->actionViewColorizeNewConversationRule->text());
1152 conv_rule_action->setData(conv_action->data());
1153 conv_rule_action->setEnabled(enable);
1154 connect(conv_rule_action, SIGNAL(triggered()), this, SLOT(colorizeWithFilter()));
1157 // set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/ViewMenu/NameResolution/ResolveName",
1158 // frame_selected && (gbl_resolv_flags.mac_name || gbl_resolv_flags.network_name ||
1159 // gbl_resolv_flags.transport_name || gbl_resolv_flags.concurrent_dns));
1160 // set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/ToolsMenu/FirewallACLRules",
1162 main_ui_->menuTcpStreamGraphs->setEnabled(is_tcp);
1163 main_ui_->actionSCTPAnalyseThisAssociation->setEnabled(is_sctp);
1164 main_ui_->actionSCTPShowAllAssociations->setEnabled(is_sctp);
1165 main_ui_->actionSCTPFilterThisAssociation->setEnabled(is_sctp);
1166 main_ui_->actionTelephonyRTPStreamAnalysis->setEnabled(is_rtp);
1167 main_ui_->actionTelephonyLteRlcGraph->setEnabled(is_lte_rlc);
1170 void MainWindow::setMenusForSelectedTreeRow(field_info *fi) {
1172 bool can_match_selected = false;
1173 bool is_framenum = false;
1174 bool have_field_info = false;
1175 bool have_subtree = false;
1176 bool can_open_url = false;
1177 QString field_filter;
1180 QList<QAction *> cc_actions = QList<QAction *>()
1181 << main_ui_->actionViewColorizeConversation1 << main_ui_->actionViewColorizeConversation2
1182 << main_ui_->actionViewColorizeConversation3 << main_ui_->actionViewColorizeConversation4
1183 << main_ui_->actionViewColorizeConversation5 << main_ui_->actionViewColorizeConversation6
1184 << main_ui_->actionViewColorizeConversation7 << main_ui_->actionViewColorizeConversation8
1185 << main_ui_->actionViewColorizeConversation9 << main_ui_->actionViewColorizeConversation10;
1187 if (capture_file_.capFile()) {
1188 capture_file_.capFile()->finfo_selected = fi;
1190 if (fi && fi->tree_type != -1) {
1191 have_subtree = true;
1195 if (capture_file_.capFile() != NULL && fi != NULL) {
1196 header_field_info *hfinfo = fi->hfinfo;
1197 int linked_frame = -1;
1199 have_field_info = true;
1200 can_match_selected = proto_can_match_selected(capture_file_.capFile()->finfo_selected, capture_file_.capFile()->edt);
1201 if (hfinfo && hfinfo->type == FT_FRAMENUM) {
1203 linked_frame = fvalue_get_uinteger(&fi->value);
1206 char *tmp_field = proto_construct_match_selected_string(fi, capture_file_.capFile()->edt);
1207 field_filter = QString(tmp_field);
1208 wmem_free(NULL, tmp_field);
1210 field_id = fi->hfinfo->id;
1211 /* if the selected field isn't a protocol, get its parent */
1212 if (!proto_registrar_is_protocol(field_id)) {
1213 field_id = proto_registrar_get_parent(fi->hfinfo->id);
1216 if (field_id >= 0) {
1217 can_open_url = true;
1218 main_ui_->actionContextWikiProtocolPage->setData(field_id);
1219 main_ui_->actionContextFilterFieldReference->setData(field_id);
1221 main_ui_->actionContextWikiProtocolPage->setData(QVariant());
1222 main_ui_->actionContextFilterFieldReference->setData(QVariant());
1225 if (linked_frame > 0) {
1226 main_ui_->actionGoGoToLinkedPacket->setData(linked_frame);
1228 main_ui_->actionGoGoToLinkedPacket->setData(QVariant());
1232 // Always enable / disable the following items.
1233 main_ui_->actionFileExportPacketBytes->setEnabled(have_field_info);
1235 main_ui_->actionCopyAllVisibleItems->setEnabled(capture_file_.capFile() != NULL);
1236 main_ui_->actionCopyAllVisibleSelectedTreeItems->setEnabled(can_match_selected);
1237 main_ui_->actionEditCopyDescription->setEnabled(can_match_selected);
1238 main_ui_->actionEditCopyFieldName->setEnabled(can_match_selected);
1239 main_ui_->actionEditCopyValue->setEnabled(can_match_selected);
1240 main_ui_->actionEditCopyAsFilter->setEnabled(can_match_selected);
1242 main_ui_->actionViewExpandSubtrees->setEnabled(have_subtree);
1244 main_ui_->actionGoGoToLinkedPacket->setEnabled(is_framenum);
1246 main_ui_->actionAnalyzeCreateAColumn->setEnabled(can_match_selected);
1248 main_ui_->actionContextShowLinkedPacketInNewWindow->setEnabled(is_framenum);
1250 main_ui_->actionContextWikiProtocolPage->setEnabled(can_open_url);
1251 main_ui_->actionContextFilterFieldReference->setEnabled(can_open_url);
1254 // Only enable / disable the following items if we have focus so that we
1255 // don't clobber anything we may have set in setMenusForSelectedPacket.
1256 if (!proto_tree_ || !proto_tree_->hasFocus()) return;
1258 main_ui_->menuConversationFilter->clear();
1259 for (GList *conv_filter_list_entry = conv_filter_list; conv_filter_list_entry; conv_filter_list_entry = g_list_next(conv_filter_list_entry)) {
1260 conversation_filter_t* conv_filter = (conversation_filter_t *)conv_filter_list_entry->data;
1261 QAction *conv_action = main_ui_->menuConversationFilter->addAction(conv_filter->display_name);
1263 bool enable = false;
1265 if (capture_file_.capFile() && capture_file_.capFile()->edt) {
1266 enable = conv_filter->is_filter_valid(&capture_file_.capFile()->edt->pi);
1267 filter = conv_filter->build_filter_string(&capture_file_.capFile()->edt->pi);
1269 conv_action->setEnabled(enable);
1270 conv_action->setData(filter);
1271 connect(conv_action, SIGNAL(triggered()), this, SLOT(applyConversationFilter()));
1274 proto_tree_->colorizeMenu()->clear();
1276 foreach (QAction *cc_action, cc_actions) {
1277 QAction *colorize_action = proto_tree_->colorizeMenu()->addAction(cc_action->icon(), cc_action->text());
1278 colorize_action->setProperty(color_number_property_, i++);
1279 colorize_action->setData(field_filter);
1280 colorize_action->setEnabled(!field_filter.isEmpty());
1281 connect(colorize_action, SIGNAL(triggered()), this, SLOT(colorizeWithFilter()));
1284 QAction *conv_rule_action = proto_tree_->colorizeMenu()->addAction(main_ui_->actionViewColorizeNewConversationRule->text());
1285 conv_rule_action->setData(field_filter);
1286 conv_rule_action->setEnabled(!field_filter.isEmpty());
1287 connect(conv_rule_action, SIGNAL(triggered()), this, SLOT(colorizeWithFilter()));
1289 // set_menu_sensitivity(ui_manager_tree_view_menu, "/TreeViewPopup/ResolveName",
1290 // frame_selected && (gbl_resolv_flags.mac_name || gbl_resolv_flags.network_name ||
1291 // gbl_resolv_flags.transport_name || gbl_resolv_flags.concurrent_dns));
1294 main_ui_->actionAnalyzeAAFSelected->setEnabled(can_match_selected);
1295 main_ui_->actionAnalyzeAAFNotSelected->setEnabled(can_match_selected);
1296 main_ui_->actionAnalyzeAAFAndSelected->setEnabled(can_match_selected);
1297 main_ui_->actionAnalyzeAAFOrSelected->setEnabled(can_match_selected);
1298 main_ui_->actionAnalyzeAAFAndNotSelected->setEnabled(can_match_selected);
1299 main_ui_->actionAnalyzeAAFOrNotSelected->setEnabled(can_match_selected);
1301 main_ui_->actionAnalyzePAFSelected->setEnabled(can_match_selected);
1302 main_ui_->actionAnalyzePAFNotSelected->setEnabled(can_match_selected);
1303 main_ui_->actionAnalyzePAFAndSelected->setEnabled(can_match_selected);
1304 main_ui_->actionAnalyzePAFOrSelected->setEnabled(can_match_selected);
1305 main_ui_->actionAnalyzePAFAndNotSelected->setEnabled(can_match_selected);
1306 main_ui_->actionAnalyzePAFOrNotSelected->setEnabled(can_match_selected);
1309 void MainWindow::interfaceSelectionChanged()
1312 // XXX This doesn't disable the toolbar button when using
1314 if (global_capture_opts.num_selected > 0 && capture_filter_valid_) {
1315 main_ui_->actionCaptureStart->setEnabled(true);
1317 main_ui_->actionCaptureStart->setEnabled(false);
1319 #endif // HAVE_LIBPCAP
1322 void MainWindow::captureFilterSyntaxChanged(bool valid)
1324 capture_filter_valid_ = valid;
1325 interfaceSelectionChanged();
1328 void MainWindow::startInterfaceCapture(bool valid)
1330 capture_filter_valid_ = valid;
1334 void MainWindow::redissectPackets()
1336 if (capture_file_.capFile())
1337 cf_redissect_packets(capture_file_.capFile());
1338 main_ui_->statusBar->expertUpdate();
1340 proto_free_deregistered_fields();
1343 void MainWindow::fieldsChanged()
1345 color_filters_reload();
1346 tap_listeners_dfilter_recompile();
1348 if (!df_combo_box_->checkDisplayFilter()) {
1349 g_free(CaptureFile::globalCapFile()->dfilter);
1350 CaptureFile::globalCapFile()->dfilter = NULL;
1353 if (have_custom_cols(&CaptureFile::globalCapFile()->cinfo)) {
1354 // Recreate packet list columns according to new/changed/deleted fields
1355 packet_list_->fieldsChanged(CaptureFile::globalCapFile());
1358 emit reloadFields();
1361 void MainWindow::showAccordionFrame(AccordionFrame *show_frame, bool toggle)
1363 QList<AccordionFrame *>frame_list = QList<AccordionFrame *>()
1364 << main_ui_->goToFrame << main_ui_->searchFrame
1365 << main_ui_->addressEditorFrame << main_ui_->columnEditorFrame
1366 << main_ui_->preferenceEditorFrame;
1368 frame_list.removeAll(show_frame);
1369 foreach (AccordionFrame *af, frame_list) af->animatedHide();
1372 if (show_frame->isVisible()) {
1373 show_frame->animatedHide();
1377 show_frame->animatedShow();
1380 void MainWindow::showColumnEditor(int column)
1382 previous_focus_ = wsApp->focusWidget();
1383 connect(previous_focus_, SIGNAL(destroyed()), this, SLOT(resetPreviousFocus()));
1384 showAccordionFrame(main_ui_->columnEditorFrame);
1385 main_ui_->columnEditorFrame->editColumn(column);
1388 void MainWindow::showPreferenceEditor()
1390 showAccordionFrame(main_ui_->preferenceEditorFrame);
1393 void MainWindow::initViewColorizeMenu()
1395 QList<QAction *> cc_actions = QList<QAction *>()
1396 << main_ui_->actionViewColorizeConversation1 << main_ui_->actionViewColorizeConversation2
1397 << main_ui_->actionViewColorizeConversation3 << main_ui_->actionViewColorizeConversation4
1398 << main_ui_->actionViewColorizeConversation5 << main_ui_->actionViewColorizeConversation6
1399 << main_ui_->actionViewColorizeConversation7 << main_ui_->actionViewColorizeConversation8
1400 << main_ui_->actionViewColorizeConversation9 << main_ui_->actionViewColorizeConversation10;
1402 guint8 color_num = 1;
1404 foreach (QAction *cc_action, cc_actions) {
1405 cc_action->setData(color_num);
1406 connect(cc_action, SIGNAL(triggered()), this, SLOT(colorizeConversation()));
1408 const color_filter_t *colorf = color_filters_tmp_color(color_num);
1410 QColor bg = ColorUtils::fromColorT(colorf->bg_color);
1411 QColor fg = ColorUtils::fromColorT(colorf->fg_color);
1412 cc_action->setIcon(StockIcon::colorIcon(bg.rgb(), fg.rgb(), QString::number(color_num)));
1418 // Spotlight uses Cmd+Space
1419 main_ui_->actionViewColorizeResetColorization->setShortcut(QKeySequence("Meta+Space"));
1423 void MainWindow::addStatsPluginsToMenu() {
1424 GList *cfg_list = stats_tree_get_cfg_list();
1425 GList *iter = g_list_first(cfg_list);
1426 QAction *stats_tree_action;
1428 bool first_item = true;
1431 stats_tree_cfg *cfg = (stats_tree_cfg*)iter->data;
1434 main_ui_->menuStatistics->addSeparator();
1438 parent_menu = main_ui_->menuStatistics;
1439 // gtk/main_menubar.c compresses double slashes, hence SkipEmptyParts
1440 QStringList cfg_name_parts = QString(cfg->name).split("/", QString::SkipEmptyParts);
1441 if (cfg_name_parts.isEmpty()) continue;
1443 QString stat_name = cfg_name_parts.takeLast();
1444 if (!cfg_name_parts.isEmpty()) {
1445 QString menu_name = cfg_name_parts.join("/");
1446 parent_menu = findOrAddMenu(parent_menu, menu_name);
1449 stats_tree_action = new QAction(stat_name, this);
1450 stats_tree_action->setData(cfg->abbr);
1451 parent_menu->addAction(stats_tree_action);
1452 connect(stats_tree_action, SIGNAL(triggered()), this, SLOT(actionStatisticsPlugin_triggered()));
1454 iter = g_list_next(iter);
1456 g_list_free(cfg_list);
1459 void MainWindow::setFeaturesEnabled(bool enabled)
1461 main_ui_->menuBar->setEnabled(enabled);
1462 main_ui_->mainToolBar->setEnabled(enabled);
1463 main_ui_->displayFilterToolBar->setEnabled(enabled);
1466 main_ui_->statusBar->clearMessage();
1470 main_ui_->statusBar->showMessage(tr("Please wait while Wireshark is initializing" UTF8_HORIZONTAL_ELLIPSIS));
1474 // Display Filter Toolbar
1476 void MainWindow::on_actionDisplayFilterExpression_triggered()
1478 DisplayFilterExpressionDialog *dfe_dialog = new DisplayFilterExpressionDialog(this);
1480 connect(dfe_dialog, SIGNAL(insertDisplayFilter(QString)),
1481 df_combo_box_->lineEdit(), SLOT(insertFilter(const QString &)));
1486 void MainWindow::on_actionNewDisplayFilterExpression_triggered()
1488 main_ui_->filterExpressionFrame->addExpression(df_combo_box_->lineEdit()->text());
1489 showAccordionFrame(main_ui_->filterExpressionFrame);
1492 // On Qt4 + OS X with unifiedTitleAndToolBarOnMac set it's possible to make
1493 // the main window obnoxiously wide.
1495 void MainWindow::displayFilterButtonClicked()
1497 QAction *dfb_action = qobject_cast<QAction*>(sender());
1500 df_combo_box_->lineEdit()->setText(dfb_action->data().toString());
1501 df_combo_box_->applyDisplayFilter();
1502 df_combo_box_->lineEdit()->setFocus();
1506 void MainWindow::openStatCommandDialog(const QString &menu_path, const char *arg, void *userdata)
1508 QString slot = QString("statCommand%1").arg(menu_path);
1509 QMetaObject::invokeMethod(this, slot.toLatin1().constData(), Q_ARG(const char *, arg), Q_ARG(void *, userdata));
1512 void MainWindow::openTapParameterDialog(const QString cfg_str, const QString arg, void *userdata)
1514 TapParameterDialog *tp_dialog = TapParameterDialog::showTapParameterStatistics(*this, capture_file_, cfg_str, arg, userdata);
1515 if (!tp_dialog) return;
1517 connect(tp_dialog, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
1518 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
1519 connect(tp_dialog, SIGNAL(updateFilter(QString)),
1520 df_combo_box_->lineEdit(), SLOT(setText(QString)));
1524 void MainWindow::openTapParameterDialog()
1526 QAction *tpa = qobject_cast<QAction *>(QObject::sender());
1529 const QString cfg_str = tpa->data().toString();
1530 openTapParameterDialog(cfg_str, NULL, NULL);
1535 void MainWindow::on_actionFileOpen_triggered()
1540 void MainWindow::on_actionFileMerge_triggered()
1545 void MainWindow::on_actionFileImportFromHexDump_triggered()
1547 importCaptureFile();
1550 void MainWindow::on_actionFileClose_triggered() {
1551 if (testCaptureFileClose())
1552 main_ui_->mainStack->setCurrentWidget(main_welcome_);
1555 void MainWindow::on_actionFileSave_triggered()
1557 saveCaptureFile(capture_file_.capFile(), FALSE);
1560 void MainWindow::on_actionFileSaveAs_triggered()
1562 saveAsCaptureFile(capture_file_.capFile());
1565 void MainWindow::on_actionFileSetListFiles_triggered()
1567 file_set_dialog_.exec();
1570 void MainWindow::on_actionFileSetNextFile_triggered()
1572 fileset_entry *entry = fileset_get_next();
1575 QString new_cf_path = entry->fullname;
1576 openCaptureFile(new_cf_path);
1580 void MainWindow::on_actionFileSetPreviousFile_triggered()
1582 fileset_entry *entry = fileset_get_previous();
1585 QString new_cf_path = entry->fullname;
1586 openCaptureFile(new_cf_path);
1590 void MainWindow::on_actionFileExportPackets_triggered()
1592 exportSelectedPackets();
1595 void MainWindow::on_actionFileExportAsPlainText_triggered()
1597 exportDissections(export_type_text);
1600 void MainWindow::on_actionFileExportAsCSV_triggered()
1602 exportDissections(export_type_csv);
1605 void MainWindow::on_actionFileExportAsCArrays_triggered()
1607 exportDissections(export_type_carrays);
1610 void MainWindow::on_actionFileExportAsPSML_triggered()
1612 exportDissections(export_type_psml);
1615 void MainWindow::on_actionFileExportAsPDML_triggered()
1617 exportDissections(export_type_pdml);
1620 void MainWindow::on_actionFileExportPacketBytes_triggered()
1624 if (!capture_file_.capFile() || !capture_file_.capFile()->finfo_selected) return;
1626 file_name = QFileDialog::getSaveFileName(this,
1627 wsApp->windowTitleString(tr("Export Selected Packet Bytes")),
1628 wsApp->lastOpenDir().canonicalPath(),
1629 tr("Raw data (*.bin *.dat *.raw);;Any File (*.*)")
1632 if (file_name.length() > 0) {
1633 const guint8 *data_p;
1636 data_p = tvb_get_ptr(capture_file_.capFile()->finfo_selected->ds_tvb, 0, -1) +
1637 capture_file_.capFile()->finfo_selected->start;
1638 fd = ws_open(file_name.toUtf8().constData(), O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666);
1640 open_failure_alert_box(file_name.toUtf8().constData(), errno, TRUE);
1643 if (ws_write(fd, data_p, capture_file_.capFile()->finfo_selected->length) < 0) {
1644 write_failure_alert_box(file_name.toUtf8().constData(), errno);
1648 if (ws_close(fd) < 0) {
1649 write_failure_alert_box(file_name.toUtf8().constData(), errno);
1653 /* Save the directory name for future file dialogs. */
1654 wsApp->setLastOpenDir(&file_name);
1657 void MainWindow::on_actionFileExportPDU_triggered()
1659 ExportPDUDialog *exportpdu_dialog = new ExportPDUDialog(this);
1661 if (exportpdu_dialog->isMinimized() == true)
1663 exportpdu_dialog->showNormal();
1667 exportpdu_dialog->show();
1670 exportpdu_dialog->raise();
1671 exportpdu_dialog->activateWindow();
1674 void MainWindow::on_actionFileExportSSLSessionKeys_triggered()
1680 keylist_len = ssl_session_key_count();
1681 /* don't show up the dialog, if no data has to be saved */
1682 if (keylist_len < 1) {
1683 /* shouldn't happen as the menu item should have been greyed out */
1684 QMessageBox::warning(
1687 tr("There are no SSL Session Keys to save."),
1693 save_title.append(wsApp->windowTitleString(tr("Export SSL Session Keys (%1 key%2").
1694 arg(keylist_len).arg(plurality(keylist_len, "", "s"))));
1695 file_name = QFileDialog::getSaveFileName(this,
1697 wsApp->lastOpenDir().canonicalPath(),
1698 tr("SSL Session Keys (*.keys *.txt);;Any File (*.*)")
1700 if (file_name.length() > 0) {
1704 keylist = ssl_export_sessions();
1705 fd = ws_open(file_name.toUtf8().constData(), O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666);
1707 open_failure_alert_box(file_name.toUtf8().constData(), errno, TRUE);
1712 * Thanks, Microsoft, for not using size_t for the third argument to
1713 * _write(). Presumably this string will be <= 4GiB long....
1715 if (ws_write(fd, keylist, (unsigned int)strlen(keylist)) < 0) {
1716 write_failure_alert_box(file_name.toUtf8().constData(), errno);
1721 if (ws_close(fd) < 0) {
1722 write_failure_alert_box(file_name.toUtf8().constData(), errno);
1727 /* Save the directory name for future file dialogs. */
1728 wsApp->setLastOpenDir(&file_name);
1733 void MainWindow::on_actionFileExportObjectsDICOM_triggered()
1735 new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Dicom);
1738 void MainWindow::on_actionStatisticsHpfeeds_triggered()
1740 openStatisticsTreeDialog("hpfeeds");
1743 void MainWindow::on_actionFileExportObjectsHTTP_triggered()
1745 new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Http);
1748 void MainWindow::on_actionFileExportObjectsSMB_triggered()
1750 new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Smb);
1753 void MainWindow::on_actionFileExportObjectsTFTP_triggered()
1755 new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Tftp);
1758 void MainWindow::on_actionFilePrint_triggered()
1760 PrintDialog pdlg(this, capture_file_.capFile());
1767 void MainWindow::recursiveCopyProtoTreeItems(QTreeWidgetItem *item, QString &clip, int ident_level) {
1768 if (!item->isExpanded()) return;
1770 for (int i_item = 0; i_item < item->childCount(); i_item += 1) {
1771 clip.append(QString(" ").repeated(ident_level));
1772 clip.append(item->child(i_item)->text(0));
1775 recursiveCopyProtoTreeItems(item->child(i_item), clip, ident_level + 1);
1779 // XXX This should probably be somewhere else.
1780 void MainWindow::actionEditCopyTriggered(MainWindow::CopySelected selection_type)
1782 char label_str[ITEM_LABEL_LENGTH];
1785 if (!capture_file_.capFile()) return;
1787 field_info *finfo_selected = capture_file_.capFile()->finfo_selected;
1789 switch(selection_type) {
1790 case CopySelectedDescription:
1791 if (finfo_selected && finfo_selected->rep
1792 && strlen (finfo_selected->rep->representation) > 0) {
1793 clip.append(finfo_selected->rep->representation);
1796 case CopySelectedFieldName:
1797 if (finfo_selected && finfo_selected->hfinfo->abbrev != 0) {
1798 clip.append(finfo_selected->hfinfo->abbrev);
1801 case CopySelectedValue:
1802 if (finfo_selected && capture_file_.capFile()->edt != 0) {
1803 gchar* field_str = get_node_field_value(finfo_selected, capture_file_.capFile()->edt);
1804 clip.append(field_str);
1808 case CopyAllVisibleItems:
1809 for (int i_item = 0; i_item < proto_tree_->topLevelItemCount(); i_item += 1) {
1810 clip.append(proto_tree_->topLevelItem(i_item)->text(0));
1813 recursiveCopyProtoTreeItems(proto_tree_->topLevelItem(i_item), clip, 1);
1817 case CopyAllVisibleSelectedTreeItems:
1818 if (proto_tree_->selectedItems().count() > 0) {
1819 clip.append(proto_tree_->currentItem()->text(0));
1822 recursiveCopyProtoTreeItems(proto_tree_->currentItem(), clip, 1);
1827 if (clip.length() == 0) {
1828 /* If no representation then... Try to read the value */
1829 proto_item_fill_label(capture_file_.capFile()->finfo_selected, label_str);
1830 clip.append(label_str);
1833 if (clip.length()) {
1834 wsApp->clipboard()->setText(clip);
1836 QString err = tr("Couldn't copy text. Try another item.");
1837 main_ui_->statusBar->pushTemporaryStatus(err);
1841 void MainWindow::on_actionCopyAllVisibleItems_triggered()
1843 actionEditCopyTriggered(CopyAllVisibleItems);
1846 void MainWindow::on_actionCopyAllVisibleSelectedTreeItems_triggered()
1848 actionEditCopyTriggered(CopyAllVisibleSelectedTreeItems);
1851 void MainWindow::on_actionEditCopyDescription_triggered()
1853 actionEditCopyTriggered(CopySelectedDescription);
1856 void MainWindow::on_actionEditCopyFieldName_triggered()
1858 actionEditCopyTriggered(CopySelectedFieldName);
1861 void MainWindow::on_actionEditCopyValue_triggered()
1863 actionEditCopyTriggered(CopySelectedValue);
1866 void MainWindow::on_actionEditCopyAsFilter_triggered()
1868 matchFieldFilter(FilterAction::ActionCopy, FilterAction::ActionTypePlain);
1871 void MainWindow::on_actionEditFindPacket_triggered()
1873 if (packet_list_->model()->rowCount() < 1) {
1876 previous_focus_ = wsApp->focusWidget();
1877 connect(previous_focus_, SIGNAL(destroyed()), this, SLOT(resetPreviousFocus()));
1878 showAccordionFrame(main_ui_->searchFrame, true);
1881 void MainWindow::on_actionEditFindNext_triggered()
1883 main_ui_->searchFrame->findNext();
1886 void MainWindow::on_actionEditFindPrevious_triggered()
1888 main_ui_->searchFrame->findPrevious();
1891 void MainWindow::on_actionEditMarkPacket_triggered()
1894 packet_list_->markFrame();
1898 void MainWindow::on_actionEditMarkAllDisplayed_triggered()
1901 packet_list_->markAllDisplayedFrames(true);
1905 void MainWindow::on_actionEditUnmarkAllDisplayed_triggered()
1908 packet_list_->markAllDisplayedFrames(false);
1912 void MainWindow::on_actionEditNextMark_triggered()
1914 if (capture_file_.capFile())
1915 cf_find_packet_marked(capture_file_.capFile(), SD_FORWARD);
1918 void MainWindow::on_actionEditPreviousMark_triggered()
1920 if (capture_file_.capFile())
1921 cf_find_packet_marked(capture_file_.capFile(), SD_BACKWARD);
1924 void MainWindow::on_actionEditIgnorePacket_triggered()
1927 packet_list_->ignoreFrame();
1931 void MainWindow::on_actionEditIgnoreAllDisplayed_triggered()
1934 packet_list_->ignoreAllDisplayedFrames(true);
1938 void MainWindow::on_actionEditUnignoreAllDisplayed_triggered()
1941 packet_list_->ignoreAllDisplayedFrames(false);
1945 void MainWindow::on_actionEditSetTimeReference_triggered()
1947 packet_list_->setTimeReference();
1950 void MainWindow::on_actionEditUnsetAllTimeReferences_triggered()
1952 packet_list_->unsetAllTimeReferences();
1955 void MainWindow::on_actionEditNextTimeReference_triggered()
1957 if (!capture_file_.capFile()) return;
1958 cf_find_packet_time_reference(capture_file_.capFile(), SD_FORWARD);
1961 void MainWindow::on_actionEditPreviousTimeReference_triggered()
1963 if (!capture_file_.capFile()) return;
1964 cf_find_packet_time_reference(capture_file_.capFile(), SD_BACKWARD);
1967 void MainWindow::on_actionEditTimeShift_triggered()
1969 TimeShiftDialog ts_dialog(this, capture_file_.capFile());
1970 connect(this, SIGNAL(setCaptureFile(capture_file*)),
1971 &ts_dialog, SLOT(setCaptureFile(capture_file*)));
1972 connect(&ts_dialog, SIGNAL(timeShifted()), packet_list_, SLOT(applyTimeShift()));
1976 void MainWindow::on_actionEditPacketComment_triggered()
1978 PacketCommentDialog pc_dialog(this, packet_list_->packetComment());
1979 if (pc_dialog.exec() == QDialog::Accepted) {
1980 packet_list_->setPacketComment(pc_dialog.text());
1981 updateForUnsavedChanges();
1985 void MainWindow::on_actionEditConfigurationProfiles_triggered()
1987 ProfileDialog cp_dialog;
1992 void MainWindow::showPreferencesDialog(PreferencesDialog::PreferencesPane start_pane)
1994 PreferencesDialog pref_dialog(this);
1996 pref_dialog.setPane(start_pane);
1999 // Emitting PacketDissectionChanged directly from a QDialog can cause
2000 // problems on OS X.
2001 wsApp->flushAppSignals();
2004 void MainWindow::showPreferencesDialog(QString module_name)
2006 PreferencesDialog pref_dialog(this);
2008 pref_dialog.setPane(module_name);
2011 // Emitting PacketDissectionChanged directly from a QDialog can cause
2012 // problems on OS X.
2013 wsApp->flushAppSignals();
2016 void MainWindow::on_actionEditPreferences_triggered()
2018 showPreferencesDialog();
2023 void MainWindow::showHideMainWidgets(QAction *action)
2028 bool show = action->isChecked();
2029 QWidget *widget = action->data().value<QWidget*>();
2031 // We may have come from the toolbar context menu, so check/uncheck each
2033 if (widget == main_ui_->mainToolBar) {
2034 recent.main_toolbar_show = show;
2035 main_ui_->actionViewMainToolbar->setChecked(show);
2036 } else if (widget == main_ui_->displayFilterToolBar) {
2037 recent.filter_toolbar_show = show;
2038 main_ui_->actionViewFilterToolbar->setChecked(show);
2039 } else if (widget == main_ui_->wirelessToolBar) {
2040 recent.wireless_toolbar_show = show;
2041 main_ui_->actionViewWirelessToolbar->setChecked(show);
2042 } else if (widget == main_ui_->statusBar) {
2043 recent.statusbar_show = show;
2044 main_ui_->actionViewStatusBar->setChecked(show);
2045 } else if (widget == packet_list_) {
2046 recent.packet_list_show = show;
2047 main_ui_->actionViewPacketList->setChecked(show);
2048 } else if (widget == proto_tree_) {
2049 recent.tree_view_show = show;
2050 main_ui_->actionViewPacketDetails->setChecked(show);
2051 } else if (widget == byte_view_tab_) {
2052 recent.byte_view_show = show;
2053 main_ui_->actionViewPacketBytes->setChecked(show);
2057 widget->setVisible(show);
2061 Q_DECLARE_METATYPE(ts_type)
2063 void MainWindow::setTimestampFormat(QAction *action)
2068 ts_type tsf = action->data().value<ts_type>();
2069 if (recent.gui_time_format != tsf) {
2070 timestamp_set_type(tsf);
2071 recent.gui_time_format = tsf;
2072 if (capture_file_.capFile()) {
2073 /* This call adjusts column width */
2074 cf_timestamp_auto_precision(capture_file_.capFile());
2077 packet_list_->columnsChanged();
2082 Q_DECLARE_METATYPE(ts_precision)
2084 void MainWindow::setTimestampPrecision(QAction *action)
2089 ts_precision tsp = action->data().value<ts_precision>();
2090 if (recent.gui_time_precision != tsp) {
2091 /* the actual precision will be set in packet_list_queue_draw() below */
2092 timestamp_set_precision(tsp);
2093 recent.gui_time_precision = tsp;
2094 if (capture_file_.capFile()) {
2095 /* This call adjusts column width */
2096 cf_timestamp_auto_precision(capture_file_.capFile());
2099 packet_list_->columnsChanged();
2104 void MainWindow::on_actionViewTimeDisplaySecondsWithHoursAndMinutes_triggered(bool checked)
2107 recent.gui_seconds_format = TS_SECONDS_HOUR_MIN_SEC;
2109 recent.gui_seconds_format = TS_SECONDS_DEFAULT;
2111 timestamp_set_seconds_type(recent.gui_seconds_format);
2113 if (capture_file_.capFile()) {
2114 /* This call adjusts column width */
2115 cf_timestamp_auto_precision(capture_file_.capFile());
2118 packet_list_->columnsChanged();
2122 void MainWindow::on_actionViewEditResolvedName_triggered()
2124 // int column = packet_list_->selectedColumn();
2127 if (packet_list_->currentIndex().isValid()) {
2128 column = packet_list_->currentIndex().column();
2131 main_ui_->addressEditorFrame->editAddresses(capture_file_, column);
2132 showAccordionFrame(main_ui_->addressEditorFrame);
2135 void MainWindow::setNameResolution()
2137 gbl_resolv_flags.mac_name = main_ui_->actionViewNameResolutionPhysical->isChecked() ? TRUE : FALSE;
2138 gbl_resolv_flags.network_name = main_ui_->actionViewNameResolutionNetwork->isChecked() ? TRUE : FALSE;
2139 gbl_resolv_flags.transport_name = main_ui_->actionViewNameResolutionTransport->isChecked() ? TRUE : FALSE;
2142 packet_list_->columnsChanged();
2146 void MainWindow::on_actionViewNameResolutionPhysical_triggered()
2148 setNameResolution();
2151 void MainWindow::on_actionViewNameResolutionNetwork_triggered()
2153 setNameResolution();
2156 void MainWindow::on_actionViewNameResolutionTransport_triggered()
2158 setNameResolution();
2161 void MainWindow::zoomText()
2163 // Scale by 10%, rounding to nearest half point, minimum 1 point.
2164 // XXX Small sizes repeat. It might just be easier to create a map of multipliers.
2165 mono_font_ = QFont(wsApp->monospaceFont());
2166 qreal zoom_size = wsApp->monospaceFont().pointSize() * 2 * qPow(1.1, recent.gui_zoom_level);
2167 zoom_size = qRound(zoom_size) / 2.0;
2168 zoom_size = qMax(zoom_size, 1.0);
2169 mono_font_.setPointSizeF(zoom_size);
2170 emit monospaceFontChanged(mono_font_);
2173 void MainWindow::on_actionViewZoomIn_triggered()
2175 recent.gui_zoom_level++;
2179 void MainWindow::on_actionViewZoomOut_triggered()
2181 recent.gui_zoom_level--;
2185 void MainWindow::on_actionViewNormalSize_triggered()
2187 recent.gui_zoom_level = 0;
2191 void MainWindow::on_actionViewColorizePacketList_triggered(bool checked) {
2192 recent.packet_list_colorize = checked;
2193 color_filters_enable(checked);
2194 packet_list_->packetListModel()->resetColorized();
2195 packet_list_->update();
2198 void MainWindow::on_actionViewColoringRules_triggered()
2200 ColoringRulesDialog coloring_rules_dialog(this);
2202 coloring_rules_dialog.exec();
2205 // actionViewColorizeConversation1 - 10
2206 void MainWindow::colorizeConversation(bool create_rule)
2208 QAction *cc_action = qobject_cast<QAction *>(sender());
2209 if (!cc_action) return;
2211 if (capture_file_.capFile() && capture_file_.capFile()->current_frame) {
2212 packet_info *pi = &capture_file_.capFile()->edt->pi;
2213 guint8 cc_num = cc_action->data().toUInt();
2214 gchar *filter = NULL;
2216 const conversation_filter_t *color_filter = find_conversation_filter("tcp");
2217 if ((color_filter != NULL) && (color_filter->is_filter_valid(pi)))
2218 filter = color_filter->build_filter_string(pi);
2219 if (filter == NULL) {
2220 color_filter = find_conversation_filter("udp");
2221 if ((color_filter != NULL) && (color_filter->is_filter_valid(pi)))
2222 filter = color_filter->build_filter_string(pi);
2224 if (filter == NULL) {
2225 color_filter = find_conversation_filter("ip");
2226 if ((color_filter != NULL) && (color_filter->is_filter_valid(pi)))
2227 filter = color_filter->build_filter_string(pi);
2229 if (filter == NULL) {
2230 color_filter = find_conversation_filter("ipv6");
2231 if ((color_filter != NULL) && (color_filter->is_filter_valid(pi)))
2232 filter = color_filter->build_filter_string(pi);
2234 if (filter == NULL) {
2235 color_filter = find_conversation_filter("eth");
2236 if ((color_filter != NULL) && (color_filter->is_filter_valid(pi)))
2237 filter = color_filter->build_filter_string(pi);
2239 if( filter == NULL ) {
2240 main_ui_->statusBar->pushTemporaryStatus(tr("Unable to build conversation filter."));
2245 ColoringRulesDialog coloring_rules_dialog(this, filter);
2246 coloring_rules_dialog.exec();
2248 color_filters_set_tmp(cc_num, filter, FALSE);
2249 packet_list_->recolorPackets();
2252 setMenusForSelectedPacket();
2255 void MainWindow::colorizeWithFilter()
2257 QAction *colorize_action = qobject_cast<QAction *>(sender());
2258 if (!colorize_action) return;
2260 QString filter = colorize_action->data().toString();
2261 if (filter.isEmpty()) return;
2264 int color_number = colorize_action->property(color_number_property_).toInt(&ok);
2268 color_filters_set_tmp(color_number, filter.toUtf8().constData(), FALSE);
2269 packet_list_->recolorPackets();
2271 // New coloring rule
2272 ColoringRulesDialog coloring_rules_dialog(window(), filter);
2273 coloring_rules_dialog.exec();
2275 main_ui_->actionViewColorizeResetColorization->setEnabled(tmp_color_filters_used());
2278 void MainWindow::on_actionViewColorizeResetColorization_triggered()
2280 color_filters_reset_tmp();
2281 packet_list_->recolorPackets();
2282 setMenusForSelectedPacket();
2285 void MainWindow::on_actionViewColorizeNewConversationRule_triggered()
2287 colorizeConversation(true);
2290 void MainWindow::on_actionViewResizeColumns_triggered()
2292 for (int col = 0; col < packet_list_->packetListModel()->columnCount(); col++) {
2293 packet_list_->resizeColumnToContents(col);
2294 recent_set_column_width(col, packet_list_->columnWidth(col));
2298 void MainWindow::openPacketDialog(bool from_reference)
2302 /* Find the frame for which we're popping up a dialog */
2303 if(from_reference) {
2304 guint32 framenum = fvalue_get_uinteger(&(capture_file_.capFile()->finfo_selected->value));
2308 fdata = frame_data_sequence_find(capture_file_.capFile()->frames, framenum);
2310 fdata = capture_file_.capFile()->current_frame;
2313 /* If we have a frame, pop up the dialog */
2315 PacketDialog *packet_dialog = new PacketDialog(*this, capture_file_, fdata);
2317 connect(this, SIGNAL(monospaceFontChanged(QFont)),
2318 packet_dialog, SIGNAL(monospaceFontChanged(QFont)));
2319 connect(this, SIGNAL(closePacketDialogs()),
2320 packet_dialog, SLOT(close()));
2321 zoomText(); // Emits monospaceFontChanged
2323 packet_dialog->show();
2327 void MainWindow::on_actionViewInternalsConversationHashTables_triggered()
2329 ConversationHashTablesDialog *conversation_hash_tables_dlg = new ConversationHashTablesDialog(this);
2330 conversation_hash_tables_dlg->show();
2333 void MainWindow::on_actionViewInternalsDissectorTables_triggered()
2335 DissectorTablesDialog *dissector_tables_dlg = new DissectorTablesDialog(this);
2336 dissector_tables_dlg->show();
2339 void MainWindow::on_actionViewInternalsSupportedProtocols_triggered()
2341 SupportedProtocolsDialog *supported_protocols_dlg = new SupportedProtocolsDialog(this);
2342 supported_protocols_dlg->show();
2345 void MainWindow::on_actionViewShowPacketInNewWindow_triggered()
2350 // This is only used in ProtoTree. Defining it here makes more sense.
2351 void MainWindow::on_actionContextShowLinkedPacketInNewWindow_triggered()
2353 openPacketDialog(true);
2356 void MainWindow::on_actionViewReload_triggered()
2358 cf_reload(CaptureFile::globalCapFile());
2361 void MainWindow::on_actionViewReload_as_File_Format_or_Capture_triggered()
2363 capture_file *cf = CaptureFile::globalCapFile();
2365 if (cf->open_type == WTAP_TYPE_AUTO)
2366 cf->open_type = open_info_name_to_type("MIME Files Format");
2367 else /* TODO: This should be latest format chosen by user */
2368 cf->open_type = WTAP_TYPE_AUTO;
2374 // Expand / collapse slots in proto_tree
2380 void MainWindow::matchFieldFilter(FilterAction::Action action, FilterAction::ActionType filter_type)
2382 QString field_filter;
2384 if (packet_list_->contextMenuActive() || packet_list_->hasFocus()) {
2385 field_filter = packet_list_->getFilterFromRowAndColumn();
2386 } else if (capture_file_.capFile() && capture_file_.capFile()->finfo_selected) {
2387 char *tmp_field = proto_construct_match_selected_string(capture_file_.capFile()->finfo_selected,
2388 capture_file_.capFile()->edt);
2389 field_filter = QString(tmp_field);
2390 wmem_free(NULL, tmp_field);
2393 if (field_filter.isEmpty()) {
2394 QString err = tr("No filter available. Try another ");
2395 err.append(packet_list_->contextMenuActive() ? "column" : "item");
2397 main_ui_->statusBar->pushTemporaryStatus(err);
2401 filterAction(field_filter, action, filter_type);
2404 static FilterDialog *display_filter_dlg_ = NULL;
2405 void MainWindow::on_actionAnalyzeDisplayFilters_triggered()
2407 if (!display_filter_dlg_) {
2408 display_filter_dlg_ = new FilterDialog(this, FilterDialog::DisplayFilter);
2410 display_filter_dlg_->show();
2411 display_filter_dlg_->raise();
2412 display_filter_dlg_->activateWindow();
2416 void MainWindow::on_actionAnalyzeDisplayFilterMacros_triggered()
2418 struct epan_uat* dfm_uat;
2419 dfilter_macro_get_uat(&dfm_uat);
2420 UatDialog uat_dlg(parentWidget(), dfm_uat);
2423 // Emitting PacketDissectionChanged directly from a QDialog can cause
2424 // problems on OS X.
2425 wsApp->flushAppSignals();
2428 void MainWindow::on_actionAnalyzeCreateAColumn_triggered()
2432 if ( capture_file_.capFile() != 0 && capture_file_.capFile()->finfo_selected != 0 )
2434 colnr = column_prefs_add_custom(COL_CUSTOM, capture_file_.capFile()->finfo_selected->hfinfo->name,
2435 capture_file_.capFile()->finfo_selected->hfinfo->abbrev,0);
2437 packet_list_->columnsChanged();
2438 packet_list_->resizeColumnToContents(colnr);
2444 void MainWindow::applyConversationFilter()
2446 QAction *cfa = qobject_cast<QAction*>(sender());
2449 QString new_filter = cfa->data().toString();
2450 if (new_filter.isEmpty()) return;
2452 df_combo_box_->lineEdit()->setText(new_filter);
2453 df_combo_box_->applyDisplayFilter();
2456 // XXX We could probably create the analyze and prepare actions
2457 // dynamically using FilterActions and consolidate the methods
2458 // below into one callback.
2459 void MainWindow::on_actionAnalyzeAAFSelected_triggered()
2461 matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypePlain);
2464 void MainWindow::on_actionAnalyzeAAFNotSelected_triggered()
2466 matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypeNot);
2469 void MainWindow::on_actionAnalyzeAAFAndSelected_triggered()
2471 matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypeAnd);
2474 void MainWindow::on_actionAnalyzeAAFOrSelected_triggered()
2476 matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypeOr);
2479 void MainWindow::on_actionAnalyzeAAFAndNotSelected_triggered()
2481 matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypeAndNot);
2484 void MainWindow::on_actionAnalyzeAAFOrNotSelected_triggered()
2486 matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypeOrNot);
2489 void MainWindow::on_actionAnalyzePAFSelected_triggered()
2491 matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypePlain);
2494 void MainWindow::on_actionAnalyzePAFNotSelected_triggered()
2496 matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypeNot);
2499 void MainWindow::on_actionAnalyzePAFAndSelected_triggered()
2501 matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypeAnd);
2504 void MainWindow::on_actionAnalyzePAFOrSelected_triggered()
2506 matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypeOr);
2509 void MainWindow::on_actionAnalyzePAFAndNotSelected_triggered()
2511 matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypeAndNot);
2514 void MainWindow::on_actionAnalyzePAFOrNotSelected_triggered()
2516 matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypeOrNot);
2519 void MainWindow::on_actionAnalyzeEnabledProtocols_triggered()
2521 EnabledProtocolsDialog enable_proto_dialog(this);
2522 enable_proto_dialog.exec();
2524 // Emitting PacketDissectionChanged directly from a QDialog can cause
2525 // problems on OS X.
2526 wsApp->flushAppSignals();
2529 void MainWindow::on_actionAnalyzeDecodeAs_triggered()
2531 QAction *da_action = qobject_cast<QAction*>(sender());
2532 bool create_new = false;
2533 if (da_action && da_action->data().toBool() == true) {
2537 DecodeAsDialog da_dialog(this, capture_file_.capFile(), create_new);
2538 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2539 &da_dialog, SLOT(setCaptureFile(capture_file*)));
2542 // Emitting PacketDissectionChanged directly from a QDialog can cause
2543 // problems on OS X.
2544 wsApp->flushAppSignals();
2548 void MainWindow::on_actionAnalyzeReloadLuaPlugins_triggered()
2550 if (wsApp->isReloadingLua())
2553 wsApp->setReloadingLua(true);
2555 wslua_reload_plugins(NULL, NULL);
2556 funnel_statistics_reload_menus();
2557 reloadDynamicMenus();
2558 closePacketDialogs();
2560 // Preferences may have been deleted so close all widgets using prefs
2561 proto_tree_->closeContextMenu();
2562 main_ui_->preferenceEditorFrame->animatedHide();
2564 char *gdp_path, *dp_path;
2565 (void) wsApp->readConfigurationFiles(&gdp_path, &dp_path);
2570 wsApp->setReloadingLua(false);
2571 SimpleDialog::displayQueuedMessages();
2575 void MainWindow::openFollowStreamDialog(follow_type_t type) {
2576 FollowStreamDialog *fsd = new FollowStreamDialog(*this, capture_file_, type);
2577 connect(fsd, SIGNAL(updateFilter(QString, bool)), this, SLOT(filterPackets(QString, bool)));
2578 connect(fsd, SIGNAL(goToPacket(int)), packet_list_, SLOT(goToPacket(int)));
2581 fsd->follow(getFilter());
2584 void MainWindow::on_actionAnalyzeFollowTCPStream_triggered()
2586 openFollowStreamDialog(FOLLOW_TCP);
2589 void MainWindow::on_actionAnalyzeFollowUDPStream_triggered()
2591 openFollowStreamDialog(FOLLOW_UDP);
2594 void MainWindow::on_actionAnalyzeFollowSSLStream_triggered()
2596 openFollowStreamDialog(FOLLOW_SSL);
2599 void MainWindow::openSCTPAllAssocsDialog()
2601 SCTPAllAssocsDialog *sctp_dialog = new SCTPAllAssocsDialog(this, capture_file_.capFile());
2602 connect(sctp_dialog, SIGNAL(filterPackets(QString,bool)),
2603 this, SLOT(filterPackets(QString,bool)));
2604 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2605 sctp_dialog, SLOT(setCaptureFile(capture_file*)));
2606 sctp_dialog->fillTable();
2608 if (sctp_dialog->isMinimized() == true)
2610 sctp_dialog->showNormal();
2614 sctp_dialog->show();
2617 sctp_dialog->raise();
2618 sctp_dialog->activateWindow();
2621 void MainWindow::on_actionSCTPShowAllAssociations_triggered()
2623 openSCTPAllAssocsDialog();
2626 void MainWindow::on_actionSCTPAnalyseThisAssociation_triggered()
2628 SCTPAssocAnalyseDialog *sctp_analyse = new SCTPAssocAnalyseDialog(this, NULL, capture_file_.capFile());
2629 connect(sctp_analyse, SIGNAL(filterPackets(QString,bool)),
2630 this, SLOT(filterPackets(QString,bool)));
2632 if (sctp_analyse->isMinimized() == true)
2634 sctp_analyse->showNormal();
2638 sctp_analyse->show();
2641 sctp_analyse->raise();
2642 sctp_analyse->activateWindow();
2645 void MainWindow::on_actionSCTPFilterThisAssociation_triggered()
2647 sctp_assoc_info_t* assoc = SCTPAssocAnalyseDialog::findAssocForPacket(capture_file_.capFile());
2649 QString newFilter = QString("sctp.assoc_index==%1").arg(assoc->assoc_id);
2651 emit filterPackets(newFilter, false);
2656 void MainWindow::statCommandWlanStatistics(const char *arg, void *)
2658 WlanStatisticsDialog *wlan_stats_dlg = new WlanStatisticsDialog(*this, capture_file_, arg);
2659 connect(wlan_stats_dlg, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
2660 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
2661 wlan_stats_dlg->show();
2664 void MainWindow::on_actionWirelessWlanStatistics_triggered()
2666 statCommandWlanStatistics(NULL, NULL);
2670 void MainWindow::statCommandExpertInfo(const char *, void *)
2672 ExpertInfoDialog *expert_dialog = new ExpertInfoDialog(*this, capture_file_);
2673 const DisplayFilterEdit *df_edit = dynamic_cast<DisplayFilterEdit *>(df_combo_box_->lineEdit());
2675 expert_dialog->setDisplayFilter(df_edit->text());
2677 connect(expert_dialog, SIGNAL(goToPacket(int, int)),
2678 packet_list_, SLOT(goToPacket(int, int)));
2679 connect(expert_dialog, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
2680 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
2682 expert_dialog->show();
2685 void MainWindow::on_actionAnalyzeExpertInfo_triggered()
2687 statCommandExpertInfo(NULL, NULL);
2691 // Next / previous / first / last slots in packet_list
2695 void MainWindow::on_actionStatisticsFlowGraph_triggered()
2697 SequenceDialog *sequence_dialog = new SequenceDialog(*this, capture_file_);
2698 connect(sequence_dialog, SIGNAL(goToPacket(int)),
2699 packet_list_, SLOT(goToPacket(int)));
2700 sequence_dialog->show();
2703 void MainWindow::openTcpStreamDialog(int graph_type)
2705 TCPStreamDialog *stream_dialog = new TCPStreamDialog(this, capture_file_.capFile(), (tcp_graph_type)graph_type);
2706 connect(stream_dialog, SIGNAL(goToPacket(int)),
2707 packet_list_, SLOT(goToPacket(int)));
2708 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2709 stream_dialog, SLOT(setCaptureFile(capture_file*)));
2710 stream_dialog->show();
2713 void MainWindow::on_actionStatisticsTcpStreamStevens_triggered()
2715 openTcpStreamDialog(GRAPH_TSEQ_STEVENS);
2718 void MainWindow::on_actionStatisticsTcpStreamTcptrace_triggered()
2720 openTcpStreamDialog(GRAPH_TSEQ_TCPTRACE);
2723 void MainWindow::on_actionStatisticsTcpStreamThroughput_triggered()
2725 openTcpStreamDialog(GRAPH_THROUGHPUT);
2728 void MainWindow::on_actionStatisticsTcpStreamRoundTripTime_triggered()
2730 openTcpStreamDialog(GRAPH_RTT);
2733 void MainWindow::on_actionStatisticsTcpStreamWindowScaling_triggered()
2735 openTcpStreamDialog(GRAPH_WSCALE);
2739 void MainWindow::statCommandMulticastStatistics(const char *arg, void *)
2741 MulticastStatisticsDialog *mcast_stats_dlg = new MulticastStatisticsDialog(*this, capture_file_, arg);
2742 connect(mcast_stats_dlg, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
2743 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
2744 mcast_stats_dlg->show();
2747 void MainWindow::on_actionStatisticsUdpMulticastStreams_triggered()
2749 statCommandMulticastStatistics(NULL, NULL);
2752 void MainWindow::openStatisticsTreeDialog(const gchar *abbr)
2754 StatsTreeDialog *st_dialog = new StatsTreeDialog(*this, capture_file_, abbr);
2755 // connect(st_dialog, SIGNAL(goToPacket(int)),
2756 // packet_list_, SLOT(goToPacket(int)));
2760 void MainWindow::on_actionStatistics29WestTopics_Advertisements_by_Topic_triggered()
2762 openStatisticsTreeDialog("lbmr_topic_ads_topic");
2765 void MainWindow::on_actionStatistics29WestTopics_Advertisements_by_Source_triggered()
2767 openStatisticsTreeDialog("lbmr_topic_ads_source");
2770 void MainWindow::on_actionStatistics29WestTopics_Advertisements_by_Transport_triggered()
2772 openStatisticsTreeDialog("lbmr_topic_ads_transport");
2775 void MainWindow::on_actionStatistics29WestTopics_Queries_by_Topic_triggered()
2777 openStatisticsTreeDialog("lbmr_topic_queries_topic");
2780 void MainWindow::on_actionStatistics29WestTopics_Queries_by_Receiver_triggered()
2782 openStatisticsTreeDialog("lbmr_topic_queries_receiver");
2785 void MainWindow::on_actionStatistics29WestTopics_Wildcard_Queries_by_Pattern_triggered()
2787 openStatisticsTreeDialog("lbmr_topic_queries_pattern");
2790 void MainWindow::on_actionStatistics29WestTopics_Wildcard_Queries_by_Receiver_triggered()
2792 openStatisticsTreeDialog("lbmr_topic_queries_pattern_receiver");
2795 void MainWindow::on_actionStatistics29WestQueues_Advertisements_by_Queue_triggered()
2797 openStatisticsTreeDialog("lbmr_queue_ads_queue");
2800 void MainWindow::on_actionStatistics29WestQueues_Advertisements_by_Source_triggered()
2802 openStatisticsTreeDialog("lbmr_queue_ads_source");
2805 void MainWindow::on_actionStatistics29WestQueues_Queries_by_Queue_triggered()
2807 openStatisticsTreeDialog("lbmr_queue_queries_queue");
2810 void MainWindow::on_actionStatistics29WestQueues_Queries_by_Receiver_triggered()
2812 openStatisticsTreeDialog("lbmr_queue_queries_receiver");
2815 void MainWindow::on_actionStatistics29WestUIM_Streams_triggered()
2817 LBMStreamDialog *stream_dialog = new LBMStreamDialog(this, capture_file_.capFile());
2818 // connect(stream_dialog, SIGNAL(goToPacket(int)),
2819 // packet_list_, SLOT(goToPacket(int)));
2820 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2821 stream_dialog, SLOT(setCaptureFile(capture_file*)));
2822 stream_dialog->show();
2825 void MainWindow::on_actionStatistics29WestUIM_Stream_Flow_Graph_triggered()
2827 LBMUIMFlowDialog * uimflow_dialog = new LBMUIMFlowDialog(this, capture_file_.capFile());
2828 connect(uimflow_dialog, SIGNAL(goToPacket(int)),
2829 packet_list_, SLOT(goToPacket(int)));
2830 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2831 uimflow_dialog, SLOT(setCaptureFile(capture_file*)));
2832 uimflow_dialog->show();
2835 void MainWindow::on_actionStatistics29WestLBTRM_triggered()
2837 LBMLBTRMTransportDialog * lbtrm_dialog = new LBMLBTRMTransportDialog(this, capture_file_.capFile());
2838 connect(lbtrm_dialog, SIGNAL(goToPacket(int)),
2839 packet_list_, SLOT(goToPacket(int)));
2840 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2841 lbtrm_dialog, SLOT(setCaptureFile(capture_file*)));
2842 lbtrm_dialog->show();
2844 void MainWindow::on_actionStatistics29WestLBTRU_triggered()
2846 LBMLBTRUTransportDialog * lbtru_dialog = new LBMLBTRUTransportDialog(this, capture_file_.capFile());
2847 connect(lbtru_dialog, SIGNAL(goToPacket(int)),
2848 packet_list_, SLOT(goToPacket(int)));
2849 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2850 lbtru_dialog, SLOT(setCaptureFile(capture_file*)));
2851 lbtru_dialog->show();
2854 void MainWindow::on_actionStatisticsANCP_triggered()
2856 openStatisticsTreeDialog("ancp");
2859 void MainWindow::on_actionStatisticsBACappInstanceId_triggered()
2861 openStatisticsTreeDialog("bacapp_instanceid");
2864 void MainWindow::on_actionStatisticsBACappIP_triggered()
2866 openStatisticsTreeDialog("bacapp_ip");
2869 void MainWindow::on_actionStatisticsBACappObjectId_triggered()
2871 openStatisticsTreeDialog("bacapp_objectid");
2874 void MainWindow::on_actionStatisticsBACappService_triggered()
2876 openStatisticsTreeDialog("bacapp_service");
2879 void MainWindow::on_actionStatisticsCollectd_triggered()
2881 openStatisticsTreeDialog("collectd");
2885 void MainWindow::statCommandConversations(const char *arg, void *userdata)
2887 ConversationDialog *conv_dialog = new ConversationDialog(*this, capture_file_, GPOINTER_TO_INT(userdata), arg);
2888 connect(conv_dialog, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
2889 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
2890 connect(conv_dialog, SIGNAL(openFollowStreamDialog(follow_type_t)),
2891 this, SLOT(openFollowStreamDialog(follow_type_t)));
2892 connect(conv_dialog, SIGNAL(openTcpStreamGraph(int)),
2893 this, SLOT(openTcpStreamDialog(int)));
2894 conv_dialog->show();
2897 void MainWindow::on_actionStatisticsConversations_triggered()
2899 statCommandConversations(NULL, NULL);
2903 void MainWindow::statCommandEndpoints(const char *arg, void *userdata)
2905 EndpointDialog *endp_dialog = new EndpointDialog(*this, capture_file_, GPOINTER_TO_INT(userdata), arg);
2906 connect(endp_dialog, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
2907 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
2908 connect(endp_dialog, SIGNAL(openFollowStreamDialog(follow_type_t)),
2909 this, SLOT(openFollowStreamDialog(follow_type_t)));
2910 connect(endp_dialog, SIGNAL(openTcpStreamGraph(int)),
2911 this, SLOT(openTcpStreamDialog(int)));
2912 endp_dialog->show();
2915 void MainWindow::on_actionStatisticsEndpoints_triggered()
2917 statCommandEndpoints(NULL, NULL);
2920 void MainWindow::on_actionStatisticsHART_IP_triggered()
2922 openStatisticsTreeDialog("hart_ip");
2925 void MainWindow::on_actionStatisticsHTTPPacketCounter_triggered()
2927 openStatisticsTreeDialog("http");
2930 void MainWindow::on_actionStatisticsHTTPRequests_triggered()
2932 openStatisticsTreeDialog("http_req");
2935 void MainWindow::on_actionStatisticsHTTPLoadDistribution_triggered()
2937 openStatisticsTreeDialog("http_srv");
2940 void MainWindow::on_actionStatisticsPacketLengths_triggered()
2942 openStatisticsTreeDialog("plen");
2946 void MainWindow::statCommandIOGraph(const char *, void *)
2948 IOGraphDialog *iog_dialog = new IOGraphDialog(*this, capture_file_);
2949 connect(iog_dialog, SIGNAL(goToPacket(int)), packet_list_, SLOT(goToPacket(int)));
2950 connect(this, SIGNAL(reloadFields()), iog_dialog, SLOT(reloadFields()));
2954 void MainWindow::on_actionStatisticsIOGraph_triggered()
2956 statCommandIOGraph(NULL, NULL);
2959 void MainWindow::on_actionStatisticsSametime_triggered()
2961 openStatisticsTreeDialog("sametime");
2964 void MainWindow::on_actionStatisticsDNS_triggered()
2966 openStatisticsTreeDialog("dns");
2969 void MainWindow::actionStatisticsPlugin_triggered()
2971 QAction* action = qobject_cast<QAction*>(sender());
2973 openStatisticsTreeDialog(action->data().toString().toUtf8());
2977 void MainWindow::on_actionStatisticsHTTP2_triggered()
2979 openStatisticsTreeDialog("http2");
2985 void MainWindow::openVoipCallsDialog(bool all_flows)
2987 VoipCallsDialog *voip_calls_dialog = new VoipCallsDialog(*this, capture_file_, all_flows);
2988 connect(voip_calls_dialog, SIGNAL(goToPacket(int)),
2989 packet_list_, SLOT(goToPacket(int)));
2990 connect(voip_calls_dialog, SIGNAL(updateFilter(QString, bool)),
2991 this, SLOT(filterPackets(QString, bool)));
2992 voip_calls_dialog->show();
2995 void MainWindow::on_actionTelephonyVoipCalls_triggered()
2997 openVoipCallsDialog();
3000 void MainWindow::on_actionTelephonyGsmMapSummary_triggered()
3002 GsmMapSummaryDialog *gms_dialog = new GsmMapSummaryDialog(*this, capture_file_);
3006 void MainWindow::on_actionTelephonyIax2StreamAnalysis_triggered()
3008 Iax2AnalysisDialog *iax2_analysis_dialog = new Iax2AnalysisDialog(*this, capture_file_);
3009 connect(iax2_analysis_dialog, SIGNAL(goToPacket(int)),
3010 packet_list_, SLOT(goToPacket(int)));
3011 iax2_analysis_dialog->show();
3014 void MainWindow::on_actionTelephonyISUPMessages_triggered()
3016 openStatisticsTreeDialog("isup_msg");
3020 void MainWindow::statCommandLteMacStatistics(const char *arg, void *)
3022 LteMacStatisticsDialog *lte_mac_stats_dlg = new LteMacStatisticsDialog(*this, capture_file_, arg);
3023 connect(lte_mac_stats_dlg, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
3024 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
3025 lte_mac_stats_dlg->show();
3028 void MainWindow::on_actionTelephonyLteMacStatistics_triggered()
3030 statCommandLteMacStatistics(NULL, NULL);
3033 void MainWindow::statCommandLteRlcStatistics(const char *arg, void *)
3035 LteRlcStatisticsDialog *lte_rlc_stats_dlg = new LteRlcStatisticsDialog(*this, capture_file_, arg);
3036 connect(lte_rlc_stats_dlg, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
3037 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
3038 // N.B. It is necessary for the RLC Statistics window to launch the RLC graph in this way, to ensure
3039 // that the goToPacket() signal/slot connection gets set up...
3040 connect(lte_rlc_stats_dlg, SIGNAL(launchRLCGraph(bool, guint16, guint8, guint16, guint16, guint8)),
3041 this, SLOT(launchRLCGraph(bool, guint16, guint8, guint16, guint16, guint8)));
3043 lte_rlc_stats_dlg->show();
3046 void MainWindow::on_actionTelephonyLteRlcStatistics_triggered()
3048 statCommandLteRlcStatistics(NULL, NULL);
3051 void MainWindow::launchRLCGraph(bool channelKnown,
3052 guint16 ueid, guint8 rlcMode,
3053 guint16 channelType, guint16 channelId, guint8 direction)
3055 LteRlcGraphDialog *lrg_dialog = new LteRlcGraphDialog(*this, capture_file_, channelKnown);
3056 connect(lrg_dialog, SIGNAL(goToPacket(int)), packet_list_, SLOT(goToPacket(int)));
3057 // This is a bit messy, but wanted to hide these parameters from users of
3058 // on_actionTelephonyLteRlcGraph_triggered().
3060 lrg_dialog->setChannelInfo(ueid, rlcMode, channelType, channelId, direction);
3065 void MainWindow::on_actionTelephonyLteRlcGraph_triggered()
3067 // We don't yet know the channel.
3068 launchRLCGraph(false, 0, 0, 0, 0, 0);
3071 void MainWindow::on_actionTelephonyMtp3Summary_triggered()
3073 Mtp3SummaryDialog *mtp3s_dialog = new Mtp3SummaryDialog(*this, capture_file_);
3074 mtp3s_dialog->show();
3077 void MainWindow::on_actionTelephonyRTPStreams_triggered()
3079 RtpStreamDialog *rtp_stream_dialog = new RtpStreamDialog(*this, capture_file_);
3080 connect(rtp_stream_dialog, SIGNAL(packetsMarked()),
3081 packet_list_, SLOT(redrawVisiblePackets()));
3082 connect(rtp_stream_dialog, SIGNAL(goToPacket(int)),
3083 packet_list_, SLOT(goToPacket(int)));
3084 connect(rtp_stream_dialog, SIGNAL(updateFilter(QString, bool)),
3085 this, SLOT(filterPackets(QString, bool)));
3086 rtp_stream_dialog->show();
3089 void MainWindow::on_actionTelephonyRTPStreamAnalysis_triggered()
3091 RtpAnalysisDialog *rtp_analysis_dialog = new RtpAnalysisDialog(*this, capture_file_);
3092 connect(rtp_analysis_dialog, SIGNAL(goToPacket(int)),
3093 packet_list_, SLOT(goToPacket(int)));
3094 rtp_analysis_dialog->show();
3097 void MainWindow::on_actionTelephonyRTSPPacketCounter_triggered()
3099 openStatisticsTreeDialog("rtsp");
3102 void MainWindow::on_actionTelephonySMPPOperations_triggered()
3104 openStatisticsTreeDialog("smpp_commands");
3107 void MainWindow::on_actionTelephonyUCPMessages_triggered()
3109 openStatisticsTreeDialog("ucp_messages");
3112 void MainWindow::on_actionTelephonySipFlows_triggered()
3114 openVoipCallsDialog(true);
3119 void MainWindow::on_actionBluetoothATT_Server_Attributes_triggered()
3121 BluetoothAttServerAttributesDialog *bluetooth_att_sever_attributes_dialog = new BluetoothAttServerAttributesDialog(*this, capture_file_);
3122 connect(bluetooth_att_sever_attributes_dialog, SIGNAL(goToPacket(int)),
3123 packet_list_, SLOT(goToPacket(int)));
3124 connect(bluetooth_att_sever_attributes_dialog, SIGNAL(updateFilter(QString, bool)),
3125 this, SLOT(filterPackets(QString, bool)));
3126 bluetooth_att_sever_attributes_dialog->show();
3129 void MainWindow::on_actionBluetoothDevices_triggered()
3131 BluetoothDevicesDialog *bluetooth_devices_dialog = new BluetoothDevicesDialog(*this, capture_file_);
3132 connect(bluetooth_devices_dialog, SIGNAL(goToPacket(int)),
3133 packet_list_, SLOT(goToPacket(int)));
3134 connect(bluetooth_devices_dialog, SIGNAL(updateFilter(QString, bool)),
3135 this, SLOT(filterPackets(QString, bool)));
3136 bluetooth_devices_dialog->show();
3139 void MainWindow::on_actionBluetoothHCI_Summary_triggered()
3141 BluetoothHciSummaryDialog *bluetooth_hci_summary_dialog = new BluetoothHciSummaryDialog(*this, capture_file_);
3142 connect(bluetooth_hci_summary_dialog, SIGNAL(goToPacket(int)),
3143 packet_list_, SLOT(goToPacket(int)));
3144 connect(bluetooth_hci_summary_dialog, SIGNAL(updateFilter(QString, bool)),
3145 this, SLOT(filterPackets(QString, bool)));
3146 bluetooth_hci_summary_dialog->show();
3150 void MainWindow::on_actionHelpContents_triggered() {
3152 wsApp->helpTopicAction(HELP_CONTENT);
3155 void MainWindow::on_actionHelpMPWireshark_triggered() {
3157 wsApp->helpTopicAction(LOCALPAGE_MAN_WIRESHARK);
3160 void MainWindow::on_actionHelpMPWireshark_Filter_triggered() {
3161 wsApp->helpTopicAction(LOCALPAGE_MAN_WIRESHARK_FILTER);
3164 void MainWindow::on_actionHelpMPCapinfos_triggered() {
3165 wsApp->helpTopicAction(LOCALPAGE_MAN_CAPINFOS);
3168 void MainWindow::on_actionHelpMPDumpcap_triggered() {
3169 wsApp->helpTopicAction(LOCALPAGE_MAN_DUMPCAP);
3172 void MainWindow::on_actionHelpMPEditcap_triggered() {
3173 wsApp->helpTopicAction(LOCALPAGE_MAN_EDITCAP);
3176 void MainWindow::on_actionHelpMPMergecap_triggered() {
3177 wsApp->helpTopicAction(LOCALPAGE_MAN_MERGECAP);
3180 void MainWindow::on_actionHelpMPRawShark_triggered() {
3181 wsApp->helpTopicAction(LOCALPAGE_MAN_RAWSHARK);
3184 void MainWindow::on_actionHelpMPReordercap_triggered() {
3185 wsApp->helpTopicAction(LOCALPAGE_MAN_REORDERCAP);
3188 void MainWindow::on_actionHelpMPText2cap_triggered() {
3189 wsApp->helpTopicAction(LOCALPAGE_MAN_TEXT2PCAP);
3192 void MainWindow::on_actionHelpMPTShark_triggered() {
3193 wsApp->helpTopicAction(LOCALPAGE_MAN_TSHARK);
3196 void MainWindow::on_actionHelpWebsite_triggered() {
3198 wsApp->helpTopicAction(ONLINEPAGE_HOME);
3201 void MainWindow::on_actionHelpFAQ_triggered() {
3203 wsApp->helpTopicAction(ONLINEPAGE_FAQ);
3206 void MainWindow::on_actionHelpAsk_triggered() {
3208 wsApp->helpTopicAction(ONLINEPAGE_ASK);
3211 void MainWindow::on_actionHelpDownloads_triggered() {
3213 wsApp->helpTopicAction(ONLINEPAGE_DOWNLOAD);
3216 void MainWindow::on_actionHelpWiki_triggered() {
3218 wsApp->helpTopicAction(ONLINEPAGE_WIKI);
3221 void MainWindow::on_actionHelpSampleCaptures_triggered() {
3223 wsApp->helpTopicAction(ONLINEPAGE_SAMPLE_FILES);
3226 #ifdef HAVE_SOFTWARE_UPDATE
3227 void MainWindow::checkForUpdates()
3229 software_update_check();
3233 void MainWindow::on_actionHelpAbout_triggered()
3235 AboutDialog *about_dialog = new AboutDialog(this);
3237 if (about_dialog->isMinimized() == true)
3239 about_dialog->showNormal();
3243 about_dialog->show();
3246 about_dialog->raise();
3247 about_dialog->activateWindow();
3250 void MainWindow::on_actionGoGoToPacket_triggered() {
3251 if (packet_list_->model()->rowCount() < 1) {
3254 previous_focus_ = wsApp->focusWidget();
3255 connect(previous_focus_, SIGNAL(destroyed()), this, SLOT(resetPreviousFocus()));
3257 showAccordionFrame(main_ui_->goToFrame, true);
3258 if (main_ui_->goToFrame->isVisible()) {
3259 main_ui_->goToLineEdit->clear();
3260 main_ui_->goToLineEdit->setFocus();
3264 void MainWindow::on_actionGoGoToLinkedPacket_triggered()
3266 QAction *gta = qobject_cast<QAction*>(sender());
3270 int packet_num = gta->data().toInt(&ok);
3273 packet_list_->goToPacket(packet_num);
3276 void MainWindow::on_actionGoAutoScroll_toggled(bool checked)
3278 packet_list_->setAutoScroll(checked);
3281 void MainWindow::resetPreviousFocus() {
3282 previous_focus_ = NULL;
3285 void MainWindow::on_goToCancel_clicked()
3287 main_ui_->goToFrame->animatedHide();
3288 if (previous_focus_) {
3289 disconnect(previous_focus_, SIGNAL(destroyed()), this, SLOT(resetPreviousFocus()));
3290 previous_focus_->setFocus();
3291 resetPreviousFocus();
3295 void MainWindow::on_goToGo_clicked()
3297 gotoFrame(main_ui_->goToLineEdit->text().toInt());
3299 on_goToCancel_clicked();
3302 void MainWindow::on_goToLineEdit_returnPressed()
3304 on_goToGo_clicked();
3307 void MainWindow::on_actionCaptureStart_triggered()
3309 //#ifdef HAVE_AIRPCAP
3310 // airpcap_if_active = airpcap_if_selected;
3311 // if (airpcap_if_active)
3312 // airpcap_set_toolbar_start_capture(airpcap_if_active);
3315 // if (cap_open_w) {
3317 // * There's an options dialog; get the values from it and close it.
3319 // gboolean success;
3321 // /* Determine if "capture start" while building of the "capture options" window */
3322 // /* is in progress. If so, ignore the "capture start. */
3323 // /* XXX: Would it be better/cleaner for the "capture options" window code to */
3324 // /* disable the capture start button temporarily ? */
3325 // if (cap_open_complete == FALSE) {
3326 // return; /* Building options window: ignore "capture start" */
3328 // success = capture_dlg_prep(cap_open_w);
3329 // window_destroy(GTK_WIDGET(cap_open_w));
3331 // return; /* error in options dialog */
3335 if (global_capture_opts.num_selected == 0) {
3336 QString err_msg = tr("No Interface Selected");
3337 main_ui_->statusBar->pushTemporaryStatus(err_msg);
3338 main_ui_->actionCaptureStart->setChecked(false);
3342 /* XXX - will closing this remove a temporary file? */
3343 QString before_what(tr(" before starting a new capture"));
3344 if (testCaptureFileClose(FALSE, before_what)) {
3347 // simply clicking the button sets it to 'checked' even though we've
3348 // decided to do nothing, so undo that
3349 main_ui_->actionCaptureStart->setChecked(false);
3351 #endif // HAVE_LIBPCAP
3354 void MainWindow::on_actionCaptureStop_triggered()
3359 void MainWindow::on_actionCaptureRestart_triggered()
3361 /* TODO: GTK use only this: capture_restart(&cap_session_); */
3366 static FilterDialog *capture_filter_dlg_ = NULL;
3367 void MainWindow::on_actionCaptureCaptureFilters_triggered()
3369 if (!capture_filter_dlg_) {
3370 capture_filter_dlg_ = new FilterDialog(this, FilterDialog::CaptureFilter);
3372 capture_filter_dlg_->show();
3373 capture_filter_dlg_->raise();
3374 capture_filter_dlg_->activateWindow();
3377 void MainWindow::on_actionStatisticsCaptureFileProperties_triggered()
3379 CaptureFilePropertiesDialog *capture_file_properties_dialog = new CaptureFilePropertiesDialog(*this, capture_file_);
3380 connect(capture_file_properties_dialog, SIGNAL(captureCommentChanged()),
3381 this, SLOT(updateForUnsavedChanges()));
3382 capture_file_properties_dialog->show();
3385 void MainWindow::on_actionStatisticsResolvedAddresses_triggered()
3387 ResolvedAddressesDialog *resolved_addresses_dialog = new ResolvedAddressesDialog(this, &capture_file_);
3388 resolved_addresses_dialog->show();
3391 void MainWindow::on_actionStatisticsProtocolHierarchy_triggered()
3393 ProtocolHierarchyDialog *phd = new ProtocolHierarchyDialog(*this, capture_file_);
3394 connect(phd, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
3395 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
3400 void MainWindow::on_actionCaptureOptions_triggered()
3402 connect(&capture_interfaces_dialog_, SIGNAL(setFilterValid(bool)), this, SLOT(startInterfaceCapture(bool)));
3403 capture_interfaces_dialog_.SetTab(0);
3404 capture_interfaces_dialog_.updateInterfaces();
3406 if (capture_interfaces_dialog_.isMinimized() == true)
3408 capture_interfaces_dialog_.showNormal();
3412 capture_interfaces_dialog_.show();
3415 capture_interfaces_dialog_.raise();
3416 capture_interfaces_dialog_.activateWindow();
3419 void MainWindow::on_actionCaptureRefreshInterfaces_triggered()
3421 wsApp->refreshLocalInterfaces();
3425 void MainWindow::externalMenuItem_triggered()
3427 QAction * triggerAction = NULL;
3429 ext_menubar_t * entry = NULL;
3431 if ( QObject::sender() != NULL)
3433 triggerAction = (QAction *)QObject::sender();
3434 v = triggerAction->data();
3436 if ( v.canConvert<void *>())
3438 entry = (ext_menubar_t *)v.value<void *>();
3440 if ( entry->type == EXT_MENUBAR_ITEM )
3442 entry->callback(EXT_MENUBAR_QT_GUI, (gpointer) ((void *)main_ui_), entry->user_data);
3446 QDesktopServices::openUrl(QUrl(QString((gchar *)entry->user_data)));
3452 void MainWindow::gotoFrame(int packet_num)
3454 if ( packet_num > 0 )
3456 packet_list_->goToPacket(packet_num);
3461 void MainWindow::extcap_options_finished(int result)
3463 if ( result == QDialog::Accepted )
3467 this->main_welcome_->getInterfaceTree()->interfaceListChanged();
3470 void MainWindow::showExtcapOptionsDialog(QString &device_name)
3472 ExtcapOptionsDialog * extcap_options_dialog = ExtcapOptionsDialog::createForDevice(device_name, this);
3473 /* The dialog returns null, if the given device name is not a valid extcap device */
3474 if ( extcap_options_dialog != NULL )
3476 connect(extcap_options_dialog, SIGNAL(finished(int)),
3477 this, SLOT(extcap_options_finished(int)));
3478 extcap_options_dialog->show();
3483 // Q_DECLARE_METATYPE(field_info *) called in proto_tree.h
3485 void MainWindow::on_actionContextCopyBytesHexTextDump_triggered()
3487 QAction *ca = qobject_cast<QAction*>(sender());
3490 field_info *fi = ca->data().value<field_info *>();
3492 byte_view_tab_->copyData(ByteViewTab::copyDataHexTextDump, fi);
3495 void MainWindow::on_actionContextCopyBytesHexDump_triggered()
3497 QAction *ca = qobject_cast<QAction*>(sender());
3500 field_info *fi = ca->data().value<field_info *>();
3502 byte_view_tab_->copyData(ByteViewTab::copyDataHexDump, fi);
3505 void MainWindow::on_actionContextCopyBytesPrintableText_triggered()
3507 QAction *ca = qobject_cast<QAction*>(sender());
3510 field_info *fi = ca->data().value<field_info *>();
3512 byte_view_tab_->copyData(ByteViewTab::copyDataPrintableText, fi);
3515 void MainWindow::on_actionContextCopyBytesHexStream_triggered()
3517 QAction *ca = qobject_cast<QAction*>(sender());
3520 field_info *fi = ca->data().value<field_info *>();
3522 byte_view_tab_->copyData(ByteViewTab::copyDataHexStream, fi);
3525 void MainWindow::on_actionContextCopyBytesBinary_triggered()
3527 QAction *ca = qobject_cast<QAction*>(sender());
3530 field_info *fi = ca->data().value<field_info *>();
3532 byte_view_tab_->copyData(ByteViewTab::copyDataBinary, fi);
3535 void MainWindow::on_actionContextWikiProtocolPage_triggered()
3537 QAction *wa = qobject_cast<QAction*>(sender());
3541 int field_id = wa->data().toInt(&ok);
3544 const QString proto_abbrev = proto_registrar_get_abbrev(field_id);
3546 int ret = QMessageBox::question(this, wsApp->windowTitleString(tr("Wiki Page for %1").arg(proto_abbrev)),
3547 tr("<p>The Wireshark Wiki is maintained by the community.</p>"
3548 "<p>The page you are about to load might be wonderful, "
3549 "incomplete, wrong, or nonexistent.</p>"
3550 "<p>Proceed to the wiki?</p>"),
3551 QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
3553 if (ret != QMessageBox::Yes) return;
3555 QUrl wiki_url = QString("https://wiki.wireshark.org/Protocols/%1").arg(proto_abbrev);
3556 QDesktopServices::openUrl(wiki_url);
3559 void MainWindow::on_actionContextFilterFieldReference_triggered()
3561 QAction *wa = qobject_cast<QAction*>(sender());
3565 int field_id = wa->data().toInt(&ok);
3568 const QString proto_abbrev = proto_registrar_get_abbrev(field_id);
3570 QUrl dfref_url = QString("https://www.wireshark.org/docs/dfref/%1/%2")
3571 .arg(proto_abbrev[0])
3573 QDesktopServices::openUrl(dfref_url);
3577 #pragma warning(pop)
3586 * indent-tabs-mode: nil
3589 * ex: set shiftwidth=4 tabstop=8 expandtab:
3590 * :indentSize=4:tabSize=8:noTabs=true: