Add drag and drop events to QWindowSystemInterface.
authorLaszlo Agocs <laszlo.p.agocs@nokia.com>
Mon, 25 Jul 2011 07:09:38 +0000 (10:09 +0300)
committerSamuel Rødal <samuel.rodal@nokia.com>
Mon, 25 Jul 2011 13:26:51 +0000 (15:26 +0200)
For non-desktop platforms these are better suited and are more
QPA style than relying purely on QDragManager/QSimpleDrag/sending
drag events directly to the windows.

Change-Id: Id466830cf83427b3d86925602086a858e8f713e5
Reviewed-on: http://codereview.qt.nokia.com/2084
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
src/gui/kernel/qguiapplication.cpp
src/gui/kernel/qguiapplication_p.h
src/gui/kernel/qwindowsysteminterface_qpa.cpp
src/gui/kernel/qwindowsysteminterface_qpa.h

index b445031..6edf71a 100644 (file)
@@ -62,6 +62,7 @@
 #include "private/qwindow_p.h"
 #include "private/qkeymapper_p.h"
 #include "private/qcursor_p.h"
+#include "private/qdnd_p.h"
 #ifndef QT_NO_CURSOR
 #include "qplatformcursor_qpa.h"
 #endif
@@ -755,6 +756,51 @@ void QGuiApplicationPrivate::processExposeEvent(QWindowSystemInterfacePrivate::E
     QCoreApplication::sendSpontaneousEvent(e->exposed.data(), &event);
 }
 
+Qt::DropAction QGuiApplicationPrivate::processDrag(QWindow *w, QMimeData *dropData, const QPoint &p)
+{
+    static QPointer<QWindow> currentDragWindow;
+    QDragManager *manager = QDragManager::self();
+    if (!dropData) {
+        if (currentDragWindow.data() == w)
+            currentDragWindow = 0;
+        QDragLeaveEvent e;
+        QGuiApplication::sendEvent(w, &e);
+        manager->global_accepted_action = Qt::IgnoreAction;
+        return Qt::IgnoreAction;
+    }
+    QDragMoveEvent me(p, manager->possible_actions, dropData,
+                      QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
+    if (w != currentDragWindow) {
+        if (currentDragWindow) {
+            QDragLeaveEvent e;
+            QGuiApplication::sendEvent(currentDragWindow, &e);
+            manager->global_accepted_action = Qt::IgnoreAction;
+        }
+        currentDragWindow = w;
+        QDragEnterEvent e(p, manager->possible_actions, dropData,
+                          QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
+        QGuiApplication::sendEvent(w, &e);
+        manager->global_accepted_action = e.isAccepted() ? e.dropAction() : Qt::IgnoreAction;
+        if (manager->global_accepted_action != Qt::IgnoreAction) {
+            me.setDropAction(manager->global_accepted_action);
+            me.accept();
+        }
+    }
+    QGuiApplication::sendEvent(w, &me);
+    manager->global_accepted_action = me.isAccepted() ? me.dropAction() : Qt::IgnoreAction;
+    return manager->global_accepted_action;
+}
+
+Qt::DropAction QGuiApplicationPrivate::processDrop(QWindow *w, QMimeData *dropData, const QPoint &p)
+{
+    QDragManager *manager = QDragManager::self();
+    QDropEvent de(p, manager->possible_actions, dropData,
+                  QGuiApplication::mouseButtons(), QGuiApplication::keyboardModifiers());
+    QGuiApplication::sendEvent(w, &de);
+    manager->global_accepted_action = de.isAccepted() ? de.dropAction() : Qt::IgnoreAction;
+    return manager->global_accepted_action;
+}
+
 #ifndef QT_NO_CLIPBOARD
 QClipboard * QGuiApplication::clipboard()
 {
index 8391662..a08dbca 100644 (file)
@@ -125,6 +125,9 @@ public:
 
     static void processExposeEvent(QWindowSystemInterfacePrivate::ExposeEvent *e);
 
+    static Qt::DropAction processDrag(QWindow *w, QMimeData *dropData, const QPoint &p);
+    static Qt::DropAction processDrop(QWindow *w, QMimeData *dropData, const QPoint &p);
+
     static inline Qt::Alignment visualAlignment(Qt::LayoutDirection direction, Qt::Alignment alignment)
     {
         if (!(alignment & Qt::AlignHorizontal_Mask))
index cde46ac..e6fbd5b 100644 (file)
@@ -308,4 +308,14 @@ int QWindowSystemInterface::windowSystemEventsQueued()
     return QWindowSystemInterfacePrivate::windowSystemEventsQueued();
 }
 
+Qt::DropAction QWindowSystemInterface::handleDrag(QWindow *w, QMimeData *dropData, const QPoint &p)
+{
+    return QGuiApplicationPrivate::processDrag(w, dropData, p);
+}
+
+Qt::DropAction QWindowSystemInterface::handleDrop(QWindow *w, QMimeData *dropData, const QPoint &p)
+{
+    return QGuiApplicationPrivate::processDrop(w, dropData, p);
+}
+
 QT_END_NAMESPACE
index 07963b6..7df7c2d 100644 (file)
@@ -55,6 +55,8 @@ QT_BEGIN_HEADER
 
 QT_BEGIN_NAMESPACE
 
+class QMimeData;
+
 QT_MODULE(Gui)
 
 class Q_GUI_EXPORT QWindowSystemInterface
@@ -103,6 +105,10 @@ public:
 
     static void handleExposeEvent(QWindow *w, const QRegion &region);
 
+    // Drag and drop. These events are sent immediately.
+    static Qt::DropAction handleDrag(QWindow *w, QMimeData *dropData, const QPoint &p);
+    static Qt::DropAction handleDrop(QWindow *w, QMimeData *dropData, const QPoint &p);
+
     // Changes to the screen
     static void handleScreenGeometryChange(int screenIndex);
     static void handleScreenAvailableGeometryChange(int screenIndex);