1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "multiplexer.hxx"
22 #include <osl/diagnose.h>
23 #include <cppuhelper/queryinterface.hxx>
25 using namespace ::cppu
;
26 using namespace ::osl
;
27 using namespace ::com::sun::star::uno
;
28 using namespace ::com::sun::star::awt
;
29 using namespace ::com::sun::star::lang
;
31 namespace unocontrols
{
35 #define MULTIPLEX( INTERFACE, METHOD, EVENTTYP, EVENT ) \
37 /* First get all interfaces from container with right type.*/ \
38 OInterfaceContainerHelper* pContainer = m_aListenerHolder.getContainer( cppu::UnoType<INTERFACE>::get() ); \
39 /* Do the follow only, if elements in container exist.*/ \
40 if( pContainer != NULL ) \
42 OInterfaceIteratorHelper aIterator( *pContainer ); \
43 EVENTTYP aLocalEvent = EVENT; \
44 /* Remark: The control is the event source not the peer.*/ \
45 /* We must change the source of the event. */ \
46 aLocalEvent.Source = m_xControl; \
47 /* Is the control not destroyed? */ \
48 if( aLocalEvent.Source.is() ) \
50 if( aIterator.hasMoreElements() ) \
52 INTERFACE * pListener = static_cast<INTERFACE *>(aIterator.next()); \
55 pListener->METHOD( aLocalEvent ); \
57 catch(const RuntimeException& ) \
59 /* Ignore all system exceptions from the listener! */ \
67 OMRCListenerMultiplexerHelper::OMRCListenerMultiplexerHelper( const Reference
< XWindow
>& xControl
,
68 const Reference
< XWindow
>& xPeer
)
70 , m_xControl ( xControl
)
71 , m_aListenerHolder ( m_aMutex
)
75 OMRCListenerMultiplexerHelper::OMRCListenerMultiplexerHelper( const OMRCListenerMultiplexerHelper
& /*aCopyInstance*/ )
80 , XMouseMotionListener()
82 , XTopWindowListener()
84 , m_aListenerHolder ( m_aMutex
)
88 OMRCListenerMultiplexerHelper::~OMRCListenerMultiplexerHelper()
94 Any SAL_CALL
OMRCListenerMultiplexerHelper::queryInterface( const Type
& rType
) throw( RuntimeException
, std::exception
)
97 // Don't use mutex or guard in this method!!! Is a method of XInterface.
99 // Ask for my own supported interfaces ...
100 // Attention: XTypeProvider and XInterface are supported by OComponentHelper!
101 Any
aReturn ( ::cppu::queryInterface( rType
,
102 static_cast< XWindowListener
* > ( this ) ,
103 static_cast< XKeyListener
* > ( this ) ,
104 static_cast< XFocusListener
* > ( this ) ,
105 static_cast< XMouseListener
* > ( this ) ,
106 static_cast< XMouseMotionListener
* > ( this ) ,
107 static_cast< XPaintListener
* > ( this ) ,
108 static_cast< XTopWindowListener
* > ( this ) ,
109 static_cast< XTopWindowListener
* > ( this )
113 // If searched interface supported by this class ...
114 if ( aReturn
.hasValue() )
116 // ... return this information.
121 // Else; ... ask baseclass for interfaces!
122 return OWeakObject::queryInterface( rType
);
128 void SAL_CALL
OMRCListenerMultiplexerHelper::acquire() throw()
131 // Don't use mutex or guard in this method!!! Is a method of XInterface.
133 // Forward to baseclass
134 OWeakObject::acquire();
139 void SAL_CALL
OMRCListenerMultiplexerHelper::release() throw()
142 // Don't use mutex or guard in this method!!! Is a method of XInterface.
144 // Forward to baseclass
145 OWeakObject::release();
150 void OMRCListenerMultiplexerHelper::setPeer( const Reference
< XWindow
>& xPeer
)
152 MutexGuard
aGuard( m_aMutex
);
153 if( m_xPeer
!= xPeer
)
157 // get all types from the listener added to the peer
158 Sequence
< Type
> aContainedTypes
= m_aListenerHolder
.getContainedTypes();
159 const Type
* pArray
= aContainedTypes
.getConstArray();
160 sal_Int32 nCount
= aContainedTypes
.getLength();
161 // loop over all listener types and remove the listeners from the peer
162 for( sal_Int32 i
=0; i
<nCount
; i
++ )
163 impl_unadviseFromPeer( m_xPeer
, pArray
[i
] );
168 // get all types from the listener added to the peer
169 Sequence
< Type
> aContainedTypes
= m_aListenerHolder
.getContainedTypes();
170 const Type
* pArray
= aContainedTypes
.getConstArray();
171 sal_Int32 nCount
= aContainedTypes
.getLength();
172 // loop over all listener types and add the listeners to the peer
173 for( sal_Int32 i
= 0; i
< nCount
; i
++ )
174 impl_adviseToPeer( m_xPeer
, pArray
[i
] );
181 void OMRCListenerMultiplexerHelper::disposeAndClear()
184 aEvent
.Source
= m_xControl
;
185 m_aListenerHolder
.disposeAndClear( aEvent
);
190 void OMRCListenerMultiplexerHelper::advise( const Type
& aType
,
191 const Reference
< XInterface
>& xListener
)
193 MutexGuard
aGuard( m_aMutex
);
194 if( m_aListenerHolder
.addInterface( aType
, xListener
) == 1 )
196 // the first listener is added
199 impl_adviseToPeer( m_xPeer
, aType
);
206 void OMRCListenerMultiplexerHelper::unadvise( const Type
& aType
,
207 const Reference
< XInterface
>& xListener
)
209 MutexGuard
aGuard( m_aMutex
);
210 if( m_aListenerHolder
.removeInterface( aType
, xListener
) == 0 )
212 // the last listener is removed
215 impl_unadviseFromPeer( m_xPeer
, aType
);
222 void SAL_CALL
OMRCListenerMultiplexerHelper::disposing( const EventObject
& /*aSource*/ ) throw( RuntimeException
, std::exception
)
224 MutexGuard
aGuard( m_aMutex
);
225 // peer is disposed, clear the reference
231 void OMRCListenerMultiplexerHelper::focusGained(const FocusEvent
& aEvent
) throw( RuntimeException
, std::exception
)
233 MULTIPLEX( XFocusListener
, focusGained
, FocusEvent
, aEvent
)
238 void OMRCListenerMultiplexerHelper::focusLost(const FocusEvent
& aEvent
) throw( RuntimeException
, std::exception
)
240 MULTIPLEX( XFocusListener
, focusLost
, FocusEvent
, aEvent
)
245 void OMRCListenerMultiplexerHelper::windowResized(const WindowEvent
& aEvent
) throw( RuntimeException
, std::exception
)
247 MULTIPLEX( XWindowListener
, windowResized
, WindowEvent
, aEvent
)
252 void OMRCListenerMultiplexerHelper::windowMoved(const WindowEvent
& aEvent
) throw( RuntimeException
, std::exception
)
254 MULTIPLEX( XWindowListener
, windowMoved
, WindowEvent
, aEvent
)
259 void OMRCListenerMultiplexerHelper::windowShown(const EventObject
& aEvent
) throw( RuntimeException
, std::exception
)
261 MULTIPLEX( XWindowListener
, windowShown
, EventObject
, aEvent
)
266 void OMRCListenerMultiplexerHelper::windowHidden(const EventObject
& aEvent
) throw( RuntimeException
, std::exception
)
268 MULTIPLEX( XWindowListener
, windowHidden
, EventObject
, aEvent
)
273 void OMRCListenerMultiplexerHelper::keyPressed(const KeyEvent
& aEvent
) throw( RuntimeException
, std::exception
)
275 MULTIPLEX( XKeyListener
, keyPressed
, KeyEvent
, aEvent
)
280 void OMRCListenerMultiplexerHelper::keyReleased(const KeyEvent
& aEvent
) throw( RuntimeException
, std::exception
)
282 MULTIPLEX( XKeyListener
, keyReleased
, KeyEvent
, aEvent
)
287 void OMRCListenerMultiplexerHelper::mousePressed(const MouseEvent
& aEvent
) throw( RuntimeException
, std::exception
)
289 MULTIPLEX( XMouseListener
, mousePressed
, MouseEvent
, aEvent
)
294 void OMRCListenerMultiplexerHelper::mouseReleased(const MouseEvent
& aEvent
) throw( RuntimeException
, std::exception
)
296 MULTIPLEX( XMouseListener
, mouseReleased
, MouseEvent
, aEvent
)
301 void OMRCListenerMultiplexerHelper::mouseEntered(const MouseEvent
& aEvent
) throw( RuntimeException
, std::exception
)
303 MULTIPLEX( XMouseListener
, mouseEntered
, MouseEvent
, aEvent
)
308 void OMRCListenerMultiplexerHelper::mouseExited(const MouseEvent
& aEvent
) throw( RuntimeException
, std::exception
)
310 MULTIPLEX( XMouseListener
, mouseExited
, MouseEvent
, aEvent
)
313 // XMouseMotionListener
315 void OMRCListenerMultiplexerHelper::mouseDragged(const MouseEvent
& aEvent
) throw( RuntimeException
, std::exception
)
317 MULTIPLEX( XMouseMotionListener
, mouseDragged
, MouseEvent
, aEvent
)
320 // XMouseMotionListener
322 void OMRCListenerMultiplexerHelper::mouseMoved(const MouseEvent
& aEvent
) throw( RuntimeException
, std::exception
)
324 MULTIPLEX( XMouseMotionListener
, mouseMoved
, MouseEvent
, aEvent
)
329 void OMRCListenerMultiplexerHelper::windowPaint(const PaintEvent
& aEvent
) throw( RuntimeException
, std::exception
)
331 MULTIPLEX( XPaintListener
, windowPaint
, PaintEvent
, aEvent
)
334 // XTopWindowListener
336 void OMRCListenerMultiplexerHelper::windowOpened(const EventObject
& aEvent
) throw( RuntimeException
, std::exception
)
338 MULTIPLEX( XTopWindowListener
, windowOpened
, EventObject
, aEvent
)
341 // XTopWindowListener
343 void OMRCListenerMultiplexerHelper::windowClosing( const EventObject
& aEvent
) throw( RuntimeException
, std::exception
)
345 MULTIPLEX( XTopWindowListener
, windowClosing
, EventObject
, aEvent
)
348 // XTopWindowListener
350 void OMRCListenerMultiplexerHelper::windowClosed( const EventObject
& aEvent
) throw( RuntimeException
, std::exception
)
352 MULTIPLEX( XTopWindowListener
, windowClosed
, EventObject
, aEvent
)
355 // XTopWindowListener
357 void OMRCListenerMultiplexerHelper::windowMinimized( const EventObject
& aEvent
) throw( RuntimeException
, std::exception
)
359 MULTIPLEX( XTopWindowListener
, windowMinimized
, EventObject
, aEvent
)
362 // XTopWindowListener
364 void OMRCListenerMultiplexerHelper::windowNormalized( const EventObject
& aEvent
) throw( RuntimeException
, std::exception
)
366 MULTIPLEX( XTopWindowListener
, windowNormalized
, EventObject
, aEvent
)
369 // XTopWindowListener
371 void OMRCListenerMultiplexerHelper::windowActivated( const EventObject
& aEvent
) throw( RuntimeException
, std::exception
)
373 MULTIPLEX( XTopWindowListener
, windowActivated
, EventObject
, aEvent
)
376 // XTopWindowListener
378 void OMRCListenerMultiplexerHelper::windowDeactivated( const EventObject
& aEvent
) throw( RuntimeException
, std::exception
)
380 MULTIPLEX( XTopWindowListener
, windowDeactivated
, EventObject
, aEvent
)
385 void OMRCListenerMultiplexerHelper::impl_adviseToPeer( const Reference
< XWindow
>& xPeer
,
388 // add a listener to the source (peer)
389 if( aType
== cppu::UnoType
<XWindowListener
>::get())
390 xPeer
->addWindowListener( this );
391 else if( aType
== cppu::UnoType
<XKeyListener
>::get())
392 xPeer
->addKeyListener( this );
393 else if( aType
== cppu::UnoType
<XFocusListener
>::get())
394 xPeer
->addFocusListener( this );
395 else if( aType
== cppu::UnoType
<XMouseListener
>::get())
396 xPeer
->addMouseListener( this );
397 else if( aType
== cppu::UnoType
<XMouseMotionListener
>::get())
398 xPeer
->addMouseMotionListener( this );
399 else if( aType
== cppu::UnoType
<XPaintListener
>::get())
400 xPeer
->addPaintListener( this );
401 else if( aType
== cppu::UnoType
<XTopWindowListener
>::get())
403 Reference
< XTopWindow
> xTop( xPeer
, UNO_QUERY
);
405 xTop
->addTopWindowListener( this );
409 OSL_FAIL( "unknown listener" );
415 void OMRCListenerMultiplexerHelper::impl_unadviseFromPeer( const Reference
< XWindow
>& xPeer
,
418 // the last listener is removed, remove the listener from the source (peer)
419 if( aType
== cppu::UnoType
<XWindowListener
>::get())
420 xPeer
->removeWindowListener( this );
421 else if( aType
== cppu::UnoType
<XKeyListener
>::get())
422 xPeer
->removeKeyListener( this );
423 else if( aType
== cppu::UnoType
<XFocusListener
>::get())
424 xPeer
->removeFocusListener( this );
425 else if( aType
== cppu::UnoType
<XMouseListener
>::get())
426 xPeer
->removeMouseListener( this );
427 else if( aType
== cppu::UnoType
<XMouseMotionListener
>::get())
428 xPeer
->removeMouseMotionListener( this );
429 else if( aType
== cppu::UnoType
<XPaintListener
>::get())
430 xPeer
->removePaintListener( this );
431 else if( aType
== cppu::UnoType
<XTopWindowListener
>::get())
433 Reference
< XTopWindow
> xTop( xPeer
, UNO_QUERY
);
435 xTop
->removeTopWindowListener( this );
439 OSL_FAIL( "unknown listener" );
443 } // namespace unocontrols
445 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */