aboutsummaryrefslogtreecommitdiffstats
path: root/ui
diff options
context:
space:
mode:
authorRoland Knall <rknall@gmail.com>2019-08-26 15:30:22 +0200
committerRoland Knall <rknall@gmail.com>2019-08-26 19:39:14 +0000
commit3870e6c0365d90f53c89a3fb5537f1b9a4d6218e (patch)
treeb765b13948feeaebe8b73224c6cc3b055b457c4e /ui
parenta7838d940339fddd85d15cacd888369c1288b337 (diff)
Qt: Make Apply/Prepare filter independent
The context menu should only use information readily available at the point of creation. Copying actions from the mainwindow introduces a bunch of synchronization and consistency issues. This is a first step to move away from a centralized approach of managing actions, towards a distributed approach. As a side effect, this also solves the old issue of having the apply items greyed out in context menu Bug: 16001 Bug: 15323 Change-Id: I10c6df11cbab0a89386f5bf1d27759103df2a012 Reviewed-on: https://code.wireshark.org/review/34370 Petri-Dish: Anders Broman <a.broman58@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Roland Knall <rknall@gmail.com>
Diffstat (limited to 'ui')
-rw-r--r--ui/qt/filter_action.cpp52
-rw-r--r--ui/qt/filter_action.h8
-rw-r--r--ui/qt/main_window.h1
-rw-r--r--ui/qt/main_window_slots.cpp7
-rw-r--r--ui/qt/proto_tree.cpp38
5 files changed, 84 insertions, 22 deletions
diff --git a/ui/qt/filter_action.cpp b/ui/qt/filter_action.cpp
index 5c5db557f5..490350d1df 100644
--- a/ui/qt/filter_action.cpp
+++ b/ui/qt/filter_action.cpp
@@ -9,6 +9,9 @@
#include "filter_action.h"
+#include <ui/qt/wireshark_application.h>
+#include <ui/qt/main_window.h>
+
FilterAction::FilterAction(QObject *parent, FilterAction::Action action, FilterAction::ActionType type, FilterAction::ActionDirection direction) :
QAction(parent),
action_(action),
@@ -176,6 +179,55 @@ const QString FilterAction::actionDirectionName(ActionDirection direction) {
}
}
+QActionGroup * FilterAction::createFilterGroup(QString filter, bool prepare, bool enabled, QWidget * parent)
+{
+ if ( filter.isEmpty() )
+ return Q_NULLPTR;
+
+ FilterAction * filterAction = new FilterAction(parent, prepare ? FilterAction::ActionPrepare : FilterAction::ActionApply);
+
+ QActionGroup * group = new QActionGroup(parent);
+ group->setProperty("filter", filter);
+ group->setProperty("filterAction", prepare ? FilterAction::ActionPrepare : FilterAction::ActionApply);
+ QAction * action = group->addAction(tr("Selected"));
+ action->setProperty("filterType", FilterAction::ActionTypePlain);
+ action = group->addAction(tr("Not Selected"));
+ action->setProperty("filterType", FilterAction::ActionTypeNot);
+ action = group->addAction(tr(UTF8_HORIZONTAL_ELLIPSIS "and Selected"));
+ action->setProperty("filterType", FilterAction::ActionTypeAnd);
+ action = group->addAction(tr(UTF8_HORIZONTAL_ELLIPSIS "or Selected"));
+ action->setProperty("filterType", FilterAction::ActionTypeOr);
+ action = group->addAction(tr(UTF8_HORIZONTAL_ELLIPSIS "and not Selected"));
+ action->setProperty("filterType", FilterAction::ActionTypeAndNot);
+ action = group->addAction(tr(UTF8_HORIZONTAL_ELLIPSIS "or not Selected"));
+ action->setProperty("filterType", FilterAction::ActionTypeOrNot);
+ group->setEnabled(enabled);
+ connect(group, &QActionGroup::triggered, filterAction, &FilterAction::groupTriggered);
+
+ return group;
+}
+
+void FilterAction::groupTriggered(QAction * action)
+{
+ if ( action && wsApp )
+ {
+ if ( action->property("filterType").canConvert<FilterAction::ActionType>() &&
+ sender()->property("filterAction").canConvert<FilterAction::Action>() )
+ {
+ FilterAction::Action act = sender()->property("filterAction").value<FilterAction::Action>();
+ FilterAction::ActionType type = action->property("filterType").value<FilterAction::ActionType>();
+ QString filter = sender()->property("filter").toString();
+
+ QWidget * mainWin = wsApp->mainWindow();
+ if ( qobject_cast<MainWindow *>(mainWin) )
+ {
+ MainWindow * mw = qobject_cast<MainWindow *>(mainWin);
+ mw->setDisplayFilter(filter, act, type);
+ }
+ }
+ }
+}
+
/*
* Editor modelines
*
diff --git a/ui/qt/filter_action.h b/ui/qt/filter_action.h
index ecc3d9d07c..10c44562e7 100644
--- a/ui/qt/filter_action.h
+++ b/ui/qt/filter_action.h
@@ -15,6 +15,7 @@
#include <wsutil/utf8_entities.h>
#include <QAction>
+#include <QActionGroup>
class FilterAction : public QAction
{
@@ -29,6 +30,7 @@ public:
ActionPrepare,
ActionWebLookup
};
+ Q_ENUM(Action)
/* Action type - says what to do with the filter */
enum ActionType {
@@ -39,6 +41,7 @@ public:
ActionTypeAndNot,
ActionTypeOrNot
};
+ Q_ENUM(ActionType)
/* Action direction */
enum ActionDirection {
@@ -69,6 +72,8 @@ public:
static const QList<ActionDirection> actionDirections();
static const QString actionDirectionName(ActionDirection direction);
+ static QActionGroup * createFilterGroup(QString filter, bool prepare, bool enabled, QWidget * parent);
+
signals:
public slots:
@@ -78,6 +83,9 @@ private:
ActionType type_;
ActionDirection direction_;
+private slots:
+ void groupTriggered(QAction *);
+
};
#endif // FILTER_ACTION_H
diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h
index 1ad363b89b..dd64baab1f 100644
--- a/ui/qt/main_window.h
+++ b/ui/qt/main_window.h
@@ -307,6 +307,7 @@ public slots:
bool openCaptureFile(QString cf_path, QString display_filter, unsigned int type, gboolean is_tempfile = FALSE);
bool openCaptureFile(QString cf_path = QString(), QString display_filter = QString()) { return openCaptureFile(cf_path, display_filter, WTAP_TYPE_AUTO); }
void filterPackets(QString new_filter = QString(), bool force = false);
+ void setDisplayFilter(QString filter, FilterAction::Action action, FilterAction::ActionType filterType);
void updateForUnsavedChanges();
void layoutPanes();
void applyRecentPaneGeometry();
diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp
index 7b2cbb37a5..21a6d5477e 100644
--- a/ui/qt/main_window_slots.cpp
+++ b/ui/qt/main_window_slots.cpp
@@ -2609,7 +2609,12 @@ void MainWindow::matchFieldFilter(FilterAction::Action action, FilterAction::Act
return;
}
- emit filterAction(field_filter, action, filter_type);
+ setDisplayFilter(field_filter, action, filter_type);
+}
+
+void MainWindow::setDisplayFilter(QString filter, FilterAction::Action action, FilterAction::ActionType filterType)
+{
+ emit filterAction(filter, action, filterType);
}
void MainWindow::on_actionAnalyzeDisplayFilters_triggered()
diff --git a/ui/qt/proto_tree.cpp b/ui/qt/proto_tree.cpp
index 4d6c228d41..80c4607d68 100644
--- a/ui/qt/proto_tree.cpp
+++ b/ui/qt/proto_tree.cpp
@@ -21,6 +21,7 @@
#include <ui/qt/widgets/drag_label.h>
#include <ui/qt/widgets/wireshark_file_dialog.h>
#include <ui/qt/show_packet_bytes_dialog.h>
+#include <ui/qt/filter_action.h>
#include <ui/all_files_wildcard.h>
#include <ui/alert_box.h>
#include "wireshark_application.h"
@@ -320,25 +321,22 @@ void ProtoTree::contextMenuEvent(QContextMenuEvent *event)
ctx_menu_.addAction(action);
ctx_menu_.addSeparator();
- main_menu_item = window()->findChild<QMenu *>("menuApplyAsFilter");
- submenu = new QMenu(main_menu_item->title(), &ctx_menu_);
- ctx_menu_.addMenu(submenu);
- submenu->addAction(window()->findChild<QAction *>("actionAnalyzeAAFSelected"));
- submenu->addAction(window()->findChild<QAction *>("actionAnalyzeAAFNotSelected"));
- submenu->addAction(window()->findChild<QAction *>("actionAnalyzeAAFAndSelected"));
- submenu->addAction(window()->findChild<QAction *>("actionAnalyzeAAFOrSelected"));
- submenu->addAction(window()->findChild<QAction *>("actionAnalyzeAAFAndNotSelected"));
- submenu->addAction(window()->findChild<QAction *>("actionAnalyzeAAFOrNotSelected"));
-
- main_menu_item = window()->findChild<QMenu *>("menuPrepareAFilter");
- submenu = new QMenu(main_menu_item->title(), &ctx_menu_);
- ctx_menu_.addMenu(submenu);
- submenu->addAction(window()->findChild<QAction *>("actionAnalyzePAFSelected"));
- submenu->addAction(window()->findChild<QAction *>("actionAnalyzePAFNotSelected"));
- submenu->addAction(window()->findChild<QAction *>("actionAnalyzePAFAndSelected"));
- submenu->addAction(window()->findChild<QAction *>("actionAnalyzePAFOrSelected"));
- submenu->addAction(window()->findChild<QAction *>("actionAnalyzePAFAndNotSelected"));
- submenu->addAction(window()->findChild<QAction *>("actionAnalyzePAFOrNotSelected"));
+ QModelIndex index = indexAt(event->pos());
+ FieldInformation finfo(proto_tree_model_->protoNodeFromIndex(index).protoNode());
+
+ epan_dissect_t *edt = cap_file_ ? cap_file_->edt : edt_;
+ char * selectedfilter = proto_construct_match_selected_string(finfo.fieldInfo(), edt);
+ bool can_match_selected = proto_can_match_selected(finfo.fieldInfo(), edt);
+ main_menu_item = new QMenu(tr("Apply as Filter"), &ctx_menu_);
+ QActionGroup * group = FilterAction::createFilterGroup(selectedfilter, false, can_match_selected, &ctx_menu_);
+ main_menu_item->addActions(group->actions());
+ ctx_menu_.addMenu(main_menu_item);
+ main_menu_item = new QMenu(tr("Prepare as Filter"), &ctx_menu_);
+ group = FilterAction::createFilterGroup(selectedfilter, true, can_match_selected, &ctx_menu_);
+ main_menu_item->addActions(group->actions());
+ ctx_menu_.addMenu(main_menu_item);
+ if ( selectedfilter )
+ wmem_free(Q_NULLPTR, selectedfilter);
QMenu *main_conv_menu = window()->findChild<QMenu *>("menuConversationFilter");
conv_menu_.setTitle(main_conv_menu->title());
@@ -374,8 +372,6 @@ void ProtoTree::contextMenuEvent(QContextMenuEvent *event)
submenu->addAction(window()->findChild<QAction *>("actionEditCopyAsFilter"));
submenu->addSeparator();
- QModelIndex index = indexAt(event->pos());
- FieldInformation finfo(proto_tree_model_->protoNodeFromIndex(index).protoNode());
QActionGroup * copyEntries = DataPrinter::copyActions(this, &finfo);
submenu->addActions(copyEntries->actions());