summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorSamuel Rødal <samuel.rodal@digia.com>2013-05-23 12:44:20 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-05-30 12:49:51 +0200
commit1df7a6a50a794721edb1bc63d268378f4f0ed7c4 (patch)
treee20fad557bfd4a3f65f41c5b5a50633a074178da /src/gui
parent853a0b764e08d5f910072b6f3fd3ff3f9dc5c0c4 (diff)
Move QBasicDrag and QSimpleDrag to QtGui.
These are useful as default implementations of QPlatformIntegration::drag(), instead of having it return 0 which will lead to crashes in Qt Quick 2 and widgets applications that use drag and drop. Task-number: QTBUG-31288 Change-Id: I70efa139306ced5d879def0f74e3a72d3bcd64f7 Reviewed-by: Jørgen Lind <jorgen.lind@digia.com>
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/kernel/kernel.pri4
-rw-r--r--src/gui/kernel/qplatformintegration.cpp7
-rw-r--r--src/gui/kernel/qshapedpixmapdndwindow.cpp106
-rw-r--r--src/gui/kernel/qshapedpixmapdndwindow_p.h75
-rw-r--r--src/gui/kernel/qsimpledrag.cpp366
-rw-r--r--src/gui/kernel/qsimpledrag_p.h122
6 files changed, 679 insertions, 1 deletions
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index 91374fe2dd..3c019fc5b5 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -31,6 +31,8 @@ HEADERS += \
kernel/qplatformclipboard.h \
kernel/qplatformnativeinterface.h \
kernel/qplatformmenu.h \
+ kernel/qshapedpixmapdndwindow_p.h \
+ kernel/qsimpledrag_p.h \
kernel/qsurfaceformat.h \
kernel/qguiapplication.h \
kernel/qguiapplication_p.h \
@@ -89,6 +91,8 @@ SOURCES += \
kernel/qplatformclipboard.cpp \
kernel/qplatformnativeinterface.cpp \
kernel/qsessionmanager.cpp \
+ kernel/qshapedpixmapdndwindow.cpp \
+ kernel/qsimpledrag.cpp \
kernel/qsurfaceformat.cpp \
kernel/qguiapplication.cpp \
kernel/qwindow.cpp \
diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp
index e82e30df80..e4f45ebb6e 100644
--- a/src/gui/kernel/qplatformintegration.cpp
+++ b/src/gui/kernel/qplatformintegration.cpp
@@ -49,6 +49,7 @@
#include <QtGui/private/qpixmap_raster_p.h>
#include <qpa/qplatformscreen_p.h>
#include <private/qdnd_p.h>
+#include <private/qsimpledrag_p.h>
QT_BEGIN_NAMESPACE
@@ -99,7 +100,11 @@ QPlatformClipboard *QPlatformIntegration::clipboard() const
*/
QPlatformDrag *QPlatformIntegration::drag() const
{
- return 0;
+ static QSimpleDrag *drag = 0;
+ if (!drag) {
+ drag = new QSimpleDrag;
+ }
+ return drag;
}
#endif
diff --git a/src/gui/kernel/qshapedpixmapdndwindow.cpp b/src/gui/kernel/qshapedpixmapdndwindow.cpp
new file mode 100644
index 0000000000..b3e64b01d0
--- /dev/null
+++ b/src/gui/kernel/qshapedpixmapdndwindow.cpp
@@ -0,0 +1,106 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qshapedpixmapdndwindow_p.h"
+
+#include <QtGui/QPainter>
+#include <QtGui/QCursor>
+
+QT_BEGIN_NAMESPACE
+
+QShapedPixmapWindow::QShapedPixmapWindow()
+ : QWindow(),
+ m_backingStore(0)
+{
+ QSurfaceFormat format;
+ format.setAlphaBufferSize(8);
+ setFormat(format);
+ setSurfaceType(RasterSurface);
+ setFlags(Qt::ToolTip | Qt::FramelessWindowHint |
+ Qt::X11BypassWindowManagerHint | Qt::WindowTransparentForInput);
+ create();
+ m_backingStore = new QBackingStore(this);
+}
+
+void QShapedPixmapWindow::render()
+{
+ QRect rect(QPoint(), geometry().size());
+
+ m_backingStore->beginPaint(rect);
+
+ QPaintDevice *device = m_backingStore->paintDevice();
+
+ {
+ QPainter p(device);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ p.drawPixmap(0, 0, m_pixmap);
+ }
+
+ m_backingStore->endPaint();
+ m_backingStore->flush(rect);
+}
+
+void QShapedPixmapWindow::setPixmap(const QPixmap &pixmap)
+{
+ m_pixmap = pixmap;
+}
+
+void QShapedPixmapWindow::setHotspot(const QPoint &hotspot)
+{
+ m_hotSpot = hotspot;
+}
+
+void QShapedPixmapWindow::updateGeometry()
+{
+ QRect rect(QCursor::pos() - m_hotSpot, m_pixmap.size());
+ if (m_pixmap.isNull())
+ m_backingStore->resize(QSize(1,1));
+ else if (m_backingStore->size() != m_pixmap.size())
+ m_backingStore->resize(m_pixmap.size());
+ setGeometry(rect);
+}
+
+void QShapedPixmapWindow::exposeEvent(QExposeEvent *)
+{
+ render();
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qshapedpixmapdndwindow_p.h b/src/gui/kernel/qshapedpixmapdndwindow_p.h
new file mode 100644
index 0000000000..20674b6b19
--- /dev/null
+++ b/src/gui/kernel/qshapedpixmapdndwindow_p.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSHAPEDPIXMAPDNDWINDOW_H
+#define QSHAPEDPIXMAPDNDWINDOW_H
+
+#include <QtGui/QWindow>
+#include <QtGui/QPixmap>
+#include <QtGui/QBackingStore>
+
+QT_BEGIN_NAMESPACE
+
+class QShapedPixmapWindow : public QWindow
+{
+ Q_OBJECT
+public:
+ QShapedPixmapWindow();
+
+ void render();
+
+ void setPixmap(const QPixmap &pixmap);
+ void setHotspot(const QPoint &hotspot);
+
+ void updateGeometry();
+
+protected:
+ void exposeEvent(QExposeEvent *);
+
+private:
+ QBackingStore *m_backingStore;
+ QPixmap m_pixmap;
+ QPoint m_hotSpot;
+};
+
+QT_END_NAMESPACE
+
+#endif // QSHAPEDPIXMAPDNDWINDOW_H
diff --git a/src/gui/kernel/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp
new file mode 100644
index 0000000000..f6912a2d57
--- /dev/null
+++ b/src/gui/kernel/qsimpledrag.cpp
@@ -0,0 +1,366 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsimpledrag_p.h"
+
+#include "qbitmap.h"
+#include "qdrag.h"
+#include "qpixmap.h"
+#include "qevent.h"
+#include "qfile.h"
+#include "qtextcodec.h"
+#include "qguiapplication.h"
+#include "qpoint.h"
+#include "qbuffer.h"
+#include "qimage.h"
+#include "qregexp.h"
+#include "qdir.h"
+#include "qimagereader.h"
+#include "qimagewriter.h"
+
+#include <QtCore/QEventLoop>
+#include <QtCore/QDebug>
+
+#include <private/qguiapplication_p.h>
+#include <private/qdnd_p.h>
+
+#include <private/qshapedpixmapdndwindow_p.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_DRAGANDDROP
+
+static QWindow* topLevelAt(const QPoint &pos)
+{
+ QWindowList list = QGuiApplication::topLevelWindows();
+ for (int i = list.count()-1; i >= 0; --i) {
+ QWindow *w = list.at(i);
+ if (w->isVisible() && w->geometry().contains(pos) && !qobject_cast<QShapedPixmapWindow*>(w))
+ return w;
+ }
+ return 0;
+}
+
+/*!
+ \class QBasicDrag
+ \brief QBasicDrag is a base class for implementing platform drag and drop.
+ \since 5.0
+ \internal
+ \ingroup qpa
+
+ QBasicDrag implements QPlatformDrag::drag() by running a local event loop in which
+ it tracks mouse movements and moves the drag icon (QShapedPixmapWindow) accordingly.
+ It provides new virtuals allowing for querying whether the receiving window
+ (within the Qt application or outside) accepts the drag and sets the state accordingly.
+*/
+
+QBasicDrag::QBasicDrag() :
+ m_restoreCursor(false), m_eventLoop(0),
+ m_executed_drop_action(Qt::IgnoreAction), m_can_drop(false),
+ m_drag(0), m_drag_icon_window(0)
+{
+}
+
+QBasicDrag::~QBasicDrag()
+{
+ delete m_drag_icon_window;
+}
+
+void QBasicDrag::enableEventFilter()
+{
+ qApp->installEventFilter(this);
+}
+
+void QBasicDrag::disableEventFilter()
+{
+ qApp->removeEventFilter(this);
+}
+
+bool QBasicDrag::eventFilter(QObject *o, QEvent *e)
+{
+ if (!m_drag) {
+ if (e->type() == QEvent::KeyRelease && static_cast<QKeyEvent*>(e)->key() == Qt::Key_Escape) {
+ disableEventFilter();
+ exitDndEventLoop();
+ return true; // block the key release
+ }
+ return false;
+ }
+
+ if (!qobject_cast<QWindow *>(o))
+ return false;
+
+ switch (e->type()) {
+ case QEvent::ShortcutOverride:
+ // prevent accelerators from firing while dragging
+ e->accept();
+ return true;
+
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ {
+ QKeyEvent *ke = static_cast<QKeyEvent *>(e);
+ if (ke->key() == Qt::Key_Escape && e->type() == QEvent::KeyPress) {
+ cancel();
+ disableEventFilter();
+ exitDndEventLoop();
+
+ }
+ return true; // Eat all key events
+ }
+
+ case QEvent::MouseMove:
+ move(static_cast<QMouseEvent *>(e));
+ return true; // Eat all mouse events
+
+ case QEvent::MouseButtonRelease:
+ disableEventFilter();
+ if (canDrop()) {
+ drop(static_cast<QMouseEvent *>(e));
+ } else {
+ cancel();
+ }
+ exitDndEventLoop();
+ return true; // Eat all mouse events
+
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::Wheel:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
+Qt::DropAction QBasicDrag::drag(QDrag *o)
+{
+ m_drag = o;
+ m_executed_drop_action = Qt::IgnoreAction;
+ m_can_drop = false;
+ m_restoreCursor = true;
+#ifndef QT_NO_CURSOR
+ qApp->setOverrideCursor(Qt::DragCopyCursor);
+ updateCursor(m_executed_drop_action);
+#endif
+ startDrag();
+ m_eventLoop = new QEventLoop;
+ m_eventLoop->exec();
+ delete m_eventLoop;
+ m_eventLoop = 0;
+ m_drag = 0;
+ endDrag();
+ return m_executed_drop_action;
+}
+
+void QBasicDrag::restoreCursor()
+{
+ if (m_restoreCursor) {
+#ifndef QT_NO_CURSOR
+ QGuiApplication::restoreOverrideCursor();
+#endif
+ m_restoreCursor = false;
+ }
+}
+
+void QBasicDrag::startDrag()
+{
+ // ### TODO Check if its really necessary to have m_drag_icon_window
+ // when QDrag is used without a pixmap - QDrag::setPixmap()
+ if (!m_drag_icon_window)
+ m_drag_icon_window = new QShapedPixmapWindow();
+
+ m_drag_icon_window->setPixmap(m_drag->pixmap());
+ m_drag_icon_window->setHotspot(m_drag->hotSpot());
+ m_drag_icon_window->updateGeometry();
+ m_drag_icon_window->setVisible(true);
+
+ enableEventFilter();
+}
+
+void QBasicDrag::endDrag()
+{
+}
+
+void QBasicDrag::cancel()
+{
+ disableEventFilter();
+ restoreCursor();
+ m_drag_icon_window->setVisible(false);
+}
+
+void QBasicDrag::move(const QMouseEvent *)
+{
+ if (m_drag)
+ m_drag_icon_window->updateGeometry();
+}
+
+void QBasicDrag::drop(const QMouseEvent *)
+{
+ disableEventFilter();
+ restoreCursor();
+ m_drag_icon_window->setVisible(false);
+}
+
+void QBasicDrag::exitDndEventLoop()
+{
+ if (m_eventLoop && m_eventLoop->isRunning())
+ m_eventLoop->exit();
+}
+
+void QBasicDrag::updateCursor(Qt::DropAction action)
+{
+#ifndef QT_NO_CURSOR
+ Qt::CursorShape cursorShape = Qt::ForbiddenCursor;
+ if (canDrop()) {
+ switch (action) {
+ case Qt::CopyAction:
+ cursorShape = Qt::DragCopyCursor;
+ break;
+ case Qt::LinkAction:
+ cursorShape = Qt::DragLinkCursor;
+ break;
+ default:
+ cursorShape = Qt::DragMoveCursor;
+ break;
+ }
+ }
+
+ QCursor *cursor = qApp->overrideCursor();
+ QPixmap pixmap = m_drag->dragCursor(action);
+ if (!cursor) {
+ qApp->changeOverrideCursor((pixmap.isNull()) ? QCursor(cursorShape) : QCursor(pixmap));
+ } else {
+ if (!pixmap.isNull()) {
+ if ((cursor->pixmap().cacheKey() != pixmap.cacheKey())) {
+ qApp->changeOverrideCursor(QCursor(pixmap));
+ }
+ } else {
+ if (cursorShape != cursor->shape()) {
+ qApp->changeOverrideCursor(QCursor(cursorShape));
+ }
+ }
+ }
+#endif
+ updateAction(action);
+}
+
+/*!
+ \class QSimpleDrag
+ \brief QSimpleDrag implements QBasicDrag for Drag and Drop operations within the Qt Application itself.
+ \since 5.0
+ \internal
+ \ingroup qpa
+
+ The class checks whether the receiving window is a window of the Qt application
+ and sets the state accordingly. It does not take windows of other applications
+ into account.
+*/
+
+QSimpleDrag::QSimpleDrag() : m_current_window(0)
+{
+}
+
+QMimeData *QSimpleDrag::platformDropData()
+{
+ if (drag())
+ return drag()->mimeData();
+ return 0;
+}
+
+void QSimpleDrag::startDrag()
+{
+ QBasicDrag::startDrag();
+ m_current_window = topLevelAt(QCursor::pos());
+ if (m_current_window) {
+ QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(m_current_window, drag()->mimeData(), QCursor::pos(), drag()->supportedActions());
+ setCanDrop(response.isAccepted());
+ updateCursor(response.acceptedAction());
+ } else {
+ setCanDrop(false);
+ updateCursor(Qt::IgnoreAction);
+ }
+ setExecutedDropAction(Qt::IgnoreAction);
+}
+
+void QSimpleDrag::cancel()
+{
+ QBasicDrag::cancel();
+ if (drag())
+ QWindowSystemInterface::handleDrag(m_current_window, 0, QPoint(), Qt::IgnoreAction);
+ m_current_window = 0;
+}
+
+void QSimpleDrag::move(const QMouseEvent *me)
+{
+ QBasicDrag::move(me);
+ QWindow *window = topLevelAt(me->globalPos());
+ if (!window)
+ return;
+
+ const QPoint pos = me->globalPos() - window->geometry().topLeft();
+ const QPlatformDragQtResponse qt_response =
+ QWindowSystemInterface::handleDrag(window, drag()->mimeData(), pos, drag()->supportedActions());
+
+ updateCursor(qt_response.acceptedAction());
+ setCanDrop(qt_response.isAccepted());
+}
+
+void QSimpleDrag::drop(const QMouseEvent *me)
+{
+ QBasicDrag::drop(me);
+ QWindow *window = topLevelAt(me->globalPos());
+ if (!window)
+ return;
+
+ const QPoint pos = me->globalPos() - window->geometry().topLeft();
+ const QPlatformDropQtResponse response =
+ QWindowSystemInterface::handleDrop(window, drag()->mimeData(),pos, drag()->supportedActions());
+ if (response.isAccepted()) {
+ setExecutedDropAction(response.acceptedAction());
+ } else {
+ setExecutedDropAction(Qt::IgnoreAction);
+ }
+}
+
+#endif // QT_NO_DRAGANDDROP
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qsimpledrag_p.h b/src/gui/kernel/qsimpledrag_p.h
new file mode 100644
index 0000000000..36ea4c1ec5
--- /dev/null
+++ b/src/gui/kernel/qsimpledrag_p.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSIMPLEDRAG_H
+#define QSIMPLEDRAG_H
+
+#include <qpa/qplatformdrag.h>
+
+#include <QtCore/QObject>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_DRAGANDDROP
+
+class QMouseEvent;
+class QWindow;
+class QEventLoop;
+class QDropData;
+class QShapedPixmapWindow;
+
+class Q_GUI_EXPORT QBasicDrag : public QPlatformDrag, public QObject
+{
+public:
+ virtual ~QBasicDrag();
+
+ virtual Qt::DropAction drag(QDrag *drag);
+
+ virtual bool eventFilter(QObject *o, QEvent *e);
+
+protected:
+ QBasicDrag();
+
+ virtual void startDrag();
+ virtual void cancel();
+ virtual void move(const QMouseEvent *me);
+ virtual void drop(const QMouseEvent *me);
+ virtual void endDrag();
+
+ QShapedPixmapWindow *shapedPixmapWindow() const { return m_drag_icon_window; }
+ void updateCursor(Qt::DropAction action);
+
+ bool canDrop() const { return m_can_drop; }
+ void setCanDrop(bool c) { m_can_drop = c; }
+
+ Qt::DropAction executedDropAction() const { return m_executed_drop_action; }
+ void setExecutedDropAction(Qt::DropAction da) { m_executed_drop_action = da; }
+
+ QDrag *drag() const { return m_drag; }
+
+private:
+ void enableEventFilter();
+ void disableEventFilter();
+ void restoreCursor();
+ void exitDndEventLoop();
+
+ bool m_restoreCursor;
+ QEventLoop *m_eventLoop;
+ Qt::DropAction m_executed_drop_action;
+ bool m_can_drop;
+ QDrag *m_drag;
+ QShapedPixmapWindow *m_drag_icon_window;
+};
+
+class Q_GUI_EXPORT QSimpleDrag : public QBasicDrag
+{
+public:
+ QSimpleDrag();
+ virtual QMimeData *platformDropData();
+
+protected:
+ virtual void startDrag();
+ virtual void cancel();
+ virtual void move(const QMouseEvent *me);
+ virtual void drop(const QMouseEvent *me);
+
+private:
+ QWindow *m_current_window;
+};
+
+#endif // QT_NO_DRAGANDDROP
+
+QT_END_NAMESPACE
+
+#endif