xref: /trunk/main/UnoControls/source/base/multiplexer.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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