2011-06-23 Yael Aharon <yael.aharon@nokia.com>
authoryael.aharon@nokia.com <yael.aharon@nokia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 23 Jun 2011 17:06:27 +0000 (17:06 +0000)
committeryael.aharon@nokia.com <yael.aharon@nokia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 23 Jun 2011 17:06:27 +0000 (17:06 +0000)
        Reviewed by Andreas Kling.

        [Qt] [WK2] Add drag and drop support
        https://bugs.webkit.org/show_bug.cgi?id=62838

        Add convenience methods to allow encoding/decoding of DragData.
        Move the call to dragEnded() to DragClient, to make WebKit1 and WebKit2
        consistent.

        * page/qt/DragControllerQt.cpp:
        (WebCore::DragController::cleanupAfterSystemDrag):
        * platform/DragData.h:
        (WebCore::DragData::flags):
        (WebCore::DragData::DragData):
        (WebCore::DragData::operator =):
2011-06-23  Yael Aharon  <yael.aharon@nokia.com>

        Reviewed by Andreas Kling.

        [Qt] [WK2] Add drag and drop support
        https://bugs.webkit.org/show_bug.cgi?id=62838

        Call dragEnded from the DragClient to make WebKit1 and WebKit2 consistent.

        * WebCoreSupport/DragClientQt.cpp:
        (WebCore::DragClientQt::startDrag):
2011-06-23  Yael Aharon  <yael.aharon@nokia.com>

        Reviewed by Andreas Kling.

        [Qt] [WK2] Add drag and drop support
        https://bugs.webkit.org/show_bug.cgi?id=62838

        Added missing pieces to add support for DnD in QtWebKit.

        * Shared/qt/ArgumentCodersQt.cpp: Added.
        (CoreIPC::::encode):
        (CoreIPC::::decode):
        * Shared/qt/ArgumentCodersQt.h: Added.
        Encode DragData so that we can transfer the QMimeData between the
        WebProcess and the UI Process.
        I encode the DragData and not QMimeData directly because we don't
        have an associated QMimeData for each message.

        * UIProcess/API/qt/qgraphicswkview.cpp:
        (QGraphicsWKView::init):
        (QGraphicsWKView::dragEnterEvent):
        (QGraphicsWKView::dragLeaveEvent):
        (QGraphicsWKView::dragMoveEvent):
        (QGraphicsWKView::dropEvent):
        * UIProcess/API/qt/qgraphicswkview.h:
        * UIProcess/API/qt/qwkpage.cpp:
        (dropActionToDragOperation):
        (dragOperationToDropAction):
        (dragOperationToDropActions):
        (QWKPagePrivate::dragEnterEvent):
        (QWKPagePrivate::dragLeaveEvent):
        (QWKPagePrivate::dragMoveEvent):
        (QWKPagePrivate::dropEvent):
        (QWKPagePrivate::startDrag):

        Send drag-and-drop related events to WebKit.

        * UIProcess/API/qt/qwkpage_p.h:
        * UIProcess/PageClient.h:
        * UIProcess/WebPageProxy.cpp:
        (WebKit::WebPageProxy::performDragControllerAction):
        (WebKit::WebPageProxy::startDrag):
        * UIProcess/WebPageProxy.h:

         Start the HTML5 drag operation from the UI process, because QDrag
         needs a handle to the QWidget under the mouse.

        * UIProcess/WebPageProxy.messages.in:

        Add message type that takes DragData as a parameter.

        * WebKit2.pro:
        * WebProcess/WebCoreSupport/WebDragClient.cpp:
        * WebProcess/WebCoreSupport/qt/WebDragClientQt.cpp: Added.
        (WebKit::convertImageToBitmap):
        (WebKit::WebDragClient::startDrag):

        Send a message to the UI process to start the HTML5 drag operation.

        * WebProcess/WebPage/WebPage.cpp:
        (WebKit::WebPage::performDragControllerAction):
        * WebProcess/WebPage/WebPage.h:
        * WebProcess/WebPage/WebPage.messages.in:

        Add message type that takes DragData as a parameter.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@89582 268f45cc-cd09-0410-ab3c-d52691b4dbfc

22 files changed:
Source/WebCore/ChangeLog
Source/WebCore/page/qt/DragControllerQt.cpp
Source/WebCore/platform/DragData.h
Source/WebKit/qt/ChangeLog
Source/WebKit/qt/WebCoreSupport/DragClientQt.cpp
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/qt/ArgumentCodersQt.cpp [new file with mode: 0644]
Source/WebKit2/Shared/qt/ArgumentCodersQt.h [new file with mode: 0644]
Source/WebKit2/UIProcess/API/qt/qgraphicswkview.cpp
Source/WebKit2/UIProcess/API/qt/qgraphicswkview.h
Source/WebKit2/UIProcess/API/qt/qwkpage.cpp
Source/WebKit2/UIProcess/API/qt/qwkpage_p.h
Source/WebKit2/UIProcess/PageClient.h
Source/WebKit2/UIProcess/WebPageProxy.cpp
Source/WebKit2/UIProcess/WebPageProxy.h
Source/WebKit2/UIProcess/WebPageProxy.messages.in
Source/WebKit2/WebKit2.pro
Source/WebKit2/WebProcess/WebCoreSupport/WebDragClient.cpp
Source/WebKit2/WebProcess/WebCoreSupport/qt/WebDragClientQt.cpp [new file with mode: 0644]
Source/WebKit2/WebProcess/WebPage/WebPage.cpp
Source/WebKit2/WebProcess/WebPage/WebPage.h
Source/WebKit2/WebProcess/WebPage/WebPage.messages.in

index fe1ca71..d8602a4 100644 (file)
@@ -1,3 +1,21 @@
+2011-06-23  Yael Aharon  <yael.aharon@nokia.com>
+
+        Reviewed by Andreas Kling.
+
+        [Qt] [WK2] Add drag and drop support
+        https://bugs.webkit.org/show_bug.cgi?id=62838
+
+        Add convenience methods to allow encoding/decoding of DragData.
+        Move the call to dragEnded() to DragClient, to make WebKit1 and WebKit2 
+        consistent.
+
+        * page/qt/DragControllerQt.cpp:
+        (WebCore::DragController::cleanupAfterSystemDrag):
+        * platform/DragData.h:
+        (WebCore::DragData::flags):
+        (WebCore::DragData::DragData):
+        (WebCore::DragData::operator =):
+
 2011-06-23  Vsevolod Vlasov  <vsevik@chromium.org>
 
         Reviewed by Yury Semikhatsky.
index dccd6cc..34937e7 100644 (file)
@@ -66,7 +66,6 @@ const IntSize& DragController::maxDragImageSize()
 
 void DragController::cleanupAfterSystemDrag()
 {
-    dragEnded();
 }
 
 }
index 27c0211..923fdb2 100644 (file)
@@ -104,7 +104,7 @@ public:
 #endif
     const IntPoint& clientPosition() const { return m_clientPosition; }
     const IntPoint& globalPosition() const { return m_globalPosition; }
-    DragApplicationFlags flags() { return m_applicationFlags; }
+    DragApplicationFlags flags() const { return m_applicationFlags; }
     DragDataRef platformData() const { return m_platformDragData; }
     DragOperation draggingSourceOperationMask() const { return m_draggingSourceOperationMask; }
     bool containsURL(Frame*, FilenameConversionPolicy filenamePolicy = ConvertFilenames) const;
@@ -122,6 +122,23 @@ public:
 #if PLATFORM(MAC)
     NSPasteboard *pasteboard() { return m_pasteboard.get(); }
 #endif
+
+#if PLATFORM(QT)
+    // This constructor should used only by WebKit2 IPC because DragData
+    // is initialized by the decoder and not in the constructor.
+    DragData() { }
+
+    DragData& operator =(const DragData& data)
+    {
+        m_clientPosition = data.m_clientPosition;
+        m_globalPosition = data.m_globalPosition;
+        m_platformDragData = data.m_platformDragData;
+        m_draggingSourceOperationMask = data.m_draggingSourceOperationMask;
+        m_applicationFlags = data.m_applicationFlags;
+        return *this;
+    }
+#endif
+
 private:
     IntPoint m_clientPosition;
     IntPoint m_globalPosition;
index af3ce26..3152025 100644 (file)
@@ -1,3 +1,15 @@
+2011-06-23  Yael Aharon  <yael.aharon@nokia.com>
+
+        Reviewed by Andreas Kling.
+
+        [Qt] [WK2] Add drag and drop support
+        https://bugs.webkit.org/show_bug.cgi?id=62838
+
+        Call dragEnded from the DragClient to make WebKit1 and WebKit2 consistent.
+
+        * WebCoreSupport/DragClientQt.cpp:
+        (WebCore::DragClientQt::startDrag):
+
 2011-06-23  Joe Wild  <joseph.wild@nokia.com>
 
         Reviewed by Laszlo Gombos.
index 8996b52..aacad69 100644 (file)
@@ -27,7 +27,9 @@
 #include "DragClientQt.h"
 
 #include "ClipboardQt.h"
+#include "DragController.h"
 #include "Frame.h"
+#include "Page.h"
 #include "PlatformMouseEvent.h"
 #include "qwebpage.h"
 
@@ -106,6 +108,7 @@ void DragClientQt::startDrag(DragImageRef dragImage, const IntPoint&, const IntP
         PlatformMouseEvent me(m_webPage->view()->mapFromGlobal(QCursor::pos()), QCursor::pos(), LeftButton, MouseEventMoved, 0, false, false, false, false, 0);
         frame->eventHandler()->dragSourceEndedAt(me, dropActionToDragOperation(actualDropAction));
     }
+    frame->page()->dragController()->dragEnded();
 #endif
 }
 
index e5de9c3..bdaa912 100644 (file)
@@ -1,3 +1,69 @@
+2011-06-23  Yael Aharon  <yael.aharon@nokia.com>
+
+        Reviewed by Andreas Kling.
+
+        [Qt] [WK2] Add drag and drop support
+        https://bugs.webkit.org/show_bug.cgi?id=62838
+
+        Added missing pieces to add support for DnD in QtWebKit.
+
+        * Shared/qt/ArgumentCodersQt.cpp: Added.
+        (CoreIPC::::encode):
+        (CoreIPC::::decode):
+        * Shared/qt/ArgumentCodersQt.h: Added.
+        Encode DragData so that we can transfer the QMimeData between the
+        WebProcess and the UI Process.
+        I encode the DragData and not QMimeData directly because we don't
+        have an associated QMimeData for each message.
+
+        * UIProcess/API/qt/qgraphicswkview.cpp:
+        (QGraphicsWKView::init):
+        (QGraphicsWKView::dragEnterEvent):
+        (QGraphicsWKView::dragLeaveEvent):
+        (QGraphicsWKView::dragMoveEvent):
+        (QGraphicsWKView::dropEvent):
+        * UIProcess/API/qt/qgraphicswkview.h:
+        * UIProcess/API/qt/qwkpage.cpp:
+        (dropActionToDragOperation):
+        (dragOperationToDropAction):
+        (dragOperationToDropActions):
+        (QWKPagePrivate::dragEnterEvent):
+        (QWKPagePrivate::dragLeaveEvent):
+        (QWKPagePrivate::dragMoveEvent):
+        (QWKPagePrivate::dropEvent):
+        (QWKPagePrivate::startDrag):
+
+        Send drag-and-drop related events to WebKit.
+
+        * UIProcess/API/qt/qwkpage_p.h:
+        * UIProcess/PageClient.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::performDragControllerAction):
+        (WebKit::WebPageProxy::startDrag):
+        * UIProcess/WebPageProxy.h:
+
+         Start the HTML5 drag operation from the UI process, because QDrag
+         needs a handle to the QWidget under the mouse.
+
+        * UIProcess/WebPageProxy.messages.in:
+
+        Add message type that takes DragData as a parameter.
+
+        * WebKit2.pro:
+        * WebProcess/WebCoreSupport/WebDragClient.cpp:
+        * WebProcess/WebCoreSupport/qt/WebDragClientQt.cpp: Added.
+        (WebKit::convertImageToBitmap):
+        (WebKit::WebDragClient::startDrag):
+
+        Send a message to the UI process to start the HTML5 drag operation.
+
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::performDragControllerAction):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+
+        Add message type that takes DragData as a parameter.
+
 2011-06-23  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         Reviewed by Martin Robinson.
diff --git a/Source/WebKit2/Shared/qt/ArgumentCodersQt.cpp b/Source/WebKit2/Shared/qt/ArgumentCodersQt.cpp
new file mode 100644 (file)
index 0000000..c89bf44
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+    Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library 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
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#include "config.h"
+#include "ArgumentCodersQt.h"
+
+#include "ArgumentCoders.h"
+#include "WebCoreArgumentCoders.h"
+#include <QMimeData>
+#include <QStringList>
+#include <wtf/text/StringHash.h>
+#include <wtf/text/WTFString.h>
+
+using namespace WebCore;
+
+namespace CoreIPC {
+
+typedef HashMap<String , Vector<uint8_t> > MIMEDataHashMap;
+
+void ArgumentCoder<WebCore::DragData>::encode(ArgumentEncoder* encoder, const DragData& dragData)
+{
+    encoder->encode(dragData.clientPosition());
+    encoder->encode(dragData.globalPosition());
+    encoder->encode((uint64_t)dragData.draggingSourceOperationMask());
+    encoder->encode((uint64_t)dragData.flags());
+
+    bool hasPlatformData = dragData.platformData();
+    encoder->encodeBool(hasPlatformData);
+    if (!hasPlatformData)
+        return;
+
+    QStringList formats = dragData.platformData()->formats();
+    MIMEDataHashMap map;
+    int size = formats.size();
+    for (int i = 0; i < size; i++) {
+        QByteArray bytes = dragData.platformData()->data(formats[i]);
+        Vector<uint8_t> vdata;
+        vdata.append((uint8_t*)(bytes.data()), bytes.size());
+        map.add(String(formats[i]), vdata);
+    }
+    encoder->encode(map);
+}
+
+bool ArgumentCoder<WebCore::DragData>::decode(ArgumentDecoder* decoder, DragData& dragData)
+{
+    IntPoint clientPosition;
+    IntPoint globalPosition;
+    uint64_t sourceOperationMask;
+    uint64_t flags;
+    if (!decoder->decode(clientPosition))
+        return false;
+    if (!decoder->decode(globalPosition))
+        return false;
+    if (!decoder->decode(sourceOperationMask))
+        return false;
+    if (!decoder->decode(flags))
+        return false;
+
+    bool hasPlatformData;
+    if (!decoder->decodeBool(hasPlatformData))
+        return false;
+
+    QMimeData* mimeData = 0;
+    if (hasPlatformData) {
+        MIMEDataHashMap map;
+        if (!decoder->decode(map))
+            return false;
+
+        mimeData = new QMimeData;
+        MIMEDataHashMap::iterator it = map.begin();
+        MIMEDataHashMap::iterator end = map.end();
+        for (; it != end; ++it) {
+            QByteArray bytes((char*)it->second.data(), it->second.size());
+            mimeData->setData(it->first, bytes);
+        }
+    }
+
+    dragData = DragData(mimeData, clientPosition, globalPosition, (DragOperation)sourceOperationMask, (DragApplicationFlags)flags);
+    return true;
+}
+
+}
diff --git a/Source/WebKit2/Shared/qt/ArgumentCodersQt.h b/Source/WebKit2/Shared/qt/ArgumentCodersQt.h
new file mode 100644 (file)
index 0000000..4d15cc0
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+    Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies)
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library 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
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+*/
+
+#ifndef ArgumentCodersQt_h
+#define ArgumentCodersQt_h
+
+#include "ArgumentDecoder.h"
+#include "ArgumentEncoder.h"
+#include "DragData.h"
+
+namespace CoreIPC {
+
+void encode(ArgumentEncoder*, const WebCore::DragData&);
+bool decode(ArgumentDecoder*, WebCore::DragData&);
+
+template<> struct ArgumentCoder<WebCore::DragData> {
+    static void encode(ArgumentEncoder*, const WebCore::DragData&);
+    static bool decode(ArgumentDecoder*, WebCore::DragData&);
+};
+
+}
+
+#endif // ArgumentCodersQt_h
index 3ce53a4..a2591d0 100644 (file)
@@ -79,6 +79,7 @@ void QGraphicsWKView::init(BackingStoreType backingStoreType)
 {
     setFocusPolicy(Qt::StrongFocus);
     setAcceptHoverEvents(true);
+    setAcceptDrops(true);
 
 #if ENABLE(TILED_BACKING_STORE)
     if (backingStoreType == Tiled)
@@ -329,6 +330,64 @@ void QGraphicsWKView::touchEvent(QTouchEvent* ev)
     page()->d->touchEvent(ev);
 }
 
+void QGraphicsWKView::dragEnterEvent(QGraphicsSceneDragDropEvent* ev)
+{
+#ifndef QT_NO_DRAGANDDROP
+    if (d->page)
+        d->page->d->dragEnterEvent(ev);
+#else
+    Q_UNUSED(ev);
+#endif
+}
+
+void QGraphicsWKView::dragLeaveEvent(QGraphicsSceneDragDropEvent* ev)
+{
+#ifndef QT_NO_DRAGANDDROP
+    if (d->page) {
+        const bool accepted = ev->isAccepted();
+        d->page->d->dragLeaveEvent(ev);
+        ev->setAccepted(accepted);
+    }
+
+    if (!ev->isAccepted())
+        QGraphicsWidget::dragLeaveEvent(ev);
+#else
+    Q_UNUSED(ev);
+#endif
+}
+
+void QGraphicsWKView::dragMoveEvent(QGraphicsSceneDragDropEvent* ev)
+{
+#ifndef QT_NO_DRAGANDDROP
+    if (d->page) {
+        const bool accepted = ev->isAccepted();
+        d->page->d->dragMoveEvent(ev);
+        ev->setAccepted(accepted);
+    }
+
+    if (!ev->isAccepted())
+        QGraphicsWidget::dragMoveEvent(ev);
+#else
+    Q_UNUSED(ev);
+#endif
+}
+
+void QGraphicsWKView::dropEvent(QGraphicsSceneDragDropEvent* ev)
+{
+#ifndef QT_NO_DRAGANDDROP
+    if (d->page) {
+        const bool accepted = ev->isAccepted();
+        d->page->d->dropEvent(ev);
+        ev->setAccepted(accepted);
+    }
+
+    if (!ev->isAccepted())
+        QGraphicsWidget::dropEvent(ev);
+#else
+    Q_UNUSED(ev);
+#endif
+}
+
 void QGraphicsWKView::focusInEvent(QFocusEvent*)
 {
     page()->d->page->viewStateDidChange(WebPageProxy::ViewIsFocused | WebPageProxy::ViewWindowIsActive);
index b9847c6..799e01f 100644 (file)
@@ -80,6 +80,11 @@ protected:
     virtual void wheelEvent(QGraphicsSceneWheelEvent*);
     virtual void touchEvent(QTouchEvent*);
 
+    virtual void dragEnterEvent(QGraphicsSceneDragDropEvent*);
+    virtual void dragLeaveEvent(QGraphicsSceneDragDropEvent*);
+    virtual void dragMoveEvent(QGraphicsSceneDragDropEvent*);
+    virtual void dropEvent(QGraphicsSceneDragDropEvent*);
+
     virtual void hoverMoveEvent(QGraphicsSceneHoverEvent*);
 
     Q_SLOT void updateCursor(const QCursor&);
index 5c49fcd..5f76bbe 100644 (file)
@@ -25,6 +25,7 @@
 #include "qwkpreferences_p.h"
 
 #include "ClientImpl.h"
+#include "DragData.h"
 #include "DrawingAreaProxyImpl.h"
 #include "qgraphicswkview.h"
 #include "qwkcontext.h"
@@ -90,6 +91,48 @@ static WebCore::ContextMenuAction contextMenuActionForWebAction(QWKPage::WebActi
     return WebCore::ContextMenuItemTagNoAction;
 }
 
+static inline DragOperation dropActionToDragOperation(Qt::DropActions actions)
+{
+    unsigned result = 0;
+    if (actions & Qt::CopyAction)
+        result |= DragOperationCopy;
+    if (actions & Qt::MoveAction)
+        result |= (DragOperationMove | DragOperationGeneric);
+    if (actions & Qt::LinkAction)
+        result |= DragOperationLink;
+    if (result == (DragOperationCopy | DragOperationMove | DragOperationGeneric | DragOperationLink))
+        result = DragOperationEvery;
+    return (DragOperation)result;
+}
+
+static inline Qt::DropAction dragOperationToDropAction(unsigned dragOperation)
+{
+    Qt::DropAction result = Qt::IgnoreAction;
+    if (dragOperation & DragOperationCopy)
+        result = Qt::CopyAction;
+    else if (dragOperation & DragOperationMove)
+        result = Qt::MoveAction;
+    else if (dragOperation & DragOperationGeneric)
+        result = Qt::MoveAction;
+    else if (dragOperation & DragOperationLink)
+        result = Qt::LinkAction;
+    return result;
+}
+
+static inline Qt::DropActions dragOperationToDropActions(unsigned dragOperations)
+{
+    Qt::DropActions result = Qt::IgnoreAction;
+    if (dragOperations & DragOperationCopy)
+        result |= Qt::CopyAction;
+    if (dragOperations & DragOperationMove)
+        result |= Qt::MoveAction;
+    if (dragOperations & DragOperationGeneric)
+        result |= Qt::MoveAction;
+    if (dragOperations & DragOperationLink)
+        result |= Qt::LinkAction;
+    return result;
+}
+
 QWKPagePrivate::QWKPagePrivate(QWKPage* qq, QWKContext* c, WKPageGroupRef pageGroupRef)
     : q(qq)
     , view(0)
@@ -453,6 +496,55 @@ void QWKPagePrivate::touchEvent(QTouchEvent* event)
 #endif
 }
 
+void QWKPagePrivate::dragEnterEvent(QGraphicsSceneDragDropEvent* ev)
+{
+#ifndef QT_NO_DRAGANDDROP
+    page->resetDragOperation();
+    DragData dragData(ev->mimeData(), ev->pos().toPoint(), QCursor::pos(), dropActionToDragOperation(ev->possibleActions()));
+    page->dragEntered(&dragData);
+    ev->acceptProposedAction();
+#else
+    Q_UNUSED(ev)
+#endif
+}
+
+void QWKPagePrivate::dragLeaveEvent(QGraphicsSceneDragDropEvent* ev)
+{
+#ifndef QT_NO_DRAGANDDROP
+    DragData dragData(0, IntPoint(), QCursor::pos(), DragOperationNone);
+    page->dragExited(&dragData);
+    page->resetDragOperation();
+#else
+    Q_UNUSED(ev)
+#endif
+}
+
+void QWKPagePrivate::dragMoveEvent(QGraphicsSceneDragDropEvent* ev)
+{
+#ifndef QT_NO_DRAGANDDROP
+    DragData dragData(ev->mimeData(), ev->pos().toPoint(), QCursor::pos(), dropActionToDragOperation(ev->possibleActions()));
+    page->dragUpdated(&dragData);
+    ev->setDropAction(dragOperationToDropAction(page->dragOperation()));
+    if (page->dragOperation() != DragOperationNone)
+        ev->accept();
+#else
+    Q_UNUSED(ev)
+#endif
+}
+
+void QWKPagePrivate::dropEvent(QGraphicsSceneDragDropEvent* ev)
+{
+#ifndef QT_NO_DRAGANDDROP
+    DragData dragData(ev->mimeData(), ev->pos().toPoint(), QCursor::pos(), dropActionToDragOperation(ev->possibleActions()));
+    SandboxExtension::Handle handle;
+    page->performDrag(&dragData, String(), handle);
+    ev->setDropAction(dragOperationToDropAction(page->dragOperation()));
+    ev->accept();
+#else
+    Q_UNUSED(ev)
+#endif
+}
+
 void QWKPagePrivate::didRelaunchProcess()
 {
     QGraphicsWKView* wkView = static_cast<QGraphicsWKView*>(view);
@@ -883,6 +975,24 @@ void QWKPagePrivate::didFindZoomableArea(const IntRect& area)
     emit q->zoomableAreaFound(QRect(area));
 }
 
+void QWKPagePrivate::startDrag(const WebCore::DragData& dragData, PassRefPtr<ShareableBitmap> dragImage)
+{
+    QWidget* widget = ownerWidget();
+    if (!widget)
+        return;
+
+    QDrag* drag = new QDrag(widget);
+    if (dragImage)
+        drag->setPixmap(QPixmap::fromImage(dragImage->createQImage()));
+    else if (dragData.platformData() && dragData.platformData()->hasImage())
+        drag->setPixmap(qvariant_cast<QPixmap>(dragData.platformData()->imageData()));
+    DragOperation dragOperationMask = dragData.draggingSourceOperationMask();
+    drag->setMimeData(const_cast<QMimeData*>(dragData.platformData()));
+    Qt::DropAction actualDropAction = drag->exec(dragOperationToDropActions(dragOperationMask));
+
+    page->dragEnded(widget->mapFromGlobal(QCursor::pos()), QCursor::pos(), dropActionToDragOperation(actualDropAction));
+}
+
 WebCore::IntRect QWKPagePrivate::viewportVisibleRect() const
 {
     QGraphicsWKView* wkView = static_cast<QGraphicsWKView*>(view);
index a88c52e..7a317c8 100644 (file)
@@ -24,6 +24,7 @@
 #include "DrawingAreaProxy.h"
 #include "LayerTreeContext.h"
 #include "PageClient.h"
+#include "ShareableBitmap.h"
 #include "qwkpage.h"
 #include "qgraphicswkview.h"
 #include "ViewportArguments.h"
@@ -71,6 +72,7 @@ public:
     virtual void didRelaunchProcess();
     virtual void didChangeContentsSize(const WebCore::IntSize&);
     virtual void didFindZoomableArea(const WebCore::IntRect&);
+    virtual void startDrag(const WebCore::DragData&, PassRefPtr<ShareableBitmap> dragImage);
     virtual WebCore::IntRect viewportVisibleRect() const;
     virtual void setCursor(const WebCore::Cursor&);
     virtual void setViewportArguments(const WebCore::ViewportArguments&);
@@ -112,6 +114,11 @@ public:
     void mouseDoubleClickEvent(QGraphicsSceneMouseEvent*);
     void wheelEvent(QGraphicsSceneWheelEvent*);
 
+    void dragEnterEvent(QGraphicsSceneDragDropEvent*);
+    void dragLeaveEvent(QGraphicsSceneDragDropEvent*);
+    void dragMoveEvent(QGraphicsSceneDragDropEvent*);
+    void dropEvent(QGraphicsSceneDragDropEvent*);
+
     void updateAction(QWKPage::WebAction action);
     void updateNavigationActions();
     void updateEditorActions();
index 2e1cd7a..f7bdc2a 100644 (file)
@@ -103,6 +103,9 @@ public:
 #if PLATFORM(QT)
     virtual void didChangeContentsSize(const WebCore::IntSize&) = 0;
     virtual void didFindZoomableArea(const WebCore::IntRect&) = 0;
+
+    virtual void startDrag(const WebCore::DragData&, PassRefPtr<ShareableBitmap> dragImage) = 0;
+
     virtual WebCore::IntRect viewportVisibleRect() const = 0;
 #endif
 
index 512532e..e71d611 100644 (file)
 #include <shlobj.h>
 #endif
 
+#if PLATFORM(QT)
+#include "ArgumentCodersQt.h"
+#endif
+
 #ifndef NDEBUG
 #include <wtf/RefCountedLeakCounter.h>
 #endif
@@ -801,6 +805,8 @@ void WebPageProxy::performDragControllerAction(DragControllerAction action, Drag
     // FIXME: We should pass the drag data map only on DragEnter.
     process()->send(Messages::WebPage::PerformDragControllerAction(action, dragData->clientPosition(), dragData->globalPosition(),
         dragData->draggingSourceOperationMask(), dragData->dragDataMap(), dragData->flags()), m_pageID);
+#elif PLATFORM(QT)
+    process()->send(Messages::WebPage::PerformDragControllerAction(action, *dragData), m_pageID);
 #else
     process()->send(Messages::WebPage::PerformDragControllerAction(action, dragData->clientPosition(), dragData->globalPosition(), dragData->draggingSourceOperationMask(), dragStorageName, dragData->flags(), sandboxExtensionHandle), m_pageID);
 #endif
@@ -873,6 +879,17 @@ void WebPageProxy::startDragDrop(const IntPoint& imageOrigin, const IntPoint& dr
 }
 #endif
 
+#if PLATFORM(QT)
+void WebPageProxy::startDrag(const DragData& dragData, const ShareableBitmap::Handle& dragImageHandle)
+{
+    RefPtr<ShareableBitmap> dragImage = ShareableBitmap::create(dragImageHandle);
+    if (!dragImage)
+        return;
+
+    m_pageClient->startDrag(dragData, dragImage.release());
+}
+#endif
+
 void WebPageProxy::dragEnded(const IntPoint& clientPosition, const IntPoint& globalPosition, uint64_t operation)
 {
     if (!isValid())
index 90617ac..2612d9a 100644 (file)
@@ -444,6 +444,9 @@ public:
 #if PLATFORM(WIN)
     void startDragDrop(const WebCore::IntPoint& imagePoint, const WebCore::IntPoint& dragPoint, uint64_t okEffect, const HashMap<UINT, Vector<String> >& dataMap, uint64_t fileSize, const String& pathname, const SharedMemory::Handle& fileContentHandle, const WebCore::IntSize& dragImageSize, const SharedMemory::Handle& dragImageHandle, bool isLinkDrag);
 #endif
+#if PLATFORM(QT)
+    void startDrag(const WebCore::DragData&, const ShareableBitmap::Handle& dragImage);
+#endif
     void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*);
     void didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, OwnPtr<CoreIPC::ArgumentEncoder>&);
 
index 6bbce82..7d0fd98 100644 (file)
@@ -209,6 +209,9 @@ messages -> WebPageProxy {
 #if PLATFORM(WIN)
     StartDragDrop(WebCore::IntPoint imagePoint, WebCore::IntPoint dragPoint, uint64_t okEffect, HashMap<UINT,Vector<String> > dataMap, uint64_t fileSize, String pathname, WebKit::SharedMemory::Handle fileContentHandle, WebCore::IntSize dragImageSize, WebKit::SharedMemory::Handle dragImage, bool linkDrag)
 #endif
+#if PLATFORM(QT)
+    StartDrag(WebCore::DragData dragData, WebKit::ShareableBitmap::Handle dragImage)
+#endif
 
 #if PLATFORM(MAC)
     # Dictionary support.
index eeb9f28..e59abec 100644 (file)
@@ -169,6 +169,7 @@ HEADERS += \
     Shared/Plugins/PluginModuleInfo.h \
     Shared/Plugins/PluginProcessCreationParameters.h \
     Shared/Plugins/PluginQuirks.h \
+    Shared/qt/ArgumentCodersQt.h \
     Shared/qt/PlatformCertificateInfo.h \
     Shared/qt/WebEventFactoryQt.h \
     UIProcess/Authentication/AuthenticationChallengeProxy.h \
@@ -374,6 +375,7 @@ SOURCES += \
     Shared/WebURLRequest.cpp \
     Shared/WebURLResponse.cpp \
     Shared/WebWheelEvent.cpp \
+    Shared/qt/ArgumentCodersQt.cpp \
     Shared/qt/LayerTreeContextQt.cpp \
     Shared/qt/ShareableBitmapQt.cpp \
     Shared/qt/NativeWebKeyboardEventQt.cpp \
@@ -517,6 +519,7 @@ SOURCES += \
     WebProcess/WebCoreSupport/WebSearchPopupMenu.cpp \
     WebProcess/WebCoreSupport/qt/WebContextMenuClientQt.cpp \
     WebProcess/WebCoreSupport/qt/WebErrorsQt.cpp \
+    WebProcess/WebCoreSupport/qt/WebDragClientQt.cpp \
     WebProcess/WebCoreSupport/qt/WebFrameNetworkingContext.cpp \
     WebProcess/WebCoreSupport/qt/WebPopupMenuQt.cpp \
     WebProcess/WebPage/DecoderAdapter.cpp \
index 204810e..aefc01a 100644 (file)
@@ -52,7 +52,7 @@ DragSourceAction WebDragClient::dragSourceActionMaskForPoint(const IntPoint& win
     return DragSourceActionAny;
 }
 
-#if !PLATFORM(MAC) && !PLATFORM(WIN)
+#if !PLATFORM(MAC) && !PLATFORM(WIN) && !PLATFORM(QT)
 void WebDragClient::startDrag(DragImageRef, const IntPoint&, const IntPoint&, Clipboard*, Frame*, bool)
 {
 }
diff --git a/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebDragClientQt.cpp b/Source/WebKit2/WebProcess/WebCoreSupport/qt/WebDragClientQt.cpp
new file mode 100644 (file)
index 0000000..826511c
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2011 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WebDragClient.h"
+
+#include "ClipboardQt.h"
+#include "DragData.h"
+#include "GraphicsContext.h"
+#include "ShareableBitmap.h"
+#include "WebCoreArgumentCoders.h"
+#include "WebPage.h"
+#include "WebPageProxyMessages.h"
+
+using namespace WebCore;
+
+namespace WebKit {
+
+static PassRefPtr<ShareableBitmap> convertQPixmapToShareableBitmap(QPixmap* pixmap)
+{
+    // FIXME: We need this hack until https://bugs.webkit.org/show_bug.cgi?id=60621 is fixed.
+    // We cannot pass a null handle so create a pixmap size 1x1 and send that instead.
+    QPixmap p(QSize(1, 1));
+    if (pixmap)
+        p = *pixmap;
+    RefPtr<ShareableBitmap> bitmap = ShareableBitmap::createShareable(IntSize(p.size()), ShareableBitmap::SupportsAlpha);
+    OwnPtr<GraphicsContext> graphicsContext = bitmap->createGraphicsContext();
+
+    graphicsContext->platformContext()->drawPixmap(0, 0, p);
+    return bitmap.release();
+}
+
+void WebDragClient::startDrag(DragImageRef dragImage, const IntPoint& clientPosition, const IntPoint& globalPosition, Clipboard* clipboard, Frame*, bool)
+{
+#ifndef QT_NO_DRAGANDDROP
+    QMimeData* clipboardData = static_cast<ClipboardQt*>(clipboard)->clipboardData();
+    DragOperation dragOperationMask = clipboard->sourceOperation();
+    static_cast<ClipboardQt*>(clipboard)->invalidateWritableData();
+    DragData dragData(clipboardData, clientPosition, globalPosition, dragOperationMask);
+
+    RefPtr<ShareableBitmap> bitmap = convertQPixmapToShareableBitmap(dragImage);
+    ShareableBitmap::Handle handle;
+    if (!bitmap->createHandle(handle))
+        return;
+
+    m_page->send(Messages::WebPageProxy::StartDrag(dragData, handle));
+#else
+    Q_UNUSED(dragImage)
+    Q_UNUSED(clientPosition)
+    Q_UNUSED(globalPosition)
+    Q_UNUSED(clipboard)
+#endif
+}
+
+}
index c05f5d7..adf5266 100644 (file)
@@ -1694,6 +1694,43 @@ void WebPage::performDragControllerAction(uint64_t action, WebCore::IntPoint cli
         ASSERT_NOT_REACHED();
     }
 }
+
+#elif PLATFORM(QT)
+void WebPage::performDragControllerAction(uint64_t action, WebCore::DragData dragData)
+{
+    if (!m_page) {
+        send(Messages::WebPageProxy::DidPerformDragControllerAction(DragOperationNone));
+        QMimeData* data = const_cast<QMimeData*>(dragData.platformData());
+        delete data;
+        return;
+    }
+
+    switch (action) {
+    case DragControllerActionEntered:
+        send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragEntered(&dragData)));
+        break;
+
+    case DragControllerActionUpdated:
+        send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragUpdated(&dragData)));
+        break;
+
+    case DragControllerActionExited:
+        m_page->dragController()->dragExited(&dragData);
+        break;
+
+    case DragControllerActionPerformDrag: {
+        m_page->dragController()->performDrag(&dragData);
+        break;
+    }
+
+    default:
+        ASSERT_NOT_REACHED();
+    }
+    // DragData does not delete its platformData so we need to do that here.
+    QMimeData* data = const_cast<QMimeData*>(dragData.platformData());
+    delete data;
+}
+
 #else
 void WebPage::performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const String& dragStorageName, uint32_t flags, const SandboxExtension::Handle& sandboxExtensionHandle)
 {
index f4513f1..b7e930e 100644 (file)
 #include <wtf/RefPtr.h>
 #include <wtf/text/WTFString.h>
 
+#if PLATFORM(QT)
+#include "ArgumentCodersQt.h"
+#endif
+
 #if ENABLE(TOUCH_EVENTS)
 #include <WebCore/PlatformTouchEvent.h>
 #endif
@@ -374,6 +378,8 @@ public:
     void clearSelection();
 #if PLATFORM(WIN)
     void performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const WebCore::DragDataMap&, uint32_t flags);
+#elif PLATFORM(QT)
+    void performDragControllerAction(uint64_t action, WebCore::DragData);
 #else
     void performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const WTF::String& dragStorageName, uint32_t flags, const SandboxExtension::Handle&);
 #endif
index 98bc0d4..ee35142 100644 (file)
@@ -124,7 +124,10 @@ messages -> WebPage {
 #if PLATFORM(WIN)
     PerformDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, HashMap<UINT,Vector<String>> dataMap, uint32_t flags)
 #endif
-#if !PLATFORM(WIN)
+#if PLATFORM(QT)
+    PerformDragControllerAction(uint64_t action, WebCore::DragData dragData)
+#endif
+#if !PLATFORM(WIN) && !PLATFORM(QT)
     PerformDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, WTF::String dragStorageName, uint32_t flags, WebKit::SandboxExtension::Handle sandboxExtensionHandle)
 #endif
     DragEnded(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t operation)