xref: /aoo42x/main/dtrans/source/os2/dnd/DropTarget.cxx (revision cc13e73e)
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