update dev300-m58
[ooovba.git] / vcl / source / window / dndevdis.cxx
blob017adbd265d33aeb9c2350e982590de4d5ceef80
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: dndevdis.cxx,v $
10 * $Revision: 1.21 $
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_vcl.hxx"
34 #include <dndevdis.hxx>
35 #include <dndlcon.hxx>
36 #include <vcl/window.h>
38 #include <vos/mutex.hxx>
39 #include <vcl/svapp.hxx>
40 #include <vcl/svdata.hxx>
41 using namespace ::osl;
42 using namespace ::vos;
43 using namespace ::cppu;
44 using namespace ::com::sun::star::uno;
45 using namespace ::com::sun::star::lang;
46 using namespace ::com::sun::star::datatransfer;
47 using namespace ::com::sun::star::datatransfer::dnd;
49 //==================================================================================================
50 // DNDEventDispatcher::DNDEventDispatcher
51 //==================================================================================================
53 DNDEventDispatcher::DNDEventDispatcher( Window * pTopWindow ):
54 m_pTopWindow( pTopWindow ),
55 m_pCurrentWindow( NULL )
59 //==================================================================================================
60 // DNDEventDispatcher::~DNDEventDispatcher
61 //==================================================================================================
63 DNDEventDispatcher::~DNDEventDispatcher()
67 //==================================================================================================
68 // DNDEventDispatcher::drop
69 //==================================================================================================
71 void SAL_CALL DNDEventDispatcher::drop( const DropTargetDropEvent& dtde )
72 throw(RuntimeException)
74 MutexGuard aImplGuard( m_aMutex );
76 Point location( dtde.LocationX, dtde.LocationY );
78 // find the window that is toplevel for this coordinates
79 OClearableGuard aSolarGuard( Application::GetSolarMutex() );
81 // because those coordinates come from outside, they must be mirrored if RTL layout is active
82 if( Application::GetSettings().GetLayoutRTL() )
83 m_pTopWindow->ImplMirrorFramePos( location );
84 Window * pChildWindow = m_pTopWindow->ImplFindWindow( location );
86 if( NULL == pChildWindow )
87 pChildWindow = m_pTopWindow;
89 while( pChildWindow->ImplGetClientWindow() )
90 pChildWindow = pChildWindow->ImplGetClientWindow();
92 if( pChildWindow->ImplIsAntiparallel() )
93 pChildWindow->ImplReMirror( location );
95 aSolarGuard.clear();
97 // handle the case that drop is in an other vcl window than the last dragOver
98 if( pChildWindow != m_pCurrentWindow )
100 // fire dragExit on listeners of previous window
101 fireDragExitEvent( m_pCurrentWindow );
103 fireDragEnterEvent( pChildWindow, static_cast < XDropTargetDragContext * > (this),
104 dtde.DropAction, location, dtde.SourceActions, m_aDataFlavorList );
107 sal_Int32 nListeners = 0;
109 // send drop event to the child window
110 nListeners = fireDropEvent( pChildWindow, dtde.Context, dtde.DropAction,
111 location, dtde.SourceActions, dtde.Transferable );
113 // reject drop if no listeners found
114 if( nListeners == 0 ) {
115 OSL_TRACE( "rejecting drop due to missing listeners." );
116 dtde.Context->rejectDrop();
119 // this is a drop -> no further drag overs
120 m_pCurrentWindow = NULL;
121 m_aDataFlavorList.realloc( 0 );
124 //==================================================================================================
125 // DNDEventDispatcher::dragEnter
126 //==================================================================================================
128 void SAL_CALL DNDEventDispatcher::dragEnter( const DropTargetDragEnterEvent& dtdee )
129 throw(RuntimeException)
131 MutexGuard aImplGuard( m_aMutex );
132 Point location( dtdee.LocationX, dtdee.LocationY );
134 // find the window that is toplevel for this coordinates
135 OClearableGuard aSolarGuard( Application::GetSolarMutex() );
137 // because those coordinates come from outside, they must be mirrored if RTL layout is active
138 if( Application::GetSettings().GetLayoutRTL() )
139 m_pTopWindow->ImplMirrorFramePos( location );
140 Window * pChildWindow = m_pTopWindow->ImplFindWindow( location );
142 if( NULL == pChildWindow )
143 pChildWindow = m_pTopWindow;
145 while( pChildWindow->ImplGetClientWindow() )
146 pChildWindow = pChildWindow->ImplGetClientWindow();
148 if( pChildWindow->ImplIsAntiparallel() )
149 pChildWindow->ImplReMirror( location );
151 aSolarGuard.clear();
153 // assume pointer write operation to be atomic
154 m_pCurrentWindow = pChildWindow;
155 m_aDataFlavorList = dtdee.SupportedDataFlavors;
157 // fire dragEnter on listeners of current window
158 sal_Int32 nListeners = fireDragEnterEvent( pChildWindow, dtdee.Context, dtdee.DropAction, location,
159 dtdee.SourceActions, dtdee.SupportedDataFlavors );
161 // reject drag if no listener found
162 if( nListeners == 0 ) {
163 OSL_TRACE( "rejecting drag enter due to missing listeners." );
164 dtdee.Context->rejectDrag();
169 //==================================================================================================
170 // DNDEventDispatcher::dragExit
171 //==================================================================================================
173 void SAL_CALL DNDEventDispatcher::dragExit( const DropTargetEvent& /*dte*/ )
174 throw(RuntimeException)
176 MutexGuard aImplGuard( m_aMutex );
178 fireDragExitEvent( m_pCurrentWindow );
180 // reset member values
181 m_pCurrentWindow = NULL;
182 m_aDataFlavorList.realloc( 0 );
185 //==================================================================================================
186 // DNDEventDispatcher::dragOver
187 //==================================================================================================
189 void SAL_CALL DNDEventDispatcher::dragOver( const DropTargetDragEvent& dtde )
190 throw(RuntimeException)
192 MutexGuard aImplGuard( m_aMutex );
194 Point location( dtde.LocationX, dtde.LocationY );
195 sal_Int32 nListeners;
197 // find the window that is toplevel for this coordinates
198 OClearableGuard aSolarGuard( Application::GetSolarMutex() );
200 // because those coordinates come from outside, they must be mirrored if RTL layout is active
201 if( Application::GetSettings().GetLayoutRTL() )
202 m_pTopWindow->ImplMirrorFramePos( location );
203 Window * pChildWindow = m_pTopWindow->ImplFindWindow( location );
205 if( NULL == pChildWindow )
206 pChildWindow = m_pTopWindow;
208 while( pChildWindow->ImplGetClientWindow() )
209 pChildWindow = pChildWindow->ImplGetClientWindow();
211 if( pChildWindow->ImplIsAntiparallel() )
212 pChildWindow->ImplReMirror( location );
214 aSolarGuard.clear();
216 if( pChildWindow != m_pCurrentWindow )
218 // fire dragExit on listeners of previous window
219 fireDragExitEvent( m_pCurrentWindow );
221 // remember new window
222 m_pCurrentWindow = pChildWindow;
224 // fire dragEnter on listeners of current window
225 nListeners = fireDragEnterEvent( pChildWindow, dtde.Context, dtde.DropAction, location,
226 dtde.SourceActions, m_aDataFlavorList );
228 else
230 // fire dragOver on listeners of current window
231 nListeners = fireDragOverEvent( pChildWindow, dtde.Context, dtde.DropAction, location,
232 dtde.SourceActions );
235 // reject drag if no listener found
236 if( nListeners == 0 )
238 OSL_TRACE( "rejecting drag over due to missing listeners." );
239 dtde.Context->rejectDrag();
243 //==================================================================================================
244 // DNDEventDispatcher::dropActionChanged
245 //==================================================================================================
247 void SAL_CALL DNDEventDispatcher::dropActionChanged( const DropTargetDragEvent& dtde )
248 throw(RuntimeException)
250 MutexGuard aImplGuard( m_aMutex );
252 Point location( dtde.LocationX, dtde.LocationY );
253 sal_Int32 nListeners;
255 // find the window that is toplevel for this coordinates
256 OClearableGuard aSolarGuard( Application::GetSolarMutex() );
258 // because those coordinates come from outside, they must be mirrored if RTL layout is active
259 if( Application::GetSettings().GetLayoutRTL() )
260 m_pTopWindow->ImplMirrorFramePos( location );
261 Window * pChildWindow = m_pTopWindow->ImplFindWindow( location );
263 if( NULL == pChildWindow )
264 pChildWindow = m_pTopWindow;
266 while( pChildWindow->ImplGetClientWindow() )
267 pChildWindow = pChildWindow->ImplGetClientWindow();
269 if( pChildWindow->ImplIsAntiparallel() )
270 pChildWindow->ImplReMirror( location );
272 aSolarGuard.clear();
274 if( pChildWindow != m_pCurrentWindow )
276 // fire dragExit on listeners of previous window
277 fireDragExitEvent( m_pCurrentWindow );
279 // remember new window
280 m_pCurrentWindow = pChildWindow;
282 // fire dragEnter on listeners of current window
283 nListeners = fireDragEnterEvent( pChildWindow, dtde.Context, dtde.DropAction, location,
284 dtde.SourceActions, m_aDataFlavorList );
286 else
288 // fire dropActionChanged on listeners of current window
289 nListeners = fireDropActionChangedEvent( pChildWindow, dtde.Context, dtde.DropAction, location,
290 dtde.SourceActions );
293 // reject drag if no listener found
294 if( nListeners == 0 )
296 OSL_TRACE( "rejecting dropActionChanged due to missing listeners." );
297 dtde.Context->rejectDrag();
302 //==================================================================================================
303 // DNDEventDispatcher::dragGestureRecognized
304 //==================================================================================================
306 void SAL_CALL DNDEventDispatcher::dragGestureRecognized( const DragGestureEvent& dge )
307 throw(RuntimeException)
308 { MutexGuard aImplGuard( m_aMutex );
310 Point origin( dge.DragOriginX, dge.DragOriginY );
312 // find the window that is toplevel for this coordinates
313 OClearableGuard aSolarGuard( Application::GetSolarMutex() );
315 // because those coordinates come from outside, they must be mirrored if RTL layout is active
316 if( Application::GetSettings().GetLayoutRTL() )
317 m_pTopWindow->ImplMirrorFramePos( origin );
318 Window * pChildWindow = m_pTopWindow->ImplFindWindow( origin );
320 if( NULL == pChildWindow )
321 pChildWindow = m_pTopWindow;
323 while( pChildWindow->ImplGetClientWindow() )
324 pChildWindow = pChildWindow->ImplGetClientWindow();
326 if( pChildWindow->ImplIsAntiparallel() )
327 pChildWindow->ImplReMirror( origin );
329 aSolarGuard.clear();
331 fireDragGestureEvent( pChildWindow, dge.DragSource, dge.Event, origin, dge.DragAction );
334 //==================================================================================================
335 // DNDEventDispatcher::disposing
336 //==================================================================================================
338 void SAL_CALL DNDEventDispatcher::disposing( const EventObject& )
339 throw(RuntimeException)
343 //==================================================================================================
344 // DNDEventDispatcher::acceptDrag
345 //==================================================================================================
347 void SAL_CALL DNDEventDispatcher::acceptDrag( sal_Int8 /*dropAction*/ ) throw(RuntimeException)
351 //==================================================================================================
352 // DNDEventDispatcher::rejectDrag
353 //==================================================================================================
355 void SAL_CALL DNDEventDispatcher::rejectDrag() throw(RuntimeException)
359 //==================================================================================================
360 // DNDEventDispatcher::fireDragEnterEvent
361 //==================================================================================================
363 sal_Int32 DNDEventDispatcher::fireDragEnterEvent( Window *pWindow,
364 const Reference< XDropTargetDragContext >& xContext, const sal_Int8 nDropAction,
365 const Point& rLocation, const sal_Int8 nSourceActions, const Sequence< DataFlavor >& aFlavorList
367 throw(RuntimeException)
369 sal_Int32 n = 0;
371 if( pWindow && pWindow->IsInputEnabled() && ! pWindow->IsInModalMode() )
373 OClearableGuard aGuard( Application::GetSolarMutex() );
375 // set an UI lock
376 pWindow->IncrementLockCount();
378 // query DropTarget from window
379 Reference< XDropTarget > xDropTarget = pWindow->GetDropTarget();
381 if( xDropTarget.is() )
383 // retrieve relative mouse position
384 Point relLoc = pWindow->ImplFrameToOutput( rLocation );
385 aGuard.clear();
387 n = static_cast < DNDListenerContainer * > ( xDropTarget.get() )->fireDragEnterEvent(
388 xContext, nDropAction, relLoc.X(), relLoc.Y(), nSourceActions, aFlavorList );
392 return n;
395 //==================================================================================================
396 // DNDEventDispatcher::fireDragOverEvent
397 //==================================================================================================
399 sal_Int32 DNDEventDispatcher::fireDragOverEvent( Window *pWindow,
400 const Reference< XDropTargetDragContext >& xContext, const sal_Int8 nDropAction,
401 const Point& rLocation, const sal_Int8 nSourceActions
403 throw(RuntimeException)
405 sal_Int32 n = 0;
407 if( pWindow && pWindow->IsInputEnabled() && ! pWindow->IsInModalMode() )
409 OClearableGuard aGuard( Application::GetSolarMutex() );
411 // query DropTarget from window
412 Reference< XDropTarget > xDropTarget = pWindow->GetDropTarget();
414 if( xDropTarget.is() )
416 // retrieve relative mouse position
417 Point relLoc = pWindow->ImplFrameToOutput( rLocation );
418 aGuard.clear();
420 n = static_cast < DNDListenerContainer * > ( xDropTarget.get() )->fireDragOverEvent(
421 xContext, nDropAction, relLoc.X(), relLoc.Y(), nSourceActions );
425 return n;
428 //==================================================================================================
429 // DNDEventDispatcher::fireDragExitEvent
430 //==================================================================================================
432 sal_Int32 DNDEventDispatcher::fireDragExitEvent( Window *pWindow ) throw(RuntimeException)
434 sal_Int32 n = 0;
436 if( pWindow && pWindow->IsInputEnabled() && ! pWindow->IsInModalMode() )
438 OClearableGuard aGuard( Application::GetSolarMutex() );
440 // query DropTarget from window
441 Reference< XDropTarget > xDropTarget = pWindow->GetDropTarget();
443 aGuard.clear();
445 if( xDropTarget.is() )
446 n = static_cast < DNDListenerContainer * > ( xDropTarget.get() )->fireDragExitEvent();
448 // release UI lock
449 pWindow->DecrementLockCount();
452 return n;
455 //==================================================================================================
456 // DNDEventDispatcher::fireDropActionChangedEvent
457 //==================================================================================================
459 sal_Int32 DNDEventDispatcher::fireDropActionChangedEvent( Window *pWindow,
460 const Reference< XDropTargetDragContext >& xContext, const sal_Int8 nDropAction,
461 const Point& rLocation, const sal_Int8 nSourceActions
463 throw(RuntimeException)
465 sal_Int32 n = 0;
467 if( pWindow && pWindow->IsInputEnabled() && ! pWindow->IsInModalMode() )
469 OClearableGuard aGuard( Application::GetSolarMutex() );
471 // query DropTarget from window
472 Reference< XDropTarget > xDropTarget = pWindow->GetDropTarget();
474 if( xDropTarget.is() )
476 // retrieve relative mouse position
477 Point relLoc = pWindow->ImplFrameToOutput( rLocation );
478 aGuard.clear();
480 n = static_cast < DNDListenerContainer * > ( xDropTarget.get() )->fireDropActionChangedEvent(
481 xContext, nDropAction, relLoc.X(), relLoc.Y(), nSourceActions );
485 return n;
488 //==================================================================================================
489 // DNDEventDispatcher::fireDropEvent
490 //==================================================================================================
492 sal_Int32 DNDEventDispatcher::fireDropEvent( Window *pWindow,
493 const Reference< XDropTargetDropContext >& xContext, const sal_Int8 nDropAction, const Point& rLocation,
494 const sal_Int8 nSourceActions, const Reference< XTransferable >& xTransferable
496 throw(RuntimeException)
498 sal_Int32 n = 0;
500 if( pWindow && pWindow->IsInputEnabled() && ! pWindow->IsInModalMode() )
502 OClearableGuard aGuard( Application::GetSolarMutex() );
504 // query DropTarget from window
505 Reference< XDropTarget > xDropTarget = pWindow->GetDropTarget();
507 // window may be destroyed in drop event handler
508 ImplDelData aDelData;
509 pWindow->ImplAddDel( &aDelData );
511 if( xDropTarget.is() )
513 // retrieve relative mouse position
514 Point relLoc = pWindow->ImplFrameToOutput( rLocation );
515 aGuard.clear();
517 n = static_cast < DNDListenerContainer * > ( xDropTarget.get() )->fireDropEvent(
518 xContext, nDropAction, relLoc.X(), relLoc.Y(), nSourceActions, xTransferable );
521 if ( !aDelData.IsDelete() )
523 pWindow->ImplRemoveDel( &aDelData );
524 // release UI lock
525 pWindow->DecrementLockCount();
530 return n;
533 //==================================================================================================
534 // DNDEventDispatcher::fireDragGestureRecognized
535 //==================================================================================================
537 sal_Int32 DNDEventDispatcher::fireDragGestureEvent( Window *pWindow,
538 const Reference< XDragSource >& xSource, const Any event,
539 const Point& rOrigin, const sal_Int8 nDragAction
541 throw(::com::sun::star::uno::RuntimeException)
543 sal_Int32 n = 0;
545 if( pWindow && pWindow->IsInputEnabled() && ! pWindow->IsInModalMode() )
547 OClearableGuard aGuard( Application::GetSolarMutex() );
549 // query DropTarget from window
550 Reference< XDragGestureRecognizer > xDragGestureRecognizer = pWindow->GetDragGestureRecognizer();
552 if( xDragGestureRecognizer.is() )
554 // retrieve relative mouse position
555 Point relLoc = pWindow->ImplFrameToOutput( rOrigin );
556 aGuard.clear();
558 n = static_cast < DNDListenerContainer * > ( xDragGestureRecognizer.get() )->fireDragGestureEvent(
559 nDragAction, relLoc.X(), relLoc.Y(), xSource, event );
562 // release UI lock
563 pWindow->DecrementLockCount();
566 return n;