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