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.
32 #include "main_window.h"
33 #include <ui_main_window.h>
41 #include "ui/capture.h"
44 #include "color_filters.h"
46 #include "wsutil/file_util.h"
47 #include "wsutil/filesystem.h"
48 #include <wsutil/str_util.h>
50 #include "epan/addr_resolv.h"
51 #include "epan/color_dissector_filters.h"
52 #include "epan/column.h"
53 #include "epan/dfilter/dfilter-macro.h"
54 #include "epan/epan_dissect.h"
55 #include "epan/filter_expressions.h"
56 #include "epan/prefs.h"
58 #include "epan/value_string.h"
61 #include <epan/wslua/init_wslua.h>
64 #include "ui/alert_box.h"
66 #include "ui/capture_ui_utils.h"
69 #include "ui/capture_globals.h"
70 #include "ui/help_url.h"
71 #include "ui/main_statusbar.h"
72 #include "ui/preference_utils.h"
73 #include "ui/recent.h"
74 #include "ui/recent_utils.h"
75 #include "ui/ssl_key_export.h"
76 #include "ui/ui_util.h"
77 #include "ui/qt/simple_dialog.h"
79 #ifdef HAVE_SOFTWARE_UPDATE
80 #include "ui/software_update.h"
83 #include "about_dialog.h"
84 #include "bluetooth_att_server_attributes_dialog.h"
85 #include "bluetooth_devices_dialog.h"
86 #include "bluetooth_hci_summary_dialog.h"
87 #include "capture_file_dialog.h"
88 #include "capture_file_properties_dialog.h"
89 #include "color_utils.h"
90 #include "coloring_rules_dialog.h"
91 #include "conversation_dialog.h"
92 #include "conversation_hash_tables_dialog.h"
93 #include "enabled_protocols_dialog.h"
94 #include "decode_as_dialog.h"
95 #include "display_filter_edit.h"
96 #include "display_filter_expression_dialog.h"
97 #include "dissector_tables_dialog.h"
98 #include "endpoint_dialog.h"
99 #include "expert_info_dialog.h"
100 #include "export_object_dialog.h"
101 #include "export_pdu_dialog.h"
103 #include "extcap_options_dialog.h"
105 #include "filter_action.h"
106 #include "filter_dialog.h"
107 #include "funnel_statistics.h"
108 #include "gsm_map_summary_dialog.h"
109 #include "iax2_analysis_dialog.h"
110 #include "io_graph_dialog.h"
111 #include "lbm_stream_dialog.h"
112 #include "lbm_uimflow_dialog.h"
113 #include "lbm_lbtrm_transport_dialog.h"
114 #include "lbm_lbtru_transport_dialog.h"
115 #include "lte_mac_statistics_dialog.h"
116 #include "lte_rlc_statistics_dialog.h"
117 #include "mtp3_summary_dialog.h"
118 #include "multicast_statistics_dialog.h"
119 #include "packet_comment_dialog.h"
120 #include "packet_dialog.h"
121 #include "packet_list.h"
122 #include "preferences_dialog.h"
123 #include "print_dialog.h"
124 #include "profile_dialog.h"
125 #include "protocol_hierarchy_dialog.h"
126 #include "qt_ui_utils.h"
127 #include "resolved_addresses_dialog.h"
128 #include "rpc_service_response_time_dialog.h"
129 #include "rtp_stream_dialog.h"
130 #include "rtp_analysis_dialog.h"
131 #include "sctp_all_assocs_dialog.h"
132 #include "sctp_assoc_analyse_dialog.h"
133 #include "sctp_graph_dialog.h"
134 #include "sequence_dialog.h"
135 #include "stats_tree_dialog.h"
136 #include "stock_icon.h"
137 #include "tap_parameter_dialog.h"
138 #include "tcp_stream_dialog.h"
139 #include "time_shift_dialog.h"
140 #include "uat_dialog.h"
141 #include "voip_calls_dialog.h"
142 #include "wireshark_application.h"
143 #include "wlan_statistics_dialog.h"
145 #include <QClipboard>
147 #include <QMessageBox>
148 #include <QMetaObject>
150 #include <QDesktopServices>
158 static const char *dfe_property_ = "display filter expression"; //TODO : Fix Translate
160 // We're too lazy to sublcass QAction.
161 static const char *color_number_property_ = "color number";
163 bool MainWindow::openCaptureFile(QString cf_path, QString read_filter, unsigned int type)
165 QString file_name = "";
166 dfilter_t *rfcode = NULL;
171 // was a file name given as function parameter?
172 name_param = !cf_path.isEmpty();
176 if (cf_path.isEmpty()) {
177 CaptureFileDialog open_dlg(this, capture_file_.capFile(), read_filter);
179 switch (prefs.gui_fileopen_style) {
181 case FO_STYLE_LAST_OPENED:
182 /* The user has specified that we should start out in the last directory
183 we looked in. If we've already opened a file, use its containing
184 directory, if we could determine it, as the directory, otherwise
185 use the "last opened" directory saved in the preferences file if
187 /* This is now the default behaviour in file_selection_new() */
190 case FO_STYLE_SPECIFIED:
191 /* The user has specified that we should always start out in a
192 specified directory; if they've specified that directory,
193 start out by showing the files in that dir. */
194 if (prefs.gui_fileopen_dir[0] != '\0')
195 open_dlg.setDirectory(prefs.gui_fileopen_dir);
199 if (open_dlg.open(file_name, type)) {
206 if (!testCaptureFileClose(false)) {
210 if (dfilter_compile(read_filter.toUtf8().constData(), &rfcode, &err_msg)) {
211 cf_set_rfcode(CaptureFile::globalCapFile(), rfcode);
213 /* Not valid. Tell the user, and go back and run the file
214 selection box again once they dismiss the alert. */
215 //bad_dfilter_alert_box(top_level, read_filter->str);
216 QMessageBox::warning(this, tr("Invalid Display Filter"),
217 QString("The filter expression ") +
219 QString(" isn't a valid display filter. (") +
220 err_msg + QString(")."),
224 // go back to the selection dialogue only if the file
225 // was selected from this dialogue
231 /* Try to open the capture file. This closes the current file if it succeeds. */
232 CaptureFile::globalCapFile()->window = this;
233 if (cf_open(CaptureFile::globalCapFile(), cf_path.toUtf8().constData(), type, FALSE, &err) != CF_OK) {
234 /* We couldn't open it; don't dismiss the open dialog box,
235 just leave it around so that the user can, after they
236 dismiss the alert box popped up for the open error,
238 CaptureFile::globalCapFile()->window = NULL;
240 dfilter_free(rfcode);
245 switch (cf_read(CaptureFile::globalCapFile(), FALSE)) {
249 /* Just because we got an error, that doesn't mean we were unable
250 to read any of the file; we handle what we could get from the
254 case CF_READ_ABORTED:
255 /* The user bailed out of re-reading the capture file; the
256 capture file has been closed - just free the capture file name
257 string and return (without changing the last containing
259 capture_file_.setCapFile(NULL);
264 // get_dirname overwrites its path. Hopefully this isn't a problem.
265 wsApp->setLastOpenDir(get_dirname(cf_path.toUtf8().data()));
267 main_ui_->statusBar->showExpert();
272 void MainWindow::filterPackets(QString new_filter, bool force)
274 cf_status_t cf_status;
276 cf_status = cf_filter_packets(CaptureFile::globalCapFile(), new_filter.toUtf8().data(), force);
278 if (cf_status == CF_OK) {
279 emit displayFilterSuccess(true);
280 if (new_filter.length() > 0) {
281 int index = df_combo_box_->findText(new_filter);
283 df_combo_box_->insertItem(0, new_filter);
284 df_combo_box_->setCurrentIndex(0);
286 df_combo_box_->setCurrentIndex(index);
289 df_combo_box_->lineEdit()->clear();
292 emit displayFilterSuccess(false);
296 // A new layout should be applied when it differs from the old layout AND
297 // at the following times:
299 // - When the preferences change
300 // - When the profile changes
301 void MainWindow::layoutPanes()
303 QVector<unsigned> new_layout = QVector<unsigned>() << prefs.gui_layout_type
304 << prefs.gui_layout_content_1
305 << prefs.gui_layout_content_2
306 << prefs.gui_layout_content_3;
307 if (cur_layout_ == new_layout) return;
309 QSplitter *parents[3];
310 int current_row = capture_file_.currentRow();
312 // Reparent all widgets and add them back in the proper order below.
313 // This hides each widget as well.
314 packet_list_->freeze(); // Clears tree and byte view tabs.
315 packet_list_->setParent(main_ui_->mainStack);
316 proto_tree_->setParent(main_ui_->mainStack);
317 byte_view_tab_->setParent(main_ui_->mainStack);
318 empty_pane_.setParent(main_ui_->mainStack);
319 extra_split_.setParent(main_ui_->mainStack);
321 // XXX We should try to preserve geometries if we can, e.g. by
322 // checking to see if the layout type is the same.
323 switch(prefs.gui_layout_type) {
326 extra_split_.setOrientation(Qt::Horizontal);
329 master_split_.setOrientation(Qt::Vertical);
334 extra_split_.setOrientation(Qt::Vertical);
337 master_split_.setOrientation(Qt::Horizontal);
341 g_assert_not_reached();
344 switch(prefs.gui_layout_type) {
347 parents[0] = &master_split_;
348 parents[1] = &master_split_;
349 parents[2] = &master_split_;
353 parents[0] = &master_split_;
354 parents[1] = &extra_split_;
355 parents[2] = &extra_split_;
359 parents[0] = &extra_split_;
360 parents[1] = &extra_split_;
361 parents[2] = &master_split_;
364 g_assert_not_reached();
367 if (parents[0] == &extra_split_) {
368 master_split_.addWidget(&extra_split_);
371 parents[0]->addWidget(getLayoutWidget(prefs.gui_layout_content_1));
373 if (parents[2] == &extra_split_) {
374 master_split_.addWidget(&extra_split_);
377 parents[1]->addWidget(getLayoutWidget(prefs.gui_layout_content_2));
378 parents[2]->addWidget(getLayoutWidget(prefs.gui_layout_content_3));
380 const QList<QWidget *> ms_children = master_split_.findChildren<QWidget *>();
382 extra_split_.setVisible(ms_children.contains(&extra_split_));
383 packet_list_->setVisible(ms_children.contains(packet_list_) && recent.packet_list_show);
384 proto_tree_->setVisible(ms_children.contains(proto_tree_) && recent.tree_view_show);
385 byte_view_tab_->setVisible(ms_children.contains(byte_view_tab_) && recent.byte_view_show);
387 packet_list_->thaw();
388 cf_select_packet(capture_file_.capFile(), current_row); // XXX Doesn't work for row 0?
389 cur_layout_ = new_layout;
392 // The recent layout geometry should be applied after the layout has been
393 // applied AND at the following times:
395 // - When the profile changes
396 void MainWindow::applyRecentPaneGeometry()
398 // XXX This shrinks slightly each time the application is run. For some
399 // reason the master_split_ geometry is two pixels shorter when
400 // saveWindowGeometry is invoked.
402 // This is also an awful lot of trouble to go through to reuse the GTK+
403 // pane settings. We might want to add gui.geometry_main_master_sizes
404 // and gui.geometry_main_extra_sizes and save QSplitter::saveState in
407 // Force a geometry recalculation
408 QWidget *cur_w = main_ui_->mainStack->currentWidget();
409 main_ui_->mainStack->setCurrentWidget(&master_split_);
410 QRect geom = master_split_.geometry();
411 QList<int> master_sizes = master_split_.sizes();
412 QList<int> extra_sizes = extra_split_.sizes();
413 main_ui_->mainStack->setCurrentWidget(cur_w);
415 int master_last_size = master_split_.orientation() == Qt::Vertical ? geom.height() : geom.width();
416 int extra_last_size = extra_split_.orientation() == Qt::Vertical ? geom.height() : geom.width();
418 if (recent.gui_geometry_main_upper_pane > 0) {
419 master_sizes[0] = recent.gui_geometry_main_upper_pane + 1; // Add back mystery pixel
420 master_last_size -= recent.gui_geometry_main_upper_pane + master_split_.handleWidth();
423 if (recent.gui_geometry_main_lower_pane > 0) {
424 if (master_sizes.length() > 2) {
425 master_sizes[1] = recent.gui_geometry_main_lower_pane + 1; // Add back mystery pixel
426 master_last_size -= recent.gui_geometry_main_lower_pane + master_split_.handleWidth();
427 } else if (extra_sizes.length() > 0) {
428 extra_sizes[0] = recent.gui_geometry_main_lower_pane; // No mystery pixel
429 extra_last_size -= recent.gui_geometry_main_lower_pane + extra_split_.handleWidth();
430 extra_sizes.last() = extra_last_size;
434 master_sizes.last() = master_last_size;
436 master_split_.setSizes(master_sizes);
437 extra_split_.setSizes(extra_sizes);
440 void MainWindow::layoutToolbars()
442 Qt::ToolButtonStyle tbstyle = Qt::ToolButtonIconOnly;
443 switch (prefs.gui_toolbar_main_style) {
445 tbstyle = Qt::ToolButtonTextOnly;
448 tbstyle = Qt::ToolButtonTextUnderIcon;
452 main_ui_->mainToolBar->setToolButtonStyle(tbstyle);
455 void MainWindow::updatePreferenceActions()
457 main_ui_->actionViewNameResolutionPhysical->setChecked(gbl_resolv_flags.mac_name);
458 main_ui_->actionViewNameResolutionNetwork->setChecked(gbl_resolv_flags.network_name);
459 main_ui_->actionViewNameResolutionTransport->setChecked(gbl_resolv_flags.transport_name);
461 // Should this be a "recent" setting?
462 main_ui_->actionGoAutoScroll->setChecked(prefs.capture_auto_scroll);
465 void MainWindow::filterAction(QString &action_filter, FilterAction::Action action, FilterAction::ActionType type)
467 QString cur_filter, new_filter;
469 if (!df_combo_box_) return;
470 cur_filter = df_combo_box_->lineEdit()->text();
473 case FilterAction::ActionTypePlain:
474 new_filter = action_filter;
476 case FilterAction::ActionTypeAnd:
477 if (cur_filter.length()) {
478 new_filter = "(" + cur_filter + ") && (" + action_filter + ")";
480 new_filter = action_filter;
483 case FilterAction::ActionTypeOr:
484 if (cur_filter.length()) {
485 new_filter = "(" + cur_filter + ") || (" + action_filter + ")";
487 new_filter = action_filter;
490 case FilterAction::ActionTypeNot:
491 new_filter = "!(" + action_filter + ")";
493 case FilterAction::ActionTypeAndNot:
494 if (cur_filter.length()) {
495 new_filter = "(" + cur_filter + ") && !(" + action_filter + ")";
497 new_filter = "!(" + action_filter + ")";
500 case FilterAction::ActionTypeOrNot:
501 if (cur_filter.length()) {
502 new_filter = "(" + cur_filter + ") || !(" + action_filter + ")";
504 new_filter = "!(" + action_filter + ")";
508 g_assert_not_reached();
513 case FilterAction::ActionApply:
514 df_combo_box_->lineEdit()->setText(new_filter);
515 df_combo_box_->applyDisplayFilter();
517 case FilterAction::ActionPrepare:
518 df_combo_box_->lineEdit()->setText(new_filter);
519 df_combo_box_->lineEdit()->setFocus();
521 case FilterAction::ActionWebLookup:
523 QString url = QString("https://www.google.com/search?q=") + new_filter;
524 QDesktopServices::openUrl(QUrl(url));
527 case FilterAction::ActionCopy:
528 wsApp->clipboard()->setText(new_filter);
531 qDebug() << "FIX FilterAction::Action" << action << "not implemented";
538 void MainWindow::captureCapturePrepared(capture_session *) {
540 setTitlebarForCaptureInProgress();
542 setWindowIcon(wsApp->captureIcon());
544 /* Disable menu items that make no sense if you're currently running
546 setForCaptureInProgress(true);
547 // set_capture_if_dialog_for_capture_in_progress(TRUE);
549 // /* Don't set up main window for a capture file. */
550 // main_set_for_capture_file(FALSE);
551 main_ui_->mainStack->setCurrentWidget(&master_split_);
552 #endif // HAVE_LIBPCAP
555 void MainWindow::captureCaptureUpdateStarted(capture_session *) {
558 /* We've done this in "prepared" above, but it will be cleared while
559 switching to the next multiple file. */
560 setTitlebarForCaptureInProgress();
562 setForCaptureInProgress(true);
564 setForCapturedPackets(true);
565 #endif // HAVE_LIBPCAP
567 void MainWindow::captureCaptureUpdateFinished(capture_session *) {
570 /* The capture isn't stopping any more - it's stopped. */
571 capture_stopping_ = false;
573 /* Update the main window as appropriate */
574 updateForUnsavedChanges();
576 /* Enable menu items that make sense if you're not currently running
578 setForCaptureInProgress(false);
580 setWindowIcon(wsApp->normalIcon());
582 if (global_capture_opts.quit_after_cap) {
583 // Command line asked us to quit after capturing.
584 // Don't pop up a dialog to ask for unsaved files etc.
587 #endif // HAVE_LIBPCAP
589 void MainWindow::captureCaptureFixedStarted(capture_session *) {
591 #endif // HAVE_LIBPCAP
593 void MainWindow::captureCaptureFixedFinished(capture_session *) {
596 /* The capture isn't stopping any more - it's stopped. */
597 capture_stopping_ = false;
599 /* Enable menu items that make sense if you're not currently running
601 setForCaptureInProgress(false);
603 setWindowIcon(wsApp->normalIcon());
605 if (global_capture_opts.quit_after_cap) {
606 // Command line asked us to quit after capturing.
607 // Don't pop up a dialog to ask for unsaved files etc.
610 #endif // HAVE_LIBPCAP
612 void MainWindow::captureCaptureStopping(capture_session *) {
615 capture_stopping_ = true;
616 setMenusForCaptureStopping();
617 #endif // HAVE_LIBPCAP
619 void MainWindow::captureCaptureFailed(capture_session *) {
621 /* Capture isn't stopping any more. */
622 capture_stopping_ = false;
624 setForCaptureInProgress(false);
625 main_ui_->mainStack->setCurrentWidget(main_welcome_);
627 setWindowIcon(wsApp->normalIcon());
629 if (global_capture_opts.quit_after_cap) {
630 // Command line asked us to quit after capturing.
631 // Don't pop up a dialog to ask for unsaved files etc.
634 #endif // HAVE_LIBPCAP
638 // Callbacks from cfile.c and file.c via CaptureFile::captureFileCallback
640 void MainWindow::captureFileOpened() {
641 if (capture_file_.window() != this) return;
643 file_set_dialog_.fileOpened(capture_file_.capFile());
644 setMenusForFileSet(true);
645 emit setCaptureFile(capture_file_.capFile());
648 void MainWindow::captureFileReadStarted(const QString &action) {
649 // tap_param_dlg_update();
651 /* Set up main window for a capture file. */
652 // main_set_for_capture_file(TRUE);
654 main_ui_->statusBar->popFileStatus();
655 QString msg = QString(tr("%1: %2")).arg(action).arg(capture_file_.fileName());
656 QString msgtip = QString();
657 main_ui_->statusBar->pushFileStatus(msg, msgtip);
658 main_ui_->mainStack->setCurrentWidget(&master_split_);
659 WiresharkApplication::processEvents();
662 void MainWindow::captureFileReadFinished() {
665 if (!capture_file_.capFile()->is_tempfile && capture_file_.capFile()->filename) {
666 /* Add this filename to the list of recent files in the "Recent Files" submenu */
667 add_menu_recent_capture_file(capture_file_.capFile()->filename);
669 /* Remember folder for next Open dialog and save it in recent */
670 dir_path = get_dirname(g_strdup(capture_file_.capFile()->filename));
671 wsApp->setLastOpenDir(dir_path);
675 /* Update the appropriate parts of the main window. */
676 updateForUnsavedChanges();
678 /* Enable menu items that make sense if you have some captured packets. */
679 setForCapturedPackets(true);
681 main_ui_->statusBar->setFileName(capture_file_);
683 packet_list_->captureFileReadFinished();
685 emit setDissectedCaptureFile(capture_file_.capFile());
688 // Our event loop becomes nested whenever we call update_progress_dlg, which
689 // includes several places in file.c. The GTK+ UI stays out of trouble by
690 // showing a modal progress dialog. We attempt to do the equivalent below by
691 // disabling parts of the main window. At a minumum the ProgressFrame in the
692 // main status bar must remain accessible.
694 // We might want to do this any time the main status bar progress frame is
696 void MainWindow::captureFileRetapStarted()
698 // XXX Push a status message?
699 main_ui_->actionFileClose->setEnabled(false);
700 main_ui_->actionViewReload->setEnabled(false);
701 main_ui_->centralWidget->setEnabled(false);
704 void MainWindow::captureFileRetapFinished()
706 main_ui_->actionFileClose->setEnabled(true);
707 main_ui_->actionViewReload->setEnabled(true);
708 main_ui_->centralWidget->setEnabled(true);
711 void MainWindow::captureFileClosing() {
712 setMenusForCaptureFile(true);
713 setForCapturedPackets(false);
714 setMenusForSelectedPacket();
715 setForCaptureInProgress(false);
717 // Reset expert information indicator
718 main_ui_->statusBar->captureFileClosing();
719 main_ui_->searchFrame->animatedHide();
720 // gtk_widget_show(expert_info_none);
721 emit setCaptureFile(NULL);
722 emit setDissectedCaptureFile(NULL);
725 void MainWindow::captureFileClosed() {
726 packets_bar_update();
728 file_set_dialog_.fileClosed();
729 setMenusForFileSet(false);
731 // Reset expert information indicator
732 main_ui_->statusBar->captureFileClosing();
734 main_ui_->statusBar->popFileStatus();
736 setTitlebarForSelectedTreeRow();
737 setMenusForSelectedTreeRow();
739 if (!global_capture_opts.multi_files_on)
740 main_ui_->mainStack->setCurrentWidget(main_welcome_);
743 void MainWindow::captureFileSaveStarted(const QString &file_path)
745 QFileInfo file_info(file_path);
746 main_ui_->statusBar->popFileStatus();
747 main_ui_->statusBar->pushFileStatus(tr("Saving %1" UTF8_HORIZONTAL_ELLIPSIS).arg(file_info.baseName()));
750 void MainWindow::filterExpressionsChanged()
752 // Recreate filter buttons
753 foreach (QAction *act, main_ui_->displayFilterToolBar->actions()) {
754 // Permanent actions shouldn't have data
755 if (act->property(dfe_property_).isValid() || act->isSeparator()) {
756 main_ui_->displayFilterToolBar->removeAction(act);
762 for (struct filter_expression *fe = *pfilter_expression_head; fe != NULL; fe = fe->next) {
763 if (!fe->enabled) continue;
764 QAction *dfb_action = new QAction(fe->label, main_ui_->displayFilterToolBar);
765 dfb_action->setToolTip(fe->expression);
766 dfb_action->setData(fe->expression);
767 dfb_action->setProperty(dfe_property_, true);
768 main_ui_->displayFilterToolBar->addAction(dfb_action);
769 connect(dfb_action, SIGNAL(triggered()), this, SLOT(displayFilterButtonClicked()));
772 main_ui_->displayFilterToolBar->insertSeparator(dfb_action);
781 // ui/gtk/capture_dlg.c:start_capture_confirmed
783 void MainWindow::startCapture() {
785 interface_options interface_opts;
788 /* did the user ever select a capture interface before? */
789 if(global_capture_opts.num_selected == 0) {
790 QString msg = QString(tr("No interface selected"));
791 main_ui_->statusBar->pushTemporaryStatus(msg);
792 main_ui_->actionCaptureStart->setChecked(false);
796 main_ui_->mainStack->setCurrentWidget(&master_split_);
798 // Ideally we should have disabled the start capture
799 // toolbar buttons and menu items. This may not be the
800 // case, e.g. with QtMacExtras.
801 if(!capture_filter_valid_) {
802 QString msg = QString(tr("Invalid capture filter"));
803 main_ui_->statusBar->pushTemporaryStatus(msg);
804 main_ui_->actionCaptureStart->setChecked(false);
808 /* XXX - we might need to init other pref data as well... */
810 /* XXX - can this ever happen? */
811 if (cap_session_.state != CAPTURE_STOPPED)
814 /* close the currently loaded capture file */
815 cf_close((capture_file *) cap_session_.cf);
817 /* Copy the selected interfaces to the set of interfaces to use for
819 collect_ifaces(&global_capture_opts);
821 CaptureFile::globalCapFile()->window = this;
822 if (capture_start(&global_capture_opts, &cap_session_, main_window_update)) {
823 capture_options *capture_opts = cap_session_.capture_opts;
824 GString *interface_names;
826 /* enable autoscroll timer as needed. */
827 packet_list_->setAutoScroll(main_ui_->actionGoAutoScroll->isChecked());
829 /* Add "interface name<live capture in progress>" on main status bar */
830 interface_names = get_iface_list_string(capture_opts, 0);
831 if (strlen (interface_names->str) > 0) {
832 g_string_append(interface_names, ":");
834 g_string_append(interface_names, " ");
836 main_ui_->statusBar->popFileStatus();
837 QString msg = QString().sprintf("%s<live capture in progress>", interface_names->str);
838 QString msgtip = QString().sprintf("to file: %s", (capture_opts->save_file) ? capture_opts->save_file : "");
839 main_ui_->statusBar->pushFileStatus(msg, msgtip);
840 g_string_free(interface_names, TRUE);
842 /* The capture succeeded, which means the capture filter syntax is
843 valid; add this capture filter to the recent capture filter list. */
844 for (i = 0; i < global_capture_opts.ifaces->len; i++) {
845 interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
846 if (interface_opts.cfilter) {
847 // cfilter_combo_add_recent(interface_opts.cfilter);
851 CaptureFile::globalCapFile()->window = NULL;
853 #endif // HAVE_LIBPCAP
856 // Copied from ui/gtk/gui_utils.c
857 void MainWindow::pipeTimeout() {
861 gboolean result, result1;
866 /* try to read data from the pipe only 5 times, to avoid blocking */
867 while(iterations < 5) {
868 /*g_log(NULL, G_LOG_LEVEL_DEBUG, "pipe_timer_cb: new iteration");*/
870 /* Oddly enough although Named pipes don't work on win9x,
871 PeekNamedPipe does !!! */
872 handle = (HANDLE) _get_osfhandle (pipe_source_);
873 result = PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL);
875 /* Get the child process exit status */
876 result1 = GetExitCodeProcess((HANDLE)*(pipe_child_process_),
879 /* If the Peek returned an error, or there are bytes to be read
880 or the childwatcher thread has terminated then call the normal
882 if (!result || avail > 0 || childstatus != STILL_ACTIVE) {
884 /*g_log(NULL, G_LOG_LEVEL_DEBUG, "pipe_timer_cb: data avail");*/
886 /* And call the real handler */
887 if (!pipe_input_cb_(pipe_source_, pipe_user_data_)) {
888 g_log(NULL, G_LOG_LEVEL_DEBUG, "pipe_timer_cb: input pipe closed, iterations: %u", iterations);
889 /* pipe closed, return false so that the old timer is not run again */
895 /*g_log(NULL, G_LOG_LEVEL_DEBUG, "pipe_timer_cb: no data avail");*/
896 /* No data, stop now */
905 void MainWindow::pipeActivated(int source) {
909 g_assert(source == pipe_source_);
911 pipe_notifier_->setEnabled(false);
912 if (pipe_input_cb_(pipe_source_, pipe_user_data_)) {
913 pipe_notifier_->setEnabled(true);
915 delete pipe_notifier_;
920 void MainWindow::pipeNotifierDestroyed() {
924 pipe_notifier_ = NULL;
928 void MainWindow::stopCapture() {
929 //#ifdef HAVE_AIRPCAP
930 // if (airpcap_if_active)
931 // airpcap_set_toolbar_stop_capture(airpcap_if_active);
935 capture_stop(&cap_session_);
936 #endif // HAVE_LIBPCAP
938 /* Pop the "<live capture in progress>" message off the status bar. */
939 main_ui_->statusBar->setFileName(capture_file_);
941 /* disable autoscroll timer if any. */
942 packet_list_->setAutoScroll(false);
945 // Keep focus rects from showing through the welcome screen. Primarily for
947 void MainWindow::mainStackChanged(int)
949 for (int i = 0; i < main_ui_->mainStack->count(); i++) {
950 main_ui_->mainStack->widget(i)->setEnabled(i == main_ui_->mainStack->currentIndex());
954 // XXX - Copied from ui/gtk/menus.c
957 * Add the capture filename (with an absolute path) to the "Recent Files" menu.
959 // XXX - We should probably create a RecentFile class.
960 void MainWindow::updateRecentFiles() {
962 QMenu *recentMenu = main_ui_->menuOpenRecentCaptureFile;
963 QString action_cf_name;
971 /* Iterate through the actions in menuOpenRecentCaptureFile,
972 * removing special items, a maybe duplicate entry and every item above count_max */
973 int shortcut = Qt::Key_0;
974 foreach (recent_item_status *ri, wsApp->recentItems()) {
976 ra = new QAction(recentMenu);
977 ra->setData(ri->filename);
978 // XXX - Needs get_recent_item_status or equivalent
979 ra->setEnabled(ri->accessible);
980 recentMenu->insertAction(NULL, ra);
981 action_cf_name = ra->data().toString();
982 if (shortcut <= Qt::Key_9) {
983 ra->setShortcut(Qt::META | shortcut);
986 ra->setText(action_cf_name);
987 connect(ra, SIGNAL(triggered()), this, SLOT(recentActionTriggered()));
990 if (recentMenu->actions().count() > 0) {
991 // Separator + "Clear"
992 // XXX - Do we really need this?
993 ra = new QAction(recentMenu);
994 ra->setSeparator(true);
995 recentMenu->insertAction(NULL, ra);
997 ra = new QAction(recentMenu);
998 ra->setText(tr("Clear Menu"));
999 recentMenu->insertAction(NULL, ra);
1000 connect(ra, SIGNAL(triggered()), wsApp, SLOT(clearRecentItems()));
1002 if (main_ui_->actionDummyNoFilesFound) {
1003 recentMenu->addAction(main_ui_->actionDummyNoFilesFound);
1008 void MainWindow::recentActionTriggered() {
1009 QAction *ra = qobject_cast<QAction*>(sender());
1012 QString cfPath = ra->data().toString();
1013 openCaptureFile(cfPath);
1017 void MainWindow::setMenusForSelectedPacket()
1019 gboolean is_ip = FALSE, is_tcp = FALSE, is_udp = FALSE, is_sctp = FALSE, is_ssl = FALSE, is_rtp = FALSE;
1021 /* Making the menu context-sensitive allows for easier selection of the
1022 desired item and has the added benefit, with large captures, of
1023 avoiding needless looping through huge lists for marked, ignored,
1024 or time-referenced packets. */
1026 /* We have one or more items in the packet list */
1027 bool have_frames = false;
1028 /* A frame is selected */
1029 bool frame_selected = false;
1030 /* We have marked frames. (XXX - why check frame_selected?) */
1031 bool have_marked = false;
1032 /* We have a marked frame other than the current frame (i.e.,
1033 we have at least one marked frame, and either there's more
1034 than one marked frame or the current frame isn't marked). */
1035 bool another_is_marked = false;
1036 /* One or more frames are hidden by a display filter */
1037 bool have_filtered = false;
1038 /* One or more frames have been ignored */
1039 bool have_ignored = false;
1040 bool have_time_ref = false;
1041 /* We have a time reference frame other than the current frame (i.e.,
1042 we have at least one time reference frame, and either there's more
1043 than one time reference frame or the current frame isn't a
1044 time reference frame). (XXX - why check frame_selected?) */
1045 bool another_is_time_ref = false;
1046 /* We have a valid filter expression */
1047 bool have_filter_expr = false;
1049 QList<QAction *> cc_actions = QList<QAction *>()
1050 << main_ui_->actionViewColorizeConversation1 << main_ui_->actionViewColorizeConversation2
1051 << main_ui_->actionViewColorizeConversation3 << main_ui_->actionViewColorizeConversation4
1052 << main_ui_->actionViewColorizeConversation5 << main_ui_->actionViewColorizeConversation6
1053 << main_ui_->actionViewColorizeConversation7 << main_ui_->actionViewColorizeConversation8
1054 << main_ui_->actionViewColorizeConversation9 << main_ui_->actionViewColorizeConversation10;
1056 if (capture_file_.capFile()) {
1057 frame_selected = capture_file_.capFile()->current_frame != NULL;
1058 have_frames = capture_file_.capFile()->count > 0;
1059 have_marked = frame_selected && capture_file_.capFile()->marked_count > 0;
1060 another_is_marked = have_marked &&
1061 !(capture_file_.capFile()->marked_count == 1 && capture_file_.capFile()->current_frame->flags.marked);
1062 have_filtered = capture_file_.capFile()->displayed_count > 0 && capture_file_.capFile()->displayed_count != capture_file_.capFile()->count;
1063 have_ignored = capture_file_.capFile()->ignored_count > 0;
1064 have_time_ref = capture_file_.capFile()->ref_time_count > 0;
1065 another_is_time_ref = frame_selected && have_time_ref &&
1066 !(capture_file_.capFile()->ref_time_count == 1 && capture_file_.capFile()->current_frame->flags.ref_time);
1068 if (capture_file_.capFile()->edt)
1070 proto_get_frame_protocols(capture_file_.capFile()->edt->pi.layers, &is_ip, &is_tcp, &is_udp, &is_sctp, &is_ssl, &is_rtp);
1074 have_filter_expr = !packet_list_->getFilterFromRowAndColumn().isEmpty();
1076 main_ui_->actionEditMarkPacket->setEnabled(frame_selected);
1077 main_ui_->actionEditMarkAllDisplayed->setEnabled(have_frames);
1078 /* Unlike un-ignore, do not allow unmark of all frames when no frames are displayed */
1079 main_ui_->actionEditUnmarkAllDisplayed->setEnabled(have_marked);
1080 main_ui_->actionEditNextMark->setEnabled(another_is_marked);
1081 main_ui_->actionEditPreviousMark->setEnabled(another_is_marked);
1083 #ifdef WANT_PACKET_EDITOR
1084 // set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/EditMenu/EditPacket",
1086 #endif // WANT_PACKET_EDITOR
1087 main_ui_->actionEditPacketComment->setEnabled(frame_selected && wtap_dump_can_write(capture_file_.capFile()->linktypes, WTAP_COMMENT_PER_PACKET));
1089 main_ui_->actionEditIgnorePacket->setEnabled(frame_selected);
1090 main_ui_->actionEditIgnoreAllDisplayed->setEnabled(have_filtered);
1091 /* Allow un-ignore of all frames even with no frames currently displayed */
1092 main_ui_->actionEditUnignoreAllDisplayed->setEnabled(have_ignored);
1094 main_ui_->actionEditSetTimeReference->setEnabled(frame_selected);
1095 main_ui_->actionEditUnsetAllTimeReferences->setEnabled(have_time_ref);
1096 main_ui_->actionEditNextTimeReference->setEnabled(another_is_time_ref);
1097 main_ui_->actionEditPreviousTimeReference->setEnabled(another_is_time_ref);
1098 main_ui_->actionEditTimeShift->setEnabled(have_frames);
1100 main_ui_->actionGoGoToLinkedPacket->setEnabled(false);
1102 main_ui_->actionAnalyzeAAFSelected->setEnabled(have_filter_expr);
1103 main_ui_->actionAnalyzeAAFNotSelected->setEnabled(have_filter_expr);
1104 main_ui_->actionAnalyzeAAFAndSelected->setEnabled(have_filter_expr);
1105 main_ui_->actionAnalyzeAAFOrSelected->setEnabled(have_filter_expr);
1106 main_ui_->actionAnalyzeAAFAndNotSelected->setEnabled(have_filter_expr);
1107 main_ui_->actionAnalyzeAAFOrNotSelected->setEnabled(have_filter_expr);
1109 main_ui_->actionAnalyzePAFSelected->setEnabled(have_filter_expr);
1110 main_ui_->actionAnalyzePAFNotSelected->setEnabled(have_filter_expr);
1111 main_ui_->actionAnalyzePAFAndSelected->setEnabled(have_filter_expr);
1112 main_ui_->actionAnalyzePAFOrSelected->setEnabled(have_filter_expr);
1113 main_ui_->actionAnalyzePAFAndNotSelected->setEnabled(have_filter_expr);
1114 main_ui_->actionAnalyzePAFOrNotSelected->setEnabled(have_filter_expr);
1116 main_ui_->actionAnalyzeFollowTCPStream->setEnabled(is_tcp);
1117 main_ui_->actionAnalyzeFollowUDPStream->setEnabled(is_udp);
1118 main_ui_->actionAnalyzeFollowSSLStream->setEnabled(is_ssl);
1120 foreach (QAction *cc_action, cc_actions) {
1121 cc_action->setEnabled(frame_selected);
1123 main_ui_->actionViewColorizeNewConversationRule->setEnabled(frame_selected);
1125 main_ui_->actionViewColorizeResetColorization->setEnabled(tmp_color_filters_used());
1127 main_ui_->actionViewColorizeNewConversationRule->setEnabled(frame_selected);
1129 main_ui_->actionViewShowPacketInNewWindow->setEnabled(frame_selected);
1130 main_ui_->actionViewEditResolvedName->setEnabled(frame_selected && is_ip);
1132 main_ui_->menuConversationFilter->clear();
1134 packet_list_->conversationMenu()->clear();
1135 packet_list_->colorizeMenu()->clear();
1137 for (GList *color_list_entry = color_conv_filter_list; color_list_entry; color_list_entry = g_list_next(color_list_entry)) {
1139 color_conversation_filter_t* color_filter = (color_conversation_filter_t *)color_list_entry->data;
1140 QAction *conv_action = main_ui_->menuConversationFilter->addAction(color_filter->display_name);
1142 bool enable = false;
1144 if (capture_file_.capFile()->edt) {
1145 enable = color_filter->is_filter_valid(&capture_file_.capFile()->edt->pi);
1146 filter = gchar_free_to_qstring(color_filter->build_filter_string(&capture_file_.capFile()->edt->pi));
1148 conv_action->setEnabled(enable);
1149 conv_action->setData(filter);
1150 connect(conv_action, SIGNAL(triggered()), this, SLOT(applyConversationFilter()));
1152 // Packet list context menu items
1153 packet_list_->conversationMenu()->addAction(conv_action);
1155 QMenu *submenu = packet_list_->colorizeMenu()->addMenu(conv_action->text());
1157 foreach (QAction *cc_action, cc_actions) {
1158 QAction *colorize_action = submenu->addAction(cc_action->icon(), cc_action->text());
1159 colorize_action->setProperty(color_number_property_, i++);
1160 colorize_action->setData(filter);
1161 colorize_action->setEnabled(enable);
1162 connect(colorize_action, SIGNAL(triggered()), this, SLOT(colorizeWithFilter()));
1165 QAction *conv_rule_action = submenu->addAction(main_ui_->actionViewColorizeNewConversationRule->text());
1166 conv_rule_action->setData(conv_action->data());
1167 conv_rule_action->setEnabled(enable);
1168 connect(conv_rule_action, SIGNAL(triggered()), this, SLOT(colorizeWithFilter()));
1171 // set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/ViewMenu/NameResolution/ResolveName",
1172 // frame_selected && (gbl_resolv_flags.mac_name || gbl_resolv_flags.network_name ||
1173 // gbl_resolv_flags.transport_name || gbl_resolv_flags.concurrent_dns));
1174 // set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/ToolsMenu/FirewallACLRules",
1176 main_ui_->menuTcpStreamGraphs->setEnabled(is_tcp);
1177 main_ui_->actionSCTPAnalyseThisAssociation->setEnabled(is_sctp);
1178 main_ui_->actionSCTPShowAllAssociations->setEnabled(is_sctp);
1179 main_ui_->actionSCTPFilterThisAssociation->setEnabled(is_sctp);
1180 main_ui_->actionTelephonyRTPStreamAnalysis->setEnabled(is_rtp);
1183 void MainWindow::setMenusForSelectedTreeRow(field_info *fi) {
1185 bool can_match_selected = false;
1186 bool is_framenum = false;
1187 bool have_field_info = false;
1188 bool have_subtree = false;
1189 bool can_open_url = false;
1190 QString field_filter;
1193 QList<QAction *> cc_actions = QList<QAction *>()
1194 << main_ui_->actionViewColorizeConversation1 << main_ui_->actionViewColorizeConversation2
1195 << main_ui_->actionViewColorizeConversation3 << main_ui_->actionViewColorizeConversation4
1196 << main_ui_->actionViewColorizeConversation5 << main_ui_->actionViewColorizeConversation6
1197 << main_ui_->actionViewColorizeConversation7 << main_ui_->actionViewColorizeConversation8
1198 << main_ui_->actionViewColorizeConversation9 << main_ui_->actionViewColorizeConversation10;
1200 if (capture_file_.capFile()) {
1201 capture_file_.capFile()->finfo_selected = fi;
1203 if (fi && fi->tree_type != -1) {
1204 have_subtree = true;
1208 if (capture_file_.capFile() != NULL && fi != NULL) {
1209 header_field_info *hfinfo = fi->hfinfo;
1210 int linked_frame = -1;
1212 have_field_info = true;
1213 can_match_selected = proto_can_match_selected(capture_file_.capFile()->finfo_selected, capture_file_.capFile()->edt);
1214 if (hfinfo && hfinfo->type == FT_FRAMENUM) {
1216 linked_frame = fvalue_get_uinteger(&fi->value);
1219 char *tmp_field = proto_construct_match_selected_string(fi, capture_file_.capFile()->edt);
1220 field_filter = QString(tmp_field);
1221 wmem_free(NULL, tmp_field);
1223 field_id = fi->hfinfo->id;
1224 /* if the selected field isn't a protocol, get its parent */
1225 if (!proto_registrar_is_protocol(field_id)) {
1226 field_id = proto_registrar_get_parent(fi->hfinfo->id);
1229 if (field_id >= 0 && !proto_is_private(field_id)) {
1230 can_open_url = true;
1231 main_ui_->actionContextWikiProtocolPage->setData(field_id);
1232 main_ui_->actionContextFilterFieldReference->setData(field_id);
1234 main_ui_->actionContextWikiProtocolPage->setData(QVariant());
1235 main_ui_->actionContextFilterFieldReference->setData(QVariant());
1238 if (linked_frame > 0) {
1239 main_ui_->actionGoGoToLinkedPacket->setData(linked_frame);
1241 main_ui_->actionGoGoToLinkedPacket->setData(QVariant());
1245 // Always enable / disable the following items.
1246 main_ui_->actionFileExportPacketBytes->setEnabled(have_field_info);
1248 main_ui_->actionCopyAllVisibleItems->setEnabled(capture_file_.capFile() != NULL);
1249 main_ui_->actionCopyAllVisibleSelectedTreeItems->setEnabled(can_match_selected);
1250 main_ui_->actionEditCopyDescription->setEnabled(can_match_selected);
1251 main_ui_->actionEditCopyFieldName->setEnabled(can_match_selected);
1252 main_ui_->actionEditCopyValue->setEnabled(can_match_selected);
1253 main_ui_->actionEditCopyAsFilter->setEnabled(can_match_selected);
1255 main_ui_->actionViewExpandSubtrees->setEnabled(have_subtree);
1257 main_ui_->actionGoGoToLinkedPacket->setEnabled(is_framenum);
1259 main_ui_->actionAnalyzeCreateAColumn->setEnabled(can_match_selected);
1261 main_ui_->actionContextShowLinkedPacketInNewWindow->setEnabled(is_framenum);
1263 main_ui_->actionContextWikiProtocolPage->setEnabled(can_open_url);
1264 main_ui_->actionContextFilterFieldReference->setEnabled(can_open_url);
1267 // Only enable / disable the following items if we have focus so that we
1268 // don't clobber anything we may have set in setMenusForSelectedPacket.
1269 if (!proto_tree_ || !proto_tree_->hasFocus()) return;
1271 main_ui_->menuConversationFilter->clear();
1272 for (GList *color_list_entry = color_conv_filter_list; color_list_entry; color_list_entry = g_list_next(color_list_entry)) {
1273 color_conversation_filter_t* color_filter = (color_conversation_filter_t *)color_list_entry->data;
1274 QAction *conv_action = main_ui_->menuConversationFilter->addAction(color_filter->display_name);
1276 bool conv_enable = false;
1277 QString conv_filter;
1278 if (capture_file_.capFile() && capture_file_.capFile()->edt) {
1279 conv_enable = color_filter->is_filter_valid(&capture_file_.capFile()->edt->pi);
1280 conv_filter = color_filter->build_filter_string(&capture_file_.capFile()->edt->pi);
1282 conv_action->setEnabled(conv_enable);
1283 conv_action->setData(conv_filter);
1284 connect(conv_action, SIGNAL(triggered()), this, SLOT(applyConversationFilter()));
1287 proto_tree_->colorizeMenu()->clear();
1289 foreach (QAction *cc_action, cc_actions) {
1290 QAction *colorize_action = proto_tree_->colorizeMenu()->addAction(cc_action->icon(), cc_action->text());
1291 colorize_action->setProperty(color_number_property_, i++);
1292 colorize_action->setData(field_filter);
1293 colorize_action->setEnabled(!field_filter.isEmpty());
1294 connect(colorize_action, SIGNAL(triggered()), this, SLOT(colorizeWithFilter()));
1297 QAction *conv_rule_action = proto_tree_->colorizeMenu()->addAction(main_ui_->actionViewColorizeNewConversationRule->text());
1298 conv_rule_action->setData(field_filter);
1299 conv_rule_action->setEnabled(!field_filter.isEmpty());
1300 connect(conv_rule_action, SIGNAL(triggered()), this, SLOT(colorizeWithFilter()));
1302 // set_menu_sensitivity(ui_manager_tree_view_menu, "/TreeViewPopup/ResolveName",
1303 // frame_selected && (gbl_resolv_flags.mac_name || gbl_resolv_flags.network_name ||
1304 // gbl_resolv_flags.transport_name || gbl_resolv_flags.concurrent_dns));
1307 main_ui_->actionAnalyzeAAFSelected->setEnabled(can_match_selected);
1308 main_ui_->actionAnalyzeAAFNotSelected->setEnabled(can_match_selected);
1309 main_ui_->actionAnalyzeAAFAndSelected->setEnabled(can_match_selected);
1310 main_ui_->actionAnalyzeAAFOrSelected->setEnabled(can_match_selected);
1311 main_ui_->actionAnalyzeAAFAndNotSelected->setEnabled(can_match_selected);
1312 main_ui_->actionAnalyzeAAFOrNotSelected->setEnabled(can_match_selected);
1314 main_ui_->actionAnalyzePAFSelected->setEnabled(can_match_selected);
1315 main_ui_->actionAnalyzePAFNotSelected->setEnabled(can_match_selected);
1316 main_ui_->actionAnalyzePAFAndSelected->setEnabled(can_match_selected);
1317 main_ui_->actionAnalyzePAFOrSelected->setEnabled(can_match_selected);
1318 main_ui_->actionAnalyzePAFAndNotSelected->setEnabled(can_match_selected);
1319 main_ui_->actionAnalyzePAFOrNotSelected->setEnabled(can_match_selected);
1322 void MainWindow::interfaceSelectionChanged()
1325 // XXX This doesn't disable the toolbar button when using
1327 if (global_capture_opts.num_selected > 0 && capture_filter_valid_) {
1328 main_ui_->actionCaptureStart->setEnabled(true);
1330 main_ui_->actionCaptureStart->setEnabled(false);
1332 #endif // HAVE_LIBPCAP
1335 void MainWindow::captureFilterSyntaxChanged(bool valid)
1337 capture_filter_valid_ = valid;
1338 interfaceSelectionChanged();
1341 void MainWindow::startInterfaceCapture(bool valid)
1343 capture_filter_valid_ = valid;
1347 void MainWindow::redissectPackets()
1349 if (capture_file_.capFile())
1350 cf_redissect_packets(capture_file_.capFile());
1351 main_ui_->statusBar->expertUpdate();
1353 proto_free_deregistered_fields();
1356 void MainWindow::fieldsChanged()
1358 color_filters_reload();
1359 tap_listeners_dfilter_recompile();
1361 if (!df_combo_box_->checkDisplayFilter()) {
1362 g_free(CaptureFile::globalCapFile()->dfilter);
1363 CaptureFile::globalCapFile()->dfilter = NULL;
1366 if (have_custom_cols(&CaptureFile::globalCapFile()->cinfo)) {
1367 // Recreate packet list columns according to new/changed/deleted fields
1368 packet_list_->fieldsChanged(CaptureFile::globalCapFile());
1371 emit reloadFields();
1374 void MainWindow::showAccordionFrame(AccordionFrame *show_frame, bool toggle)
1376 QList<AccordionFrame *>frame_list = QList<AccordionFrame *>()
1377 << main_ui_->goToFrame << main_ui_->searchFrame
1378 << main_ui_->addressEditorFrame << main_ui_->columnEditorFrame
1379 << main_ui_->preferenceEditorFrame;
1381 frame_list.removeAll(show_frame);
1382 foreach (AccordionFrame *af, frame_list) af->animatedHide();
1385 if (show_frame->isVisible()) {
1386 show_frame->animatedHide();
1390 show_frame->animatedShow();
1393 void MainWindow::showColumnEditor(int column)
1395 previous_focus_ = wsApp->focusWidget();
1396 connect(previous_focus_, SIGNAL(destroyed()), this, SLOT(resetPreviousFocus()));
1397 showAccordionFrame(main_ui_->columnEditorFrame);
1398 main_ui_->columnEditorFrame->editColumn(column);
1401 void MainWindow::showPreferenceEditor()
1403 showAccordionFrame(main_ui_->preferenceEditorFrame);
1406 void MainWindow::initViewColorizeMenu()
1408 QList<QAction *> cc_actions = QList<QAction *>()
1409 << main_ui_->actionViewColorizeConversation1 << main_ui_->actionViewColorizeConversation2
1410 << main_ui_->actionViewColorizeConversation3 << main_ui_->actionViewColorizeConversation4
1411 << main_ui_->actionViewColorizeConversation5 << main_ui_->actionViewColorizeConversation6
1412 << main_ui_->actionViewColorizeConversation7 << main_ui_->actionViewColorizeConversation8
1413 << main_ui_->actionViewColorizeConversation9 << main_ui_->actionViewColorizeConversation10;
1415 guint8 color_num = 1;
1417 foreach (QAction *cc_action, cc_actions) {
1418 cc_action->setData(color_num);
1419 connect(cc_action, SIGNAL(triggered()), this, SLOT(colorizeConversation()));
1421 const color_filter_t *colorf = color_filters_tmp_color(color_num);
1423 QColor bg = ColorUtils::fromColorT(colorf->bg_color);
1424 QColor fg = ColorUtils::fromColorT(colorf->fg_color);
1425 cc_action->setIcon(StockIcon::colorIcon(bg.rgb(), fg.rgb(), QString::number(color_num)));
1431 // Spotlight uses Cmd+Space
1432 main_ui_->actionViewColorizeResetColorization->setShortcut(QKeySequence("Meta+Space"));
1436 void MainWindow::addStatsPluginsToMenu() {
1437 GList *cfg_list = stats_tree_get_cfg_list();
1438 GList *iter = g_list_first(cfg_list);
1439 QAction *stats_tree_action;
1441 bool first_item = true;
1444 stats_tree_cfg *cfg = (stats_tree_cfg*)iter->data;
1447 main_ui_->menuStatistics->addSeparator();
1451 parent_menu = main_ui_->menuStatistics;
1452 // gtk/main_menubar.c compresses double slashes, hence SkipEmptyParts
1453 QStringList cfg_name_parts = QString(cfg->name).split("/", QString::SkipEmptyParts);
1454 if (cfg_name_parts.isEmpty()) continue;
1456 QString stat_name = cfg_name_parts.takeLast();
1457 if (!cfg_name_parts.isEmpty()) {
1458 QString menu_name = cfg_name_parts.join("/");
1459 parent_menu = findOrAddMenu(parent_menu, menu_name);
1462 stats_tree_action = new QAction(stat_name, this);
1463 stats_tree_action->setData(cfg->abbr);
1464 parent_menu->addAction(stats_tree_action);
1465 connect(stats_tree_action, SIGNAL(triggered()), this, SLOT(actionStatisticsPlugin_triggered()));
1467 iter = g_list_next(iter);
1469 g_list_free(cfg_list);
1472 void MainWindow::setFeaturesEnabled(bool enabled)
1474 main_ui_->menuBar->setEnabled(enabled);
1475 main_ui_->mainToolBar->setEnabled(enabled);
1476 main_ui_->displayFilterToolBar->setEnabled(enabled);
1479 main_ui_->statusBar->clearMessage();
1483 main_ui_->statusBar->showMessage(tr("Please wait while Wireshark is initializing" UTF8_HORIZONTAL_ELLIPSIS));
1487 // Display Filter Toolbar
1489 void MainWindow::on_actionDisplayFilterExpression_triggered()
1491 DisplayFilterExpressionDialog *dfe_dialog = new DisplayFilterExpressionDialog(this);
1493 connect(dfe_dialog, SIGNAL(insertDisplayFilter(QString)),
1494 df_combo_box_->lineEdit(), SLOT(insertFilter(const QString &)));
1499 // On Qt4 + OS X with unifiedTitleAndToolBarOnMac set it's possible to make
1500 // the main window obnoxiously wide.
1502 void MainWindow::displayFilterButtonClicked()
1504 QAction *dfb_action = qobject_cast<QAction*>(sender());
1507 df_combo_box_->lineEdit()->setText(dfb_action->data().toString());
1508 df_combo_box_->applyDisplayFilter();
1509 df_combo_box_->lineEdit()->setFocus();
1513 void MainWindow::openStatCommandDialog(const QString &menu_path, const char *arg, void *userdata)
1515 QString slot = QString("statCommand%1").arg(menu_path);
1516 QMetaObject::invokeMethod(this, slot.toLatin1().constData(), Q_ARG(const char *, arg), Q_ARG(void *, userdata));
1519 void MainWindow::openTapParameterDialog(const QString cfg_str, const QString arg, void *userdata)
1521 TapParameterDialog *tp_dialog = TapParameterDialog::showTapParameterStatistics(*this, capture_file_, cfg_str, arg, userdata);
1522 if (!tp_dialog) return;
1524 connect(tp_dialog, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
1525 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
1526 connect(tp_dialog, SIGNAL(updateFilter(QString)),
1527 df_combo_box_->lineEdit(), SLOT(setText(QString)));
1531 void MainWindow::openTapParameterDialog()
1533 QAction *tpa = qobject_cast<QAction *>(QObject::sender());
1536 const QString cfg_str = tpa->data().toString();
1537 openTapParameterDialog(cfg_str, NULL, NULL);
1542 void MainWindow::on_actionFileOpen_triggered()
1547 void MainWindow::on_actionFileMerge_triggered()
1552 void MainWindow::on_actionFileImportFromHexDump_triggered()
1554 importCaptureFile();
1557 void MainWindow::on_actionFileClose_triggered() {
1558 if (testCaptureFileClose())
1559 main_ui_->mainStack->setCurrentWidget(main_welcome_);
1562 void MainWindow::on_actionFileSave_triggered()
1564 saveCaptureFile(capture_file_.capFile(), FALSE);
1567 void MainWindow::on_actionFileSaveAs_triggered()
1569 saveAsCaptureFile(capture_file_.capFile());
1572 void MainWindow::on_actionFileSetListFiles_triggered()
1574 file_set_dialog_.exec();
1577 void MainWindow::on_actionFileSetNextFile_triggered()
1579 fileset_entry *entry = fileset_get_next();
1582 QString new_cf_path = entry->fullname;
1583 openCaptureFile(new_cf_path);
1587 void MainWindow::on_actionFileSetPreviousFile_triggered()
1589 fileset_entry *entry = fileset_get_previous();
1592 QString new_cf_path = entry->fullname;
1593 openCaptureFile(new_cf_path);
1597 void MainWindow::on_actionFileExportPackets_triggered()
1599 exportSelectedPackets();
1602 void MainWindow::on_actionFileExportAsPlainText_triggered()
1604 exportDissections(export_type_text);
1607 void MainWindow::on_actionFileExportAsCSV_triggered()
1609 exportDissections(export_type_csv);
1612 void MainWindow::on_actionFileExportAsCArrays_triggered()
1614 exportDissections(export_type_carrays);
1617 void MainWindow::on_actionFileExportAsPSML_triggered()
1619 exportDissections(export_type_psml);
1622 void MainWindow::on_actionFileExportAsPDML_triggered()
1624 exportDissections(export_type_pdml);
1627 void MainWindow::on_actionFileExportPacketBytes_triggered()
1631 if (!capture_file_.capFile() || !capture_file_.capFile()->finfo_selected) return;
1633 file_name = QFileDialog::getSaveFileName(this,
1634 wsApp->windowTitleString(tr("Export Selected Packet Bytes")),
1635 wsApp->lastOpenDir().canonicalPath(),
1636 tr("Raw data (*.bin *.dat *.raw);;Any File (*.*)")
1639 if (file_name.length() > 0) {
1640 const guint8 *data_p;
1643 data_p = tvb_get_ptr(capture_file_.capFile()->finfo_selected->ds_tvb, 0, -1) +
1644 capture_file_.capFile()->finfo_selected->start;
1645 fd = ws_open(file_name.toUtf8().constData(), O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666);
1647 open_failure_alert_box(file_name.toUtf8().constData(), errno, TRUE);
1650 if (write(fd, data_p, capture_file_.capFile()->finfo_selected->length) < 0) {
1651 write_failure_alert_box(file_name.toUtf8().constData(), errno);
1655 if (::close(fd) < 0) {
1656 write_failure_alert_box(file_name.toUtf8().constData(), errno);
1660 /* Save the directory name for future file dialogs. */
1661 wsApp->setLastOpenDir(&file_name);
1664 void MainWindow::on_actionFileExportPDU_triggered()
1666 ExportPDUDialog *exportpdu_dialog = new ExportPDUDialog(this);
1668 if (exportpdu_dialog->isMinimized() == true)
1670 exportpdu_dialog->showNormal();
1674 exportpdu_dialog->show();
1677 exportpdu_dialog->raise();
1678 exportpdu_dialog->activateWindow();
1681 void MainWindow::on_actionFileExportSSLSessionKeys_triggered()
1687 keylist_len = ssl_session_key_count();
1688 /* don't show up the dialog, if no data has to be saved */
1689 if (keylist_len < 1) {
1690 /* shouldn't happen as the menu item should have been greyed out */
1691 QMessageBox::warning(
1694 tr("There are no SSL Session Keys to save."),
1700 save_title.append(wsApp->windowTitleString(tr("Export SSL Session Keys (%1 key%2").
1701 arg(keylist_len).arg(plurality(keylist_len, "", "s"))));
1702 file_name = QFileDialog::getSaveFileName(this,
1704 wsApp->lastOpenDir().canonicalPath(),
1705 tr("SSL Session Keys (*.keys *.txt);;Any File (*.*)")
1707 if (file_name.length() > 0) {
1711 keylist = ssl_export_sessions();
1712 fd = ws_open(file_name.toUtf8().constData(), O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666);
1714 open_failure_alert_box(file_name.toUtf8().constData(), errno, TRUE);
1719 * Thanks, Microsoft, for not using size_t for the third argument to
1720 * _write(). Presumably this string will be <= 4GiB long....
1722 if (ws_write(fd, keylist, (unsigned int)strlen(keylist)) < 0) {
1723 write_failure_alert_box(file_name.toUtf8().constData(), errno);
1728 if (::close(fd) < 0) {
1729 write_failure_alert_box(file_name.toUtf8().constData(), errno);
1734 /* Save the directory name for future file dialogs. */
1735 wsApp->setLastOpenDir(&file_name);
1740 void MainWindow::on_actionFileExportObjectsDICOM_triggered()
1742 new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Dicom);
1745 void MainWindow::on_actionStatisticsHpfeeds_triggered()
1747 openStatisticsTreeDialog("hpfeeds");
1750 void MainWindow::on_actionFileExportObjectsHTTP_triggered()
1752 new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Http);
1755 void MainWindow::on_actionFileExportObjectsSMB_triggered()
1757 new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Smb);
1760 void MainWindow::on_actionFileExportObjectsTFTP_triggered()
1762 new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Tftp);
1765 void MainWindow::on_actionFilePrint_triggered()
1767 PrintDialog pdlg(this, capture_file_.capFile());
1774 void MainWindow::recursiveCopyProtoTreeItems(QTreeWidgetItem *item, QString &clip, int ident_level) {
1775 if (!item->isExpanded()) return;
1777 for (int i_item = 0; i_item < item->childCount(); i_item += 1) {
1778 clip.append(QString(" ").repeated(ident_level));
1779 clip.append(item->child(i_item)->text(0));
1782 recursiveCopyProtoTreeItems(item->child(i_item), clip, ident_level + 1);
1786 // XXX This should probably be somewhere else.
1787 void MainWindow::actionEditCopyTriggered(MainWindow::CopySelected selection_type)
1789 char label_str[ITEM_LABEL_LENGTH];
1792 if (!capture_file_.capFile()) return;
1794 field_info *finfo_selected = capture_file_.capFile()->finfo_selected;
1796 switch(selection_type) {
1797 case CopySelectedDescription:
1798 if (finfo_selected && finfo_selected->rep
1799 && strlen (finfo_selected->rep->representation) > 0) {
1800 clip.append(finfo_selected->rep->representation);
1803 case CopySelectedFieldName:
1804 if (finfo_selected && finfo_selected->hfinfo->abbrev != 0) {
1805 clip.append(finfo_selected->hfinfo->abbrev);
1808 case CopySelectedValue:
1809 if (finfo_selected && capture_file_.capFile()->edt != 0) {
1810 gchar* field_str = get_node_field_value(finfo_selected, capture_file_.capFile()->edt);
1811 clip.append(field_str);
1815 case CopyAllVisibleItems:
1816 for (int i_item = 0; i_item < proto_tree_->topLevelItemCount(); i_item += 1) {
1817 clip.append(proto_tree_->topLevelItem(i_item)->text(0));
1820 recursiveCopyProtoTreeItems(proto_tree_->topLevelItem(i_item), clip, 1);
1824 case CopyAllVisibleSelectedTreeItems:
1825 if (proto_tree_->selectedItems().count() > 0) {
1826 clip.append(proto_tree_->currentItem()->text(0));
1829 recursiveCopyProtoTreeItems(proto_tree_->currentItem(), clip, 1);
1834 if (clip.length() == 0) {
1835 /* If no representation then... Try to read the value */
1836 proto_item_fill_label(capture_file_.capFile()->finfo_selected, label_str);
1837 clip.append(label_str);
1840 if (clip.length()) {
1841 wsApp->clipboard()->setText(clip);
1843 QString err = tr("Couldn't copy text. Try another item.");
1844 main_ui_->statusBar->pushTemporaryStatus(err);
1848 void MainWindow::on_actionCopyAllVisibleItems_triggered()
1850 actionEditCopyTriggered(CopyAllVisibleItems);
1853 void MainWindow::on_actionCopyAllVisibleSelectedTreeItems_triggered()
1855 actionEditCopyTriggered(CopyAllVisibleSelectedTreeItems);
1858 void MainWindow::on_actionEditCopyDescription_triggered()
1860 actionEditCopyTriggered(CopySelectedDescription);
1863 void MainWindow::on_actionEditCopyFieldName_triggered()
1865 actionEditCopyTriggered(CopySelectedFieldName);
1868 void MainWindow::on_actionEditCopyValue_triggered()
1870 actionEditCopyTriggered(CopySelectedValue);
1873 void MainWindow::on_actionEditCopyAsFilter_triggered()
1875 matchFieldFilter(FilterAction::ActionCopy, FilterAction::ActionTypePlain);
1878 void MainWindow::on_actionEditFindPacket_triggered()
1880 if (packet_list_->model()->rowCount() < 1) {
1883 previous_focus_ = wsApp->focusWidget();
1884 connect(previous_focus_, SIGNAL(destroyed()), this, SLOT(resetPreviousFocus()));
1885 showAccordionFrame(main_ui_->searchFrame, true);
1888 void MainWindow::on_actionEditFindNext_triggered()
1890 main_ui_->searchFrame->findNext();
1893 void MainWindow::on_actionEditFindPrevious_triggered()
1895 main_ui_->searchFrame->findPrevious();
1898 void MainWindow::on_actionEditMarkPacket_triggered()
1900 packet_list_->markFrame();
1903 void MainWindow::on_actionEditMarkAllDisplayed_triggered()
1905 packet_list_->markAllDisplayedFrames(true);
1908 void MainWindow::on_actionEditUnmarkAllDisplayed_triggered()
1910 packet_list_->markAllDisplayedFrames(false);
1913 void MainWindow::on_actionEditNextMark_triggered()
1915 if (capture_file_.capFile())
1916 cf_find_packet_marked(capture_file_.capFile(), SD_FORWARD);
1919 void MainWindow::on_actionEditPreviousMark_triggered()
1921 if (capture_file_.capFile())
1922 cf_find_packet_marked(capture_file_.capFile(), SD_BACKWARD);
1925 void MainWindow::on_actionEditIgnorePacket_triggered()
1927 packet_list_->ignoreFrame();
1930 void MainWindow::on_actionEditIgnoreAllDisplayed_triggered()
1932 packet_list_->ignoreAllDisplayedFrames(true);
1935 void MainWindow::on_actionEditUnignoreAllDisplayed_triggered()
1937 packet_list_->ignoreAllDisplayedFrames(false);
1940 void MainWindow::on_actionEditSetTimeReference_triggered()
1942 packet_list_->setTimeReference();
1945 void MainWindow::on_actionEditUnsetAllTimeReferences_triggered()
1947 packet_list_->unsetAllTimeReferences();
1950 void MainWindow::on_actionEditNextTimeReference_triggered()
1952 if (!capture_file_.capFile()) return;
1953 cf_find_packet_time_reference(capture_file_.capFile(), SD_FORWARD);
1956 void MainWindow::on_actionEditPreviousTimeReference_triggered()
1958 if (!capture_file_.capFile()) return;
1959 cf_find_packet_time_reference(capture_file_.capFile(), SD_BACKWARD);
1962 void MainWindow::on_actionEditTimeShift_triggered()
1964 TimeShiftDialog ts_dialog(this, capture_file_.capFile());
1965 connect(this, SIGNAL(setCaptureFile(capture_file*)),
1966 &ts_dialog, SLOT(setCaptureFile(capture_file*)));
1970 void MainWindow::on_actionEditPacketComment_triggered()
1972 PacketCommentDialog pc_dialog(this, packet_list_->packetComment());
1973 if (pc_dialog.exec() == QDialog::Accepted) {
1974 packet_list_->setPacketComment(pc_dialog.text());
1975 updateForUnsavedChanges();
1979 void MainWindow::on_actionEditConfigurationProfiles_triggered()
1981 ProfileDialog cp_dialog;
1986 void MainWindow::showPreferencesDialog(PreferencesDialog::PreferencesPane start_pane)
1988 PreferencesDialog pref_dialog(this);
1990 pref_dialog.setPane(start_pane);
1993 // Emitting PacketDissectionChanged directly from a QDialog can cause
1994 // problems on OS X.
1995 wsApp->flushAppSignals();
1998 void MainWindow::showPreferencesDialog(QString module_name)
2000 PreferencesDialog pref_dialog(this);
2002 pref_dialog.setPane(module_name);
2005 // Emitting PacketDissectionChanged directly from a QDialog can cause
2006 // problems on OS X.
2007 wsApp->flushAppSignals();
2010 void MainWindow::on_actionEditPreferences_triggered()
2012 showPreferencesDialog();
2017 void MainWindow::showHideMainWidgets(QAction *action)
2022 bool show = action->isChecked();
2023 QWidget *widget = action->data().value<QWidget*>();
2025 // We may have come from the toolbar context menu, so check/uncheck each
2027 if (widget == main_ui_->mainToolBar) {
2028 recent.main_toolbar_show = show;
2029 main_ui_->actionViewMainToolbar->setChecked(show);
2030 } else if (widget == main_ui_->displayFilterToolBar) {
2031 recent.filter_toolbar_show = show;
2032 main_ui_->actionViewFilterToolbar->setChecked(show);
2033 } else if (widget == main_ui_->wirelessToolBar) {
2034 recent.wireless_toolbar_show = show;
2035 main_ui_->actionViewWirelessToolbar->setChecked(show);
2036 } else if (widget == main_ui_->statusBar) {
2037 recent.statusbar_show = show;
2038 main_ui_->actionViewStatusBar->setChecked(show);
2039 } else if (widget == packet_list_) {
2040 recent.packet_list_show = show;
2041 main_ui_->actionViewPacketList->setChecked(show);
2042 } else if (widget == proto_tree_) {
2043 recent.tree_view_show = show;
2044 main_ui_->actionViewPacketDetails->setChecked(show);
2045 } else if (widget == byte_view_tab_) {
2046 recent.byte_view_show = show;
2047 main_ui_->actionViewPacketBytes->setChecked(show);
2051 widget->setVisible(show);
2055 Q_DECLARE_METATYPE(ts_type)
2057 void MainWindow::setTimestampFormat(QAction *action)
2062 ts_type tsf = action->data().value<ts_type>();
2063 if (recent.gui_time_format != tsf) {
2064 timestamp_set_type(tsf);
2065 recent.gui_time_format = tsf;
2066 if (capture_file_.capFile()) {
2067 /* This call adjusts column width */
2068 cf_timestamp_auto_precision(capture_file_.capFile());
2071 packet_list_->columnsChanged();
2076 Q_DECLARE_METATYPE(ts_precision)
2078 void MainWindow::setTimestampPrecision(QAction *action)
2083 ts_precision tsp = action->data().value<ts_precision>();
2084 if (recent.gui_time_precision != tsp) {
2085 /* the actual precision will be set in packet_list_queue_draw() below */
2086 timestamp_set_precision(tsp);
2087 recent.gui_time_precision = tsp;
2088 if (capture_file_.capFile()) {
2089 /* This call adjusts column width */
2090 cf_timestamp_auto_precision(capture_file_.capFile());
2093 packet_list_->columnsChanged();
2098 void MainWindow::on_actionViewTimeDisplaySecondsWithHoursAndMinutes_triggered(bool checked)
2101 recent.gui_seconds_format = TS_SECONDS_HOUR_MIN_SEC;
2103 recent.gui_seconds_format = TS_SECONDS_DEFAULT;
2105 timestamp_set_seconds_type(recent.gui_seconds_format);
2107 if (capture_file_.capFile()) {
2108 /* This call adjusts column width */
2109 cf_timestamp_auto_precision(capture_file_.capFile());
2112 packet_list_->columnsChanged();
2116 void MainWindow::on_actionViewEditResolvedName_triggered()
2118 // int column = packet_list_->selectedColumn();
2121 if (packet_list_->currentIndex().isValid()) {
2122 column = packet_list_->currentIndex().column();
2125 main_ui_->addressEditorFrame->editAddresses(capture_file_, column);
2126 showAccordionFrame(main_ui_->addressEditorFrame);
2129 void MainWindow::setNameResolution()
2131 gbl_resolv_flags.mac_name = main_ui_->actionViewNameResolutionPhysical->isChecked() ? TRUE : FALSE;
2132 gbl_resolv_flags.network_name = main_ui_->actionViewNameResolutionNetwork->isChecked() ? TRUE : FALSE;
2133 gbl_resolv_flags.transport_name = main_ui_->actionViewNameResolutionTransport->isChecked() ? TRUE : FALSE;
2136 packet_list_->columnsChanged();
2140 void MainWindow::on_actionViewNameResolutionPhysical_triggered()
2142 setNameResolution();
2145 void MainWindow::on_actionViewNameResolutionNetwork_triggered()
2147 setNameResolution();
2150 void MainWindow::on_actionViewNameResolutionTransport_triggered()
2152 setNameResolution();
2155 void MainWindow::zoomText()
2157 // Scale by 10%, rounding to nearest half point, minimum 1 point.
2158 // XXX Small sizes repeat. It might just be easier to create a map of multipliers.
2159 mono_font_ = QFont(wsApp->monospaceFont());
2160 qreal zoom_size = wsApp->monospaceFont().pointSize() * 2 * qPow(1.1, recent.gui_zoom_level);
2161 zoom_size = qRound(zoom_size) / 2.0;
2162 zoom_size = qMax(zoom_size, 1.0);
2163 mono_font_.setPointSizeF(zoom_size);
2164 emit monospaceFontChanged(mono_font_);
2167 void MainWindow::on_actionViewZoomIn_triggered()
2169 recent.gui_zoom_level++;
2173 void MainWindow::on_actionViewZoomOut_triggered()
2175 recent.gui_zoom_level--;
2179 void MainWindow::on_actionViewNormalSize_triggered()
2181 recent.gui_zoom_level = 0;
2185 void MainWindow::on_actionViewColorizePacketList_triggered(bool checked) {
2186 recent.packet_list_colorize = checked;
2187 color_filters_enable(checked);
2188 packet_list_->packetListModel()->resetColorized();
2189 packet_list_->update();
2192 void MainWindow::on_actionViewColoringRules_triggered()
2194 ColoringRulesDialog coloring_rules_dialog(this);
2196 coloring_rules_dialog.exec();
2199 // actionViewColorizeConversation1 - 10
2200 void MainWindow::colorizeConversation(bool create_rule)
2202 QAction *cc_action = qobject_cast<QAction *>(sender());
2203 if (!cc_action) return;
2205 if (capture_file_.capFile() && capture_file_.capFile()->current_frame) {
2206 packet_info *pi = &capture_file_.capFile()->edt->pi;
2207 guint8 cc_num = cc_action->data().toUInt();
2208 gchar *filter = NULL;
2210 const color_conversation_filter_t *color_filter = find_color_conversation_filter("tcp");
2211 if ((color_filter != NULL) && (color_filter->is_filter_valid(pi)))
2212 filter = color_filter->build_filter_string(pi);
2213 if (filter == NULL) {
2214 color_filter = find_color_conversation_filter("udp");
2215 if ((color_filter != NULL) && (color_filter->is_filter_valid(pi)))
2216 filter = color_filter->build_filter_string(pi);
2218 if (filter == NULL) {
2219 color_filter = find_color_conversation_filter("ip");
2220 if ((color_filter != NULL) && (color_filter->is_filter_valid(pi)))
2221 filter = color_filter->build_filter_string(pi);
2223 if (filter == NULL) {
2224 color_filter = find_color_conversation_filter("ipv6");
2225 if ((color_filter != NULL) && (color_filter->is_filter_valid(pi)))
2226 filter = color_filter->build_filter_string(pi);
2228 if (filter == NULL) {
2229 color_filter = find_color_conversation_filter("eth");
2230 if ((color_filter != NULL) && (color_filter->is_filter_valid(pi)))
2231 filter = color_filter->build_filter_string(pi);
2233 if( filter == NULL ) {
2234 main_ui_->statusBar->pushTemporaryStatus(tr("Unable to build conversation filter."));
2239 ColoringRulesDialog coloring_rules_dialog(this, filter);
2240 coloring_rules_dialog.exec();
2242 color_filters_set_tmp(cc_num, filter, FALSE);
2243 packet_list_->recolorPackets();
2246 setMenusForSelectedPacket();
2249 void MainWindow::colorizeWithFilter()
2251 QAction *colorize_action = qobject_cast<QAction *>(sender());
2252 if (!colorize_action) return;
2254 QString filter = colorize_action->data().toString();
2255 if (filter.isEmpty()) return;
2258 int color_number = colorize_action->property(color_number_property_).toInt(&ok);
2262 color_filters_set_tmp(color_number, filter.toUtf8().constData(), FALSE);
2263 packet_list_->recolorPackets();
2265 // New coloring rule
2266 ColoringRulesDialog coloring_rules_dialog(window(), filter);
2267 coloring_rules_dialog.exec();
2269 main_ui_->actionViewColorizeResetColorization->setEnabled(tmp_color_filters_used());
2272 void MainWindow::on_actionViewColorizeResetColorization_triggered()
2274 color_filters_reset_tmp();
2275 packet_list_->recolorPackets();
2276 setMenusForSelectedPacket();
2279 void MainWindow::on_actionViewColorizeNewConversationRule_triggered()
2281 colorizeConversation(true);
2284 void MainWindow::on_actionViewResizeColumns_triggered()
2286 for (int col = 0; col < packet_list_->packetListModel()->columnCount(); col++) {
2287 packet_list_->resizeColumnToContents(col);
2288 recent_set_column_width(col, packet_list_->columnWidth(col));
2292 void MainWindow::openPacketDialog(bool from_reference)
2296 /* Find the frame for which we're popping up a dialog */
2297 if(from_reference) {
2298 guint32 framenum = fvalue_get_uinteger(&(capture_file_.capFile()->finfo_selected->value));
2302 fdata = frame_data_sequence_find(capture_file_.capFile()->frames, framenum);
2304 fdata = capture_file_.capFile()->current_frame;
2307 /* If we have a frame, pop up the dialog */
2309 PacketDialog *packet_dialog = new PacketDialog(*this, capture_file_, fdata);
2311 connect(this, SIGNAL(monospaceFontChanged(QFont)),
2312 packet_dialog, SIGNAL(monospaceFontChanged(QFont)));
2313 connect(this, SIGNAL(closePacketDialogs()),
2314 packet_dialog, SLOT(close()));
2315 zoomText(); // Emits monospaceFontChanged
2317 packet_dialog->show();
2321 void MainWindow::on_actionViewInternalsConversationHashTables_triggered()
2323 ConversationHashTablesDialog *conversation_hash_tables_dlg = new ConversationHashTablesDialog(this);
2324 conversation_hash_tables_dlg->show();
2327 void MainWindow::on_actionViewInternalsDissectorTables_triggered()
2329 DissectorTablesDialog *dissector_tables_dlg = new DissectorTablesDialog(this);
2330 dissector_tables_dlg->show();
2333 void MainWindow::on_actionViewShowPacketInNewWindow_triggered()
2338 // This is only used in ProtoTree. Defining it here makes more sense.
2339 void MainWindow::on_actionContextShowLinkedPacketInNewWindow_triggered()
2341 openPacketDialog(true);
2344 void MainWindow::on_actionViewReload_triggered()
2346 cf_reload(CaptureFile::globalCapFile());
2349 // Expand / collapse slots in proto_tree
2355 void MainWindow::matchFieldFilter(FilterAction::Action action, FilterAction::ActionType filter_type)
2357 QString field_filter;
2359 if (packet_list_->contextMenuActive() || packet_list_->hasFocus()) {
2360 field_filter = packet_list_->getFilterFromRowAndColumn();
2361 } else if (capture_file_.capFile() && capture_file_.capFile()->finfo_selected) {
2362 char *tmp_field = proto_construct_match_selected_string(capture_file_.capFile()->finfo_selected,
2363 capture_file_.capFile()->edt);
2364 field_filter = QString(tmp_field);
2365 wmem_free(NULL, tmp_field);
2368 if (field_filter.isEmpty()) {
2369 QString err = tr("No filter available. Try another ");
2370 err.append(packet_list_->contextMenuActive() ? "column" : "item");
2372 main_ui_->statusBar->pushTemporaryStatus(err);
2376 filterAction(field_filter, action, filter_type);
2379 static FilterDialog *display_filter_dlg_ = NULL;
2380 void MainWindow::on_actionAnalyzeDisplayFilters_triggered()
2382 if (!display_filter_dlg_) {
2383 display_filter_dlg_ = new FilterDialog(this, FilterDialog::DisplayFilter);
2385 display_filter_dlg_->show();
2386 display_filter_dlg_->raise();
2387 display_filter_dlg_->activateWindow();
2391 void MainWindow::on_actionAnalyzeDisplayFilterMacros_triggered()
2393 struct epan_uat* dfm_uat;
2394 dfilter_macro_get_uat(&dfm_uat);
2395 UatDialog uat_dlg(parentWidget(), dfm_uat);
2398 // Emitting PacketDissectionChanged directly from a QDialog can cause
2399 // problems on OS X.
2400 wsApp->flushAppSignals();
2403 void MainWindow::on_actionAnalyzeCreateAColumn_triggered()
2407 if ( capture_file_.capFile() != 0 && capture_file_.capFile()->finfo_selected != 0 )
2409 colnr = column_prefs_add_custom(COL_CUSTOM, capture_file_.capFile()->finfo_selected->hfinfo->name,
2410 capture_file_.capFile()->finfo_selected->hfinfo->abbrev,0);
2412 packet_list_->columnsChanged();
2413 packet_list_->resizeColumnToContents(colnr);
2419 void MainWindow::applyConversationFilter()
2421 QAction *cfa = qobject_cast<QAction*>(sender());
2424 QString new_filter = cfa->data().toString();
2425 if (new_filter.isEmpty()) return;
2427 df_combo_box_->lineEdit()->setText(new_filter);
2428 df_combo_box_->applyDisplayFilter();
2431 // XXX We could probably create the analyze and prepare actions
2432 // dynamically using FilterActions and consolidate the methods
2433 // below into one callback.
2434 void MainWindow::on_actionAnalyzeAAFSelected_triggered()
2436 matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypePlain);
2439 void MainWindow::on_actionAnalyzeAAFNotSelected_triggered()
2441 matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypeNot);
2444 void MainWindow::on_actionAnalyzeAAFAndSelected_triggered()
2446 matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypeAnd);
2449 void MainWindow::on_actionAnalyzeAAFOrSelected_triggered()
2451 matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypeOr);
2454 void MainWindow::on_actionAnalyzeAAFAndNotSelected_triggered()
2456 matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypeAndNot);
2459 void MainWindow::on_actionAnalyzeAAFOrNotSelected_triggered()
2461 matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypeOrNot);
2464 void MainWindow::on_actionAnalyzePAFSelected_triggered()
2466 matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypePlain);
2469 void MainWindow::on_actionAnalyzePAFNotSelected_triggered()
2471 matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypeNot);
2474 void MainWindow::on_actionAnalyzePAFAndSelected_triggered()
2476 matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypeAnd);
2479 void MainWindow::on_actionAnalyzePAFOrSelected_triggered()
2481 matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypeOr);
2484 void MainWindow::on_actionAnalyzePAFAndNotSelected_triggered()
2486 matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypeAndNot);
2489 void MainWindow::on_actionAnalyzePAFOrNotSelected_triggered()
2491 matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypeOrNot);
2494 void MainWindow::on_actionAnalyzeEnabledProtocols_triggered()
2496 EnabledProtocolsDialog enable_proto_dialog(this);
2497 enable_proto_dialog.exec();
2499 // Emitting PacketDissectionChanged directly from a QDialog can cause
2500 // problems on OS X.
2501 wsApp->flushAppSignals();
2504 void MainWindow::on_actionAnalyzeDecodeAs_triggered()
2506 QAction *da_action = qobject_cast<QAction*>(sender());
2507 bool create_new = false;
2508 if (da_action && da_action->data().toBool() == true) {
2512 DecodeAsDialog da_dialog(this, capture_file_.capFile(), create_new);
2513 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2514 &da_dialog, SLOT(setCaptureFile(capture_file*)));
2517 // Emitting PacketDissectionChanged directly from a QDialog can cause
2518 // problems on OS X.
2519 wsApp->flushAppSignals();
2523 void MainWindow::on_actionAnalyzeReloadLuaPlugins_triggered()
2525 if (wsApp->isReloadingLua())
2528 wsApp->setReloadingLua(true);
2530 wslua_reload_plugins(NULL, NULL);
2531 funnel_statistics_reload_menus();
2532 reloadDynamicMenus();
2533 closePacketDialogs();
2535 // Preferences may have been deleted so close all widgets using prefs
2536 proto_tree_->closeContextMenu();
2537 main_ui_->preferenceEditorFrame->animatedHide();
2539 char *gdp_path, *dp_path;
2540 (void) wsApp->readConfigurationFiles(&gdp_path, &dp_path);
2545 wsApp->setReloadingLua(false);
2546 SimpleDialog::displayQueuedMessages();
2550 void MainWindow::openFollowStreamDialog(follow_type_t type) {
2551 FollowStreamDialog *fsd = new FollowStreamDialog(*this, capture_file_, type);
2552 connect(fsd, SIGNAL(updateFilter(QString, bool)), this, SLOT(filterPackets(QString, bool)));
2553 connect(fsd, SIGNAL(goToPacket(int)), packet_list_, SLOT(goToPacket(int)));
2556 fsd->follow(getFilter());
2559 void MainWindow::on_actionAnalyzeFollowTCPStream_triggered()
2561 openFollowStreamDialog(FOLLOW_TCP);
2564 void MainWindow::on_actionAnalyzeFollowUDPStream_triggered()
2566 openFollowStreamDialog(FOLLOW_UDP);
2569 void MainWindow::on_actionAnalyzeFollowSSLStream_triggered()
2571 openFollowStreamDialog(FOLLOW_SSL);
2574 void MainWindow::openSCTPAllAssocsDialog()
2576 SCTPAllAssocsDialog *sctp_dialog = new SCTPAllAssocsDialog(this, capture_file_.capFile());
2577 connect(sctp_dialog, SIGNAL(filterPackets(QString,bool)),
2578 this, SLOT(filterPackets(QString,bool)));
2579 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2580 sctp_dialog, SLOT(setCaptureFile(capture_file*)));
2581 sctp_dialog->fillTable();
2583 if (sctp_dialog->isMinimized() == true)
2585 sctp_dialog->showNormal();
2589 sctp_dialog->show();
2592 sctp_dialog->raise();
2593 sctp_dialog->activateWindow();
2596 void MainWindow::on_actionSCTPShowAllAssociations_triggered()
2598 openSCTPAllAssocsDialog();
2601 void MainWindow::on_actionSCTPAnalyseThisAssociation_triggered()
2603 SCTPAssocAnalyseDialog *sctp_analyse = new SCTPAssocAnalyseDialog(this, NULL, capture_file_.capFile());
2604 connect(sctp_analyse, SIGNAL(filterPackets(QString,bool)),
2605 this, SLOT(filterPackets(QString,bool)));
2607 if (sctp_analyse->isMinimized() == true)
2609 sctp_analyse->showNormal();
2613 sctp_analyse->show();
2616 sctp_analyse->raise();
2617 sctp_analyse->activateWindow();
2620 void MainWindow::on_actionSCTPFilterThisAssociation_triggered()
2622 sctp_assoc_info_t* assoc = SCTPAssocAnalyseDialog::findAssocForPacket(capture_file_.capFile());
2624 QString newFilter = QString("sctp.assoc_index==%1").arg(assoc->assoc_id);
2626 emit filterPackets(newFilter, false);
2631 void MainWindow::statCommandWlanStatistics(const char *arg, void *)
2633 WlanStatisticsDialog *wlan_stats_dlg = new WlanStatisticsDialog(*this, capture_file_, arg);
2634 connect(wlan_stats_dlg, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
2635 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
2636 wlan_stats_dlg->show();
2639 void MainWindow::on_actionWirelessWlanStatistics_triggered()
2641 statCommandWlanStatistics(NULL, NULL);
2645 void MainWindow::statCommandExpertInfo(const char *, void *)
2647 ExpertInfoDialog *expert_dialog = new ExpertInfoDialog(*this, capture_file_);
2648 const DisplayFilterEdit *df_edit = dynamic_cast<DisplayFilterEdit *>(df_combo_box_->lineEdit());
2650 expert_dialog->setDisplayFilter(df_edit->text());
2652 connect(expert_dialog, SIGNAL(goToPacket(int, int)),
2653 packet_list_, SLOT(goToPacket(int, int)));
2654 connect(expert_dialog, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
2655 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
2657 expert_dialog->show();
2660 void MainWindow::on_actionAnalyzeExpertInfo_triggered()
2662 statCommandExpertInfo(NULL, NULL);
2666 // Next / previous / first / last slots in packet_list
2670 void MainWindow::on_actionStatisticsFlowGraph_triggered()
2672 SequenceDialog *sequence_dialog = new SequenceDialog(*this, capture_file_);
2673 connect(sequence_dialog, SIGNAL(goToPacket(int)),
2674 packet_list_, SLOT(goToPacket(int)));
2675 sequence_dialog->show();
2678 void MainWindow::openTcpStreamDialog(int graph_type)
2680 TCPStreamDialog *stream_dialog = new TCPStreamDialog(this, capture_file_.capFile(), (tcp_graph_type)graph_type);
2681 connect(stream_dialog, SIGNAL(goToPacket(int)),
2682 packet_list_, SLOT(goToPacket(int)));
2683 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2684 stream_dialog, SLOT(setCaptureFile(capture_file*)));
2685 stream_dialog->show();
2688 void MainWindow::on_actionStatisticsTcpStreamStevens_triggered()
2690 openTcpStreamDialog(GRAPH_TSEQ_STEVENS);
2693 void MainWindow::on_actionStatisticsTcpStreamTcptrace_triggered()
2695 openTcpStreamDialog(GRAPH_TSEQ_TCPTRACE);
2698 void MainWindow::on_actionStatisticsTcpStreamThroughput_triggered()
2700 openTcpStreamDialog(GRAPH_THROUGHPUT);
2703 void MainWindow::on_actionStatisticsTcpStreamRoundTripTime_triggered()
2705 openTcpStreamDialog(GRAPH_RTT);
2708 void MainWindow::on_actionStatisticsTcpStreamWindowScaling_triggered()
2710 openTcpStreamDialog(GRAPH_WSCALE);
2714 void MainWindow::statCommandMulticastStatistics(const char *arg, void *)
2716 MulticastStatisticsDialog *mcast_stats_dlg = new MulticastStatisticsDialog(*this, capture_file_, arg);
2717 connect(mcast_stats_dlg, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
2718 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
2719 mcast_stats_dlg->show();
2722 void MainWindow::on_actionStatisticsUdpMulticastStreams_triggered()
2724 statCommandMulticastStatistics(NULL, NULL);
2727 void MainWindow::openStatisticsTreeDialog(const gchar *abbr)
2729 StatsTreeDialog *st_dialog = new StatsTreeDialog(*this, capture_file_, abbr);
2730 // connect(st_dialog, SIGNAL(goToPacket(int)),
2731 // packet_list_, SLOT(goToPacket(int)));
2735 void MainWindow::on_actionStatistics29WestTopics_Advertisements_by_Topic_triggered()
2737 openStatisticsTreeDialog("lbmr_topic_ads_topic");
2740 void MainWindow::on_actionStatistics29WestTopics_Advertisements_by_Source_triggered()
2742 openStatisticsTreeDialog("lbmr_topic_ads_source");
2745 void MainWindow::on_actionStatistics29WestTopics_Advertisements_by_Transport_triggered()
2747 openStatisticsTreeDialog("lbmr_topic_ads_transport");
2750 void MainWindow::on_actionStatistics29WestTopics_Queries_by_Topic_triggered()
2752 openStatisticsTreeDialog("lbmr_topic_queries_topic");
2755 void MainWindow::on_actionStatistics29WestTopics_Queries_by_Receiver_triggered()
2757 openStatisticsTreeDialog("lbmr_topic_queries_receiver");
2760 void MainWindow::on_actionStatistics29WestTopics_Wildcard_Queries_by_Pattern_triggered()
2762 openStatisticsTreeDialog("lbmr_topic_queries_pattern");
2765 void MainWindow::on_actionStatistics29WestTopics_Wildcard_Queries_by_Receiver_triggered()
2767 openStatisticsTreeDialog("lbmr_topic_queries_pattern_receiver");
2770 void MainWindow::on_actionStatistics29WestQueues_Advertisements_by_Queue_triggered()
2772 openStatisticsTreeDialog("lbmr_queue_ads_queue");
2775 void MainWindow::on_actionStatistics29WestQueues_Advertisements_by_Source_triggered()
2777 openStatisticsTreeDialog("lbmr_queue_ads_source");
2780 void MainWindow::on_actionStatistics29WestQueues_Queries_by_Queue_triggered()
2782 openStatisticsTreeDialog("lbmr_queue_queries_queue");
2785 void MainWindow::on_actionStatistics29WestQueues_Queries_by_Receiver_triggered()
2787 openStatisticsTreeDialog("lbmr_queue_queries_receiver");
2790 void MainWindow::on_actionStatistics29WestUIM_Streams_triggered()
2792 LBMStreamDialog *stream_dialog = new LBMStreamDialog(this, capture_file_.capFile());
2793 // connect(stream_dialog, SIGNAL(goToPacket(int)),
2794 // packet_list_, SLOT(goToPacket(int)));
2795 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2796 stream_dialog, SLOT(setCaptureFile(capture_file*)));
2797 stream_dialog->show();
2800 void MainWindow::on_actionStatistics29WestUIM_Stream_Flow_Graph_triggered()
2802 LBMUIMFlowDialog * uimflow_dialog = new LBMUIMFlowDialog(this, capture_file_.capFile());
2803 connect(uimflow_dialog, SIGNAL(goToPacket(int)),
2804 packet_list_, SLOT(goToPacket(int)));
2805 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2806 uimflow_dialog, SLOT(setCaptureFile(capture_file*)));
2807 uimflow_dialog->show();
2810 void MainWindow::on_actionStatistics29WestLBTRM_triggered()
2812 LBMLBTRMTransportDialog * lbtrm_dialog = new LBMLBTRMTransportDialog(this, capture_file_.capFile());
2813 connect(lbtrm_dialog, SIGNAL(goToPacket(int)),
2814 packet_list_, SLOT(goToPacket(int)));
2815 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2816 lbtrm_dialog, SLOT(setCaptureFile(capture_file*)));
2817 lbtrm_dialog->show();
2819 void MainWindow::on_actionStatistics29WestLBTRU_triggered()
2821 LBMLBTRUTransportDialog * lbtru_dialog = new LBMLBTRUTransportDialog(this, capture_file_.capFile());
2822 connect(lbtru_dialog, SIGNAL(goToPacket(int)),
2823 packet_list_, SLOT(goToPacket(int)));
2824 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2825 lbtru_dialog, SLOT(setCaptureFile(capture_file*)));
2826 lbtru_dialog->show();
2829 void MainWindow::on_actionStatisticsANCP_triggered()
2831 openStatisticsTreeDialog("ancp");
2834 void MainWindow::on_actionStatisticsBACappInstanceId_triggered()
2836 openStatisticsTreeDialog("bacapp_instanceid");
2839 void MainWindow::on_actionStatisticsBACappIP_triggered()
2841 openStatisticsTreeDialog("bacapp_ip");
2844 void MainWindow::on_actionStatisticsBACappObjectId_triggered()
2846 openStatisticsTreeDialog("bacapp_objectid");
2849 void MainWindow::on_actionStatisticsBACappService_triggered()
2851 openStatisticsTreeDialog("bacapp_service");
2854 void MainWindow::on_actionStatisticsCollectd_triggered()
2856 openStatisticsTreeDialog("collectd");
2860 void MainWindow::statCommandConversations(const char *arg, void *userdata)
2862 ConversationDialog *conv_dialog = new ConversationDialog(*this, capture_file_, GPOINTER_TO_INT(userdata), arg);
2863 connect(conv_dialog, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
2864 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
2865 connect(conv_dialog, SIGNAL(openFollowStreamDialog(follow_type_t)),
2866 this, SLOT(openFollowStreamDialog(follow_type_t)));
2867 connect(conv_dialog, SIGNAL(openTcpStreamGraph(int)),
2868 this, SLOT(openTcpStreamDialog(int)));
2869 conv_dialog->show();
2872 void MainWindow::on_actionStatisticsConversations_triggered()
2874 statCommandConversations(NULL, NULL);
2878 void MainWindow::statCommandEndpoints(const char *arg, void *userdata)
2880 EndpointDialog *endp_dialog = new EndpointDialog(*this, capture_file_, GPOINTER_TO_INT(userdata), arg);
2881 connect(endp_dialog, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
2882 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
2883 connect(endp_dialog, SIGNAL(openFollowStreamDialog(follow_type_t)),
2884 this, SLOT(openFollowStreamDialog(follow_type_t)));
2885 connect(endp_dialog, SIGNAL(openTcpStreamGraph(int)),
2886 this, SLOT(openTcpStreamDialog(int)));
2887 endp_dialog->show();
2890 void MainWindow::on_actionStatisticsEndpoints_triggered()
2892 statCommandEndpoints(NULL, NULL);
2895 void MainWindow::on_actionStatisticsHART_IP_triggered()
2897 openStatisticsTreeDialog("hart_ip");
2900 void MainWindow::on_actionStatisticsHTTPPacketCounter_triggered()
2902 openStatisticsTreeDialog("http");
2905 void MainWindow::on_actionStatisticsHTTPRequests_triggered()
2907 openStatisticsTreeDialog("http_req");
2910 void MainWindow::on_actionStatisticsHTTPLoadDistribution_triggered()
2912 openStatisticsTreeDialog("http_srv");
2915 void MainWindow::on_actionStatisticsPacketLengths_triggered()
2917 openStatisticsTreeDialog("plen");
2921 void MainWindow::statCommandIOGraph(const char *, void *)
2923 IOGraphDialog *iog_dialog = new IOGraphDialog(*this, capture_file_);
2924 connect(iog_dialog, SIGNAL(goToPacket(int)), packet_list_, SLOT(goToPacket(int)));
2925 connect(this, SIGNAL(reloadFields()), iog_dialog, SLOT(reloadFields()));
2929 void MainWindow::on_actionStatisticsIOGraph_triggered()
2931 statCommandIOGraph(NULL, NULL);
2934 void MainWindow::on_actionStatisticsSametime_triggered()
2936 openStatisticsTreeDialog("sametime");
2939 void MainWindow::on_actionStatisticsDNS_triggered()
2941 openStatisticsTreeDialog("dns");
2944 void MainWindow::actionStatisticsPlugin_triggered()
2946 QAction* action = qobject_cast<QAction*>(sender());
2948 openStatisticsTreeDialog(action->data().toString().toUtf8());
2952 void MainWindow::on_actionStatisticsHTTP2_triggered()
2954 openStatisticsTreeDialog("http2");
2960 void MainWindow::openVoipCallsDialog(bool all_flows)
2962 VoipCallsDialog *voip_calls_dialog = new VoipCallsDialog(*this, capture_file_, all_flows);
2963 connect(voip_calls_dialog, SIGNAL(goToPacket(int)),
2964 packet_list_, SLOT(goToPacket(int)));
2965 connect(voip_calls_dialog, SIGNAL(updateFilter(QString, bool)),
2966 this, SLOT(filterPackets(QString, bool)));
2967 voip_calls_dialog->show();
2970 void MainWindow::on_actionTelephonyVoipCalls_triggered()
2972 openVoipCallsDialog();
2975 void MainWindow::on_actionTelephonyGsmMapSummary_triggered()
2977 GsmMapSummaryDialog *gms_dialog = new GsmMapSummaryDialog(*this, capture_file_);
2981 void MainWindow::on_actionTelephonyIax2StreamAnalysis_triggered()
2983 Iax2AnalysisDialog *iax2_analysis_dialog = new Iax2AnalysisDialog(*this, capture_file_);
2984 connect(iax2_analysis_dialog, SIGNAL(goToPacket(int)),
2985 packet_list_, SLOT(goToPacket(int)));
2986 iax2_analysis_dialog->show();
2989 void MainWindow::on_actionTelephonyISUPMessages_triggered()
2991 openStatisticsTreeDialog("isup_msg");
2995 void MainWindow::statCommandLteMacStatistics(const char *arg, void *)
2997 LteMacStatisticsDialog *lte_mac_stats_dlg = new LteMacStatisticsDialog(*this, capture_file_, arg);
2998 connect(lte_mac_stats_dlg, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
2999 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
3000 lte_mac_stats_dlg->show();
3003 void MainWindow::on_actionTelephonyLteMacStatistics_triggered()
3005 statCommandLteMacStatistics(NULL, NULL);
3008 void MainWindow::statCommandLteRlcStatistics(const char *arg, void *)
3010 LteRlcStatisticsDialog *lte_rlc_stats_dlg = new LteRlcStatisticsDialog(*this, capture_file_, arg);
3011 connect(lte_rlc_stats_dlg, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
3012 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
3013 lte_rlc_stats_dlg->show();
3016 void MainWindow::on_actionTelephonyLteRlcStatistics_triggered()
3018 statCommandLteRlcStatistics(NULL, NULL);
3021 void MainWindow::on_actionTelephonyMtp3Summary_triggered()
3023 Mtp3SummaryDialog *mtp3s_dialog = new Mtp3SummaryDialog(*this, capture_file_);
3024 mtp3s_dialog->show();
3027 void MainWindow::on_actionTelephonyRTPStreams_triggered()
3029 RtpStreamDialog *rtp_stream_dialog = new RtpStreamDialog(*this, capture_file_);
3030 connect(rtp_stream_dialog, SIGNAL(packetsMarked()),
3031 packet_list_, SLOT(redrawVisiblePackets()));
3032 connect(rtp_stream_dialog, SIGNAL(goToPacket(int)),
3033 packet_list_, SLOT(goToPacket(int)));
3034 connect(rtp_stream_dialog, SIGNAL(updateFilter(QString, bool)),
3035 this, SLOT(filterPackets(QString, bool)));
3036 rtp_stream_dialog->show();
3039 void MainWindow::on_actionTelephonyRTPStreamAnalysis_triggered()
3041 RtpAnalysisDialog *rtp_analysis_dialog = new RtpAnalysisDialog(*this, capture_file_);
3042 connect(rtp_analysis_dialog, SIGNAL(goToPacket(int)),
3043 packet_list_, SLOT(goToPacket(int)));
3044 rtp_analysis_dialog->show();
3047 void MainWindow::on_actionTelephonyRTSPPacketCounter_triggered()
3049 openStatisticsTreeDialog("rtsp");
3052 void MainWindow::on_actionTelephonySMPPOperations_triggered()
3054 openStatisticsTreeDialog("smpp_commands");
3057 void MainWindow::on_actionTelephonyUCPMessages_triggered()
3059 openStatisticsTreeDialog("ucp_messages");
3062 void MainWindow::on_actionTelephonySipFlows_triggered()
3064 openVoipCallsDialog(true);
3069 void MainWindow::on_actionATT_Server_Attributes_triggered()
3071 BluetoothAttServerAttributesDialog *bluetooth_att_sever_attributes_dialog = new BluetoothAttServerAttributesDialog(*this, capture_file_);
3072 connect(bluetooth_att_sever_attributes_dialog, SIGNAL(goToPacket(int)),
3073 packet_list_, SLOT(goToPacket(int)));
3074 connect(bluetooth_att_sever_attributes_dialog, SIGNAL(updateFilter(QString, bool)),
3075 this, SLOT(filterPackets(QString, bool)));
3076 bluetooth_att_sever_attributes_dialog->show();
3079 void MainWindow::on_actionDevices_triggered()
3081 BluetoothDevicesDialog *bluetooth_devices_dialog = new BluetoothDevicesDialog(*this, capture_file_);
3082 connect(bluetooth_devices_dialog, SIGNAL(goToPacket(int)),
3083 packet_list_, SLOT(goToPacket(int)));
3084 connect(bluetooth_devices_dialog, SIGNAL(updateFilter(QString, bool)),
3085 this, SLOT(filterPackets(QString, bool)));
3086 bluetooth_devices_dialog->show();
3089 void MainWindow::on_actionHCI_Summary_triggered()
3091 BluetoothHciSummaryDialog *bluetooth_hci_summary_dialog = new BluetoothHciSummaryDialog(*this, capture_file_);
3092 connect(bluetooth_hci_summary_dialog, SIGNAL(goToPacket(int)),
3093 packet_list_, SLOT(goToPacket(int)));
3094 connect(bluetooth_hci_summary_dialog, SIGNAL(updateFilter(QString, bool)),
3095 this, SLOT(filterPackets(QString, bool)));
3096 bluetooth_hci_summary_dialog->show();
3100 void MainWindow::on_actionHelpContents_triggered() {
3102 wsApp->helpTopicAction(HELP_CONTENT);
3105 void MainWindow::on_actionHelpMPWireshark_triggered() {
3107 wsApp->helpTopicAction(LOCALPAGE_MAN_WIRESHARK);
3110 void MainWindow::on_actionHelpMPWireshark_Filter_triggered() {
3111 wsApp->helpTopicAction(LOCALPAGE_MAN_WIRESHARK_FILTER);
3114 void MainWindow::on_actionHelpMPCapinfos_triggered() {
3115 wsApp->helpTopicAction(LOCALPAGE_MAN_CAPINFOS);
3118 void MainWindow::on_actionHelpMPDumpcap_triggered() {
3119 wsApp->helpTopicAction(LOCALPAGE_MAN_DUMPCAP);
3122 void MainWindow::on_actionHelpMPEditcap_triggered() {
3123 wsApp->helpTopicAction(LOCALPAGE_MAN_EDITCAP);
3126 void MainWindow::on_actionHelpMPMergecap_triggered() {
3127 wsApp->helpTopicAction(LOCALPAGE_MAN_MERGECAP);
3130 void MainWindow::on_actionHelpMPRawShark_triggered() {
3131 wsApp->helpTopicAction(LOCALPAGE_MAN_RAWSHARK);
3134 void MainWindow::on_actionHelpMPReordercap_triggered() {
3135 wsApp->helpTopicAction(LOCALPAGE_MAN_REORDERCAP);
3138 void MainWindow::on_actionHelpMPText2cap_triggered() {
3139 wsApp->helpTopicAction(LOCALPAGE_MAN_TEXT2PCAP);
3142 void MainWindow::on_actionHelpMPTShark_triggered() {
3143 wsApp->helpTopicAction(LOCALPAGE_MAN_TSHARK);
3146 void MainWindow::on_actionHelpWebsite_triggered() {
3148 wsApp->helpTopicAction(ONLINEPAGE_HOME);
3151 void MainWindow::on_actionHelpFAQ_triggered() {
3153 wsApp->helpTopicAction(ONLINEPAGE_FAQ);
3156 void MainWindow::on_actionHelpAsk_triggered() {
3158 wsApp->helpTopicAction(ONLINEPAGE_ASK);
3161 void MainWindow::on_actionHelpDownloads_triggered() {
3163 wsApp->helpTopicAction(ONLINEPAGE_DOWNLOAD);
3166 void MainWindow::on_actionHelpWiki_triggered() {
3168 wsApp->helpTopicAction(ONLINEPAGE_WIKI);
3171 void MainWindow::on_actionHelpSampleCaptures_triggered() {
3173 wsApp->helpTopicAction(ONLINEPAGE_SAMPLE_FILES);
3176 #ifdef HAVE_SOFTWARE_UPDATE
3177 void MainWindow::checkForUpdates()
3179 software_update_check();
3183 void MainWindow::on_actionHelpAbout_triggered()
3185 AboutDialog *about_dialog = new AboutDialog(this);
3187 if (about_dialog->isMinimized() == true)
3189 about_dialog->showNormal();
3193 about_dialog->show();
3196 about_dialog->raise();
3197 about_dialog->activateWindow();
3200 void MainWindow::on_actionGoGoToPacket_triggered() {
3201 if (packet_list_->model()->rowCount() < 1) {
3204 previous_focus_ = wsApp->focusWidget();
3205 connect(previous_focus_, SIGNAL(destroyed()), this, SLOT(resetPreviousFocus()));
3207 showAccordionFrame(main_ui_->goToFrame, true);
3208 if (main_ui_->goToFrame->isVisible()) {
3209 main_ui_->goToLineEdit->clear();
3210 main_ui_->goToLineEdit->setFocus();
3214 void MainWindow::on_actionGoGoToLinkedPacket_triggered()
3216 QAction *gta = qobject_cast<QAction*>(sender());
3220 int packet_num = gta->data().toInt(&ok);
3223 packet_list_->goToPacket(packet_num);
3226 void MainWindow::on_actionGoAutoScroll_toggled(bool checked)
3228 packet_list_->setAutoScroll(checked);
3231 void MainWindow::resetPreviousFocus() {
3232 previous_focus_ = NULL;
3235 void MainWindow::on_goToCancel_clicked()
3237 main_ui_->goToFrame->animatedHide();
3238 if (previous_focus_) {
3239 disconnect(previous_focus_, SIGNAL(destroyed()), this, SLOT(resetPreviousFocus()));
3240 previous_focus_->setFocus();
3241 resetPreviousFocus();
3245 void MainWindow::on_goToGo_clicked()
3247 gotoFrame(main_ui_->goToLineEdit->text().toInt());
3249 on_goToCancel_clicked();
3252 void MainWindow::on_goToLineEdit_returnPressed()
3254 on_goToGo_clicked();
3257 void MainWindow::on_actionCaptureStart_triggered()
3259 //#ifdef HAVE_AIRPCAP
3260 // airpcap_if_active = airpcap_if_selected;
3261 // if (airpcap_if_active)
3262 // airpcap_set_toolbar_start_capture(airpcap_if_active);
3265 // if (cap_open_w) {
3267 // * There's an options dialog; get the values from it and close it.
3269 // gboolean success;
3271 // /* Determine if "capture start" while building of the "capture options" window */
3272 // /* is in progress. If so, ignore the "capture start. */
3273 // /* XXX: Would it be better/cleaner for the "capture options" window code to */
3274 // /* disable the capture start button temporarily ? */
3275 // if (cap_open_complete == FALSE) {
3276 // return; /* Building options window: ignore "capture start" */
3278 // success = capture_dlg_prep(cap_open_w);
3279 // window_destroy(GTK_WIDGET(cap_open_w));
3281 // return; /* error in options dialog */
3285 if (global_capture_opts.num_selected == 0) {
3286 QString err_msg = tr("No Interface Selected");
3287 main_ui_->statusBar->pushTemporaryStatus(err_msg);
3288 main_ui_->actionCaptureStart->setChecked(false);
3292 /* XXX - will closing this remove a temporary file? */
3293 QString before_what(tr(" before starting a new capture"));
3294 if (testCaptureFileClose(FALSE, before_what)) {
3297 // simply clicking the button sets it to 'checked' even though we've
3298 // decided to do nothing, so undo that
3299 main_ui_->actionCaptureStart->setChecked(false);
3301 #endif // HAVE_LIBPCAP
3304 void MainWindow::on_actionCaptureStop_triggered()
3309 void MainWindow::on_actionCaptureRestart_triggered()
3311 /* TODO: GTK use only this: capture_restart(&cap_session_); */
3316 static FilterDialog *capture_filter_dlg_ = NULL;
3317 void MainWindow::on_actionCaptureCaptureFilters_triggered()
3319 if (!capture_filter_dlg_) {
3320 capture_filter_dlg_ = new FilterDialog(this, FilterDialog::CaptureFilter);
3322 capture_filter_dlg_->show();
3323 capture_filter_dlg_->raise();
3324 capture_filter_dlg_->activateWindow();
3327 void MainWindow::on_actionStatisticsCaptureFileProperties_triggered()
3329 CaptureFilePropertiesDialog *capture_file_properties_dialog = new CaptureFilePropertiesDialog(*this, capture_file_);
3330 connect(capture_file_properties_dialog, SIGNAL(captureCommentChanged()),
3331 this, SLOT(updateForUnsavedChanges()));
3332 capture_file_properties_dialog->show();
3335 void MainWindow::on_actionStatisticsResolvedAddresses_triggered()
3337 ResolvedAddressesDialog *resolved_addresses_dialog = new ResolvedAddressesDialog(this, &capture_file_);
3338 resolved_addresses_dialog->show();
3341 void MainWindow::on_actionStatisticsProtocolHierarchy_triggered()
3343 ProtocolHierarchyDialog *phd = new ProtocolHierarchyDialog(*this, capture_file_);
3344 connect(phd, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
3345 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
3350 void MainWindow::on_actionCaptureOptions_triggered()
3352 connect(&capture_interfaces_dialog_, SIGNAL(setFilterValid(bool)), this, SLOT(startInterfaceCapture(bool)));
3353 capture_interfaces_dialog_.SetTab(0);
3354 capture_interfaces_dialog_.updateInterfaces();
3356 if (capture_interfaces_dialog_.isMinimized() == true)
3358 capture_interfaces_dialog_.showNormal();
3362 capture_interfaces_dialog_.show();
3365 capture_interfaces_dialog_.raise();
3366 capture_interfaces_dialog_.activateWindow();
3369 void MainWindow::on_actionCaptureRefreshInterfaces_triggered()
3371 wsApp->refreshLocalInterfaces();
3375 void MainWindow::externalMenuItem_triggered()
3377 QAction * triggerAction = NULL;
3379 ext_menubar_t * entry = NULL;
3381 if ( QObject::sender() != NULL)
3383 triggerAction = (QAction *)QObject::sender();
3384 v = triggerAction->data();
3386 if ( v.canConvert<void *>())
3388 entry = (ext_menubar_t *)v.value<void *>();
3390 if ( entry->type == EXT_MENUBAR_ITEM )
3392 entry->callback(EXT_MENUBAR_QT_GUI, (gpointer) ((void *)main_ui_), entry->user_data);
3396 QDesktopServices::openUrl(QUrl(QString((gchar *)entry->user_data)));
3402 void MainWindow::gotoFrame(int packet_num)
3404 if ( packet_num > 0 )
3406 packet_list_->goToPacket(packet_num);
3411 void MainWindow::extcap_options_finished(int result)
3413 if ( result == QDialog::Accepted )
3417 this->main_welcome_->getInterfaceTree()->interfaceListChanged();
3420 void MainWindow::showExtcapOptionsDialog(QString &device_name)
3422 ExtcapOptionsDialog * extcap_options_dialog = ExtcapOptionsDialog::createForDevice(device_name, this);
3423 /* The dialog returns null, if the given device name is not a valid extcap device */
3424 if ( extcap_options_dialog != NULL )
3426 connect(extcap_options_dialog, SIGNAL(finished(int)),
3427 this, SLOT(extcap_options_finished(int)));
3428 extcap_options_dialog->show();
3433 // Q_DECLARE_METATYPE(field_info *) called in proto_tree.h
3435 void MainWindow::on_actionContextCopyBytesHexTextDump_triggered()
3437 QAction *ca = qobject_cast<QAction*>(sender());
3440 field_info *fi = ca->data().value<field_info *>();
3442 byte_view_tab_->copyData(ByteViewTab::copyDataHexTextDump, fi);
3445 void MainWindow::on_actionContextCopyBytesHexDump_triggered()
3447 QAction *ca = qobject_cast<QAction*>(sender());
3450 field_info *fi = ca->data().value<field_info *>();
3452 byte_view_tab_->copyData(ByteViewTab::copyDataHexDump, fi);
3455 void MainWindow::on_actionContextCopyBytesPrintableText_triggered()
3457 QAction *ca = qobject_cast<QAction*>(sender());
3460 field_info *fi = ca->data().value<field_info *>();
3462 byte_view_tab_->copyData(ByteViewTab::copyDataPrintableText, fi);
3465 void MainWindow::on_actionContextCopyBytesHexStream_triggered()
3467 QAction *ca = qobject_cast<QAction*>(sender());
3470 field_info *fi = ca->data().value<field_info *>();
3472 byte_view_tab_->copyData(ByteViewTab::copyDataHexStream, fi);
3475 void MainWindow::on_actionContextCopyBytesBinary_triggered()
3477 QAction *ca = qobject_cast<QAction*>(sender());
3480 field_info *fi = ca->data().value<field_info *>();
3482 byte_view_tab_->copyData(ByteViewTab::copyDataBinary, fi);
3485 void MainWindow::on_actionContextWikiProtocolPage_triggered()
3487 QAction *wa = qobject_cast<QAction*>(sender());
3491 int field_id = wa->data().toInt(&ok);
3494 const QString proto_abbrev = proto_registrar_get_abbrev(field_id);
3496 int ret = QMessageBox::question(this, wsApp->windowTitleString(tr("Wiki Page for %1").arg(proto_abbrev)),
3497 tr("<p>The Wireshark Wiki is maintained by the community.</p>"
3498 "<p>The page you are about to load might be wonderful, "
3499 "incomplete, wrong, or nonexistent.</p>"
3500 "<p>Proceed to the wiki?</p>"),
3501 QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
3503 if (ret != QMessageBox::Yes) return;
3505 QUrl wiki_url = QString("https://wiki.wireshark.org/Protocols/%1").arg(proto_abbrev);
3506 QDesktopServices::openUrl(wiki_url);
3509 void MainWindow::on_actionContextFilterFieldReference_triggered()
3511 QAction *wa = qobject_cast<QAction*>(sender());
3515 int field_id = wa->data().toInt(&ok);
3518 const QString proto_abbrev = proto_registrar_get_abbrev(field_id);
3520 QUrl dfref_url = QString("https://www.wireshark.org/docs/dfref/%1/%2")
3521 .arg(proto_abbrev[0])
3523 QDesktopServices::openUrl(dfref_url);
3532 * indent-tabs-mode: nil
3535 * ex: set shiftwidth=4 tabstop=8 expandtab:
3536 * :indentSize=4:tabSize=8:noTabs=true: