aboutsummaryrefslogtreecommitdiffstats
path: root/ui/qt
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2015-07-08 15:44:04 -0700
committerGerald Combs <gerald@wireshark.org>2015-07-09 00:05:51 +0000
commita8faa04234a5ac07c37da41d42ed943e8ebf5406 (patch)
treeb661f5ab0244abf0bb8a7d9ec712b25a7000b2d2 /ui/qt
parent131e0ab7ea461d519f0fbe80b03aa6bc99b9d452 (diff)
Qt: Add dynamic menu support.
Generalize the dynamic menu code and make it possible to connect multiple types of actions to their corresponding slots. Change-Id: Ib915ad5a666310e2a6e366fada006336820d1653 Reviewed-on: https://code.wireshark.org/review/9568 Reviewed-by: Gerald Combs <gerald@wireshark.org>
Diffstat (limited to 'ui/qt')
-rw-r--r--ui/qt/funnel_statistics.cpp4
-rw-r--r--ui/qt/funnel_statistics.h2
-rw-r--r--ui/qt/main_window.cpp147
-rw-r--r--ui/qt/main_window.h3
-rw-r--r--ui/qt/main_window.ui15
-rw-r--r--ui/qt/tap_parameter_dialog.cpp4
-rw-r--r--ui/qt/tap_parameter_dialog.h2
-rw-r--r--ui/qt/wireshark_application.cpp35
-rw-r--r--ui/qt/wireshark_application.h7
9 files changed, 121 insertions, 98 deletions
diff --git a/ui/qt/funnel_statistics.cpp b/ui/qt/funnel_statistics.cpp
index d2d1ee3063..a1cd51c62e 100644
--- a/ui/qt/funnel_statistics.cpp
+++ b/ui/qt/funnel_statistics.cpp
@@ -74,6 +74,7 @@ public:
retap_(retap)
{
setText(title);
+ setObjectName(FunnelStatistics::actionName());
}
void triggerCallback() {
@@ -94,6 +95,7 @@ private:
};
static QList<FunnelAction *> funnel_actions_;
+const QString FunnelStatistics::action_name_ = "FunnelStatisticsAction";
FunnelStatistics::FunnelStatistics(QObject *parent, CaptureFile &cf) :
QObject(parent),
@@ -276,7 +278,7 @@ static void register_menu_cb(const char *name,
gpointer callback_data,
gboolean retap) {
FunnelAction *funnel_action = new FunnelAction(name, callback, callback_data, retap);
- wsApp->addFunnelGroupItem(group, funnel_action);
+ wsApp->addDynamicMenuGroupItem(group, funnel_action);
funnel_actions_ << funnel_action;
}
diff --git a/ui/qt/funnel_statistics.h b/ui/qt/funnel_statistics.h
index ba8e2bf31d..19778cef6e 100644
--- a/ui/qt/funnel_statistics.h
+++ b/ui/qt/funnel_statistics.h
@@ -44,6 +44,7 @@ public:
void reloadPackets();
void emitApplyDisplayFilter();
void emitOpenCaptureFile(QString &cf_path, QString &filter);
+ static const QString &actionName() { return action_name_; }
signals:
void setDisplayFilter(const QString &filter);
@@ -55,6 +56,7 @@ public slots:
void displayFilterTextChanged(const QString &filter);
private:
+ static const QString action_name_;
struct _funnel_ops_t *funnel_ops_;
CaptureFile &capture_file_;
QByteArray display_filter_;
diff --git a/ui/qt/main_window.cpp b/ui/qt/main_window.cpp
index 9a462e0578..16297ec08a 100644
--- a/ui/qt/main_window.cpp
+++ b/ui/qt/main_window.cpp
@@ -53,6 +53,7 @@
#include "proto_tree.h"
#include "simple_dialog.h"
#include "stock_icon.h"
+#include "tap_parameter_dialog.h"
#include "wireless_frame.h"
#include "wireshark_application.h"
@@ -239,9 +240,8 @@ MainWindow::MainWindow(QWidget *parent) :
connect(wsApp, SIGNAL(appInitialized()), this, SLOT(setFeaturesEnabled()));
connect(wsApp, SIGNAL(appInitialized()), this, SLOT(zoomText()));
connect(wsApp, SIGNAL(appInitialized()), this, SLOT(addStatsPluginsToMenu()));
- connect(wsApp, SIGNAL(appInitialized()), this, SLOT(addStatisticsMenus()));
+ connect(wsApp, SIGNAL(appInitialized()), this, SLOT(addDynamicMenus()));
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()));
@@ -1977,33 +1977,93 @@ void MainWindow::setForCaptureInProgress(gboolean capture_in_progress)
#endif
}
-void MainWindow::addStatisticsMenus()
+void MainWindow::addDynamicMenus()
{
- // actionStatistics_REGISTER_STAT_GROUP_UNSORTED should exist and be.
- // invisible.
- QList<QAction *>unsorted_actions = wsApp->statisticsGroupItems(REGISTER_STAT_GROUP_UNSORTED);
-
- foreach (QAction *unsorted_action, unsorted_actions) {
- main_ui_->menuStatistics->insertAction(
- main_ui_->actionStatistics_REGISTER_STAT_GROUP_UNSORTED,
- unsorted_action);
- connect(unsorted_action, SIGNAL(triggered(bool)), this, SLOT(openTapParameterDialog()));
- }
-
- // Response time
- QList<QAction *>sg_actions = wsApp->statisticsGroupItems(REGISTER_STAT_GROUP_RESPONSE_TIME);
+ QList<register_stat_group_t> menu_groups = QList<register_stat_group_t>()
+ << REGISTER_ANALYZE_GROUP_UNSORTED
+ << REGISTER_ANALYZE_GROUP_CONVERSATION_FILTER
+ << REGISTER_STAT_GROUP_UNSORTED
+ << REGISTER_STAT_GROUP_GENERIC
+ << REGISTER_STAT_GROUP_CONVERSATION_LIST
+ << REGISTER_STAT_GROUP_ENDPOINT_LIST
+ << REGISTER_STAT_GROUP_RESPONSE_TIME
+ << REGISTER_STAT_GROUP_TELEPHONY
+ << REGISTER_STAT_GROUP_TELEPHONY_ANSI
+ << REGISTER_STAT_GROUP_TELEPHONY_GSM
+ << REGISTER_STAT_GROUP_TELEPHONY_LTE
+ << REGISTER_STAT_GROUP_TELEPHONY_SCTP
+ << REGISTER_TOOLS_GROUP_UNSORTED;
+
+ foreach (register_stat_group_t menu_group, menu_groups) {
+ QList<QAction *>actions = wsApp->dynamicMenuGroupItems(menu_group);
+ foreach (QAction *action, actions) {
+ switch (menu_group) {
+ case REGISTER_ANALYZE_GROUP_UNSORTED:
+ case REGISTER_STAT_GROUP_UNSORTED:
+ main_ui_->menuStatistics->insertAction(
+ main_ui_->actionStatistics_REGISTER_STAT_GROUP_UNSORTED,
+ action);
+ break;
+ case REGISTER_STAT_GROUP_RESPONSE_TIME:
+ main_ui_->menuServiceResponseTime->addAction(action);
+ break;
+ case REGISTER_STAT_GROUP_TELEPHONY:
+ main_ui_->menuTelephony->addAction(action);
+ break;
+ case REGISTER_STAT_GROUP_TELEPHONY_ANSI:
+ main_ui_->menuANSI->addAction(action);
+ break;
+ case REGISTER_TOOLS_GROUP_UNSORTED:
+ {
+ // Allow the creation of submenus. Mimics the behavor of
+ // ui/gtk/main_menubar.c:add_menu_item_to_main_menubar
+ // and GtkUIManager.
+ //
+ // For now we limit the insanity to the "Tools" menu.
+ QStringList menu_path = 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;
+ }
+ action->setText(menu_path.last());
+ cur_menu->addAction(action);
+ break;
+ }
+ default:
+// qDebug() << "FIX: Add" << action->text() << "to the menu";
+ break;
+ }
- foreach (QAction *sg_action, sg_actions) {
- main_ui_->menuServiceResponseTime->addAction(sg_action);
- connect(sg_action, SIGNAL(triggered(bool)), this, SLOT(openTapParameterDialog()));
+ // Connect each action type to its corresponding slot. We to
+ // distinguish various types of actions. Setting their objectName
+ // seems to work OK.
+ if (action->objectName() == TapParameterDialog::actionName()) {
+ connect(action, SIGNAL(triggered(bool)), this, SLOT(openTapParameterDialog()));
+ } else if (action->objectName() == FunnelStatistics::actionName()) {
+ connect(action, SIGNAL(triggered(bool)), funnel_statistics_, SLOT(funnelActionTriggered()));
+ }
+ }
}
- // Telephony
- sg_actions = wsApp->statisticsGroupItems(REGISTER_STAT_GROUP_TELEPHONY);
-
- foreach (QAction *sg_action, sg_actions) {
- main_ui_->menuTelephony->addAction(sg_action);
- connect(sg_action, SIGNAL(triggered(bool)), this, SLOT(openTapParameterDialog()));
+ // 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 (wsApp->dynamicMenuGroupItems(REGISTER_TOOLS_GROUP_UNSORTED).length() > 0) {
+ main_ui_->actionToolsPlaceholder->setVisible(false);
+ }
+ if (wsApp->dynamicMenuGroupItems(REGISTER_STAT_GROUP_TELEPHONY_ANSI).length() > 0) {
+ main_ui_->actionTelephonyANSIPlaceholder->setVisible(false);
}
}
@@ -2080,43 +2140,6 @@ 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 0bc10938bc..d11248b094 100644
--- a/ui/qt/main_window.h
+++ b/ui/qt/main_window.h
@@ -262,9 +262,8 @@ private slots:
void showColumnEditor(int column);
void showPreferenceEditor(); // module_t *, pref *
void addStatsPluginsToMenu();
- void addStatisticsMenus();
+ void addDynamicMenus();
void addExternalMenus();
- void addFunnelMenus();
void startInterfaceCapture(bool valid);
diff --git a/ui/qt/main_window.ui b/ui/qt/main_window.ui
index 72f163c7e9..b0d238bffb 100644
--- a/ui/qt/main_window.ui
+++ b/ui/qt/main_window.ui
@@ -481,7 +481,14 @@
</property>
<addaction name="actionTelephonyRTPStreams"/>
</widget>
+ <widget class="QMenu" name="menuANSI">
+ <property name="title">
+ <string>ANSI</string>
+ </property>
+ <addaction name="actionTelephonyANSIPlaceholder"/>
+ </widget>
<addaction name="actionTelephonyVoipCalls"/>
+ <addaction name="menuANSI"/>
<addaction name="actionTelephonyISUPMessages"/>
<addaction name="menuRTP"/>
<addaction name="menuRTSP"/>
@@ -2390,6 +2397,14 @@
<enum>QAction::NoRole</enum>
</property>
</action>
+ <action name="actionTelephonyANSIPlaceholder">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>No ANSI statistics registered</string>
+ </property>
+ </action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
diff --git a/ui/qt/tap_parameter_dialog.cpp b/ui/qt/tap_parameter_dialog.cpp
index 9bc6433c46..b337b857d7 100644
--- a/ui/qt/tap_parameter_dialog.cpp
+++ b/ui/qt/tap_parameter_dialog.cpp
@@ -70,6 +70,7 @@
const int expand_all_threshold_ = 100; // Arbitrary
static QHash<const QString, tpdCreator> cfg_str_to_creator_;
+const QString TapParameterDialog::action_name_ = "TapParameterAction";
TapParameterDialog::TapParameterDialog(QWidget &parent, CaptureFile &cf, int help_topic) :
WiresharkDialog(parent, cf),
@@ -117,8 +118,9 @@ void TapParameterDialog::registerDialog(const QString title, const char *cfg_abb
cfg_str_to_creator_[cfg_str] = creator;
QAction *tpd_action = new QAction(title, NULL);
+ tpd_action->setObjectName(action_name_);
tpd_action->setData(cfg_str);
- wsApp->addStatisticsGroupItem(group, tpd_action);
+ wsApp->addDynamicMenuGroupItem(group, tpd_action);
}
TapParameterDialog *TapParameterDialog::showTapParameterStatistics(QWidget &parent, CaptureFile &cf, const QString cfg_str, const QString arg, void *)
diff --git a/ui/qt/tap_parameter_dialog.h b/ui/qt/tap_parameter_dialog.h
index 8203fcbd7f..f9af3391bd 100644
--- a/ui/qt/tap_parameter_dialog.h
+++ b/ui/qt/tap_parameter_dialog.h
@@ -52,6 +52,7 @@ public:
explicit TapParameterDialog(QWidget &parent, CaptureFile &cf, int help_topic = 0);
~TapParameterDialog();
+ static const QString &actionName() { return action_name_; }
static void registerDialog(const QString title, const char *cfg_abbr, register_stat_group_t group, stat_tap_init_cb tap_init_cb, tpdCreator creator);
static TapParameterDialog *showTapParameterStatistics(QWidget &parent, CaptureFile &cf, const QString cfg_str, const QString arg, void *);
@@ -81,6 +82,7 @@ protected slots:
private:
Ui::TapParameterDialog *ui;
int help_topic_;
+ static const QString action_name_;
// Called by the constructor. The subclass should tap packets here.
virtual void fillTree() = 0;
diff --git a/ui/qt/wireshark_application.cpp b/ui/qt/wireshark_application.cpp
index 1439c72f0f..fb37ccf2e8 100644
--- a/ui/qt/wireshark_application.cpp
+++ b/ui/qt/wireshark_application.cpp
@@ -89,7 +89,7 @@ WiresharkApplication *wsApp = NULL;
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 *> > dynamic_menu_groups_;
static QHash<int, QList<QAction *> > funnel_groups_;
QString WiresharkApplication::window_title_separator_ = QString::fromUtf8(" " UTF8_MIDDLE_DOT " ");
@@ -573,44 +573,25 @@ void WiresharkApplication::emitTapParameterSignal(const QString cfg_abbr, const
}
// XXX Combine statistics and funnel routines into addGroupItem + groupItems?
-void WiresharkApplication::addStatisticsGroupItem(int group, QAction *sg_action)
+void WiresharkApplication::addDynamicMenuGroupItem(int group, QAction *sg_action)
{
- if (!statistics_groups_.contains(group)) {
- statistics_groups_[group] = QList<QAction *>();
+ if (!dynamic_menu_groups_.contains(group)) {
+ dynamic_menu_groups_[group] = QList<QAction *>();
}
- statistics_groups_[group] << sg_action;
+ dynamic_menu_groups_[group] << sg_action;
}
-QList<QAction *> WiresharkApplication::statisticsGroupItems(int group)
+QList<QAction *> WiresharkApplication::dynamicMenuGroupItems(int group)
{
- if (!statistics_groups_.contains(group)) {
+ if (!dynamic_menu_groups_.contains(group)) {
return QList<QAction *>();
}
- QList<QAction *> sgi_list = statistics_groups_[group];
+ QList<QAction *> sgi_list = dynamic_menu_groups_[group];
std::sort(sgi_list.begin(), sgi_list.end(), qActionLessThan);
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 1b7941e8e8..dcd9cb24ea 100644
--- a/ui/qt/wireshark_application.h
+++ b/ui/qt/wireshark_application.h
@@ -74,11 +74,8 @@ public:
void emitAppSignal(AppSignal signal);
void emitStatCommandSignal(const QString &menu_path, const char *arg, void *userdata);
void emitTapParameterSignal(const QString cfg_abbr, const QString arg, void *userdata);
- // 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 addDynamicMenuGroupItem(int group, QAction *sg_action);
+ QList<QAction *> dynamicMenuGroupItems(int group);
void allSystemsGo();
void refreshLocalInterfaces();