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 = static_cast<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 : // container method
148 :
149 0 : void OMRCListenerMultiplexerHelper::setPeer( const Reference< XWindow >& xPeer )
150 : {
151 0 : MutexGuard aGuard( m_aMutex );
152 0 : if( m_xPeer != xPeer )
153 : {
154 0 : if( m_xPeer.is() )
155 : {
156 : // get all types from the listener added to the peer
157 0 : Sequence< Type > aContainedTypes = m_aListenerHolder.getContainedTypes();
158 0 : const Type* pArray = aContainedTypes.getConstArray();
159 0 : sal_Int32 nCount = aContainedTypes.getLength();
160 : // loop over all listener types and remove the listeners from the peer
161 0 : for( sal_Int32 i=0; i<nCount; i++ )
162 0 : impl_unadviseFromPeer( m_xPeer, pArray[i] );
163 : }
164 0 : m_xPeer = xPeer;
165 0 : if( m_xPeer.is() )
166 : {
167 : // get all types from the listener added to the peer
168 0 : Sequence< Type > aContainedTypes = m_aListenerHolder.getContainedTypes();
169 0 : const Type* pArray = aContainedTypes.getConstArray();
170 0 : sal_Int32 nCount = aContainedTypes.getLength();
171 : // loop over all listener types and add the listeners to the peer
172 0 : for( sal_Int32 i = 0; i < nCount; i++ )
173 0 : impl_adviseToPeer( m_xPeer, pArray[i] );
174 : }
175 0 : }
176 0 : }
177 :
178 : // container method
179 :
180 0 : void OMRCListenerMultiplexerHelper::disposeAndClear()
181 : {
182 0 : EventObject aEvent;
183 0 : aEvent.Source = m_xControl;
184 0 : m_aListenerHolder.disposeAndClear( aEvent );
185 0 : }
186 :
187 : // container method
188 :
189 0 : void OMRCListenerMultiplexerHelper::advise( const Type& aType ,
190 : const Reference< XInterface >& xListener )
191 : {
192 0 : MutexGuard aGuard( m_aMutex );
193 0 : if( m_aListenerHolder.addInterface( aType, xListener ) == 1 )
194 : {
195 : // the first listener is added
196 0 : if( m_xPeer.is() )
197 : {
198 0 : impl_adviseToPeer( m_xPeer, aType );
199 : }
200 0 : }
201 0 : }
202 :
203 : // container method
204 :
205 0 : void OMRCListenerMultiplexerHelper::unadvise( const Type& aType ,
206 : const Reference< XInterface >& xListener )
207 : {
208 0 : MutexGuard aGuard( m_aMutex );
209 0 : if( m_aListenerHolder.removeInterface( aType, xListener ) == 0 )
210 : {
211 : // the last listener is removed
212 0 : if ( m_xPeer.is() )
213 : {
214 0 : impl_unadviseFromPeer( m_xPeer, aType );
215 : }
216 0 : }
217 0 : }
218 :
219 : // XEventListener
220 :
221 0 : void SAL_CALL OMRCListenerMultiplexerHelper::disposing( const EventObject& /*aSource*/ ) throw( RuntimeException, std::exception )
222 : {
223 0 : MutexGuard aGuard( m_aMutex );
224 : // peer is disposed, clear the reference
225 0 : m_xPeer.clear();
226 0 : }
227 :
228 : // XFcousListener
229 :
230 0 : void OMRCListenerMultiplexerHelper::focusGained(const FocusEvent& aEvent ) throw( RuntimeException, std::exception )
231 : {
232 0 : MULTIPLEX( XFocusListener, focusGained, FocusEvent, aEvent )
233 0 : }
234 :
235 : // XFcousListener
236 :
237 0 : void OMRCListenerMultiplexerHelper::focusLost(const FocusEvent& aEvent ) throw( RuntimeException, std::exception )
238 : {
239 0 : MULTIPLEX( XFocusListener, focusLost, FocusEvent, aEvent )
240 0 : }
241 :
242 : // XWindowListener
243 :
244 0 : void OMRCListenerMultiplexerHelper::windowResized(const WindowEvent& aEvent ) throw( RuntimeException, std::exception )
245 : {
246 0 : MULTIPLEX( XWindowListener, windowResized, WindowEvent, aEvent )
247 0 : }
248 :
249 : // XWindowListener
250 :
251 0 : void OMRCListenerMultiplexerHelper::windowMoved(const WindowEvent& aEvent ) throw( RuntimeException, std::exception )
252 : {
253 0 : MULTIPLEX( XWindowListener, windowMoved, WindowEvent, aEvent )
254 0 : }
255 :
256 : // XWindowListener
257 :
258 0 : void OMRCListenerMultiplexerHelper::windowShown(const EventObject& aEvent ) throw( RuntimeException, std::exception )
259 : {
260 0 : MULTIPLEX( XWindowListener, windowShown, EventObject, aEvent )
261 0 : }
262 :
263 : // XWindowListener
264 :
265 0 : void OMRCListenerMultiplexerHelper::windowHidden(const EventObject& aEvent ) throw( RuntimeException, std::exception )
266 : {
267 0 : MULTIPLEX( XWindowListener, windowHidden, EventObject, aEvent )
268 0 : }
269 :
270 : // XKeyListener
271 :
272 0 : void OMRCListenerMultiplexerHelper::keyPressed(const KeyEvent& aEvent) throw( RuntimeException, std::exception )
273 : {
274 0 : MULTIPLEX( XKeyListener, keyPressed, KeyEvent, aEvent )
275 0 : }
276 :
277 : // XKeyListener
278 :
279 0 : void OMRCListenerMultiplexerHelper::keyReleased(const KeyEvent& aEvent) throw( RuntimeException, std::exception )
280 : {
281 0 : MULTIPLEX( XKeyListener, keyReleased, KeyEvent, aEvent )
282 0 : }
283 :
284 : // XMouseListener
285 :
286 0 : void OMRCListenerMultiplexerHelper::mousePressed(const MouseEvent& aEvent) throw( RuntimeException, std::exception )
287 : {
288 0 : MULTIPLEX( XMouseListener, mousePressed, MouseEvent, aEvent )
289 0 : }
290 :
291 : // XMouseListener
292 :
293 0 : void OMRCListenerMultiplexerHelper::mouseReleased(const MouseEvent& aEvent) throw( RuntimeException, std::exception )
294 : {
295 0 : MULTIPLEX( XMouseListener, mouseReleased, MouseEvent, aEvent )
296 0 : }
297 :
298 : // XMouseListener
299 :
300 0 : void OMRCListenerMultiplexerHelper::mouseEntered(const MouseEvent& aEvent) throw( RuntimeException, std::exception )
301 : {
302 0 : MULTIPLEX( XMouseListener, mouseEntered, MouseEvent, aEvent )
303 0 : }
304 :
305 : // XMouseListener
306 :
307 0 : void OMRCListenerMultiplexerHelper::mouseExited(const MouseEvent& aEvent) throw( RuntimeException, std::exception )
308 : {
309 0 : MULTIPLEX( XMouseListener, mouseExited, MouseEvent, aEvent )
310 0 : }
311 :
312 : // XMouseMotionListener
313 :
314 0 : void OMRCListenerMultiplexerHelper::mouseDragged(const MouseEvent& aEvent) throw( RuntimeException, std::exception )
315 : {
316 0 : MULTIPLEX( XMouseMotionListener, mouseDragged, MouseEvent, aEvent )
317 0 : }
318 :
319 : // XMouseMotionListener
320 :
321 0 : void OMRCListenerMultiplexerHelper::mouseMoved(const MouseEvent& aEvent) throw( RuntimeException, std::exception )
322 : {
323 0 : MULTIPLEX( XMouseMotionListener, mouseMoved, MouseEvent, aEvent )
324 0 : }
325 :
326 : // XPaintListener
327 :
328 0 : void OMRCListenerMultiplexerHelper::windowPaint(const PaintEvent& aEvent) throw( RuntimeException, std::exception )
329 : {
330 0 : MULTIPLEX( XPaintListener, windowPaint, PaintEvent, aEvent )
331 0 : }
332 :
333 : // XTopWindowListener
334 :
335 0 : void OMRCListenerMultiplexerHelper::windowOpened(const EventObject& aEvent) throw( RuntimeException, std::exception )
336 : {
337 0 : MULTIPLEX( XTopWindowListener, windowOpened, EventObject, aEvent )
338 0 : }
339 :
340 : // XTopWindowListener
341 :
342 0 : void OMRCListenerMultiplexerHelper::windowClosing( const EventObject& aEvent ) throw( RuntimeException, std::exception )
343 : {
344 0 : MULTIPLEX( XTopWindowListener, windowClosing, EventObject, aEvent )
345 0 : }
346 :
347 : // XTopWindowListener
348 :
349 0 : void OMRCListenerMultiplexerHelper::windowClosed( const EventObject& aEvent ) throw( RuntimeException, std::exception )
350 : {
351 0 : MULTIPLEX( XTopWindowListener, windowClosed, EventObject, aEvent )
352 0 : }
353 :
354 : // XTopWindowListener
355 :
356 0 : void OMRCListenerMultiplexerHelper::windowMinimized( const EventObject& aEvent ) throw( RuntimeException, std::exception )
357 : {
358 0 : MULTIPLEX( XTopWindowListener, windowMinimized, EventObject, aEvent )
359 0 : }
360 :
361 : // XTopWindowListener
362 :
363 0 : void OMRCListenerMultiplexerHelper::windowNormalized( const EventObject& aEvent ) throw( RuntimeException, std::exception )
364 : {
365 0 : MULTIPLEX( XTopWindowListener, windowNormalized, EventObject, aEvent )
366 0 : }
367 :
368 : // XTopWindowListener
369 :
370 0 : void OMRCListenerMultiplexerHelper::windowActivated( const EventObject& aEvent ) throw( RuntimeException, std::exception )
371 : {
372 0 : MULTIPLEX( XTopWindowListener, windowActivated, EventObject, aEvent )
373 0 : }
374 :
375 : // XTopWindowListener
376 :
377 0 : void OMRCListenerMultiplexerHelper::windowDeactivated( const EventObject& aEvent ) throw( RuntimeException, std::exception )
378 : {
379 0 : MULTIPLEX( XTopWindowListener, windowDeactivated, EventObject, aEvent )
380 0 : }
381 :
382 : // protected method
383 :
384 0 : void OMRCListenerMultiplexerHelper::impl_adviseToPeer( const Reference< XWindow >& xPeer ,
385 : const Type& aType )
386 : {
387 : // add a listener to the source (peer)
388 0 : if( aType == cppu::UnoType<XWindowListener>::get())
389 0 : xPeer->addWindowListener( this );
390 0 : else if( aType == cppu::UnoType<XKeyListener>::get())
391 0 : xPeer->addKeyListener( this );
392 0 : else if( aType == cppu::UnoType<XFocusListener>::get())
393 0 : xPeer->addFocusListener( this );
394 0 : else if( aType == cppu::UnoType<XMouseListener>::get())
395 0 : xPeer->addMouseListener( this );
396 0 : else if( aType == cppu::UnoType<XMouseMotionListener>::get())
397 0 : xPeer->addMouseMotionListener( this );
398 0 : else if( aType == cppu::UnoType<XPaintListener>::get())
399 0 : xPeer->addPaintListener( this );
400 0 : else if( aType == cppu::UnoType<XTopWindowListener>::get())
401 : {
402 0 : Reference< XTopWindow > xTop( xPeer, UNO_QUERY );
403 0 : if( xTop.is() )
404 0 : xTop->addTopWindowListener( this );
405 : }
406 : else
407 : {
408 : OSL_FAIL( "unknown listener" );
409 : }
410 0 : }
411 :
412 : // protected method
413 :
414 0 : void OMRCListenerMultiplexerHelper::impl_unadviseFromPeer( const Reference< XWindow >& xPeer ,
415 : const Type& aType )
416 : {
417 : // the last listener is removed, remove the listener from the source (peer)
418 0 : if( aType == cppu::UnoType<XWindowListener>::get())
419 0 : xPeer->removeWindowListener( this );
420 0 : else if( aType == cppu::UnoType<XKeyListener>::get())
421 0 : xPeer->removeKeyListener( this );
422 0 : else if( aType == cppu::UnoType<XFocusListener>::get())
423 0 : xPeer->removeFocusListener( this );
424 0 : else if( aType == cppu::UnoType<XMouseListener>::get())
425 0 : xPeer->removeMouseListener( this );
426 0 : else if( aType == cppu::UnoType<XMouseMotionListener>::get())
427 0 : xPeer->removeMouseMotionListener( this );
428 0 : else if( aType == cppu::UnoType<XPaintListener>::get())
429 0 : xPeer->removePaintListener( this );
430 0 : else if( aType == cppu::UnoType<XTopWindowListener>::get())
431 : {
432 0 : Reference< XTopWindow > xTop( xPeer, UNO_QUERY );
433 0 : if( xTop.is() )
434 0 : xTop->removeTopWindowListener( this );
435 : }
436 : else
437 : {
438 : OSL_FAIL( "unknown listener" );
439 : }
440 0 : }
441 :
442 : } // namespace unocontrols
443 :
444 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|