xref: /trunk/main/vcl/source/window/dndlcon.cxx (revision 3a7cf181c55416e69e525ddc0b38c22235ec1569)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_vcl.hxx"
30 
31 #include <dndlcon.hxx>
32 
33 using namespace ::cppu;
34 using namespace ::com::sun::star::uno;
35 using namespace ::com::sun::star::datatransfer;
36 using namespace ::com::sun::star::datatransfer::dnd;
37 
38 //==================================================================================================
39 //
40 //==================================================================================================
41 
42 DNDListenerContainer::DNDListenerContainer( sal_Int8 nDefaultActions )
43     : WeakComponentImplHelper4< XDragGestureRecognizer, XDropTargetDragContext, XDropTargetDropContext, XDropTarget >(GetMutex())
44 {
45     m_bActive = sal_True;
46     m_nDefaultActions = nDefaultActions;
47 }
48 
49 //==================================================================================================
50 //
51 //==================================================================================================
52 
53 DNDListenerContainer::~DNDListenerContainer()
54 {
55 }
56 
57 //==================================================================================================
58 // DNDListenerContainer::addDragGestureListener
59 //==================================================================================================
60 
61 void SAL_CALL DNDListenerContainer::addDragGestureListener( const Reference< XDragGestureListener >& dgl )
62     throw(RuntimeException)
63 {
64     rBHelper.addListener( getCppuType( ( const Reference< XDragGestureListener > * ) 0 ), dgl );
65 }
66 
67 //==================================================================================================
68 // DNDListenerContainer::removeDragGestureListener
69 //==================================================================================================
70 
71 void SAL_CALL DNDListenerContainer::removeDragGestureListener( const Reference< XDragGestureListener >& dgl )
72     throw(RuntimeException)
73 {
74     rBHelper.removeListener( getCppuType( ( const Reference< XDragGestureListener > * ) 0 ), dgl );
75 }
76 
77 //==================================================================================================
78 // DNDListenerContainer::resetRecognizer
79 //==================================================================================================
80 
81 void SAL_CALL DNDListenerContainer::resetRecognizer(  )
82     throw(RuntimeException)
83 {
84 }
85 
86 //==================================================================================================
87 // DNDListenerContainer::addDropTargetListener
88 //==================================================================================================
89 
90 void SAL_CALL DNDListenerContainer::addDropTargetListener( const Reference< XDropTargetListener >& dtl )
91     throw(RuntimeException)
92 {
93     rBHelper.addListener( getCppuType( ( const Reference< XDropTargetListener > * ) 0 ), dtl );
94 }
95 
96 //==================================================================================================
97 // DNDListenerContainer::removeDropTargetListener
98 //==================================================================================================
99 
100 void SAL_CALL DNDListenerContainer::removeDropTargetListener( const Reference< XDropTargetListener >& dtl )
101     throw(RuntimeException)
102 {
103     rBHelper.removeListener( getCppuType( ( const Reference< XDropTargetListener > * ) 0 ), dtl );
104 }
105 
106 //==================================================================================================
107 // DNDListenerContainer::isActive
108 //==================================================================================================
109 
110 sal_Bool SAL_CALL DNDListenerContainer::isActive(  )
111     throw(RuntimeException)
112 {
113     return m_bActive;
114 }
115 
116 //==================================================================================================
117 // DNDListenerContainer::setActive
118 //==================================================================================================
119 
120 void SAL_CALL DNDListenerContainer::setActive( sal_Bool active )
121     throw(RuntimeException)
122 {
123     m_bActive = active;
124 }
125 
126 //==================================================================================================
127 // DNDListenerContainer::getDefaultActions
128 //==================================================================================================
129 
130 sal_Int8 SAL_CALL DNDListenerContainer::getDefaultActions(  )
131     throw(RuntimeException)
132 {
133     return m_nDefaultActions;
134 }
135 
136 //==================================================================================================
137 // DNDListenerContainer::setDefaultActions
138 //==================================================================================================
139 
140 void SAL_CALL DNDListenerContainer::setDefaultActions( sal_Int8 actions )
141     throw(RuntimeException)
142 {
143     m_nDefaultActions = actions;
144 }
145 
146 //==================================================================================================
147 // DNDListenerContainer::fireDropEvent
148 //==================================================================================================
149 
150 sal_uInt32 DNDListenerContainer::fireDropEvent( const Reference< XDropTargetDropContext >& context,
151     sal_Int8 dropAction, sal_Int32 locationX, sal_Int32 locationY, sal_Int8 sourceActions,
152     const Reference< XTransferable >& transferable )
153 {
154     sal_uInt32 nRet = 0;
155 
156     // fire DropTargetDropEvent on all XDropTargetListeners
157     OInterfaceContainerHelper *pContainer = rBHelper.getContainer( getCppuType( ( Reference < XDropTargetListener > * ) 0) );
158 
159     if( pContainer && m_bActive )
160     {
161         OInterfaceIteratorHelper aIterator( *pContainer );
162 
163         // remember context to use in own context methods
164         m_xDropTargetDropContext = context;
165 
166         // do not construct the event before you are sure at least one listener is registered
167         DropTargetDropEvent aEvent( static_cast < XDropTarget * > (this), 0,
168             static_cast < XDropTargetDropContext * > (this), dropAction,
169             locationX, locationY, sourceActions, transferable );
170 
171         while (aIterator.hasMoreElements())
172         {
173             // FIXME: this can be simplified as soon as the Iterator has a remove method
174             Reference< XInterface > xElement( aIterator.next() );
175 
176             try
177             {
178                 // this may result in a runtime exception
179                 Reference < XDropTargetListener > xListener( xElement, UNO_QUERY );
180 
181                 if( xListener.is() )
182                 {
183                     // fire drop until the first one has accepted
184                     if( m_xDropTargetDropContext.is() )
185                         xListener->drop( aEvent );
186                     else
187                     {
188                         DropTargetEvent aDTEvent( static_cast < XDropTarget * > (this), 0 );
189                         xListener->dragExit( aDTEvent );
190                     }
191 
192                     nRet++;
193                 }
194             }
195 
196             catch( RuntimeException&)
197             {
198                 pContainer->removeInterface( xElement );
199             }
200         }
201 
202         // if context still valid, then reject drop
203         if( m_xDropTargetDropContext.is() )
204         {
205             m_xDropTargetDropContext.clear();
206 
207             try
208             {
209                 context->rejectDrop();
210             }
211 
212             catch( RuntimeException&)
213             {
214             }
215         }
216     }
217 
218     return nRet;
219 }
220 
221 //==================================================================================================
222 // DNDListenerContainer::fireDragExitEvent
223 //==================================================================================================
224 
225 sal_uInt32 DNDListenerContainer::fireDragExitEvent()
226 {
227     sal_uInt32 nRet = 0;
228 
229     // fire DropTargetDropEvent on all XDropTargetListeners
230     OInterfaceContainerHelper *pContainer = rBHelper.getContainer( getCppuType( ( Reference < XDropTargetListener > * ) 0) );
231 
232     if( pContainer && m_bActive )
233     {
234         OInterfaceIteratorHelper aIterator( *pContainer );
235 
236         // do not construct the event before you are sure at least one listener is registered
237         DropTargetEvent aEvent( static_cast < XDropTarget * > (this), 0 );
238 
239         while (aIterator.hasMoreElements())
240         {
241             // FIXME: this can be simplified as soon as the Iterator has a remove method
242             Reference< XInterface > xElement( aIterator.next() );
243 
244             try
245             {
246                 // this may result in a runtime exception
247                 Reference < XDropTargetListener > xListener( xElement, UNO_QUERY );
248 
249                 if( xListener.is() )
250                 {
251                     xListener->dragExit( aEvent );
252                     nRet++;
253                 }
254             }
255 
256             catch( RuntimeException&)
257             {
258                 pContainer->removeInterface( xElement );
259             }
260         }
261     }
262 
263     return nRet;
264 }
265 
266 //==================================================================================================
267 // DNDListenerContainer::fireDragOverEvent
268 //==================================================================================================
269 
270 sal_uInt32 DNDListenerContainer::fireDragOverEvent( const Reference< XDropTargetDragContext >& context,
271     sal_Int8 dropAction, sal_Int32 locationX, sal_Int32 locationY, sal_Int8 sourceActions )
272 {
273     sal_uInt32 nRet = 0;
274 
275     // fire DropTargetDropEvent on all XDropTargetListeners
276     OInterfaceContainerHelper *pContainer = rBHelper.getContainer( getCppuType( ( Reference < XDropTargetListener > * ) 0) );
277 
278     if( pContainer && m_bActive )
279     {
280         OInterfaceIteratorHelper aIterator( *pContainer );
281 
282         // remember context to use in own context methods
283         m_xDropTargetDragContext = context;
284 
285         // do not construct the event before you are sure at least one listener is registered
286         DropTargetDragEvent aEvent( static_cast < XDropTarget * > (this), 0,
287             static_cast < XDropTargetDragContext * > (this),
288             dropAction, locationX, locationY, sourceActions );
289 
290         while (aIterator.hasMoreElements())
291         {
292             // FIXME: this can be simplified as soon as the Iterator has a remove method
293             Reference< XInterface > xElement( aIterator.next() );
294 
295             try
296             {
297                 // this may result in a runtime exception
298                 Reference < XDropTargetListener > xListener( xElement, UNO_QUERY );
299 
300                 if( xListener.is() )
301                 {
302                     if( m_xDropTargetDragContext.is() )
303                         xListener->dragOver( aEvent );
304                     nRet++;
305                 }
306             }
307 
308             catch( RuntimeException&)
309             {
310                 pContainer->removeInterface( xElement );
311             }
312         }
313 
314         // if context still valid, then reject drag
315         if( m_xDropTargetDragContext.is() )
316         {
317             m_xDropTargetDragContext.clear();
318 
319             try
320             {
321                 context->rejectDrag();
322             }
323 
324             catch( RuntimeException&)
325             {
326             }
327         }
328     }
329 
330     return nRet;
331 }
332 
333 //==================================================================================================
334 // DNDListenerContainer::fireDragEnterEvent
335 //==================================================================================================
336 
337 sal_uInt32 DNDListenerContainer::fireDragEnterEvent( const Reference< XDropTargetDragContext >& context,
338     sal_Int8 dropAction, sal_Int32 locationX, sal_Int32 locationY, sal_Int8 sourceActions,
339     const Sequence< DataFlavor >& dataFlavors )
340 {
341     sal_uInt32 nRet = 0;
342 
343     // fire DropTargetDropEvent on all XDropTargetListeners
344     OInterfaceContainerHelper *pContainer = rBHelper.getContainer( getCppuType( ( Reference < XDropTargetListener > * ) 0) );
345 
346     if( pContainer && m_bActive )
347     {
348         OInterfaceIteratorHelper aIterator( *pContainer );
349 
350         // remember context to use in own context methods
351         m_xDropTargetDragContext = context;
352 
353         // do not construct the event before you are sure at least one listener is registered
354         DropTargetDragEnterEvent aEvent( static_cast < XDropTarget * > (this), 0,
355             static_cast < XDropTargetDragContext * > (this),
356             dropAction, locationX, locationY, sourceActions, dataFlavors );
357 
358         while (aIterator.hasMoreElements())
359         {
360             // FIXME: this can be simplified as soon as the Iterator has a remove method
361             Reference< XInterface > xElement( aIterator.next() );
362 
363             try
364             {
365                 // this may result in a runtime exception
366                 Reference < XDropTargetListener > xListener( xElement, UNO_QUERY );
367 
368                 if( xListener.is() )
369                 {
370                     if( m_xDropTargetDragContext.is() )
371                         xListener->dragEnter( aEvent );
372                     nRet++;
373                 }
374             }
375 
376             catch( RuntimeException&)
377             {
378                 pContainer->removeInterface( xElement );
379             }
380         }
381 
382         // if context still valid, then reject drag
383         if( m_xDropTargetDragContext.is() )
384         {
385             m_xDropTargetDragContext.clear();
386 
387             try
388             {
389                 context->rejectDrag();
390             }
391 
392             catch( RuntimeException&)
393             {
394             }
395         }
396     }
397 
398     return nRet;
399 }
400 
401 //==================================================================================================
402 // DNDListenerContainer::fireDropActionChangedEvent
403 //==================================================================================================
404 
405 sal_uInt32 DNDListenerContainer::fireDropActionChangedEvent( const Reference< XDropTargetDragContext >& context,
406     sal_Int8 dropAction, sal_Int32 locationX, sal_Int32 locationY, sal_Int8 sourceActions )
407 {
408     sal_uInt32 nRet = 0;
409 
410     // fire DropTargetDropEvent on all XDropTargetListeners
411     OInterfaceContainerHelper *pContainer = rBHelper.getContainer( getCppuType( ( Reference < XDropTargetListener > * ) 0) );
412 
413     if( pContainer && m_bActive )
414     {
415         OInterfaceIteratorHelper aIterator( *pContainer );
416 
417         // remember context to use in own context methods
418         m_xDropTargetDragContext = context;
419 
420         // do not construct the event before you are sure at least one listener is registered
421         DropTargetDragEvent aEvent( static_cast < XDropTarget * > (this), 0,
422             static_cast < XDropTargetDragContext * > (this),
423             dropAction, locationX, locationY, sourceActions );
424 
425         while (aIterator.hasMoreElements())
426         {
427             // FIXME: this can be simplified as soon as the Iterator has a remove method
428             Reference< XInterface > xElement( aIterator.next() );
429 
430             try
431             {
432                 // this may result in a runtime exception
433                 Reference < XDropTargetListener > xListener( xElement, UNO_QUERY );
434 
435                 if( xListener.is() )
436                 {
437                     if( m_xDropTargetDragContext.is() )
438                         xListener->dropActionChanged( aEvent );
439                     nRet++;
440                 }
441             }
442 
443             catch( RuntimeException&)
444             {
445                 pContainer->removeInterface( xElement );
446             }
447         }
448 
449         // if context still valid, then reject drag
450         if( m_xDropTargetDragContext.is() )
451         {
452             m_xDropTargetDragContext.clear();
453 
454             try
455             {
456                 context->rejectDrag();
457             }
458 
459             catch( RuntimeException&)
460             {
461             }
462         }
463     }
464 
465     return nRet;
466 }
467 
468 //==================================================================================================
469 // DNDListenerContainer::fireDragGestureEvent
470 //==================================================================================================
471 
472 sal_uInt32 DNDListenerContainer::fireDragGestureEvent( sal_Int8 dragAction, sal_Int32 dragOriginX,
473     sal_Int32 dragOriginY, const Reference< XDragSource >& dragSource, const Any& triggerEvent )
474 {
475     sal_uInt32 nRet = 0;
476 
477     // fire DropTargetDropEvent on all XDropTargetListeners
478     OInterfaceContainerHelper *pContainer = rBHelper.getContainer( getCppuType( ( Reference < XDragGestureListener > * ) 0) );
479 
480     if( pContainer )
481     {
482         OInterfaceIteratorHelper aIterator( *pContainer );
483 
484         // do not construct the event before you are sure at least one listener is registered
485         DragGestureEvent aEvent( static_cast < XDragGestureRecognizer * > (this), dragAction,
486             dragOriginX, dragOriginY, dragSource, triggerEvent );
487 
488         while( aIterator.hasMoreElements() )
489         {
490             // FIXME: this can be simplified as soon as the Iterator has a remove method
491             Reference< XInterface > xElement( aIterator.next() );
492 
493             try
494             {
495                 // this may result in a runtime exception
496                 Reference < XDragGestureListener > xListener( xElement, UNO_QUERY );
497 
498                 if( xListener.is() )
499                 {
500                     xListener->dragGestureRecognized( aEvent );
501                     nRet++;
502                 }
503             }
504 
505             catch( RuntimeException&)
506             {
507                 pContainer->removeInterface( xElement );
508             }
509         }
510     }
511 
512     return nRet;
513 }
514 
515 //==================================================================================================
516 // DNDListenerContainer::acceptDrag
517 //==================================================================================================
518 
519 void SAL_CALL DNDListenerContainer::acceptDrag( sal_Int8 dragOperation ) throw (RuntimeException)
520 {
521     if( m_xDropTargetDragContext.is() )
522     {
523         m_xDropTargetDragContext->acceptDrag( dragOperation );
524         m_xDropTargetDragContext.clear();
525     }
526 }
527 
528 //==================================================================================================
529 // DNDListenerContainer::rejectDrag
530 //==================================================================================================
531 
532 void SAL_CALL DNDListenerContainer::rejectDrag(  ) throw (RuntimeException)
533 {
534     // nothing to do here
535 }
536 
537 //==================================================================================================
538 // DNDListenerContainer::acceptDrop
539 //==================================================================================================
540 
541 void SAL_CALL DNDListenerContainer::acceptDrop( sal_Int8 dropOperation ) throw (RuntimeException)
542 {
543     if( m_xDropTargetDropContext.is() )
544         m_xDropTargetDropContext->acceptDrop( dropOperation );
545 }
546 
547 //==================================================================================================
548 // DNDListenerContainer::rejectDrop
549 //==================================================================================================
550 
551 void SAL_CALL DNDListenerContainer::rejectDrop(  ) throw (RuntimeException)
552 {
553     // nothing to do here
554 }
555 
556 //==================================================================================================
557 // DNDListenerContainer::dropComplete
558 //==================================================================================================
559 
560 void SAL_CALL DNDListenerContainer::dropComplete( sal_Bool success ) throw (RuntimeException)
561 {
562     if( m_xDropTargetDropContext.is() )
563     {
564         m_xDropTargetDropContext->dropComplete( success );
565         m_xDropTargetDropContext.clear();
566     }
567 }
568