diff options
Diffstat (limited to 'ui/qt')
-rw-r--r-- | ui/qt/CMakeLists.txt | 8 | ||||
-rw-r--r-- | ui/qt/Makefile.am | 4 | ||||
-rw-r--r-- | ui/qt/Makefile.common | 10 | ||||
-rw-r--r-- | ui/qt/Wireshark.pro | 8 | ||||
-rw-r--r-- | ui/qt/capture_file.cpp | 7 | ||||
-rw-r--r-- | ui/qt/capture_file.h | 3 | ||||
-rw-r--r-- | ui/qt/capture_file_progress_frame.cpp | 21 | ||||
-rw-r--r-- | ui/qt/funnel_statistics.cpp | 302 | ||||
-rw-r--r-- | ui/qt/funnel_statistics.h | 76 | ||||
-rw-r--r-- | ui/qt/funnel_string_dialog.cpp | 101 | ||||
-rw-r--r-- | ui/qt/funnel_string_dialog.h | 75 | ||||
-rw-r--r-- | ui/qt/funnel_string_dialog.ui | 67 | ||||
-rw-r--r-- | ui/qt/funnel_text_dialog.cpp | 239 | ||||
-rw-r--r-- | ui/qt/funnel_text_dialog.h | 98 | ||||
-rw-r--r-- | ui/qt/funnel_text_dialog.ui | 88 | ||||
-rw-r--r-- | ui/qt/main_window.cpp | 47 | ||||
-rw-r--r-- | ui/qt/main_window.h | 6 | ||||
-rw-r--r-- | ui/qt/main_window.ui | 21 | ||||
-rw-r--r-- | ui/qt/wireshark_application.cpp | 21 | ||||
-rw-r--r-- | ui/qt/wireshark_application.h | 2 |
20 files changed, 1194 insertions, 10 deletions
diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt index dbd57ad3c0..bb64a01df4 100644 --- a/ui/qt/CMakeLists.txt +++ b/ui/qt/CMakeLists.txt @@ -63,6 +63,9 @@ set(WIRESHARK_QT_HEADERS follow_stream_dialog.h follow_stream_text.h font_color_preferences_frame.h + funnel_string_dialog.h + funnel_text_dialog.h + funnel_statistics.h import_text_dialog.h interface_tree.h io_graph_dialog.h @@ -182,6 +185,8 @@ set(WIRESHARK_QT_SRC follow_stream_dialog.cpp follow_stream_text.cpp font_color_preferences_frame.cpp + funnel_string_dialog.cpp + funnel_text_dialog.cpp import_text_dialog.cpp interface_tree.cpp label_stack.cpp @@ -262,6 +267,7 @@ endif() set(WIRESHARK_QT_TAP_SRC conversation_dialog.cpp endpoint_dialog.cpp + funnel_statistics.cpp io_graph_dialog.cpp stats_tree_dialog.cpp ) @@ -293,6 +299,8 @@ set(WIRESHARK_QT_UI filter_expressions_preferences_frame.ui follow_stream_dialog.ui font_color_preferences_frame.ui + funnel_string_dialog.ui + funnel_text_dialog.ui import_text_dialog.ui io_graph_dialog.ui layout_preferences_frame.ui diff --git a/ui/qt/Makefile.am b/ui/qt/Makefile.am index 01cd6ab54b..cc9ff5aa1c 100644 --- a/ui/qt/Makefile.am +++ b/ui/qt/Makefile.am @@ -164,6 +164,10 @@ follow_stream_dialog.cpp: ui_follow_stream_dialog.h font_color_preferences_frame.cpp font_color_preferences_frame.h: ui_font_color_preferences_frame.h +funnel_string_dialog.cpp funnel_string_dialog.h: ui_funnel_string_dialog.h + +funnel_text_dialog.cpp funnel_text_dialog.h: ui_funnel_text_dialog.h + import_text_dialog.cpp import_text_dialog.h: ui_import_text_dialog.h io_graph_dialog.cpp io_graph_dialog.h: ui_io_graph_dialog.h diff --git a/ui/qt/Makefile.common b/ui/qt/Makefile.common index 9536d983ca..1e89b4c94b 100644 --- a/ui/qt/Makefile.common +++ b/ui/qt/Makefile.common @@ -51,6 +51,8 @@ NODIST_GENERATED_HEADER_FILES = \ ui_filter_expressions_preferences_frame.h \ ui_follow_stream_dialog.h \ ui_font_color_preferences_frame.h \ + ui_funnel_string_dialog.h \ + ui_funnel_text_dialog.h \ ui_import_text_dialog.h \ ui_io_graph_dialog.h \ ui_layout_preferences_frame.h \ @@ -168,6 +170,9 @@ MOC_HDRS = \ follow_stream_dialog.h \ follow_stream_text.h \ font_color_preferences_frame.h \ + funnel_string_dialog.h \ + funnel_text_dialog.h \ + funnel_statistics.h \ import_text_dialog.h \ interface_tree.h \ io_graph_dialog.h \ @@ -254,6 +259,8 @@ UI_FILES = \ filter_expressions_preferences_frame.ui \ follow_stream_dialog.ui \ font_color_preferences_frame.ui \ + funnel_string_dialog.ui \ + funnel_text_dialog.ui \ import_text_dialog.ui \ io_graph_dialog.ui \ layout_preferences_frame.ui \ @@ -387,6 +394,9 @@ WIRESHARK_QT_SRC = \ follow_stream_dialog.cpp \ follow_stream_text.cpp \ font_color_preferences_frame.cpp \ + funnel_string_dialog.cpp \ + funnel_text_dialog.cpp \ + funnel_statistics.cpp \ import_text_dialog.cpp \ interface_tree.cpp \ io_graph_dialog.cpp \ diff --git a/ui/qt/Wireshark.pro b/ui/qt/Wireshark.pro index f9d6a2b689..72140d221e 100644 --- a/ui/qt/Wireshark.pro +++ b/ui/qt/Wireshark.pro @@ -227,6 +227,8 @@ FORMS += \ filter_expressions_preferences_frame.ui \ follow_stream_dialog.ui \ font_color_preferences_frame.ui \ + funnel_string_dialog.ui \ + funnel_text_dialog.ui \ import_text_dialog.ui \ io_graph_dialog.ui \ layout_preferences_frame.ui \ @@ -299,6 +301,9 @@ HEADERS += $$HEADERS_WS_C \ follow_stream_dialog.h \ follow_stream_text.h \ font_color_preferences_frame.h \ + funnel_string_dialog.h \ + funnel_text_dialog.h \ + funnel_statistics.h \ layout_preferences_frame.h \ lbm_lbtrm_transport_dialog.h \ lbm_lbtru_transport_dialog.h \ @@ -662,6 +667,9 @@ SOURCES += \ follow_stream_dialog.cpp \ follow_stream_text.cpp \ font_color_preferences_frame.cpp \ + funnel_string_dialog.cpp \ + funnel_text_dialog.cpp \ + funnel_statistics.cpp \ import_text_dialog.cpp \ interface_tree.cpp \ io_graph_dialog.cpp \ diff --git a/ui/qt/capture_file.cpp b/ui/qt/capture_file.cpp index 37358e044d..82a26d1f19 100644 --- a/ui/qt/capture_file.cpp +++ b/ui/qt/capture_file.cpp @@ -96,6 +96,13 @@ void CaptureFile::retapPackets() } } +void CaptureFile::reload() +{ + if (cap_file_ && cap_file_->state == FILE_READ_DONE) { + cf_reload(cap_file_); + } +} + void CaptureFile::stopLoading() { setCaptureStopFlag(true); diff --git a/ui/qt/capture_file.h b/ui/qt/capture_file.h index 9fd8ba92c8..a4b77fdaaf 100644 --- a/ui/qt/capture_file.h +++ b/ui/qt/capture_file.h @@ -72,6 +72,9 @@ public: */ void retapPackets(); + /** Re;load the capture file + */ + void reload(); // XXX This shouldn't be needed. static capture_file *globalCapFile(); diff --git a/ui/qt/capture_file_progress_frame.cpp b/ui/qt/capture_file_progress_frame.cpp index 2a42958d26..329510f715 100644 --- a/ui/qt/capture_file_progress_frame.cpp +++ b/ui/qt/capture_file_progress_frame.cpp @@ -38,14 +38,10 @@ // - Start adding the progress bar to dialogs. // - Don't complain so loudly when the user stops a capture. -progdlg_t * -delayed_create_progress_dlg(const gpointer top_level_window, const gchar *task_title, const gchar *item_title, - gboolean terminate_is_stop, gboolean *stop_flag, - const GTimeVal *start_time, gfloat progress) -{ +progdlg_t *create_progress_dlg(const gpointer top_level_window, const gchar *task_title, const gchar *item_title, + gboolean terminate_is_stop, gboolean *stop_flag) { Q_UNUSED(task_title); Q_UNUSED(item_title); - Q_UNUSED(start_time); CaptureFileProgressFrame *cfpf; QWidget *main_window; @@ -65,7 +61,18 @@ delayed_create_progress_dlg(const gpointer top_level_window, const gchar *task_t if (!cfpf) { return NULL; } - return cfpf->show(true, terminate_is_stop, stop_flag, progress * 100); + return cfpf->show(true, terminate_is_stop, stop_flag, 0); +} + +progdlg_t * +delayed_create_progress_dlg(const gpointer top_level_window, const gchar *task_title, const gchar *item_title, + gboolean terminate_is_stop, gboolean *stop_flag, + const GTimeVal *start_time, gfloat progress) +{ + Q_UNUSED(start_time); + progdlg_t *progress_dialog = create_progress_dlg(top_level_window, task_title, item_title, terminate_is_stop, stop_flag); + update_progress_dlg(progress_dialog, progress, item_title); + return progress_dialog; } /* diff --git a/ui/qt/funnel_statistics.cpp b/ui/qt/funnel_statistics.cpp new file mode 100644 index 0000000000..d2d1ee3063 --- /dev/null +++ b/ui/qt/funnel_statistics.cpp @@ -0,0 +1,302 @@ +/* funnel_statistics.cpp + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include <glib.h> + +#include "color.h" +#include "color_filters.h" +#include "file.h" + +#include "epan/funnel.h" + +#include "ui/progress_dlg.h" + +#include "funnel_statistics.h" +#include "funnel_string_dialog.h" +#include "funnel_text_dialog.h" + +#include <QAction> +#include <QClipboard> +#include <QDebug> +#include <QDesktopServices> +#include <QUrl> + +#include "wireshark_application.h" + +// To do: +// - Handle menu paths. Do we create a new path (GTK+) or use the base element? +// - Add a FunnelGraphDialog class? + +extern "C" { +static void funnel_statistics_logger(const gchar *, GLogLevelFlags, const gchar *message, gpointer); +static void funnel_statistics_retap_packets(funnel_ops_id_t *ops_id); +static void funnel_statistics_copy_to_clipboard(GString *text); +static const gchar *funnel_statistics_get_filter(funnel_ops_id_t *ops_id); +static void funnel_statistics_set_filter(funnel_ops_id_t *ops_id, const char* filter_string); +static void funnel_statistics_set_color_filter_slot(guint8 filter_num, const gchar* filter_string); +static gboolean funnel_statistics_open_file(funnel_ops_id_t *ops_id, const char* fname, const char* filter, char**); +static void funnel_statistics_reload(funnel_ops_id_t *ops_id); +static void funnel_statistics_apply_filter(funnel_ops_id_t *ops_id); +static gboolean browser_open_url(const gchar *url); +static void browser_open_data_file(const gchar *filename); +static struct progdlg *progress_window_new(funnel_ops_id_t *ops_id, const gchar* title, const gchar* task, gboolean terminate_is_stop, gboolean *stop_flag); +static void progress_window_update(struct progdlg *progress_dialog, float percentage, const gchar* status); +static void progress_window_destroy(struct progdlg *progress_dialog); +} + +class FunnelAction : public QAction +{ +public: + FunnelAction(const QString title, void (*callback)(gpointer), gpointer callback_data, gboolean retap) : + QAction(NULL), + callback_(callback), + callback_data_(callback_data), + retap_(retap) + { + setText(title); + } + + void triggerCallback() { + if (callback_) { + callback_(callback_data_); + } + } + + bool retap() { + if (retap_) return true; + return false; + } + +private: + void (*callback_)(gpointer); + gpointer callback_data_; + gboolean retap_; +}; + +static QList<FunnelAction *> funnel_actions_; + +FunnelStatistics::FunnelStatistics(QObject *parent, CaptureFile &cf) : + QObject(parent), + capture_file_(cf) +{ + funnel_ops_ = new(struct _funnel_ops_t); + memset(funnel_ops_, 0, sizeof(struct _funnel_ops_t)); + + funnel_ops_->ops_id = (funnel_ops_id_t*) this; + funnel_ops_->new_text_window = text_window_new; + funnel_ops_->set_text = text_window_set_text; + funnel_ops_->append_text = text_window_append; + funnel_ops_->prepend_text = text_window_prepend; + funnel_ops_->clear_text = text_window_clear; + funnel_ops_->get_text = text_window_get_text; + funnel_ops_->set_close_cb = text_window_set_close_cb; + funnel_ops_->set_editable = text_window_set_editable; + funnel_ops_->destroy_text_window = text_window_destroy; + funnel_ops_->add_button = text_window_add_button; + funnel_ops_->new_dialog = string_dialog_new; + funnel_ops_->logger = funnel_statistics_logger; + funnel_ops_->retap_packets = funnel_statistics_retap_packets; + funnel_ops_->copy_to_clipboard = funnel_statistics_copy_to_clipboard; + funnel_ops_->get_filter = funnel_statistics_get_filter; + funnel_ops_->set_filter = funnel_statistics_set_filter; + funnel_ops_->set_color_filter_slot = funnel_statistics_set_color_filter_slot; + funnel_ops_->open_file = funnel_statistics_open_file; + funnel_ops_->reload = funnel_statistics_reload; + funnel_ops_->apply_filter = funnel_statistics_apply_filter; + funnel_ops_->browser_open_url = browser_open_url; + funnel_ops_->browser_open_data_file = browser_open_data_file; + funnel_ops_->new_progress_window = progress_window_new; + funnel_ops_->update_progress = progress_window_update; + funnel_ops_->destroy_progress_window = progress_window_destroy; + + funnel_set_funnel_ops(funnel_ops_); +} + +void FunnelStatistics::retapPackets() +{ + capture_file_.retapPackets(); +} + +struct progdlg *FunnelStatistics::progressDialogNew(const gchar *task_title, const gchar *item_title, gboolean terminate_is_stop, gboolean *stop_flag) +{ + return create_progress_dlg(capture_file_.window(), task_title, item_title, terminate_is_stop, stop_flag); +} + +const char *FunnelStatistics::displayFilter() +{ + return display_filter_.constData(); +} + +void FunnelStatistics::emitSetDisplayFilter(const QString &filter) +{ + emit setDisplayFilter(filter); +} + +void FunnelStatistics::reloadPackets() +{ + capture_file_.reload(); +} + +void FunnelStatistics::emitApplyDisplayFilter() +{ + emit applyDisplayFilter(); +} + +void FunnelStatistics::emitOpenCaptureFile(QString &cf_path, QString &filter) +{ + emit openCaptureFile(cf_path, filter); +} + +void FunnelStatistics::funnelActionTriggered() +{ + FunnelAction *funnel_action = dynamic_cast<FunnelAction *>(sender()); + if (!funnel_action) return; + + funnel_action->triggerCallback(); +} + +void FunnelStatistics::displayFilterTextChanged(const QString &filter) +{ + display_filter_ = filter.toUtf8(); +} + + +/* The GTK+ code says "finish this." We shall follow its lead */ +// XXX Finish this. +void funnel_statistics_logger(const gchar *, + GLogLevelFlags, + const gchar *message, + gpointer) { + qDebug() << message; +} +void funnel_statistics_retap_packets(funnel_ops_id_t *ops_id) { + FunnelStatistics *funnel_statistics = dynamic_cast<FunnelStatistics *>((FunnelStatistics *)ops_id); + if (!funnel_statistics) return; + + funnel_statistics->retapPackets(); +} + +void funnel_statistics_copy_to_clipboard(GString *text) { + wsApp->clipboard()->setText(text->str); +} + +const gchar *funnel_statistics_get_filter(funnel_ops_id_t *ops_id) { + FunnelStatistics *funnel_statistics = dynamic_cast<FunnelStatistics *>((FunnelStatistics *)ops_id); + if (!funnel_statistics) return NULL; + + return funnel_statistics->displayFilter(); +} + +void funnel_statistics_set_filter(funnel_ops_id_t *ops_id, const char* filter_string) { + FunnelStatistics *funnel_statistics = dynamic_cast<FunnelStatistics *>((FunnelStatistics *)ops_id); + if (!funnel_statistics) return; + + funnel_statistics->emitSetDisplayFilter(filter_string); +} + +void funnel_statistics_set_color_filter_slot(guint8 filter_num, const gchar* filter_string) { + color_filters_set_tmp(filter_num, (gchar *)filter_string, FALSE); +} + +gboolean funnel_statistics_open_file(funnel_ops_id_t *ops_id, const char* fname, const char* filter, char**) { + // XXX We need to return a proper error value. We should probably move + // MainWindow::openCaptureFile to CaptureFile and add error handling + // there. + FunnelStatistics *funnel_statistics = dynamic_cast<FunnelStatistics *>((FunnelStatistics *)ops_id); + if (!funnel_statistics) return FALSE; + + QString cf_name(fname); + QString cf_filter(filter); + funnel_statistics->emitOpenCaptureFile(cf_name, cf_filter); + return TRUE; +} + +void funnel_statistics_reload(funnel_ops_id_t *ops_id) { + FunnelStatistics *funnel_statistics = dynamic_cast<FunnelStatistics *>((FunnelStatistics *)ops_id); + if (!funnel_statistics) return; + + funnel_statistics->reloadPackets(); +} + +void funnel_statistics_apply_filter(funnel_ops_id_t *ops_id) { + FunnelStatistics *funnel_statistics = dynamic_cast<FunnelStatistics *>((FunnelStatistics *)ops_id); + if (!funnel_statistics) return; + + funnel_statistics->emitApplyDisplayFilter(); +} + +gboolean browser_open_url(const gchar *url) { + return QDesktopServices::openUrl(QUrl(url)) ? TRUE : FALSE; +} + +void browser_open_data_file(const gchar *filename) { + QDesktopServices::openUrl(QUrl::fromLocalFile(filename)); +} + +struct progdlg *progress_window_new(funnel_ops_id_t *ops_id, const gchar* task_title, const gchar* item_title, gboolean terminate_is_stop, gboolean *stop_flag) { + FunnelStatistics *funnel_statistics = dynamic_cast<FunnelStatistics *>((FunnelStatistics *)ops_id); + if (!funnel_statistics) return NULL; + + return funnel_statistics->progressDialogNew(task_title, item_title, terminate_is_stop, stop_flag); +} + +void progress_window_update(struct progdlg *progress_dialog, float percentage, const gchar* status) { + update_progress_dlg(progress_dialog, percentage, status); +} + +void progress_window_destroy(progdlg *progress_dialog) { + destroy_progress_dlg(progress_dialog); +} + +extern "C" { + +static void register_menu_cb(const char *name, + register_stat_group_t group, + void (*callback)(gpointer), + gpointer callback_data, + gboolean retap) { + FunnelAction *funnel_action = new FunnelAction(name, callback, callback_data, retap); + wsApp->addFunnelGroupItem(group, funnel_action); + funnel_actions_ << funnel_action; +} + +void +register_tap_listener_qt_funnel(void) +{ + funnel_register_all_menus(register_menu_cb); +} + +} // extern "C" + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/ui/qt/funnel_statistics.h b/ui/qt/funnel_statistics.h new file mode 100644 index 0000000000..ba8e2bf31d --- /dev/null +++ b/ui/qt/funnel_statistics.h @@ -0,0 +1,76 @@ +/* funnel_statistics.cpp + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef FUNNELSTATISTICS_H +#define FUNNELSTATISTICS_H + +#include <QObject> + +#include "capture_file.h" + +#include "funnel_text_dialog.h" + +struct _funnel_ops_t; +struct _funnel_progress_window_t; +struct progdlg; + +class FunnelStatistics : public QObject +{ + Q_OBJECT +public: + explicit FunnelStatistics(QObject *parent, CaptureFile &cf); + void retapPackets(); + struct progdlg *progressDialogNew(const gchar *task_title, const gchar *item_title, gboolean terminate_is_stop, gboolean *stop_flag); + const char *displayFilter(); + void emitSetDisplayFilter(const QString &filter); + void reloadPackets(); + void emitApplyDisplayFilter(); + void emitOpenCaptureFile(QString &cf_path, QString &filter); + +signals: + void setDisplayFilter(const QString &filter); + void applyDisplayFilter(); + void openCaptureFile(QString &cf_path, QString &filter); + +public slots: + void funnelActionTriggered(); + void displayFilterTextChanged(const QString &filter); + +private: + struct _funnel_ops_t *funnel_ops_; + CaptureFile &capture_file_; + QByteArray display_filter_; +}; + +#endif // FUNNELSTATISTICS_H + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/ui/qt/funnel_string_dialog.cpp b/ui/qt/funnel_string_dialog.cpp new file mode 100644 index 0000000000..187acbfd27 --- /dev/null +++ b/ui/qt/funnel_string_dialog.cpp @@ -0,0 +1,101 @@ +/* funnel_string_dialog.cpp + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "funnel_string_dialog.h" +#include "ui_funnel_string_dialog.h" + +#include <QLabel> +#include <QLineEdit> + +#include "qt_ui_utils.h" +#include "wireshark_application.h" + +const int min_edit_width_ = 20; // em widths +FunnelStringDialog::FunnelStringDialog(const QString title, const QStringList field_name_list, funnel_dlg_cb_t dialog_cb, void *dialog_cb_data) : + QDialog(NULL), + ui(new Ui::FunnelStringDialog), + dialog_cb_(dialog_cb), + dialog_cb_data_(dialog_cb_data) +{ + ui->setupUi(this); + setWindowTitle(wsApp->windowTitleString(title)); + int one_em = fontMetrics().height(); + + int row = 0; + foreach (QString field_name, field_name_list) { + QLabel *field_label = new QLabel(field_name, this); + ui->stringGridLayout->addWidget(field_label, row, 0); + QLineEdit *field_edit = new QLineEdit(this); + field_edit->setMinimumWidth(one_em * min_edit_width_); + field_edits_ << field_edit; + ui->stringGridLayout->addWidget(field_edit, row, 1); + row++; + } +} + +FunnelStringDialog::~FunnelStringDialog() +{ + delete ui; +} + +void FunnelStringDialog::on_buttonBox_accepted() +{ + if (!dialog_cb_) return; + + GPtrArray* returns = g_ptr_array_new(); + + foreach (QLineEdit *field_edit, field_edits_) { + g_ptr_array_add(returns, qstring_strdup(field_edit->text())); + } + g_ptr_array_add(returns, NULL); + + dialog_cb_((gchar**)returns->pdata, dialog_cb_data_); + + g_ptr_array_free(returns, FALSE); +} + +void FunnelStringDialog::stringDialogNew(const QString title, const QStringList field_name_list, funnel_dlg_cb_t dialog_cb, void *dialog_cb_data) +{ + FunnelStringDialog *fsd = new FunnelStringDialog(title, field_name_list, dialog_cb, dialog_cb_data); + fsd->show(); +} + +void string_dialog_new(const gchar *title, const gchar **fieldnames, funnel_dlg_cb_t dialog_cb, void *dialog_cb_data) +{ + QStringList field_name_list; + for (int i = 0; fieldnames[i]; i++) { + field_name_list << fieldnames[i]; + } + FunnelStringDialog::stringDialogNew(title, field_name_list, dialog_cb, dialog_cb_data); +} + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/ui/qt/funnel_string_dialog.h b/ui/qt/funnel_string_dialog.h new file mode 100644 index 0000000000..1f4dd9ae30 --- /dev/null +++ b/ui/qt/funnel_string_dialog.h @@ -0,0 +1,75 @@ +/* funnel_string_dialog.h + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef FUNNEL_STRING_DIALOG_H +#define FUNNEL_STRING_DIALOG_H + +#include <glib.h> + +#include "epan/funnel.h" + +#include <QDialog> + +class QLineEdit; + +namespace Ui { +class FunnelStringDialog; +} + +class FunnelStringDialog : public QDialog +{ + Q_OBJECT + +public: + explicit FunnelStringDialog(const QString title, const QStringList field_name_list, funnel_dlg_cb_t dialog_cb, void *dialog_cb_data); + ~FunnelStringDialog(); + + // Funnel ops + static void stringDialogNew(const QString title, const QStringList field_name_list, funnel_dlg_cb_t dialog_cb, void* dialog_cb_data); + +private slots: + void on_buttonBox_accepted(); + +private: + Ui::FunnelStringDialog *ui; + funnel_dlg_cb_t dialog_cb_; + void *dialog_cb_data_; + QList<QLineEdit *> field_edits_; +}; + +extern "C" { +void string_dialog_new(const gchar* title, const gchar** fieldnames, funnel_dlg_cb_t dialog_cb, void* dialog_cb_data); +} + +#endif // FUNNEL_STRING_DIALOG_H + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/ui/qt/funnel_string_dialog.ui b/ui/qt/funnel_string_dialog.ui new file mode 100644 index 0000000000..c6ba7e2d10 --- /dev/null +++ b/ui/qt/funnel_string_dialog.ui @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>FunnelStringDialog</class> + <widget class="QDialog" name="FunnelStringDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>176</width> + <height>66</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QGridLayout" name="stringGridLayout"/> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>FunnelStringDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>FunnelStringDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/ui/qt/funnel_text_dialog.cpp b/ui/qt/funnel_text_dialog.cpp new file mode 100644 index 0000000000..7aee7d165b --- /dev/null +++ b/ui/qt/funnel_text_dialog.cpp @@ -0,0 +1,239 @@ +/* funnel_text_dialog.cpp + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "funnel_text_dialog.h" +#include "ui_funnel_text_dialog.h" + +#include <QPushButton> +#include <QRegExp> +#include <QTextCharFormat> +#include <QTextCursor> + +#include "qt_ui_utils.h" +#include "wireshark_application.h" + +// To do: +// - Add "Find next" to highlighting. +// - Add rich text support? +// - Zoom text? + +static QHash<QObject *, funnel_bt_t*> text_button_to_funnel_button_; + +FunnelTextDialog::FunnelTextDialog() : + QDialog(NULL), + ui(new Ui::FunnelTextDialog), + close_cb_(NULL), + close_cb_data_(NULL) +{ + ui->setupUi(this); + + funnel_text_window_.funnel_text_dialog = this; + + ui->textEdit->setFont(wsApp->monospaceFont()); + ui->textEdit->setReadOnly(true); + ui->textEdit->setAcceptRichText(false); +} + +FunnelTextDialog::~FunnelTextDialog() +{ + delete ui; + + if (close_cb_) { + close_cb_(close_cb_data_); + } +} + +struct _funnel_text_window_t *FunnelTextDialog::textWindowNew(const QString title) +{ + FunnelTextDialog *ftd = new FunnelTextDialog(); + ftd->setWindowTitle(wsApp->windowTitleString(title)); + ftd->show(); + return &ftd->funnel_text_window_; +} + +void FunnelTextDialog::setText(const QString text) +{ + ui->textEdit->setText(text); +} + +void FunnelTextDialog::appendText(const QString text) +{ + ui->textEdit->moveCursor(QTextCursor::Start); + ui->textEdit->insertPlainText(text); +} + +void FunnelTextDialog::prependText(const QString text) +{ + ui->textEdit->moveCursor(QTextCursor::End); + ui->textEdit->insertPlainText(text); +} + +void FunnelTextDialog::clearText() +{ + ui->textEdit->clear(); +} + +const char *FunnelTextDialog::getText() +{ + return qstring_strdup(ui->textEdit->toPlainText()); +} + +void FunnelTextDialog::setCloseCallback(text_win_close_cb_t close_cb, void *close_cb_data) +{ + close_cb_ = close_cb; + close_cb_data_ = close_cb_data; +} + +void FunnelTextDialog::setTextEditable(gboolean editable) +{ + ui->textEdit->setReadOnly(!editable); +} + +void FunnelTextDialog::addButton(funnel_bt_t *funnel_button, const QString label) +{ + QPushButton *button = new QPushButton(label); + ui->buttonBox->addButton(button, QDialogButtonBox::ActionRole); + text_button_to_funnel_button_[button] = funnel_button; + connect(button, SIGNAL(clicked(bool)), this, SLOT(buttonClicked())); +} + +void FunnelTextDialog::buttonClicked() +{ + if (text_button_to_funnel_button_.contains(sender())) { + funnel_bt_t *funnel_button = text_button_to_funnel_button_[sender()]; + if (funnel_button) { + funnel_button->func(&funnel_text_window_, funnel_button->data); + } + } +} + +void FunnelTextDialog::on_findLineEdit_textChanged(const QString &pattern) +{ + QRegExp re(pattern, Qt::CaseInsensitive); + QTextCharFormat plain_fmt, highlight_fmt; + highlight_fmt.setBackground(Qt::yellow); + QTextCursor csr(ui->textEdit->document()); + int position = csr.position(); + + setUpdatesEnabled(false); + + // Reset highlighting + csr.movePosition(QTextCursor::Start); + csr.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); + csr.setCharFormat(plain_fmt); + + // Apply new highlighting + if (!pattern.isEmpty()) { + int match_pos = 0; + while ((match_pos = re.indexIn(ui->textEdit->toPlainText(), match_pos)) > -1) { + csr.setPosition(match_pos, QTextCursor::MoveAnchor); + csr.setPosition(match_pos + re.matchedLength(), QTextCursor::KeepAnchor); + csr.setCharFormat(highlight_fmt); + match_pos += re.matchedLength(); + } + } + + // Restore cursor and anchor + csr.setPosition(position, QTextCursor::MoveAnchor); + setUpdatesEnabled(true); +} + +struct _funnel_text_window_t* text_window_new(const char* title) +{ + return FunnelTextDialog::textWindowNew(title); +} + +void text_window_set_text(funnel_text_window_t *ftw, const char* text) +{ + if (ftw) { + ftw->funnel_text_dialog->setText(text); + } +} + +void text_window_append(funnel_text_window_t* ftw, const char* text) +{ + if (ftw) { + ftw->funnel_text_dialog->appendText(text); + } +} + +void text_window_prepend(funnel_text_window_t *ftw, const char* text) +{ + if (ftw) { + ftw->funnel_text_dialog->prependText(text); + } +} + +void text_window_clear(funnel_text_window_t* ftw) +{ + if (ftw) { + ftw->funnel_text_dialog->clearText(); + } +} + +const char *text_window_get_text(funnel_text_window_t *ftw) +{ + if (ftw) { + return ftw->funnel_text_dialog->getText(); + } + return NULL; +} + +void text_window_set_close_cb(funnel_text_window_t *ftw, text_win_close_cb_t close_cb, void *close_cb_data) +{ + if (ftw) { + ftw->funnel_text_dialog->setCloseCallback(close_cb, close_cb_data); + } +} + +void text_window_set_editable(funnel_text_window_t *ftw, gboolean editable) +{ + if (ftw) { + ftw->funnel_text_dialog->setTextEditable(editable); + } +} + +void text_window_destroy(funnel_text_window_t *ftw) +{ + if (ftw) { + ftw->funnel_text_dialog->close(); + } +} + +void text_window_add_button(funnel_text_window_t *ftw, funnel_bt_t *funnel_button, const char *label) +{ + if (ftw) { + ftw->funnel_text_dialog->addButton(funnel_button, label); + } +} + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/ui/qt/funnel_text_dialog.h b/ui/qt/funnel_text_dialog.h new file mode 100644 index 0000000000..0ee9be5edf --- /dev/null +++ b/ui/qt/funnel_text_dialog.h @@ -0,0 +1,98 @@ +/* funnel_text_dialog.h + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef FUNNEL_TEXT_DIALOG_H +#define FUNNEL_TEXT_DIALOG_H + +#include <glib.h> + +#include "epan/funnel.h" + +#include <QDialog> + +namespace Ui { +class FunnelTextDialog; +} + +class FunnelTextDialog; +struct _funnel_text_window_t { + FunnelTextDialog* funnel_text_dialog; +}; + +class FunnelTextDialog : public QDialog +{ + Q_OBJECT + +public: + explicit FunnelTextDialog(); + ~FunnelTextDialog(); + + // Funnel ops + static struct _funnel_text_window_t *textWindowNew(const QString title); + void setText(const QString text); + void appendText(const QString text); + void prependText(const QString text); + void clearText(); + const char *getText(); + void setCloseCallback(text_win_close_cb_t close_cb, void* close_cb_data); + void setTextEditable(gboolean editable); + void addButton(funnel_bt_t *button_cb, const QString label); + +private slots: + void buttonClicked(); + void on_findLineEdit_textChanged(const QString &pattern); + +private: + Ui::FunnelTextDialog *ui; + + struct _funnel_text_window_t funnel_text_window_; + text_win_close_cb_t close_cb_; + void *close_cb_data_; +}; + +extern "C" { +struct _funnel_text_window_t* text_window_new(const char* title); +void text_window_set_text(funnel_text_window_t* ftw, const char* text); +void text_window_append(funnel_text_window_t *ftw, const char* text); +void text_window_prepend(funnel_text_window_t* ftw, const char* text); +void text_window_clear(funnel_text_window_t *ftw); +const char *text_window_get_text(funnel_text_window_t* ftw); +void text_window_set_close_cb(funnel_text_window_t *ftw, text_win_close_cb_t close_cb, void* close_cb_data); +void text_window_set_editable(funnel_text_window_t* ftw, gboolean editable); +void text_window_destroy(funnel_text_window_t* ftw); +void text_window_add_button(funnel_text_window_t* ftw, funnel_bt_t* funnel_button, const char* label); +} + + +#endif // FUNNEL_TEXT_DIALOG_H + +/* + * Editor modelines + * + * Local Variables: + * c-basic-offset: 4 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * ex: set shiftwidth=4 tabstop=8 expandtab: + * :indentSize=4:tabSize=8:noTabs=true: + */ diff --git a/ui/qt/funnel_text_dialog.ui b/ui/qt/funnel_text_dialog.ui new file mode 100644 index 0000000000..80bb02f371 --- /dev/null +++ b/ui/qt/funnel_text_dialog.ui @@ -0,0 +1,88 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>FunnelTextDialog</class> + <widget class="QDialog" name="FunnelTextDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>620</width> + <height>450</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QTextEdit" name="textEdit"/> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="label"> + <property name="toolTip"> + <string><html><head/><body><p>Enter some text or a regular expression. It will be highlighted above.</p></body></html></string> + </property> + <property name="text"> + <string>Highlight:</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="findLineEdit"> + <property name="toolTip"> + <string><html><head/><body><p>Enter some text or a regular expression. It will be highlighted above.</p></body></html></string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Close</set> + </property> + </widget> + </item> + </layout> + </widget> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>FunnelTextDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>FunnelTextDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/ui/qt/main_window.cpp b/ui/qt/main_window.cpp index 737aadc511..312769829d 100644 --- a/ui/qt/main_window.cpp +++ b/ui/qt/main_window.cpp @@ -47,6 +47,7 @@ #include "byte_view_tab.h" #include "display_filter_edit.h" #include "export_dissection_dialog.h" +#include "funnel_statistics.h" #include "import_text_dialog.h" #include "packet_list.h" #include "proto_tree.h" @@ -202,6 +203,7 @@ MainWindow::MainWindow(QWidget *parent) : show_hide_actions_(NULL), time_display_actions_(NULL), time_precision_actions_(NULL), + funnel_statistics_(new FunnelStatistics(this, capture_file_)), capture_stopping_(false), capture_filter_valid_(false), #ifdef _WIN32 @@ -239,6 +241,7 @@ MainWindow::MainWindow(QWidget *parent) : connect(wsApp, SIGNAL(appInitialized()), this, SLOT(addStatsPluginsToMenu())); connect(wsApp, SIGNAL(appInitialized()), this, SLOT(addStatisticsMenus())); connect(wsApp, SIGNAL(appInitialized()), this, SLOT(addExternalMenus())); + connect(wsApp, SIGNAL(appInitialized()), this, SLOT(addFunnelMenus())); connect(wsApp, SIGNAL(profileChanging()), this, SLOT(saveWindowGeometry())); connect(wsApp, SIGNAL(preferencesChanged()), this, SLOT(layoutPanes())); @@ -262,6 +265,11 @@ MainWindow::MainWindow(QWidget *parent) : main_ui_->statusBar, SLOT(pushTemporaryStatus(const QString&))); connect(df_edit, SIGNAL(filterPackets(QString&,bool)), this, SLOT(filterPackets(QString&,bool))); connect(df_edit, SIGNAL(addBookmark(QString)), this, SLOT(addDisplayFilterButton(QString))); + connect(df_edit, SIGNAL(textChanged(QString)), funnel_statistics_, SLOT(displayFilterTextChanged(QString))); + connect(funnel_statistics_, SIGNAL(setDisplayFilter(QString)), df_edit, SLOT(setText(QString))); + connect(funnel_statistics_, SIGNAL(applyDisplayFilter()), df_combo_box_, SLOT(applyDisplayFilter())); + connect(funnel_statistics_, SIGNAL(openCaptureFile(QString&,QString&)), + this, SLOT(openCaptureFile(QString&,QString&))); connect(this, SIGNAL(displayFilterSuccess(bool)), df_edit, SLOT(displayFilterSuccess(bool))); initMainToolbarIcons(); @@ -1971,8 +1979,6 @@ void MainWindow::setForCaptureInProgress(gboolean capture_in_progress) void MainWindow::addStatisticsMenus() { - - // Unsorted // actionStatistics_REGISTER_STAT_GROUP_UNSORTED should exist and be. // invisible. QList<QAction *>unsorted_actions = wsApp->statisticsGroupItems(REGISTER_STAT_GROUP_UNSORTED); @@ -2066,6 +2072,43 @@ void MainWindow::addExternalMenus() } } +void MainWindow::addFunnelMenus() +{ + // XXX Add support for MENU_STAT_UNSORTED, MENU_STAT_GENERIC, etc. We + // should probably add a common routine that we can use in + // addStatisticsMenus as well. + QList<QAction *>funnel_actions = wsApp->funnelGroupItems(REGISTER_TOOLS_GROUP_UNSORTED); + + // Empty menus don't show up: https://bugreports.qt.io/browse/QTBUG-33728 + // We've added a placeholder in order to make sure the "Tools" menu is + // visible. Hide it as needed. + if (funnel_actions.length() > 0) { + main_ui_->actionToolsPlaceholder->setVisible(false); + } + + foreach (QAction *tools_action, funnel_actions) { + QStringList menu_path = tools_action->text().split('/'); + QMenu *cur_menu = main_ui_->menuTools; + while (menu_path.length() > 1) { + QString menu_title = menu_path.takeFirst(); +#if (QT_VERSION > QT_VERSION_CHECK(5, 0, 0)) + QMenu *submenu = cur_menu->findChild<QMenu *>(menu_title.toLower(), Qt::FindDirectChildrenOnly); +#else + QMenu *submenu = cur_menu->findChild<QMenu *>(menu_title.toLower()); + if (submenu && submenu->parent() != cur_menu) submenu = NULL; +#endif + if (!submenu) { + submenu = cur_menu->addMenu(menu_title); + submenu->setObjectName(menu_title.toLower()); + } + cur_menu = submenu; + } + tools_action->setText(menu_path.last()); + cur_menu->addAction(tools_action); + connect(tools_action, SIGNAL(triggered(bool)), funnel_statistics_, SLOT(funnelActionTriggered())); + } +} + /* * Editor modelines * diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h index ea53ad115a..0bc10938bc 100644 --- a/ui/qt/main_window.h +++ b/ui/qt/main_window.h @@ -61,6 +61,7 @@ class AccordionFrame; class ByteViewTab; +class FunnelStatistics; class MainWelcome; class PacketList; class ProtoTree; @@ -136,6 +137,7 @@ private: QActionGroup *show_hide_actions_; QActionGroup *time_display_actions_; QActionGroup *time_precision_actions_; + FunnelStatistics *funnel_statistics_; bool capture_stopping_; bool capture_filter_valid_; @@ -207,7 +209,8 @@ public slots: * @return True on success, false on failure. */ // XXX We might want to return a cf_read_status_t or a CaptureFile. - bool openCaptureFile(QString& cf_path = *new QString(), QString& display_filter = *new QString(), unsigned int type = WTAP_TYPE_AUTO); + bool openCaptureFile(QString& cf_path, QString& display_filter, unsigned int type); + bool openCaptureFile(QString& cf_path = *new QString(), QString& display_filter = *new QString()) { return openCaptureFile(cf_path, display_filter, WTAP_TYPE_AUTO); } void filterPackets(QString& new_filter = *new QString(), bool force = false); void updateForUnsavedChanges(); void layoutPanes(); @@ -261,6 +264,7 @@ private slots: void addStatsPluginsToMenu(); void addStatisticsMenus(); void addExternalMenus(); + void addFunnelMenus(); void startInterfaceCapture(bool valid); diff --git a/ui/qt/main_window.ui b/ui/qt/main_window.ui index 50cef78629..72f163c7e9 100644 --- a/ui/qt/main_window.ui +++ b/ui/qt/main_window.ui @@ -539,6 +539,12 @@ <addaction name="actionATT_Server_Attributes"/> <addaction name="actionDevices"/> </widget> + <widget class="QMenu" name="menuTools"> + <property name="title"> + <string>Tools</string> + </property> + <addaction name="actionToolsPlaceholder"/> + </widget> <addaction name="menuFile"/> <addaction name="menuEdit"/> <addaction name="menuView"/> @@ -547,6 +553,7 @@ <addaction name="menuAnalyze"/> <addaction name="menuStatistics"/> <addaction name="menuTelephony"/> + <addaction name="menuTools"/> <addaction name="menuBluetooth"/> <addaction name="menuHelp"/> </widget> @@ -2369,6 +2376,20 @@ <enum>QAction::NoRole</enum> </property> </action> + <action name="actionToolsPlaceholder"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>No tools registered</string> + </property> + <property name="toolTip"> + <string>No tools have been registered.</string> + </property> + <property name="menuRole"> + <enum>QAction::NoRole</enum> + </property> + </action> </widget> <layoutdefault spacing="6" margin="11"/> <customwidgets> diff --git a/ui/qt/wireshark_application.cpp b/ui/qt/wireshark_application.cpp index e34c1ae3dc..1439c72f0f 100644 --- a/ui/qt/wireshark_application.cpp +++ b/ui/qt/wireshark_application.cpp @@ -90,6 +90,7 @@ static char *last_open_dir = NULL; static bool updated_last_open_dir = FALSE; static QList<recent_item_status *> recent_items_; static QHash<int, QList<QAction *> > statistics_groups_; +static QHash<int, QList<QAction *> > funnel_groups_; QString WiresharkApplication::window_title_separator_ = QString::fromUtf8(" " UTF8_MIDDLE_DOT " "); @@ -571,6 +572,7 @@ void WiresharkApplication::emitTapParameterSignal(const QString cfg_abbr, const emit openTapParameterDialog(cfg_abbr, arg, userdata); } +// XXX Combine statistics and funnel routines into addGroupItem + groupItems? void WiresharkApplication::addStatisticsGroupItem(int group, QAction *sg_action) { if (!statistics_groups_.contains(group)) { @@ -590,6 +592,25 @@ QList<QAction *> WiresharkApplication::statisticsGroupItems(int group) return sgi_list; } +void WiresharkApplication::addFunnelGroupItem(int group, QAction *fg_action) +{ + if (!funnel_groups_.contains(group)) { + funnel_groups_[group] = QList<QAction *>(); + } + funnel_groups_[group] << fg_action; +} + +QList<QAction *> WiresharkApplication::funnelGroupItems(int group) +{ + if (!funnel_groups_.contains(group)) { + return QList<QAction *>(); + } + + QList<QAction *> fgi_list = funnel_groups_[group]; + std::sort(fgi_list.begin(), fgi_list.end(), qActionLessThan); + return fgi_list; +} + #ifdef HAVE_LIBPCAP static void diff --git a/ui/qt/wireshark_application.h b/ui/qt/wireshark_application.h index 5cfd5ee032..1b7941e8e8 100644 --- a/ui/qt/wireshark_application.h +++ b/ui/qt/wireshark_application.h @@ -77,6 +77,8 @@ public: // Map a register_stat_group_t to a list of stat_tap_ui.title void addStatisticsGroupItem(int group, QAction *sg_action); QList<QAction *>statisticsGroupItems(int group); + void addFunnelGroupItem(int group, QAction *fg_action); + QList<QAction *> funnelGroupItems(int group); void allSystemsGo(); void refreshLocalInterfaces(); |