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 "enabled_protocols_dialog.h"
93 #include "decode_as_dialog.h"
94 #include "display_filter_edit.h"
95 #include "display_filter_expression_dialog.h"
96 #include "endpoint_dialog.h"
97 #include "expert_info_dialog.h"
98 #include "export_object_dialog.h"
99 #include "export_pdu_dialog.h"
101 #include "extcap_options_dialog.h"
103 #include "filter_action.h"
104 #include "filter_dialog.h"
105 #include "funnel_statistics.h"
106 #include "gsm_map_summary_dialog.h"
107 #include "iax2_analysis_dialog.h"
108 #include "io_graph_dialog.h"
109 #include "lbm_stream_dialog.h"
110 #include "lbm_uimflow_dialog.h"
111 #include "lbm_lbtrm_transport_dialog.h"
112 #include "lbm_lbtru_transport_dialog.h"
113 #include "mtp3_summary_dialog.h"
114 #include "multicast_statistics_dialog.h"
115 #include "packet_comment_dialog.h"
116 #include "packet_dialog.h"
117 #include "packet_list.h"
118 #include "preferences_dialog.h"
119 #include "print_dialog.h"
120 #include "profile_dialog.h"
121 #include "protocol_hierarchy_dialog.h"
122 #include "qt_ui_utils.h"
123 #include "resolved_addresses_dialog.h"
124 #include "rpc_service_response_time_dialog.h"
125 #include "rtp_stream_dialog.h"
126 #include "rtp_analysis_dialog.h"
127 #include "sctp_all_assocs_dialog.h"
128 #include "sctp_assoc_analyse_dialog.h"
129 #include "sctp_graph_dialog.h"
130 #include "sequence_dialog.h"
131 #include "stats_tree_dialog.h"
132 #include "stock_icon.h"
133 #include "tap_parameter_dialog.h"
134 #include "tcp_stream_dialog.h"
135 #include "time_shift_dialog.h"
136 #include "uat_dialog.h"
137 #include "voip_calls_dialog.h"
138 #include "wireshark_application.h"
139 #include "wlan_statistics_dialog.h"
141 #include <QClipboard>
143 #include <QMessageBox>
144 #include <QMetaObject>
146 #include <QDesktopServices>
154 static const char *dfe_property_ = "display filter expression"; //TODO : Fix Translate
156 // We're too lazy to sublcass QAction.
157 static const char *color_number_property_ = "color number";
159 bool MainWindow::openCaptureFile(QString cf_path, QString read_filter, unsigned int type)
161 QString file_name = "";
162 dfilter_t *rfcode = NULL;
167 // was a file name given as function parameter?
168 name_param = !cf_path.isEmpty();
172 if (cf_path.isEmpty()) {
173 CaptureFileDialog open_dlg(this, capture_file_.capFile(), read_filter);
175 switch (prefs.gui_fileopen_style) {
177 case FO_STYLE_LAST_OPENED:
178 /* The user has specified that we should start out in the last directory
179 we looked in. If we've already opened a file, use its containing
180 directory, if we could determine it, as the directory, otherwise
181 use the "last opened" directory saved in the preferences file if
183 /* This is now the default behaviour in file_selection_new() */
186 case FO_STYLE_SPECIFIED:
187 /* The user has specified that we should always start out in a
188 specified directory; if they've specified that directory,
189 start out by showing the files in that dir. */
190 if (prefs.gui_fileopen_dir[0] != '\0')
191 open_dlg.setDirectory(prefs.gui_fileopen_dir);
195 if (open_dlg.open(file_name, type)) {
202 if (!testCaptureFileClose(false)) {
206 if (dfilter_compile(read_filter.toUtf8().constData(), &rfcode, &err_msg)) {
207 cf_set_rfcode(CaptureFile::globalCapFile(), rfcode);
209 /* Not valid. Tell the user, and go back and run the file
210 selection box again once they dismiss the alert. */
211 //bad_dfilter_alert_box(top_level, read_filter->str);
212 QMessageBox::warning(this, tr("Invalid Display Filter"),
213 QString("The filter expression ") +
215 QString(" isn't a valid display filter. (") +
216 err_msg + QString(")."),
220 // go back to the selection dialogue only if the file
221 // was selected from this dialogue
227 /* Try to open the capture file. This closes the current file if it succeeds. */
228 CaptureFile::globalCapFile()->window = this;
229 if (cf_open(CaptureFile::globalCapFile(), cf_path.toUtf8().constData(), type, FALSE, &err) != CF_OK) {
230 /* We couldn't open it; don't dismiss the open dialog box,
231 just leave it around so that the user can, after they
232 dismiss the alert box popped up for the open error,
234 CaptureFile::globalCapFile()->window = NULL;
236 dfilter_free(rfcode);
241 switch (cf_read(CaptureFile::globalCapFile(), FALSE)) {
245 /* Just because we got an error, that doesn't mean we were unable
246 to read any of the file; we handle what we could get from the
250 case CF_READ_ABORTED:
251 /* The user bailed out of re-reading the capture file; the
252 capture file has been closed - just free the capture file name
253 string and return (without changing the last containing
255 capture_file_.setCapFile(NULL);
260 // get_dirname overwrites its path. Hopefully this isn't a problem.
261 wsApp->setLastOpenDir(get_dirname(cf_path.toUtf8().data()));
263 main_ui_->statusBar->showExpert();
268 void MainWindow::filterPackets(QString new_filter, bool force)
270 cf_status_t cf_status;
272 cf_status = cf_filter_packets(CaptureFile::globalCapFile(), new_filter.toUtf8().data(), force);
274 if (cf_status == CF_OK) {
275 emit displayFilterSuccess(true);
276 if (new_filter.length() > 0) {
277 int index = df_combo_box_->findText(new_filter);
279 df_combo_box_->insertItem(0, new_filter);
280 df_combo_box_->setCurrentIndex(0);
282 df_combo_box_->setCurrentIndex(index);
285 df_combo_box_->lineEdit()->clear();
288 emit displayFilterSuccess(false);
292 // A new layout should be applied when it differs from the old layout AND
293 // at the following times:
295 // - When the preferences change
296 // - When the profile changes
297 void MainWindow::layoutPanes()
299 QVector<unsigned> new_layout = QVector<unsigned>() << prefs.gui_layout_type
300 << prefs.gui_layout_content_1
301 << prefs.gui_layout_content_2
302 << prefs.gui_layout_content_3;
303 if (cur_layout_ == new_layout) return;
305 QSplitter *parents[3];
306 int current_row = capture_file_.currentRow();
308 // Reparent all widgets and add them back in the proper order below.
309 // This hides each widget as well.
310 packet_list_->freeze(); // Clears tree and byte view tabs.
311 packet_list_->setParent(main_ui_->mainStack);
312 proto_tree_->setParent(main_ui_->mainStack);
313 byte_view_tab_->setParent(main_ui_->mainStack);
314 empty_pane_.setParent(main_ui_->mainStack);
315 extra_split_.setParent(main_ui_->mainStack);
317 // XXX We should try to preserve geometries if we can, e.g. by
318 // checking to see if the layout type is the same.
319 switch(prefs.gui_layout_type) {
322 extra_split_.setOrientation(Qt::Horizontal);
325 master_split_.setOrientation(Qt::Vertical);
330 extra_split_.setOrientation(Qt::Vertical);
333 master_split_.setOrientation(Qt::Horizontal);
337 g_assert_not_reached();
340 switch(prefs.gui_layout_type) {
343 parents[0] = &master_split_;
344 parents[1] = &master_split_;
345 parents[2] = &master_split_;
349 parents[0] = &master_split_;
350 parents[1] = &extra_split_;
351 parents[2] = &extra_split_;
355 parents[0] = &extra_split_;
356 parents[1] = &extra_split_;
357 parents[2] = &master_split_;
360 g_assert_not_reached();
363 if (parents[0] == &extra_split_) {
364 master_split_.addWidget(&extra_split_);
367 parents[0]->addWidget(getLayoutWidget(prefs.gui_layout_content_1));
369 if (parents[2] == &extra_split_) {
370 master_split_.addWidget(&extra_split_);
373 parents[1]->addWidget(getLayoutWidget(prefs.gui_layout_content_2));
374 parents[2]->addWidget(getLayoutWidget(prefs.gui_layout_content_3));
376 const QList<QWidget *> ms_children = master_split_.findChildren<QWidget *>();
378 extra_split_.setVisible(ms_children.contains(&extra_split_));
379 packet_list_->setVisible(ms_children.contains(packet_list_) && recent.packet_list_show);
380 proto_tree_->setVisible(ms_children.contains(proto_tree_) && recent.tree_view_show);
381 byte_view_tab_->setVisible(ms_children.contains(byte_view_tab_) && recent.byte_view_show);
383 packet_list_->thaw();
384 cf_select_packet(capture_file_.capFile(), current_row); // XXX Doesn't work for row 0?
385 cur_layout_ = new_layout;
388 // The recent layout geometry should be applied after the layout has been
389 // applied AND at the following times:
391 // - When the profile changes
392 void MainWindow::applyRecentPaneGeometry()
394 // XXX This shrinks slightly each time the application is run. For some
395 // reason the master_split_ geometry is two pixels shorter when
396 // saveWindowGeometry is invoked.
398 // This is also an awful lot of trouble to go through to reuse the GTK+
399 // pane settings. We might want to add gui.geometry_main_master_sizes
400 // and gui.geometry_main_extra_sizes and save QSplitter::saveState in
403 // Force a geometry recalculation
404 QWidget *cur_w = main_ui_->mainStack->currentWidget();
405 main_ui_->mainStack->setCurrentWidget(&master_split_);
406 QRect geom = master_split_.geometry();
407 QList<int> master_sizes = master_split_.sizes();
408 QList<int> extra_sizes = extra_split_.sizes();
409 main_ui_->mainStack->setCurrentWidget(cur_w);
411 int master_last_size = master_split_.orientation() == Qt::Vertical ? geom.height() : geom.width();
412 int extra_last_size = extra_split_.orientation() == Qt::Vertical ? geom.height() : geom.width();
414 if (recent.gui_geometry_main_upper_pane > 0) {
415 master_sizes[0] = recent.gui_geometry_main_upper_pane + 1; // Add back mystery pixel
416 master_last_size -= recent.gui_geometry_main_upper_pane + master_split_.handleWidth();
419 if (recent.gui_geometry_main_lower_pane > 0) {
420 if (master_sizes.length() > 2) {
421 master_sizes[1] = recent.gui_geometry_main_lower_pane + 1; // Add back mystery pixel
422 master_last_size -= recent.gui_geometry_main_lower_pane + master_split_.handleWidth();
423 } else if (extra_sizes.length() > 0) {
424 extra_sizes[0] = recent.gui_geometry_main_lower_pane; // No mystery pixel
425 extra_last_size -= recent.gui_geometry_main_lower_pane + extra_split_.handleWidth();
426 extra_sizes.last() = extra_last_size;
430 master_sizes.last() = master_last_size;
432 master_split_.setSizes(master_sizes);
433 extra_split_.setSizes(extra_sizes);
436 void MainWindow::layoutToolbars()
438 Qt::ToolButtonStyle tbstyle = Qt::ToolButtonIconOnly;
439 switch (prefs.gui_toolbar_main_style) {
441 tbstyle = Qt::ToolButtonTextOnly;
444 tbstyle = Qt::ToolButtonTextUnderIcon;
448 main_ui_->mainToolBar->setToolButtonStyle(tbstyle);
451 void MainWindow::updatePreferenceActions()
453 main_ui_->actionViewNameResolutionPhysical->setChecked(gbl_resolv_flags.mac_name);
454 main_ui_->actionViewNameResolutionNetwork->setChecked(gbl_resolv_flags.network_name);
455 main_ui_->actionViewNameResolutionTransport->setChecked(gbl_resolv_flags.transport_name);
457 // Should this be a "recent" setting?
458 main_ui_->actionGoAutoScroll->setChecked(prefs.capture_auto_scroll);
461 void MainWindow::filterAction(QString &action_filter, FilterAction::Action action, FilterAction::ActionType type)
463 QString cur_filter, new_filter;
465 if (!df_combo_box_) return;
466 cur_filter = df_combo_box_->lineEdit()->text();
469 case FilterAction::ActionTypePlain:
470 new_filter = action_filter;
472 case FilterAction::ActionTypeAnd:
473 if (cur_filter.length()) {
474 new_filter = "(" + cur_filter + ") && (" + action_filter + ")";
476 new_filter = action_filter;
479 case FilterAction::ActionTypeOr:
480 if (cur_filter.length()) {
481 new_filter = "(" + cur_filter + ") || (" + action_filter + ")";
483 new_filter = action_filter;
486 case FilterAction::ActionTypeNot:
487 new_filter = "!(" + action_filter + ")";
489 case FilterAction::ActionTypeAndNot:
490 if (cur_filter.length()) {
491 new_filter = "(" + cur_filter + ") && !(" + action_filter + ")";
493 new_filter = "!(" + action_filter + ")";
496 case FilterAction::ActionTypeOrNot:
497 if (cur_filter.length()) {
498 new_filter = "(" + cur_filter + ") || !(" + action_filter + ")";
500 new_filter = "!(" + action_filter + ")";
504 g_assert_not_reached();
509 case FilterAction::ActionApply:
510 df_combo_box_->lineEdit()->setText(new_filter);
511 df_combo_box_->applyDisplayFilter();
513 case FilterAction::ActionPrepare:
514 df_combo_box_->lineEdit()->setText(new_filter);
515 df_combo_box_->lineEdit()->setFocus();
517 case FilterAction::ActionWebLookup:
519 QString url = QString("https://www.google.com/search?q=") + new_filter;
520 QDesktopServices::openUrl(QUrl(url));
523 case FilterAction::ActionCopy:
524 wsApp->clipboard()->setText(new_filter);
527 qDebug() << "FIX FilterAction::Action" << action << "not implemented";
534 void MainWindow::captureCapturePrepared(capture_session *) {
536 setTitlebarForCaptureInProgress();
538 setWindowIcon(wsApp->captureIcon());
540 /* Disable menu items that make no sense if you're currently running
542 setForCaptureInProgress(true);
543 // set_capture_if_dialog_for_capture_in_progress(TRUE);
545 // /* Don't set up main window for a capture file. */
546 // main_set_for_capture_file(FALSE);
547 main_ui_->mainStack->setCurrentWidget(&master_split_);
548 #endif // HAVE_LIBPCAP
551 void MainWindow::captureCaptureUpdateStarted(capture_session *) {
554 /* We've done this in "prepared" above, but it will be cleared while
555 switching to the next multiple file. */
556 setTitlebarForCaptureInProgress();
558 setForCaptureInProgress(true);
560 setForCapturedPackets(true);
561 #endif // HAVE_LIBPCAP
563 void MainWindow::captureCaptureUpdateFinished(capture_session *) {
566 /* The capture isn't stopping any more - it's stopped. */
567 capture_stopping_ = false;
569 /* Update the main window as appropriate */
570 updateForUnsavedChanges();
572 /* Enable menu items that make sense if you're not currently running
574 setForCaptureInProgress(false);
576 setWindowIcon(wsApp->normalIcon());
578 if (global_capture_opts.quit_after_cap) {
579 // Command line asked us to quit after capturing.
580 // Don't pop up a dialog to ask for unsaved files etc.
583 #endif // HAVE_LIBPCAP
585 void MainWindow::captureCaptureFixedStarted(capture_session *) {
587 #endif // HAVE_LIBPCAP
589 void MainWindow::captureCaptureFixedFinished(capture_session *) {
592 /* The capture isn't stopping any more - it's stopped. */
593 capture_stopping_ = false;
595 /* Enable menu items that make sense if you're not currently running
597 setForCaptureInProgress(false);
599 setWindowIcon(wsApp->normalIcon());
601 if (global_capture_opts.quit_after_cap) {
602 // Command line asked us to quit after capturing.
603 // Don't pop up a dialog to ask for unsaved files etc.
606 #endif // HAVE_LIBPCAP
608 void MainWindow::captureCaptureStopping(capture_session *) {
611 capture_stopping_ = true;
612 setMenusForCaptureStopping();
613 #endif // HAVE_LIBPCAP
615 void MainWindow::captureCaptureFailed(capture_session *) {
617 /* Capture isn't stopping any more. */
618 capture_stopping_ = false;
620 setForCaptureInProgress(false);
621 main_ui_->mainStack->setCurrentWidget(main_welcome_);
623 setWindowIcon(wsApp->normalIcon());
625 if (global_capture_opts.quit_after_cap) {
626 // Command line asked us to quit after capturing.
627 // Don't pop up a dialog to ask for unsaved files etc.
630 #endif // HAVE_LIBPCAP
634 // Callbacks from cfile.c and file.c via CaptureFile::captureFileCallback
636 void MainWindow::captureFileOpened() {
637 if (capture_file_.window() != this) return;
639 file_set_dialog_.fileOpened(capture_file_.capFile());
640 setMenusForFileSet(true);
641 emit setCaptureFile(capture_file_.capFile());
644 void MainWindow::captureFileReadStarted(const QString &action) {
645 // tap_param_dlg_update();
647 /* Set up main window for a capture file. */
648 // main_set_for_capture_file(TRUE);
650 main_ui_->statusBar->popFileStatus();
651 QString msg = QString(tr("%1: %2")).arg(action).arg(capture_file_.fileName());
652 QString msgtip = QString();
653 main_ui_->statusBar->pushFileStatus(msg, msgtip);
654 main_ui_->mainStack->setCurrentWidget(&master_split_);
655 WiresharkApplication::processEvents();
658 void MainWindow::captureFileReadFinished() {
661 if (!capture_file_.capFile()->is_tempfile && capture_file_.capFile()->filename) {
662 /* Add this filename to the list of recent files in the "Recent Files" submenu */
663 add_menu_recent_capture_file(capture_file_.capFile()->filename);
665 /* Remember folder for next Open dialog and save it in recent */
666 dir_path = get_dirname(g_strdup(capture_file_.capFile()->filename));
667 wsApp->setLastOpenDir(dir_path);
671 /* Update the appropriate parts of the main window. */
672 updateForUnsavedChanges();
674 /* Enable menu items that make sense if you have some captured packets. */
675 setForCapturedPackets(true);
677 main_ui_->statusBar->setFileName(capture_file_);
679 packet_list_->captureFileReadFinished();
681 emit setDissectedCaptureFile(capture_file_.capFile());
684 // Our event loop becomes nested whenever we call update_progress_dlg, which
685 // includes several places in file.c. The GTK+ UI stays out of trouble by
686 // showing a modal progress dialog. We attempt to do the equivalent below by
687 // disabling parts of the main window. At a minumum the ProgressFrame in the
688 // main status bar must remain accessible.
690 // We might want to do this any time the main status bar progress frame is
692 void MainWindow::captureFileRetapStarted()
694 // XXX Push a status message?
695 main_ui_->actionFileClose->setEnabled(false);
696 main_ui_->actionViewReload->setEnabled(false);
697 main_ui_->centralWidget->setEnabled(false);
700 void MainWindow::captureFileRetapFinished()
702 main_ui_->actionFileClose->setEnabled(true);
703 main_ui_->actionViewReload->setEnabled(true);
704 main_ui_->centralWidget->setEnabled(true);
707 void MainWindow::captureFileClosing() {
708 setMenusForCaptureFile(true);
709 setForCapturedPackets(false);
710 setMenusForSelectedPacket();
711 setForCaptureInProgress(false);
713 // Reset expert information indicator
714 main_ui_->statusBar->captureFileClosing();
715 main_ui_->searchFrame->animatedHide();
716 // gtk_widget_show(expert_info_none);
717 emit setCaptureFile(NULL);
718 emit setDissectedCaptureFile(NULL);
721 void MainWindow::captureFileClosed() {
722 packets_bar_update();
724 file_set_dialog_.fileClosed();
725 setMenusForFileSet(false);
727 // Reset expert information indicator
728 main_ui_->statusBar->captureFileClosing();
730 main_ui_->statusBar->popFileStatus();
732 setTitlebarForSelectedTreeRow();
733 setMenusForSelectedTreeRow();
735 if (!global_capture_opts.multi_files_on)
736 main_ui_->mainStack->setCurrentWidget(main_welcome_);
739 void MainWindow::captureFileSaveStarted(const QString &file_path)
741 QFileInfo file_info(file_path);
742 main_ui_->statusBar->popFileStatus();
743 main_ui_->statusBar->pushFileStatus(tr("Saving %1" UTF8_HORIZONTAL_ELLIPSIS).arg(file_info.baseName()));
746 void MainWindow::filterExpressionsChanged()
748 // Recreate filter buttons
749 foreach (QAction *act, main_ui_->displayFilterToolBar->actions()) {
750 // Permanent actions shouldn't have data
751 if (act->property(dfe_property_).isValid() || act->isSeparator()) {
752 main_ui_->displayFilterToolBar->removeAction(act);
758 for (struct filter_expression *fe = *pfilter_expression_head; fe != NULL; fe = fe->next) {
759 if (!fe->enabled) continue;
760 QAction *dfb_action = new QAction(fe->label, main_ui_->displayFilterToolBar);
761 dfb_action->setToolTip(fe->expression);
762 dfb_action->setData(fe->expression);
763 dfb_action->setProperty(dfe_property_, true);
764 main_ui_->displayFilterToolBar->addAction(dfb_action);
765 connect(dfb_action, SIGNAL(triggered()), this, SLOT(displayFilterButtonClicked()));
768 main_ui_->displayFilterToolBar->insertSeparator(dfb_action);
777 // ui/gtk/capture_dlg.c:start_capture_confirmed
779 void MainWindow::startCapture() {
781 interface_options interface_opts;
784 /* did the user ever select a capture interface before? */
785 if(global_capture_opts.num_selected == 0) {
786 QString msg = QString(tr("No interface selected"));
787 main_ui_->statusBar->pushTemporaryStatus(msg);
788 main_ui_->actionCaptureStart->setChecked(false);
792 main_ui_->mainStack->setCurrentWidget(&master_split_);
794 // Ideally we should have disabled the start capture
795 // toolbar buttons and menu items. This may not be the
796 // case, e.g. with QtMacExtras.
797 if(!capture_filter_valid_) {
798 QString msg = QString(tr("Invalid capture filter"));
799 main_ui_->statusBar->pushTemporaryStatus(msg);
800 main_ui_->actionCaptureStart->setChecked(false);
804 /* XXX - we might need to init other pref data as well... */
806 /* XXX - can this ever happen? */
807 if (cap_session_.state != CAPTURE_STOPPED)
810 /* close the currently loaded capture file */
811 cf_close((capture_file *) cap_session_.cf);
813 /* Copy the selected interfaces to the set of interfaces to use for
815 collect_ifaces(&global_capture_opts);
817 CaptureFile::globalCapFile()->window = this;
818 if (capture_start(&global_capture_opts, &cap_session_, main_window_update)) {
819 capture_options *capture_opts = cap_session_.capture_opts;
820 GString *interface_names;
822 /* enable autoscroll timer as needed. */
823 packet_list_->setAutoScroll(main_ui_->actionGoAutoScroll->isChecked());
825 /* Add "interface name<live capture in progress>" on main status bar */
826 interface_names = get_iface_list_string(capture_opts, 0);
827 if (strlen (interface_names->str) > 0) {
828 g_string_append(interface_names, ":");
830 g_string_append(interface_names, " ");
832 main_ui_->statusBar->popFileStatus();
833 QString msg = QString().sprintf("%s<live capture in progress>", interface_names->str);
834 QString msgtip = QString().sprintf("to file: %s", (capture_opts->save_file) ? capture_opts->save_file : "");
835 main_ui_->statusBar->pushFileStatus(msg, msgtip);
836 g_string_free(interface_names, TRUE);
838 /* The capture succeeded, which means the capture filter syntax is
839 valid; add this capture filter to the recent capture filter list. */
840 for (i = 0; i < global_capture_opts.ifaces->len; i++) {
841 interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
842 if (interface_opts.cfilter) {
843 // cfilter_combo_add_recent(interface_opts.cfilter);
847 CaptureFile::globalCapFile()->window = NULL;
849 #endif // HAVE_LIBPCAP
852 // Copied from ui/gtk/gui_utils.c
853 void MainWindow::pipeTimeout() {
857 gboolean result, result1;
862 /* try to read data from the pipe only 5 times, to avoid blocking */
863 while(iterations < 5) {
864 /*g_log(NULL, G_LOG_LEVEL_DEBUG, "pipe_timer_cb: new iteration");*/
866 /* Oddly enough although Named pipes don't work on win9x,
867 PeekNamedPipe does !!! */
868 handle = (HANDLE) _get_osfhandle (pipe_source_);
869 result = PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL);
871 /* Get the child process exit status */
872 result1 = GetExitCodeProcess((HANDLE)*(pipe_child_process_),
875 /* If the Peek returned an error, or there are bytes to be read
876 or the childwatcher thread has terminated then call the normal
878 if (!result || avail > 0 || childstatus != STILL_ACTIVE) {
880 /*g_log(NULL, G_LOG_LEVEL_DEBUG, "pipe_timer_cb: data avail");*/
882 /* And call the real handler */
883 if (!pipe_input_cb_(pipe_source_, pipe_user_data_)) {
884 g_log(NULL, G_LOG_LEVEL_DEBUG, "pipe_timer_cb: input pipe closed, iterations: %u", iterations);
885 /* pipe closed, return false so that the old timer is not run again */
891 /*g_log(NULL, G_LOG_LEVEL_DEBUG, "pipe_timer_cb: no data avail");*/
892 /* No data, stop now */
901 void MainWindow::pipeActivated(int source) {
905 g_assert(source == pipe_source_);
907 pipe_notifier_->setEnabled(false);
908 if (pipe_input_cb_(pipe_source_, pipe_user_data_)) {
909 pipe_notifier_->setEnabled(true);
911 delete pipe_notifier_;
916 void MainWindow::pipeNotifierDestroyed() {
920 pipe_notifier_ = NULL;
924 void MainWindow::stopCapture() {
925 //#ifdef HAVE_AIRPCAP
926 // if (airpcap_if_active)
927 // airpcap_set_toolbar_stop_capture(airpcap_if_active);
931 capture_stop(&cap_session_);
932 #endif // HAVE_LIBPCAP
934 /* Pop the "<live capture in progress>" message off the status bar. */
935 main_ui_->statusBar->setFileName(capture_file_);
937 /* disable autoscroll timer if any. */
938 packet_list_->setAutoScroll(false);
941 // Keep focus rects from showing through the welcome screen. Primarily for
943 void MainWindow::mainStackChanged(int)
945 for (int i = 0; i < main_ui_->mainStack->count(); i++) {
946 main_ui_->mainStack->widget(i)->setEnabled(i == main_ui_->mainStack->currentIndex());
950 // XXX - Copied from ui/gtk/menus.c
953 * Add the capture filename (with an absolute path) to the "Recent Files" menu.
955 // XXX - We should probably create a RecentFile class.
956 void MainWindow::updateRecentFiles() {
958 QMenu *recentMenu = main_ui_->menuOpenRecentCaptureFile;
959 QString action_cf_name;
967 /* Iterate through the actions in menuOpenRecentCaptureFile,
968 * removing special items, a maybe duplicate entry and every item above count_max */
969 int shortcut = Qt::Key_0;
970 foreach (recent_item_status *ri, wsApp->recentItems()) {
972 ra = new QAction(recentMenu);
973 ra->setData(ri->filename);
974 // XXX - Needs get_recent_item_status or equivalent
975 ra->setEnabled(ri->accessible);
976 recentMenu->insertAction(NULL, ra);
977 action_cf_name = ra->data().toString();
978 if (shortcut <= Qt::Key_9) {
979 ra->setShortcut(Qt::META | shortcut);
982 ra->setText(action_cf_name);
983 connect(ra, SIGNAL(triggered()), this, SLOT(recentActionTriggered()));
986 if (recentMenu->actions().count() > 0) {
987 // Separator + "Clear"
988 // XXX - Do we really need this?
989 ra = new QAction(recentMenu);
990 ra->setSeparator(true);
991 recentMenu->insertAction(NULL, ra);
993 ra = new QAction(recentMenu);
994 ra->setText(tr("Clear Menu"));
995 recentMenu->insertAction(NULL, ra);
996 connect(ra, SIGNAL(triggered()), wsApp, SLOT(clearRecentItems()));
998 if (main_ui_->actionDummyNoFilesFound) {
999 recentMenu->addAction(main_ui_->actionDummyNoFilesFound);
1004 void MainWindow::recentActionTriggered() {
1005 QAction *ra = qobject_cast<QAction*>(sender());
1008 QString cfPath = ra->data().toString();
1009 openCaptureFile(cfPath);
1013 void MainWindow::setMenusForSelectedPacket()
1015 gboolean is_ip = FALSE, is_tcp = FALSE, is_udp = FALSE, is_sctp = FALSE, is_ssl = FALSE, is_rtp = FALSE;
1017 /* Making the menu context-sensitive allows for easier selection of the
1018 desired item and has the added benefit, with large captures, of
1019 avoiding needless looping through huge lists for marked, ignored,
1020 or time-referenced packets. */
1022 /* We have one or more items in the packet list */
1023 bool have_frames = false;
1024 /* A frame is selected */
1025 bool frame_selected = false;
1026 /* We have marked frames. (XXX - why check frame_selected?) */
1027 bool have_marked = false;
1028 /* We have a marked frame other than the current frame (i.e.,
1029 we have at least one marked frame, and either there's more
1030 than one marked frame or the current frame isn't marked). */
1031 bool another_is_marked = false;
1032 /* One or more frames are hidden by a display filter */
1033 bool have_filtered = false;
1034 /* One or more frames have been ignored */
1035 bool have_ignored = false;
1036 bool have_time_ref = false;
1037 /* We have a time reference frame other than the current frame (i.e.,
1038 we have at least one time reference frame, and either there's more
1039 than one time reference frame or the current frame isn't a
1040 time reference frame). (XXX - why check frame_selected?) */
1041 bool another_is_time_ref = false;
1042 /* We have a valid filter expression */
1043 bool have_filter_expr = false;
1045 QList<QAction *> cc_actions = QList<QAction *>()
1046 << main_ui_->actionViewColorizeConversation1 << main_ui_->actionViewColorizeConversation2
1047 << main_ui_->actionViewColorizeConversation3 << main_ui_->actionViewColorizeConversation4
1048 << main_ui_->actionViewColorizeConversation5 << main_ui_->actionViewColorizeConversation6
1049 << main_ui_->actionViewColorizeConversation7 << main_ui_->actionViewColorizeConversation8
1050 << main_ui_->actionViewColorizeConversation9 << main_ui_->actionViewColorizeConversation10;
1052 if (capture_file_.capFile()) {
1053 frame_selected = capture_file_.capFile()->current_frame != NULL;
1054 have_frames = capture_file_.capFile()->count > 0;
1055 have_marked = frame_selected && capture_file_.capFile()->marked_count > 0;
1056 another_is_marked = have_marked &&
1057 !(capture_file_.capFile()->marked_count == 1 && capture_file_.capFile()->current_frame->flags.marked);
1058 have_filtered = capture_file_.capFile()->displayed_count > 0 && capture_file_.capFile()->displayed_count != capture_file_.capFile()->count;
1059 have_ignored = capture_file_.capFile()->ignored_count > 0;
1060 have_time_ref = capture_file_.capFile()->ref_time_count > 0;
1061 another_is_time_ref = frame_selected && have_time_ref &&
1062 !(capture_file_.capFile()->ref_time_count == 1 && capture_file_.capFile()->current_frame->flags.ref_time);
1064 if (capture_file_.capFile()->edt)
1066 proto_get_frame_protocols(capture_file_.capFile()->edt->pi.layers, &is_ip, &is_tcp, &is_udp, &is_sctp, &is_ssl, &is_rtp);
1070 have_filter_expr = !packet_list_->getFilterFromRowAndColumn().isEmpty();
1072 main_ui_->actionEditMarkPacket->setEnabled(frame_selected);
1073 main_ui_->actionEditMarkAllDisplayed->setEnabled(have_frames);
1074 /* Unlike un-ignore, do not allow unmark of all frames when no frames are displayed */
1075 main_ui_->actionEditUnmarkAllDisplayed->setEnabled(have_marked);
1076 main_ui_->actionEditNextMark->setEnabled(another_is_marked);
1077 main_ui_->actionEditPreviousMark->setEnabled(another_is_marked);
1079 #ifdef WANT_PACKET_EDITOR
1080 // set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/EditMenu/EditPacket",
1082 #endif // WANT_PACKET_EDITOR
1083 main_ui_->actionEditPacketComment->setEnabled(frame_selected && wtap_dump_can_write(capture_file_.capFile()->linktypes, WTAP_COMMENT_PER_PACKET));
1085 main_ui_->actionEditIgnorePacket->setEnabled(frame_selected);
1086 main_ui_->actionEditIgnoreAllDisplayed->setEnabled(have_filtered);
1087 /* Allow un-ignore of all frames even with no frames currently displayed */
1088 main_ui_->actionEditUnignoreAllDisplayed->setEnabled(have_ignored);
1090 main_ui_->actionEditSetTimeReference->setEnabled(frame_selected);
1091 main_ui_->actionEditUnsetAllTimeReferences->setEnabled(have_time_ref);
1092 main_ui_->actionEditNextTimeReference->setEnabled(another_is_time_ref);
1093 main_ui_->actionEditPreviousTimeReference->setEnabled(another_is_time_ref);
1094 main_ui_->actionEditTimeShift->setEnabled(have_frames);
1096 main_ui_->actionGoGoToLinkedPacket->setEnabled(false);
1098 main_ui_->actionAnalyzeAAFSelected->setEnabled(have_filter_expr);
1099 main_ui_->actionAnalyzeAAFNotSelected->setEnabled(have_filter_expr);
1100 main_ui_->actionAnalyzeAAFAndSelected->setEnabled(have_filter_expr);
1101 main_ui_->actionAnalyzeAAFOrSelected->setEnabled(have_filter_expr);
1102 main_ui_->actionAnalyzeAAFAndNotSelected->setEnabled(have_filter_expr);
1103 main_ui_->actionAnalyzeAAFOrNotSelected->setEnabled(have_filter_expr);
1105 main_ui_->actionAnalyzePAFSelected->setEnabled(have_filter_expr);
1106 main_ui_->actionAnalyzePAFNotSelected->setEnabled(have_filter_expr);
1107 main_ui_->actionAnalyzePAFAndSelected->setEnabled(have_filter_expr);
1108 main_ui_->actionAnalyzePAFOrSelected->setEnabled(have_filter_expr);
1109 main_ui_->actionAnalyzePAFAndNotSelected->setEnabled(have_filter_expr);
1110 main_ui_->actionAnalyzePAFOrNotSelected->setEnabled(have_filter_expr);
1112 main_ui_->actionAnalyzeFollowTCPStream->setEnabled(is_tcp);
1113 main_ui_->actionAnalyzeFollowUDPStream->setEnabled(is_udp);
1114 main_ui_->actionAnalyzeFollowSSLStream->setEnabled(is_ssl);
1116 foreach (QAction *cc_action, cc_actions) {
1117 cc_action->setEnabled(frame_selected);
1119 main_ui_->actionViewColorizeNewConversationRule->setEnabled(frame_selected);
1121 main_ui_->actionViewColorizeResetColorization->setEnabled(tmp_color_filters_used());
1123 main_ui_->actionViewColorizeNewConversationRule->setEnabled(frame_selected);
1125 main_ui_->actionViewShowPacketInNewWindow->setEnabled(frame_selected);
1126 main_ui_->actionViewEditResolvedName->setEnabled(frame_selected && is_ip);
1128 main_ui_->menuConversationFilter->clear();
1130 packet_list_->conversationMenu()->clear();
1131 packet_list_->colorizeMenu()->clear();
1133 for (GList *color_list_entry = color_conv_filter_list; color_list_entry; color_list_entry = g_list_next(color_list_entry)) {
1135 color_conversation_filter_t* color_filter = (color_conversation_filter_t *)color_list_entry->data;
1136 QAction *conv_action = main_ui_->menuConversationFilter->addAction(color_filter->display_name);
1138 bool enable = false;
1140 if (capture_file_.capFile()->edt) {
1141 enable = color_filter->is_filter_valid(&capture_file_.capFile()->edt->pi);
1142 filter = gchar_free_to_qstring(color_filter->build_filter_string(&capture_file_.capFile()->edt->pi));
1144 conv_action->setEnabled(enable);
1145 conv_action->setData(filter);
1146 connect(conv_action, SIGNAL(triggered()), this, SLOT(applyConversationFilter()));
1148 // Packet list context menu items
1149 packet_list_->conversationMenu()->addAction(conv_action);
1151 QMenu *submenu = packet_list_->colorizeMenu()->addMenu(conv_action->text());
1153 foreach (QAction *cc_action, cc_actions) {
1154 QAction *colorize_action = submenu->addAction(cc_action->icon(), cc_action->text());
1155 colorize_action->setProperty(color_number_property_, i++);
1156 colorize_action->setData(filter);
1157 colorize_action->setEnabled(enable);
1158 connect(colorize_action, SIGNAL(triggered()), this, SLOT(colorizeWithFilter()));
1161 QAction *conv_rule_action = submenu->addAction(main_ui_->actionViewColorizeNewConversationRule->text());
1162 conv_rule_action->setData(conv_action->data());
1163 conv_rule_action->setEnabled(enable);
1164 connect(conv_rule_action, SIGNAL(triggered()), this, SLOT(colorizeWithFilter()));
1167 // set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/ViewMenu/NameResolution/ResolveName",
1168 // frame_selected && (gbl_resolv_flags.mac_name || gbl_resolv_flags.network_name ||
1169 // gbl_resolv_flags.transport_name || gbl_resolv_flags.concurrent_dns));
1170 // set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/ToolsMenu/FirewallACLRules",
1172 main_ui_->menuTcpStreamGraphs->setEnabled(is_tcp);
1173 main_ui_->actionSCTPAnalyseThisAssociation->setEnabled(is_sctp);
1174 main_ui_->actionSCTPShowAllAssociations->setEnabled(is_sctp);
1175 main_ui_->actionSCTPFilterThisAssociation->setEnabled(is_sctp);
1176 main_ui_->actionTelephonyRTPStreamAnalysis->setEnabled(is_rtp);
1179 void MainWindow::setMenusForSelectedTreeRow(field_info *fi) {
1180 // XXX Add commented items below
1182 // The ProtoTree either doesn't exist yet or emitted protoItemSelected as
1183 // a result of a packet list selection. Don't assume control of the menu.
1184 if (!proto_tree_ || !proto_tree_->hasFocus()) return;
1186 bool can_match_selected = false;
1187 bool is_framenum = false;
1188 bool have_field_info = false;
1189 bool have_subtree = false;
1190 bool can_open_url = false;
1191 QString field_filter;
1194 QList<QAction *> cc_actions = QList<QAction *>()
1195 << main_ui_->actionViewColorizeConversation1 << main_ui_->actionViewColorizeConversation2
1196 << main_ui_->actionViewColorizeConversation3 << main_ui_->actionViewColorizeConversation4
1197 << main_ui_->actionViewColorizeConversation5 << main_ui_->actionViewColorizeConversation6
1198 << main_ui_->actionViewColorizeConversation7 << main_ui_->actionViewColorizeConversation8
1199 << main_ui_->actionViewColorizeConversation9 << main_ui_->actionViewColorizeConversation10;
1201 if (capture_file_.capFile()) {
1202 capture_file_.capFile()->finfo_selected = fi;
1204 if (fi && fi->tree_type != -1) {
1205 have_subtree = true;
1209 if (capture_file_.capFile() != NULL && fi != NULL) {
1210 header_field_info *hfinfo = fi->hfinfo;
1211 int linked_frame = -1;
1213 have_field_info = true;
1214 can_match_selected = proto_can_match_selected(capture_file_.capFile()->finfo_selected, capture_file_.capFile()->edt);
1215 if (hfinfo && hfinfo->type == FT_FRAMENUM) {
1217 linked_frame = fvalue_get_uinteger(&fi->value);
1220 char *tmp_field = proto_construct_match_selected_string(fi, capture_file_.capFile()->edt);
1221 field_filter = QString(tmp_field);
1222 wmem_free(NULL, tmp_field);
1224 field_id = fi->hfinfo->id;
1225 /* if the selected field isn't a protocol, get its parent */
1226 if (!proto_registrar_is_protocol(field_id)) {
1227 field_id = proto_registrar_get_parent(fi->hfinfo->id);
1230 if (field_id >= 0 && !proto_is_private(field_id)) {
1231 can_open_url = true;
1232 main_ui_->actionContextWikiProtocolPage->setData(field_id);
1233 main_ui_->actionContextFilterFieldReference->setData(field_id);
1235 main_ui_->actionContextWikiProtocolPage->setData(QVariant());
1236 main_ui_->actionContextFilterFieldReference->setData(QVariant());
1239 if (linked_frame > 0) {
1240 main_ui_->actionGoGoToLinkedPacket->setData(linked_frame);
1242 main_ui_->actionGoGoToLinkedPacket->setData(QVariant());
1246 main_ui_->menuConversationFilter->clear();
1247 for (GList *color_list_entry = color_conv_filter_list; color_list_entry; color_list_entry = g_list_next(color_list_entry)) {
1248 color_conversation_filter_t* color_filter = (color_conversation_filter_t *)color_list_entry->data;
1249 QAction *conv_action = main_ui_->menuConversationFilter->addAction(color_filter->display_name);
1251 bool conv_enable = false;
1252 QString conv_filter;
1253 if (capture_file_.capFile() && capture_file_.capFile()->edt) {
1254 conv_enable = color_filter->is_filter_valid(&capture_file_.capFile()->edt->pi);
1255 conv_filter = color_filter->build_filter_string(&capture_file_.capFile()->edt->pi);
1257 conv_action->setEnabled(conv_enable);
1258 conv_action->setData(conv_filter);
1259 connect(conv_action, SIGNAL(triggered()), this, SLOT(applyConversationFilter()));
1262 proto_tree_->colorizeMenu()->clear();
1264 foreach (QAction *cc_action, cc_actions) {
1265 QAction *colorize_action = proto_tree_->colorizeMenu()->addAction(cc_action->icon(), cc_action->text());
1266 colorize_action->setProperty(color_number_property_, i++);
1267 colorize_action->setData(field_filter);
1268 colorize_action->setEnabled(!field_filter.isEmpty());
1269 connect(colorize_action, SIGNAL(triggered()), this, SLOT(colorizeWithFilter()));
1272 QAction *conv_rule_action = proto_tree_->colorizeMenu()->addAction(main_ui_->actionViewColorizeNewConversationRule->text());
1273 conv_rule_action->setData(field_filter);
1274 conv_rule_action->setEnabled(!field_filter.isEmpty());
1275 connect(conv_rule_action, SIGNAL(triggered()), this, SLOT(colorizeWithFilter()));
1277 // set_menu_sensitivity(ui_manager_tree_view_menu, "/TreeViewPopup/ResolveName",
1278 // frame_selected && (gbl_resolv_flags.mac_name || gbl_resolv_flags.network_name ||
1279 // gbl_resolv_flags.transport_name || gbl_resolv_flags.concurrent_dns));
1281 main_ui_->actionFileExportPacketBytes->setEnabled(have_field_info);
1282 main_ui_->actionContextShowLinkedPacketInNewWindow->setEnabled(is_framenum);
1284 main_ui_->actionCopyAllVisibleItems->setEnabled(capture_file_.capFile() != NULL);
1285 main_ui_->actionCopyAllVisibleSelectedTreeItems->setEnabled(can_match_selected);
1287 main_ui_->actionEditCopyDescription->setEnabled(can_match_selected);
1288 main_ui_->actionEditCopyFieldName->setEnabled(can_match_selected);
1289 main_ui_->actionEditCopyValue->setEnabled(can_match_selected);
1290 main_ui_->actionEditCopyAsFilter->setEnabled(can_match_selected);
1292 main_ui_->actionGoGoToLinkedPacket->setEnabled(is_framenum);
1294 main_ui_->actionAnalyzeCreateAColumn->setEnabled(can_match_selected);
1296 main_ui_->actionAnalyzeAAFSelected->setEnabled(can_match_selected);
1297 main_ui_->actionAnalyzeAAFNotSelected->setEnabled(can_match_selected);
1298 main_ui_->actionAnalyzeAAFAndSelected->setEnabled(can_match_selected);
1299 main_ui_->actionAnalyzeAAFOrSelected->setEnabled(can_match_selected);
1300 main_ui_->actionAnalyzeAAFAndNotSelected->setEnabled(can_match_selected);
1301 main_ui_->actionAnalyzeAAFOrNotSelected->setEnabled(can_match_selected);
1303 main_ui_->actionAnalyzePAFSelected->setEnabled(can_match_selected);
1304 main_ui_->actionAnalyzePAFNotSelected->setEnabled(can_match_selected);
1305 main_ui_->actionAnalyzePAFAndSelected->setEnabled(can_match_selected);
1306 main_ui_->actionAnalyzePAFOrSelected->setEnabled(can_match_selected);
1307 main_ui_->actionAnalyzePAFAndNotSelected->setEnabled(can_match_selected);
1308 main_ui_->actionAnalyzePAFOrNotSelected->setEnabled(can_match_selected);
1310 main_ui_->actionViewExpandSubtrees->setEnabled(have_subtree);
1312 main_ui_->actionContextWikiProtocolPage->setEnabled(can_open_url);
1313 main_ui_->actionContextFilterFieldReference->setEnabled(can_open_url);
1316 void MainWindow::interfaceSelectionChanged()
1319 // XXX This doesn't disable the toolbar button when using
1321 if (global_capture_opts.num_selected > 0 && capture_filter_valid_) {
1322 main_ui_->actionCaptureStart->setEnabled(true);
1324 main_ui_->actionCaptureStart->setEnabled(false);
1326 #endif // HAVE_LIBPCAP
1329 void MainWindow::captureFilterSyntaxChanged(bool valid)
1331 capture_filter_valid_ = valid;
1332 interfaceSelectionChanged();
1335 void MainWindow::startInterfaceCapture(bool valid)
1337 capture_filter_valid_ = valid;
1341 void MainWindow::redissectPackets()
1343 if (capture_file_.capFile())
1344 cf_redissect_packets(capture_file_.capFile());
1345 main_ui_->statusBar->expertUpdate();
1347 proto_free_deregistered_fields();
1350 void MainWindow::fieldsChanged()
1352 color_filters_reload();
1353 tap_listeners_dfilter_recompile();
1355 if (!df_combo_box_->checkDisplayFilter()) {
1356 g_free(CaptureFile::globalCapFile()->dfilter);
1357 CaptureFile::globalCapFile()->dfilter = NULL;
1360 if (have_custom_cols(&CaptureFile::globalCapFile()->cinfo)) {
1361 // Recreate packet list columns according to new/changed/deleted fields
1362 packet_list_->fieldsChanged(CaptureFile::globalCapFile());
1365 emit reloadFields();
1368 void MainWindow::showAccordionFrame(AccordionFrame *show_frame, bool toggle)
1370 QList<AccordionFrame *>frame_list = QList<AccordionFrame *>()
1371 << main_ui_->goToFrame << main_ui_->searchFrame
1372 << main_ui_->addressEditorFrame << main_ui_->columnEditorFrame
1373 << main_ui_->preferenceEditorFrame;
1375 frame_list.removeAll(show_frame);
1376 foreach (AccordionFrame *af, frame_list) af->animatedHide();
1379 if (show_frame->isVisible()) {
1380 show_frame->animatedHide();
1384 show_frame->animatedShow();
1387 void MainWindow::showColumnEditor(int column)
1389 previous_focus_ = wsApp->focusWidget();
1390 connect(previous_focus_, SIGNAL(destroyed()), this, SLOT(resetPreviousFocus()));
1391 showAccordionFrame(main_ui_->columnEditorFrame);
1392 main_ui_->columnEditorFrame->editColumn(column);
1395 void MainWindow::showPreferenceEditor()
1397 showAccordionFrame(main_ui_->preferenceEditorFrame);
1400 void MainWindow::initViewColorizeMenu()
1402 QList<QAction *> cc_actions = QList<QAction *>()
1403 << main_ui_->actionViewColorizeConversation1 << main_ui_->actionViewColorizeConversation2
1404 << main_ui_->actionViewColorizeConversation3 << main_ui_->actionViewColorizeConversation4
1405 << main_ui_->actionViewColorizeConversation5 << main_ui_->actionViewColorizeConversation6
1406 << main_ui_->actionViewColorizeConversation7 << main_ui_->actionViewColorizeConversation8
1407 << main_ui_->actionViewColorizeConversation9 << main_ui_->actionViewColorizeConversation10;
1409 guint8 color_num = 1;
1411 foreach (QAction *cc_action, cc_actions) {
1412 cc_action->setData(color_num);
1413 connect(cc_action, SIGNAL(triggered()), this, SLOT(colorizeConversation()));
1415 const color_filter_t *colorf = color_filters_tmp_color(color_num);
1417 QColor bg = ColorUtils::fromColorT(colorf->bg_color);
1418 QColor fg = ColorUtils::fromColorT(colorf->fg_color);
1419 cc_action->setIcon(StockIcon::colorIcon(bg.rgb(), fg.rgb(), QString::number(color_num)));
1425 // Spotlight uses Cmd+Space
1426 main_ui_->actionViewColorizeResetColorization->setShortcut(QKeySequence("Meta+Space"));
1430 void MainWindow::addStatsPluginsToMenu() {
1431 GList *cfg_list = stats_tree_get_cfg_list();
1432 GList *iter = g_list_first(cfg_list);
1433 QAction *stats_tree_action;
1435 bool first_item = true;
1438 stats_tree_cfg *cfg = (stats_tree_cfg*)iter->data;
1441 main_ui_->menuStatistics->addSeparator();
1445 parent_menu = main_ui_->menuStatistics;
1446 // gtk/main_menubar.c compresses double slashes, hence SkipEmptyParts
1447 QStringList cfg_name_parts = QString(cfg->name).split("/", QString::SkipEmptyParts);
1448 if (cfg_name_parts.isEmpty()) continue;
1450 QString stat_name = cfg_name_parts.takeLast();
1451 if (!cfg_name_parts.isEmpty()) {
1452 QString menu_name = cfg_name_parts.join("/");
1453 parent_menu = findOrAddMenu(parent_menu, menu_name);
1456 stats_tree_action = new QAction(stat_name, this);
1457 stats_tree_action->setData(cfg->abbr);
1458 parent_menu->addAction(stats_tree_action);
1459 connect(stats_tree_action, SIGNAL(triggered()), this, SLOT(actionStatisticsPlugin_triggered()));
1461 iter = g_list_next(iter);
1463 g_list_free(cfg_list);
1466 void MainWindow::setFeaturesEnabled(bool enabled)
1468 main_ui_->menuBar->setEnabled(enabled);
1469 main_ui_->mainToolBar->setEnabled(enabled);
1470 main_ui_->displayFilterToolBar->setEnabled(enabled);
1473 main_ui_->statusBar->clearMessage();
1477 main_ui_->statusBar->showMessage(tr("Please wait while Wireshark is initializing" UTF8_HORIZONTAL_ELLIPSIS));
1481 // Display Filter Toolbar
1483 void MainWindow::on_actionDisplayFilterExpression_triggered()
1485 DisplayFilterExpressionDialog *dfe_dialog = new DisplayFilterExpressionDialog(this);
1487 connect(dfe_dialog, SIGNAL(insertDisplayFilter(QString)),
1488 df_combo_box_->lineEdit(), SLOT(insertFilter(const QString &)));
1493 // On Qt4 + OS X with unifiedTitleAndToolBarOnMac set it's possible to make
1494 // the main window obnoxiously wide.
1496 void MainWindow::displayFilterButtonClicked()
1498 QAction *dfb_action = qobject_cast<QAction*>(sender());
1501 df_combo_box_->lineEdit()->setText(dfb_action->data().toString());
1502 df_combo_box_->applyDisplayFilter();
1503 df_combo_box_->lineEdit()->setFocus();
1507 void MainWindow::openStatCommandDialog(const QString &menu_path, const char *arg, void *userdata)
1509 QString slot = QString("statCommand%1").arg(menu_path);
1510 QMetaObject::invokeMethod(this, slot.toLatin1().constData(), Q_ARG(const char *, arg), Q_ARG(void *, userdata));
1513 void MainWindow::openTapParameterDialog(const QString cfg_str, const QString arg, void *userdata)
1515 TapParameterDialog *tp_dialog = TapParameterDialog::showTapParameterStatistics(*this, capture_file_, cfg_str, arg, userdata);
1516 if (!tp_dialog) return;
1518 connect(tp_dialog, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
1519 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
1520 connect(tp_dialog, SIGNAL(updateFilter(QString)),
1521 df_combo_box_->lineEdit(), SLOT(setText(QString)));
1525 void MainWindow::openTapParameterDialog()
1527 QAction *tpa = qobject_cast<QAction *>(QObject::sender());
1530 const QString cfg_str = tpa->data().toString();
1531 openTapParameterDialog(cfg_str, NULL, NULL);
1536 void MainWindow::on_actionFileOpen_triggered()
1541 void MainWindow::on_actionFileMerge_triggered()
1546 void MainWindow::on_actionFileImportFromHexDump_triggered()
1548 importCaptureFile();
1551 void MainWindow::on_actionFileClose_triggered() {
1552 if (testCaptureFileClose())
1553 main_ui_->mainStack->setCurrentWidget(main_welcome_);
1556 void MainWindow::on_actionFileSave_triggered()
1558 saveCaptureFile(capture_file_.capFile(), FALSE);
1561 void MainWindow::on_actionFileSaveAs_triggered()
1563 saveAsCaptureFile(capture_file_.capFile());
1566 void MainWindow::on_actionFileSetListFiles_triggered()
1568 file_set_dialog_.exec();
1571 void MainWindow::on_actionFileSetNextFile_triggered()
1573 fileset_entry *entry = fileset_get_next();
1576 QString new_cf_path = entry->fullname;
1577 openCaptureFile(new_cf_path);
1581 void MainWindow::on_actionFileSetPreviousFile_triggered()
1583 fileset_entry *entry = fileset_get_previous();
1586 QString new_cf_path = entry->fullname;
1587 openCaptureFile(new_cf_path);
1591 void MainWindow::on_actionFileExportPackets_triggered()
1593 exportSelectedPackets();
1596 void MainWindow::on_actionFileExportAsPlainText_triggered()
1598 exportDissections(export_type_text);
1601 void MainWindow::on_actionFileExportAsCSV_triggered()
1603 exportDissections(export_type_csv);
1606 void MainWindow::on_actionFileExportAsCArrays_triggered()
1608 exportDissections(export_type_carrays);
1611 void MainWindow::on_actionFileExportAsPSML_triggered()
1613 exportDissections(export_type_psml);
1616 void MainWindow::on_actionFileExportAsPDML_triggered()
1618 exportDissections(export_type_pdml);
1621 void MainWindow::on_actionFileExportPacketBytes_triggered()
1625 if (!capture_file_.capFile() || !capture_file_.capFile()->finfo_selected) return;
1627 file_name = QFileDialog::getSaveFileName(this,
1628 wsApp->windowTitleString(tr("Export Selected Packet Bytes")),
1629 wsApp->lastOpenDir().canonicalPath(),
1630 tr("Raw data (*.bin *.dat *.raw);;Any File (*.*)")
1633 if (file_name.length() > 0) {
1634 const guint8 *data_p;
1637 data_p = tvb_get_ptr(capture_file_.capFile()->finfo_selected->ds_tvb, 0, -1) +
1638 capture_file_.capFile()->finfo_selected->start;
1639 fd = ws_open(file_name.toUtf8().constData(), O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666);
1641 open_failure_alert_box(file_name.toUtf8().constData(), errno, TRUE);
1644 if (write(fd, data_p, capture_file_.capFile()->finfo_selected->length) < 0) {
1645 write_failure_alert_box(file_name.toUtf8().constData(), errno);
1649 if (::close(fd) < 0) {
1650 write_failure_alert_box(file_name.toUtf8().constData(), errno);
1654 /* Save the directory name for future file dialogs. */
1655 wsApp->setLastOpenDir(&file_name);
1658 void MainWindow::on_actionFileExportPDU_triggered()
1660 ExportPDUDialog *exportpdu_dialog = new ExportPDUDialog(this);
1662 if (exportpdu_dialog->isMinimized() == true)
1664 exportpdu_dialog->showNormal();
1668 exportpdu_dialog->show();
1671 exportpdu_dialog->raise();
1672 exportpdu_dialog->activateWindow();
1675 void MainWindow::on_actionFileExportSSLSessionKeys_triggered()
1681 keylist_len = ssl_session_key_count();
1682 /* don't show up the dialog, if no data has to be saved */
1683 if (keylist_len < 1) {
1684 /* shouldn't happen as the menu item should have been greyed out */
1685 QMessageBox::warning(
1688 tr("There are no SSL Session Keys to save."),
1694 save_title.append(wsApp->windowTitleString(tr("Export SSL Session Keys (%1 key%2").
1695 arg(keylist_len).arg(plurality(keylist_len, "", "s"))));
1696 file_name = QFileDialog::getSaveFileName(this,
1698 wsApp->lastOpenDir().canonicalPath(),
1699 tr("SSL Session Keys (*.keys *.txt);;Any File (*.*)")
1701 if (file_name.length() > 0) {
1705 keylist = ssl_export_sessions();
1706 fd = ws_open(file_name.toUtf8().constData(), O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666);
1708 open_failure_alert_box(file_name.toUtf8().constData(), errno, TRUE);
1713 * Thanks, Microsoft, for not using size_t for the third argument to
1714 * _write(). Presumably this string will be <= 4GiB long....
1716 if (ws_write(fd, keylist, (unsigned int)strlen(keylist)) < 0) {
1717 write_failure_alert_box(file_name.toUtf8().constData(), errno);
1722 if (::close(fd) < 0) {
1723 write_failure_alert_box(file_name.toUtf8().constData(), errno);
1728 /* Save the directory name for future file dialogs. */
1729 wsApp->setLastOpenDir(&file_name);
1734 void MainWindow::on_actionFileExportObjectsDICOM_triggered()
1736 new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Dicom);
1739 void MainWindow::on_actionStatisticsHpfeeds_triggered()
1741 openStatisticsTreeDialog("hpfeeds");
1744 void MainWindow::on_actionFileExportObjectsHTTP_triggered()
1746 new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Http);
1749 void MainWindow::on_actionFileExportObjectsSMB_triggered()
1751 new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Smb);
1754 void MainWindow::on_actionFileExportObjectsTFTP_triggered()
1756 new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Tftp);
1759 void MainWindow::on_actionFilePrint_triggered()
1761 PrintDialog pdlg(this, capture_file_.capFile());
1768 void MainWindow::recursiveCopyProtoTreeItems(QTreeWidgetItem *item, QString &clip, int ident_level) {
1769 if (!item->isExpanded()) return;
1771 for (int i_item = 0; i_item < item->childCount(); i_item += 1) {
1772 clip.append(QString(" ").repeated(ident_level));
1773 clip.append(item->child(i_item)->text(0));
1776 recursiveCopyProtoTreeItems(item->child(i_item), clip, ident_level + 1);
1780 // XXX This should probably be somewhere else.
1781 void MainWindow::actionEditCopyTriggered(MainWindow::CopySelected selection_type)
1783 char label_str[ITEM_LABEL_LENGTH];
1786 if (!capture_file_.capFile()) return;
1788 switch(selection_type) {
1789 case CopySelectedDescription:
1790 if (capture_file_.capFile()->finfo_selected->rep &&
1791 strlen (capture_file_.capFile()->finfo_selected->rep->representation) > 0) {
1792 clip.append(capture_file_.capFile()->finfo_selected->rep->representation);
1795 case CopySelectedFieldName:
1796 if (capture_file_.capFile()->finfo_selected->hfinfo->abbrev != 0) {
1797 clip.append(capture_file_.capFile()->finfo_selected->hfinfo->abbrev);
1800 case CopySelectedValue:
1801 if (capture_file_.capFile()->edt != 0) {
1802 gchar* field_str = get_node_field_value(capture_file_.capFile()->finfo_selected, capture_file_.capFile()->edt);
1803 clip.append(field_str);
1807 case CopyAllVisibleItems:
1808 for (int i_item = 0; i_item < proto_tree_->topLevelItemCount(); i_item += 1) {
1809 clip.append(proto_tree_->topLevelItem(i_item)->text(0));
1812 recursiveCopyProtoTreeItems(proto_tree_->topLevelItem(i_item), clip, 1);
1816 case CopyAllVisibleSelectedTreeItems:
1817 clip.append(proto_tree_->currentItem()->text(0));
1820 recursiveCopyProtoTreeItems(proto_tree_->currentItem(), clip, 1);
1825 if (clip.length() == 0) {
1826 /* If no representation then... Try to read the value */
1827 proto_item_fill_label(capture_file_.capFile()->finfo_selected, label_str);
1828 clip.append(label_str);
1831 if (clip.length()) {
1832 wsApp->clipboard()->setText(clip);
1834 QString err = tr("Couldn't copy text. Try another item.");
1835 main_ui_->statusBar->pushTemporaryStatus(err);
1839 void MainWindow::on_actionCopyAllVisibleItems_triggered()
1841 actionEditCopyTriggered(CopyAllVisibleItems);
1844 void MainWindow::on_actionCopyAllVisibleSelectedTreeItems_triggered()
1846 actionEditCopyTriggered(CopyAllVisibleSelectedTreeItems);
1849 void MainWindow::on_actionEditCopyDescription_triggered()
1851 actionEditCopyTriggered(CopySelectedDescription);
1854 void MainWindow::on_actionEditCopyFieldName_triggered()
1856 actionEditCopyTriggered(CopySelectedFieldName);
1859 void MainWindow::on_actionEditCopyValue_triggered()
1861 actionEditCopyTriggered(CopySelectedValue);
1864 void MainWindow::on_actionEditCopyAsFilter_triggered()
1866 matchFieldFilter(FilterAction::ActionCopy, FilterAction::ActionTypePlain);
1869 void MainWindow::on_actionEditFindPacket_triggered()
1871 if (packet_list_->model()->rowCount() < 1) {
1874 previous_focus_ = wsApp->focusWidget();
1875 connect(previous_focus_, SIGNAL(destroyed()), this, SLOT(resetPreviousFocus()));
1876 showAccordionFrame(main_ui_->searchFrame, true);
1879 void MainWindow::on_actionEditFindNext_triggered()
1881 main_ui_->searchFrame->findNext();
1884 void MainWindow::on_actionEditFindPrevious_triggered()
1886 main_ui_->searchFrame->findPrevious();
1889 void MainWindow::on_actionEditMarkPacket_triggered()
1891 packet_list_->markFrame();
1894 void MainWindow::on_actionEditMarkAllDisplayed_triggered()
1896 packet_list_->markAllDisplayedFrames(true);
1899 void MainWindow::on_actionEditUnmarkAllDisplayed_triggered()
1901 packet_list_->markAllDisplayedFrames(false);
1904 void MainWindow::on_actionEditNextMark_triggered()
1906 if (capture_file_.capFile())
1907 cf_find_packet_marked(capture_file_.capFile(), SD_FORWARD);
1910 void MainWindow::on_actionEditPreviousMark_triggered()
1912 if (capture_file_.capFile())
1913 cf_find_packet_marked(capture_file_.capFile(), SD_BACKWARD);
1916 void MainWindow::on_actionEditIgnorePacket_triggered()
1918 packet_list_->ignoreFrame();
1921 void MainWindow::on_actionEditIgnoreAllDisplayed_triggered()
1923 packet_list_->ignoreAllDisplayedFrames(true);
1926 void MainWindow::on_actionEditUnignoreAllDisplayed_triggered()
1928 packet_list_->ignoreAllDisplayedFrames(false);
1931 void MainWindow::on_actionEditSetTimeReference_triggered()
1933 packet_list_->setTimeReference();
1936 void MainWindow::on_actionEditUnsetAllTimeReferences_triggered()
1938 packet_list_->unsetAllTimeReferences();
1941 void MainWindow::on_actionEditNextTimeReference_triggered()
1943 if (!capture_file_.capFile()) return;
1944 cf_find_packet_time_reference(capture_file_.capFile(), SD_FORWARD);
1947 void MainWindow::on_actionEditPreviousTimeReference_triggered()
1949 if (!capture_file_.capFile()) return;
1950 cf_find_packet_time_reference(capture_file_.capFile(), SD_BACKWARD);
1953 void MainWindow::on_actionEditTimeShift_triggered()
1955 TimeShiftDialog ts_dialog(this, capture_file_.capFile());
1956 connect(this, SIGNAL(setCaptureFile(capture_file*)),
1957 &ts_dialog, SLOT(setCaptureFile(capture_file*)));
1961 void MainWindow::on_actionEditPacketComment_triggered()
1963 PacketCommentDialog pc_dialog(this, packet_list_->packetComment());
1964 if (pc_dialog.exec() == QDialog::Accepted) {
1965 packet_list_->setPacketComment(pc_dialog.text());
1966 updateForUnsavedChanges();
1970 void MainWindow::on_actionEditConfigurationProfiles_triggered()
1972 ProfileDialog cp_dialog;
1977 void MainWindow::showPreferencesDialog(PreferencesDialog::PreferencesPane start_pane)
1979 PreferencesDialog pref_dialog(this);
1981 pref_dialog.setPane(start_pane);
1984 // Emitting PacketDissectionChanged directly from a QDialog can cause
1985 // problems on OS X.
1986 wsApp->flushAppSignals();
1989 void MainWindow::showPreferencesDialog(QString module_name)
1991 PreferencesDialog pref_dialog(this);
1993 pref_dialog.setPane(module_name);
1996 // Emitting PacketDissectionChanged directly from a QDialog can cause
1997 // problems on OS X.
1998 wsApp->flushAppSignals();
2001 void MainWindow::on_actionEditPreferences_triggered()
2003 showPreferencesDialog();
2008 void MainWindow::showHideMainWidgets(QAction *action)
2013 bool show = action->isChecked();
2014 QWidget *widget = action->data().value<QWidget*>();
2016 // We may have come from the toolbar context menu, so check/uncheck each
2018 if (widget == main_ui_->mainToolBar) {
2019 recent.main_toolbar_show = show;
2020 main_ui_->actionViewMainToolbar->setChecked(show);
2021 } else if (widget == main_ui_->displayFilterToolBar) {
2022 recent.filter_toolbar_show = show;
2023 main_ui_->actionViewFilterToolbar->setChecked(show);
2024 } else if (widget == main_ui_->wirelessToolBar) {
2025 recent.wireless_toolbar_show = show;
2026 main_ui_->actionViewWirelessToolbar->setChecked(show);
2027 } else if (widget == main_ui_->statusBar) {
2028 recent.statusbar_show = show;
2029 main_ui_->actionViewStatusBar->setChecked(show);
2030 } else if (widget == packet_list_) {
2031 recent.packet_list_show = show;
2032 main_ui_->actionViewPacketList->setChecked(show);
2033 } else if (widget == proto_tree_) {
2034 recent.tree_view_show = show;
2035 main_ui_->actionViewPacketDetails->setChecked(show);
2036 } else if (widget == byte_view_tab_) {
2037 recent.byte_view_show = show;
2038 main_ui_->actionViewPacketBytes->setChecked(show);
2042 widget->setVisible(show);
2046 Q_DECLARE_METATYPE(ts_type)
2048 void MainWindow::setTimestampFormat(QAction *action)
2053 ts_type tsf = action->data().value<ts_type>();
2054 if (recent.gui_time_format != tsf) {
2055 timestamp_set_type(tsf);
2056 recent.gui_time_format = tsf;
2057 if (capture_file_.capFile()) {
2058 /* This call adjusts column width */
2059 cf_timestamp_auto_precision(capture_file_.capFile());
2062 packet_list_->columnsChanged();
2067 Q_DECLARE_METATYPE(ts_precision)
2069 void MainWindow::setTimestampPrecision(QAction *action)
2074 ts_precision tsp = action->data().value<ts_precision>();
2075 if (recent.gui_time_precision != tsp) {
2076 /* the actual precision will be set in packet_list_queue_draw() below */
2077 timestamp_set_precision(tsp);
2078 recent.gui_time_precision = tsp;
2079 if (capture_file_.capFile()) {
2080 /* This call adjusts column width */
2081 cf_timestamp_auto_precision(capture_file_.capFile());
2084 packet_list_->columnsChanged();
2089 void MainWindow::on_actionViewTimeDisplaySecondsWithHoursAndMinutes_triggered(bool checked)
2092 recent.gui_seconds_format = TS_SECONDS_HOUR_MIN_SEC;
2094 recent.gui_seconds_format = TS_SECONDS_DEFAULT;
2096 timestamp_set_seconds_type(recent.gui_seconds_format);
2098 if (capture_file_.capFile()) {
2099 /* This call adjusts column width */
2100 cf_timestamp_auto_precision(capture_file_.capFile());
2103 packet_list_->columnsChanged();
2107 void MainWindow::on_actionViewEditResolvedName_triggered()
2109 // int column = packet_list_->selectedColumn();
2112 if (packet_list_->currentIndex().isValid()) {
2113 column = packet_list_->currentIndex().column();
2116 main_ui_->addressEditorFrame->editAddresses(capture_file_, column);
2117 showAccordionFrame(main_ui_->addressEditorFrame);
2120 void MainWindow::setNameResolution()
2122 gbl_resolv_flags.mac_name = main_ui_->actionViewNameResolutionPhysical->isChecked() ? TRUE : FALSE;
2123 gbl_resolv_flags.network_name = main_ui_->actionViewNameResolutionNetwork->isChecked() ? TRUE : FALSE;
2124 gbl_resolv_flags.transport_name = main_ui_->actionViewNameResolutionTransport->isChecked() ? TRUE : FALSE;
2127 packet_list_->columnsChanged();
2131 void MainWindow::on_actionViewNameResolutionPhysical_triggered()
2133 setNameResolution();
2136 void MainWindow::on_actionViewNameResolutionNetwork_triggered()
2138 setNameResolution();
2141 void MainWindow::on_actionViewNameResolutionTransport_triggered()
2143 setNameResolution();
2146 void MainWindow::zoomText()
2148 // Scale by 10%, rounding to nearest half point, minimum 1 point.
2149 // XXX Small sizes repeat. It might just be easier to create a map of multipliers.
2150 mono_font_ = QFont(wsApp->monospaceFont());
2151 qreal zoom_size = wsApp->monospaceFont().pointSize() * 2 * qPow(1.1, recent.gui_zoom_level);
2152 zoom_size = qRound(zoom_size) / 2.0;
2153 zoom_size = qMax(zoom_size, 1.0);
2154 mono_font_.setPointSizeF(zoom_size);
2155 emit monospaceFontChanged(mono_font_);
2158 void MainWindow::on_actionViewZoomIn_triggered()
2160 recent.gui_zoom_level++;
2164 void MainWindow::on_actionViewZoomOut_triggered()
2166 recent.gui_zoom_level--;
2170 void MainWindow::on_actionViewNormalSize_triggered()
2172 recent.gui_zoom_level = 0;
2176 void MainWindow::on_actionViewColorizePacketList_triggered(bool checked) {
2177 recent.packet_list_colorize = checked;
2178 color_filters_enable(checked);
2179 packet_list_->packetListModel()->resetColorized();
2180 packet_list_->update();
2183 void MainWindow::on_actionViewColoringRules_triggered()
2185 ColoringRulesDialog coloring_rules_dialog(this);
2187 coloring_rules_dialog.exec();
2190 // actionViewColorizeConversation1 - 10
2191 void MainWindow::colorizeConversation(bool create_rule)
2193 QAction *cc_action = qobject_cast<QAction *>(sender());
2194 if (!cc_action) return;
2196 if (capture_file_.capFile() && capture_file_.capFile()->current_frame) {
2197 packet_info *pi = &capture_file_.capFile()->edt->pi;
2198 guint8 cc_num = cc_action->data().toUInt();
2199 gchar *filter = NULL;
2201 const color_conversation_filter_t *color_filter = find_color_conversation_filter("tcp");
2202 if ((color_filter != NULL) && (color_filter->is_filter_valid(pi)))
2203 filter = color_filter->build_filter_string(pi);
2204 if (filter == NULL) {
2205 color_filter = find_color_conversation_filter("udp");
2206 if ((color_filter != NULL) && (color_filter->is_filter_valid(pi)))
2207 filter = color_filter->build_filter_string(pi);
2209 if (filter == NULL) {
2210 color_filter = find_color_conversation_filter("ip");
2211 if ((color_filter != NULL) && (color_filter->is_filter_valid(pi)))
2212 filter = color_filter->build_filter_string(pi);
2214 if (filter == NULL) {
2215 color_filter = find_color_conversation_filter("ipv6");
2216 if ((color_filter != NULL) && (color_filter->is_filter_valid(pi)))
2217 filter = color_filter->build_filter_string(pi);
2219 if (filter == NULL) {
2220 color_filter = find_color_conversation_filter("eth");
2221 if ((color_filter != NULL) && (color_filter->is_filter_valid(pi)))
2222 filter = color_filter->build_filter_string(pi);
2224 if( filter == NULL ) {
2225 main_ui_->statusBar->pushTemporaryStatus(tr("Unable to build conversation filter."));
2230 ColoringRulesDialog coloring_rules_dialog(this, filter);
2231 coloring_rules_dialog.exec();
2233 color_filters_set_tmp(cc_num, filter, FALSE);
2234 packet_list_->recolorPackets();
2237 setMenusForSelectedPacket();
2240 void MainWindow::colorizeWithFilter()
2242 QAction *colorize_action = qobject_cast<QAction *>(sender());
2243 if (!colorize_action) return;
2245 QString filter = colorize_action->data().toString();
2246 if (filter.isEmpty()) return;
2249 int color_number = colorize_action->property(color_number_property_).toInt(&ok);
2253 color_filters_set_tmp(color_number, filter.toUtf8().constData(), FALSE);
2254 packet_list_->recolorPackets();
2256 // New coloring rule
2257 ColoringRulesDialog coloring_rules_dialog(window(), filter);
2258 coloring_rules_dialog.exec();
2260 main_ui_->actionViewColorizeResetColorization->setEnabled(tmp_color_filters_used());
2263 void MainWindow::on_actionViewColorizeResetColorization_triggered()
2265 color_filters_reset_tmp();
2266 packet_list_->recolorPackets();
2267 setMenusForSelectedPacket();
2270 void MainWindow::on_actionViewColorizeNewConversationRule_triggered()
2272 colorizeConversation(true);
2275 void MainWindow::on_actionViewResizeColumns_triggered()
2277 for (int col = 0; col < packet_list_->packetListModel()->columnCount(); col++) {
2278 packet_list_->resizeColumnToContents(col);
2279 recent_set_column_width(col, packet_list_->columnWidth(col));
2283 void MainWindow::openPacketDialog(bool from_reference)
2287 /* Find the frame for which we're popping up a dialog */
2288 if(from_reference) {
2289 guint32 framenum = fvalue_get_uinteger(&(capture_file_.capFile()->finfo_selected->value));
2293 fdata = frame_data_sequence_find(capture_file_.capFile()->frames, framenum);
2295 fdata = capture_file_.capFile()->current_frame;
2298 /* If we have a frame, pop up the dialog */
2300 PacketDialog *packet_dialog = new PacketDialog(*this, capture_file_, fdata);
2302 connect(this, SIGNAL(monospaceFontChanged(QFont)),
2303 packet_dialog, SIGNAL(monospaceFontChanged(QFont)));
2304 connect(this, SIGNAL(closePacketDialogs()),
2305 packet_dialog, SLOT(close()));
2306 zoomText(); // Emits monospaceFontChanged
2308 packet_dialog->show();
2312 void MainWindow::on_actionViewShowPacketInNewWindow_triggered()
2317 // This is only used in ProtoTree. Defining it here makes more sense.
2318 void MainWindow::on_actionContextShowLinkedPacketInNewWindow_triggered()
2320 openPacketDialog(true);
2323 void MainWindow::on_actionViewReload_triggered()
2325 cf_reload(CaptureFile::globalCapFile());
2328 // Expand / collapse slots in proto_tree
2334 void MainWindow::matchFieldFilter(FilterAction::Action action, FilterAction::ActionType filter_type)
2336 QString field_filter;
2338 if (packet_list_->contextMenuActive() || packet_list_->hasFocus()) {
2339 field_filter = packet_list_->getFilterFromRowAndColumn();
2340 } else if (capture_file_.capFile() && capture_file_.capFile()->finfo_selected) {
2341 char *tmp_field = proto_construct_match_selected_string(capture_file_.capFile()->finfo_selected,
2342 capture_file_.capFile()->edt);
2343 field_filter = QString(tmp_field);
2344 wmem_free(NULL, tmp_field);
2347 if (field_filter.isEmpty()) {
2348 QString err = tr("No filter available. Try another ");
2349 err.append(packet_list_->contextMenuActive() ? "column" : "item");
2351 main_ui_->statusBar->pushTemporaryStatus(err);
2355 filterAction(field_filter, action, filter_type);
2358 static FilterDialog *display_filter_dlg_ = NULL;
2359 void MainWindow::on_actionAnalyzeDisplayFilters_triggered()
2361 if (!display_filter_dlg_) {
2362 display_filter_dlg_ = new FilterDialog(this, FilterDialog::DisplayFilter);
2364 display_filter_dlg_->show();
2365 display_filter_dlg_->raise();
2366 display_filter_dlg_->activateWindow();
2370 void MainWindow::on_actionAnalyzeDisplayFilterMacros_triggered()
2372 struct epan_uat* dfm_uat;
2373 dfilter_macro_get_uat(&dfm_uat);
2374 UatDialog uat_dlg(parentWidget(), dfm_uat);
2377 // Emitting PacketDissectionChanged directly from a QDialog can cause
2378 // problems on OS X.
2379 wsApp->flushAppSignals();
2382 void MainWindow::on_actionAnalyzeCreateAColumn_triggered()
2386 if ( capture_file_.capFile() != 0 && capture_file_.capFile()->finfo_selected != 0 )
2388 colnr = column_prefs_add_custom(COL_CUSTOM, capture_file_.capFile()->finfo_selected->hfinfo->name,
2389 capture_file_.capFile()->finfo_selected->hfinfo->abbrev,0);
2391 packet_list_->columnsChanged();
2392 packet_list_->resizeColumnToContents(colnr);
2398 void MainWindow::applyConversationFilter()
2400 QAction *cfa = qobject_cast<QAction*>(sender());
2403 QString new_filter = cfa->data().toString();
2404 if (new_filter.isEmpty()) return;
2406 df_combo_box_->lineEdit()->setText(new_filter);
2407 df_combo_box_->applyDisplayFilter();
2410 // XXX We could probably create the analyze and prepare actions
2411 // dynamically using FilterActions and consolidate the methods
2412 // below into one callback.
2413 void MainWindow::on_actionAnalyzeAAFSelected_triggered()
2415 matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypePlain);
2418 void MainWindow::on_actionAnalyzeAAFNotSelected_triggered()
2420 matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypeNot);
2423 void MainWindow::on_actionAnalyzeAAFAndSelected_triggered()
2425 matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypeAnd);
2428 void MainWindow::on_actionAnalyzeAAFOrSelected_triggered()
2430 matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypeOr);
2433 void MainWindow::on_actionAnalyzeAAFAndNotSelected_triggered()
2435 matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypeAndNot);
2438 void MainWindow::on_actionAnalyzeAAFOrNotSelected_triggered()
2440 matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypeOrNot);
2443 void MainWindow::on_actionAnalyzePAFSelected_triggered()
2445 matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypePlain);
2448 void MainWindow::on_actionAnalyzePAFNotSelected_triggered()
2450 matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypeNot);
2453 void MainWindow::on_actionAnalyzePAFAndSelected_triggered()
2455 matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypeAnd);
2458 void MainWindow::on_actionAnalyzePAFOrSelected_triggered()
2460 matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypeOr);
2463 void MainWindow::on_actionAnalyzePAFAndNotSelected_triggered()
2465 matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypeAndNot);
2468 void MainWindow::on_actionAnalyzePAFOrNotSelected_triggered()
2470 matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypeOrNot);
2473 void MainWindow::on_actionAnalyzeEnabledProtocols_triggered()
2475 EnabledProtocolsDialog enable_proto_dialog(this);
2476 enable_proto_dialog.exec();
2478 // Emitting PacketDissectionChanged directly from a QDialog can cause
2479 // problems on OS X.
2480 wsApp->flushAppSignals();
2483 void MainWindow::on_actionAnalyzeDecodeAs_triggered()
2485 QAction *da_action = qobject_cast<QAction*>(sender());
2486 bool create_new = false;
2487 if (da_action && da_action->data().toBool() == true) {
2491 DecodeAsDialog da_dialog(this, capture_file_.capFile(), create_new);
2492 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2493 &da_dialog, SLOT(setCaptureFile(capture_file*)));
2496 // Emitting PacketDissectionChanged directly from a QDialog can cause
2497 // problems on OS X.
2498 wsApp->flushAppSignals();
2502 void MainWindow::on_actionAnalyzeReloadLuaPlugins_triggered()
2504 if (wsApp->isReloadingLua())
2507 wsApp->setReloadingLua(true);
2509 wslua_reload_plugins(NULL, NULL);
2510 funnel_statistics_reload_menus();
2511 reloadDynamicMenus();
2512 closePacketDialogs();
2514 // Preferences may have been deleted so close all widgets using prefs
2515 proto_tree_->closeContextMenu();
2516 main_ui_->preferenceEditorFrame->animatedHide();
2518 char *gdp_path, *dp_path;
2519 (void) wsApp->readConfigurationFiles(&gdp_path, &dp_path);
2524 wsApp->setReloadingLua(false);
2525 SimpleDialog::displayQueuedMessages();
2529 void MainWindow::openFollowStreamDialog(follow_type_t type) {
2530 FollowStreamDialog *fsd = new FollowStreamDialog(*this, capture_file_, type);
2531 connect(fsd, SIGNAL(updateFilter(QString, bool)), this, SLOT(filterPackets(QString, bool)));
2532 connect(fsd, SIGNAL(goToPacket(int)), packet_list_, SLOT(goToPacket(int)));
2535 fsd->follow(getFilter());
2538 void MainWindow::on_actionAnalyzeFollowTCPStream_triggered()
2540 openFollowStreamDialog(FOLLOW_TCP);
2543 void MainWindow::on_actionAnalyzeFollowUDPStream_triggered()
2545 openFollowStreamDialog(FOLLOW_UDP);
2548 void MainWindow::on_actionAnalyzeFollowSSLStream_triggered()
2550 openFollowStreamDialog(FOLLOW_SSL);
2553 void MainWindow::openSCTPAllAssocsDialog()
2555 SCTPAllAssocsDialog *sctp_dialog = new SCTPAllAssocsDialog(this, capture_file_.capFile());
2556 connect(sctp_dialog, SIGNAL(filterPackets(QString,bool)),
2557 this, SLOT(filterPackets(QString,bool)));
2558 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2559 sctp_dialog, SLOT(setCaptureFile(capture_file*)));
2560 sctp_dialog->fillTable();
2562 if (sctp_dialog->isMinimized() == true)
2564 sctp_dialog->showNormal();
2568 sctp_dialog->show();
2571 sctp_dialog->raise();
2572 sctp_dialog->activateWindow();
2575 void MainWindow::on_actionSCTPShowAllAssociations_triggered()
2577 openSCTPAllAssocsDialog();
2580 void MainWindow::on_actionSCTPAnalyseThisAssociation_triggered()
2582 SCTPAssocAnalyseDialog *sctp_analyse = new SCTPAssocAnalyseDialog(this, NULL, capture_file_.capFile());
2583 connect(sctp_analyse, SIGNAL(filterPackets(QString,bool)),
2584 this, SLOT(filterPackets(QString,bool)));
2586 if (sctp_analyse->isMinimized() == true)
2588 sctp_analyse->showNormal();
2592 sctp_analyse->show();
2595 sctp_analyse->raise();
2596 sctp_analyse->activateWindow();
2599 void MainWindow::on_actionSCTPFilterThisAssociation_triggered()
2601 sctp_assoc_info_t* assoc = SCTPAssocAnalyseDialog::findAssocForPacket(capture_file_.capFile());
2603 QString newFilter = QString("sctp.assoc_index==%1").arg(assoc->assoc_id);
2605 emit filterPackets(newFilter, false);
2610 void MainWindow::statCommandWlanStatistics(const char *arg, void *)
2612 WlanStatisticsDialog *wlan_stats_dlg = new WlanStatisticsDialog(*this, capture_file_, arg);
2613 connect(wlan_stats_dlg, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
2614 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
2615 wlan_stats_dlg->show();
2618 void MainWindow::on_actionWirelessWlanStatistics_triggered()
2620 statCommandWlanStatistics(NULL, NULL);
2624 void MainWindow::statCommandExpertInfo(const char *, void *)
2626 ExpertInfoDialog *expert_dialog = new ExpertInfoDialog(*this, capture_file_);
2627 const DisplayFilterEdit *df_edit = dynamic_cast<DisplayFilterEdit *>(df_combo_box_->lineEdit());
2629 expert_dialog->setDisplayFilter(df_edit->text());
2631 connect(expert_dialog, SIGNAL(goToPacket(int, int)),
2632 packet_list_, SLOT(goToPacket(int, int)));
2633 connect(expert_dialog, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
2634 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
2636 expert_dialog->show();
2639 void MainWindow::on_actionAnalyzeExpertInfo_triggered()
2641 statCommandExpertInfo(NULL, NULL);
2645 // Next / previous / first / last slots in packet_list
2649 void MainWindow::on_actionStatisticsFlowGraph_triggered()
2651 SequenceDialog *sequence_dialog = new SequenceDialog(*this, capture_file_);
2652 connect(sequence_dialog, SIGNAL(goToPacket(int)),
2653 packet_list_, SLOT(goToPacket(int)));
2654 sequence_dialog->show();
2657 void MainWindow::openTcpStreamDialog(int graph_type)
2659 TCPStreamDialog *stream_dialog = new TCPStreamDialog(this, capture_file_.capFile(), (tcp_graph_type)graph_type);
2660 connect(stream_dialog, SIGNAL(goToPacket(int)),
2661 packet_list_, SLOT(goToPacket(int)));
2662 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2663 stream_dialog, SLOT(setCaptureFile(capture_file*)));
2664 stream_dialog->show();
2667 void MainWindow::on_actionStatisticsTcpStreamStevens_triggered()
2669 openTcpStreamDialog(GRAPH_TSEQ_STEVENS);
2672 void MainWindow::on_actionStatisticsTcpStreamTcptrace_triggered()
2674 openTcpStreamDialog(GRAPH_TSEQ_TCPTRACE);
2677 void MainWindow::on_actionStatisticsTcpStreamThroughput_triggered()
2679 openTcpStreamDialog(GRAPH_THROUGHPUT);
2682 void MainWindow::on_actionStatisticsTcpStreamRoundTripTime_triggered()
2684 openTcpStreamDialog(GRAPH_RTT);
2687 void MainWindow::on_actionStatisticsTcpStreamWindowScaling_triggered()
2689 openTcpStreamDialog(GRAPH_WSCALE);
2693 void MainWindow::statCommandMulticastStatistics(const char *arg, void *)
2695 MulticastStatisticsDialog *mcast_stats_dlg = new MulticastStatisticsDialog(*this, capture_file_, arg);
2696 connect(mcast_stats_dlg, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
2697 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
2698 mcast_stats_dlg->show();
2701 void MainWindow::on_actionStatisticsUdpMulticastStreams_triggered()
2703 statCommandMulticastStatistics(NULL, NULL);
2706 void MainWindow::openStatisticsTreeDialog(const gchar *abbr)
2708 StatsTreeDialog *st_dialog = new StatsTreeDialog(*this, capture_file_, abbr);
2709 // connect(st_dialog, SIGNAL(goToPacket(int)),
2710 // packet_list_, SLOT(goToPacket(int)));
2714 void MainWindow::on_actionStatistics29WestTopics_Advertisements_by_Topic_triggered()
2716 openStatisticsTreeDialog("lbmr_topic_ads_topic");
2719 void MainWindow::on_actionStatistics29WestTopics_Advertisements_by_Source_triggered()
2721 openStatisticsTreeDialog("lbmr_topic_ads_source");
2724 void MainWindow::on_actionStatistics29WestTopics_Advertisements_by_Transport_triggered()
2726 openStatisticsTreeDialog("lbmr_topic_ads_transport");
2729 void MainWindow::on_actionStatistics29WestTopics_Queries_by_Topic_triggered()
2731 openStatisticsTreeDialog("lbmr_topic_queries_topic");
2734 void MainWindow::on_actionStatistics29WestTopics_Queries_by_Receiver_triggered()
2736 openStatisticsTreeDialog("lbmr_topic_queries_receiver");
2739 void MainWindow::on_actionStatistics29WestTopics_Wildcard_Queries_by_Pattern_triggered()
2741 openStatisticsTreeDialog("lbmr_topic_queries_pattern");
2744 void MainWindow::on_actionStatistics29WestTopics_Wildcard_Queries_by_Receiver_triggered()
2746 openStatisticsTreeDialog("lbmr_topic_queries_pattern_receiver");
2749 void MainWindow::on_actionStatistics29WestQueues_Advertisements_by_Queue_triggered()
2751 openStatisticsTreeDialog("lbmr_queue_ads_queue");
2754 void MainWindow::on_actionStatistics29WestQueues_Advertisements_by_Source_triggered()
2756 openStatisticsTreeDialog("lbmr_queue_ads_source");
2759 void MainWindow::on_actionStatistics29WestQueues_Queries_by_Queue_triggered()
2761 openStatisticsTreeDialog("lbmr_queue_queries_queue");
2764 void MainWindow::on_actionStatistics29WestQueues_Queries_by_Receiver_triggered()
2766 openStatisticsTreeDialog("lbmr_queue_queries_receiver");
2769 void MainWindow::on_actionStatistics29WestUIM_Streams_triggered()
2771 LBMStreamDialog *stream_dialog = new LBMStreamDialog(this, capture_file_.capFile());
2772 // connect(stream_dialog, SIGNAL(goToPacket(int)),
2773 // packet_list_, SLOT(goToPacket(int)));
2774 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2775 stream_dialog, SLOT(setCaptureFile(capture_file*)));
2776 stream_dialog->show();
2779 void MainWindow::on_actionStatistics29WestUIM_Stream_Flow_Graph_triggered()
2781 LBMUIMFlowDialog * uimflow_dialog = new LBMUIMFlowDialog(this, capture_file_.capFile());
2782 connect(uimflow_dialog, SIGNAL(goToPacket(int)),
2783 packet_list_, SLOT(goToPacket(int)));
2784 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2785 uimflow_dialog, SLOT(setCaptureFile(capture_file*)));
2786 uimflow_dialog->show();
2789 void MainWindow::on_actionStatistics29WestLBTRM_triggered()
2791 LBMLBTRMTransportDialog * lbtrm_dialog = new LBMLBTRMTransportDialog(this, capture_file_.capFile());
2792 connect(lbtrm_dialog, SIGNAL(goToPacket(int)),
2793 packet_list_, SLOT(goToPacket(int)));
2794 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2795 lbtrm_dialog, SLOT(setCaptureFile(capture_file*)));
2796 lbtrm_dialog->show();
2798 void MainWindow::on_actionStatistics29WestLBTRU_triggered()
2800 LBMLBTRUTransportDialog * lbtru_dialog = new LBMLBTRUTransportDialog(this, capture_file_.capFile());
2801 connect(lbtru_dialog, SIGNAL(goToPacket(int)),
2802 packet_list_, SLOT(goToPacket(int)));
2803 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2804 lbtru_dialog, SLOT(setCaptureFile(capture_file*)));
2805 lbtru_dialog->show();
2808 void MainWindow::on_actionStatisticsANCP_triggered()
2810 openStatisticsTreeDialog("ancp");
2813 void MainWindow::on_actionStatisticsBACappInstanceId_triggered()
2815 openStatisticsTreeDialog("bacapp_instanceid");
2818 void MainWindow::on_actionStatisticsBACappIP_triggered()
2820 openStatisticsTreeDialog("bacapp_ip");
2823 void MainWindow::on_actionStatisticsBACappObjectId_triggered()
2825 openStatisticsTreeDialog("bacapp_objectid");
2828 void MainWindow::on_actionStatisticsBACappService_triggered()
2830 openStatisticsTreeDialog("bacapp_service");
2833 void MainWindow::on_actionStatisticsCollectd_triggered()
2835 openStatisticsTreeDialog("collectd");
2839 void MainWindow::statCommandConversations(const char *arg, void *userdata)
2841 ConversationDialog *conv_dialog = new ConversationDialog(*this, capture_file_, GPOINTER_TO_INT(userdata), arg);
2842 connect(conv_dialog, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
2843 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
2844 connect(conv_dialog, SIGNAL(openFollowStreamDialog(follow_type_t)),
2845 this, SLOT(openFollowStreamDialog(follow_type_t)));
2846 connect(conv_dialog, SIGNAL(openTcpStreamGraph(int)),
2847 this, SLOT(openTcpStreamDialog(int)));
2848 conv_dialog->show();
2851 void MainWindow::on_actionStatisticsConversations_triggered()
2853 statCommandConversations(NULL, NULL);
2857 void MainWindow::statCommandEndpoints(const char *arg, void *userdata)
2859 EndpointDialog *endp_dialog = new EndpointDialog(*this, capture_file_, GPOINTER_TO_INT(userdata), arg);
2860 connect(endp_dialog, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
2861 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
2862 connect(endp_dialog, SIGNAL(openFollowStreamDialog(follow_type_t)),
2863 this, SLOT(openFollowStreamDialog(follow_type_t)));
2864 connect(endp_dialog, SIGNAL(openTcpStreamGraph(int)),
2865 this, SLOT(openTcpStreamDialog(int)));
2866 endp_dialog->show();
2869 void MainWindow::on_actionStatisticsEndpoints_triggered()
2871 statCommandEndpoints(NULL, NULL);
2874 void MainWindow::on_actionStatisticsHART_IP_triggered()
2876 openStatisticsTreeDialog("hart_ip");
2879 void MainWindow::on_actionStatisticsHTTPPacketCounter_triggered()
2881 openStatisticsTreeDialog("http");
2884 void MainWindow::on_actionStatisticsHTTPRequests_triggered()
2886 openStatisticsTreeDialog("http_req");
2889 void MainWindow::on_actionStatisticsHTTPLoadDistribution_triggered()
2891 openStatisticsTreeDialog("http_srv");
2894 void MainWindow::on_actionStatisticsPacketLengths_triggered()
2896 openStatisticsTreeDialog("plen");
2900 void MainWindow::statCommandIOGraph(const char *, void *)
2902 IOGraphDialog *iog_dialog = new IOGraphDialog(*this, capture_file_);
2903 connect(iog_dialog, SIGNAL(goToPacket(int)), packet_list_, SLOT(goToPacket(int)));
2904 connect(this, SIGNAL(reloadFields()), iog_dialog, SLOT(reloadFields()));
2908 void MainWindow::on_actionStatisticsIOGraph_triggered()
2910 statCommandIOGraph(NULL, NULL);
2913 void MainWindow::on_actionStatisticsSametime_triggered()
2915 openStatisticsTreeDialog("sametime");
2918 void MainWindow::on_actionStatisticsDNS_triggered()
2920 openStatisticsTreeDialog("dns");
2923 void MainWindow::actionStatisticsPlugin_triggered()
2925 QAction* action = qobject_cast<QAction*>(sender());
2927 openStatisticsTreeDialog(action->data().toString().toUtf8());
2931 void MainWindow::on_actionStatisticsHTTP2_triggered()
2933 openStatisticsTreeDialog("http2");
2939 void MainWindow::openVoipCallsDialog(bool all_flows)
2941 VoipCallsDialog *voip_calls_dialog = new VoipCallsDialog(*this, capture_file_, all_flows);
2942 connect(voip_calls_dialog, SIGNAL(goToPacket(int)),
2943 packet_list_, SLOT(goToPacket(int)));
2944 connect(voip_calls_dialog, SIGNAL(updateFilter(QString, bool)),
2945 this, SLOT(filterPackets(QString, bool)));
2946 voip_calls_dialog->show();
2949 void MainWindow::on_actionTelephonyVoipCalls_triggered()
2951 openVoipCallsDialog();
2954 void MainWindow::on_actionTelephonyGsmMapSummary_triggered()
2956 GsmMapSummaryDialog *gms_dialog = new GsmMapSummaryDialog(*this, capture_file_);
2960 void MainWindow::on_actionTelephonyIax2StreamAnalysis_triggered()
2962 Iax2AnalysisDialog *iax2_analysis_dialog = new Iax2AnalysisDialog(*this, capture_file_);
2963 connect(iax2_analysis_dialog, SIGNAL(goToPacket(int)),
2964 packet_list_, SLOT(goToPacket(int)));
2965 iax2_analysis_dialog->show();
2968 void MainWindow::on_actionTelephonyISUPMessages_triggered()
2970 openStatisticsTreeDialog("isup_msg");
2973 void MainWindow::on_actionTelephonyMtp3Summary_triggered()
2975 Mtp3SummaryDialog *mtp3s_dialog = new Mtp3SummaryDialog(*this, capture_file_);
2976 mtp3s_dialog->show();
2979 void MainWindow::on_actionTelephonyRTPStreams_triggered()
2981 RtpStreamDialog *rtp_stream_dialog = new RtpStreamDialog(*this, capture_file_);
2982 connect(rtp_stream_dialog, SIGNAL(packetsMarked()),
2983 packet_list_, SLOT(redrawVisiblePackets()));
2984 connect(rtp_stream_dialog, SIGNAL(goToPacket(int)),
2985 packet_list_, SLOT(goToPacket(int)));
2986 connect(rtp_stream_dialog, SIGNAL(updateFilter(QString, bool)),
2987 this, SLOT(filterPackets(QString, bool)));
2988 rtp_stream_dialog->show();
2991 void MainWindow::on_actionTelephonyRTPStreamAnalysis_triggered()
2993 RtpAnalysisDialog *rtp_analysis_dialog = new RtpAnalysisDialog(*this, capture_file_);
2994 connect(rtp_analysis_dialog, SIGNAL(goToPacket(int)),
2995 packet_list_, SLOT(goToPacket(int)));
2996 rtp_analysis_dialog->show();
2999 void MainWindow::on_actionTelephonyRTSPPacketCounter_triggered()
3001 openStatisticsTreeDialog("rtsp");
3004 void MainWindow::on_actionTelephonySMPPOperations_triggered()
3006 openStatisticsTreeDialog("smpp_commands");
3009 void MainWindow::on_actionTelephonyUCPMessages_triggered()
3011 openStatisticsTreeDialog("ucp_messages");
3014 void MainWindow::on_actionTelephonySipFlows_triggered()
3016 openVoipCallsDialog(true);
3021 void MainWindow::on_actionATT_Server_Attributes_triggered()
3023 BluetoothAttServerAttributesDialog *bluetooth_att_sever_attributes_dialog = new BluetoothAttServerAttributesDialog(*this, capture_file_);
3024 connect(bluetooth_att_sever_attributes_dialog, SIGNAL(goToPacket(int)),
3025 packet_list_, SLOT(goToPacket(int)));
3026 connect(bluetooth_att_sever_attributes_dialog, SIGNAL(updateFilter(QString, bool)),
3027 this, SLOT(filterPackets(QString, bool)));
3028 bluetooth_att_sever_attributes_dialog->show();
3031 void MainWindow::on_actionDevices_triggered()
3033 BluetoothDevicesDialog *bluetooth_devices_dialog = new BluetoothDevicesDialog(*this, capture_file_);
3034 connect(bluetooth_devices_dialog, SIGNAL(goToPacket(int)),
3035 packet_list_, SLOT(goToPacket(int)));
3036 connect(bluetooth_devices_dialog, SIGNAL(updateFilter(QString, bool)),
3037 this, SLOT(filterPackets(QString, bool)));
3038 bluetooth_devices_dialog->show();
3041 void MainWindow::on_actionHCI_Summary_triggered()
3043 BluetoothHciSummaryDialog *bluetooth_hci_summary_dialog = new BluetoothHciSummaryDialog(*this, capture_file_);
3044 connect(bluetooth_hci_summary_dialog, SIGNAL(goToPacket(int)),
3045 packet_list_, SLOT(goToPacket(int)));
3046 connect(bluetooth_hci_summary_dialog, SIGNAL(updateFilter(QString, bool)),
3047 this, SLOT(filterPackets(QString, bool)));
3048 bluetooth_hci_summary_dialog->show();
3052 void MainWindow::on_actionHelpContents_triggered() {
3054 wsApp->helpTopicAction(HELP_CONTENT);
3057 void MainWindow::on_actionHelpMPWireshark_triggered() {
3059 wsApp->helpTopicAction(LOCALPAGE_MAN_WIRESHARK);
3062 void MainWindow::on_actionHelpMPWireshark_Filter_triggered() {
3063 wsApp->helpTopicAction(LOCALPAGE_MAN_WIRESHARK_FILTER);
3066 void MainWindow::on_actionHelpMPCapinfos_triggered() {
3067 wsApp->helpTopicAction(LOCALPAGE_MAN_CAPINFOS);
3070 void MainWindow::on_actionHelpMPDumpcap_triggered() {
3071 wsApp->helpTopicAction(LOCALPAGE_MAN_DUMPCAP);
3074 void MainWindow::on_actionHelpMPEditcap_triggered() {
3075 wsApp->helpTopicAction(LOCALPAGE_MAN_EDITCAP);
3078 void MainWindow::on_actionHelpMPMergecap_triggered() {
3079 wsApp->helpTopicAction(LOCALPAGE_MAN_MERGECAP);
3082 void MainWindow::on_actionHelpMPRawShark_triggered() {
3083 wsApp->helpTopicAction(LOCALPAGE_MAN_RAWSHARK);
3086 void MainWindow::on_actionHelpMPReordercap_triggered() {
3087 wsApp->helpTopicAction(LOCALPAGE_MAN_REORDERCAP);
3090 void MainWindow::on_actionHelpMPText2cap_triggered() {
3091 wsApp->helpTopicAction(LOCALPAGE_MAN_TEXT2PCAP);
3094 void MainWindow::on_actionHelpMPTShark_triggered() {
3095 wsApp->helpTopicAction(LOCALPAGE_MAN_TSHARK);
3098 void MainWindow::on_actionHelpWebsite_triggered() {
3100 wsApp->helpTopicAction(ONLINEPAGE_HOME);
3103 void MainWindow::on_actionHelpFAQ_triggered() {
3105 wsApp->helpTopicAction(ONLINEPAGE_FAQ);
3108 void MainWindow::on_actionHelpAsk_triggered() {
3110 wsApp->helpTopicAction(ONLINEPAGE_ASK);
3113 void MainWindow::on_actionHelpDownloads_triggered() {
3115 wsApp->helpTopicAction(ONLINEPAGE_DOWNLOAD);
3118 void MainWindow::on_actionHelpWiki_triggered() {
3120 wsApp->helpTopicAction(ONLINEPAGE_WIKI);
3123 void MainWindow::on_actionHelpSampleCaptures_triggered() {
3125 wsApp->helpTopicAction(ONLINEPAGE_SAMPLE_FILES);
3128 #ifdef HAVE_SOFTWARE_UPDATE
3129 void MainWindow::checkForUpdates()
3131 software_update_check();
3135 void MainWindow::on_actionHelpAbout_triggered()
3137 AboutDialog *about_dialog = new AboutDialog(this);
3139 if (about_dialog->isMinimized() == true)
3141 about_dialog->showNormal();
3145 about_dialog->show();
3148 about_dialog->raise();
3149 about_dialog->activateWindow();
3152 void MainWindow::on_actionGoGoToPacket_triggered() {
3153 if (packet_list_->model()->rowCount() < 1) {
3156 previous_focus_ = wsApp->focusWidget();
3157 connect(previous_focus_, SIGNAL(destroyed()), this, SLOT(resetPreviousFocus()));
3159 showAccordionFrame(main_ui_->goToFrame, true);
3160 if (main_ui_->goToFrame->isVisible()) {
3161 main_ui_->goToLineEdit->clear();
3162 main_ui_->goToLineEdit->setFocus();
3166 void MainWindow::on_actionGoGoToLinkedPacket_triggered()
3168 QAction *gta = qobject_cast<QAction*>(sender());
3172 int packet_num = gta->data().toInt(&ok);
3175 packet_list_->goToPacket(packet_num);
3178 void MainWindow::on_actionGoAutoScroll_toggled(bool checked)
3180 packet_list_->setAutoScroll(checked);
3183 void MainWindow::resetPreviousFocus() {
3184 previous_focus_ = NULL;
3187 void MainWindow::on_goToCancel_clicked()
3189 main_ui_->goToFrame->animatedHide();
3190 if (previous_focus_) {
3191 disconnect(previous_focus_, SIGNAL(destroyed()), this, SLOT(resetPreviousFocus()));
3192 previous_focus_->setFocus();
3193 resetPreviousFocus();
3197 void MainWindow::on_goToGo_clicked()
3199 gotoFrame(main_ui_->goToLineEdit->text().toInt());
3201 on_goToCancel_clicked();
3204 void MainWindow::on_goToLineEdit_returnPressed()
3206 on_goToGo_clicked();
3209 void MainWindow::on_actionCaptureStart_triggered()
3211 //#ifdef HAVE_AIRPCAP
3212 // airpcap_if_active = airpcap_if_selected;
3213 // if (airpcap_if_active)
3214 // airpcap_set_toolbar_start_capture(airpcap_if_active);
3217 // if (cap_open_w) {
3219 // * There's an options dialog; get the values from it and close it.
3221 // gboolean success;
3223 // /* Determine if "capture start" while building of the "capture options" window */
3224 // /* is in progress. If so, ignore the "capture start. */
3225 // /* XXX: Would it be better/cleaner for the "capture options" window code to */
3226 // /* disable the capture start button temporarily ? */
3227 // if (cap_open_complete == FALSE) {
3228 // return; /* Building options window: ignore "capture start" */
3230 // success = capture_dlg_prep(cap_open_w);
3231 // window_destroy(GTK_WIDGET(cap_open_w));
3233 // return; /* error in options dialog */
3237 if (global_capture_opts.num_selected == 0) {
3238 QString err_msg = tr("No Interface Selected");
3239 main_ui_->statusBar->pushTemporaryStatus(err_msg);
3240 main_ui_->actionCaptureStart->setChecked(false);
3244 /* XXX - will closing this remove a temporary file? */
3245 QString before_what(tr(" before starting a new capture"));
3246 if (testCaptureFileClose(FALSE, before_what)) {
3249 // simply clicking the button sets it to 'checked' even though we've
3250 // decided to do nothing, so undo that
3251 main_ui_->actionCaptureStart->setChecked(false);
3253 #endif // HAVE_LIBPCAP
3256 void MainWindow::on_actionCaptureStop_triggered()
3261 void MainWindow::on_actionCaptureRestart_triggered()
3263 /* TODO: GTK use only this: capture_restart(&cap_session_); */
3268 static FilterDialog *capture_filter_dlg_ = NULL;
3269 void MainWindow::on_actionCaptureCaptureFilters_triggered()
3271 if (!capture_filter_dlg_) {
3272 capture_filter_dlg_ = new FilterDialog(this, FilterDialog::CaptureFilter);
3274 capture_filter_dlg_->show();
3275 capture_filter_dlg_->raise();
3276 capture_filter_dlg_->activateWindow();
3279 void MainWindow::on_actionStatisticsCaptureFileProperties_triggered()
3281 CaptureFilePropertiesDialog *capture_file_properties_dialog = new CaptureFilePropertiesDialog(*this, capture_file_);
3282 connect(capture_file_properties_dialog, SIGNAL(captureCommentChanged()),
3283 this, SLOT(updateForUnsavedChanges()));
3284 capture_file_properties_dialog->show();
3287 void MainWindow::on_actionStatisticsResolvedAddresses_triggered()
3289 ResolvedAddressesDialog *resolved_addresses_dialog = new ResolvedAddressesDialog(this, &capture_file_);
3290 resolved_addresses_dialog->show();
3293 void MainWindow::on_actionStatisticsProtocolHierarchy_triggered()
3295 ProtocolHierarchyDialog *phd = new ProtocolHierarchyDialog(*this, capture_file_);
3296 connect(phd, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
3297 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
3302 void MainWindow::on_actionCaptureOptions_triggered()
3304 connect(&capture_interfaces_dialog_, SIGNAL(setFilterValid(bool)), this, SLOT(startInterfaceCapture(bool)));
3305 capture_interfaces_dialog_.SetTab(0);
3306 capture_interfaces_dialog_.updateInterfaces();
3308 if (capture_interfaces_dialog_.isMinimized() == true)
3310 capture_interfaces_dialog_.showNormal();
3314 capture_interfaces_dialog_.show();
3317 capture_interfaces_dialog_.raise();
3318 capture_interfaces_dialog_.activateWindow();
3321 void MainWindow::on_actionCaptureRefreshInterfaces_triggered()
3323 wsApp->refreshLocalInterfaces();
3327 void MainWindow::externalMenuItem_triggered()
3329 QAction * triggerAction = NULL;
3331 ext_menubar_t * entry = NULL;
3333 if ( QObject::sender() != NULL)
3335 triggerAction = (QAction *)QObject::sender();
3336 v = triggerAction->data();
3338 if ( v.canConvert<void *>())
3340 entry = (ext_menubar_t *)v.value<void *>();
3342 if ( entry->type == EXT_MENUBAR_ITEM )
3344 entry->callback(EXT_MENUBAR_QT_GUI, (gpointer) ((void *)main_ui_), entry->user_data);
3348 QDesktopServices::openUrl(QUrl(QString((gchar *)entry->user_data)));
3354 void MainWindow::gotoFrame(int packet_num)
3356 if ( packet_num > 0 )
3358 packet_list_->goToPacket(packet_num);
3363 void MainWindow::extcap_options_finished(int result)
3365 if ( result == QDialog::Accepted )
3369 this->main_welcome_->getInterfaceTree()->interfaceListChanged();
3372 void MainWindow::showExtcapOptionsDialog(QString &device_name)
3374 ExtcapOptionsDialog * extcap_options_dialog = ExtcapOptionsDialog::createForDevice(device_name, this);
3375 /* The dialog returns null, if the given device name is not a valid extcap device */
3376 if ( extcap_options_dialog != NULL )
3378 connect(extcap_options_dialog, SIGNAL(finished(int)),
3379 this, SLOT(extcap_options_finished(int)));
3380 extcap_options_dialog->show();
3385 // Q_DECLARE_METATYPE(field_info *) called in proto_tree.h
3387 void MainWindow::on_actionContextCopyBytesHexTextDump_triggered()
3389 QAction *ca = qobject_cast<QAction*>(sender());
3392 field_info *fi = ca->data().value<field_info *>();
3394 byte_view_tab_->copyData(ByteViewTab::copyDataHexTextDump, fi);
3397 void MainWindow::on_actionContextCopyBytesHexDump_triggered()
3399 QAction *ca = qobject_cast<QAction*>(sender());
3402 field_info *fi = ca->data().value<field_info *>();
3404 byte_view_tab_->copyData(ByteViewTab::copyDataHexDump, fi);
3407 void MainWindow::on_actionContextCopyBytesPrintableText_triggered()
3409 QAction *ca = qobject_cast<QAction*>(sender());
3412 field_info *fi = ca->data().value<field_info *>();
3414 byte_view_tab_->copyData(ByteViewTab::copyDataPrintableText, fi);
3417 void MainWindow::on_actionContextCopyBytesHexStream_triggered()
3419 QAction *ca = qobject_cast<QAction*>(sender());
3422 field_info *fi = ca->data().value<field_info *>();
3424 byte_view_tab_->copyData(ByteViewTab::copyDataHexStream, fi);
3427 void MainWindow::on_actionContextCopyBytesBinary_triggered()
3429 QAction *ca = qobject_cast<QAction*>(sender());
3432 field_info *fi = ca->data().value<field_info *>();
3434 byte_view_tab_->copyData(ByteViewTab::copyDataBinary, fi);
3437 void MainWindow::on_actionContextWikiProtocolPage_triggered()
3439 QAction *wa = qobject_cast<QAction*>(sender());
3443 int field_id = wa->data().toInt(&ok);
3446 const QString proto_abbrev = proto_registrar_get_abbrev(field_id);
3448 int ret = QMessageBox::question(this, wsApp->windowTitleString(tr("Wiki Page for %1").arg(proto_abbrev)),
3449 tr("<p>The Wireshark Wiki is maintained by the community.</p>"
3450 "<p>The page you are about to load might be wonderful, "
3451 "incomplete, wrong, or nonexistent.</p>"
3452 "<p>Proceed to the wiki?</p>"),
3453 QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
3455 if (ret != QMessageBox::Yes) return;
3457 QUrl wiki_url = QString("https://wiki.wireshark.org/Protocols/%1").arg(proto_abbrev);
3458 QDesktopServices::openUrl(wiki_url);
3461 void MainWindow::on_actionContextFilterFieldReference_triggered()
3463 QAction *wa = qobject_cast<QAction*>(sender());
3467 int field_id = wa->data().toInt(&ok);
3470 const QString proto_abbrev = proto_registrar_get_abbrev(field_id);
3472 QUrl dfref_url = QString("https://www.wireshark.org/docs/dfref/%1/%2")
3473 .arg(proto_abbrev[0])
3475 QDesktopServices::openUrl(dfref_url);
3484 * indent-tabs-mode: nil
3487 * ex: set shiftwidth=4 tabstop=8 expandtab:
3488 * :indentSize=4:tabSize=8:noTabs=true: