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