Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include "multiplexer.hxx"
21 :
22 : #include <osl/diagnose.h>
23 :
24 : using namespace ::cppu;
25 : using namespace ::osl;
26 : using namespace ::com::sun::star::uno;
27 : using namespace ::com::sun::star::awt;
28 : using namespace ::com::sun::star::lang;
29 :
30 : namespace unocontrols{
31 :
32 : // macros
33 :
34 : #define MULTIPLEX( INTERFACE, METHOD, EVENTTYP, EVENT ) \
35 : \
36 : /* First get all interfaces from container with right type.*/ \
37 : OInterfaceContainerHelper* pContainer = m_aListenerHolder.getContainer( ::getCppuType((const Reference< INTERFACE >*)0) ); \
38 : /* Do the follow only, if elements in container exist.*/ \
39 : if( pContainer != NULL ) \
40 : { \
41 : OInterfaceIteratorHelper aIterator( *pContainer ); \
42 : EVENTTYP aLocalEvent = EVENT; \
43 : /* Remark: The control is the event source not the peer.*/ \
44 : /* We must change the source of the event. */ \
45 : aLocalEvent.Source = m_xControl; \
46 : /* Is the control not destroyed? */ \
47 : if( aLocalEvent.Source.is() ) \
48 : { \
49 : if( aIterator.hasMoreElements() ) \
50 : { \
51 : INTERFACE * pListener = (INTERFACE *)aIterator.next(); \
52 : try \
53 : { \
54 : pListener->METHOD( aLocalEvent ); \
55 : } \
56 : catch(const RuntimeException& ) \
57 : { \
58 : /* Ignore all system exceptions from the listener! */ \
59 : } \
60 : } \
61 : } \
62 : }
63 :
64 : // construct/destruct
65 :
66 0 : OMRCListenerMultiplexerHelper::OMRCListenerMultiplexerHelper( const Reference< XWindow >& xControl ,
67 : const Reference< XWindow >& xPeer )
68 : : m_xPeer ( xPeer )
69 : , m_xControl ( xControl )
70 0 : , m_aListenerHolder ( m_aMutex )
71 : {
72 0 : }
73 :
74 0 : OMRCListenerMultiplexerHelper::OMRCListenerMultiplexerHelper( const OMRCListenerMultiplexerHelper& /*aCopyInstance*/ )
75 : : XFocusListener()
76 : , XWindowListener()
77 : , XKeyListener()
78 : , XMouseListener()
79 : , XMouseMotionListener()
80 : , XPaintListener()
81 : , XTopWindowListener()
82 : , OWeakObject()
83 0 : , m_aListenerHolder ( m_aMutex )
84 : {
85 0 : }
86 :
87 0 : OMRCListenerMultiplexerHelper::~OMRCListenerMultiplexerHelper()
88 : {
89 0 : }
90 :
91 : // XInterface
92 :
93 0 : Any SAL_CALL OMRCListenerMultiplexerHelper::queryInterface( const Type& rType ) throw( RuntimeException, std::exception )
94 : {
95 : // Attention:
96 : // Don't use mutex or guard in this method!!! Is a method of XInterface.
97 :
98 : // Ask for my own supported interfaces ...
99 : // Attention: XTypeProvider and XInterface are supported by OComponentHelper!
100 : Any aReturn ( ::cppu::queryInterface( rType ,
101 : static_cast< XWindowListener* > ( this ) ,
102 : static_cast< XKeyListener* > ( this ) ,
103 : static_cast< XFocusListener* > ( this ) ,
104 : static_cast< XMouseListener* > ( this ) ,
105 : static_cast< XMouseMotionListener* > ( this ) ,
106 : static_cast< XPaintListener* > ( this ) ,
107 : static_cast< XTopWindowListener* > ( this ) ,
108 : static_cast< XTopWindowListener* > ( this )
109 : )
110 0 : );
111 :
112 : // If searched interface supported by this class ...
113 0 : if ( aReturn.hasValue() )
114 : {
115 : // ... return this information.
116 0 : return aReturn;
117 : }
118 : else
119 : {
120 : // Else; ... ask baseclass for interfaces!
121 0 : return OWeakObject::queryInterface( rType );
122 0 : }
123 : }
124 :
125 : // XInterface
126 :
127 0 : void SAL_CALL OMRCListenerMultiplexerHelper::acquire() throw()
128 : {
129 : // Attention:
130 : // Don't use mutex or guard in this method!!! Is a method of XInterface.
131 :
132 : // Forward to baseclass
133 0 : OWeakObject::acquire();
134 0 : }
135 :
136 : // XInterface
137 :
138 0 : void SAL_CALL OMRCListenerMultiplexerHelper::release() throw()
139 : {
140 : // Attention:
141 : // Don't use mutex or guard in this method!!! Is a method of XInterface.
142 :
143 : // Forward to baseclass
144 0 : OWeakObject::release();
145 0 : }
146 :
147 : // operator
148 :
149 0 : OMRCListenerMultiplexerHelper::operator Reference< XInterface >() const
150 : {
151 0 : return ((OWeakObject*)this);
152 : }
153 :
154 : // container method
155 :
156 0 : void OMRCListenerMultiplexerHelper::setPeer( const Reference< XWindow >& xPeer )
157 : {
158 0 : MutexGuard aGuard( m_aMutex );
159 0 : if( m_xPeer != xPeer )
160 : {
161 0 : if( m_xPeer.is() )
162 : {
163 : // get all types from the listener added to the peer
164 0 : Sequence< Type > aContainedTypes = m_aListenerHolder.getContainedTypes();
165 0 : const Type* pArray = aContainedTypes.getConstArray();
166 0 : sal_Int32 nCount = aContainedTypes.getLength();
167 : // loop over all listener types and remove the listeners from the peer
168 0 : for( sal_Int32 i=0; i<nCount; i++ )
169 0 : impl_unadviseFromPeer( m_xPeer, pArray[i] );
170 : }
171 0 : m_xPeer = xPeer;
172 0 : if( m_xPeer.is() )
173 : {
174 : // get all types from the listener added to the peer
175 0 : Sequence< Type > aContainedTypes = m_aListenerHolder.getContainedTypes();
176 0 : const Type* pArray = aContainedTypes.getConstArray();
177 0 : sal_Int32 nCount = aContainedTypes.getLength();
178 : // loop over all listener types and add the listeners to the peer
179 0 : for( sal_Int32 i = 0; i < nCount; i++ )
180 0 : impl_adviseToPeer( m_xPeer, pArray[i] );
181 : }
182 0 : }
183 0 : }
184 :
185 : // container method
186 :
187 0 : void OMRCListenerMultiplexerHelper::disposeAndClear()
188 : {
189 0 : EventObject aEvent;
190 0 : aEvent.Source = m_xControl;
191 0 : m_aListenerHolder.disposeAndClear( aEvent );
192 0 : }
193 :
194 : // container method
195 :
196 0 : void OMRCListenerMultiplexerHelper::advise( const Type& aType ,
197 : const Reference< XInterface >& xListener )
198 : {
199 0 : MutexGuard aGuard( m_aMutex );
200 0 : if( m_aListenerHolder.addInterface( aType, xListener ) == 1 )
201 : {
202 : // the first listener is added
203 0 : if( m_xPeer.is() )
204 : {
205 0 : impl_adviseToPeer( m_xPeer, aType );
206 : }
207 0 : }
208 0 : }
209 :
210 : // container method
211 :
212 0 : void OMRCListenerMultiplexerHelper::unadvise( const Type& aType ,
213 : const Reference< XInterface >& xListener )
214 : {
215 0 : MutexGuard aGuard( m_aMutex );
216 0 : if( m_aListenerHolder.removeInterface( aType, xListener ) == 0 )
217 : {
218 : // the last listener is removed
219 0 : if ( m_xPeer.is() )
220 : {
221 0 : impl_unadviseFromPeer( m_xPeer, aType );
222 : }
223 0 : }
224 0 : }
225 :
226 : // XEventListener
227 :
228 0 : void SAL_CALL OMRCListenerMultiplexerHelper::disposing( const EventObject& /*aSource*/ ) throw( RuntimeException, std::exception )
229 : {
230 0 : MutexGuard aGuard( m_aMutex );
231 : // peer is disposed, clear the reference
232 0 : m_xPeer.clear();
233 0 : }
234 :
235 : // XFcousListener
236 :
237 0 : void OMRCListenerMultiplexerHelper::focusGained(const FocusEvent& aEvent ) throw( RuntimeException, std::exception )
238 : {
239 0 : MULTIPLEX( XFocusListener, focusGained, FocusEvent, aEvent )
240 0 : }
241 :
242 : // XFcousListener
243 :
244 0 : void OMRCListenerMultiplexerHelper::focusLost(const FocusEvent& aEvent ) throw( RuntimeException, std::exception )
245 : {
246 0 : MULTIPLEX( XFocusListener, focusLost, FocusEvent, aEvent )
247 0 : }
248 :
249 : // XWindowListener
250 :
251 0 : void OMRCListenerMultiplexerHelper::windowResized(const WindowEvent& aEvent ) throw( RuntimeException, std::exception )
252 : {
253 0 : MULTIPLEX( XWindowListener, windowResized, WindowEvent, aEvent )
254 0 : }
255 :
256 : // XWindowListener
257 :
258 0 : void OMRCListenerMultiplexerHelper::windowMoved(const WindowEvent& aEvent ) throw( RuntimeException, std::exception )
259 : {
260 0 : MULTIPLEX( XWindowListener, windowMoved, WindowEvent, aEvent )
261 0 : }
262 :
263 : // XWindowListener
264 :
265 0 : void OMRCListenerMultiplexerHelper::windowShown(const EventObject& aEvent ) throw( RuntimeException, std::exception )
266 : {
267 0 : MULTIPLEX( XWindowListener, windowShown, EventObject, aEvent )
268 0 : }
269 :
270 : // XWindowListener
271 :
272 0 : void OMRCListenerMultiplexerHelper::windowHidden(const EventObject& aEvent ) throw( RuntimeException, std::exception )
273 : {
274 0 : MULTIPLEX( XWindowListener, windowHidden, EventObject, aEvent )
275 0 : }
276 :
277 : // XKeyListener
278 :
279 0 : void OMRCListenerMultiplexerHelper::keyPressed(const KeyEvent& aEvent) throw( RuntimeException, std::exception )
280 : {
281 0 : MULTIPLEX( XKeyListener, keyPressed, KeyEvent, aEvent )
282 0 : }
283 :
284 : // XKeyListener
285 :
286 0 : void OMRCListenerMultiplexerHelper::keyReleased(const KeyEvent& aEvent) throw( RuntimeException, std::exception )
287 : {
288 0 : MULTIPLEX( XKeyListener, keyReleased, KeyEvent, aEvent )
289 0 : }
290 :
291 : // XMouseListener
292 :
293 0 : void OMRCListenerMultiplexerHelper::mousePressed(const MouseEvent& aEvent) throw( RuntimeException, std::exception )
294 : {
295 0 : MULTIPLEX( XMouseListener, mousePressed, MouseEvent, aEvent )
296 0 : }
297 :
298 : // XMouseListener
299 :
300 0 : void OMRCListenerMultiplexerHelper::mouseReleased(const MouseEvent& aEvent) throw( RuntimeException, std::exception )
301 : {
302 0 : MULTIPLEX( XMouseListener, mouseReleased, MouseEvent, aEvent )
303 0 : }
304 :
305 : // XMouseListener
306 :
307 0 : void OMRCListenerMultiplexerHelper::mouseEntered(const MouseEvent& aEvent) throw( RuntimeException, std::exception )
308 : {
309 0 : MULTIPLEX( XMouseListener, mouseEntered, MouseEvent, aEvent )
310 0 : }
311 :
312 : // XMouseListener
313 :
314 0 : void OMRCListenerMultiplexerHelper::mouseExited(const MouseEvent& aEvent) throw( RuntimeException, std::exception )
315 : {
316 0 : MULTIPLEX( XMouseListener, mouseExited, MouseEvent, aEvent )
317 0 : }
318 :
319 : // XMouseMotionListener
320 :
321 0 : void OMRCListenerMultiplexerHelper::mouseDragged(const MouseEvent& aEvent) throw( RuntimeException, std::exception )
322 : {
323 0 : MULTIPLEX( XMouseMotionListener, mouseDragged, MouseEvent, aEvent )
324 0 : }
325 :
326 : // XMouseMotionListener
327 :
328 0 : void OMRCListenerMultiplexerHelper::mouseMoved(const MouseEvent& aEvent) throw( RuntimeException, std::exception )
329 : {
330 0 : MULTIPLEX( XMouseMotionListener, mouseMoved, MouseEvent, aEvent )
331 0 : }
332 :
333 : // XPaintListener
334 :
335 0 : void OMRCListenerMultiplexerHelper::windowPaint(const PaintEvent& aEvent) throw( RuntimeException, std::exception )
336 : {
337 0 : MULTIPLEX( XPaintListener, windowPaint, PaintEvent, aEvent )
338 0 : }
339 :
340 : // XTopWindowListener
341 :
342 0 : void OMRCListenerMultiplexerHelper::windowOpened(const EventObject& aEvent) throw( RuntimeException, std::exception )
343 : {
344 0 : MULTIPLEX( XTopWindowListener, windowOpened, EventObject, aEvent )
345 0 : }
346 :
347 : // XTopWindowListener
348 :
349 0 : void OMRCListenerMultiplexerHelper::windowClosing( const EventObject& aEvent ) throw( RuntimeException, std::exception )
350 : {
351 0 : MULTIPLEX( XTopWindowListener, windowClosing, EventObject, aEvent )
352 0 : }
353 :
354 : // XTopWindowListener
355 :
356 0 : void OMRCListenerMultiplexerHelper::windowClosed( const EventObject& aEvent ) throw( RuntimeException, std::exception )
357 : {
358 0 : MULTIPLEX( XTopWindowListener, windowClosed, EventObject, aEvent )
359 0 : }
360 :
361 : // XTopWindowListener
362 :
363 0 : void OMRCListenerMultiplexerHelper::windowMinimized( const EventObject& aEvent ) throw( RuntimeException, std::exception )
364 : {
365 0 : MULTIPLEX( XTopWindowListener, windowMinimized, EventObject, aEvent )
366 0 : }
367 :
368 : // XTopWindowListener
369 :
370 0 : void OMRCListenerMultiplexerHelper::windowNormalized( const EventObject& aEvent ) throw( RuntimeException, std::exception )
371 : {
372 0 : MULTIPLEX( XTopWindowListener, windowNormalized, EventObject, aEvent )
373 0 : }
374 :
375 : // XTopWindowListener
376 :
377 0 : void OMRCListenerMultiplexerHelper::windowActivated( const EventObject& aEvent ) throw( RuntimeException, std::exception )
378 : {
379 0 : MULTIPLEX( XTopWindowListener, windowActivated, EventObject, aEvent )
380 0 : }
381 :
382 : // XTopWindowListener
383 :
384 0 : void OMRCListenerMultiplexerHelper::windowDeactivated( const EventObject& aEvent ) throw( RuntimeException, std::exception )
385 : {
386 0 : MULTIPLEX( XTopWindowListener, windowDeactivated, EventObject, aEvent )
387 0 : }
388 :
389 : // protected method
390 :
391 0 : void OMRCListenerMultiplexerHelper::impl_adviseToPeer( const Reference< XWindow >& xPeer ,
392 : const Type& aType )
393 : {
394 : // add a listener to the source (peer)
395 0 : if( aType == ::getCppuType((const Reference< XWindowListener >*)0) )
396 0 : xPeer->addWindowListener( this );
397 0 : else if( aType == ::getCppuType((const Reference< XKeyListener >*)0) )
398 0 : xPeer->addKeyListener( this );
399 0 : else if( aType == ::getCppuType((const Reference< XFocusListener >*)0) )
400 0 : xPeer->addFocusListener( this );
401 0 : else if( aType == ::getCppuType((const Reference< XMouseListener >*)0) )
402 0 : xPeer->addMouseListener( this );
403 0 : else if( aType == ::getCppuType((const Reference< XMouseMotionListener >*)0) )
404 0 : xPeer->addMouseMotionListener( this );
405 0 : else if( aType == ::getCppuType((const Reference< XPaintListener >*)0) )
406 0 : xPeer->addPaintListener( this );
407 0 : else if( aType == ::getCppuType((const Reference< XTopWindowListener >*)0) )
408 : {
409 0 : Reference< XTopWindow > xTop( xPeer, UNO_QUERY );
410 0 : if( xTop.is() )
411 0 : xTop->addTopWindowListener( this );
412 : }
413 : else
414 : {
415 : OSL_FAIL( "unknown listener" );
416 : }
417 0 : }
418 :
419 : // protected method
420 :
421 0 : void OMRCListenerMultiplexerHelper::impl_unadviseFromPeer( const Reference< XWindow >& xPeer ,
422 : const Type& aType )
423 : {
424 : // the last listener is removed, remove the listener from the source (peer)
425 0 : if( aType == ::getCppuType((const Reference< XWindowListener >*)0) )
426 0 : xPeer->removeWindowListener( this );
427 0 : else if( aType == ::getCppuType((const Reference< XKeyListener >*)0) )
428 0 : xPeer->removeKeyListener( this );
429 0 : else if( aType == ::getCppuType((const Reference< XFocusListener >*)0) )
430 0 : xPeer->removeFocusListener( this );
431 0 : else if( aType == ::getCppuType((const Reference< XMouseListener >*)0) )
432 0 : xPeer->removeMouseListener( this );
433 0 : else if( aType == ::getCppuType((const Reference< XMouseMotionListener >*)0) )
434 0 : xPeer->removeMouseMotionListener( this );
435 0 : else if( aType == ::getCppuType((const Reference< XPaintListener >*)0) )
436 0 : xPeer->removePaintListener( this );
437 0 : else if( aType == ::getCppuType((const Reference< XTopWindowListener >*)0) )
438 : {
439 0 : Reference< XTopWindow > xTop( xPeer, UNO_QUERY );
440 0 : if( xTop.is() )
441 0 : xTop->removeTopWindowListener( this );
442 : }
443 : else
444 : {
445 : OSL_FAIL( "unknown listener" );
446 : }
447 0 : }
448 :
449 : } // namespace unocontrols
450 :
451 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|