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