1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 #include <com/sun/star/awt/MouseButton.hpp>
12 #include <com/sun/star/datatransfer/DataFlavor.hpp>
13 #include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
14 #include <cppuhelper/supportsservice.hxx>
15 #include <sal/log.hxx>
17 #include <QtDragAndDrop.hxx>
18 #include <QtFrame.hxx>
19 #include <QtTransferable.hxx>
20 #include <QtWidget.hxx>
22 #include <QtGui/QDrag>
24 using namespace com::sun::star
;
26 QtDragSource::~QtDragSource() {}
28 void QtDragSource::deinitialize() { m_pFrame
= nullptr; }
30 sal_Bool
QtDragSource::isDragImageSupported() { return true; }
32 sal_Int32
QtDragSource::getDefaultCursor(sal_Int8
) { return 0; }
34 void QtDragSource::initialize(const css::uno::Sequence
<css::uno::Any
>& rArguments
)
36 if (rArguments
.getLength() < 2)
38 throw uno::RuntimeException("DragSource::initialize: Cannot install window event handler",
42 sal_IntPtr nFrame
= 0;
43 rArguments
.getConstArray()[1] >>= nFrame
;
47 throw uno::RuntimeException("DragSource::initialize: missing SalFrame", getXWeak());
50 m_pFrame
= reinterpret_cast<QtFrame
*>(nFrame
);
51 m_pFrame
->registerDragSource(this);
54 void QtDragSource::startDrag(
55 const datatransfer::dnd::DragGestureEvent
& /*rEvent*/, sal_Int8 sourceActions
,
56 sal_Int32
/*cursor*/, sal_Int32
/*image*/,
57 const css::uno::Reference
<css::datatransfer::XTransferable
>& rTrans
,
58 const css::uno::Reference
<css::datatransfer::dnd::XDragSourceListener
>& rListener
)
60 m_xListener
= rListener
;
64 QDrag
* drag
= new QDrag(m_pFrame
->GetQWidget());
65 drag
->setMimeData(new QtMimeData(rTrans
));
66 // just a reminder that exec starts a nested event loop, so everything after
67 // this call is just executed, after D'n'D has finished!
68 drag
->exec(toQtDropActions(sourceActions
), getPreferredDropAction(sourceActions
));
71 // the drop will eventually call fire_dragEnd, which will clear the listener.
72 // if D'n'D ends without success, we just get a leave event without any indicator,
73 // but the event loop will be terminated, so we have to try to inform the source of
74 // a failure in any way.
75 fire_dragEnd(datatransfer::dnd::DNDConstants::ACTION_NONE
, false);
78 void QtDragSource::fire_dragEnd(sal_Int8 nAction
, bool bDropSuccessful
)
80 if (!m_xListener
.is())
83 datatransfer::dnd::DragSourceDropEvent aEv
;
84 aEv
.DropAction
= nAction
;
85 aEv
.DropSuccess
= bDropSuccessful
;
87 auto xListener
= m_xListener
;
89 xListener
->dragDropEnd(aEv
);
92 OUString SAL_CALL
QtDragSource::getImplementationName()
94 return "com.sun.star.datatransfer.dnd.VclQtDragSource";
97 sal_Bool SAL_CALL
QtDragSource::supportsService(OUString
const& ServiceName
)
99 return cppu::supportsService(this, ServiceName
);
102 css::uno::Sequence
<OUString
> SAL_CALL
QtDragSource::getSupportedServiceNames()
104 return { "com.sun.star.datatransfer.dnd.QtDragSource" };
107 QtDropTarget::QtDropTarget()
108 : WeakComponentImplHelper(m_aMutex
)
111 , m_nDefaultActions(0)
115 OUString SAL_CALL
QtDropTarget::getImplementationName()
117 return "com.sun.star.datatransfer.dnd.VclQtDropTarget";
120 sal_Bool SAL_CALL
QtDropTarget::supportsService(OUString
const& ServiceName
)
122 return cppu::supportsService(this, ServiceName
);
125 css::uno::Sequence
<OUString
> SAL_CALL
QtDropTarget::getSupportedServiceNames()
127 return { "com.sun.star.datatransfer.dnd.QtDropTarget" };
130 QtDropTarget::~QtDropTarget() {}
132 void QtDropTarget::deinitialize()
138 void QtDropTarget::initialize(const uno::Sequence
<uno::Any
>& rArguments
)
140 if (rArguments
.getLength() < 2)
142 throw uno::RuntimeException("DropTarget::initialize: Cannot install window event handler",
146 sal_IntPtr nFrame
= 0;
147 rArguments
.getConstArray()[1] >>= nFrame
;
151 throw uno::RuntimeException("DropTarget::initialize: missing SalFrame", getXWeak());
154 m_nDropAction
= datatransfer::dnd::DNDConstants::ACTION_NONE
;
156 m_pFrame
= reinterpret_cast<QtFrame
*>(nFrame
);
157 m_pFrame
->registerDropTarget(this);
161 void QtDropTarget::addDropTargetListener(
162 const uno::Reference
<css::datatransfer::dnd::XDropTargetListener
>& xListener
)
164 ::osl::Guard
<::osl::Mutex
> aGuard(m_aMutex
);
166 m_aListeners
.push_back(xListener
);
169 void QtDropTarget::removeDropTargetListener(
170 const uno::Reference
<css::datatransfer::dnd::XDropTargetListener
>& xListener
)
172 ::osl::Guard
<::osl::Mutex
> aGuard(m_aMutex
);
174 m_aListeners
.erase(std::remove(m_aListeners
.begin(), m_aListeners
.end(), xListener
),
178 sal_Bool
QtDropTarget::isActive() { return m_bActive
; }
180 void QtDropTarget::setActive(sal_Bool bActive
) { m_bActive
= bActive
; }
182 sal_Int8
QtDropTarget::getDefaultActions() { return m_nDefaultActions
; }
184 void QtDropTarget::setDefaultActions(sal_Int8 nDefaultActions
)
186 m_nDefaultActions
= nDefaultActions
;
189 void QtDropTarget::fire_dragEnter(const css::datatransfer::dnd::DropTargetDragEnterEvent
& dtde
)
191 osl::ClearableGuard
<::osl::Mutex
> aGuard(m_aMutex
);
192 std::vector
<css::uno::Reference
<css::datatransfer::dnd::XDropTargetListener
>> aListeners(
196 for (auto const& listener
: aListeners
)
198 listener
->dragEnter(dtde
);
202 void QtDropTarget::fire_dragOver(const css::datatransfer::dnd::DropTargetDragEnterEvent
& dtde
)
204 osl::ClearableGuard
<::osl::Mutex
> aGuard(m_aMutex
);
205 std::vector
<css::uno::Reference
<css::datatransfer::dnd::XDropTargetListener
>> aListeners(
209 for (auto const& listener
: aListeners
)
210 listener
->dragOver(dtde
);
213 void QtDropTarget::fire_drop(const css::datatransfer::dnd::DropTargetDropEvent
& dtde
)
215 m_bDropSuccessful
= true;
217 osl::ClearableGuard
<osl::Mutex
> aGuard(m_aMutex
);
218 std::vector
<css::uno::Reference
<css::datatransfer::dnd::XDropTargetListener
>> aListeners(
222 for (auto const& listener
: aListeners
)
223 listener
->drop(dtde
);
226 void QtDropTarget::fire_dragExit(const css::datatransfer::dnd::DropTargetEvent
& dte
)
228 osl::ClearableGuard
<::osl::Mutex
> aGuard(m_aMutex
);
229 std::vector
<css::uno::Reference
<css::datatransfer::dnd::XDropTargetListener
>> aListeners(
233 for (auto const& listener
: aListeners
)
234 listener
->dragExit(dte
);
237 void QtDropTarget::acceptDrag(sal_Int8 dragOperation
) { m_nDropAction
= dragOperation
; }
239 void QtDropTarget::rejectDrag() { m_nDropAction
= 0; }
241 void QtDropTarget::acceptDrop(sal_Int8 dropOperation
) { m_nDropAction
= dropOperation
; }
243 void QtDropTarget::rejectDrop() { m_nDropAction
= 0; }
245 void QtDropTarget::dropComplete(sal_Bool success
)
247 m_bDropSuccessful
= (m_bDropSuccessful
&& success
);
250 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */