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  OInterfaceContainerHelper* pContainer = m_aListenerHolder.getContainer( cppu::UnoType<INTERFACE>::get() ); \
42  /* Do the follow only, if elements in container exist.*/ \
43  if( pContainer != nullptr ) \
44  { \
45  OInterfaceIteratorHelper 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.is() ) \
52  { \
53  if( aIterator.hasMoreElements() ) \
54  { \
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  } \
66  }
67 
68 // construct/destruct
69 
70 OMRCListenerMultiplexerHelper::OMRCListenerMultiplexerHelper( const Reference< XWindow >& xControl ,
71  const Reference< XWindow >& xPeer )
72  : m_xPeer ( xPeer )
73  , m_xControl ( xControl )
74  , m_aListenerHolder ( m_aMutex )
75 {
76 }
77 
78 OMRCListenerMultiplexerHelper::OMRCListenerMultiplexerHelper( const OMRCListenerMultiplexerHelper& aCopyInstance )
79  : XFocusListener()
80  , XWindowListener()
81  , XKeyListener()
82  , XMouseListener()
83  , XMouseMotionListener()
84  , XPaintListener()
85  , XTopWindowListener()
86  , OWeakObject(aCopyInstance)
87  , m_aListenerHolder ( m_aMutex )
88 {
89 }
90 
92 {
93 }
94 
95 // XInterface
96 
98 {
99  // Attention:
100  // Don't use mutex or guard in this method!!! Is a method of XInterface.
101 
102  // Ask for my own supported interfaces ...
103  // Attention: XTypeProvider and XInterface are supported by OComponentHelper!
104  Any aReturn ( ::cppu::queryInterface( rType ,
105  static_cast< XWindowListener* > ( this ) ,
106  static_cast< XKeyListener* > ( this ) ,
107  static_cast< XFocusListener* > ( this ) ,
108  static_cast< XMouseListener* > ( this ) ,
109  static_cast< XMouseMotionListener* > ( this ) ,
110  static_cast< XPaintListener* > ( this ) ,
111  static_cast< XTopWindowListener* > ( this ) ,
112  static_cast< XTopWindowListener* > ( this )
113  )
114  );
115 
116  // If searched interface supported by this class ...
117  if ( aReturn.hasValue() )
118  {
119  // ... return this information.
120  return aReturn;
121  }
122  else
123  {
124  // Else; ... ask baseclass for interfaces!
125  return OWeakObject::queryInterface( rType );
126  }
127 }
128 
129 // XInterface
130 
132 {
133  // Attention:
134  // Don't use mutex or guard in this method!!! Is a method of XInterface.
135 
136  // Forward to baseclass
137  OWeakObject::acquire();
138 }
139 
140 // XInterface
141 
143 {
144  // Attention:
145  // Don't use mutex or guard in this method!!! Is a method of XInterface.
146 
147  // Forward to baseclass
148  OWeakObject::release();
149 }
150 
151 // container method
152 
153 void OMRCListenerMultiplexerHelper::setPeer( const Reference< XWindow >& xPeer )
154 {
155  MutexGuard aGuard( m_aMutex );
156  if( m_xPeer == xPeer )
157  return;
158 
159  if( m_xPeer.is() )
160  {
161  // get all types from the listener added to the peer
162  const Sequence< Type > aContainedTypes = m_aListenerHolder.getContainedTypes();
163  // loop over all listener types and remove the listeners from the peer
164  for( const auto& rContainedType : aContainedTypes )
165  impl_unadviseFromPeer( m_xPeer, rContainedType );
166  }
167  m_xPeer = xPeer;
168  if( m_xPeer.is() )
169  {
170  // get all types from the listener added to the peer
171  const Sequence< Type > aContainedTypes = m_aListenerHolder.getContainedTypes();
172  // loop over all listener types and add the listeners to the peer
173  for( const auto& rContainedType : aContainedTypes )
174  impl_adviseToPeer( m_xPeer, rContainedType );
175  }
176 }
177 
178 // container method
179 
181 {
182  EventObject aEvent;
183  aEvent.Source = m_xControl;
185 }
186 
187 // container method
188 
190  const Reference< XInterface >& xListener )
191 {
192  MutexGuard aGuard( m_aMutex );
193  if( m_aListenerHolder.addInterface( aType, xListener ) == 1 )
194  {
195  // the first listener is added
196  if( m_xPeer.is() )
197  {
198  impl_adviseToPeer( m_xPeer, aType );
199  }
200  }
201 }
202 
203 // container method
204 
206  const Reference< XInterface >& xListener )
207 {
208  MutexGuard aGuard( m_aMutex );
209  if( m_aListenerHolder.removeInterface( aType, xListener ) == 0 )
210  {
211  // the last listener is removed
212  if ( m_xPeer.is() )
213  {
214  impl_unadviseFromPeer( m_xPeer, aType );
215  }
216  }
217 }
218 
219 // XEventListener
220 
221 void SAL_CALL OMRCListenerMultiplexerHelper::disposing( const EventObject& /*aSource*/ )
222 {
223  MutexGuard aGuard( m_aMutex );
224  // peer is disposed, clear the reference
225  m_xPeer.clear();
226 }
227 
228 // XFcousListener
229 
230 void OMRCListenerMultiplexerHelper::focusGained(const FocusEvent& aEvent )
231 {
232  MULTIPLEX( XFocusListener, focusGained, FocusEvent, aEvent )
233 }
234 
235 // XFcousListener
236 
237 void OMRCListenerMultiplexerHelper::focusLost(const FocusEvent& aEvent )
238 {
239  MULTIPLEX( XFocusListener, focusLost, FocusEvent, aEvent )
240 }
241 
242 // XWindowListener
243 
244 void OMRCListenerMultiplexerHelper::windowResized(const WindowEvent& aEvent )
245 {
246  MULTIPLEX( XWindowListener, windowResized, WindowEvent, aEvent )
247 }
248 
249 // XWindowListener
250 
251 void OMRCListenerMultiplexerHelper::windowMoved(const WindowEvent& aEvent )
252 {
253  MULTIPLEX( XWindowListener, windowMoved, WindowEvent, aEvent )
254 }
255 
256 // XWindowListener
257 
258 void OMRCListenerMultiplexerHelper::windowShown(const EventObject& aEvent )
259 {
260  MULTIPLEX( XWindowListener, windowShown, EventObject, aEvent )
261 }
262 
263 // XWindowListener
264 
265 void OMRCListenerMultiplexerHelper::windowHidden(const EventObject& aEvent )
266 {
267  MULTIPLEX( XWindowListener, windowHidden, EventObject, aEvent )
268 }
269 
270 // XKeyListener
271 
273 {
274  MULTIPLEX( XKeyListener, keyPressed, KeyEvent, aEvent )
275 }
276 
277 // XKeyListener
278 
280 {
281  MULTIPLEX( XKeyListener, keyReleased, KeyEvent, aEvent )
282 }
283 
284 // XMouseListener
285 
287 {
288  MULTIPLEX( XMouseListener, mousePressed, MouseEvent, aEvent )
289 }
290 
291 // XMouseListener
292 
294 {
295  MULTIPLEX( XMouseListener, mouseReleased, MouseEvent, aEvent )
296 }
297 
298 // XMouseListener
299 
301 {
302  MULTIPLEX( XMouseListener, mouseEntered, MouseEvent, aEvent )
303 }
304 
305 // XMouseListener
306 
308 {
309  MULTIPLEX( XMouseListener, mouseExited, MouseEvent, aEvent )
310 }
311 
312 // XMouseMotionListener
313 
315 {
316  MULTIPLEX( XMouseMotionListener, mouseDragged, MouseEvent, aEvent )
317 }
318 
319 // XMouseMotionListener
320 
322 {
323  MULTIPLEX( XMouseMotionListener, mouseMoved, MouseEvent, aEvent )
324 }
325 
326 // XPaintListener
327 
328 void OMRCListenerMultiplexerHelper::windowPaint(const PaintEvent& aEvent)
329 {
330  MULTIPLEX( XPaintListener, windowPaint, PaintEvent, aEvent )
331 }
332 
333 // XTopWindowListener
334 
335 void OMRCListenerMultiplexerHelper::windowOpened(const EventObject& aEvent)
336 {
337  MULTIPLEX( XTopWindowListener, windowOpened, EventObject, aEvent )
338 }
339 
340 // XTopWindowListener
341 
342 void OMRCListenerMultiplexerHelper::windowClosing( const EventObject& aEvent )
343 {
344  MULTIPLEX( XTopWindowListener, windowClosing, EventObject, aEvent )
345 }
346 
347 // XTopWindowListener
348 
349 void OMRCListenerMultiplexerHelper::windowClosed( const EventObject& aEvent )
350 {
351  MULTIPLEX( XTopWindowListener, windowClosed, EventObject, aEvent )
352 }
353 
354 // XTopWindowListener
355 
356 void OMRCListenerMultiplexerHelper::windowMinimized( const EventObject& aEvent )
357 {
358  MULTIPLEX( XTopWindowListener, windowMinimized, EventObject, aEvent )
359 }
360 
361 // XTopWindowListener
362 
363 void OMRCListenerMultiplexerHelper::windowNormalized( const EventObject& aEvent )
364 {
365  MULTIPLEX( XTopWindowListener, windowNormalized, EventObject, aEvent )
366 }
367 
368 // XTopWindowListener
369 
370 void OMRCListenerMultiplexerHelper::windowActivated( const EventObject& aEvent )
371 {
372  MULTIPLEX( XTopWindowListener, windowActivated, EventObject, aEvent )
373 }
374 
375 // XTopWindowListener
376 
377 void OMRCListenerMultiplexerHelper::windowDeactivated( const EventObject& aEvent )
378 {
379  MULTIPLEX( XTopWindowListener, windowDeactivated, EventObject, aEvent )
380 }
381 
382 // protected method
383 
384 void OMRCListenerMultiplexerHelper::impl_adviseToPeer( const Reference< XWindow >& xPeer ,
385  const Type& aType )
386 {
387  // add a listener to the source (peer)
389  xPeer->addWindowListener( this );
390  else if( aType == cppu::UnoType<XKeyListener>::get())
391  xPeer->addKeyListener( this );
392  else if( aType == cppu::UnoType<XFocusListener>::get())
393  xPeer->addFocusListener( this );
394  else if( aType == cppu::UnoType<XMouseListener>::get())
395  xPeer->addMouseListener( this );
396  else if( aType == cppu::UnoType<XMouseMotionListener>::get())
397  xPeer->addMouseMotionListener( this );
398  else if( aType == cppu::UnoType<XPaintListener>::get())
399  xPeer->addPaintListener( this );
400  else if( aType == cppu::UnoType<XTopWindowListener>::get())
401  {
402  Reference< XTopWindow > xTop( xPeer, UNO_QUERY );
403  if( xTop.is() )
404  xTop->addTopWindowListener( this );
405  }
406  else
407  {
408  OSL_FAIL( "unknown listener" );
409  }
410 }
411 
412 // protected method
413 
414 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)
419  xPeer->removeWindowListener( this );
420  else if( aType == cppu::UnoType<XKeyListener>::get())
421  xPeer->removeKeyListener( this );
422  else if( aType == cppu::UnoType<XFocusListener>::get())
423  xPeer->removeFocusListener( this );
424  else if( aType == cppu::UnoType<XMouseListener>::get())
425  xPeer->removeMouseListener( this );
426  else if( aType == cppu::UnoType<XMouseMotionListener>::get())
427  xPeer->removeMouseMotionListener( this );
428  else if( aType == cppu::UnoType<XPaintListener>::get())
429  xPeer->removePaintListener( this );
430  else if( aType == cppu::UnoType<XTopWindowListener>::get())
431  {
432  Reference< XTopWindow > xTop( xPeer, UNO_QUERY );
433  if( xTop.is() )
434  xTop->removeTopWindowListener( this );
435  }
436  else
437  {
438  OSL_FAIL( "unknown listener" );
439  }
440 }
441 
442 } // namespace unocontrols
443 
444 /* 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.
osl::Mutex m_aMutex
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
sal_Int32 SAL_CALL removeInterface(const css::uno::Type &rKey, const css::uno::Reference< css::uno::XInterface > &rxIFace)
virtual void SAL_CALL windowOpened(const css::lang::EventObject &aEvent) override
virtual void SAL_CALL windowPaint(const css::awt::PaintEvent &aEvent) override
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:97
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.
::cppu::OMultiTypeInterfaceContainerHelper m_aListenerHolder
virtual void SAL_CALL keyPressed(const css::awt::KeyEvent &aEvent) override
sal_Int32 SAL_CALL addInterface(const css::uno::Type &rKey, const css::uno::Reference< css::uno::XInterface > &r)
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
void SAL_CALL disposeAndClear(const css::lang::EventObject &rEvt)
virtual void SAL_CALL acquire() override
increment refcount XInterface release() A RuntimeException is thrown.
virtual void SAL_CALL mouseReleased(const css::awt::MouseEvent &aEvent) override
virtual void SAL_CALL windowNormalized(const css::lang::EventObject &aEvent) override
virtual void SAL_CALL windowHidden(const css::lang::EventObject &aEvent) override
virtual void SAL_CALL windowShown(const css::lang::EventObject &aEvent) override
css::uno::Sequence< css::uno::Type > SAL_CALL getContainedTypes() const
virtual void SAL_CALL windowMinimized(const css::lang::EventObject &aEvent) override
virtual void SAL_CALL mousePressed(const css::awt::MouseEvent &aEvent) override
virtual void SAL_CALL mouseExited(const css::awt::MouseEvent &aEvent) override
virtual void SAL_CALL release() override
decrement refcount XInterface acquire() A RuntimeException is thrown.
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.