diff options
Diffstat (limited to 'ui/qt/widgets/drag_drop_toolbar.cpp')
-rw-r--r-- | ui/qt/widgets/drag_drop_toolbar.cpp | 216 |
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: + */ |