summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland Knall <roland.knall@br-automation.com>2017-06-27 16:36:19 +0200
committerRoland Knall <rknall@gmail.com>2017-06-28 15:09:03 +0000
commit8020be30fd46798aa61017f0ec936806d6495d07 (patch)
tree3066cad0abaaf66d537455e1ea35488c8ce76ae9
parent9731b50bc501673a98b588be3ae6f43492ae3150 (diff)
downloadwireshark-8020be30fd46798aa61017f0ec936806d6495d07.tar.gz
Qt: Drag/Drop Filter buttons to order
Allow the ordering of the filter buttons via drag/drop in the toolbar Change-Id: Id8793d6514bae36066a7a23d6890985665e753bd Reviewed-on: https://code.wireshark.org/review/22422 Petri-Dish: Roland Knall <rknall@gmail.com> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Roland Knall <rknall@gmail.com>
-rw-r--r--epan/uat-int.h6
-rw-r--r--epan/uat.c14
-rw-r--r--ui/qt/CMakeLists.txt2
-rw-r--r--ui/qt/Makefile.am6
-rw-r--r--ui/qt/main_window.cpp6
-rw-r--r--ui/qt/main_window.h6
-rw-r--r--ui/qt/main_window_slots.cpp20
-rw-r--r--ui/qt/widgets/drag_drop_toolbar.cpp216
-rw-r--r--ui/qt/widgets/drag_drop_toolbar.h70
9 files changed, 342 insertions, 4 deletions
diff --git a/epan/uat-int.h b/epan/uat-int.h
index c36a5c136e..a272c8f209 100644
--- a/epan/uat-int.h
+++ b/epan/uat-int.h
@@ -112,6 +112,12 @@ WS_DLL_PUBLIC
void uat_remove_record_idx(uat_t *uat, guint rec_idx);
/**
+ * Moves the entry from the old position to the new one
+ */
+WS_DLL_PUBLIC
+void uat_move_index(uat_t *uat, guint old_idx, guint new_idx);
+
+/**
* Removes and destroys all records from the UAT.
*/
WS_DLL_PUBLIC
diff --git a/epan/uat.c b/epan/uat.c
index 71403485b7..03f73d2a34 100644
--- a/epan/uat.c
+++ b/epan/uat.c
@@ -225,6 +225,20 @@ void uat_remove_record_idx(uat_t* uat, guint idx) {
g_array_remove_index(uat->valid_data, idx);
}
+void uat_move_index(uat_t * uat, guint old_idx, guint new_idx)
+{
+ guint dir = 1;
+ guint start = old_idx;
+ if ( old_idx > new_idx )
+ dir = -1;
+
+ while ( start != new_idx )
+ {
+ uat_swap(uat, start, start + dir);
+ start += dir;
+ }
+}
+
/* The returned filename was g_malloc()'d so the caller must free it */
gchar* uat_get_actual_filename(uat_t* uat, gboolean for_writing) {
gchar *pers_fname = NULL;
diff --git a/ui/qt/CMakeLists.txt b/ui/qt/CMakeLists.txt
index 9addc44d43..8024e3fdab 100644
--- a/ui/qt/CMakeLists.txt
+++ b/ui/qt/CMakeLists.txt
@@ -174,6 +174,7 @@ set(WIRESHARK_QT_HEADERS
wireshark_application.h
wireshark_dialog.h
wlan_statistics_dialog.h
+ widgets/drag_drop_toolbar.h
${WIRESHARK_CUSTOM_QT_HEADERS}
)
@@ -348,6 +349,7 @@ set(WIRESHARK_QT_SRC
wireless_timeline.cpp
wireshark_application.cpp
wireshark_dialog.cpp
+ widgets/drag_drop_toolbar.cpp
${WIRESHARK_CUSTOM_QT_SRCS}
)
diff --git a/ui/qt/Makefile.am b/ui/qt/Makefile.am
index ee9c82a6f1..b8c4720998 100644
--- a/ui/qt/Makefile.am
+++ b/ui/qt/Makefile.am
@@ -305,7 +305,8 @@ MOC_HDRS = \
wireless_timeline.h \
wireshark_application.h \
wireshark_dialog.h \
- wlan_statistics_dialog.h
+ wlan_statistics_dialog.h \
+ widgets/drag_drop_toolbar.h
#
# .ui files.
@@ -592,7 +593,8 @@ WIRESHARK_QT_SRC = \
wireless_frame.cpp \
wireless_timeline.cpp \
wireshark_application.cpp \
- wireshark_dialog.cpp
+ wireshark_dialog.cpp \
+ widgets/drag_drop_toolbar.cpp
WIRESHARK_QT_TAP_SRC = \
expert_info_dialog.cpp \
diff --git a/ui/qt/main_window.cpp b/ui/qt/main_window.cpp
index 5d7ac14741..fbbbcf58ba 100644
--- a/ui/qt/main_window.cpp
+++ b/ui/qt/main_window.cpp
@@ -84,6 +84,8 @@ DIAG_ON(frame-larger-than=)
#include "qt_ui_utils.h"
+#include <ui/qt/widgets/drag_drop_toolbar.h>
+
#include <QAction>
#include <QActionGroup>
#include <QDesktopWidget>
@@ -460,11 +462,13 @@ MainWindow::MainWindow(QWidget *parent) :
// Make sure filter expressions overflow into a menu instead of a
// larger toolbar. We do this by adding them to a child toolbar.
// https://bugreports.qt.io/browse/QTBUG-2472
- filter_expression_toolbar_ = new QToolBar();
+ filter_expression_toolbar_ = new DragDropToolBar();
filter_expression_toolbar_->setStyleSheet("QToolBar { background: none; border: none; }");
filter_expression_toolbar_->setContextMenuPolicy(Qt::CustomContextMenu);
connect(filter_expression_toolbar_, SIGNAL(customContextMenuRequested(QPoint)),
this, SLOT(filterToolbarCustomMenuHandler(QPoint)));
+ connect(filter_expression_toolbar_, SIGNAL(actionMoved(QAction*, int, int)),
+ this, SLOT(filterToolbarActionMoved(QAction*, int, int)));
main_ui_->displayFilterToolBar->addWidget(filter_expression_toolbar_);
diff --git a/ui/qt/main_window.h b/ui/qt/main_window.h
index 55e3407add..26b76d8317 100644
--- a/ui/qt/main_window.h
+++ b/ui/qt/main_window.h
@@ -68,6 +68,7 @@ class MainWelcome;
class PacketList;
class ProtoTree;
class WirelessFrame;
+class DragDropToolBar;
class QAction;
class QActionGroup;
@@ -165,7 +166,7 @@ private:
QWidget *freeze_focus_;
QMap<QAction *, ts_type> td_actions;
QMap<QAction *, ts_precision> tp_actions;
- QToolBar *filter_expression_toolbar_;
+ DragDropToolBar *filter_expression_toolbar_;
bool was_maximized_;
bool capture_stopping_;
@@ -195,6 +196,8 @@ private:
QAction *update_action_;
#endif
+ QPoint dragStartPosition;
+
QWidget* getLayoutWidget(layout_pane_content_e type);
void freeze();
@@ -350,6 +353,7 @@ private slots:
void filterToolbarEditFilter();
void filterToolbarDisableFilter();
void filterToolbarRemoveFilter();
+ void filterToolbarActionMoved(QAction * action, int oldPos, int newPos);
void startInterfaceCapture(bool valid, const QString capture_filter);
diff --git a/ui/qt/main_window_slots.cpp b/ui/qt/main_window_slots.cpp
index cf70ad4e07..f41f13b104 100644
--- a/ui/qt/main_window_slots.cpp
+++ b/ui/qt/main_window_slots.cpp
@@ -64,6 +64,7 @@ DIAG_ON(frame-larger-than=)
#include "epan/prefs.h"
#include "epan/plugin_if.h"
#include "epan/uat.h"
+#include "epan/uat-int.h"
#include "epan/value_string.h"
#ifdef HAVE_LUA
@@ -87,6 +88,7 @@ DIAG_ON(frame-larger-than=)
#include "ui/qt/simple_dialog.h"
#include <ui/qt/variant_pointer.h>
+#include <ui/qt/widgets/drag_drop_toolbar.h>
#ifdef HAVE_SOFTWARE_UPDATE
#include "ui/software_update.h"
@@ -4112,6 +4114,24 @@ void MainWindow::filterToolbarRemoveFilter()
}
}
+void MainWindow::filterToolbarActionMoved(QAction* action, int oldPos, int newPos)
+{
+ gchar* err = NULL;
+ if ( oldPos == newPos )
+ return;
+
+ UatModel * uatModel = new UatModel(this, "Display expressions");
+ QModelIndex rowIndex = uatModel->findRowForColumnContent(action->data(), 2);
+ if ( rowIndex.isValid() )
+ {
+ uat_t * table = uat_get_table_by_name("Display expressions");
+ uat_move_index(table, oldPos, newPos);
+ uat_save(table, &err);
+
+ g_free(err);
+ }
+}
+
#ifdef _MSC_VER
#pragma warning(pop)
#endif
diff --git a/ui/qt/widgets/drag_drop_toolbar.cpp b/ui/qt/widgets/drag_drop_toolbar.cpp
new file mode 100644
index 0000000000..04f6c7d096
--- /dev/null
+++ b/ui/qt/widgets/drag_drop_toolbar.cpp
@@ -0,0 +1,216 @@
+/* drag_drop_toolbar.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 <ui/qt/widgets/drag_drop_toolbar.h>
+
+#include <QAction>
+#include <QApplication>
+#include <QToolBar>
+#include <QToolButton>
+#include <QDrag>
+#include <QLayout>
+#include <QMimeData>
+#include <QMouseEvent>
+#include <QWindow>
+
+#define drag_drop_toolbar_action_ "drag_drop_toolbar_action_"
+
+DragDropToolBar::DragDropToolBar(const QString &title, QWidget *parent) :
+ QToolBar(title, parent)
+{
+ childCounter = 0;
+ setAcceptDrops(true);
+}
+
+DragDropToolBar::DragDropToolBar(QWidget *parent) :
+ QToolBar(parent)
+{
+ childCounter = 0;
+ setAcceptDrops(true);
+}
+
+DragDropToolBar::~DragDropToolBar()
+{
+}
+
+void DragDropToolBar::childEvent(QChildEvent * event)
+{
+ /* New action has been added */
+ if ( event->type() == QEvent::ChildAdded )
+ {
+ if ( event->child()->isWidgetType() )
+ {
+ ((QWidget *)event->child())->installEventFilter(this);
+ event->child()->setProperty(drag_drop_toolbar_action_, qVariantFromValue(childCounter));
+ childCounter++;
+ }
+ }
+ else if ( event->type() == QEvent::ChildRemoved )
+ {
+ childCounter--;
+ }
+}
+
+bool DragDropToolBar::eventFilter(QObject * obj, QEvent * event)
+{
+ if ( ! obj->isWidgetType() )
+ return QToolBar::eventFilter(obj, event);
+
+ QWidget * elem = qobject_cast<QWidget *>(obj);
+
+ if ( ! elem || ( event->type() != QEvent::MouseButtonPress && event->type() != QEvent::MouseMove ) )
+ return QToolBar::eventFilter(obj, event);
+
+ QMouseEvent * ev = (QMouseEvent *)event;
+
+ if ( event->type() == QEvent::MouseButtonPress )
+ {
+ if ( ev->buttons() & Qt::LeftButton )
+ dragStartPosition = ev->pos();
+ }
+ else if ( event->type() == QEvent::MouseMove )
+ {
+ if ( ( ev->buttons() & Qt::LeftButton ) && (ev->pos() - dragStartPosition).manhattanLength()
+ > QApplication::startDragDistance())
+ {
+ QDrag * drag = new QDrag(elem);
+ QMimeData *mimeData = new QMimeData;
+ mimeData->setData("application/x-wireshark-toolbar-entry",
+ elem->property(drag_drop_toolbar_action_).toByteArray());
+ drag->setMimeData(mimeData);
+
+ qreal dpr = window()->windowHandle()->devicePixelRatio();
+ QPixmap pixmap(elem->size() * dpr);
+ pixmap.setDevicePixelRatio(dpr);
+ elem->render(&pixmap);
+ drag->setPixmap(pixmap);
+
+ Qt::DropAction dropAction = drag->exec(Qt::CopyAction | Qt::MoveAction);
+
+ if (dropAction == Qt::MoveAction)
+ elem->setVisible(false);
+
+ return true;
+ }
+ }
+
+ return QToolBar::eventFilter(obj, event);
+}
+
+void DragDropToolBar::dragEnterEvent(QDragEnterEvent *event)
+{
+ if (event->mimeData()->hasFormat("application/x-wireshark-toolbar-entry"))
+ {
+ if (event->source() == this) {
+ event->setDropAction(Qt::MoveAction);
+ event->accept();
+ } else {
+ event->acceptProposedAction();
+ }
+ } else {
+ event->ignore();
+ }
+}
+
+void DragDropToolBar::dragMoveEvent(QDragMoveEvent *event)
+{
+ if (event->mimeData()->hasFormat("application/x-wireshark-toolbar-entry"))
+ {
+ if (event->source() == this) {
+ event->setDropAction(Qt::MoveAction);
+ event->accept();
+ } else {
+ event->acceptProposedAction();
+ QAction * action = actionAt(event->pos());
+ if ( action )
+ {
+ foreach(QAction * act, actions())
+ {
+ if ( widgetForAction(act) )
+ widgetForAction(act)->setStyleSheet("QWidget { border: none; };");
+ }
+
+ widgetForAction(action)->setStyleSheet("QWidget { border: 2px dotted grey; };");
+ }
+ }
+ } else {
+ event->ignore();
+ }
+}
+
+void DragDropToolBar::dropEvent(QDropEvent *event)
+{
+ if (event->mimeData()->hasFormat("application/x-wireshark-toolbar-entry"))
+ {
+ int oldPos = event->mimeData()->data("application/x-wireshark-toolbar-entry").toInt();
+ int newPos = -1;
+ QAction * action = actionAt(event->pos());
+ if ( action && actions().at(oldPos) )
+ {
+ widgetForAction(action)->setStyleSheet("QWidget { border: none; };");
+ newPos = widgetForAction(action)->property(drag_drop_toolbar_action_).toInt();
+ moveToolbarItems(oldPos, newPos);
+ emit actionMoved(actions().at(oldPos), oldPos, newPos);
+ }
+
+ if (event->source() == this) {
+ event->setDropAction(Qt::MoveAction);
+ event->accept();
+ } else {
+ event->acceptProposedAction();
+ }
+
+ } else {
+ event->ignore();
+ }
+}
+
+void DragDropToolBar::moveToolbarItems(int fromPos, int newPos)
+{
+ if ( fromPos == newPos )
+ return;
+
+ setUpdatesEnabled(false);
+
+ QList<QAction *> storedActions = actions();
+
+ clear();
+ childCounter = 0;
+
+ storedActions.move(fromPos, newPos);
+ foreach ( QAction * action, storedActions )
+ addAction(action);
+
+ setUpdatesEnabled(true);
+}
+
+/*
+ * 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/widgets/drag_drop_toolbar.h b/ui/qt/widgets/drag_drop_toolbar.h
new file mode 100644
index 0000000000..6de98ef628
--- /dev/null
+++ b/ui/qt/widgets/drag_drop_toolbar.h
@@ -0,0 +1,70 @@
+/* drag_drop_toolbar.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 DRAG_DROP_TOOLBAR_H
+#define DRAG_DROP_TOOLBAR_H
+
+#include <QToolBar>
+#include <QPoint>
+
+class DragDropToolBar : public QToolBar
+{
+ Q_OBJECT
+public:
+ explicit DragDropToolBar(const QString &title, QWidget *parent = Q_NULLPTR);
+ explicit DragDropToolBar(QWidget *parent = Q_NULLPTR);
+ ~DragDropToolBar();
+
+Q_SIGNALS:
+ void actionMoved(QAction * action, int oldPos, int newPos);
+
+protected:
+
+ virtual void childEvent(QChildEvent * event);
+
+ virtual bool eventFilter(QObject * obj, QEvent * ev);
+ virtual void dragEnterEvent(QDragEnterEvent *event);
+ virtual void dragMoveEvent(QDragMoveEvent *event);
+ virtual void dropEvent(QDropEvent *event);
+
+private:
+
+ QPoint dragStartPosition;
+ int childCounter;
+
+ void moveToolbarItems(int fromPos, int toPos);
+
+};
+
+#endif // DRAG_DROP_TOOLBAR_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:
+ */