1*cc13e73eSYuri Dario /**************************************************************
2*cc13e73eSYuri Dario *
3*cc13e73eSYuri Dario * Licensed to the Apache Software Foundation (ASF) under one
4*cc13e73eSYuri Dario * or more contributor license agreements. See the NOTICE file
5*cc13e73eSYuri Dario * distributed with this work for additional information
6*cc13e73eSYuri Dario * regarding copyright ownership. The ASF licenses this file
7*cc13e73eSYuri Dario * to you under the Apache License, Version 2.0 (the
8*cc13e73eSYuri Dario * "License"); you may not use this file except in compliance
9*cc13e73eSYuri Dario * with the License. You may obtain a copy of the License at
10*cc13e73eSYuri Dario *
11*cc13e73eSYuri Dario * http://www.apache.org/licenses/LICENSE-2.0
12*cc13e73eSYuri Dario *
13*cc13e73eSYuri Dario * Unless required by applicable law or agreed to in writing,
14*cc13e73eSYuri Dario * software distributed under the License is distributed on an
15*cc13e73eSYuri Dario * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*cc13e73eSYuri Dario * KIND, either express or implied. See the License for the
17*cc13e73eSYuri Dario * specific language governing permissions and limitations
18*cc13e73eSYuri Dario * under the License.
19*cc13e73eSYuri Dario *
20*cc13e73eSYuri Dario *************************************************************/
21*cc13e73eSYuri Dario
22*cc13e73eSYuri Dario
23*cc13e73eSYuri Dario // MARKER(update_precomp.py): autogen include statement, do not remove
24*cc13e73eSYuri Dario #include "precompiled_dtrans.hxx"
25*cc13e73eSYuri Dario #include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
26*cc13e73eSYuri Dario #include <com/sun/star/datatransfer/XTransferable.hpp>
27*cc13e73eSYuri Dario #include <rtl/ustring.h>
28*cc13e73eSYuri Dario #include <cppuhelper/implbase1.hxx>
29*cc13e73eSYuri Dario
30*cc13e73eSYuri Dario #include <vcl/window.hxx>
31*cc13e73eSYuri Dario
32*cc13e73eSYuri Dario #include "globals.hxx"
33*cc13e73eSYuri Dario #include "DropTarget.hxx"
34*cc13e73eSYuri Dario #include "DragSource.hxx"
35*cc13e73eSYuri Dario #include "OTransferable.hxx"
36*cc13e73eSYuri Dario
37*cc13e73eSYuri Dario
38*cc13e73eSYuri Dario using namespace com::sun::star;
39*cc13e73eSYuri Dario using namespace com::sun::star::io;
40*cc13e73eSYuri Dario using namespace com::sun::star::datatransfer::dnd::DNDConstants;
41*cc13e73eSYuri Dario
42*cc13e73eSYuri Dario
DropTarget(const Reference<XMultiServiceFactory> & sf)43*cc13e73eSYuri Dario DropTarget::DropTarget( const Reference<XMultiServiceFactory>& sf):
44*cc13e73eSYuri Dario WeakComponentImplHelper5< XInitialization,
45*cc13e73eSYuri Dario XDropTarget,
46*cc13e73eSYuri Dario XDropTargetDragContext,
47*cc13e73eSYuri Dario XDropTargetDropContext,
48*cc13e73eSYuri Dario XServiceInfo>(m_aMutex),
49*cc13e73eSYuri Dario m_serviceFactory( sf),
50*cc13e73eSYuri Dario dragEnterEmulation( true),
51*cc13e73eSYuri Dario mbActive(false),
52*cc13e73eSYuri Dario mDragSourceSupportedActions(ACTION_NONE),
53*cc13e73eSYuri Dario mSelectedDropAction(ACTION_NONE),
54*cc13e73eSYuri Dario mDefaultActions(ACTION_COPY_OR_MOVE | ACTION_LINK | ACTION_DEFAULT)
55*cc13e73eSYuri Dario {
56*cc13e73eSYuri Dario g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
57*cc13e73eSYuri Dario }
58*cc13e73eSYuri Dario
~DropTarget()59*cc13e73eSYuri Dario DropTarget::~DropTarget()
60*cc13e73eSYuri Dario {
61*cc13e73eSYuri Dario debug_printf("DropTarget::~DropTarget");
62*cc13e73eSYuri Dario
63*cc13e73eSYuri Dario // This will free the previous instance if present,
64*cc13e73eSYuri Dario // so it removes the tmp file
65*cc13e73eSYuri Dario mXTransferable = Reference<XTransferable>();
66*cc13e73eSYuri Dario
67*cc13e73eSYuri Dario g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
68*cc13e73eSYuri Dario }
69*cc13e73eSYuri Dario
initialize(const Sequence<Any> & aArguments)70*cc13e73eSYuri Dario void SAL_CALL DropTarget::initialize(const Sequence< Any >& aArguments)
71*cc13e73eSYuri Dario throw(Exception)
72*cc13e73eSYuri Dario {
73*cc13e73eSYuri Dario if (aArguments.getLength() < 2) {
74*cc13e73eSYuri Dario throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("DropTarget::initialize: Cannot install window event handler")),
75*cc13e73eSYuri Dario static_cast<OWeakObject*>(this));
76*cc13e73eSYuri Dario }
77*cc13e73eSYuri Dario
78*cc13e73eSYuri Dario m_hWnd = *(HWND*) aArguments[0].getValue();
79*cc13e73eSYuri Dario debug_printf("DropTarget::initialize hwnd %x", m_hWnd);
80*cc13e73eSYuri Dario
81*cc13e73eSYuri Dario // subclass window to allow intercepting D&D messages
82*cc13e73eSYuri Dario defWndProc = WinSubclassWindow( m_hWnd, dndFrameProc);
83*cc13e73eSYuri Dario SetWindowDropTargetPtr( m_hWnd, this);
84*cc13e73eSYuri Dario }
85*cc13e73eSYuri Dario
86*cc13e73eSYuri Dario // called from WeakComponentImplHelperX::dispose
87*cc13e73eSYuri Dario // WeakComponentImplHelper calls disposing before it destroys
88*cc13e73eSYuri Dario // itself.
disposing()89*cc13e73eSYuri Dario void SAL_CALL DropTarget::disposing()
90*cc13e73eSYuri Dario {
91*cc13e73eSYuri Dario debug_printf("DropTarget::disposing hwnd %x", m_hWnd);
92*cc13e73eSYuri Dario
93*cc13e73eSYuri Dario // revert window subclassing
94*cc13e73eSYuri Dario WinSubclassWindow( m_hWnd, defWndProc);
95*cc13e73eSYuri Dario defWndProc = NULL;
96*cc13e73eSYuri Dario SetWindowDropTargetPtr( m_hWnd, 0);
97*cc13e73eSYuri Dario }
98*cc13e73eSYuri Dario
addDropTargetListener(const uno::Reference<XDropTargetListener> & dtl)99*cc13e73eSYuri Dario void SAL_CALL DropTarget::addDropTargetListener(const uno::Reference<XDropTargetListener>& dtl)
100*cc13e73eSYuri Dario throw(RuntimeException)
101*cc13e73eSYuri Dario {
102*cc13e73eSYuri Dario debug_printf("DropTarget::addDropTargetListener hwnd %x", m_hWnd);
103*cc13e73eSYuri Dario rBHelper.addListener(::getCppuType(&dtl), dtl);
104*cc13e73eSYuri Dario }
105*cc13e73eSYuri Dario
removeDropTargetListener(const uno::Reference<XDropTargetListener> & dtl)106*cc13e73eSYuri Dario void SAL_CALL DropTarget::removeDropTargetListener(const uno::Reference<XDropTargetListener>& dtl)
107*cc13e73eSYuri Dario throw(RuntimeException)
108*cc13e73eSYuri Dario {
109*cc13e73eSYuri Dario debug_printf("DropTarget::removeDropTargetListener hwnd %x", m_hWnd);
110*cc13e73eSYuri Dario rBHelper.removeListener(::getCppuType(&dtl), dtl);
111*cc13e73eSYuri Dario }
112*cc13e73eSYuri Dario
isActive()113*cc13e73eSYuri Dario sal_Bool SAL_CALL DropTarget::isActive( ) throw(RuntimeException)
114*cc13e73eSYuri Dario {
115*cc13e73eSYuri Dario debug_printf("DropTarget::isActive %d", mbActive);
116*cc13e73eSYuri Dario return mbActive;
117*cc13e73eSYuri Dario }
118*cc13e73eSYuri Dario
setActive(sal_Bool active)119*cc13e73eSYuri Dario void SAL_CALL DropTarget::setActive(sal_Bool active) throw(RuntimeException)
120*cc13e73eSYuri Dario {
121*cc13e73eSYuri Dario debug_printf("DropTarget::setActive %d", active);
122*cc13e73eSYuri Dario mbActive = active;
123*cc13e73eSYuri Dario }
124*cc13e73eSYuri Dario
getDefaultActions()125*cc13e73eSYuri Dario sal_Int8 SAL_CALL DropTarget::getDefaultActions() throw(RuntimeException)
126*cc13e73eSYuri Dario {
127*cc13e73eSYuri Dario debug_printf("DropTarget::getDefaultActions %d", mDefaultActions);
128*cc13e73eSYuri Dario return mDefaultActions;
129*cc13e73eSYuri Dario }
130*cc13e73eSYuri Dario
setDefaultActions(sal_Int8 actions)131*cc13e73eSYuri Dario void SAL_CALL DropTarget::setDefaultActions(sal_Int8 actions) throw(RuntimeException)
132*cc13e73eSYuri Dario {
133*cc13e73eSYuri Dario OSL_ENSURE( actions < 8, "No valid default actions");
134*cc13e73eSYuri Dario mDefaultActions= actions;
135*cc13e73eSYuri Dario }
136*cc13e73eSYuri Dario
137*cc13e73eSYuri Dario //
138*cc13e73eSYuri Dario // XDropTargetDragContext
139*cc13e73eSYuri Dario //
140*cc13e73eSYuri Dario // Non - interface functions ============================================================
141*cc13e73eSYuri Dario // DropTarget fires events to XDropTargetListeners. The event object can contains an
142*cc13e73eSYuri Dario // XDropTargetDragContext implementaion. When the listener calls on that interface
143*cc13e73eSYuri Dario // then the calls are delegated from DragContext (XDropTargetDragContext) to these
144*cc13e73eSYuri Dario // functions.
145*cc13e73eSYuri Dario // Only one listener which visible area is affected is allowed to call on
146*cc13e73eSYuri Dario // XDropTargetDragContext
147*cc13e73eSYuri Dario
acceptDrag(sal_Int8 dragOperation)148*cc13e73eSYuri Dario void SAL_CALL DropTarget::acceptDrag(sal_Int8 dragOperation) throw (RuntimeException)
149*cc13e73eSYuri Dario {
150*cc13e73eSYuri Dario debug_printf("DropTarget::acceptDrag hwnd %x, dragOperation %d", m_hWnd, dragOperation);
151*cc13e73eSYuri Dario mSelectedDropAction = dragOperation;
152*cc13e73eSYuri Dario }
153*cc13e73eSYuri Dario
rejectDrag()154*cc13e73eSYuri Dario void SAL_CALL DropTarget::rejectDrag() throw (RuntimeException)
155*cc13e73eSYuri Dario {
156*cc13e73eSYuri Dario debug_printf("DropTarget::rejectDrag hwnd %x", m_hWnd);
157*cc13e73eSYuri Dario mSelectedDropAction = ACTION_NONE;
158*cc13e73eSYuri Dario }
159*cc13e73eSYuri Dario
160*cc13e73eSYuri Dario //
161*cc13e73eSYuri Dario // XDropTargetDropContext
162*cc13e73eSYuri Dario //
163*cc13e73eSYuri Dario // Non - interface functions ============================================================
164*cc13e73eSYuri Dario // DropTarget fires events to XDropTargetListeners. The event object contains an
165*cc13e73eSYuri Dario // XDropTargetDropContext implementaion. When the listener calls on that interface
166*cc13e73eSYuri Dario // then the calls are delegated from DropContext (XDropTargetDropContext) to these
167*cc13e73eSYuri Dario // functions.
168*cc13e73eSYuri Dario // Only one listener which visible area is affected is allowed to call on
169*cc13e73eSYuri Dario // XDropTargetDropContext
170*cc13e73eSYuri Dario // Returning sal_False would cause the XDropTargetDropContext or ..DragContext implementation
171*cc13e73eSYuri Dario // to throw an InvalidDNDOperationException, meaning that a Drag is not currently performed.
172*cc13e73eSYuri Dario // return sal_False results in throwing a InvalidDNDOperationException in the caller.
173*cc13e73eSYuri Dario //
acceptDrop(sal_Int8 dropOperation)174*cc13e73eSYuri Dario void SAL_CALL DropTarget::acceptDrop(sal_Int8 dropOperation) throw( RuntimeException)
175*cc13e73eSYuri Dario {
176*cc13e73eSYuri Dario debug_printf("DropTarget::acceptDrop hwnd %x, dragOperation %d", m_hWnd, dropOperation);
177*cc13e73eSYuri Dario mSelectedDropAction = dropOperation;
178*cc13e73eSYuri Dario }
179*cc13e73eSYuri Dario
rejectDrop()180*cc13e73eSYuri Dario void SAL_CALL DropTarget::rejectDrop() throw (RuntimeException)
181*cc13e73eSYuri Dario {
182*cc13e73eSYuri Dario debug_printf("DropTarget::rejectDrop hwnd %x", m_hWnd);
183*cc13e73eSYuri Dario mSelectedDropAction = ACTION_NONE;
184*cc13e73eSYuri Dario }
185*cc13e73eSYuri Dario
dropComplete(sal_Bool success)186*cc13e73eSYuri Dario void SAL_CALL DropTarget::dropComplete(sal_Bool success) throw (RuntimeException)
187*cc13e73eSYuri Dario {
188*cc13e73eSYuri Dario debug_printf("DropTarget::dropComplete hwnd %x", m_hWnd);
189*cc13e73eSYuri Dario
190*cc13e73eSYuri Dario // reset action flags
191*cc13e73eSYuri Dario mDragSourceSupportedActions = ACTION_NONE;
192*cc13e73eSYuri Dario mSelectedDropAction = ACTION_NONE;
193*cc13e73eSYuri Dario // enable drag enter emulation again
194*cc13e73eSYuri Dario dragEnterEmulation = true;
195*cc13e73eSYuri Dario // free local transferable list on next d&d or destruction
196*cc13e73eSYuri Dario
197*cc13e73eSYuri Dario // post a dummy message to source window to allow DragSource
198*cc13e73eSYuri Dario // release resources and close internal d&d
199*cc13e73eSYuri Dario if (DragSource::g_DragSourceHwnd != NULLHANDLE) {
200*cc13e73eSYuri Dario debug_printf("DropTarget::renderComplete post DM_AOO_ENDCONVERSATION to source");
201*cc13e73eSYuri Dario WinPostMsg( DragSource::g_DragSourceHwnd, DM_AOO_ENDCONVERSATION, 0,
202*cc13e73eSYuri Dario MPFROMSHORT(success ? DMFL_TARGETSUCCESSFUL : DMFL_TARGETFAIL));
203*cc13e73eSYuri Dario }
204*cc13e73eSYuri Dario
205*cc13e73eSYuri Dario }
206*cc13e73eSYuri Dario
207*cc13e73eSYuri Dario //
208*cc13e73eSYuri Dario // XServiceInfo
209*cc13e73eSYuri Dario //
getImplementationName()210*cc13e73eSYuri Dario OUString SAL_CALL DropTarget::getImplementationName() throw (RuntimeException)
211*cc13e73eSYuri Dario {
212*cc13e73eSYuri Dario return OUString(RTL_CONSTASCII_USTRINGPARAM(OS2_DNDTARGET_IMPL_NAME));;
213*cc13e73eSYuri Dario }
214*cc13e73eSYuri Dario
supportsService(const OUString & ServiceName)215*cc13e73eSYuri Dario sal_Bool SAL_CALL DropTarget::supportsService( const OUString& ServiceName ) throw (RuntimeException)
216*cc13e73eSYuri Dario {
217*cc13e73eSYuri Dario return ServiceName.equals(OUString(RTL_CONSTASCII_USTRINGPARAM( OS2_DNDTARGET_SERVICE_NAME)));
218*cc13e73eSYuri Dario }
219*cc13e73eSYuri Dario
getSupportedServiceNames()220*cc13e73eSYuri Dario Sequence< OUString > SAL_CALL DropTarget::getSupportedServiceNames( ) throw (RuntimeException)
221*cc13e73eSYuri Dario {
222*cc13e73eSYuri Dario OUString names[1]= {OUString(RTL_CONSTASCII_USTRINGPARAM( OS2_DNDTARGET_SERVICE_NAME))};
223*cc13e73eSYuri Dario return Sequence<OUString>(names, 1);
224*cc13e73eSYuri Dario }
225*cc13e73eSYuri Dario
226*cc13e73eSYuri Dario //
227*cc13e73eSYuri Dario // AOO private interface events
228*cc13e73eSYuri Dario //
fire_drop(const DropTargetDropEvent & dte)229*cc13e73eSYuri Dario void DropTarget::fire_drop( const DropTargetDropEvent& dte)
230*cc13e73eSYuri Dario {
231*cc13e73eSYuri Dario OInterfaceContainerHelper* pContainer= rBHelper.getContainer( getCppuType( (uno::Reference<XDropTargetListener>* )0 ) );
232*cc13e73eSYuri Dario if( pContainer)
233*cc13e73eSYuri Dario {
234*cc13e73eSYuri Dario OInterfaceIteratorHelper iter( *pContainer);
235*cc13e73eSYuri Dario while( iter.hasMoreElements())
236*cc13e73eSYuri Dario {
237*cc13e73eSYuri Dario uno::Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next()));
238*cc13e73eSYuri Dario
239*cc13e73eSYuri Dario try { listener->drop( dte); }
240*cc13e73eSYuri Dario catch(RuntimeException&) {}
241*cc13e73eSYuri Dario }
242*cc13e73eSYuri Dario }
243*cc13e73eSYuri Dario debug_printf("DropTarget::fire_drop fired");
244*cc13e73eSYuri Dario }
245*cc13e73eSYuri Dario
fire_dragEnter(const DropTargetDragEnterEvent & e)246*cc13e73eSYuri Dario void DropTarget::fire_dragEnter(const DropTargetDragEnterEvent& e)
247*cc13e73eSYuri Dario {
248*cc13e73eSYuri Dario OInterfaceContainerHelper* pContainer= rBHelper.getContainer( getCppuType( (uno::Reference<XDropTargetListener>* )0 ) );
249*cc13e73eSYuri Dario if( pContainer)
250*cc13e73eSYuri Dario {
251*cc13e73eSYuri Dario OInterfaceIteratorHelper iter( *pContainer);
252*cc13e73eSYuri Dario while( iter.hasMoreElements())
253*cc13e73eSYuri Dario {
254*cc13e73eSYuri Dario uno::Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next()));
255*cc13e73eSYuri Dario
256*cc13e73eSYuri Dario try { listener->dragEnter( e); }
257*cc13e73eSYuri Dario catch (RuntimeException&) {}
258*cc13e73eSYuri Dario }
259*cc13e73eSYuri Dario }
260*cc13e73eSYuri Dario debug_printf("DropTarget::fire_dragEnter fired");
261*cc13e73eSYuri Dario }
262*cc13e73eSYuri Dario
fire_dragExit(const DropTargetEvent & dte)263*cc13e73eSYuri Dario void DropTarget::fire_dragExit(const DropTargetEvent& dte)
264*cc13e73eSYuri Dario {
265*cc13e73eSYuri Dario OInterfaceContainerHelper* pContainer= rBHelper.getContainer( getCppuType( (uno::Reference<XDropTargetListener>* )0 ) );
266*cc13e73eSYuri Dario
267*cc13e73eSYuri Dario if( pContainer)
268*cc13e73eSYuri Dario {
269*cc13e73eSYuri Dario OInterfaceIteratorHelper iter( *pContainer);
270*cc13e73eSYuri Dario while( iter.hasMoreElements())
271*cc13e73eSYuri Dario {
272*cc13e73eSYuri Dario uno::Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next()));
273*cc13e73eSYuri Dario
274*cc13e73eSYuri Dario try { listener->dragExit( dte); }
275*cc13e73eSYuri Dario catch (RuntimeException&) {}
276*cc13e73eSYuri Dario }
277*cc13e73eSYuri Dario }
278*cc13e73eSYuri Dario debug_printf("DropTarget::fire_dragExit fired");
279*cc13e73eSYuri Dario }
280*cc13e73eSYuri Dario
fire_dragOver(const DropTargetDragEvent & dtde)281*cc13e73eSYuri Dario void DropTarget::fire_dragOver(const DropTargetDragEvent& dtde)
282*cc13e73eSYuri Dario {
283*cc13e73eSYuri Dario OInterfaceContainerHelper* pContainer= rBHelper.getContainer( getCppuType( (uno::Reference<XDropTargetListener>* )0 ) );
284*cc13e73eSYuri Dario if( pContainer)
285*cc13e73eSYuri Dario {
286*cc13e73eSYuri Dario OInterfaceIteratorHelper iter( *pContainer );
287*cc13e73eSYuri Dario while( iter.hasMoreElements())
288*cc13e73eSYuri Dario {
289*cc13e73eSYuri Dario uno::Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next()));
290*cc13e73eSYuri Dario
291*cc13e73eSYuri Dario try { listener->dragOver( dtde); }
292*cc13e73eSYuri Dario catch (RuntimeException&) {}
293*cc13e73eSYuri Dario }
294*cc13e73eSYuri Dario }
295*cc13e73eSYuri Dario debug_printf("DropTarget::fire_dragOver fired");
296*cc13e73eSYuri Dario }
297*cc13e73eSYuri Dario
fire_dropActionChanged(const DropTargetDragEvent & dtde)298*cc13e73eSYuri Dario void DropTarget::fire_dropActionChanged(const DropTargetDragEvent& dtde)
299*cc13e73eSYuri Dario {
300*cc13e73eSYuri Dario OInterfaceContainerHelper* pContainer= rBHelper.getContainer( getCppuType( (uno::Reference<XDropTargetListener>* )0 ) );
301*cc13e73eSYuri Dario if( pContainer)
302*cc13e73eSYuri Dario {
303*cc13e73eSYuri Dario OInterfaceIteratorHelper iter( *pContainer);
304*cc13e73eSYuri Dario while( iter.hasMoreElements())
305*cc13e73eSYuri Dario {
306*cc13e73eSYuri Dario uno::Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next()));
307*cc13e73eSYuri Dario
308*cc13e73eSYuri Dario try { listener->dropActionChanged( dtde); }
309*cc13e73eSYuri Dario catch (RuntimeException&) {}
310*cc13e73eSYuri Dario }
311*cc13e73eSYuri Dario }
312*cc13e73eSYuri Dario debug_printf("DropTarget::fire_dropActionChanged fired");
313*cc13e73eSYuri Dario }
314*cc13e73eSYuri Dario
315*cc13e73eSYuri Dario //
316*cc13e73eSYuri Dario // OS/2 specific platform code
317*cc13e73eSYuri Dario //
318*cc13e73eSYuri Dario
dragEnter(PDRAGINFO dragInfo)319*cc13e73eSYuri Dario MRESULT DropTarget::dragEnter( PDRAGINFO dragInfo)
320*cc13e73eSYuri Dario {
321*cc13e73eSYuri Dario debug_printf("DropTarget::dragEnter start hwnd 0x%x", m_hWnd);
322*cc13e73eSYuri Dario
323*cc13e73eSYuri Dario // disable drag enter emulation until next DM_DRAGLEAVE
324*cc13e73eSYuri Dario dragEnterEmulation = false;
325*cc13e73eSYuri Dario
326*cc13e73eSYuri Dario // Get access to the DRAGINFO data structure
327*cc13e73eSYuri Dario DrgAccessDraginfo( dragInfo);
328*cc13e73eSYuri Dario
329*cc13e73eSYuri Dario // Initially when DnD will be started no modifier key can be pressed yet
330*cc13e73eSYuri Dario // thus we are getting all actions that the drag source supports, we save
331*cc13e73eSYuri Dario // this value because later the system masks the drag source actions if
332*cc13e73eSYuri Dario // a modifier key will be pressed
333*cc13e73eSYuri Dario mDragSourceSupportedActions =
334*cc13e73eSYuri Dario SystemToOfficeDragActions( dragInfo->usOperation);
335*cc13e73eSYuri Dario
336*cc13e73eSYuri Dario // Only if the drop target is really interested in the drag actions
337*cc13e73eSYuri Dario // supported by the source
338*cc13e73eSYuri Dario if (mDragSourceSupportedActions & mDefaultActions) {
339*cc13e73eSYuri Dario
340*cc13e73eSYuri Dario //sal_Int8 currentAction = determineDropAction(mDragSourceSupportedActions, sender);
341*cc13e73eSYuri Dario sal_Int8 currentAction = mDragSourceSupportedActions;
342*cc13e73eSYuri Dario
343*cc13e73eSYuri Dario // map from desktop to client window
344*cc13e73eSYuri Dario MapWindowPoint( m_hWnd, dragInfo, &ptlMouse);
345*cc13e73eSYuri Dario
346*cc13e73eSYuri Dario // This will free the previous instance if present,
347*cc13e73eSYuri Dario // so it removes the tmp file
348*cc13e73eSYuri Dario mXTransferable = Reference<XTransferable>();
349*cc13e73eSYuri Dario
350*cc13e73eSYuri Dario // if g_XTransferable is empty this is an external drop operation,
351*cc13e73eSYuri Dario // create a new transferable set
352*cc13e73eSYuri Dario mXTransferable = DragSource::g_XTransferable;
353*cc13e73eSYuri Dario if (!mXTransferable.is()) {
354*cc13e73eSYuri Dario mXTransferable =
355*cc13e73eSYuri Dario //new OTransferable( OUString::createFromAscii( "TestString" ) );
356*cc13e73eSYuri Dario new OTransferable( m_hWnd, dragInfo);
357*cc13e73eSYuri Dario }
358*cc13e73eSYuri Dario
359*cc13e73eSYuri Dario #if 1
360*cc13e73eSYuri Dario // dump data flavours
361*cc13e73eSYuri Dario Sequence<DataFlavor> seq = mXTransferable->getTransferDataFlavors();
362*cc13e73eSYuri Dario for( int i=0; i<seq.getLength(); i++) {
363*cc13e73eSYuri Dario DataFlavor df = seq[i];
364*cc13e73eSYuri Dario debug_printf("DropTarget::dragEnter mimetype %s",
365*cc13e73eSYuri Dario ::rtl::OUStringToOString( df.MimeType, RTL_TEXTENCODING_UTF8 ).getStr());
366*cc13e73eSYuri Dario }
367*cc13e73eSYuri Dario #endif
368*cc13e73eSYuri Dario
369*cc13e73eSYuri Dario debug_printf("DropTarget::dragEnter (%dx%d) mDragSourceSupportedActions %d",
370*cc13e73eSYuri Dario ptlMouse.x, ptlMouse.y,
371*cc13e73eSYuri Dario mDragSourceSupportedActions);
372*cc13e73eSYuri Dario
373*cc13e73eSYuri Dario DropTargetDragEnterEvent dtdee(static_cast<OWeakObject*>(this),
374*cc13e73eSYuri Dario 0, this, currentAction,
375*cc13e73eSYuri Dario ptlMouse.x, ptlMouse.y,
376*cc13e73eSYuri Dario mDragSourceSupportedActions,
377*cc13e73eSYuri Dario mXTransferable->getTransferDataFlavors());
378*cc13e73eSYuri Dario fire_dragEnter(dtdee);
379*cc13e73eSYuri Dario }
380*cc13e73eSYuri Dario
381*cc13e73eSYuri Dario // Release the draginfo data structure
382*cc13e73eSYuri Dario DrgFreeDraginfo(dragInfo);
383*cc13e73eSYuri Dario
384*cc13e73eSYuri Dario return OfficeToSystemDragActions( mSelectedDropAction);
385*cc13e73eSYuri Dario }
386*cc13e73eSYuri Dario
dragOver(PDRAGINFO dragInfo)387*cc13e73eSYuri Dario MRESULT DropTarget::dragOver( PDRAGINFO dragInfo)
388*cc13e73eSYuri Dario {
389*cc13e73eSYuri Dario MRESULT dragOp = MRFROM2SHORT( DOR_NODROPOP, 0);
390*cc13e73eSYuri Dario
391*cc13e73eSYuri Dario if (dragEnterEmulation)
392*cc13e73eSYuri Dario return dragEnter( dragInfo);
393*cc13e73eSYuri Dario
394*cc13e73eSYuri Dario // Get access to the DRAGINFO data structure
395*cc13e73eSYuri Dario DrgAccessDraginfo( dragInfo);
396*cc13e73eSYuri Dario
397*cc13e73eSYuri Dario sal_Int8 currentDragSourceActions =
398*cc13e73eSYuri Dario SystemToOfficeDragActions( dragInfo->usOperation);
399*cc13e73eSYuri Dario
400*cc13e73eSYuri Dario // Only if the drop target is really interessted in the drag actions
401*cc13e73eSYuri Dario // supported by the source
402*cc13e73eSYuri Dario if (currentDragSourceActions & mDefaultActions) {
403*cc13e73eSYuri Dario //sal_Int8 currentAction = determineDropAction(mDragSourceSupportedActions, sender);
404*cc13e73eSYuri Dario sal_Int8 currentAction = currentDragSourceActions;
405*cc13e73eSYuri Dario
406*cc13e73eSYuri Dario // map from desktop to client window
407*cc13e73eSYuri Dario MapWindowPoint( m_hWnd, dragInfo, &ptlMouse);
408*cc13e73eSYuri Dario
409*cc13e73eSYuri Dario DropTargetDragEvent dtde(static_cast<OWeakObject*>(this),
410*cc13e73eSYuri Dario 0, this, currentAction,
411*cc13e73eSYuri Dario ptlMouse.x, ptlMouse.y,
412*cc13e73eSYuri Dario mDragSourceSupportedActions);
413*cc13e73eSYuri Dario // firing the event will result in a XDropTargetDragContext event
414*cc13e73eSYuri Dario fire_dragOver(dtde);
415*cc13e73eSYuri Dario
416*cc13e73eSYuri Dario dragOp = OfficeToSystemDragActions(mSelectedDropAction);
417*cc13e73eSYuri Dario }
418*cc13e73eSYuri Dario
419*cc13e73eSYuri Dario // Release the draginfo data structure
420*cc13e73eSYuri Dario DrgFreeDraginfo(dragInfo);
421*cc13e73eSYuri Dario return dragOp;
422*cc13e73eSYuri Dario }
423*cc13e73eSYuri Dario
dragLeave(PDRAGINFO)424*cc13e73eSYuri Dario MRESULT DropTarget::dragLeave( PDRAGINFO /* dragInfo */)
425*cc13e73eSYuri Dario {
426*cc13e73eSYuri Dario debug_printf("DropTarget::dragLeave");
427*cc13e73eSYuri Dario
428*cc13e73eSYuri Dario DropTargetEvent dte(static_cast<OWeakObject*>(this), 0);
429*cc13e73eSYuri Dario fire_dragExit(dte);
430*cc13e73eSYuri Dario
431*cc13e73eSYuri Dario // reset action flags
432*cc13e73eSYuri Dario mDragSourceSupportedActions = ACTION_NONE;
433*cc13e73eSYuri Dario mSelectedDropAction = ACTION_NONE;
434*cc13e73eSYuri Dario // enable drag enter emulation again
435*cc13e73eSYuri Dario dragEnterEmulation = true;
436*cc13e73eSYuri Dario // free local transferable list on next d&d or destruction
437*cc13e73eSYuri Dario
438*cc13e73eSYuri Dario return 0;
439*cc13e73eSYuri Dario }
440*cc13e73eSYuri Dario
drop(PDRAGINFO dragInfo)441*cc13e73eSYuri Dario MRESULT DropTarget::drop( PDRAGINFO dragInfo)
442*cc13e73eSYuri Dario {
443*cc13e73eSYuri Dario debug_printf("DropTarget::drop");
444*cc13e73eSYuri Dario
445*cc13e73eSYuri Dario // Get access to the DRAGINFO data structure
446*cc13e73eSYuri Dario DrgAccessDraginfo( dragInfo);
447*cc13e73eSYuri Dario
448*cc13e73eSYuri Dario MRESULT dropOp = MRFROM2SHORT( DOR_NODROPOP, 0);
449*cc13e73eSYuri Dario
450*cc13e73eSYuri Dario if (mSelectedDropAction != ACTION_NONE) {
451*cc13e73eSYuri Dario
452*cc13e73eSYuri Dario bool rr = false;
453*cc13e73eSYuri Dario
454*cc13e73eSYuri Dario // map from desktop to client window
455*cc13e73eSYuri Dario MapWindowPoint( m_hWnd, dragInfo, &ptlMouse);
456*cc13e73eSYuri Dario
457*cc13e73eSYuri Dario // if external d&d, request rendering
458*cc13e73eSYuri Dario OTransferable* ot = dynamic_cast<OTransferable*>(mXTransferable.get());
459*cc13e73eSYuri Dario if (ot != NULL) {
460*cc13e73eSYuri Dario // request rendering, if operation is already possible it
461*cc13e73eSYuri Dario // will return false
462*cc13e73eSYuri Dario rr = ot->requestRendering();
463*cc13e73eSYuri Dario debug_printf("DropTarget::drop requestRendering=%d", rr);
464*cc13e73eSYuri Dario }
465*cc13e73eSYuri Dario
466*cc13e73eSYuri Dario // no rendering requested, post a DM_RENDERCOMPLETE to ourselves
467*cc13e73eSYuri Dario // to fire AOO drop event
468*cc13e73eSYuri Dario if (rr == false)
469*cc13e73eSYuri Dario WinPostMsg( m_hWnd, DM_RENDERCOMPLETE, 0, 0);
470*cc13e73eSYuri Dario
471*cc13e73eSYuri Dario dropOp = OfficeToSystemDragActions(mSelectedDropAction);
472*cc13e73eSYuri Dario }
473*cc13e73eSYuri Dario
474*cc13e73eSYuri Dario // Release the draginfo data structure
475*cc13e73eSYuri Dario DrgFreeDraginfo(dragInfo);
476*cc13e73eSYuri Dario
477*cc13e73eSYuri Dario return dropOp;
478*cc13e73eSYuri Dario
479*cc13e73eSYuri Dario }
480*cc13e73eSYuri Dario
renderComplete(PDRAGTRANSFER dragTransfer)481*cc13e73eSYuri Dario MRESULT DropTarget::renderComplete( PDRAGTRANSFER dragTransfer)
482*cc13e73eSYuri Dario {
483*cc13e73eSYuri Dario debug_printf("DropTarget::renderComplete dragTransfer 0x%x", dragTransfer);
484*cc13e73eSYuri Dario
485*cc13e73eSYuri Dario if (dragTransfer != NULL) {
486*cc13e73eSYuri Dario OTransferable* ot = dynamic_cast<OTransferable*>(mXTransferable.get());
487*cc13e73eSYuri Dario // DM_RENDERCOMPLETE cannot be received in internal AOO d&d
488*cc13e73eSYuri Dario if (ot == NULL) {
489*cc13e73eSYuri Dario debug_printf("DropTarget::renderComplete INTERNAL ERROR null dragtransfer");
490*cc13e73eSYuri Dario return 0;
491*cc13e73eSYuri Dario }
492*cc13e73eSYuri Dario
493*cc13e73eSYuri Dario // set rendered data
494*cc13e73eSYuri Dario ot->renderComplete( dragTransfer);
495*cc13e73eSYuri Dario }
496*cc13e73eSYuri Dario
497*cc13e73eSYuri Dario debug_printf("DropTarget::renderComplete mXTransferable.is() %d", mXTransferable.is());
498*cc13e73eSYuri Dario
499*cc13e73eSYuri Dario // complete AOO drop event, this will make AOO call
500*cc13e73eSYuri Dario // XTransferable::getTransferData() for external ops,
501*cc13e73eSYuri Dario // then acceptDrop(), dropComplete() are called from listeners
502*cc13e73eSYuri Dario DropTargetDropEvent dtde( static_cast<OWeakObject*>(this),
503*cc13e73eSYuri Dario 0, this, mSelectedDropAction,
504*cc13e73eSYuri Dario ptlMouse.x, ptlMouse.y,
505*cc13e73eSYuri Dario mDragSourceSupportedActions,
506*cc13e73eSYuri Dario mXTransferable);
507*cc13e73eSYuri Dario fire_drop(dtde);
508*cc13e73eSYuri Dario
509*cc13e73eSYuri Dario // Reserved value, should be 0
510*cc13e73eSYuri Dario return 0;
511*cc13e73eSYuri Dario }
512