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 // Qt 5.5.0 + Visual C++ 2013
35 #pragma warning(disable:4996)
38 #include "main_window.h"
39 #include <ui_main_window.h>
47 #include "ui/capture.h"
50 #include "color_filters.h"
52 #include "wsutil/file_util.h"
53 #include "wsutil/filesystem.h"
54 #include <wsutil/str_util.h>
56 #include "epan/addr_resolv.h"
57 #include "epan/color_dissector_filters.h"
58 #include "epan/column.h"
59 #include "epan/dfilter/dfilter-macro.h"
60 #include "epan/epan_dissect.h"
61 #include "epan/filter_expressions.h"
62 #include "epan/prefs.h"
64 #include "epan/value_string.h"
67 #include <epan/wslua/init_wslua.h>
70 #include "ui/alert_box.h"
72 #include "ui/capture_ui_utils.h"
75 #include "ui/capture_globals.h"
76 #include "ui/help_url.h"
77 #include "ui/main_statusbar.h"
78 #include "ui/preference_utils.h"
79 #include "ui/recent.h"
80 #include "ui/recent_utils.h"
81 #include "ui/ssl_key_export.h"
82 #include "ui/ui_util.h"
83 #include "ui/qt/simple_dialog.h"
85 #ifdef HAVE_SOFTWARE_UPDATE
86 #include "ui/software_update.h"
89 #include "about_dialog.h"
90 #include "bluetooth_att_server_attributes_dialog.h"
91 #include "bluetooth_devices_dialog.h"
92 #include "bluetooth_hci_summary_dialog.h"
93 #include "capture_file_dialog.h"
94 #include "capture_file_properties_dialog.h"
95 #include "color_utils.h"
96 #include "coloring_rules_dialog.h"
97 #include "conversation_dialog.h"
98 #include "conversation_hash_tables_dialog.h"
99 #include "enabled_protocols_dialog.h"
100 #include "decode_as_dialog.h"
101 #include "display_filter_edit.h"
102 #include "display_filter_expression_dialog.h"
103 #include "dissector_tables_dialog.h"
104 #include "endpoint_dialog.h"
105 #include "expert_info_dialog.h"
106 #include "export_object_dialog.h"
107 #include "export_pdu_dialog.h"
109 #include "extcap_options_dialog.h"
111 #include "filter_action.h"
112 #include "filter_dialog.h"
113 #include "funnel_statistics.h"
114 #include "gsm_map_summary_dialog.h"
115 #include "iax2_analysis_dialog.h"
116 #include "io_graph_dialog.h"
117 #include "lbm_stream_dialog.h"
118 #include "lbm_uimflow_dialog.h"
119 #include "lbm_lbtrm_transport_dialog.h"
120 #include "lbm_lbtru_transport_dialog.h"
121 #include "lte_mac_statistics_dialog.h"
122 #include "lte_rlc_statistics_dialog.h"
123 #include "lte_rlc_graph_dialog.h"
124 #include "mtp3_summary_dialog.h"
125 #include "multicast_statistics_dialog.h"
126 #include "packet_comment_dialog.h"
127 #include "packet_dialog.h"
128 #include "packet_list.h"
129 #include "preferences_dialog.h"
130 #include "print_dialog.h"
131 #include "profile_dialog.h"
132 #include "protocol_hierarchy_dialog.h"
133 #include "qt_ui_utils.h"
134 #include "resolved_addresses_dialog.h"
135 #include "rpc_service_response_time_dialog.h"
136 #include "rtp_stream_dialog.h"
137 #include "rtp_analysis_dialog.h"
138 #include "sctp_all_assocs_dialog.h"
139 #include "sctp_assoc_analyse_dialog.h"
140 #include "sctp_graph_dialog.h"
141 #include "sequence_dialog.h"
142 #include "stats_tree_dialog.h"
143 #include "stock_icon.h"
144 #include "supported_protocols_dialog.h"
145 #include "tap_parameter_dialog.h"
146 #include "tcp_stream_dialog.h"
147 #include "time_shift_dialog.h"
148 #include "uat_dialog.h"
149 #include "voip_calls_dialog.h"
150 #include "wireshark_application.h"
151 #include "wlan_statistics_dialog.h"
153 #include <QClipboard>
155 #include <QMessageBox>
156 #include <QMetaObject>
158 #include <QDesktopServices>
166 static const char *dfe_property_ = "display filter expression"; //TODO : Fix Translate
168 // We're too lazy to sublcass QAction.
169 static const char *color_number_property_ = "color number";
171 bool MainWindow::openCaptureFile(QString cf_path, QString read_filter, unsigned int type)
173 QString file_name = "";
174 dfilter_t *rfcode = NULL;
179 // was a file name given as function parameter?
180 name_param = !cf_path.isEmpty();
184 if (cf_path.isEmpty()) {
185 CaptureFileDialog open_dlg(this, capture_file_.capFile(), read_filter);
187 switch (prefs.gui_fileopen_style) {
189 case FO_STYLE_LAST_OPENED:
190 /* The user has specified that we should start out in the last directory
191 we looked in. If we've already opened a file, use its containing
192 directory, if we could determine it, as the directory, otherwise
193 use the "last opened" directory saved in the preferences file if
195 /* This is now the default behaviour in file_selection_new() */
198 case FO_STYLE_SPECIFIED:
199 /* The user has specified that we should always start out in a
200 specified directory; if they've specified that directory,
201 start out by showing the files in that dir. */
202 if (prefs.gui_fileopen_dir[0] != '\0')
203 open_dlg.setDirectory(prefs.gui_fileopen_dir);
207 if (open_dlg.open(file_name, type)) {
214 if (!testCaptureFileClose(false)) {
218 if (dfilter_compile(read_filter.toUtf8().constData(), &rfcode, &err_msg)) {
219 cf_set_rfcode(CaptureFile::globalCapFile(), rfcode);
221 /* Not valid. Tell the user, and go back and run the file
222 selection box again once they dismiss the alert. */
223 //bad_dfilter_alert_box(top_level, read_filter->str);
224 QMessageBox::warning(this, tr("Invalid Display Filter"),
225 QString("The filter expression ") +
227 QString(" isn't a valid display filter. (") +
228 err_msg + QString(")."),
232 // go back to the selection dialogue only if the file
233 // was selected from this dialogue
239 /* Try to open the capture file. This closes the current file if it succeeds. */
240 CaptureFile::globalCapFile()->window = this;
241 if (cf_open(CaptureFile::globalCapFile(), cf_path.toUtf8().constData(), type, FALSE, &err) != CF_OK) {
242 /* We couldn't open it; don't dismiss the open dialog box,
243 just leave it around so that the user can, after they
244 dismiss the alert box popped up for the open error,
246 CaptureFile::globalCapFile()->window = NULL;
248 dfilter_free(rfcode);
253 switch (cf_read(CaptureFile::globalCapFile(), FALSE)) {
257 /* Just because we got an error, that doesn't mean we were unable
258 to read any of the file; we handle what we could get from the
262 case CF_READ_ABORTED:
263 /* The user bailed out of re-reading the capture file; the
264 capture file has been closed - just free the capture file name
265 string and return (without changing the last containing
267 capture_file_.setCapFile(NULL);
272 // get_dirname overwrites its path. Hopefully this isn't a problem.
273 wsApp->setLastOpenDir(get_dirname(cf_path.toUtf8().data()));
275 main_ui_->statusBar->showExpert();
280 void MainWindow::filterPackets(QString new_filter, bool force)
282 cf_status_t cf_status;
284 cf_status = cf_filter_packets(CaptureFile::globalCapFile(), new_filter.toUtf8().data(), force);
286 if (cf_status == CF_OK) {
287 emit displayFilterSuccess(true);
288 if (new_filter.length() > 0) {
289 int index = df_combo_box_->findText(new_filter);
291 df_combo_box_->insertItem(0, new_filter);
292 df_combo_box_->setCurrentIndex(0);
294 df_combo_box_->setCurrentIndex(index);
297 df_combo_box_->lineEdit()->clear();
300 emit displayFilterSuccess(false);
304 // A new layout should be applied when it differs from the old layout AND
305 // at the following times:
307 // - When the preferences change
308 // - When the profile changes
309 void MainWindow::layoutPanes()
311 QVector<unsigned> new_layout = QVector<unsigned>() << prefs.gui_layout_type
312 << prefs.gui_layout_content_1
313 << prefs.gui_layout_content_2
314 << prefs.gui_layout_content_3;
315 if (cur_layout_ == new_layout) return;
317 QSplitter *parents[3];
318 int current_row = capture_file_.currentRow();
320 // Reparent all widgets and add them back in the proper order below.
321 // This hides each widget as well.
322 packet_list_->freeze(); // Clears tree and byte view tabs.
323 packet_list_->setParent(main_ui_->mainStack);
324 proto_tree_->setParent(main_ui_->mainStack);
325 byte_view_tab_->setParent(main_ui_->mainStack);
326 empty_pane_.setParent(main_ui_->mainStack);
327 extra_split_.setParent(main_ui_->mainStack);
329 // XXX We should try to preserve geometries if we can, e.g. by
330 // checking to see if the layout type is the same.
331 switch(prefs.gui_layout_type) {
334 extra_split_.setOrientation(Qt::Horizontal);
337 master_split_.setOrientation(Qt::Vertical);
342 extra_split_.setOrientation(Qt::Vertical);
345 master_split_.setOrientation(Qt::Horizontal);
349 g_assert_not_reached();
352 switch(prefs.gui_layout_type) {
355 parents[0] = &master_split_;
356 parents[1] = &master_split_;
357 parents[2] = &master_split_;
361 parents[0] = &master_split_;
362 parents[1] = &extra_split_;
363 parents[2] = &extra_split_;
367 parents[0] = &extra_split_;
368 parents[1] = &extra_split_;
369 parents[2] = &master_split_;
372 g_assert_not_reached();
375 if (parents[0] == &extra_split_) {
376 master_split_.addWidget(&extra_split_);
379 parents[0]->addWidget(getLayoutWidget(prefs.gui_layout_content_1));
381 if (parents[2] == &extra_split_) {
382 master_split_.addWidget(&extra_split_);
385 parents[1]->addWidget(getLayoutWidget(prefs.gui_layout_content_2));
386 parents[2]->addWidget(getLayoutWidget(prefs.gui_layout_content_3));
388 const QList<QWidget *> ms_children = master_split_.findChildren<QWidget *>();
390 extra_split_.setVisible(ms_children.contains(&extra_split_));
391 packet_list_->setVisible(ms_children.contains(packet_list_) && recent.packet_list_show);
392 proto_tree_->setVisible(ms_children.contains(proto_tree_) && recent.tree_view_show);
393 byte_view_tab_->setVisible(ms_children.contains(byte_view_tab_) && recent.byte_view_show);
395 packet_list_->thaw();
396 cf_select_packet(capture_file_.capFile(), current_row); // XXX Doesn't work for row 0?
397 cur_layout_ = new_layout;
400 // The recent layout geometry should be applied after the layout has been
401 // applied AND at the following times:
403 // - When the profile changes
404 void MainWindow::applyRecentPaneGeometry()
406 // XXX This shrinks slightly each time the application is run. For some
407 // reason the master_split_ geometry is two pixels shorter when
408 // saveWindowGeometry is invoked.
410 // This is also an awful lot of trouble to go through to reuse the GTK+
411 // pane settings. We might want to add gui.geometry_main_master_sizes
412 // and gui.geometry_main_extra_sizes and save QSplitter::saveState in
415 // Force a geometry recalculation
416 QWidget *cur_w = main_ui_->mainStack->currentWidget();
417 main_ui_->mainStack->setCurrentWidget(&master_split_);
418 QRect geom = master_split_.geometry();
419 QList<int> master_sizes = master_split_.sizes();
420 QList<int> extra_sizes = extra_split_.sizes();
421 main_ui_->mainStack->setCurrentWidget(cur_w);
423 int master_last_size = master_split_.orientation() == Qt::Vertical ? geom.height() : geom.width();
424 int extra_last_size = extra_split_.orientation() == Qt::Vertical ? geom.height() : geom.width();
426 if (recent.gui_geometry_main_upper_pane > 0) {
427 master_sizes[0] = recent.gui_geometry_main_upper_pane + 1; // Add back mystery pixel
428 master_last_size -= recent.gui_geometry_main_upper_pane + master_split_.handleWidth();
431 if (recent.gui_geometry_main_lower_pane > 0) {
432 if (master_sizes.length() > 2) {
433 master_sizes[1] = recent.gui_geometry_main_lower_pane + 1; // Add back mystery pixel
434 master_last_size -= recent.gui_geometry_main_lower_pane + master_split_.handleWidth();
435 } else if (extra_sizes.length() > 0) {
436 extra_sizes[0] = recent.gui_geometry_main_lower_pane; // No mystery pixel
437 extra_last_size -= recent.gui_geometry_main_lower_pane + extra_split_.handleWidth();
438 extra_sizes.last() = extra_last_size;
442 master_sizes.last() = master_last_size;
444 master_split_.setSizes(master_sizes);
445 extra_split_.setSizes(extra_sizes);
448 void MainWindow::layoutToolbars()
450 Qt::ToolButtonStyle tbstyle = Qt::ToolButtonIconOnly;
451 switch (prefs.gui_toolbar_main_style) {
453 tbstyle = Qt::ToolButtonTextOnly;
456 tbstyle = Qt::ToolButtonTextUnderIcon;
460 main_ui_->mainToolBar->setToolButtonStyle(tbstyle);
463 void MainWindow::updatePreferenceActions()
465 main_ui_->actionViewNameResolutionPhysical->setChecked(gbl_resolv_flags.mac_name);
466 main_ui_->actionViewNameResolutionNetwork->setChecked(gbl_resolv_flags.network_name);
467 main_ui_->actionViewNameResolutionTransport->setChecked(gbl_resolv_flags.transport_name);
469 // Should this be a "recent" setting?
470 main_ui_->actionGoAutoScroll->setChecked(prefs.capture_auto_scroll);
473 void MainWindow::filterAction(QString &action_filter, FilterAction::Action action, FilterAction::ActionType type)
475 QString cur_filter, new_filter;
477 if (!df_combo_box_) return;
478 cur_filter = df_combo_box_->lineEdit()->text();
481 case FilterAction::ActionTypePlain:
482 new_filter = action_filter;
484 case FilterAction::ActionTypeAnd:
485 if (cur_filter.length()) {
486 new_filter = "(" + cur_filter + ") && (" + action_filter + ")";
488 new_filter = action_filter;
491 case FilterAction::ActionTypeOr:
492 if (cur_filter.length()) {
493 new_filter = "(" + cur_filter + ") || (" + action_filter + ")";
495 new_filter = action_filter;
498 case FilterAction::ActionTypeNot:
499 new_filter = "!(" + action_filter + ")";
501 case FilterAction::ActionTypeAndNot:
502 if (cur_filter.length()) {
503 new_filter = "(" + cur_filter + ") && !(" + action_filter + ")";
505 new_filter = "!(" + action_filter + ")";
508 case FilterAction::ActionTypeOrNot:
509 if (cur_filter.length()) {
510 new_filter = "(" + cur_filter + ") || !(" + action_filter + ")";
512 new_filter = "!(" + action_filter + ")";
516 g_assert_not_reached();
521 case FilterAction::ActionApply:
522 df_combo_box_->lineEdit()->setText(new_filter);
523 df_combo_box_->applyDisplayFilter();
525 case FilterAction::ActionPrepare:
526 df_combo_box_->lineEdit()->setText(new_filter);
527 df_combo_box_->lineEdit()->setFocus();
529 case FilterAction::ActionWebLookup:
531 QString url = QString("https://www.google.com/search?q=") + new_filter;
532 QDesktopServices::openUrl(QUrl(url));
535 case FilterAction::ActionCopy:
536 wsApp->clipboard()->setText(new_filter);
539 qDebug() << "FIX FilterAction::Action" << action << "not implemented";
546 void MainWindow::captureCapturePrepared(capture_session *) {
548 setTitlebarForCaptureInProgress();
550 setWindowIcon(wsApp->captureIcon());
552 /* Disable menu items that make no sense if you're currently running
554 setForCaptureInProgress(true);
555 // set_capture_if_dialog_for_capture_in_progress(TRUE);
557 // /* Don't set up main window for a capture file. */
558 // main_set_for_capture_file(FALSE);
559 main_ui_->mainStack->setCurrentWidget(&master_split_);
560 #endif // HAVE_LIBPCAP
563 void MainWindow::captureCaptureUpdateStarted(capture_session *) {
566 /* We've done this in "prepared" above, but it will be cleared while
567 switching to the next multiple file. */
568 setTitlebarForCaptureInProgress();
570 setForCaptureInProgress(true);
572 setForCapturedPackets(true);
573 #endif // HAVE_LIBPCAP
575 void MainWindow::captureCaptureUpdateFinished(capture_session *) {
578 /* The capture isn't stopping any more - it's stopped. */
579 capture_stopping_ = false;
581 /* Update the main window as appropriate */
582 updateForUnsavedChanges();
584 /* Enable menu items that make sense if you're not currently running
586 setForCaptureInProgress(false);
588 setWindowIcon(wsApp->normalIcon());
590 if (global_capture_opts.quit_after_cap) {
591 // Command line asked us to quit after capturing.
592 // Don't pop up a dialog to ask for unsaved files etc.
595 #endif // HAVE_LIBPCAP
597 void MainWindow::captureCaptureFixedStarted(capture_session *) {
599 #endif // HAVE_LIBPCAP
601 void MainWindow::captureCaptureFixedFinished(capture_session *) {
604 /* The capture isn't stopping any more - it's stopped. */
605 capture_stopping_ = false;
607 /* Enable menu items that make sense if you're not currently running
609 setForCaptureInProgress(false);
611 setWindowIcon(wsApp->normalIcon());
613 if (global_capture_opts.quit_after_cap) {
614 // Command line asked us to quit after capturing.
615 // Don't pop up a dialog to ask for unsaved files etc.
618 #endif // HAVE_LIBPCAP
620 void MainWindow::captureCaptureStopping(capture_session *) {
623 capture_stopping_ = true;
624 setMenusForCaptureStopping();
625 #endif // HAVE_LIBPCAP
627 void MainWindow::captureCaptureFailed(capture_session *) {
629 /* Capture isn't stopping any more. */
630 capture_stopping_ = false;
632 setForCaptureInProgress(false);
633 main_ui_->mainStack->setCurrentWidget(main_welcome_);
635 setWindowIcon(wsApp->normalIcon());
637 if (global_capture_opts.quit_after_cap) {
638 // Command line asked us to quit after capturing.
639 // Don't pop up a dialog to ask for unsaved files etc.
642 #endif // HAVE_LIBPCAP
646 // Callbacks from cfile.c and file.c via CaptureFile::captureFileCallback
648 void MainWindow::captureFileOpened() {
649 if (capture_file_.window() != this) return;
651 file_set_dialog_.fileOpened(capture_file_.capFile());
652 setMenusForFileSet(true);
653 emit setCaptureFile(capture_file_.capFile());
656 void MainWindow::captureFileReadStarted(const QString &action) {
657 // tap_param_dlg_update();
659 /* Set up main window for a capture file. */
660 // main_set_for_capture_file(TRUE);
662 main_ui_->statusBar->popFileStatus();
663 QString msg = QString(tr("%1: %2")).arg(action).arg(capture_file_.fileName());
664 QString msgtip = QString();
665 main_ui_->statusBar->pushFileStatus(msg, msgtip);
666 main_ui_->mainStack->setCurrentWidget(&master_split_);
667 WiresharkApplication::processEvents();
670 void MainWindow::captureFileReadFinished() {
673 if (!capture_file_.capFile()->is_tempfile && capture_file_.capFile()->filename) {
674 /* Add this filename to the list of recent files in the "Recent Files" submenu */
675 add_menu_recent_capture_file(capture_file_.capFile()->filename);
677 /* Remember folder for next Open dialog and save it in recent */
678 dir_path = get_dirname(g_strdup(capture_file_.capFile()->filename));
679 wsApp->setLastOpenDir(dir_path);
683 /* Update the appropriate parts of the main window. */
684 updateForUnsavedChanges();
686 /* Enable menu items that make sense if you have some captured packets. */
687 setForCapturedPackets(true);
689 main_ui_->statusBar->setFileName(capture_file_);
691 packet_list_->captureFileReadFinished();
693 emit setDissectedCaptureFile(capture_file_.capFile());
696 // Our event loop becomes nested whenever we call update_progress_dlg, which
697 // includes several places in file.c. The GTK+ UI stays out of trouble by
698 // showing a modal progress dialog. We attempt to do the equivalent below by
699 // disabling parts of the main window. At a minumum the ProgressFrame in the
700 // main status bar must remain accessible.
702 // We might want to do this any time the main status bar progress frame is
704 void MainWindow::captureFileRetapStarted()
706 // XXX Push a status message?
707 main_ui_->actionFileClose->setEnabled(false);
708 main_ui_->actionViewReload->setEnabled(false);
709 main_ui_->centralWidget->setEnabled(false);
712 void MainWindow::captureFileRetapFinished()
714 main_ui_->actionFileClose->setEnabled(true);
715 main_ui_->actionViewReload->setEnabled(true);
716 main_ui_->centralWidget->setEnabled(true);
719 void MainWindow::captureFileClosing() {
720 setMenusForCaptureFile(true);
721 setForCapturedPackets(false);
722 setMenusForSelectedPacket();
723 setForCaptureInProgress(false);
725 // Reset expert information indicator
726 main_ui_->statusBar->captureFileClosing();
727 main_ui_->searchFrame->animatedHide();
728 // gtk_widget_show(expert_info_none);
729 emit setCaptureFile(NULL);
730 emit setDissectedCaptureFile(NULL);
733 void MainWindow::captureFileClosed() {
734 packets_bar_update();
736 file_set_dialog_.fileClosed();
737 setMenusForFileSet(false);
739 // Reset expert information indicator
740 main_ui_->statusBar->captureFileClosing();
742 main_ui_->statusBar->popFileStatus();
744 setTitlebarForSelectedTreeRow();
745 setMenusForSelectedTreeRow();
747 if (!global_capture_opts.multi_files_on)
748 main_ui_->mainStack->setCurrentWidget(main_welcome_);
751 void MainWindow::captureFileSaveStarted(const QString &file_path)
753 QFileInfo file_info(file_path);
754 main_ui_->statusBar->popFileStatus();
755 main_ui_->statusBar->pushFileStatus(tr("Saving %1" UTF8_HORIZONTAL_ELLIPSIS).arg(file_info.baseName()));
758 void MainWindow::filterExpressionsChanged()
760 // Recreate filter buttons
761 foreach (QAction *act, main_ui_->displayFilterToolBar->actions()) {
762 // Permanent actions shouldn't have data
763 if (act->property(dfe_property_).isValid() || act->isSeparator()) {
764 main_ui_->displayFilterToolBar->removeAction(act);
770 for (struct filter_expression *fe = *pfilter_expression_head; fe != NULL; fe = fe->next) {
771 if (!fe->enabled) continue;
772 QAction *dfb_action = new QAction(fe->label, main_ui_->displayFilterToolBar);
773 dfb_action->setToolTip(fe->expression);
774 dfb_action->setData(fe->expression);
775 dfb_action->setProperty(dfe_property_, true);
776 main_ui_->displayFilterToolBar->addAction(dfb_action);
777 connect(dfb_action, SIGNAL(triggered()), this, SLOT(displayFilterButtonClicked()));
780 main_ui_->displayFilterToolBar->insertSeparator(dfb_action);
789 // ui/gtk/capture_dlg.c:start_capture_confirmed
791 void MainWindow::startCapture() {
793 interface_options interface_opts;
796 /* did the user ever select a capture interface before? */
797 if(global_capture_opts.num_selected == 0) {
798 QString msg = QString(tr("No interface selected"));
799 main_ui_->statusBar->pushTemporaryStatus(msg);
800 main_ui_->actionCaptureStart->setChecked(false);
804 main_ui_->mainStack->setCurrentWidget(&master_split_);
806 // Ideally we should have disabled the start capture
807 // toolbar buttons and menu items. This may not be the
808 // case, e.g. with QtMacExtras.
809 if(!capture_filter_valid_) {
810 QString msg = QString(tr("Invalid capture filter"));
811 main_ui_->statusBar->pushTemporaryStatus(msg);
812 main_ui_->actionCaptureStart->setChecked(false);
816 /* XXX - we might need to init other pref data as well... */
818 /* XXX - can this ever happen? */
819 if (cap_session_.state != CAPTURE_STOPPED)
822 /* close the currently loaded capture file */
823 cf_close((capture_file *) cap_session_.cf);
825 /* Copy the selected interfaces to the set of interfaces to use for
827 collect_ifaces(&global_capture_opts);
829 CaptureFile::globalCapFile()->window = this;
830 if (capture_start(&global_capture_opts, &cap_session_, main_window_update)) {
831 capture_options *capture_opts = cap_session_.capture_opts;
832 GString *interface_names;
834 /* enable autoscroll timer as needed. */
835 packet_list_->setAutoScroll(main_ui_->actionGoAutoScroll->isChecked());
837 /* Add "interface name<live capture in progress>" on main status bar */
838 interface_names = get_iface_list_string(capture_opts, 0);
839 if (strlen (interface_names->str) > 0) {
840 g_string_append(interface_names, ":");
842 g_string_append(interface_names, " ");
844 main_ui_->statusBar->popFileStatus();
845 QString msg = QString().sprintf("%s<live capture in progress>", interface_names->str);
846 QString msgtip = QString().sprintf("to file: %s", (capture_opts->save_file) ? capture_opts->save_file : "");
847 main_ui_->statusBar->pushFileStatus(msg, msgtip);
848 g_string_free(interface_names, TRUE);
850 /* The capture succeeded, which means the capture filter syntax is
851 valid; add this capture filter to the recent capture filter list. */
852 for (i = 0; i < global_capture_opts.ifaces->len; i++) {
853 interface_opts = g_array_index(global_capture_opts.ifaces, interface_options, i);
854 if (interface_opts.cfilter) {
855 // cfilter_combo_add_recent(interface_opts.cfilter);
859 CaptureFile::globalCapFile()->window = NULL;
861 #endif // HAVE_LIBPCAP
864 // Copied from ui/gtk/gui_utils.c
865 void MainWindow::pipeTimeout() {
869 gboolean result, result1;
874 /* try to read data from the pipe only 5 times, to avoid blocking */
875 while(iterations < 5) {
876 /*g_log(NULL, G_LOG_LEVEL_DEBUG, "pipe_timer_cb: new iteration");*/
878 /* Oddly enough although Named pipes don't work on win9x,
879 PeekNamedPipe does !!! */
880 handle = (HANDLE) _get_osfhandle (pipe_source_);
881 result = PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL);
883 /* Get the child process exit status */
884 result1 = GetExitCodeProcess((HANDLE)*(pipe_child_process_),
887 /* If the Peek returned an error, or there are bytes to be read
888 or the childwatcher thread has terminated then call the normal
890 if (!result || avail > 0 || childstatus != STILL_ACTIVE) {
892 /*g_log(NULL, G_LOG_LEVEL_DEBUG, "pipe_timer_cb: data avail");*/
894 /* And call the real handler */
895 if (!pipe_input_cb_(pipe_source_, pipe_user_data_)) {
896 g_log(NULL, G_LOG_LEVEL_DEBUG, "pipe_timer_cb: input pipe closed, iterations: %u", iterations);
897 /* pipe closed, return false so that the old timer is not run again */
903 /*g_log(NULL, G_LOG_LEVEL_DEBUG, "pipe_timer_cb: no data avail");*/
904 /* No data, stop now */
913 void MainWindow::pipeActivated(int source) {
917 g_assert(source == pipe_source_);
919 pipe_notifier_->setEnabled(false);
920 if (pipe_input_cb_(pipe_source_, pipe_user_data_)) {
921 pipe_notifier_->setEnabled(true);
923 delete pipe_notifier_;
928 void MainWindow::pipeNotifierDestroyed() {
932 pipe_notifier_ = NULL;
936 void MainWindow::stopCapture() {
937 //#ifdef HAVE_AIRPCAP
938 // if (airpcap_if_active)
939 // airpcap_set_toolbar_stop_capture(airpcap_if_active);
943 capture_stop(&cap_session_);
944 #endif // HAVE_LIBPCAP
946 /* Pop the "<live capture in progress>" message off the status bar. */
947 main_ui_->statusBar->setFileName(capture_file_);
949 /* disable autoscroll timer if any. */
950 packet_list_->setAutoScroll(false);
953 // Keep focus rects from showing through the welcome screen. Primarily for
955 void MainWindow::mainStackChanged(int)
957 for (int i = 0; i < main_ui_->mainStack->count(); i++) {
958 main_ui_->mainStack->widget(i)->setEnabled(i == main_ui_->mainStack->currentIndex());
962 // XXX - Copied from ui/gtk/menus.c
965 * Add the capture filename (with an absolute path) to the "Recent Files" menu.
967 // XXX - We should probably create a RecentFile class.
968 void MainWindow::updateRecentFiles() {
970 QMenu *recentMenu = main_ui_->menuOpenRecentCaptureFile;
971 QString action_cf_name;
979 /* Iterate through the actions in menuOpenRecentCaptureFile,
980 * removing special items, a maybe duplicate entry and every item above count_max */
981 int shortcut = Qt::Key_0;
982 foreach (recent_item_status *ri, wsApp->recentItems()) {
984 ra = new QAction(recentMenu);
985 ra->setData(ri->filename);
986 // XXX - Needs get_recent_item_status or equivalent
987 ra->setEnabled(ri->accessible);
988 recentMenu->insertAction(NULL, ra);
989 action_cf_name = ra->data().toString();
990 if (shortcut <= Qt::Key_9) {
991 ra->setShortcut(Qt::META | shortcut);
994 ra->setText(action_cf_name);
995 connect(ra, SIGNAL(triggered()), this, SLOT(recentActionTriggered()));
998 if (recentMenu->actions().count() > 0) {
999 // Separator + "Clear"
1000 // XXX - Do we really need this?
1001 ra = new QAction(recentMenu);
1002 ra->setSeparator(true);
1003 recentMenu->insertAction(NULL, ra);
1005 ra = new QAction(recentMenu);
1006 ra->setText(tr("Clear Menu"));
1007 recentMenu->insertAction(NULL, ra);
1008 connect(ra, SIGNAL(triggered()), wsApp, SLOT(clearRecentItems()));
1010 if (main_ui_->actionDummyNoFilesFound) {
1011 recentMenu->addAction(main_ui_->actionDummyNoFilesFound);
1016 void MainWindow::recentActionTriggered() {
1017 QAction *ra = qobject_cast<QAction*>(sender());
1020 QString cfPath = ra->data().toString();
1021 openCaptureFile(cfPath);
1025 void MainWindow::setMenusForSelectedPacket()
1027 gboolean is_ip = FALSE, is_tcp = FALSE, is_udp = FALSE, is_sctp = FALSE, is_ssl = FALSE, is_rtp = FALSE;
1029 /* Making the menu context-sensitive allows for easier selection of the
1030 desired item and has the added benefit, with large captures, of
1031 avoiding needless looping through huge lists for marked, ignored,
1032 or time-referenced packets. */
1034 /* We have one or more items in the packet list */
1035 bool have_frames = false;
1036 /* A frame is selected */
1037 bool frame_selected = false;
1038 /* We have marked frames. (XXX - why check frame_selected?) */
1039 bool have_marked = false;
1040 /* We have a marked frame other than the current frame (i.e.,
1041 we have at least one marked frame, and either there's more
1042 than one marked frame or the current frame isn't marked). */
1043 bool another_is_marked = false;
1044 /* One or more frames are hidden by a display filter */
1045 bool have_filtered = false;
1046 /* One or more frames have been ignored */
1047 bool have_ignored = false;
1048 bool have_time_ref = false;
1049 /* We have a time reference frame other than the current frame (i.e.,
1050 we have at least one time reference frame, and either there's more
1051 than one time reference frame or the current frame isn't a
1052 time reference frame). (XXX - why check frame_selected?) */
1053 bool another_is_time_ref = false;
1054 /* We have a valid filter expression */
1055 bool have_filter_expr = false;
1057 QList<QAction *> cc_actions = QList<QAction *>()
1058 << main_ui_->actionViewColorizeConversation1 << main_ui_->actionViewColorizeConversation2
1059 << main_ui_->actionViewColorizeConversation3 << main_ui_->actionViewColorizeConversation4
1060 << main_ui_->actionViewColorizeConversation5 << main_ui_->actionViewColorizeConversation6
1061 << main_ui_->actionViewColorizeConversation7 << main_ui_->actionViewColorizeConversation8
1062 << main_ui_->actionViewColorizeConversation9 << main_ui_->actionViewColorizeConversation10;
1064 if (capture_file_.capFile()) {
1065 frame_selected = capture_file_.capFile()->current_frame != NULL;
1066 have_frames = capture_file_.capFile()->count > 0;
1067 have_marked = frame_selected && capture_file_.capFile()->marked_count > 0;
1068 another_is_marked = have_marked &&
1069 !(capture_file_.capFile()->marked_count == 1 && capture_file_.capFile()->current_frame->flags.marked);
1070 have_filtered = capture_file_.capFile()->displayed_count > 0 && capture_file_.capFile()->displayed_count != capture_file_.capFile()->count;
1071 have_ignored = capture_file_.capFile()->ignored_count > 0;
1072 have_time_ref = capture_file_.capFile()->ref_time_count > 0;
1073 another_is_time_ref = frame_selected && have_time_ref &&
1074 !(capture_file_.capFile()->ref_time_count == 1 && capture_file_.capFile()->current_frame->flags.ref_time);
1076 if (capture_file_.capFile()->edt)
1078 proto_get_frame_protocols(capture_file_.capFile()->edt->pi.layers, &is_ip, &is_tcp, &is_udp, &is_sctp, &is_ssl, &is_rtp);
1082 have_filter_expr = !packet_list_->getFilterFromRowAndColumn().isEmpty();
1084 main_ui_->actionEditMarkPacket->setEnabled(frame_selected);
1085 main_ui_->actionEditMarkAllDisplayed->setEnabled(have_frames);
1086 /* Unlike un-ignore, do not allow unmark of all frames when no frames are displayed */
1087 main_ui_->actionEditUnmarkAllDisplayed->setEnabled(have_marked);
1088 main_ui_->actionEditNextMark->setEnabled(another_is_marked);
1089 main_ui_->actionEditPreviousMark->setEnabled(another_is_marked);
1091 #ifdef WANT_PACKET_EDITOR
1092 // set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/EditMenu/EditPacket",
1094 #endif // WANT_PACKET_EDITOR
1095 main_ui_->actionEditPacketComment->setEnabled(frame_selected && wtap_dump_can_write(capture_file_.capFile()->linktypes, WTAP_COMMENT_PER_PACKET));
1097 main_ui_->actionEditIgnorePacket->setEnabled(frame_selected);
1098 main_ui_->actionEditIgnoreAllDisplayed->setEnabled(have_filtered);
1099 /* Allow un-ignore of all frames even with no frames currently displayed */
1100 main_ui_->actionEditUnignoreAllDisplayed->setEnabled(have_ignored);
1102 main_ui_->actionEditSetTimeReference->setEnabled(frame_selected);
1103 main_ui_->actionEditUnsetAllTimeReferences->setEnabled(have_time_ref);
1104 main_ui_->actionEditNextTimeReference->setEnabled(another_is_time_ref);
1105 main_ui_->actionEditPreviousTimeReference->setEnabled(another_is_time_ref);
1106 main_ui_->actionEditTimeShift->setEnabled(have_frames);
1108 main_ui_->actionGoGoToLinkedPacket->setEnabled(false);
1110 main_ui_->actionAnalyzeAAFSelected->setEnabled(have_filter_expr);
1111 main_ui_->actionAnalyzeAAFNotSelected->setEnabled(have_filter_expr);
1112 main_ui_->actionAnalyzeAAFAndSelected->setEnabled(have_filter_expr);
1113 main_ui_->actionAnalyzeAAFOrSelected->setEnabled(have_filter_expr);
1114 main_ui_->actionAnalyzeAAFAndNotSelected->setEnabled(have_filter_expr);
1115 main_ui_->actionAnalyzeAAFOrNotSelected->setEnabled(have_filter_expr);
1117 main_ui_->actionAnalyzePAFSelected->setEnabled(have_filter_expr);
1118 main_ui_->actionAnalyzePAFNotSelected->setEnabled(have_filter_expr);
1119 main_ui_->actionAnalyzePAFAndSelected->setEnabled(have_filter_expr);
1120 main_ui_->actionAnalyzePAFOrSelected->setEnabled(have_filter_expr);
1121 main_ui_->actionAnalyzePAFAndNotSelected->setEnabled(have_filter_expr);
1122 main_ui_->actionAnalyzePAFOrNotSelected->setEnabled(have_filter_expr);
1124 main_ui_->actionAnalyzeFollowTCPStream->setEnabled(is_tcp);
1125 main_ui_->actionAnalyzeFollowUDPStream->setEnabled(is_udp);
1126 main_ui_->actionAnalyzeFollowSSLStream->setEnabled(is_ssl);
1128 foreach (QAction *cc_action, cc_actions) {
1129 cc_action->setEnabled(frame_selected);
1131 main_ui_->actionViewColorizeNewConversationRule->setEnabled(frame_selected);
1133 main_ui_->actionViewColorizeResetColorization->setEnabled(tmp_color_filters_used());
1135 main_ui_->actionViewColorizeNewConversationRule->setEnabled(frame_selected);
1137 main_ui_->actionViewShowPacketInNewWindow->setEnabled(frame_selected);
1138 main_ui_->actionViewEditResolvedName->setEnabled(frame_selected && is_ip);
1140 main_ui_->menuConversationFilter->clear();
1142 packet_list_->conversationMenu()->clear();
1143 packet_list_->colorizeMenu()->clear();
1145 for (GList *color_list_entry = color_conv_filter_list; color_list_entry; color_list_entry = g_list_next(color_list_entry)) {
1147 color_conversation_filter_t* color_filter = (color_conversation_filter_t *)color_list_entry->data;
1148 QAction *conv_action = main_ui_->menuConversationFilter->addAction(color_filter->display_name);
1150 bool enable = false;
1152 if (capture_file_.capFile()->edt) {
1153 enable = color_filter->is_filter_valid(&capture_file_.capFile()->edt->pi);
1154 filter = gchar_free_to_qstring(color_filter->build_filter_string(&capture_file_.capFile()->edt->pi));
1156 conv_action->setEnabled(enable);
1157 conv_action->setData(filter);
1158 connect(conv_action, SIGNAL(triggered()), this, SLOT(applyConversationFilter()));
1160 // Packet list context menu items
1161 packet_list_->conversationMenu()->addAction(conv_action);
1163 QMenu *submenu = packet_list_->colorizeMenu()->addMenu(conv_action->text());
1165 foreach (QAction *cc_action, cc_actions) {
1166 QAction *colorize_action = submenu->addAction(cc_action->icon(), cc_action->text());
1167 colorize_action->setProperty(color_number_property_, i++);
1168 colorize_action->setData(filter);
1169 colorize_action->setEnabled(enable);
1170 connect(colorize_action, SIGNAL(triggered()), this, SLOT(colorizeWithFilter()));
1173 QAction *conv_rule_action = submenu->addAction(main_ui_->actionViewColorizeNewConversationRule->text());
1174 conv_rule_action->setData(conv_action->data());
1175 conv_rule_action->setEnabled(enable);
1176 connect(conv_rule_action, SIGNAL(triggered()), this, SLOT(colorizeWithFilter()));
1179 // set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/ViewMenu/NameResolution/ResolveName",
1180 // frame_selected && (gbl_resolv_flags.mac_name || gbl_resolv_flags.network_name ||
1181 // gbl_resolv_flags.transport_name || gbl_resolv_flags.concurrent_dns));
1182 // set_menu_sensitivity(ui_manager_main_menubar, "/Menubar/ToolsMenu/FirewallACLRules",
1184 main_ui_->menuTcpStreamGraphs->setEnabled(is_tcp);
1185 main_ui_->actionSCTPAnalyseThisAssociation->setEnabled(is_sctp);
1186 main_ui_->actionSCTPShowAllAssociations->setEnabled(is_sctp);
1187 main_ui_->actionSCTPFilterThisAssociation->setEnabled(is_sctp);
1188 main_ui_->actionTelephonyRTPStreamAnalysis->setEnabled(is_rtp);
1191 void MainWindow::setMenusForSelectedTreeRow(field_info *fi) {
1193 bool can_match_selected = false;
1194 bool is_framenum = false;
1195 bool have_field_info = false;
1196 bool have_subtree = false;
1197 bool can_open_url = false;
1198 QString field_filter;
1201 QList<QAction *> cc_actions = QList<QAction *>()
1202 << main_ui_->actionViewColorizeConversation1 << main_ui_->actionViewColorizeConversation2
1203 << main_ui_->actionViewColorizeConversation3 << main_ui_->actionViewColorizeConversation4
1204 << main_ui_->actionViewColorizeConversation5 << main_ui_->actionViewColorizeConversation6
1205 << main_ui_->actionViewColorizeConversation7 << main_ui_->actionViewColorizeConversation8
1206 << main_ui_->actionViewColorizeConversation9 << main_ui_->actionViewColorizeConversation10;
1208 if (capture_file_.capFile()) {
1209 capture_file_.capFile()->finfo_selected = fi;
1211 if (fi && fi->tree_type != -1) {
1212 have_subtree = true;
1216 if (capture_file_.capFile() != NULL && fi != NULL) {
1217 header_field_info *hfinfo = fi->hfinfo;
1218 int linked_frame = -1;
1220 have_field_info = true;
1221 can_match_selected = proto_can_match_selected(capture_file_.capFile()->finfo_selected, capture_file_.capFile()->edt);
1222 if (hfinfo && hfinfo->type == FT_FRAMENUM) {
1224 linked_frame = fvalue_get_uinteger(&fi->value);
1227 char *tmp_field = proto_construct_match_selected_string(fi, capture_file_.capFile()->edt);
1228 field_filter = QString(tmp_field);
1229 wmem_free(NULL, tmp_field);
1231 field_id = fi->hfinfo->id;
1232 /* if the selected field isn't a protocol, get its parent */
1233 if (!proto_registrar_is_protocol(field_id)) {
1234 field_id = proto_registrar_get_parent(fi->hfinfo->id);
1237 if (field_id >= 0 && !proto_is_private(field_id)) {
1238 can_open_url = true;
1239 main_ui_->actionContextWikiProtocolPage->setData(field_id);
1240 main_ui_->actionContextFilterFieldReference->setData(field_id);
1242 main_ui_->actionContextWikiProtocolPage->setData(QVariant());
1243 main_ui_->actionContextFilterFieldReference->setData(QVariant());
1246 if (linked_frame > 0) {
1247 main_ui_->actionGoGoToLinkedPacket->setData(linked_frame);
1249 main_ui_->actionGoGoToLinkedPacket->setData(QVariant());
1253 // Always enable / disable the following items.
1254 main_ui_->actionFileExportPacketBytes->setEnabled(have_field_info);
1256 main_ui_->actionCopyAllVisibleItems->setEnabled(capture_file_.capFile() != NULL);
1257 main_ui_->actionCopyAllVisibleSelectedTreeItems->setEnabled(can_match_selected);
1258 main_ui_->actionEditCopyDescription->setEnabled(can_match_selected);
1259 main_ui_->actionEditCopyFieldName->setEnabled(can_match_selected);
1260 main_ui_->actionEditCopyValue->setEnabled(can_match_selected);
1261 main_ui_->actionEditCopyAsFilter->setEnabled(can_match_selected);
1263 main_ui_->actionViewExpandSubtrees->setEnabled(have_subtree);
1265 main_ui_->actionGoGoToLinkedPacket->setEnabled(is_framenum);
1267 main_ui_->actionAnalyzeCreateAColumn->setEnabled(can_match_selected);
1269 main_ui_->actionContextShowLinkedPacketInNewWindow->setEnabled(is_framenum);
1271 main_ui_->actionContextWikiProtocolPage->setEnabled(can_open_url);
1272 main_ui_->actionContextFilterFieldReference->setEnabled(can_open_url);
1275 // Only enable / disable the following items if we have focus so that we
1276 // don't clobber anything we may have set in setMenusForSelectedPacket.
1277 if (!proto_tree_ || !proto_tree_->hasFocus()) return;
1279 main_ui_->menuConversationFilter->clear();
1280 for (GList *color_list_entry = color_conv_filter_list; color_list_entry; color_list_entry = g_list_next(color_list_entry)) {
1281 color_conversation_filter_t* color_filter = (color_conversation_filter_t *)color_list_entry->data;
1282 QAction *conv_action = main_ui_->menuConversationFilter->addAction(color_filter->display_name);
1284 bool conv_enable = false;
1285 QString conv_filter;
1286 if (capture_file_.capFile() && capture_file_.capFile()->edt) {
1287 conv_enable = color_filter->is_filter_valid(&capture_file_.capFile()->edt->pi);
1288 conv_filter = color_filter->build_filter_string(&capture_file_.capFile()->edt->pi);
1290 conv_action->setEnabled(conv_enable);
1291 conv_action->setData(conv_filter);
1292 connect(conv_action, SIGNAL(triggered()), this, SLOT(applyConversationFilter()));
1295 proto_tree_->colorizeMenu()->clear();
1297 foreach (QAction *cc_action, cc_actions) {
1298 QAction *colorize_action = proto_tree_->colorizeMenu()->addAction(cc_action->icon(), cc_action->text());
1299 colorize_action->setProperty(color_number_property_, i++);
1300 colorize_action->setData(field_filter);
1301 colorize_action->setEnabled(!field_filter.isEmpty());
1302 connect(colorize_action, SIGNAL(triggered()), this, SLOT(colorizeWithFilter()));
1305 QAction *conv_rule_action = proto_tree_->colorizeMenu()->addAction(main_ui_->actionViewColorizeNewConversationRule->text());
1306 conv_rule_action->setData(field_filter);
1307 conv_rule_action->setEnabled(!field_filter.isEmpty());
1308 connect(conv_rule_action, SIGNAL(triggered()), this, SLOT(colorizeWithFilter()));
1310 // set_menu_sensitivity(ui_manager_tree_view_menu, "/TreeViewPopup/ResolveName",
1311 // frame_selected && (gbl_resolv_flags.mac_name || gbl_resolv_flags.network_name ||
1312 // gbl_resolv_flags.transport_name || gbl_resolv_flags.concurrent_dns));
1315 main_ui_->actionAnalyzeAAFSelected->setEnabled(can_match_selected);
1316 main_ui_->actionAnalyzeAAFNotSelected->setEnabled(can_match_selected);
1317 main_ui_->actionAnalyzeAAFAndSelected->setEnabled(can_match_selected);
1318 main_ui_->actionAnalyzeAAFOrSelected->setEnabled(can_match_selected);
1319 main_ui_->actionAnalyzeAAFAndNotSelected->setEnabled(can_match_selected);
1320 main_ui_->actionAnalyzeAAFOrNotSelected->setEnabled(can_match_selected);
1322 main_ui_->actionAnalyzePAFSelected->setEnabled(can_match_selected);
1323 main_ui_->actionAnalyzePAFNotSelected->setEnabled(can_match_selected);
1324 main_ui_->actionAnalyzePAFAndSelected->setEnabled(can_match_selected);
1325 main_ui_->actionAnalyzePAFOrSelected->setEnabled(can_match_selected);
1326 main_ui_->actionAnalyzePAFAndNotSelected->setEnabled(can_match_selected);
1327 main_ui_->actionAnalyzePAFOrNotSelected->setEnabled(can_match_selected);
1330 void MainWindow::interfaceSelectionChanged()
1333 // XXX This doesn't disable the toolbar button when using
1335 if (global_capture_opts.num_selected > 0 && capture_filter_valid_) {
1336 main_ui_->actionCaptureStart->setEnabled(true);
1338 main_ui_->actionCaptureStart->setEnabled(false);
1340 #endif // HAVE_LIBPCAP
1343 void MainWindow::captureFilterSyntaxChanged(bool valid)
1345 capture_filter_valid_ = valid;
1346 interfaceSelectionChanged();
1349 void MainWindow::startInterfaceCapture(bool valid)
1351 capture_filter_valid_ = valid;
1355 void MainWindow::redissectPackets()
1357 if (capture_file_.capFile())
1358 cf_redissect_packets(capture_file_.capFile());
1359 main_ui_->statusBar->expertUpdate();
1361 proto_free_deregistered_fields();
1364 void MainWindow::fieldsChanged()
1366 color_filters_reload();
1367 tap_listeners_dfilter_recompile();
1369 if (!df_combo_box_->checkDisplayFilter()) {
1370 g_free(CaptureFile::globalCapFile()->dfilter);
1371 CaptureFile::globalCapFile()->dfilter = NULL;
1374 if (have_custom_cols(&CaptureFile::globalCapFile()->cinfo)) {
1375 // Recreate packet list columns according to new/changed/deleted fields
1376 packet_list_->fieldsChanged(CaptureFile::globalCapFile());
1379 emit reloadFields();
1382 void MainWindow::showAccordionFrame(AccordionFrame *show_frame, bool toggle)
1384 QList<AccordionFrame *>frame_list = QList<AccordionFrame *>()
1385 << main_ui_->goToFrame << main_ui_->searchFrame
1386 << main_ui_->addressEditorFrame << main_ui_->columnEditorFrame
1387 << main_ui_->preferenceEditorFrame;
1389 frame_list.removeAll(show_frame);
1390 foreach (AccordionFrame *af, frame_list) af->animatedHide();
1393 if (show_frame->isVisible()) {
1394 show_frame->animatedHide();
1398 show_frame->animatedShow();
1401 void MainWindow::showColumnEditor(int column)
1403 previous_focus_ = wsApp->focusWidget();
1404 connect(previous_focus_, SIGNAL(destroyed()), this, SLOT(resetPreviousFocus()));
1405 showAccordionFrame(main_ui_->columnEditorFrame);
1406 main_ui_->columnEditorFrame->editColumn(column);
1409 void MainWindow::showPreferenceEditor()
1411 showAccordionFrame(main_ui_->preferenceEditorFrame);
1414 void MainWindow::initViewColorizeMenu()
1416 QList<QAction *> cc_actions = QList<QAction *>()
1417 << main_ui_->actionViewColorizeConversation1 << main_ui_->actionViewColorizeConversation2
1418 << main_ui_->actionViewColorizeConversation3 << main_ui_->actionViewColorizeConversation4
1419 << main_ui_->actionViewColorizeConversation5 << main_ui_->actionViewColorizeConversation6
1420 << main_ui_->actionViewColorizeConversation7 << main_ui_->actionViewColorizeConversation8
1421 << main_ui_->actionViewColorizeConversation9 << main_ui_->actionViewColorizeConversation10;
1423 guint8 color_num = 1;
1425 foreach (QAction *cc_action, cc_actions) {
1426 cc_action->setData(color_num);
1427 connect(cc_action, SIGNAL(triggered()), this, SLOT(colorizeConversation()));
1429 const color_filter_t *colorf = color_filters_tmp_color(color_num);
1431 QColor bg = ColorUtils::fromColorT(colorf->bg_color);
1432 QColor fg = ColorUtils::fromColorT(colorf->fg_color);
1433 cc_action->setIcon(StockIcon::colorIcon(bg.rgb(), fg.rgb(), QString::number(color_num)));
1439 // Spotlight uses Cmd+Space
1440 main_ui_->actionViewColorizeResetColorization->setShortcut(QKeySequence("Meta+Space"));
1444 void MainWindow::addStatsPluginsToMenu() {
1445 GList *cfg_list = stats_tree_get_cfg_list();
1446 GList *iter = g_list_first(cfg_list);
1447 QAction *stats_tree_action;
1449 bool first_item = true;
1452 stats_tree_cfg *cfg = (stats_tree_cfg*)iter->data;
1455 main_ui_->menuStatistics->addSeparator();
1459 parent_menu = main_ui_->menuStatistics;
1460 // gtk/main_menubar.c compresses double slashes, hence SkipEmptyParts
1461 QStringList cfg_name_parts = QString(cfg->name).split("/", QString::SkipEmptyParts);
1462 if (cfg_name_parts.isEmpty()) continue;
1464 QString stat_name = cfg_name_parts.takeLast();
1465 if (!cfg_name_parts.isEmpty()) {
1466 QString menu_name = cfg_name_parts.join("/");
1467 parent_menu = findOrAddMenu(parent_menu, menu_name);
1470 stats_tree_action = new QAction(stat_name, this);
1471 stats_tree_action->setData(cfg->abbr);
1472 parent_menu->addAction(stats_tree_action);
1473 connect(stats_tree_action, SIGNAL(triggered()), this, SLOT(actionStatisticsPlugin_triggered()));
1475 iter = g_list_next(iter);
1477 g_list_free(cfg_list);
1480 void MainWindow::setFeaturesEnabled(bool enabled)
1482 main_ui_->menuBar->setEnabled(enabled);
1483 main_ui_->mainToolBar->setEnabled(enabled);
1484 main_ui_->displayFilterToolBar->setEnabled(enabled);
1487 main_ui_->statusBar->clearMessage();
1491 main_ui_->statusBar->showMessage(tr("Please wait while Wireshark is initializing" UTF8_HORIZONTAL_ELLIPSIS));
1495 // Display Filter Toolbar
1497 void MainWindow::on_actionDisplayFilterExpression_triggered()
1499 DisplayFilterExpressionDialog *dfe_dialog = new DisplayFilterExpressionDialog(this);
1501 connect(dfe_dialog, SIGNAL(insertDisplayFilter(QString)),
1502 df_combo_box_->lineEdit(), SLOT(insertFilter(const QString &)));
1507 // On Qt4 + OS X with unifiedTitleAndToolBarOnMac set it's possible to make
1508 // the main window obnoxiously wide.
1510 void MainWindow::displayFilterButtonClicked()
1512 QAction *dfb_action = qobject_cast<QAction*>(sender());
1515 df_combo_box_->lineEdit()->setText(dfb_action->data().toString());
1516 df_combo_box_->applyDisplayFilter();
1517 df_combo_box_->lineEdit()->setFocus();
1521 void MainWindow::openStatCommandDialog(const QString &menu_path, const char *arg, void *userdata)
1523 QString slot = QString("statCommand%1").arg(menu_path);
1524 QMetaObject::invokeMethod(this, slot.toLatin1().constData(), Q_ARG(const char *, arg), Q_ARG(void *, userdata));
1527 void MainWindow::openTapParameterDialog(const QString cfg_str, const QString arg, void *userdata)
1529 TapParameterDialog *tp_dialog = TapParameterDialog::showTapParameterStatistics(*this, capture_file_, cfg_str, arg, userdata);
1530 if (!tp_dialog) return;
1532 connect(tp_dialog, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
1533 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
1534 connect(tp_dialog, SIGNAL(updateFilter(QString)),
1535 df_combo_box_->lineEdit(), SLOT(setText(QString)));
1539 void MainWindow::openTapParameterDialog()
1541 QAction *tpa = qobject_cast<QAction *>(QObject::sender());
1544 const QString cfg_str = tpa->data().toString();
1545 openTapParameterDialog(cfg_str, NULL, NULL);
1550 void MainWindow::on_actionFileOpen_triggered()
1555 void MainWindow::on_actionFileMerge_triggered()
1560 void MainWindow::on_actionFileImportFromHexDump_triggered()
1562 importCaptureFile();
1565 void MainWindow::on_actionFileClose_triggered() {
1566 if (testCaptureFileClose())
1567 main_ui_->mainStack->setCurrentWidget(main_welcome_);
1570 void MainWindow::on_actionFileSave_triggered()
1572 saveCaptureFile(capture_file_.capFile(), FALSE);
1575 void MainWindow::on_actionFileSaveAs_triggered()
1577 saveAsCaptureFile(capture_file_.capFile());
1580 void MainWindow::on_actionFileSetListFiles_triggered()
1582 file_set_dialog_.exec();
1585 void MainWindow::on_actionFileSetNextFile_triggered()
1587 fileset_entry *entry = fileset_get_next();
1590 QString new_cf_path = entry->fullname;
1591 openCaptureFile(new_cf_path);
1595 void MainWindow::on_actionFileSetPreviousFile_triggered()
1597 fileset_entry *entry = fileset_get_previous();
1600 QString new_cf_path = entry->fullname;
1601 openCaptureFile(new_cf_path);
1605 void MainWindow::on_actionFileExportPackets_triggered()
1607 exportSelectedPackets();
1610 void MainWindow::on_actionFileExportAsPlainText_triggered()
1612 exportDissections(export_type_text);
1615 void MainWindow::on_actionFileExportAsCSV_triggered()
1617 exportDissections(export_type_csv);
1620 void MainWindow::on_actionFileExportAsCArrays_triggered()
1622 exportDissections(export_type_carrays);
1625 void MainWindow::on_actionFileExportAsPSML_triggered()
1627 exportDissections(export_type_psml);
1630 void MainWindow::on_actionFileExportAsPDML_triggered()
1632 exportDissections(export_type_pdml);
1635 void MainWindow::on_actionFileExportPacketBytes_triggered()
1639 if (!capture_file_.capFile() || !capture_file_.capFile()->finfo_selected) return;
1641 file_name = QFileDialog::getSaveFileName(this,
1642 wsApp->windowTitleString(tr("Export Selected Packet Bytes")),
1643 wsApp->lastOpenDir().canonicalPath(),
1644 tr("Raw data (*.bin *.dat *.raw);;Any File (*.*)")
1647 if (file_name.length() > 0) {
1648 const guint8 *data_p;
1651 data_p = tvb_get_ptr(capture_file_.capFile()->finfo_selected->ds_tvb, 0, -1) +
1652 capture_file_.capFile()->finfo_selected->start;
1653 fd = ws_open(file_name.toUtf8().constData(), O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666);
1655 open_failure_alert_box(file_name.toUtf8().constData(), errno, TRUE);
1658 if (write(fd, data_p, capture_file_.capFile()->finfo_selected->length) < 0) {
1659 write_failure_alert_box(file_name.toUtf8().constData(), errno);
1663 if (::close(fd) < 0) {
1664 write_failure_alert_box(file_name.toUtf8().constData(), errno);
1668 /* Save the directory name for future file dialogs. */
1669 wsApp->setLastOpenDir(&file_name);
1672 void MainWindow::on_actionFileExportPDU_triggered()
1674 ExportPDUDialog *exportpdu_dialog = new ExportPDUDialog(this);
1676 if (exportpdu_dialog->isMinimized() == true)
1678 exportpdu_dialog->showNormal();
1682 exportpdu_dialog->show();
1685 exportpdu_dialog->raise();
1686 exportpdu_dialog->activateWindow();
1689 void MainWindow::on_actionFileExportSSLSessionKeys_triggered()
1695 keylist_len = ssl_session_key_count();
1696 /* don't show up the dialog, if no data has to be saved */
1697 if (keylist_len < 1) {
1698 /* shouldn't happen as the menu item should have been greyed out */
1699 QMessageBox::warning(
1702 tr("There are no SSL Session Keys to save."),
1708 save_title.append(wsApp->windowTitleString(tr("Export SSL Session Keys (%1 key%2").
1709 arg(keylist_len).arg(plurality(keylist_len, "", "s"))));
1710 file_name = QFileDialog::getSaveFileName(this,
1712 wsApp->lastOpenDir().canonicalPath(),
1713 tr("SSL Session Keys (*.keys *.txt);;Any File (*.*)")
1715 if (file_name.length() > 0) {
1719 keylist = ssl_export_sessions();
1720 fd = ws_open(file_name.toUtf8().constData(), O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666);
1722 open_failure_alert_box(file_name.toUtf8().constData(), errno, TRUE);
1727 * Thanks, Microsoft, for not using size_t for the third argument to
1728 * _write(). Presumably this string will be <= 4GiB long....
1730 if (ws_write(fd, keylist, (unsigned int)strlen(keylist)) < 0) {
1731 write_failure_alert_box(file_name.toUtf8().constData(), errno);
1736 if (::close(fd) < 0) {
1737 write_failure_alert_box(file_name.toUtf8().constData(), errno);
1742 /* Save the directory name for future file dialogs. */
1743 wsApp->setLastOpenDir(&file_name);
1748 void MainWindow::on_actionFileExportObjectsDICOM_triggered()
1750 new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Dicom);
1753 void MainWindow::on_actionStatisticsHpfeeds_triggered()
1755 openStatisticsTreeDialog("hpfeeds");
1758 void MainWindow::on_actionFileExportObjectsHTTP_triggered()
1760 new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Http);
1763 void MainWindow::on_actionFileExportObjectsSMB_triggered()
1765 new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Smb);
1768 void MainWindow::on_actionFileExportObjectsTFTP_triggered()
1770 new ExportObjectDialog(*this, capture_file_, ExportObjectDialog::Tftp);
1773 void MainWindow::on_actionFilePrint_triggered()
1775 PrintDialog pdlg(this, capture_file_.capFile());
1782 void MainWindow::recursiveCopyProtoTreeItems(QTreeWidgetItem *item, QString &clip, int ident_level) {
1783 if (!item->isExpanded()) return;
1785 for (int i_item = 0; i_item < item->childCount(); i_item += 1) {
1786 clip.append(QString(" ").repeated(ident_level));
1787 clip.append(item->child(i_item)->text(0));
1790 recursiveCopyProtoTreeItems(item->child(i_item), clip, ident_level + 1);
1794 // XXX This should probably be somewhere else.
1795 void MainWindow::actionEditCopyTriggered(MainWindow::CopySelected selection_type)
1797 char label_str[ITEM_LABEL_LENGTH];
1800 if (!capture_file_.capFile()) return;
1802 field_info *finfo_selected = capture_file_.capFile()->finfo_selected;
1804 switch(selection_type) {
1805 case CopySelectedDescription:
1806 if (finfo_selected && finfo_selected->rep
1807 && strlen (finfo_selected->rep->representation) > 0) {
1808 clip.append(finfo_selected->rep->representation);
1811 case CopySelectedFieldName:
1812 if (finfo_selected && finfo_selected->hfinfo->abbrev != 0) {
1813 clip.append(finfo_selected->hfinfo->abbrev);
1816 case CopySelectedValue:
1817 if (finfo_selected && capture_file_.capFile()->edt != 0) {
1818 gchar* field_str = get_node_field_value(finfo_selected, capture_file_.capFile()->edt);
1819 clip.append(field_str);
1823 case CopyAllVisibleItems:
1824 for (int i_item = 0; i_item < proto_tree_->topLevelItemCount(); i_item += 1) {
1825 clip.append(proto_tree_->topLevelItem(i_item)->text(0));
1828 recursiveCopyProtoTreeItems(proto_tree_->topLevelItem(i_item), clip, 1);
1832 case CopyAllVisibleSelectedTreeItems:
1833 if (proto_tree_->selectedItems().count() > 0) {
1834 clip.append(proto_tree_->currentItem()->text(0));
1837 recursiveCopyProtoTreeItems(proto_tree_->currentItem(), clip, 1);
1842 if (clip.length() == 0) {
1843 /* If no representation then... Try to read the value */
1844 proto_item_fill_label(capture_file_.capFile()->finfo_selected, label_str);
1845 clip.append(label_str);
1848 if (clip.length()) {
1849 wsApp->clipboard()->setText(clip);
1851 QString err = tr("Couldn't copy text. Try another item.");
1852 main_ui_->statusBar->pushTemporaryStatus(err);
1856 void MainWindow::on_actionCopyAllVisibleItems_triggered()
1858 actionEditCopyTriggered(CopyAllVisibleItems);
1861 void MainWindow::on_actionCopyAllVisibleSelectedTreeItems_triggered()
1863 actionEditCopyTriggered(CopyAllVisibleSelectedTreeItems);
1866 void MainWindow::on_actionEditCopyDescription_triggered()
1868 actionEditCopyTriggered(CopySelectedDescription);
1871 void MainWindow::on_actionEditCopyFieldName_triggered()
1873 actionEditCopyTriggered(CopySelectedFieldName);
1876 void MainWindow::on_actionEditCopyValue_triggered()
1878 actionEditCopyTriggered(CopySelectedValue);
1881 void MainWindow::on_actionEditCopyAsFilter_triggered()
1883 matchFieldFilter(FilterAction::ActionCopy, FilterAction::ActionTypePlain);
1886 void MainWindow::on_actionEditFindPacket_triggered()
1888 if (packet_list_->model()->rowCount() < 1) {
1891 previous_focus_ = wsApp->focusWidget();
1892 connect(previous_focus_, SIGNAL(destroyed()), this, SLOT(resetPreviousFocus()));
1893 showAccordionFrame(main_ui_->searchFrame, true);
1896 void MainWindow::on_actionEditFindNext_triggered()
1898 main_ui_->searchFrame->findNext();
1901 void MainWindow::on_actionEditFindPrevious_triggered()
1903 main_ui_->searchFrame->findPrevious();
1906 void MainWindow::on_actionEditMarkPacket_triggered()
1908 packet_list_->markFrame();
1911 void MainWindow::on_actionEditMarkAllDisplayed_triggered()
1913 packet_list_->markAllDisplayedFrames(true);
1916 void MainWindow::on_actionEditUnmarkAllDisplayed_triggered()
1918 packet_list_->markAllDisplayedFrames(false);
1921 void MainWindow::on_actionEditNextMark_triggered()
1923 if (capture_file_.capFile())
1924 cf_find_packet_marked(capture_file_.capFile(), SD_FORWARD);
1927 void MainWindow::on_actionEditPreviousMark_triggered()
1929 if (capture_file_.capFile())
1930 cf_find_packet_marked(capture_file_.capFile(), SD_BACKWARD);
1933 void MainWindow::on_actionEditIgnorePacket_triggered()
1935 packet_list_->ignoreFrame();
1938 void MainWindow::on_actionEditIgnoreAllDisplayed_triggered()
1940 packet_list_->ignoreAllDisplayedFrames(true);
1943 void MainWindow::on_actionEditUnignoreAllDisplayed_triggered()
1945 packet_list_->ignoreAllDisplayedFrames(false);
1948 void MainWindow::on_actionEditSetTimeReference_triggered()
1950 packet_list_->setTimeReference();
1953 void MainWindow::on_actionEditUnsetAllTimeReferences_triggered()
1955 packet_list_->unsetAllTimeReferences();
1958 void MainWindow::on_actionEditNextTimeReference_triggered()
1960 if (!capture_file_.capFile()) return;
1961 cf_find_packet_time_reference(capture_file_.capFile(), SD_FORWARD);
1964 void MainWindow::on_actionEditPreviousTimeReference_triggered()
1966 if (!capture_file_.capFile()) return;
1967 cf_find_packet_time_reference(capture_file_.capFile(), SD_BACKWARD);
1970 void MainWindow::on_actionEditTimeShift_triggered()
1972 TimeShiftDialog ts_dialog(this, capture_file_.capFile());
1973 connect(this, SIGNAL(setCaptureFile(capture_file*)),
1974 &ts_dialog, SLOT(setCaptureFile(capture_file*)));
1978 void MainWindow::on_actionEditPacketComment_triggered()
1980 PacketCommentDialog pc_dialog(this, packet_list_->packetComment());
1981 if (pc_dialog.exec() == QDialog::Accepted) {
1982 packet_list_->setPacketComment(pc_dialog.text());
1983 updateForUnsavedChanges();
1987 void MainWindow::on_actionEditConfigurationProfiles_triggered()
1989 ProfileDialog cp_dialog;
1994 void MainWindow::showPreferencesDialog(PreferencesDialog::PreferencesPane start_pane)
1996 PreferencesDialog pref_dialog(this);
1998 pref_dialog.setPane(start_pane);
2001 // Emitting PacketDissectionChanged directly from a QDialog can cause
2002 // problems on OS X.
2003 wsApp->flushAppSignals();
2006 void MainWindow::showPreferencesDialog(QString module_name)
2008 PreferencesDialog pref_dialog(this);
2010 pref_dialog.setPane(module_name);
2013 // Emitting PacketDissectionChanged directly from a QDialog can cause
2014 // problems on OS X.
2015 wsApp->flushAppSignals();
2018 void MainWindow::on_actionEditPreferences_triggered()
2020 showPreferencesDialog();
2025 void MainWindow::showHideMainWidgets(QAction *action)
2030 bool show = action->isChecked();
2031 QWidget *widget = action->data().value<QWidget*>();
2033 // We may have come from the toolbar context menu, so check/uncheck each
2035 if (widget == main_ui_->mainToolBar) {
2036 recent.main_toolbar_show = show;
2037 main_ui_->actionViewMainToolbar->setChecked(show);
2038 } else if (widget == main_ui_->displayFilterToolBar) {
2039 recent.filter_toolbar_show = show;
2040 main_ui_->actionViewFilterToolbar->setChecked(show);
2041 } else if (widget == main_ui_->wirelessToolBar) {
2042 recent.wireless_toolbar_show = show;
2043 main_ui_->actionViewWirelessToolbar->setChecked(show);
2044 } else if (widget == main_ui_->statusBar) {
2045 recent.statusbar_show = show;
2046 main_ui_->actionViewStatusBar->setChecked(show);
2047 } else if (widget == packet_list_) {
2048 recent.packet_list_show = show;
2049 main_ui_->actionViewPacketList->setChecked(show);
2050 } else if (widget == proto_tree_) {
2051 recent.tree_view_show = show;
2052 main_ui_->actionViewPacketDetails->setChecked(show);
2053 } else if (widget == byte_view_tab_) {
2054 recent.byte_view_show = show;
2055 main_ui_->actionViewPacketBytes->setChecked(show);
2059 widget->setVisible(show);
2063 Q_DECLARE_METATYPE(ts_type)
2065 void MainWindow::setTimestampFormat(QAction *action)
2070 ts_type tsf = action->data().value<ts_type>();
2071 if (recent.gui_time_format != tsf) {
2072 timestamp_set_type(tsf);
2073 recent.gui_time_format = tsf;
2074 if (capture_file_.capFile()) {
2075 /* This call adjusts column width */
2076 cf_timestamp_auto_precision(capture_file_.capFile());
2079 packet_list_->columnsChanged();
2084 Q_DECLARE_METATYPE(ts_precision)
2086 void MainWindow::setTimestampPrecision(QAction *action)
2091 ts_precision tsp = action->data().value<ts_precision>();
2092 if (recent.gui_time_precision != tsp) {
2093 /* the actual precision will be set in packet_list_queue_draw() below */
2094 timestamp_set_precision(tsp);
2095 recent.gui_time_precision = tsp;
2096 if (capture_file_.capFile()) {
2097 /* This call adjusts column width */
2098 cf_timestamp_auto_precision(capture_file_.capFile());
2101 packet_list_->columnsChanged();
2106 void MainWindow::on_actionViewTimeDisplaySecondsWithHoursAndMinutes_triggered(bool checked)
2109 recent.gui_seconds_format = TS_SECONDS_HOUR_MIN_SEC;
2111 recent.gui_seconds_format = TS_SECONDS_DEFAULT;
2113 timestamp_set_seconds_type(recent.gui_seconds_format);
2115 if (capture_file_.capFile()) {
2116 /* This call adjusts column width */
2117 cf_timestamp_auto_precision(capture_file_.capFile());
2120 packet_list_->columnsChanged();
2124 void MainWindow::on_actionViewEditResolvedName_triggered()
2126 // int column = packet_list_->selectedColumn();
2129 if (packet_list_->currentIndex().isValid()) {
2130 column = packet_list_->currentIndex().column();
2133 main_ui_->addressEditorFrame->editAddresses(capture_file_, column);
2134 showAccordionFrame(main_ui_->addressEditorFrame);
2137 void MainWindow::setNameResolution()
2139 gbl_resolv_flags.mac_name = main_ui_->actionViewNameResolutionPhysical->isChecked() ? TRUE : FALSE;
2140 gbl_resolv_flags.network_name = main_ui_->actionViewNameResolutionNetwork->isChecked() ? TRUE : FALSE;
2141 gbl_resolv_flags.transport_name = main_ui_->actionViewNameResolutionTransport->isChecked() ? TRUE : FALSE;
2144 packet_list_->columnsChanged();
2148 void MainWindow::on_actionViewNameResolutionPhysical_triggered()
2150 setNameResolution();
2153 void MainWindow::on_actionViewNameResolutionNetwork_triggered()
2155 setNameResolution();
2158 void MainWindow::on_actionViewNameResolutionTransport_triggered()
2160 setNameResolution();
2163 void MainWindow::zoomText()
2165 // Scale by 10%, rounding to nearest half point, minimum 1 point.
2166 // XXX Small sizes repeat. It might just be easier to create a map of multipliers.
2167 mono_font_ = QFont(wsApp->monospaceFont());
2168 qreal zoom_size = wsApp->monospaceFont().pointSize() * 2 * qPow(1.1, recent.gui_zoom_level);
2169 zoom_size = qRound(zoom_size) / 2.0;
2170 zoom_size = qMax(zoom_size, 1.0);
2171 mono_font_.setPointSizeF(zoom_size);
2172 emit monospaceFontChanged(mono_font_);
2175 void MainWindow::on_actionViewZoomIn_triggered()
2177 recent.gui_zoom_level++;
2181 void MainWindow::on_actionViewZoomOut_triggered()
2183 recent.gui_zoom_level--;
2187 void MainWindow::on_actionViewNormalSize_triggered()
2189 recent.gui_zoom_level = 0;
2193 void MainWindow::on_actionViewColorizePacketList_triggered(bool checked) {
2194 recent.packet_list_colorize = checked;
2195 color_filters_enable(checked);
2196 packet_list_->packetListModel()->resetColorized();
2197 packet_list_->update();
2200 void MainWindow::on_actionViewColoringRules_triggered()
2202 ColoringRulesDialog coloring_rules_dialog(this);
2204 coloring_rules_dialog.exec();
2207 // actionViewColorizeConversation1 - 10
2208 void MainWindow::colorizeConversation(bool create_rule)
2210 QAction *cc_action = qobject_cast<QAction *>(sender());
2211 if (!cc_action) return;
2213 if (capture_file_.capFile() && capture_file_.capFile()->current_frame) {
2214 packet_info *pi = &capture_file_.capFile()->edt->pi;
2215 guint8 cc_num = cc_action->data().toUInt();
2216 gchar *filter = NULL;
2218 const color_conversation_filter_t *color_filter = find_color_conversation_filter("tcp");
2219 if ((color_filter != NULL) && (color_filter->is_filter_valid(pi)))
2220 filter = color_filter->build_filter_string(pi);
2221 if (filter == NULL) {
2222 color_filter = find_color_conversation_filter("udp");
2223 if ((color_filter != NULL) && (color_filter->is_filter_valid(pi)))
2224 filter = color_filter->build_filter_string(pi);
2226 if (filter == NULL) {
2227 color_filter = find_color_conversation_filter("ip");
2228 if ((color_filter != NULL) && (color_filter->is_filter_valid(pi)))
2229 filter = color_filter->build_filter_string(pi);
2231 if (filter == NULL) {
2232 color_filter = find_color_conversation_filter("ipv6");
2233 if ((color_filter != NULL) && (color_filter->is_filter_valid(pi)))
2234 filter = color_filter->build_filter_string(pi);
2236 if (filter == NULL) {
2237 color_filter = find_color_conversation_filter("eth");
2238 if ((color_filter != NULL) && (color_filter->is_filter_valid(pi)))
2239 filter = color_filter->build_filter_string(pi);
2241 if( filter == NULL ) {
2242 main_ui_->statusBar->pushTemporaryStatus(tr("Unable to build conversation filter."));
2247 ColoringRulesDialog coloring_rules_dialog(this, filter);
2248 coloring_rules_dialog.exec();
2250 color_filters_set_tmp(cc_num, filter, FALSE);
2251 packet_list_->recolorPackets();
2254 setMenusForSelectedPacket();
2257 void MainWindow::colorizeWithFilter()
2259 QAction *colorize_action = qobject_cast<QAction *>(sender());
2260 if (!colorize_action) return;
2262 QString filter = colorize_action->data().toString();
2263 if (filter.isEmpty()) return;
2266 int color_number = colorize_action->property(color_number_property_).toInt(&ok);
2270 color_filters_set_tmp(color_number, filter.toUtf8().constData(), FALSE);
2271 packet_list_->recolorPackets();
2273 // New coloring rule
2274 ColoringRulesDialog coloring_rules_dialog(window(), filter);
2275 coloring_rules_dialog.exec();
2277 main_ui_->actionViewColorizeResetColorization->setEnabled(tmp_color_filters_used());
2280 void MainWindow::on_actionViewColorizeResetColorization_triggered()
2282 color_filters_reset_tmp();
2283 packet_list_->recolorPackets();
2284 setMenusForSelectedPacket();
2287 void MainWindow::on_actionViewColorizeNewConversationRule_triggered()
2289 colorizeConversation(true);
2292 void MainWindow::on_actionViewResizeColumns_triggered()
2294 for (int col = 0; col < packet_list_->packetListModel()->columnCount(); col++) {
2295 packet_list_->resizeColumnToContents(col);
2296 recent_set_column_width(col, packet_list_->columnWidth(col));
2300 void MainWindow::openPacketDialog(bool from_reference)
2304 /* Find the frame for which we're popping up a dialog */
2305 if(from_reference) {
2306 guint32 framenum = fvalue_get_uinteger(&(capture_file_.capFile()->finfo_selected->value));
2310 fdata = frame_data_sequence_find(capture_file_.capFile()->frames, framenum);
2312 fdata = capture_file_.capFile()->current_frame;
2315 /* If we have a frame, pop up the dialog */
2317 PacketDialog *packet_dialog = new PacketDialog(*this, capture_file_, fdata);
2319 connect(this, SIGNAL(monospaceFontChanged(QFont)),
2320 packet_dialog, SIGNAL(monospaceFontChanged(QFont)));
2321 connect(this, SIGNAL(closePacketDialogs()),
2322 packet_dialog, SLOT(close()));
2323 zoomText(); // Emits monospaceFontChanged
2325 packet_dialog->show();
2329 void MainWindow::on_actionViewInternalsConversationHashTables_triggered()
2331 ConversationHashTablesDialog *conversation_hash_tables_dlg = new ConversationHashTablesDialog(this);
2332 conversation_hash_tables_dlg->show();
2335 void MainWindow::on_actionViewInternalsDissectorTables_triggered()
2337 DissectorTablesDialog *dissector_tables_dlg = new DissectorTablesDialog(this);
2338 dissector_tables_dlg->show();
2341 void MainWindow::on_actionViewInternalsSupportedProtocols_triggered()
2343 SupportedProtocolsDialog *supported_protocols_dlg = new SupportedProtocolsDialog(this);
2344 supported_protocols_dlg->show();
2347 void MainWindow::on_actionViewShowPacketInNewWindow_triggered()
2352 // This is only used in ProtoTree. Defining it here makes more sense.
2353 void MainWindow::on_actionContextShowLinkedPacketInNewWindow_triggered()
2355 openPacketDialog(true);
2358 void MainWindow::on_actionViewReload_triggered()
2360 cf_reload(CaptureFile::globalCapFile());
2363 // Expand / collapse slots in proto_tree
2369 void MainWindow::matchFieldFilter(FilterAction::Action action, FilterAction::ActionType filter_type)
2371 QString field_filter;
2373 if (packet_list_->contextMenuActive() || packet_list_->hasFocus()) {
2374 field_filter = packet_list_->getFilterFromRowAndColumn();
2375 } else if (capture_file_.capFile() && capture_file_.capFile()->finfo_selected) {
2376 char *tmp_field = proto_construct_match_selected_string(capture_file_.capFile()->finfo_selected,
2377 capture_file_.capFile()->edt);
2378 field_filter = QString(tmp_field);
2379 wmem_free(NULL, tmp_field);
2382 if (field_filter.isEmpty()) {
2383 QString err = tr("No filter available. Try another ");
2384 err.append(packet_list_->contextMenuActive() ? "column" : "item");
2386 main_ui_->statusBar->pushTemporaryStatus(err);
2390 filterAction(field_filter, action, filter_type);
2393 static FilterDialog *display_filter_dlg_ = NULL;
2394 void MainWindow::on_actionAnalyzeDisplayFilters_triggered()
2396 if (!display_filter_dlg_) {
2397 display_filter_dlg_ = new FilterDialog(this, FilterDialog::DisplayFilter);
2399 display_filter_dlg_->show();
2400 display_filter_dlg_->raise();
2401 display_filter_dlg_->activateWindow();
2405 void MainWindow::on_actionAnalyzeDisplayFilterMacros_triggered()
2407 struct epan_uat* dfm_uat;
2408 dfilter_macro_get_uat(&dfm_uat);
2409 UatDialog uat_dlg(parentWidget(), dfm_uat);
2412 // Emitting PacketDissectionChanged directly from a QDialog can cause
2413 // problems on OS X.
2414 wsApp->flushAppSignals();
2417 void MainWindow::on_actionAnalyzeCreateAColumn_triggered()
2421 if ( capture_file_.capFile() != 0 && capture_file_.capFile()->finfo_selected != 0 )
2423 colnr = column_prefs_add_custom(COL_CUSTOM, capture_file_.capFile()->finfo_selected->hfinfo->name,
2424 capture_file_.capFile()->finfo_selected->hfinfo->abbrev,0);
2426 packet_list_->columnsChanged();
2427 packet_list_->resizeColumnToContents(colnr);
2433 void MainWindow::applyConversationFilter()
2435 QAction *cfa = qobject_cast<QAction*>(sender());
2438 QString new_filter = cfa->data().toString();
2439 if (new_filter.isEmpty()) return;
2441 df_combo_box_->lineEdit()->setText(new_filter);
2442 df_combo_box_->applyDisplayFilter();
2445 // XXX We could probably create the analyze and prepare actions
2446 // dynamically using FilterActions and consolidate the methods
2447 // below into one callback.
2448 void MainWindow::on_actionAnalyzeAAFSelected_triggered()
2450 matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypePlain);
2453 void MainWindow::on_actionAnalyzeAAFNotSelected_triggered()
2455 matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypeNot);
2458 void MainWindow::on_actionAnalyzeAAFAndSelected_triggered()
2460 matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypeAnd);
2463 void MainWindow::on_actionAnalyzeAAFOrSelected_triggered()
2465 matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypeOr);
2468 void MainWindow::on_actionAnalyzeAAFAndNotSelected_triggered()
2470 matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypeAndNot);
2473 void MainWindow::on_actionAnalyzeAAFOrNotSelected_triggered()
2475 matchFieldFilter(FilterAction::ActionApply, FilterAction::ActionTypeOrNot);
2478 void MainWindow::on_actionAnalyzePAFSelected_triggered()
2480 matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypePlain);
2483 void MainWindow::on_actionAnalyzePAFNotSelected_triggered()
2485 matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypeNot);
2488 void MainWindow::on_actionAnalyzePAFAndSelected_triggered()
2490 matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypeAnd);
2493 void MainWindow::on_actionAnalyzePAFOrSelected_triggered()
2495 matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypeOr);
2498 void MainWindow::on_actionAnalyzePAFAndNotSelected_triggered()
2500 matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypeAndNot);
2503 void MainWindow::on_actionAnalyzePAFOrNotSelected_triggered()
2505 matchFieldFilter(FilterAction::ActionPrepare, FilterAction::ActionTypeOrNot);
2508 void MainWindow::on_actionAnalyzeEnabledProtocols_triggered()
2510 EnabledProtocolsDialog enable_proto_dialog(this);
2511 enable_proto_dialog.exec();
2513 // Emitting PacketDissectionChanged directly from a QDialog can cause
2514 // problems on OS X.
2515 wsApp->flushAppSignals();
2518 void MainWindow::on_actionAnalyzeDecodeAs_triggered()
2520 QAction *da_action = qobject_cast<QAction*>(sender());
2521 bool create_new = false;
2522 if (da_action && da_action->data().toBool() == true) {
2526 DecodeAsDialog da_dialog(this, capture_file_.capFile(), create_new);
2527 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2528 &da_dialog, SLOT(setCaptureFile(capture_file*)));
2531 // Emitting PacketDissectionChanged directly from a QDialog can cause
2532 // problems on OS X.
2533 wsApp->flushAppSignals();
2537 void MainWindow::on_actionAnalyzeReloadLuaPlugins_triggered()
2539 if (wsApp->isReloadingLua())
2542 wsApp->setReloadingLua(true);
2544 wslua_reload_plugins(NULL, NULL);
2545 funnel_statistics_reload_menus();
2546 reloadDynamicMenus();
2547 closePacketDialogs();
2549 // Preferences may have been deleted so close all widgets using prefs
2550 proto_tree_->closeContextMenu();
2551 main_ui_->preferenceEditorFrame->animatedHide();
2553 char *gdp_path, *dp_path;
2554 (void) wsApp->readConfigurationFiles(&gdp_path, &dp_path);
2559 wsApp->setReloadingLua(false);
2560 SimpleDialog::displayQueuedMessages();
2564 void MainWindow::openFollowStreamDialog(follow_type_t type) {
2565 FollowStreamDialog *fsd = new FollowStreamDialog(*this, capture_file_, type);
2566 connect(fsd, SIGNAL(updateFilter(QString, bool)), this, SLOT(filterPackets(QString, bool)));
2567 connect(fsd, SIGNAL(goToPacket(int)), packet_list_, SLOT(goToPacket(int)));
2570 fsd->follow(getFilter());
2573 void MainWindow::on_actionAnalyzeFollowTCPStream_triggered()
2575 openFollowStreamDialog(FOLLOW_TCP);
2578 void MainWindow::on_actionAnalyzeFollowUDPStream_triggered()
2580 openFollowStreamDialog(FOLLOW_UDP);
2583 void MainWindow::on_actionAnalyzeFollowSSLStream_triggered()
2585 openFollowStreamDialog(FOLLOW_SSL);
2588 void MainWindow::openSCTPAllAssocsDialog()
2590 SCTPAllAssocsDialog *sctp_dialog = new SCTPAllAssocsDialog(this, capture_file_.capFile());
2591 connect(sctp_dialog, SIGNAL(filterPackets(QString,bool)),
2592 this, SLOT(filterPackets(QString,bool)));
2593 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2594 sctp_dialog, SLOT(setCaptureFile(capture_file*)));
2595 sctp_dialog->fillTable();
2597 if (sctp_dialog->isMinimized() == true)
2599 sctp_dialog->showNormal();
2603 sctp_dialog->show();
2606 sctp_dialog->raise();
2607 sctp_dialog->activateWindow();
2610 void MainWindow::on_actionSCTPShowAllAssociations_triggered()
2612 openSCTPAllAssocsDialog();
2615 void MainWindow::on_actionSCTPAnalyseThisAssociation_triggered()
2617 SCTPAssocAnalyseDialog *sctp_analyse = new SCTPAssocAnalyseDialog(this, NULL, capture_file_.capFile());
2618 connect(sctp_analyse, SIGNAL(filterPackets(QString,bool)),
2619 this, SLOT(filterPackets(QString,bool)));
2621 if (sctp_analyse->isMinimized() == true)
2623 sctp_analyse->showNormal();
2627 sctp_analyse->show();
2630 sctp_analyse->raise();
2631 sctp_analyse->activateWindow();
2634 void MainWindow::on_actionSCTPFilterThisAssociation_triggered()
2636 sctp_assoc_info_t* assoc = SCTPAssocAnalyseDialog::findAssocForPacket(capture_file_.capFile());
2638 QString newFilter = QString("sctp.assoc_index==%1").arg(assoc->assoc_id);
2640 emit filterPackets(newFilter, false);
2645 void MainWindow::statCommandWlanStatistics(const char *arg, void *)
2647 WlanStatisticsDialog *wlan_stats_dlg = new WlanStatisticsDialog(*this, capture_file_, arg);
2648 connect(wlan_stats_dlg, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
2649 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
2650 wlan_stats_dlg->show();
2653 void MainWindow::on_actionWirelessWlanStatistics_triggered()
2655 statCommandWlanStatistics(NULL, NULL);
2659 void MainWindow::statCommandExpertInfo(const char *, void *)
2661 ExpertInfoDialog *expert_dialog = new ExpertInfoDialog(*this, capture_file_);
2662 const DisplayFilterEdit *df_edit = dynamic_cast<DisplayFilterEdit *>(df_combo_box_->lineEdit());
2664 expert_dialog->setDisplayFilter(df_edit->text());
2666 connect(expert_dialog, SIGNAL(goToPacket(int, int)),
2667 packet_list_, SLOT(goToPacket(int, int)));
2668 connect(expert_dialog, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
2669 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
2671 expert_dialog->show();
2674 void MainWindow::on_actionAnalyzeExpertInfo_triggered()
2676 statCommandExpertInfo(NULL, NULL);
2680 // Next / previous / first / last slots in packet_list
2684 void MainWindow::on_actionStatisticsFlowGraph_triggered()
2686 SequenceDialog *sequence_dialog = new SequenceDialog(*this, capture_file_);
2687 connect(sequence_dialog, SIGNAL(goToPacket(int)),
2688 packet_list_, SLOT(goToPacket(int)));
2689 sequence_dialog->show();
2692 void MainWindow::openTcpStreamDialog(int graph_type)
2694 TCPStreamDialog *stream_dialog = new TCPStreamDialog(this, capture_file_.capFile(), (tcp_graph_type)graph_type);
2695 connect(stream_dialog, SIGNAL(goToPacket(int)),
2696 packet_list_, SLOT(goToPacket(int)));
2697 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2698 stream_dialog, SLOT(setCaptureFile(capture_file*)));
2699 stream_dialog->show();
2702 void MainWindow::on_actionStatisticsTcpStreamStevens_triggered()
2704 openTcpStreamDialog(GRAPH_TSEQ_STEVENS);
2707 void MainWindow::on_actionStatisticsTcpStreamTcptrace_triggered()
2709 openTcpStreamDialog(GRAPH_TSEQ_TCPTRACE);
2712 void MainWindow::on_actionStatisticsTcpStreamThroughput_triggered()
2714 openTcpStreamDialog(GRAPH_THROUGHPUT);
2717 void MainWindow::on_actionStatisticsTcpStreamRoundTripTime_triggered()
2719 openTcpStreamDialog(GRAPH_RTT);
2722 void MainWindow::on_actionStatisticsTcpStreamWindowScaling_triggered()
2724 openTcpStreamDialog(GRAPH_WSCALE);
2728 void MainWindow::statCommandMulticastStatistics(const char *arg, void *)
2730 MulticastStatisticsDialog *mcast_stats_dlg = new MulticastStatisticsDialog(*this, capture_file_, arg);
2731 connect(mcast_stats_dlg, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
2732 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
2733 mcast_stats_dlg->show();
2736 void MainWindow::on_actionStatisticsUdpMulticastStreams_triggered()
2738 statCommandMulticastStatistics(NULL, NULL);
2741 void MainWindow::openStatisticsTreeDialog(const gchar *abbr)
2743 StatsTreeDialog *st_dialog = new StatsTreeDialog(*this, capture_file_, abbr);
2744 // connect(st_dialog, SIGNAL(goToPacket(int)),
2745 // packet_list_, SLOT(goToPacket(int)));
2749 void MainWindow::on_actionStatistics29WestTopics_Advertisements_by_Topic_triggered()
2751 openStatisticsTreeDialog("lbmr_topic_ads_topic");
2754 void MainWindow::on_actionStatistics29WestTopics_Advertisements_by_Source_triggered()
2756 openStatisticsTreeDialog("lbmr_topic_ads_source");
2759 void MainWindow::on_actionStatistics29WestTopics_Advertisements_by_Transport_triggered()
2761 openStatisticsTreeDialog("lbmr_topic_ads_transport");
2764 void MainWindow::on_actionStatistics29WestTopics_Queries_by_Topic_triggered()
2766 openStatisticsTreeDialog("lbmr_topic_queries_topic");
2769 void MainWindow::on_actionStatistics29WestTopics_Queries_by_Receiver_triggered()
2771 openStatisticsTreeDialog("lbmr_topic_queries_receiver");
2774 void MainWindow::on_actionStatistics29WestTopics_Wildcard_Queries_by_Pattern_triggered()
2776 openStatisticsTreeDialog("lbmr_topic_queries_pattern");
2779 void MainWindow::on_actionStatistics29WestTopics_Wildcard_Queries_by_Receiver_triggered()
2781 openStatisticsTreeDialog("lbmr_topic_queries_pattern_receiver");
2784 void MainWindow::on_actionStatistics29WestQueues_Advertisements_by_Queue_triggered()
2786 openStatisticsTreeDialog("lbmr_queue_ads_queue");
2789 void MainWindow::on_actionStatistics29WestQueues_Advertisements_by_Source_triggered()
2791 openStatisticsTreeDialog("lbmr_queue_ads_source");
2794 void MainWindow::on_actionStatistics29WestQueues_Queries_by_Queue_triggered()
2796 openStatisticsTreeDialog("lbmr_queue_queries_queue");
2799 void MainWindow::on_actionStatistics29WestQueues_Queries_by_Receiver_triggered()
2801 openStatisticsTreeDialog("lbmr_queue_queries_receiver");
2804 void MainWindow::on_actionStatistics29WestUIM_Streams_triggered()
2806 LBMStreamDialog *stream_dialog = new LBMStreamDialog(this, capture_file_.capFile());
2807 // connect(stream_dialog, SIGNAL(goToPacket(int)),
2808 // packet_list_, SLOT(goToPacket(int)));
2809 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2810 stream_dialog, SLOT(setCaptureFile(capture_file*)));
2811 stream_dialog->show();
2814 void MainWindow::on_actionStatistics29WestUIM_Stream_Flow_Graph_triggered()
2816 LBMUIMFlowDialog * uimflow_dialog = new LBMUIMFlowDialog(this, capture_file_.capFile());
2817 connect(uimflow_dialog, SIGNAL(goToPacket(int)),
2818 packet_list_, SLOT(goToPacket(int)));
2819 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2820 uimflow_dialog, SLOT(setCaptureFile(capture_file*)));
2821 uimflow_dialog->show();
2824 void MainWindow::on_actionStatistics29WestLBTRM_triggered()
2826 LBMLBTRMTransportDialog * lbtrm_dialog = new LBMLBTRMTransportDialog(this, capture_file_.capFile());
2827 connect(lbtrm_dialog, SIGNAL(goToPacket(int)),
2828 packet_list_, SLOT(goToPacket(int)));
2829 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2830 lbtrm_dialog, SLOT(setCaptureFile(capture_file*)));
2831 lbtrm_dialog->show();
2833 void MainWindow::on_actionStatistics29WestLBTRU_triggered()
2835 LBMLBTRUTransportDialog * lbtru_dialog = new LBMLBTRUTransportDialog(this, capture_file_.capFile());
2836 connect(lbtru_dialog, SIGNAL(goToPacket(int)),
2837 packet_list_, SLOT(goToPacket(int)));
2838 connect(this, SIGNAL(setCaptureFile(capture_file*)),
2839 lbtru_dialog, SLOT(setCaptureFile(capture_file*)));
2840 lbtru_dialog->show();
2843 void MainWindow::on_actionStatisticsANCP_triggered()
2845 openStatisticsTreeDialog("ancp");
2848 void MainWindow::on_actionStatisticsBACappInstanceId_triggered()
2850 openStatisticsTreeDialog("bacapp_instanceid");
2853 void MainWindow::on_actionStatisticsBACappIP_triggered()
2855 openStatisticsTreeDialog("bacapp_ip");
2858 void MainWindow::on_actionStatisticsBACappObjectId_triggered()
2860 openStatisticsTreeDialog("bacapp_objectid");
2863 void MainWindow::on_actionStatisticsBACappService_triggered()
2865 openStatisticsTreeDialog("bacapp_service");
2868 void MainWindow::on_actionStatisticsCollectd_triggered()
2870 openStatisticsTreeDialog("collectd");
2874 void MainWindow::statCommandConversations(const char *arg, void *userdata)
2876 ConversationDialog *conv_dialog = new ConversationDialog(*this, capture_file_, GPOINTER_TO_INT(userdata), arg);
2877 connect(conv_dialog, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
2878 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
2879 connect(conv_dialog, SIGNAL(openFollowStreamDialog(follow_type_t)),
2880 this, SLOT(openFollowStreamDialog(follow_type_t)));
2881 connect(conv_dialog, SIGNAL(openTcpStreamGraph(int)),
2882 this, SLOT(openTcpStreamDialog(int)));
2883 conv_dialog->show();
2886 void MainWindow::on_actionStatisticsConversations_triggered()
2888 statCommandConversations(NULL, NULL);
2892 void MainWindow::statCommandEndpoints(const char *arg, void *userdata)
2894 EndpointDialog *endp_dialog = new EndpointDialog(*this, capture_file_, GPOINTER_TO_INT(userdata), arg);
2895 connect(endp_dialog, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
2896 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
2897 connect(endp_dialog, SIGNAL(openFollowStreamDialog(follow_type_t)),
2898 this, SLOT(openFollowStreamDialog(follow_type_t)));
2899 connect(endp_dialog, SIGNAL(openTcpStreamGraph(int)),
2900 this, SLOT(openTcpStreamDialog(int)));
2901 endp_dialog->show();
2904 void MainWindow::on_actionStatisticsEndpoints_triggered()
2906 statCommandEndpoints(NULL, NULL);
2909 void MainWindow::on_actionStatisticsHART_IP_triggered()
2911 openStatisticsTreeDialog("hart_ip");
2914 void MainWindow::on_actionStatisticsHTTPPacketCounter_triggered()
2916 openStatisticsTreeDialog("http");
2919 void MainWindow::on_actionStatisticsHTTPRequests_triggered()
2921 openStatisticsTreeDialog("http_req");
2924 void MainWindow::on_actionStatisticsHTTPLoadDistribution_triggered()
2926 openStatisticsTreeDialog("http_srv");
2929 void MainWindow::on_actionStatisticsPacketLengths_triggered()
2931 openStatisticsTreeDialog("plen");
2935 void MainWindow::statCommandIOGraph(const char *, void *)
2937 IOGraphDialog *iog_dialog = new IOGraphDialog(*this, capture_file_);
2938 connect(iog_dialog, SIGNAL(goToPacket(int)), packet_list_, SLOT(goToPacket(int)));
2939 connect(this, SIGNAL(reloadFields()), iog_dialog, SLOT(reloadFields()));
2943 void MainWindow::on_actionStatisticsIOGraph_triggered()
2945 statCommandIOGraph(NULL, NULL);
2948 void MainWindow::on_actionStatisticsSametime_triggered()
2950 openStatisticsTreeDialog("sametime");
2953 void MainWindow::on_actionStatisticsDNS_triggered()
2955 openStatisticsTreeDialog("dns");
2958 void MainWindow::actionStatisticsPlugin_triggered()
2960 QAction* action = qobject_cast<QAction*>(sender());
2962 openStatisticsTreeDialog(action->data().toString().toUtf8());
2966 void MainWindow::on_actionStatisticsHTTP2_triggered()
2968 openStatisticsTreeDialog("http2");
2974 void MainWindow::openVoipCallsDialog(bool all_flows)
2976 VoipCallsDialog *voip_calls_dialog = new VoipCallsDialog(*this, capture_file_, all_flows);
2977 connect(voip_calls_dialog, SIGNAL(goToPacket(int)),
2978 packet_list_, SLOT(goToPacket(int)));
2979 connect(voip_calls_dialog, SIGNAL(updateFilter(QString, bool)),
2980 this, SLOT(filterPackets(QString, bool)));
2981 voip_calls_dialog->show();
2984 void MainWindow::on_actionTelephonyVoipCalls_triggered()
2986 openVoipCallsDialog();
2989 void MainWindow::on_actionTelephonyGsmMapSummary_triggered()
2991 GsmMapSummaryDialog *gms_dialog = new GsmMapSummaryDialog(*this, capture_file_);
2995 void MainWindow::on_actionTelephonyIax2StreamAnalysis_triggered()
2997 Iax2AnalysisDialog *iax2_analysis_dialog = new Iax2AnalysisDialog(*this, capture_file_);
2998 connect(iax2_analysis_dialog, SIGNAL(goToPacket(int)),
2999 packet_list_, SLOT(goToPacket(int)));
3000 iax2_analysis_dialog->show();
3003 void MainWindow::on_actionTelephonyISUPMessages_triggered()
3005 openStatisticsTreeDialog("isup_msg");
3009 void MainWindow::statCommandLteMacStatistics(const char *arg, void *)
3011 LteMacStatisticsDialog *lte_mac_stats_dlg = new LteMacStatisticsDialog(*this, capture_file_, arg);
3012 connect(lte_mac_stats_dlg, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
3013 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
3014 lte_mac_stats_dlg->show();
3017 void MainWindow::on_actionTelephonyLteMacStatistics_triggered()
3019 statCommandLteMacStatistics(NULL, NULL);
3022 void MainWindow::statCommandLteRlcStatistics(const char *arg, void *)
3024 LteRlcStatisticsDialog *lte_rlc_stats_dlg = new LteRlcStatisticsDialog(*this, capture_file_, arg);
3025 connect(lte_rlc_stats_dlg, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
3026 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
3027 lte_rlc_stats_dlg->show();
3030 void MainWindow::on_actionTelephonyLteRlcStatistics_triggered()
3032 statCommandLteRlcStatistics(NULL, NULL);
3035 void MainWindow::on_actionTelephonyLteRlcGraph_triggered()
3037 LteRlcGraphDialog *lrg_dialog = new LteRlcGraphDialog(*this, capture_file_);
3041 void MainWindow::on_actionTelephonyMtp3Summary_triggered()
3043 Mtp3SummaryDialog *mtp3s_dialog = new Mtp3SummaryDialog(*this, capture_file_);
3044 mtp3s_dialog->show();
3047 void MainWindow::on_actionTelephonyRTPStreams_triggered()
3049 RtpStreamDialog *rtp_stream_dialog = new RtpStreamDialog(*this, capture_file_);
3050 connect(rtp_stream_dialog, SIGNAL(packetsMarked()),
3051 packet_list_, SLOT(redrawVisiblePackets()));
3052 connect(rtp_stream_dialog, SIGNAL(goToPacket(int)),
3053 packet_list_, SLOT(goToPacket(int)));
3054 connect(rtp_stream_dialog, SIGNAL(updateFilter(QString, bool)),
3055 this, SLOT(filterPackets(QString, bool)));
3056 rtp_stream_dialog->show();
3059 void MainWindow::on_actionTelephonyRTPStreamAnalysis_triggered()
3061 RtpAnalysisDialog *rtp_analysis_dialog = new RtpAnalysisDialog(*this, capture_file_);
3062 connect(rtp_analysis_dialog, SIGNAL(goToPacket(int)),
3063 packet_list_, SLOT(goToPacket(int)));
3064 rtp_analysis_dialog->show();
3067 void MainWindow::on_actionTelephonyRTSPPacketCounter_triggered()
3069 openStatisticsTreeDialog("rtsp");
3072 void MainWindow::on_actionTelephonySMPPOperations_triggered()
3074 openStatisticsTreeDialog("smpp_commands");
3077 void MainWindow::on_actionTelephonyUCPMessages_triggered()
3079 openStatisticsTreeDialog("ucp_messages");
3082 void MainWindow::on_actionTelephonySipFlows_triggered()
3084 openVoipCallsDialog(true);
3089 void MainWindow::on_actionBluetoothATT_Server_Attributes_triggered()
3091 BluetoothAttServerAttributesDialog *bluetooth_att_sever_attributes_dialog = new BluetoothAttServerAttributesDialog(*this, capture_file_);
3092 connect(bluetooth_att_sever_attributes_dialog, SIGNAL(goToPacket(int)),
3093 packet_list_, SLOT(goToPacket(int)));
3094 connect(bluetooth_att_sever_attributes_dialog, SIGNAL(updateFilter(QString, bool)),
3095 this, SLOT(filterPackets(QString, bool)));
3096 bluetooth_att_sever_attributes_dialog->show();
3099 void MainWindow::on_actionBluetoothDevices_triggered()
3101 BluetoothDevicesDialog *bluetooth_devices_dialog = new BluetoothDevicesDialog(*this, capture_file_);
3102 connect(bluetooth_devices_dialog, SIGNAL(goToPacket(int)),
3103 packet_list_, SLOT(goToPacket(int)));
3104 connect(bluetooth_devices_dialog, SIGNAL(updateFilter(QString, bool)),
3105 this, SLOT(filterPackets(QString, bool)));
3106 bluetooth_devices_dialog->show();
3109 void MainWindow::on_actionBluetoothHCI_Summary_triggered()
3111 BluetoothHciSummaryDialog *bluetooth_hci_summary_dialog = new BluetoothHciSummaryDialog(*this, capture_file_);
3112 connect(bluetooth_hci_summary_dialog, SIGNAL(goToPacket(int)),
3113 packet_list_, SLOT(goToPacket(int)));
3114 connect(bluetooth_hci_summary_dialog, SIGNAL(updateFilter(QString, bool)),
3115 this, SLOT(filterPackets(QString, bool)));
3116 bluetooth_hci_summary_dialog->show();
3120 void MainWindow::on_actionHelpContents_triggered() {
3122 wsApp->helpTopicAction(HELP_CONTENT);
3125 void MainWindow::on_actionHelpMPWireshark_triggered() {
3127 wsApp->helpTopicAction(LOCALPAGE_MAN_WIRESHARK);
3130 void MainWindow::on_actionHelpMPWireshark_Filter_triggered() {
3131 wsApp->helpTopicAction(LOCALPAGE_MAN_WIRESHARK_FILTER);
3134 void MainWindow::on_actionHelpMPCapinfos_triggered() {
3135 wsApp->helpTopicAction(LOCALPAGE_MAN_CAPINFOS);
3138 void MainWindow::on_actionHelpMPDumpcap_triggered() {
3139 wsApp->helpTopicAction(LOCALPAGE_MAN_DUMPCAP);
3142 void MainWindow::on_actionHelpMPEditcap_triggered() {
3143 wsApp->helpTopicAction(LOCALPAGE_MAN_EDITCAP);
3146 void MainWindow::on_actionHelpMPMergecap_triggered() {
3147 wsApp->helpTopicAction(LOCALPAGE_MAN_MERGECAP);
3150 void MainWindow::on_actionHelpMPRawShark_triggered() {
3151 wsApp->helpTopicAction(LOCALPAGE_MAN_RAWSHARK);
3154 void MainWindow::on_actionHelpMPReordercap_triggered() {
3155 wsApp->helpTopicAction(LOCALPAGE_MAN_REORDERCAP);
3158 void MainWindow::on_actionHelpMPText2cap_triggered() {
3159 wsApp->helpTopicAction(LOCALPAGE_MAN_TEXT2PCAP);
3162 void MainWindow::on_actionHelpMPTShark_triggered() {
3163 wsApp->helpTopicAction(LOCALPAGE_MAN_TSHARK);
3166 void MainWindow::on_actionHelpWebsite_triggered() {
3168 wsApp->helpTopicAction(ONLINEPAGE_HOME);
3171 void MainWindow::on_actionHelpFAQ_triggered() {
3173 wsApp->helpTopicAction(ONLINEPAGE_FAQ);
3176 void MainWindow::on_actionHelpAsk_triggered() {
3178 wsApp->helpTopicAction(ONLINEPAGE_ASK);
3181 void MainWindow::on_actionHelpDownloads_triggered() {
3183 wsApp->helpTopicAction(ONLINEPAGE_DOWNLOAD);
3186 void MainWindow::on_actionHelpWiki_triggered() {
3188 wsApp->helpTopicAction(ONLINEPAGE_WIKI);
3191 void MainWindow::on_actionHelpSampleCaptures_triggered() {
3193 wsApp->helpTopicAction(ONLINEPAGE_SAMPLE_FILES);
3196 #ifdef HAVE_SOFTWARE_UPDATE
3197 void MainWindow::checkForUpdates()
3199 software_update_check();
3203 void MainWindow::on_actionHelpAbout_triggered()
3205 AboutDialog *about_dialog = new AboutDialog(this);
3207 if (about_dialog->isMinimized() == true)
3209 about_dialog->showNormal();
3213 about_dialog->show();
3216 about_dialog->raise();
3217 about_dialog->activateWindow();
3220 void MainWindow::on_actionGoGoToPacket_triggered() {
3221 if (packet_list_->model()->rowCount() < 1) {
3224 previous_focus_ = wsApp->focusWidget();
3225 connect(previous_focus_, SIGNAL(destroyed()), this, SLOT(resetPreviousFocus()));
3227 showAccordionFrame(main_ui_->goToFrame, true);
3228 if (main_ui_->goToFrame->isVisible()) {
3229 main_ui_->goToLineEdit->clear();
3230 main_ui_->goToLineEdit->setFocus();
3234 void MainWindow::on_actionGoGoToLinkedPacket_triggered()
3236 QAction *gta = qobject_cast<QAction*>(sender());
3240 int packet_num = gta->data().toInt(&ok);
3243 packet_list_->goToPacket(packet_num);
3246 void MainWindow::on_actionGoAutoScroll_toggled(bool checked)
3248 packet_list_->setAutoScroll(checked);
3251 void MainWindow::resetPreviousFocus() {
3252 previous_focus_ = NULL;
3255 void MainWindow::on_goToCancel_clicked()
3257 main_ui_->goToFrame->animatedHide();
3258 if (previous_focus_) {
3259 disconnect(previous_focus_, SIGNAL(destroyed()), this, SLOT(resetPreviousFocus()));
3260 previous_focus_->setFocus();
3261 resetPreviousFocus();
3265 void MainWindow::on_goToGo_clicked()
3267 gotoFrame(main_ui_->goToLineEdit->text().toInt());
3269 on_goToCancel_clicked();
3272 void MainWindow::on_goToLineEdit_returnPressed()
3274 on_goToGo_clicked();
3277 void MainWindow::on_actionCaptureStart_triggered()
3279 //#ifdef HAVE_AIRPCAP
3280 // airpcap_if_active = airpcap_if_selected;
3281 // if (airpcap_if_active)
3282 // airpcap_set_toolbar_start_capture(airpcap_if_active);
3285 // if (cap_open_w) {
3287 // * There's an options dialog; get the values from it and close it.
3289 // gboolean success;
3291 // /* Determine if "capture start" while building of the "capture options" window */
3292 // /* is in progress. If so, ignore the "capture start. */
3293 // /* XXX: Would it be better/cleaner for the "capture options" window code to */
3294 // /* disable the capture start button temporarily ? */
3295 // if (cap_open_complete == FALSE) {
3296 // return; /* Building options window: ignore "capture start" */
3298 // success = capture_dlg_prep(cap_open_w);
3299 // window_destroy(GTK_WIDGET(cap_open_w));
3301 // return; /* error in options dialog */
3305 if (global_capture_opts.num_selected == 0) {
3306 QString err_msg = tr("No Interface Selected");
3307 main_ui_->statusBar->pushTemporaryStatus(err_msg);
3308 main_ui_->actionCaptureStart->setChecked(false);
3312 /* XXX - will closing this remove a temporary file? */
3313 QString before_what(tr(" before starting a new capture"));
3314 if (testCaptureFileClose(FALSE, before_what)) {
3317 // simply clicking the button sets it to 'checked' even though we've
3318 // decided to do nothing, so undo that
3319 main_ui_->actionCaptureStart->setChecked(false);
3321 #endif // HAVE_LIBPCAP
3324 void MainWindow::on_actionCaptureStop_triggered()
3329 void MainWindow::on_actionCaptureRestart_triggered()
3331 /* TODO: GTK use only this: capture_restart(&cap_session_); */
3336 static FilterDialog *capture_filter_dlg_ = NULL;
3337 void MainWindow::on_actionCaptureCaptureFilters_triggered()
3339 if (!capture_filter_dlg_) {
3340 capture_filter_dlg_ = new FilterDialog(this, FilterDialog::CaptureFilter);
3342 capture_filter_dlg_->show();
3343 capture_filter_dlg_->raise();
3344 capture_filter_dlg_->activateWindow();
3347 void MainWindow::on_actionStatisticsCaptureFileProperties_triggered()
3349 CaptureFilePropertiesDialog *capture_file_properties_dialog = new CaptureFilePropertiesDialog(*this, capture_file_);
3350 connect(capture_file_properties_dialog, SIGNAL(captureCommentChanged()),
3351 this, SLOT(updateForUnsavedChanges()));
3352 capture_file_properties_dialog->show();
3355 void MainWindow::on_actionStatisticsResolvedAddresses_triggered()
3357 ResolvedAddressesDialog *resolved_addresses_dialog = new ResolvedAddressesDialog(this, &capture_file_);
3358 resolved_addresses_dialog->show();
3361 void MainWindow::on_actionStatisticsProtocolHierarchy_triggered()
3363 ProtocolHierarchyDialog *phd = new ProtocolHierarchyDialog(*this, capture_file_);
3364 connect(phd, SIGNAL(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)),
3365 this, SLOT(filterAction(QString&,FilterAction::Action,FilterAction::ActionType)));
3370 void MainWindow::on_actionCaptureOptions_triggered()
3372 connect(&capture_interfaces_dialog_, SIGNAL(setFilterValid(bool)), this, SLOT(startInterfaceCapture(bool)));
3373 capture_interfaces_dialog_.SetTab(0);
3374 capture_interfaces_dialog_.updateInterfaces();
3376 if (capture_interfaces_dialog_.isMinimized() == true)
3378 capture_interfaces_dialog_.showNormal();
3382 capture_interfaces_dialog_.show();
3385 capture_interfaces_dialog_.raise();
3386 capture_interfaces_dialog_.activateWindow();
3389 void MainWindow::on_actionCaptureRefreshInterfaces_triggered()
3391 wsApp->refreshLocalInterfaces();
3395 void MainWindow::externalMenuItem_triggered()
3397 QAction * triggerAction = NULL;
3399 ext_menubar_t * entry = NULL;
3401 if ( QObject::sender() != NULL)
3403 triggerAction = (QAction *)QObject::sender();
3404 v = triggerAction->data();
3406 if ( v.canConvert<void *>())
3408 entry = (ext_menubar_t *)v.value<void *>();
3410 if ( entry->type == EXT_MENUBAR_ITEM )
3412 entry->callback(EXT_MENUBAR_QT_GUI, (gpointer) ((void *)main_ui_), entry->user_data);
3416 QDesktopServices::openUrl(QUrl(QString((gchar *)entry->user_data)));
3422 void MainWindow::gotoFrame(int packet_num)
3424 if ( packet_num > 0 )
3426 packet_list_->goToPacket(packet_num);
3431 void MainWindow::extcap_options_finished(int result)
3433 if ( result == QDialog::Accepted )
3437 this->main_welcome_->getInterfaceTree()->interfaceListChanged();
3440 void MainWindow::showExtcapOptionsDialog(QString &device_name)
3442 ExtcapOptionsDialog * extcap_options_dialog = ExtcapOptionsDialog::createForDevice(device_name, this);
3443 /* The dialog returns null, if the given device name is not a valid extcap device */
3444 if ( extcap_options_dialog != NULL )
3446 connect(extcap_options_dialog, SIGNAL(finished(int)),
3447 this, SLOT(extcap_options_finished(int)));
3448 extcap_options_dialog->show();
3453 // Q_DECLARE_METATYPE(field_info *) called in proto_tree.h
3455 void MainWindow::on_actionContextCopyBytesHexTextDump_triggered()
3457 QAction *ca = qobject_cast<QAction*>(sender());
3460 field_info *fi = ca->data().value<field_info *>();
3462 byte_view_tab_->copyData(ByteViewTab::copyDataHexTextDump, fi);
3465 void MainWindow::on_actionContextCopyBytesHexDump_triggered()
3467 QAction *ca = qobject_cast<QAction*>(sender());
3470 field_info *fi = ca->data().value<field_info *>();
3472 byte_view_tab_->copyData(ByteViewTab::copyDataHexDump, fi);
3475 void MainWindow::on_actionContextCopyBytesPrintableText_triggered()
3477 QAction *ca = qobject_cast<QAction*>(sender());
3480 field_info *fi = ca->data().value<field_info *>();
3482 byte_view_tab_->copyData(ByteViewTab::copyDataPrintableText, fi);
3485 void MainWindow::on_actionContextCopyBytesHexStream_triggered()
3487 QAction *ca = qobject_cast<QAction*>(sender());
3490 field_info *fi = ca->data().value<field_info *>();
3492 byte_view_tab_->copyData(ByteViewTab::copyDataHexStream, fi);
3495 void MainWindow::on_actionContextCopyBytesBinary_triggered()
3497 QAction *ca = qobject_cast<QAction*>(sender());
3500 field_info *fi = ca->data().value<field_info *>();
3502 byte_view_tab_->copyData(ByteViewTab::copyDataBinary, fi);
3505 void MainWindow::on_actionContextWikiProtocolPage_triggered()
3507 QAction *wa = qobject_cast<QAction*>(sender());
3511 int field_id = wa->data().toInt(&ok);
3514 const QString proto_abbrev = proto_registrar_get_abbrev(field_id);
3516 int ret = QMessageBox::question(this, wsApp->windowTitleString(tr("Wiki Page for %1").arg(proto_abbrev)),
3517 tr("<p>The Wireshark Wiki is maintained by the community.</p>"
3518 "<p>The page you are about to load might be wonderful, "
3519 "incomplete, wrong, or nonexistent.</p>"
3520 "<p>Proceed to the wiki?</p>"),
3521 QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
3523 if (ret != QMessageBox::Yes) return;
3525 QUrl wiki_url = QString("https://wiki.wireshark.org/Protocols/%1").arg(proto_abbrev);
3526 QDesktopServices::openUrl(wiki_url);
3529 void MainWindow::on_actionContextFilterFieldReference_triggered()
3531 QAction *wa = qobject_cast<QAction*>(sender());
3535 int field_id = wa->data().toInt(&ok);
3538 const QString proto_abbrev = proto_registrar_get_abbrev(field_id);
3540 QUrl dfref_url = QString("https://www.wireshark.org/docs/dfref/%1/%2")
3541 .arg(proto_abbrev[0])
3543 QDesktopServices::openUrl(dfref_url);
3547 #pragma warning(pop)
3556 * indent-tabs-mode: nil
3559 * ex: set shiftwidth=4 tabstop=8 expandtab:
3560 * :indentSize=4:tabSize=8:noTabs=true: