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 //	my own include
29 //____________________________________________________________________________________________________________
30 
31 #include "multiplexer.hxx"
32 
33 //____________________________________________________________________________________________________________
34 //	includes of other projects
35 //____________________________________________________________________________________________________________
36 #include <vos/diagnose.hxx>
37 
38 //____________________________________________________________________________________________________________
39 //	includes of my own project
40 //____________________________________________________________________________________________________________
41 
42 //____________________________________________________________________________________________________________
43 //	namespaces
44 //____________________________________________________________________________________________________________
45 
46 using namespace	::cppu					;
47 using namespace	::osl					;
48 using namespace	::com::sun::star::uno	;
49 using namespace	::com::sun::star::awt	;
50 using namespace	::com::sun::star::lang	;
51 
52 namespace unocontrols{
53 
54 //____________________________________________________________________________________________________________
55 //	macros
56 //____________________________________________________________________________________________________________
57 
58 #define MULTIPLEX( INTERFACE, METHOD, EVENTTYP, EVENT )																				\
59 																																	\
60 	/* First get all interfaces from container with right type.*/																	\
61 	OInterfaceContainerHelper* pContainer = m_aListenerHolder.getContainer( ::getCppuType((const Reference< INTERFACE >*)0) );	\
62 	/* Do the follow only, if elements in container exist.*/																		\
63 	if( pContainer != NULL )																										\
64 	{																																\
65 		OInterfaceIteratorHelper aIterator( *pContainer );																			\
66 		EVENTTYP aLocalEvent = EVENT;																								\
67 		/* Remark: The control is the event source not the peer.*/																	\
68 		/*         We must change the source of the event.		*/																	\
69 		aLocalEvent.Source = m_xControl ;																							\
70 		/* Is the control not destroyed? */																							\
71 		if( aLocalEvent.Source.is() == sal_True )																					\
72 		{																															\
73 			if( aIterator.hasMoreElements() )																						\
74 			{																														\
75 				INTERFACE * pListener = (INTERFACE *)aIterator.next();															\
76 				try																													\
77 				{																													\
78 					pListener->METHOD( aLocalEvent );																				\
79 				}																													\
80 				catch( RuntimeException& )																							\
81 				{																													\
82 					/* Ignore all system exceptions from the listener! */															\
83 				}																													\
84 			}																														\
85 		}																															\
86 	}
87 
88 //____________________________________________________________________________________________________________
89 //	construct/destruct
90 //____________________________________________________________________________________________________________
91 
92 OMRCListenerMultiplexerHelper::OMRCListenerMultiplexerHelper(	const	Reference< XWindow >&	xControl	,
93 																const	Reference< XWindow >&	xPeer		)
94 	: m_xPeer			( xPeer		)
95 	, m_xControl		( xControl	)
96 	, m_aListenerHolder	( m_aMutex	)
97 {
98 }
99 
100 OMRCListenerMultiplexerHelper::OMRCListenerMultiplexerHelper( const OMRCListenerMultiplexerHelper& /*aCopyInstance*/ )
101 	: XFocusListener()
102     , XWindowListener()
103     , XKeyListener()
104     , XMouseListener()
105     , XMouseMotionListener()
106     , XPaintListener()
107     , XTopWindowListener()
108     , OWeakObject()
109     , m_aListenerHolder	( m_aMutex	)
110 {
111 }
112 
113 OMRCListenerMultiplexerHelper::~OMRCListenerMultiplexerHelper()
114 {
115 }
116 
117 //____________________________________________________________________________________________________________
118 //	XInterface
119 //____________________________________________________________________________________________________________
120 
121 Any SAL_CALL OMRCListenerMultiplexerHelper::queryInterface( const Type& rType ) throw( RuntimeException )
122 {
123 	// Attention:
124 	//	Don't use mutex or guard in this method!!! Is a method of XInterface.
125 
126 	// Ask for my own supported interfaces ...
127 	// Attention: XTypeProvider and XInterface are supported by OComponentHelper!
128 	Any aReturn	( ::cppu::queryInterface(	rType											,
129 											static_cast< XWindowListener*		> ( this )	,
130 											static_cast< XKeyListener*			> ( this )	,
131 											static_cast< XFocusListener*		> ( this )	,
132 											static_cast< XMouseListener*		> ( this )	,
133 											static_cast< XMouseMotionListener*	> ( this )	,
134 											static_cast< XPaintListener*		> ( this )	,
135 											static_cast< XTopWindowListener*	> ( this )	,
136 											static_cast< XTopWindowListener*	> ( this )
137 										)
138 				);
139 
140 	// If searched interface supported by this class ...
141 	if ( aReturn.hasValue() == sal_True )
142 	{
143 		// ... return this information.
144 		return aReturn ;
145 	}
146 	else
147 	{
148 		// Else; ... ask baseclass for interfaces!
149 		return OWeakObject::queryInterface( rType );
150 	}
151 }
152 
153 //____________________________________________________________________________________________________________
154 //	XInterface
155 //____________________________________________________________________________________________________________
156 
157 void SAL_CALL OMRCListenerMultiplexerHelper::acquire() throw()
158 {
159 	// Attention:
160 	//	Don't use mutex or guard in this method!!! Is a method of XInterface.
161 
162 	// Forward to baseclass
163 	OWeakObject::acquire();
164 }
165 
166 //____________________________________________________________________________________________________________
167 //	XInterface
168 //____________________________________________________________________________________________________________
169 
170 void SAL_CALL OMRCListenerMultiplexerHelper::release() throw()
171 {
172 	// Attention:
173 	//	Don't use mutex or guard in this method!!! Is a method of XInterface.
174 
175 	// Forward to baseclass
176 	OWeakObject::release();
177 }
178 
179 //____________________________________________________________________________________________________________
180 //	operator
181 //____________________________________________________________________________________________________________
182 
183 OMRCListenerMultiplexerHelper::operator Reference< XInterface >() const
184 {
185 	return ((OWeakObject*)this) ;
186 }
187 
188 //____________________________________________________________________________________________________________
189 //	operator
190 //____________________________________________________________________________________________________________
191 
192 //OMRCListenerMultiplexerHelper& OMRCListenerMultiplexerHelper::operator= ( const OMRCListenerMultiplexerHelper& aCopyInstance )
193 //{
194 //	return this ;
195 //}
196 
197 //____________________________________________________________________________________________________________
198 //	container method
199 //____________________________________________________________________________________________________________
200 
201 void OMRCListenerMultiplexerHelper::setPeer( const Reference< XWindow >& xPeer )
202 {
203 	MutexGuard aGuard( m_aMutex );
204 	if( m_xPeer != xPeer )
205 	{
206 		if( m_xPeer.is() )
207 		{
208 			// get all types from the listener added to the peer
209 			Sequence< Type >	aContainedTypes	= m_aListenerHolder.getContainedTypes();
210 			const Type*			pArray			= aContainedTypes.getConstArray();
211 			sal_Int32			nCount			= aContainedTypes.getLength();
212 			// loop over all listener types and remove the listeners from the peer
213 			for( sal_Int32 i=0; i<nCount; i++ )
214 				impl_unadviseFromPeer( m_xPeer, pArray[i] );
215 		}
216 		m_xPeer = xPeer;
217 		if( m_xPeer.is() )
218 		{
219 			// get all types from the listener added to the peer
220 			Sequence< Type >	aContainedTypes	= m_aListenerHolder.getContainedTypes();
221 			const Type*			pArray			= aContainedTypes.getConstArray();
222 			sal_Int32			nCount			= aContainedTypes.getLength();
223 			// loop over all listener types and add the listeners to the peer
224 			for( sal_Int32 i = 0; i < nCount; i++ )
225 				impl_adviseToPeer( m_xPeer, pArray[i] );
226 		}
227 	}
228 }
229 
230 //____________________________________________________________________________________________________________
231 //	container method
232 //____________________________________________________________________________________________________________
233 
234 void OMRCListenerMultiplexerHelper::disposeAndClear()
235 {
236 	EventObject aEvent ;
237 	aEvent.Source = m_xControl ;
238 	m_aListenerHolder.disposeAndClear( aEvent );
239 }
240 
241 //____________________________________________________________________________________________________________
242 //	container method
243 //____________________________________________________________________________________________________________
244 
245 void OMRCListenerMultiplexerHelper::advise(	const	Type&						aType		,
246 											const	Reference< XInterface >&	xListener	)
247 {
248 	MutexGuard aGuard( m_aMutex );
249 	if( m_aListenerHolder.addInterface( aType, xListener ) == 1 )
250 	{
251 		// the first listener is added
252 		if( m_xPeer.is() )
253 		{
254 			impl_adviseToPeer( m_xPeer, aType );
255 		}
256 	}
257 }
258 
259 //____________________________________________________________________________________________________________
260 //	container method
261 //____________________________________________________________________________________________________________
262 
263 void OMRCListenerMultiplexerHelper::unadvise(	const	Type&						aType		,
264 												const	Reference< XInterface >&	xListener	)
265 {
266 	MutexGuard aGuard( m_aMutex );
267 	if( m_aListenerHolder.removeInterface( aType, xListener ) == 0 )
268 	{
269 		// the last listener is removed
270 		if ( m_xPeer.is() )
271 		{
272 			impl_unadviseFromPeer( m_xPeer, aType );
273 		}
274 	}
275 }
276 
277 //____________________________________________________________________________________________________________
278 //	XEventListener
279 //____________________________________________________________________________________________________________
280 
281 void SAL_CALL OMRCListenerMultiplexerHelper::disposing( const EventObject& /*aSource*/ ) throw( RuntimeException )
282 {
283 	MutexGuard aGuard( m_aMutex );
284 	// peer is disposed, clear the reference
285 	m_xPeer = Reference< XWindow >();
286 }
287 
288 //____________________________________________________________________________________________________________
289 //	XFcousListener
290 //____________________________________________________________________________________________________________
291 
292 void OMRCListenerMultiplexerHelper::focusGained(const FocusEvent& aEvent ) throw( UNO3_RUNTIMEEXCEPTION )
293 {
294 /*
295 	OInterfaceContainerHelper * pCont = aListenerHolder.getContainer( ::getCppuType((const Reference< XFocusListener >*)0) );
296 	if( pCont )
297 	{
298 		OInterfaceIteratorHelper	aIt( *pCont );
299 		FocusEvent aEvt = e;
300 		// Reamark: The control is the event source not the peer. We must change
301 		// the source of the event
302 		xControl.queryHardRef( ((XInterface*)NULL)->getSmartUik(), aEvt.Source );
303 		//.is the control not destroyed
304 		if( aEvt.Source.is() )
305 		{
306 			if( aIt.hasMoreElements() )
307 			{
308 				XFocusListener * pListener = (XFocusListener *)aIt.next();
309 				try
310 				{
311 					pListener->focusGained( aEvt );
312 				}
313 				catch( RuntimeException, e )
314 				{
315 					// ignore all usr system exceptions from the listener
316 				}
317 			}
318 		}
319 	}
320 */
321 	MULTIPLEX( XFocusListener, focusGained, FocusEvent, aEvent )
322 }
323 
324 //____________________________________________________________________________________________________________
325 //	XFcousListener
326 //____________________________________________________________________________________________________________
327 
328 void OMRCListenerMultiplexerHelper::focusLost(const FocusEvent& aEvent ) throw( UNO3_RUNTIMEEXCEPTION )
329 {
330 	MULTIPLEX( XFocusListener, focusLost, FocusEvent, aEvent )
331 }
332 
333 //____________________________________________________________________________________________________________
334 //	XWindowListener
335 //____________________________________________________________________________________________________________
336 
337 void OMRCListenerMultiplexerHelper::windowResized(const WindowEvent& aEvent ) throw( UNO3_RUNTIMEEXCEPTION )
338 {
339 	MULTIPLEX( XWindowListener, windowResized, WindowEvent, aEvent )
340 }
341 
342 //____________________________________________________________________________________________________________
343 //	XWindowListener
344 //____________________________________________________________________________________________________________
345 
346 void OMRCListenerMultiplexerHelper::windowMoved(const WindowEvent& aEvent ) throw( UNO3_RUNTIMEEXCEPTION )
347 {
348 	MULTIPLEX( XWindowListener, windowMoved, WindowEvent, aEvent )
349 }
350 
351 //____________________________________________________________________________________________________________
352 //	XWindowListener
353 //____________________________________________________________________________________________________________
354 
355 void OMRCListenerMultiplexerHelper::windowShown(const EventObject& aEvent ) throw( UNO3_RUNTIMEEXCEPTION )
356 {
357 	MULTIPLEX( XWindowListener, windowShown, EventObject, aEvent )
358 }
359 
360 //____________________________________________________________________________________________________________
361 //	XWindowListener
362 //____________________________________________________________________________________________________________
363 
364 void OMRCListenerMultiplexerHelper::windowHidden(const EventObject& aEvent ) throw( UNO3_RUNTIMEEXCEPTION )
365 {
366 	MULTIPLEX( XWindowListener, windowHidden, EventObject, aEvent )
367 }
368 
369 //____________________________________________________________________________________________________________
370 //	XKeyListener
371 //____________________________________________________________________________________________________________
372 
373 void OMRCListenerMultiplexerHelper::keyPressed(const KeyEvent& aEvent) throw( UNO3_RUNTIMEEXCEPTION )
374 {
375 	MULTIPLEX( XKeyListener, keyPressed, KeyEvent, aEvent )
376 }
377 
378 //____________________________________________________________________________________________________________
379 //	XKeyListener
380 //____________________________________________________________________________________________________________
381 
382 void OMRCListenerMultiplexerHelper::keyReleased(const KeyEvent& aEvent) throw( UNO3_RUNTIMEEXCEPTION )
383 {
384 	MULTIPLEX( XKeyListener, keyReleased, KeyEvent, aEvent )
385 }
386 
387 //____________________________________________________________________________________________________________
388 //	XMouseListener
389 //____________________________________________________________________________________________________________
390 
391 void OMRCListenerMultiplexerHelper::mousePressed(const MouseEvent& aEvent) throw( UNO3_RUNTIMEEXCEPTION )
392 {
393 	MULTIPLEX( XMouseListener, mousePressed, MouseEvent, aEvent )
394 }
395 
396 //____________________________________________________________________________________________________________
397 //	XMouseListener
398 //____________________________________________________________________________________________________________
399 
400 void OMRCListenerMultiplexerHelper::mouseReleased(const MouseEvent& aEvent) throw( UNO3_RUNTIMEEXCEPTION )
401 {
402 	MULTIPLEX( XMouseListener, mouseReleased, MouseEvent, aEvent )
403 }
404 
405 //____________________________________________________________________________________________________________
406 //	XMouseListener
407 //____________________________________________________________________________________________________________
408 
409 void OMRCListenerMultiplexerHelper::mouseEntered(const MouseEvent& aEvent) throw( UNO3_RUNTIMEEXCEPTION )
410 {
411 	MULTIPLEX( XMouseListener, mouseEntered, MouseEvent, aEvent )
412 }
413 
414 //____________________________________________________________________________________________________________
415 //	XMouseListener
416 //____________________________________________________________________________________________________________
417 
418 void OMRCListenerMultiplexerHelper::mouseExited(const MouseEvent& aEvent) throw( UNO3_RUNTIMEEXCEPTION )
419 {
420 	MULTIPLEX( XMouseListener, mouseExited, MouseEvent, aEvent )
421 }
422 
423 //____________________________________________________________________________________________________________
424 //	XMouseMotionListener
425 //____________________________________________________________________________________________________________
426 
427 void OMRCListenerMultiplexerHelper::mouseDragged(const MouseEvent& aEvent) throw( UNO3_RUNTIMEEXCEPTION )
428 {
429 	MULTIPLEX( XMouseMotionListener, mouseDragged, MouseEvent, aEvent )
430 }
431 
432 //____________________________________________________________________________________________________________
433 //	XMouseMotionListener
434 //____________________________________________________________________________________________________________
435 
436 void OMRCListenerMultiplexerHelper::mouseMoved(const MouseEvent& aEvent) throw( UNO3_RUNTIMEEXCEPTION )
437 {
438 	MULTIPLEX( XMouseMotionListener, mouseMoved, MouseEvent, aEvent )
439 }
440 
441 //____________________________________________________________________________________________________________
442 //	XPaintListener
443 //____________________________________________________________________________________________________________
444 
445 void OMRCListenerMultiplexerHelper::windowPaint(const PaintEvent& aEvent) throw( UNO3_RUNTIMEEXCEPTION )
446 {
447 	MULTIPLEX( XPaintListener, windowPaint, PaintEvent, aEvent )
448 }
449 
450 //____________________________________________________________________________________________________________
451 //	XTopWindowListener
452 //____________________________________________________________________________________________________________
453 
454 void OMRCListenerMultiplexerHelper::windowOpened(const EventObject& aEvent) throw( UNO3_RUNTIMEEXCEPTION )
455 {
456 	MULTIPLEX( XTopWindowListener, windowOpened, EventObject, aEvent )
457 }
458 
459 //____________________________________________________________________________________________________________
460 //	XTopWindowListener
461 //____________________________________________________________________________________________________________
462 
463 void OMRCListenerMultiplexerHelper::windowClosing( const EventObject& aEvent ) throw( UNO3_RUNTIMEEXCEPTION )
464 {
465 	MULTIPLEX( XTopWindowListener, windowClosing, EventObject, aEvent )
466 }
467 
468 //____________________________________________________________________________________________________________
469 //	XTopWindowListener
470 //____________________________________________________________________________________________________________
471 
472 void OMRCListenerMultiplexerHelper::windowClosed( const EventObject& aEvent ) throw( UNO3_RUNTIMEEXCEPTION )
473 {
474 	MULTIPLEX( XTopWindowListener, windowClosed, EventObject, aEvent )
475 }
476 
477 //____________________________________________________________________________________________________________
478 //	XTopWindowListener
479 //____________________________________________________________________________________________________________
480 
481 void OMRCListenerMultiplexerHelper::windowMinimized( const EventObject& aEvent ) throw( UNO3_RUNTIMEEXCEPTION )
482 {
483 	MULTIPLEX( XTopWindowListener, windowMinimized, EventObject, aEvent )
484 }
485 
486 //____________________________________________________________________________________________________________
487 //	XTopWindowListener
488 //____________________________________________________________________________________________________________
489 
490 void OMRCListenerMultiplexerHelper::windowNormalized( const EventObject& aEvent ) throw( UNO3_RUNTIMEEXCEPTION )
491 {
492 	MULTIPLEX( XTopWindowListener, windowNormalized, EventObject, aEvent )
493 }
494 
495 //____________________________________________________________________________________________________________
496 //	XTopWindowListener
497 //____________________________________________________________________________________________________________
498 
499 void OMRCListenerMultiplexerHelper::windowActivated( const EventObject& aEvent ) throw( UNO3_RUNTIMEEXCEPTION )
500 {
501 	MULTIPLEX( XTopWindowListener, windowActivated, EventObject, aEvent )
502 }
503 
504 //____________________________________________________________________________________________________________
505 //	XTopWindowListener
506 //____________________________________________________________________________________________________________
507 
508 void OMRCListenerMultiplexerHelper::windowDeactivated( const EventObject& aEvent ) throw( UNO3_RUNTIMEEXCEPTION )
509 {
510 	MULTIPLEX( XTopWindowListener, windowDeactivated, EventObject, aEvent )
511 }
512 
513 //____________________________________________________________________________________________________________
514 //	protected method
515 //____________________________________________________________________________________________________________
516 
517 void OMRCListenerMultiplexerHelper::impl_adviseToPeer(	const	Reference< XWindow >&	xPeer	,
518 														const	Type&					aType	)
519 {
520 	// add a listener to the source (peer)
521 	if( aType == ::getCppuType((const Reference< XWindowListener >*)0) )
522 		xPeer->addWindowListener( this );
523 	else if( aType == ::getCppuType((const Reference< XKeyListener >*)0) )
524 		xPeer->addKeyListener( this );
525 	else if( aType == ::getCppuType((const Reference< XFocusListener >*)0) )
526 		xPeer->addFocusListener( this );
527 	else if( aType == ::getCppuType((const Reference< XMouseListener >*)0) )
528 		xPeer->addMouseListener( this );
529 	else if( aType == ::getCppuType((const Reference< XMouseMotionListener >*)0) )
530 		xPeer->addMouseMotionListener( this );
531 	else if( aType == ::getCppuType((const Reference< XPaintListener >*)0) )
532 		xPeer->addPaintListener( this );
533 	else if( aType == ::getCppuType((const Reference< XTopWindowListener >*)0) )
534 	{
535 		Reference< XTopWindow > xTop( xPeer, UNO_QUERY );
536 		if( xTop.is() )
537 			xTop->addTopWindowListener( this );
538 	}
539 	else
540 	{
541 		VOS_ENSHURE( sal_False, "unknown listener" );
542 	}
543 }
544 
545 //____________________________________________________________________________________________________________
546 //	protected method
547 //____________________________________________________________________________________________________________
548 
549 void OMRCListenerMultiplexerHelper::impl_unadviseFromPeer(	const	Reference< XWindow >&	xPeer	,
550 															const	Type&					aType	)
551 {
552 	// the last listener is removed, remove the listener from the source (peer)
553 	if( aType == ::getCppuType((const Reference< XWindowListener >*)0) )
554 		xPeer->removeWindowListener( this );
555 	else if( aType == ::getCppuType((const Reference< XKeyListener >*)0) )
556 		xPeer->removeKeyListener( this );
557 	else if( aType == ::getCppuType((const Reference< XFocusListener >*)0) )
558 		xPeer->removeFocusListener( this );
559 	else if( aType == ::getCppuType((const Reference< XMouseListener >*)0) )
560 		xPeer->removeMouseListener( this );
561 	else if( aType == ::getCppuType((const Reference< XMouseMotionListener >*)0) )
562 		xPeer->removeMouseMotionListener( this );
563 	else if( aType == ::getCppuType((const Reference< XPaintListener >*)0) )
564 		xPeer->removePaintListener( this );
565 	else if( aType == ::getCppuType((const Reference< XTopWindowListener >*)0) )
566 	{
567 		Reference< XTopWindow >  xTop( xPeer, UNO_QUERY );
568 		if( xTop.is() )
569 			xTop->removeTopWindowListener( this );
570 	}
571 	else
572 	{
573 		VOS_ENSHURE( sal_False, "unknown listener" );
574 	}
575 }
576 
577 } // namespace unocontrols
578