merge the formfield patch from ooo-build
[ooovba.git] / dtrans / source / win32 / dnd / target.cxx
blobde8da3c581def44ab96068cd0b0088715fbb7d26
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: target.cxx,v $
10 * $Revision: 1.28 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_dtrans.hxx"
33 #include <com/sun/star/datatransfer/dnd/DNDConstants.hpp>
34 #include <com/sun/star/datatransfer/XTransferable.hpp>
35 #include <rtl/unload.h>
37 #include <stdio.h>
38 #include "target.hxx"
39 #include "idroptarget.hxx"
40 #include "globals.hxx"
41 #include "targetdropcontext.hxx"
42 #include "targetdragcontext.hxx"
43 #include <rtl/ustring.h>
44 using namespace rtl;
45 using namespace cppu;
46 using namespace osl;
47 using namespace com::sun::star::datatransfer;
48 using namespace com::sun::star::datatransfer::dnd;
49 using namespace com::sun::star::datatransfer::dnd::DNDConstants;
51 #define WM_REGISTERDRAGDROP WM_USER + 1
52 #define WM_REVOKEDRAGDROP WM_USER + 2
53 //--> TRA
54 extern Reference< XTransferable > g_XTransferable;
56 //<-- TRA
58 extern rtl_StandardModuleCount g_moduleCount;
59 DWORD WINAPI DndTargetOleSTAFunc(LPVOID pParams);
61 DropTarget::DropTarget( const Reference<XMultiServiceFactory>& sf):
62 m_hWnd( NULL),
63 m_serviceFactory( sf),
64 WeakComponentImplHelper3<XInitialization,XDropTarget, XServiceInfo>(m_mutex),
65 m_bActive(sal_True),
66 m_nDefaultActions(ACTION_COPY|ACTION_MOVE|ACTION_LINK|ACTION_DEFAULT),
67 m_nCurrentDropAction( ACTION_NONE),
68 m_oleThreadId( 0),
69 m_pDropTarget( NULL),
70 m_threadIdWindow(0),
71 m_threadIdTarget(0),
72 m_hOleThread(0),
73 m_nLastDropAction(0)
77 g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
81 DropTarget::~DropTarget()
83 g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
86 // called from WeakComponentImplHelperX::dispose
87 // WeakComponentImplHelper calls disposing before it destroys
88 // itself.
89 // NOTE: RevokeDragDrop decrements the ref count on the IDropTarget
90 // interface. (m_pDropTarget)
91 // If the HWND is invalid then it doesn't decrement and
92 // the IDropTarget object will live on. MEMORY LEAK
93 void SAL_CALL DropTarget::disposing()
95 HRESULT hr= S_OK;
96 if( m_threadIdTarget)
98 // Call RevokeDragDrop and wait for the OLE thread to die;
99 PostThreadMessage( m_threadIdTarget, WM_REVOKEDRAGDROP, (WPARAM)this, 0);
100 WaitForSingleObject( m_hOleThread, INFINITE);
101 CloseHandle( m_hOleThread);
102 //OSL_ENSURE( SUCCEEDED( hr), "HWND not valid!" );
104 else
106 hr= RevokeDragDrop( m_hWnd);
107 m_hWnd= 0;
109 if( m_pDropTarget)
111 CoLockObjectExternal( m_pDropTarget, FALSE, TRUE);
112 m_pDropTarget->Release();
115 if( m_oleThreadId)
117 if( m_oleThreadId == CoGetCurrentProcess() )
118 OleUninitialize();
123 void SAL_CALL DropTarget::initialize( const Sequence< Any >& aArguments )
124 throw(Exception, RuntimeException)
126 // The window must be registered for Dnd by RegisterDragDrop. We must ensure
127 // that RegisterDragDrop is called from an STA ( OleInitialize) thread.
128 // As long as the window is registered we need to receive OLE messages in
129 // an OLE thread. That is to say, if DropTarget::initialize was called from an
130 // MTA thread then we create an OLE thread in which the window is registered.
131 // The thread will stay alive until aver RevokeDragDrop has been called.
133 // Additionally even if RegisterDragDrop is called from an STA thread we have
134 // to ensure that it is called from the same thread that created the Window
135 // otherwise meesages sent during DND won't reach the windows message queue.
136 // Calling AttachThreadInput first would resolve this problem but would block
137 // the message queue of the calling thread. So if the current thread
138 // (even if it's an STA thread) and the thread that created the window are not
139 // identical we need to create a new thread as we do when the calling thread is
140 // an MTA thread.
142 if( aArguments.getLength() > 0)
144 // Get the window handle from aArgument. It is needed for RegisterDragDrop.
145 m_hWnd= *(HWND*)aArguments[0].getValue();
146 OSL_ASSERT( IsWindow( m_hWnd) );
148 // Obtain the id of the thread that created the window
149 m_threadIdWindow= GetWindowThreadProcessId( m_hWnd, NULL);
151 HRESULT hr= OleInitialize( NULL);
153 // Current thread is MTA or Current thread and Window thread are not identical
154 if( hr == RPC_E_CHANGED_MODE || GetCurrentThreadId() != m_threadIdWindow )
156 OSL_ENSURE( ! m_threadIdTarget,"initialize was called twice");
157 // create the IDropTargetImplementation
158 m_pDropTarget= new IDropTargetImpl( *static_cast<DropTarget*>( this) );
159 m_pDropTarget->AddRef();
162 // Obtain the id of the thread that created the window
163 m_threadIdWindow= GetWindowThreadProcessId( m_hWnd, NULL);
164 // The event is set by the thread that we will create momentarily.
165 // It indicates that the thread is ready to receive messages.
166 HANDLE m_evtThreadReady= CreateEvent( NULL, FALSE, FALSE, NULL);
168 m_hOleThread= CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)DndTargetOleSTAFunc,
169 &m_evtThreadReady, 0, &m_threadIdTarget);
170 WaitForSingleObject( m_evtThreadReady, INFINITE);
171 CloseHandle( m_evtThreadReady);
172 PostThreadMessage( m_threadIdTarget, WM_REGISTERDRAGDROP, (WPARAM)static_cast<DropTarget*>(this), 0);
174 else if( hr == S_OK || hr == S_FALSE)
176 // current thread is STA
177 // If OleInitialize has been called by the caller then we must not call
178 // OleUninitialize
179 if( hr == S_OK)
181 // caller did not call OleInitialize, so we call OleUninitialize
182 // remember the thread that will call OleUninitialize
183 m_oleThreadId= CoGetCurrentProcess(); // get a unique thread id
186 // Get the window handle from aArgument. It is needed for RegisterDragDrop.
187 // create the IDropTargetImplementation
188 m_pDropTarget= new IDropTargetImpl( *static_cast<DropTarget*>( this) );
189 m_pDropTarget->AddRef();
190 // CoLockObjectExternal is prescribed by the protocol. It bumps up the ref count
191 if( SUCCEEDED( CoLockObjectExternal( m_pDropTarget, TRUE, FALSE)))
193 if( FAILED( RegisterDragDrop( m_hWnd, m_pDropTarget) ) )
195 // do clean up if drag and drop is not possible
196 CoLockObjectExternal( m_pDropTarget, FALSE, FALSE);
197 m_pDropTarget->Release();
198 m_hWnd= NULL;
202 else
203 throw Exception();
208 // This function is called as extra thread from DragSource::startDrag.
209 // The function carries out a drag and drop operation by calling
210 // DoDragDrop. The thread also notifies all XSourceListener.
211 DWORD WINAPI DndTargetOleSTAFunc(LPVOID pParams)
213 HRESULT hr= OleInitialize( NULL);
214 if( SUCCEEDED( hr) )
216 MSG msg;
217 // force the creation of a message queue
218 PeekMessage( &msg, (HWND)NULL, 0, 0, PM_NOREMOVE);
219 // Signal the creator ( DropTarget::initialize) that the thread is
220 // ready to receive messages.
221 SetEvent( *(HANDLE*) pParams);
222 // Thread id is needed for attaching this message queue to the one of the
223 // thread where the window was created.
224 DWORD threadId= GetCurrentThreadId();
225 // We force the creation of a thread message queue. This is necessary
226 // for a later call to AttachThreadInput
227 while( GetMessage(&msg, (HWND)NULL, 0, 0) )
229 if( msg.message == WM_REGISTERDRAGDROP)
231 DropTarget *pTarget= (DropTarget*)msg.wParam;
232 // This thread is attached to the thread that created the window. Hence
233 // this thread also receives all mouse and keyboard messages which are
234 // needed
235 AttachThreadInput( threadId , pTarget->m_threadIdWindow, TRUE );
237 if( SUCCEEDED( CoLockObjectExternal(pTarget-> m_pDropTarget, TRUE, FALSE)))
239 if( FAILED( RegisterDragDrop( pTarget-> m_hWnd, pTarget-> m_pDropTarget) ) )
241 // do clean up if drag and drop is not possible
242 CoLockObjectExternal( pTarget->m_pDropTarget, FALSE, FALSE);
243 pTarget->m_pDropTarget->Release();
244 pTarget->m_hWnd= NULL;
248 else if( msg.message == WM_REVOKEDRAGDROP)
250 DropTarget *pTarget= (DropTarget*)msg.wParam;
251 RevokeDragDrop( pTarget-> m_hWnd);
252 // Detach this thread from the window thread
253 AttachThreadInput( threadId, pTarget->m_threadIdWindow, FALSE);
254 pTarget->m_hWnd= 0;
255 break;
257 TranslateMessage( &msg);
258 DispatchMessage( &msg);
260 OleUninitialize();
262 return 0;
268 // XServiceInfo
269 OUString SAL_CALL DropTarget::getImplementationName( ) throw (RuntimeException)
271 return OUString(RTL_CONSTASCII_USTRINGPARAM(DNDTARGET_IMPL_NAME));;
273 // XServiceInfo
274 sal_Bool SAL_CALL DropTarget::supportsService( const OUString& ServiceName ) throw (RuntimeException)
276 if( ServiceName.equals(OUString(RTL_CONSTASCII_USTRINGPARAM(DNDTARGET_SERVICE_NAME ))))
277 return sal_True;
278 return sal_False;
281 Sequence< OUString > SAL_CALL DropTarget::getSupportedServiceNames( ) throw (RuntimeException)
283 OUString names[1]= {OUString(RTL_CONSTASCII_USTRINGPARAM(DNDTARGET_SERVICE_NAME))};
284 return Sequence<OUString>(names, 1);
288 // XDropTarget ----------------------------------------------------------------
289 void SAL_CALL DropTarget::addDropTargetListener( const Reference< XDropTargetListener >& dtl )
290 throw(RuntimeException)
292 rBHelper.addListener( ::getCppuType( &dtl ), dtl );
295 void SAL_CALL DropTarget::removeDropTargetListener( const Reference< XDropTargetListener >& dtl )
296 throw(RuntimeException)
298 rBHelper.removeListener( ::getCppuType( &dtl ), dtl );
301 sal_Bool SAL_CALL DropTarget::isActive( ) throw(RuntimeException)
303 return m_bActive; //m_bDropTargetRegistered;
307 void SAL_CALL DropTarget::setActive( sal_Bool _b ) throw(RuntimeException)
309 MutexGuard g(m_mutex);
310 m_bActive= _b;
314 sal_Int8 SAL_CALL DropTarget::getDefaultActions( ) throw(RuntimeException)
316 return m_nDefaultActions;
319 void SAL_CALL DropTarget::setDefaultActions( sal_Int8 actions ) throw(RuntimeException)
321 OSL_ENSURE( actions < 8, "No valid default actions");
322 m_nDefaultActions= actions;
326 HRESULT DropTarget::DragEnter( IDataObject *pDataObj,
327 DWORD grfKeyState,
328 POINTL pt,
329 DWORD *pdwEffect)
331 #if defined DBG_CONSOLE_OUT
332 printf("\nDropTarget::DragEnter state: %x effect %d", grfKeyState, *pdwEffect);
333 #endif
334 if( m_bActive )
336 // Intersection of pdwEffect and the allowed actions ( setDefaultActions)
337 m_nCurrentDropAction= getFilteredActions( grfKeyState, *pdwEffect);
338 // m_nLastDropAction has to be set by a listener. If no listener calls
339 //XDropTargetDragContext::acceptDrag and specifies an action then pdwEffect
340 // will be DROPEFFECT_NONE throughout
341 m_nLastDropAction= ACTION_DEFAULT | ACTION_MOVE;
343 m_currentDragContext= static_cast<XDropTargetDragContext*>( new TargetDragContext(
344 static_cast<DropTarget*>(this) ) );
346 //--> TRA
348 // shortcut
349 if ( g_XTransferable.is( ) )
350 m_currentData = g_XTransferable;
351 else
353 // Convert the IDataObject to a XTransferable
354 m_currentData= m_aDataConverter.createTransferableFromDataObj(
355 m_serviceFactory, IDataObjectPtr(pDataObj));
358 //<-- TRA
360 if( m_nCurrentDropAction != ACTION_NONE)
362 DropTargetDragEnterEvent e;
363 e.SupportedDataFlavors= m_currentData->getTransferDataFlavors();
364 e.DropAction= m_nCurrentDropAction;
365 e.Source= Reference<XInterface>( static_cast<XDropTarget*>(this),UNO_QUERY);
366 e.Context= m_currentDragContext;
367 POINT point={ pt.x, pt.y};
368 ScreenToClient( m_hWnd, &point);
369 e.LocationX= point.x;
370 e.LocationY= point.y;
371 e.SourceActions= dndOleDropEffectsToActions( *pdwEffect);
373 fire_dragEnter( e);
374 // Check if the action derived from grfKeyState (m_nCurrentDropAction) or the action set
375 // by the listener (m_nCurrentDropAction) is allowed by the source. Only a allowed action is set
376 // in pdwEffect. The listener notification is asynchron, that is we cannot expext that the listener
377 // has already reacted to the notification.
378 // If there is more then one valid action which is the case when ALT or RIGHT MOUSE BUTTON is pressed
379 // then getDropEffect returns DROPEFFECT_MOVE which is the default value if no other modifier is pressed.
380 // On drop the target should present the user a dialog from which the user may change the action.
381 sal_Int8 allowedActions= dndOleDropEffectsToActions( *pdwEffect);
382 *pdwEffect= dndActionsToSingleDropEffect( m_nLastDropAction & allowedActions);
384 else
386 *pdwEffect= DROPEFFECT_NONE;
389 return S_OK;
392 HRESULT DropTarget::DragOver( DWORD grfKeyState,
393 POINTL pt,
394 DWORD *pdwEffect)
396 if( m_bActive)
398 m_nCurrentDropAction= getFilteredActions( grfKeyState, *pdwEffect);
400 if( m_nCurrentDropAction)
402 DropTargetDragEvent e;
403 e.DropAction= m_nCurrentDropAction;
404 e.Source= Reference<XInterface>(static_cast<XDropTarget*>(this),UNO_QUERY);
405 e.Context= m_currentDragContext;
406 POINT point={ pt.x, pt.y};
407 ScreenToClient( m_hWnd, &point);
408 e.LocationX= point.x;
409 e.LocationY= point.y;
410 e.SourceActions= dndOleDropEffectsToActions( *pdwEffect);
412 // if grfKeyState has changed since the last DragOver then fire events.
413 // A listener might change m_nCurrentDropAction by calling the
414 // XDropTargetDragContext::acceptDrag function. But this is not important
415 // because in the afterwards fired dragOver event the action reflects
416 // grgKeyState again.
417 if( m_nLastDropAction != m_nCurrentDropAction)
418 fire_dropActionChanged( e);
420 // The Event contains a XDropTargetDragContext implementation.
421 fire_dragOver( e);
422 // Check if the action derived from grfKeyState (m_nCurrentDropAction) or the action set
423 // by the listener (m_nCurrentDropAction) is allowed by the source. Only a allowed action is set
424 // in pdwEffect. The listener notification is asynchron, that is we cannot expext that the listener
425 // has already reacted to the notification.
426 // If there is more then one valid action which is the case when ALT or RIGHT MOUSE BUTTON is pressed
427 // then getDropEffect returns DROPEFFECT_MOVE which is the default value if no other modifier is pressed.
428 // On drop the target should present the user a dialog from which the user may change the action.
429 sal_Int8 allowedActions= dndOleDropEffectsToActions( *pdwEffect);
430 // set the last action to the current if listener has not changed the value yet
431 *pdwEffect= dndActionsToSingleDropEffect( m_nLastDropAction & allowedActions);
433 else
435 *pdwEffect= DROPEFFECT_NONE;
438 #if defined DBG_CONSOLE_OUT
439 printf("\nDropTarget::DragOver %d", *pdwEffect );
440 #endif
441 return S_OK;
444 HRESULT DropTarget::DragLeave( void)
446 #if defined DBG_CONSOLE_OUT
447 printf("\nDropTarget::DragLeave");
448 #endif
449 if( m_bActive)
452 m_currentData=0;
453 m_currentDragContext= 0;
454 m_currentDropContext= 0;
455 m_nLastDropAction= 0;
457 if( m_nDefaultActions != ACTION_NONE)
459 DropTargetEvent e;
460 e.Source= static_cast<XDropTarget*>(this);
462 fire_dragExit( e);
465 return S_OK;
468 HRESULT DropTarget::Drop( IDataObject * /*pDataObj*/,
469 DWORD grfKeyState,
470 POINTL pt,
471 DWORD *pdwEffect)
473 #if defined DBG_CONSOLE_OUT
474 printf("\nDropTarget::Drop");
475 #endif
476 if( m_bActive)
479 m_bDropComplete= sal_False;
481 m_nCurrentDropAction= getFilteredActions( grfKeyState, *pdwEffect);
482 m_currentDropContext= static_cast<XDropTargetDropContext*>( new TargetDropContext( static_cast<DropTarget*>(this )) );
483 if( m_nCurrentDropAction)
485 DropTargetDropEvent e;
486 e.DropAction= m_nCurrentDropAction;
487 e.Source= Reference<XInterface>( static_cast<XDropTarget*>(this), UNO_QUERY);
488 e.Context= m_currentDropContext;
489 POINT point={ pt.x, pt.y};
490 ScreenToClient( m_hWnd, &point);
491 e.LocationX= point.x;
492 e.LocationY= point.y;
493 e.SourceActions= dndOleDropEffectsToActions( *pdwEffect);
494 e.Transferable= m_currentData;
495 fire_drop( e);
497 //if fire_drop returns than a listener might have modified m_nCurrentDropAction
498 if( m_bDropComplete == sal_True)
500 sal_Int8 allowedActions= dndOleDropEffectsToActions( *pdwEffect);
501 *pdwEffect= dndActionsToSingleDropEffect( m_nCurrentDropAction & allowedActions);
503 else
504 *pdwEffect= DROPEFFECT_NONE;
506 else
507 *pdwEffect= DROPEFFECT_NONE;
509 m_currentData= 0;
510 m_currentDragContext= 0;
511 m_currentDropContext= 0;
512 m_nLastDropAction= 0;
514 return S_OK;
519 void DropTarget::fire_drop( const DropTargetDropEvent& dte)
521 OInterfaceContainerHelper* pContainer= rBHelper.getContainer( getCppuType( (Reference<XDropTargetListener>* )0 ) );
522 if( pContainer)
524 OInterfaceIteratorHelper iter( *pContainer);
525 while( iter.hasMoreElements())
527 Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next()));
528 listener->drop( dte);
533 void DropTarget::fire_dragEnter( const DropTargetDragEnterEvent& e )
535 OInterfaceContainerHelper* pContainer= rBHelper.getContainer( getCppuType( (Reference<XDropTargetListener>* )0 ) );
536 if( pContainer)
538 OInterfaceIteratorHelper iter( *pContainer);
539 while( iter.hasMoreElements())
541 Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next()));
542 listener->dragEnter( e);
547 void DropTarget::fire_dragExit( const DropTargetEvent& dte )
549 OInterfaceContainerHelper* pContainer= rBHelper.getContainer( getCppuType( (Reference<XDropTargetListener>* )0 ) );
551 if( pContainer)
553 OInterfaceIteratorHelper iter( *pContainer);
554 while( iter.hasMoreElements())
556 Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next()));
557 listener->dragExit( dte);
562 void DropTarget::fire_dragOver( const DropTargetDragEvent& dtde )
564 OInterfaceContainerHelper* pContainer= rBHelper.getContainer( getCppuType( (Reference<XDropTargetListener>* )0 ) );
565 if( pContainer)
567 OInterfaceIteratorHelper iter( *pContainer );
568 while( iter.hasMoreElements())
570 Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next()));
571 listener->dragOver( dtde);
576 void DropTarget::fire_dropActionChanged( const DropTargetDragEvent& dtde )
578 OInterfaceContainerHelper* pContainer= rBHelper.getContainer( getCppuType( (Reference<XDropTargetListener>* )0 ) );
579 if( pContainer)
581 OInterfaceIteratorHelper iter( *pContainer);
582 while( iter.hasMoreElements())
584 Reference<XDropTargetListener> listener( static_cast<XDropTargetListener*>( iter.next()));
585 listener->dropActionChanged( dtde);
590 // Non - interface functions ============================================================
591 // DropTarget fires events to XDropTargetListeners. The event object contains an
592 // XDropTargetDropContext implementaion. When the listener calls on that interface
593 // then the calls are delegated from DropContext (XDropTargetDropContext) to these
594 // functions.
595 // Only one listener which visible area is affected is allowed to call on
596 // XDropTargetDropContext
597 // Returning sal_False would cause the XDropTargetDropContext or ..DragContext implementation
598 // to throw an InvalidDNDOperationException, meaning that a Drag is not currently performed.
599 // return sal_False results in throwing a InvalidDNDOperationException in the caller.
601 void DropTarget::_acceptDrop(sal_Int8 dropOperation, const Reference<XDropTargetDropContext>& context)
603 if( context == m_currentDropContext)
605 m_nCurrentDropAction= dropOperation;
609 void DropTarget::_rejectDrop( const Reference<XDropTargetDropContext>& context)
611 if( context == m_currentDropContext)
613 m_nCurrentDropAction= ACTION_NONE;
617 void DropTarget::_dropComplete(sal_Bool success, const Reference<XDropTargetDropContext>& context)
619 if(context == m_currentDropContext)
621 m_bDropComplete= success;
624 // --------------------------------------------------------------------------------------
625 // DropTarget fires events to XDropTargetListeners. The event object can contains an
626 // XDropTargetDragContext implementaion. When the listener calls on that interface
627 // then the calls are delegated from DragContext (XDropTargetDragContext) to these
628 // functions.
629 // Only one listener which visible area is affected is allowed to call on
630 // XDropTargetDragContext
631 void DropTarget::_acceptDrag( sal_Int8 dragOperation, const Reference<XDropTargetDragContext>& context)
633 if( context == m_currentDragContext)
635 m_nLastDropAction= dragOperation;
639 void DropTarget::_rejectDrag( const Reference<XDropTargetDragContext>& context)
641 if(context == m_currentDragContext)
643 m_nLastDropAction= ACTION_NONE;
648 //--------------------------------------------------------------------------------------
651 // This function determines the action dependend on the pressed
652 // key modifiers ( CTRL, SHIFT, ALT, Right Mouse Button). The result
653 // is then checked against the allowed actions which can be set through
654 // XDropTarget::setDefaultActions. Only those values which are also
655 // default actions are returned. If setDefaultActions has not been called
656 // beforehand the the default actions comprise all possible actions.
657 // params: grfKeyState - the modifier keys and mouse buttons currently pressed
658 inline sal_Int8 DropTarget::getFilteredActions( DWORD grfKeyState, DWORD dwEffect)
660 sal_Int8 actions= dndOleKeysToAction( grfKeyState, dndOleDropEffectsToActions( dwEffect));
661 return actions & m_nDefaultActions;