vcl/inc/qt5/QtDragAndDrop.hxx    |   13 ++-
 vcl/inc/qt5/QtInstanceWidget.hxx |    2 
 vcl/inc/qt5/QtTools.hxx          |    9 --
 vcl/qt5/QtDragAndDrop.cxx        |  132 +++++++++++++++++++++++++++++++++++++--
 vcl/qt5/QtInstanceWidget.cxx     |   46 +++++++++++++
 vcl/qt5/QtTools.cxx              |  120 -----------------------------------
 6 files changed, 182 insertions(+), 140 deletions(-)

New commits:
commit 81dcfb488ac2a0bfc41ff5f1ca2be46e315dff62
Author:     Michael Weghorn <[email protected]>
AuthorDate: Wed Jul 23 14:28:27 2025 +0200
Commit:     Michael Weghorn <[email protected]>
CommitDate: Wed Jul 23 22:56:07 2025 +0200

    qt dnd: Move some logic from QtTools to QtDropTarget
    
    These are only used in QtDragAndDrop.cxx and
    are not very generic, so move them to the latter
    source file instead.
    
    Also change the helper functions to create a VCL
    drop event from a QEvent to helper methods
    in QtDropTarget and use `this` directly instead
    of them being static functions that take a QtDropTarget*
    param.
    
    Most of the logic was previously moved to QtTools in
    
        commit cc4dbbf714faef42cd17ccd7fcfc240d3e5aa977
        Author: Michael Weghorn <[email protected]>
        Date:   Tue Jul 1 16:49:38 2025 +0200
    
            tdf#130857 qt: Extract helpers to convert Qt drag/drop to LO events
    
    with the idea to share it between QtFrame and
    QtInstanceWidget, but the logic was now eventually
    moved from QtFrame to QtDropTarget in
    
        Change-Id: I2b4df4459028b7c2b1da300306e12f032a7605ff
        Author: Michael Weghorn <[email protected]>
        Date:   Wed Jul 23 13:36:22 2025 +0200
    
            tdf#130857 qt dnd: Move some logic from QtFrame to QtDropTarget
    
    instead and that is reused by QtInstanceWidget, so it
    is no longer needed elsewhere.
    
    Change-Id: I2303d88d74bb1da4d1871396075737c1f0b6866c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188233
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <[email protected]>

diff --git a/vcl/inc/qt5/QtDragAndDrop.hxx b/vcl/inc/qt5/QtDragAndDrop.hxx
index ed8b32a8f10f..77c246352da7 100644
--- a/vcl/inc/qt5/QtDragAndDrop.hxx
+++ b/vcl/inc/qt5/QtDragAndDrop.hxx
@@ -92,6 +92,13 @@ public:
 
     sal_Int8 proposedDropAction() const { return m_nDropAction; }
     bool dropSuccessful() const { return m_bDropSuccessful; }
+
+private:
+    css::datatransfer::dnd::DropTargetDragEnterEvent
+    createDropTargetDragEnterEvent(const QDragMoveEvent& rEvent, bool 
bSetDataFlavors,
+                                   qreal fScaleFactor);
+    css::datatransfer::dnd::DropTargetDropEvent 
createDropTargetDropEvent(const QDropEvent& rEvent,
+                                                                          
qreal fScaleFactor);
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/vcl/inc/qt5/QtTools.hxx b/vcl/inc/qt5/QtTools.hxx
index c97d87f4c881..a30e3fdf4bd9 100644
--- a/vcl/inc/qt5/QtTools.hxx
+++ b/vcl/inc/qt5/QtTools.hxx
@@ -21,8 +21,6 @@
 
 #include <config_vclplug.h>
 
-#include "QtDragAndDrop.hxx"
-
 #include <QtCore/QDate>
 #include <QtCore/QPoint>
 #include <QtCore/QRect>
@@ -42,7 +40,6 @@
 #include <vcl/qt/QtUtils.hxx>
 #include <vcl/vclenum.hxx>
 
-#include <com/sun/star/datatransfer/dnd/DropTargetDragEnterEvent.hpp>
 #include <com/sun/star/lang/Locale.hpp>
 #include <com/sun/star/uno/Sequence.hxx>
 #include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
@@ -103,12 +100,6 @@ TriState toVclTriState(Qt::CheckState eTristate);
 Qt::DropActions toQtDropActions(sal_Int8 dragOperation);
 sal_Int8 toVclDropActions(Qt::DropActions dragOperation);
 sal_Int8 toVclDropAction(Qt::DropAction dragOperation);
-css::datatransfer::dnd::DropTargetDragEnterEvent
-toVclDropTargetDragEnterEvent(const QDragMoveEvent& rEvent, QtDropTarget* 
pDropTarget,
-                              bool bSetDataFlavors, qreal fScaleFactor);
-css::datatransfer::dnd::DropTargetDropEvent
-toVclDropTargetDropEvent(const QDropEvent& rEvent, QtDropTarget* pDropTarget, 
qreal fScaleFactor);
-Qt::DropAction getPreferredDropAction(sal_Int8 dragOperation);
 
 inline QList<int> toQList(const css::uno::Sequence<sal_Int32>& aSequence)
 {
diff --git a/vcl/qt5/QtDragAndDrop.cxx b/vcl/qt5/QtDragAndDrop.cxx
index 04c1198d0307..a5dae454d4a4 100644
--- a/vcl/qt5/QtDragAndDrop.cxx
+++ b/vcl/qt5/QtDragAndDrop.cxx
@@ -44,6 +44,71 @@ public:
         return { "application/x.libreoffice-internal-drag-and-drop" };
     }
 };
+
+Qt::DropAction lcl_getPreferredDropAction(sal_Int8 dragOperation)
+{
+    Qt::DropAction eAct = Qt::IgnoreAction;
+    if (dragOperation & css::datatransfer::dnd::DNDConstants::ACTION_MOVE)
+        eAct = Qt::MoveAction;
+    else if (dragOperation & css::datatransfer::dnd::DNDConstants::ACTION_COPY)
+        eAct = Qt::CopyAction;
+    else if (dragOperation & css::datatransfer::dnd::DNDConstants::ACTION_LINK)
+        eAct = Qt::LinkAction;
+    return eAct;
+}
+
+css::uno::Reference<css::datatransfer::XTransferable>
+lcl_getXTransferable(const QMimeData* pMimeData)
+{
+    css::uno::Reference<css::datatransfer::XTransferable> xTransferable;
+    const QtMimeData* pQtMimeData = qobject_cast<const QtMimeData*>(pMimeData);
+    if (!pQtMimeData)
+        xTransferable = new QtDnDTransferable(pMimeData);
+    else
+        xTransferable = pQtMimeData->xTransferable();
+    return xTransferable;
+}
+
+sal_Int8 lcl_getUserDropAction(const QDropEvent& rEvent, const sal_Int8 
nSourceActions,
+                               const QMimeData* pMimeData)
+{
+// we completely ignore all proposals by the Qt event, as they don't
+// match at all with the preferred LO DnD actions.
+// check the key modifiers to detect a user-overridden DnD action
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+    const Qt::KeyboardModifiers eKeyMod = rEvent.modifiers();
+#else
+    const Qt::KeyboardModifiers eKeyMod = rEvent.keyboardModifiers();
+#endif
+    sal_Int8 nUserDropAction = 0;
+    if ((eKeyMod & Qt::ShiftModifier) && !(eKeyMod & Qt::ControlModifier))
+        nUserDropAction = css::datatransfer::dnd::DNDConstants::ACTION_MOVE;
+    else if ((eKeyMod & Qt::ControlModifier) && !(eKeyMod & Qt::ShiftModifier))
+        nUserDropAction = css::datatransfer::dnd::DNDConstants::ACTION_COPY;
+    else if ((eKeyMod & Qt::ShiftModifier) && (eKeyMod & Qt::ControlModifier))
+        nUserDropAction = css::datatransfer::dnd::DNDConstants::ACTION_LINK;
+    nUserDropAction &= nSourceActions;
+
+    // select the default DnD action, if there isn't a user preference
+    if (0 == nUserDropAction)
+    {
+        // default LO internal action is move, but default external action is 
copy
+        nUserDropAction = qobject_cast<const QtMimeData*>(pMimeData)
+                              ? 
css::datatransfer::dnd::DNDConstants::ACTION_MOVE
+                              : 
css::datatransfer::dnd::DNDConstants::ACTION_COPY;
+        nUserDropAction &= nSourceActions;
+
+        // if the default doesn't match any allowed source action, fall back 
to the
+        // preferred of all allowed source actions
+        if (0 == nUserDropAction)
+            nUserDropAction = 
toVclDropAction(lcl_getPreferredDropAction(nSourceActions));
+
+        // this is "our" preference, but actually we would even prefer any 
default,
+        // if there is any
+        nUserDropAction |= 
css::datatransfer::dnd::DNDConstants::ACTION_DEFAULT;
+    }
+    return nUserDropAction;
+}
 }
 
 QtDragSource::QtDragSource(QtFrame* pFrame)
@@ -74,7 +139,7 @@ void QtDragSource::startDrag(
         drag->setMimeData(new QtDragMimeData(rTrans));
         // just a reminder that exec starts a nested event loop, so everything 
after
         // this call is just executed, after D'n'D has finished!
-        drag->exec(toQtDropActions(sourceActions), 
getPreferredDropAction(sourceActions));
+        drag->exec(toQtDropActions(sourceActions), 
lcl_getPreferredDropAction(sourceActions));
     }
 
     // the drop will eventually call fire_dragEnd, which will clear the 
listener.
@@ -138,7 +203,7 @@ QtDropTarget::~QtDropTarget() {}
 void QtDropTarget::handleDragEnterEvent(QDragEnterEvent& rEvent, qreal 
fScaleFactor)
 {
     css::datatransfer::dnd::DropTargetDragEnterEvent aEvent
-        = toVclDropTargetDragEnterEvent(rEvent, this, true, fScaleFactor);
+        = createDropTargetDragEnterEvent(rEvent, true, fScaleFactor);
     dragEnter(aEvent);
 
     if (qobject_cast<const QtMimeData*>(rEvent.mimeData()))
@@ -150,13 +215,13 @@ void QtDropTarget::handleDragEnterEvent(QDragEnterEvent& 
rEvent, qreal fScaleFac
 void QtDropTarget::handleDragMoveEvent(QDragMoveEvent& rEvent, qreal 
fScaleFactor)
 {
     css::datatransfer::dnd::DropTargetDragEnterEvent aEvent
-        = toVclDropTargetDragEnterEvent(rEvent, this, false, fScaleFactor);
+        = createDropTargetDragEnterEvent(rEvent, false, fScaleFactor);
     dragOver(aEvent);
 
     // the drop target accepted our drop action => inform Qt
     if (proposedDropAction() != 0)
     {
-        rEvent.setDropAction(getPreferredDropAction(proposedDropAction()));
+        rEvent.setDropAction(lcl_getPreferredDropAction(proposedDropAction()));
         rEvent.accept();
     }
     else // or maybe someone else likes it?
@@ -169,7 +234,7 @@ void QtDropTarget::handleDropEvent(QDropEvent& rEvent, 
qreal fScaleFactor)
 
     // ask the drop target to accept our drop action
     css::datatransfer::dnd::DropTargetDropEvent aEvent
-        = toVclDropTargetDropEvent(rEvent, this, fScaleFactor);
+        = createDropTargetDropEvent(rEvent, fScaleFactor);
     drop(aEvent);
 
     const bool bDropSuccessful = dropSuccessful();
@@ -178,7 +243,7 @@ void QtDropTarget::handleDropEvent(QDropEvent& rEvent, 
qreal fScaleFactor)
     // the drop target accepted our drop action => inform Qt
     if (bDropSuccessful)
     {
-        rEvent.setDropAction(getPreferredDropAction(nDropAction));
+        rEvent.setDropAction(lcl_getPreferredDropAction(nDropAction));
         rEvent.accept();
     }
     else // or maybe someone else likes it?
@@ -198,4 +263,59 @@ void QtDropTarget::dropComplete(sal_Bool success)
     m_bDropSuccessful = (m_bDropSuccessful && success);
 }
 
+css::datatransfer::dnd::DropTargetDragEnterEvent
+QtDropTarget::createDropTargetDragEnterEvent(const QDragMoveEvent& rEvent, 
bool bSetDataFlavors,
+                                             qreal fScaleFactor)
+{
+    // prepare our suggested drop action for the drop target
+    const sal_Int8 nSourceActions = toVclDropActions(rEvent.possibleActions());
+    const QMimeData* pMimeData = rEvent.mimeData();
+    const sal_Int8 nUserDropAction = lcl_getUserDropAction(rEvent, 
nSourceActions, pMimeData);
+
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+    const QPoint aPos = rEvent.position().toPoint();
+#else
+    const QPoint aPos = rEvent.pos();
+#endif
+
+    css::datatransfer::dnd::DropTargetDragEnterEvent aEvent;
+    aEvent.Source = static_cast<css::datatransfer::dnd::XDropTarget*>(this);
+    aEvent.Context = this;
+    aEvent.LocationX = aPos.x() * fScaleFactor;
+    aEvent.LocationY = aPos.y() * fScaleFactor;
+    aEvent.DropAction = nUserDropAction;
+    aEvent.SourceActions = nSourceActions;
+
+    if (bSetDataFlavors)
+        aEvent.SupportedDataFlavors = 
lcl_getXTransferable(pMimeData)->getTransferDataFlavors();
+
+    return aEvent;
+}
+
+css::datatransfer::dnd::DropTargetDropEvent
+QtDropTarget::createDropTargetDropEvent(const QDropEvent& rEvent, qreal 
fScaleFactor)
+{
+    // prepare our suggested drop action for the drop target
+    const sal_Int8 nSourceActions = toVclDropActions(rEvent.possibleActions());
+    const sal_Int8 nUserDropAction
+        = lcl_getUserDropAction(rEvent, nSourceActions, rEvent.mimeData());
+
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+    const QPoint aPos = rEvent.position().toPoint();
+#else
+    const QPoint aPos = rEvent.pos();
+#endif
+
+    css::datatransfer::dnd::DropTargetDropEvent aEvent;
+    aEvent.Source = static_cast<css::datatransfer::dnd::XDropTarget*>(this);
+    aEvent.Context = this;
+    aEvent.LocationX = aPos.x() * fScaleFactor;
+    aEvent.LocationY = aPos.y() * fScaleFactor;
+    aEvent.SourceActions = nSourceActions;
+    aEvent.DropAction = nUserDropAction;
+    aEvent.Transferable = lcl_getXTransferable(rEvent.mimeData());
+
+    return aEvent;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/vcl/qt5/QtTools.cxx b/vcl/qt5/QtTools.cxx
index e17936ebfa9c..bb69d490baa4 100644
--- a/vcl/qt5/QtTools.cxx
+++ b/vcl/qt5/QtTools.cxx
@@ -263,126 +263,6 @@ sal_Int8 toVclDropAction(Qt::DropAction dragOperation)
     return nRet;
 }
 
-static css::uno::Reference<css::datatransfer::XTransferable>
-lcl_getXTransferable(const QMimeData* pMimeData)
-{
-    css::uno::Reference<css::datatransfer::XTransferable> xTransferable;
-    const QtMimeData* pQtMimeData = qobject_cast<const QtMimeData*>(pMimeData);
-    if (!pQtMimeData)
-        xTransferable = new QtDnDTransferable(pMimeData);
-    else
-        xTransferable = pQtMimeData->xTransferable();
-    return xTransferable;
-}
-
-static sal_Int8 lcl_getUserDropAction(const QDropEvent& rEvent, const sal_Int8 
nSourceActions,
-                                      const QMimeData* pMimeData)
-{
-// we completely ignore all proposals by the Qt event, as they don't
-// match at all with the preferred LO DnD actions.
-// check the key modifiers to detect a user-overridden DnD action
-#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
-    const Qt::KeyboardModifiers eKeyMod = rEvent.modifiers();
-#else
-    const Qt::KeyboardModifiers eKeyMod = rEvent.keyboardModifiers();
-#endif
-    sal_Int8 nUserDropAction = 0;
-    if ((eKeyMod & Qt::ShiftModifier) && !(eKeyMod & Qt::ControlModifier))
-        nUserDropAction = css::datatransfer::dnd::DNDConstants::ACTION_MOVE;
-    else if ((eKeyMod & Qt::ControlModifier) && !(eKeyMod & Qt::ShiftModifier))
-        nUserDropAction = css::datatransfer::dnd::DNDConstants::ACTION_COPY;
-    else if ((eKeyMod & Qt::ShiftModifier) && (eKeyMod & Qt::ControlModifier))
-        nUserDropAction = css::datatransfer::dnd::DNDConstants::ACTION_LINK;
-    nUserDropAction &= nSourceActions;
-
-    // select the default DnD action, if there isn't a user preference
-    if (0 == nUserDropAction)
-    {
-        // default LO internal action is move, but default external action is 
copy
-        nUserDropAction = qobject_cast<const QtMimeData*>(pMimeData)
-                              ? 
css::datatransfer::dnd::DNDConstants::ACTION_MOVE
-                              : 
css::datatransfer::dnd::DNDConstants::ACTION_COPY;
-        nUserDropAction &= nSourceActions;
-
-        // if the default doesn't match any allowed source action, fall back 
to the
-        // preferred of all allowed source actions
-        if (0 == nUserDropAction)
-            nUserDropAction = 
toVclDropAction(getPreferredDropAction(nSourceActions));
-
-        // this is "our" preference, but actually we would even prefer any 
default,
-        // if there is any
-        nUserDropAction |= 
css::datatransfer::dnd::DNDConstants::ACTION_DEFAULT;
-    }
-    return nUserDropAction;
-}
-
-css::datatransfer::dnd::DropTargetDragEnterEvent
-toVclDropTargetDragEnterEvent(const QDragMoveEvent& rEvent, QtDropTarget* 
pDropTarget,
-                              bool bSetDataFlavors, qreal fScaleFactor)
-{
-    // prepare our suggested drop action for the drop target
-    const sal_Int8 nSourceActions = toVclDropActions(rEvent.possibleActions());
-    const QMimeData* pMimeData = rEvent.mimeData();
-    const sal_Int8 nUserDropAction = lcl_getUserDropAction(rEvent, 
nSourceActions, pMimeData);
-
-#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
-    const QPoint aPos = rEvent.position().toPoint();
-#else
-    const QPoint aPos = rEvent.pos();
-#endif
-
-    css::datatransfer::dnd::DropTargetDragEnterEvent aEvent;
-    aEvent.Source = 
static_cast<css::datatransfer::dnd::XDropTarget*>(pDropTarget);
-    aEvent.Context = pDropTarget;
-    aEvent.LocationX = aPos.x() * fScaleFactor;
-    aEvent.LocationY = aPos.y() * fScaleFactor;
-    aEvent.DropAction = nUserDropAction;
-    aEvent.SourceActions = nSourceActions;
-
-    if (bSetDataFlavors)
-        aEvent.SupportedDataFlavors = 
lcl_getXTransferable(pMimeData)->getTransferDataFlavors();
-
-    return aEvent;
-}
-
-css::datatransfer::dnd::DropTargetDropEvent
-toVclDropTargetDropEvent(const QDropEvent& rEvent, QtDropTarget* pDropTarget, 
qreal fScaleFactor)
-{
-    // prepare our suggested drop action for the drop target
-    const sal_Int8 nSourceActions = toVclDropActions(rEvent.possibleActions());
-    const sal_Int8 nUserDropAction
-        = lcl_getUserDropAction(rEvent, nSourceActions, rEvent.mimeData());
-
-#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
-    const QPoint aPos = rEvent.position().toPoint();
-#else
-    const QPoint aPos = rEvent.pos();
-#endif
-
-    css::datatransfer::dnd::DropTargetDropEvent aEvent;
-    aEvent.Source = 
static_cast<css::datatransfer::dnd::XDropTarget*>(pDropTarget);
-    aEvent.Context = pDropTarget;
-    aEvent.LocationX = aPos.x() * fScaleFactor;
-    aEvent.LocationY = aPos.y() * fScaleFactor;
-    aEvent.SourceActions = nSourceActions;
-    aEvent.DropAction = nUserDropAction;
-    aEvent.Transferable = lcl_getXTransferable(rEvent.mimeData());
-
-    return aEvent;
-}
-
-Qt::DropAction getPreferredDropAction(sal_Int8 dragOperation)
-{
-    Qt::DropAction eAct = Qt::IgnoreAction;
-    if (dragOperation & css::datatransfer::dnd::DNDConstants::ACTION_MOVE)
-        eAct = Qt::MoveAction;
-    else if (dragOperation & css::datatransfer::dnd::DNDConstants::ACTION_COPY)
-        eAct = Qt::CopyAction;
-    else if (dragOperation & css::datatransfer::dnd::DNDConstants::ACTION_LINK)
-        eAct = Qt::LinkAction;
-    return eAct;
-}
-
 QImage toQImage(const Image& rImage)
 {
     QImage aImage;
commit 62b4c5e281200ba06411ac289a0aa769dc4308ef
Author:     Michael Weghorn <[email protected]>
AuthorDate: Wed Jul 23 13:54:57 2025 +0200
Commit:     Michael Weghorn <[email protected]>
CommitDate: Wed Jul 23 22:56:01 2025 +0200

    tdf#130857 qt weld dnd: Implement drop support
    
    Implement the "Drop" side of Drag'n'Drop support
    by implementing QtInstanceWidget::get_drop_target
    and handling the corresponding events in
    QtInstanceWidget::eventFilter.
    
    The relevant logic was moved to QtDropTarget in
    previous commits up to
    
        Change-Id: I2b4df4459028b7c2b1da300306e12f032a7605ff
        Author: Michael Weghorn <[email protected]>
        Date:   Wed Jul 23 13:36:22 2025 +0200
    
            tdf#130857 qt dnd: Move some logic from QtFrame to QtDropTarget
    
    in order to be able to reuse it from here.
    
    In a WIP branch for supporting the "Tools" -> "SQL" dialog
    in Base, this allows to insert text into the
    "Command to execute" field by selecting it in Kate or Gedit
    and using drag'n'drop to get it into the LO dialog.
    
    Change-Id: I636fbcf1bc8aba67b8e32f81291efe10bc08ac9c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188232
    Tested-by: Jenkins
    Reviewed-by: Michael Weghorn <[email protected]>

diff --git a/vcl/inc/qt5/QtDragAndDrop.hxx b/vcl/inc/qt5/QtDragAndDrop.hxx
index c999718b8f3a..ed8b32a8f10f 100644
--- a/vcl/inc/qt5/QtDragAndDrop.hxx
+++ b/vcl/inc/qt5/QtDragAndDrop.hxx
@@ -86,9 +86,9 @@ public:
     sal_Bool SAL_CALL supportsService(OUString const& ServiceName) override;
     css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
 
-    void handleDragEnterEvent(QDragEnterEvent& rEvent, qreal fScaleFactor);
-    void handleDragMoveEvent(QDragMoveEvent& rEvent, qreal fScaleFactor);
-    void handleDropEvent(QDropEvent& rEvent, qreal fScaleFactor);
+    void handleDragEnterEvent(QDragEnterEvent& rEvent, qreal fScaleFactor = 
1.0);
+    void handleDragMoveEvent(QDragMoveEvent& rEvent, qreal fScaleFactor = 1.0);
+    void handleDropEvent(QDropEvent& rEvent, qreal fScaleFactor = 1.0);
 
     sal_Int8 proposedDropAction() const { return m_nDropAction; }
     bool dropSuccessful() const { return m_bDropSuccessful; }
diff --git a/vcl/inc/qt5/QtInstanceWidget.hxx b/vcl/inc/qt5/QtInstanceWidget.hxx
index 3799f09815e4..38edefd7d1e9 100644
--- a/vcl/inc/qt5/QtInstanceWidget.hxx
+++ b/vcl/inc/qt5/QtInstanceWidget.hxx
@@ -9,6 +9,7 @@
 
 #pragma once
 
+#include "QtDragAndDrop.hxx"
 #include "QtInstance.hxx"
 #include <QtWidgets/QApplication>
 #include <QtWidgets/QWidget>
@@ -25,6 +26,7 @@ class QtInstanceWidget : public QObject, public virtual 
weld::Widget
 
     QWidget* m_pWidget;
 
+    rtl::Reference<QtDropTarget> m_pDropTarget;
     int m_nBusyCount = 0;
 
 public:
diff --git a/vcl/qt5/QtInstanceWidget.cxx b/vcl/qt5/QtInstanceWidget.cxx
index 3cf97d867585..a263c5eadcb6 100644
--- a/vcl/qt5/QtInstanceWidget.cxx
+++ b/vcl/qt5/QtInstanceWidget.cxx
@@ -278,6 +278,41 @@ bool QtInstanceWidget::eventFilter(QObject* pObject, 
QEvent* pEvent)
 
     switch (pEvent->type())
     {
+        case QEvent::DragEnter:
+        {
+            if (!m_pDropTarget)
+                return false;
+
+            QDragEnterEvent* pDragEnterEvent = 
static_cast<QDragEnterEvent*>(pEvent);
+            m_pDropTarget->handleDragEnterEvent(*pDragEnterEvent);
+            return true;
+        }
+        case QEvent::DragLeave:
+        {
+            if (!m_pDropTarget)
+                return false;
+
+            m_pDropTarget->dragExit();
+            return true;
+        }
+        case QEvent::DragMove:
+        {
+            if (!m_pDropTarget)
+                return false;
+
+            QDragMoveEvent* pDragMoveEvent = 
static_cast<QDragMoveEvent*>(pEvent);
+            m_pDropTarget->handleDragMoveEvent(*pDragMoveEvent);
+            return true;
+        }
+        case QEvent::Drop:
+        {
+            if (!m_pDropTarget)
+                return false;
+
+            QDropEvent* pDropEvent = static_cast<QDropEvent*>(pEvent);
+            m_pDropTarget->handleDropEvent(*pDropEvent);
+            return true;
+        }
         case QEvent::KeyPress:
         {
             QKeyEvent* pKeyEvent = static_cast<QKeyEvent*>(pEvent);
@@ -697,8 +732,15 @@ VclPtr<VirtualDevice> 
QtInstanceWidget::create_virtual_device() const
 
 css::uno::Reference<css::datatransfer::dnd::XDropTarget> 
QtInstanceWidget::get_drop_target()
 {
-    assert(false && "Not implemented yet");
-    return nullptr;
+    SolarMutexGuard g;
+
+    GetQtInstance().RunInMainThread([this] {
+        getQWidget()->setAcceptDrops(true);
+        if (!m_pDropTarget)
+            m_pDropTarget.set(new QtDropTarget);
+    });
+
+    return m_pDropTarget;
 }
 
 css::uno::Reference<css::datatransfer::clipboard::XClipboard>

Reply via email to