xref: /aoo42x/main/vcl/source/window/dndlcon.cxx (revision cdf0e10c)
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 exc )
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 exc )
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 exc )
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 exc )
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 exc )
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 exc )
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 exc )
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 exc )
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 exc )
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 exc )
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