summaryrefslogtreecommitdiff
path: root/ui/qt/widgets/drag_drop_toolbar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ui/qt/widgets/drag_drop_toolbar.cpp')
-rw-r--r--ui/qt/widgets/drag_drop_toolbar.cpp216
1 files changed, 216 insertions, 0 deletions
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:
+ */