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 
28 using namespace ::cppu;
29 using namespace ::osl;
30 using namespace ::com::sun::star::uno;
31 using namespace ::com::sun::star::awt;
32 using namespace ::com::sun::star::lang;
33 
34 namespace 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 
67 OMRCListenerMultiplexerHelper::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 
75 OMRCListenerMultiplexerHelper::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 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 )
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 
150 void 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  {
211  impl_unadviseFromPeer( m_xPeer, aType );
212  }
213  }
214 }
215 
216 // XEventListener
217 
218 void 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 
227 void OMRCListenerMultiplexerHelper::focusGained(const FocusEvent& aEvent )
228 {
229  MULTIPLEX( XFocusListener, focusGained, FocusEvent, aEvent )
230 }
231 
232 // XFcousListener
233 
234 void OMRCListenerMultiplexerHelper::focusLost(const FocusEvent& aEvent )
235 {
236  MULTIPLEX( XFocusListener, focusLost, FocusEvent, aEvent )
237 }
238 
239 // XWindowListener
240 
241 void OMRCListenerMultiplexerHelper::windowResized(const WindowEvent& aEvent )
242 {
243  MULTIPLEX( XWindowListener, windowResized, WindowEvent, aEvent )
244 }
245 
246 // XWindowListener
247 
248 void OMRCListenerMultiplexerHelper::windowMoved(const WindowEvent& aEvent )
249 {
250  MULTIPLEX( XWindowListener, windowMoved, WindowEvent, aEvent )
251 }
252 
253 // XWindowListener
254 
255 void OMRCListenerMultiplexerHelper::windowShown(const EventObject& aEvent )
256 {
257  MULTIPLEX( XWindowListener, windowShown, EventObject, aEvent )
258 }
259 
260 // XWindowListener
261 
262 void 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 
325 void OMRCListenerMultiplexerHelper::windowPaint(const PaintEvent& aEvent)
326 {
327  MULTIPLEX( XPaintListener, windowPaint, PaintEvent, aEvent )
328 }
329 
330 // XTopWindowListener
331 
332 void OMRCListenerMultiplexerHelper::windowOpened(const EventObject& aEvent)
333 {
334  MULTIPLEX( XTopWindowListener, windowOpened, EventObject, aEvent )
335 }
336 
337 // XTopWindowListener
338 
339 void OMRCListenerMultiplexerHelper::windowClosing( const EventObject& aEvent )
340 {
341  MULTIPLEX( XTopWindowListener, windowClosing, EventObject, aEvent )
342 }
343 
344 // XTopWindowListener
345 
346 void OMRCListenerMultiplexerHelper::windowClosed( const EventObject& aEvent )
347 {
348  MULTIPLEX( XTopWindowListener, windowClosed, EventObject, aEvent )
349 }
350 
351 // XTopWindowListener
352 
353 void OMRCListenerMultiplexerHelper::windowMinimized( const EventObject& aEvent )
354 {
355  MULTIPLEX( XTopWindowListener, windowMinimized, EventObject, aEvent )
356 }
357 
358 // XTopWindowListener
359 
360 void OMRCListenerMultiplexerHelper::windowNormalized( const EventObject& aEvent )
361 {
362  MULTIPLEX( XTopWindowListener, windowNormalized, EventObject, aEvent )
363 }
364 
365 // XTopWindowListener
366 
367 void OMRCListenerMultiplexerHelper::windowActivated( const EventObject& aEvent )
368 {
369  MULTIPLEX( XTopWindowListener, windowActivated, EventObject, aEvent )
370 }
371 
372 // XTopWindowListener
373 
374 void OMRCListenerMultiplexerHelper::windowDeactivated( const EventObject& aEvent )
375 {
376  MULTIPLEX( XTopWindowListener, windowDeactivated, EventObject, aEvent )
377 }
378 
379 // protected method
380 
381 void 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 );
393  else if( aType == cppu::UnoType<XMouseMotionListener>::get())
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 
411 void 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 );
423  else if( aType == cppu::UnoType<XMouseMotionListener>::get())
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: */
Type
virtual void SAL_CALL mouseMoved(const css::awt::MouseEvent &aEvent) override
void impl_adviseToPeer(const css::uno::Reference< css::awt::XWindow > &xPeer, const css::uno::Type &aType)
Remove the listener from the peer.
void unadvise(const css::uno::Type &aType, const css::uno::Reference< css::uno::XInterface > &xListener)
Remove the specified listener from the source.
void advise(const css::uno::Type &aType, const css::uno::Reference< css::uno::XInterface > &xListener)
Add the specified listener to the source.
Reference< XControl > m_xControl
virtual void SAL_CALL windowResized(const css::awt::WindowEvent &aEvent) override
virtual void SAL_CALL windowClosed(const css::lang::EventObject &aEvent) override
virtual void SAL_CALL keyReleased(const css::awt::KeyEvent &aEvent) override
virtual void SAL_CALL windowOpened(const css::lang::EventObject &aEvent) override
virtual void SAL_CALL windowPaint(const css::awt::PaintEvent &aEvent) override
sal_Int32 removeInterface(const css::uno::Type &rKey, const css::uno::Reference< css::uno::XInterface > &rxIFace)
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &aType) override
give answer, if interface is supported The interfaces are searched by type.
Definition: multiplexer.cxx:94
virtual void SAL_CALL acquire() noexcept override
increment refcount XInterface release() A RuntimeException is thrown.
virtual void SAL_CALL windowActivated(const css::lang::EventObject &aEvent) override
virtual void SAL_CALL mouseDragged(const css::awt::MouseEvent &aEvent) override
virtual void SAL_CALL windowMoved(const css::awt::WindowEvent &aEvent) override
virtual void SAL_CALL focusLost(const css::awt::FocusEvent &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 keyPressed(const css::awt::KeyEvent &aEvent) override
std::mutex m_aMutex
virtual void SAL_CALL focusGained(const css::awt::FocusEvent &aEvent) override
virtual void SAL_CALL windowDeactivated(const css::lang::EventObject &aEvent) override
css::uno::WeakReference< css::awt::XWindow > m_xControl
The source of the events. Normally this is the peer object.
OMRCListenerMultiplexerHelper(const css::uno::Reference< css::awt::XWindow > &xControl, const css::uno::Reference< css::awt::XWindow > &xPeer)
constructor Create a Multiplexer of XWindowEvents.
virtual void SAL_CALL disposing(const css::lang::EventObject &aSource) override
#define MULTIPLEX(INTERFACE, METHOD, EVENTTYP, EVENT)
Definition: multiplexer.cxx:38
virtual void SAL_CALL mouseEntered(const css::awt::MouseEvent &aEvent) override
virtual void SAL_CALL mouseReleased(const css::awt::MouseEvent &aEvent) override
virtual void SAL_CALL windowNormalized(const css::lang::EventObject &aEvent) override
void disposeAndClear(const css::lang::EventObject &rEvt)
virtual void SAL_CALL windowHidden(const css::lang::EventObject &aEvent) override
virtual void SAL_CALL windowShown(const css::lang::EventObject &aEvent) override
virtual void SAL_CALL windowMinimized(const css::lang::EventObject &aEvent) override
std::vector< css::uno::Type > getContainedTypes() const
virtual void SAL_CALL mousePressed(const css::awt::MouseEvent &aEvent) override
comphelper::OMultiTypeInterfaceContainerHelper2 m_aListenerHolder
virtual void SAL_CALL release() noexcept override
decrement refcount XInterface acquire() A RuntimeException is thrown.
virtual void SAL_CALL mouseExited(const css::awt::MouseEvent &aEvent) override
sal_Int32 addInterface(const css::uno::Type &rKey, const css::uno::Reference< css::uno::XInterface > &r)
virtual void SAL_CALL windowClosing(const css::lang::EventObject &aEvent) override
css::uno::Reference< css::awt::XWindow > m_xPeer
void impl_unadviseFromPeer(const css::uno::Reference< css::awt::XWindow > &xPeer, const css::uno::Type &aType)
Add the listener to the peer.
css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType, Interface1 *p1)
AnyEventRef aEvent
void disposeAndClear()
Remove all listeners and send a disposing message.