LibreOffice Module comphelper (master)  1
listenernotification.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 
21 
22 #include <com/sun/star/lang/XEventListener.hpp>
23 #include <com/sun/star/lang/DisposedException.hpp>
24 #include <osl/diagnose.h>
25 
26 
27 namespace comphelper
28 {
29 
30 
31  using namespace ::com::sun::star::uno;
32  using namespace ::com::sun::star::lang;
33 
34  OListenerContainer::OListenerContainer( ::osl::Mutex& _rMutex )
35  :m_aListeners( _rMutex )
36  {
37  }
38 
40 
41 
42  void OListenerContainer::impl_addListener( const Reference< XEventListener >& _rxListener )
43  {
44  OSL_PRECOND( _rxListener.is(), "OListenerContainer::impl_addListener: a NULL listener?!" );
45  if ( _rxListener.is() )
46  m_aListeners.addInterface( _rxListener );
47  }
48 
49 
50  void OListenerContainer::impl_removeListener( const Reference< XEventListener >& _rxListener )
51  {
52 #if OSL_DEBUG_LEVEL > 0
54  bool bFound = false;
55  while ( aIter.hasMoreElements() && !bFound )
56  {
57  bFound = ( Reference< XInterface >( aIter.next() ) == _rxListener );
58  }
59  OSL_ENSURE( bFound, "OListenerContainer::impl_removeListener: sure your listener handling is correct? The given listener is not registered!" );
60 #endif
61  m_aListeners.removeInterface( _rxListener );
62  }
63 
64 
65  void OListenerContainer::disposing( const EventObject& _rEventSource )
66  {
67  m_aListeners.disposeAndClear( _rEventSource );
68  }
69 
70 
72  {
74  }
75 
76 
77  bool OListenerContainer::impl_notify( const EventObject& _rEvent )
78  {
80  bool bCancelled = false;
81  while ( aIter.hasMoreElements() && !bCancelled )
82  {
83  Reference< XEventListener > xListener( static_cast< XEventListener* >( aIter.next() ) );
84  if ( !xListener.is() )
85  continue;
86 
87  try
88  {
89  bCancelled = !implNotify( xListener, _rEvent );
90  }
91  catch( const DisposedException& e )
92  {
93  // DisposedExceptions from the listener might indicate a
94  // broken connection to a different environment.
95 
96  OSL_ENSURE( e.Context.is(), "OListenerContainer::impl_notify: caught dispose exception with empty Context field" );
97 
98  // If the exception stems from the listener then remove it
99  // from the list of listeners. If the Context field of the
100  // exception is empty this is interpreted to indicate the
101  // listener as well.
102  if ( e.Context == xListener || !e.Context.is() )
103  aIter.remove();
104  }
105  }
106 
107  return !bCancelled;
108  }
109 
110 
111 } // namespace comphelper
112 
113 
114 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
bool hasMoreElements() const
Return true, if there are more elements in the iterator.
OListenerContainer(::osl::Mutex &_rMutex)
sal_Int32 addInterface(const css::uno::Reference< css::uno::XInterface > &rxIFace)
Inserts an element into the container.
void disposeAndClear(const css::lang::EventObject &rEvt)
Call disposing on all object in the container that support XEventListener.
std::vector< Reference< css::datatransfer::clipboard::XClipboardListener > > m_aListeners
sal_Int32 removeInterface(const css::uno::Reference< css::uno::XInterface > &rxIFace)
Removes an element from the container.
bool impl_notify(const css::lang::EventObject &_rEvent)
notifies all listeners of the given event, using THB's notification pattern
void disposing(const css::lang::EventObject &_rEventSource)
sends a XEventObject::disposing notification to all listeners, and clears the listener container ...
void impl_removeListener(const css::uno::Reference< css::lang::XEventListener > &_rxListener)
void clear()
clears the container without calling XEventListener::disposing at ...
void clear()
Clears the container without calling disposing().
This is the iterator of an InterfaceContainerHelper.
::comphelper::OInterfaceContainerHelper2 m_aListeners
void impl_addListener(const css::uno::Reference< css::lang::XEventListener > &_rxListener)
css::uno::XInterface * next()
Return the next element of the iterator.
void remove()
Removes the current element (the last one returned by next()) from the underlying container...
virtual bool implNotify(const css::uno::Reference< css::lang::XEventListener > &_rxListener, const css::lang::EventObject &_rEvent)=0
call a single listener