bump product version to 4.1.6.2
[LibreOffice.git] / include / comphelper / listenernotification.hxx
blob21e2ea74723b3642f5dbbc2a5c1d6185cbb82013
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #ifndef COMPHELPER_INC_COMPHELPER_LISTENERNOTIFICATION_HXX
21 #define COMPHELPER_INC_COMPHELPER_LISTENERNOTIFICATION_HXX
23 #include <cppuhelper/interfacecontainer.hxx>
25 #include <com/sun/star/lang/XEventListener.hpp>
26 #include "comphelper/comphelperdllapi.h"
28 #include <memory>
30 //........................................................................
31 namespace comphelper
33 //........................................................................
35 //====================================================================
36 //= OListenerContainer
37 //====================================================================
38 /** abstract base class which manages a listener container, including
39 THB's listener notification pattern which cares for removing listeners
40 which throw an DisposedException upon notification
42 Using this class is pretty easy:
43 <ul>
44 <li>Derive from it, and overwrite implNotify.</li>
45 <li>Use <member>impl_addListener</member> and <member>impl_removeListener</member> in your
46 XFoo::addFooListener and XFoo::removeFooListener methods.</li>
47 <li>call <member>impl_notify</member> whenever the event you want to notify happened</li>
48 <li>call <member>disposing</member> upon the disposal of your broadcaster.</li>
49 </ul>
51 See <type>OListenerContainerBase</type> for an implementation which even saves
52 you some more work, by doing the casts for you.
54 @see http://www.openoffice.org/servlets/ReadMsg?list=interface-announce&msgId=494345
55 @see OListenerContainerBase
57 class COMPHELPER_DLLPUBLIC OListenerContainer
59 private:
60 ::cppu::OInterfaceContainerHelper m_aListeners;
62 public:
63 /** sends a XEventObject::disposing notification to all listeners, and clears the
64 listener container
66 You'll usually call this from within your own dispose/disposing method
68 void disposing( const ::com::sun::star::lang::EventObject& _rEventSource );
70 /** clears the container without calling <member scope="com::sun::star::lang">XEventListener::disposing</member>
71 at the listeners
73 void clear();
75 /** determines whether the listener container is currently empty
77 inline bool
78 empty() const SAL_THROW(());
80 /** determines the number of elements in the container
82 inline size_t
83 size() const SAL_THROW(());
85 /** creates an iterator for looping through all registered listeners
87 SAL_WNODEPRECATED_DECLARATIONS_PUSH
88 ::std::auto_ptr< ::cppu::OInterfaceIteratorHelper > createIterator()
90 ::std::auto_ptr< ::cppu::OInterfaceIteratorHelper > pIterator( new ::cppu::OInterfaceIteratorHelper( m_aListeners ) );
91 return pIterator;
93 SAL_WNODEPRECATED_DECLARATIONS_POP
95 protected:
96 OListenerContainer( ::osl::Mutex& _rMutex );
98 virtual ~OListenerContainer();
100 void impl_addListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& _rxListener );
101 void impl_removeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& _rxListener );
103 /** notifies all listeners of the given event, using THB's notification pattern
105 internally, this method will call <member>implNotify</member> for every listener
107 @return
108 <TRUE/> if all listeners have been notified, <FALSE/> else. The latter can happen
109 if <member>implNotify</member> cancelles the notification loop.
111 @see implNotify
113 bool impl_notify( const ::com::sun::star::lang::EventObject& _rEvent ) SAL_THROW(( ::com::sun::star::uno::Exception ));
115 protected:
116 /** call a single listener
118 @pure
120 @throws ::com::sun::star::uno::Exception
121 if the listener throws an exception during notification. Please don't catch
122 any listener exceptions in your implementation of this method, simply let them
123 pass to the caller.
125 @param _rxListener
126 specifies the listener to call. Is guaranteed to not be <NULL/>
127 @param _rEvent
128 the event to broadcast. This is the same as passed to <member>notify</member>, so if
129 your base class knows the type passed into <member>notify</member>, it can safely assume
130 that <arg>_rEvent</arg> is also of this type.
132 @return
133 <TRUE/> if the remaining listeners should be called, <FALSE/> if the notification
134 loop should be cancelled
136 @see notify
138 virtual bool implNotify(
139 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& _rxListener,
140 const ::com::sun::star::lang::EventObject& _rEvent
141 ) SAL_THROW( ( ::com::sun::star::uno::Exception ) ) = 0;
144 //====================================================================
145 inline bool OListenerContainer::empty() const SAL_THROW(())
147 return ( m_aListeners.getLength() == 0 );
150 inline size_t OListenerContainer::size() const SAL_THROW(())
152 return m_aListeners.getLength();
155 //====================================================================
156 //= OSimpleListenerContainer
157 //====================================================================
158 /** helper class for simple notification of the form LISTENER::METHOD( EVENT )
160 This class is not threadsafe!
162 @param LISTENER
163 the listener class to call, e.g. <type scope="com::sun::star::lang">XEventListener</type>
164 @param EVENT
165 the event type to notify, e.g. <type scope="com::sun::star::lang">EventObject</type>
167 template< class LISTENER, class EVENT >
168 class OSimpleListenerContainer : protected OListenerContainer
170 public:
171 typedef LISTENER ListenerClass;
172 typedef EVENT EventClass;
173 typedef void ( SAL_CALL LISTENER::*NotificationMethod )( const EventClass& );
175 private:
176 NotificationMethod m_pNotificationMethod;
178 public:
179 OSimpleListenerContainer( ::osl::Mutex& _rMutex )
180 :OListenerContainer( _rMutex )
181 ,m_pNotificationMethod( NULL )
185 inline void addListener( const ::com::sun::star::uno::Reference< ListenerClass >& _rxListener )
187 OListenerContainer::impl_addListener( _rxListener.get() );
190 inline void removeListener( const ::com::sun::star::uno::Reference< ListenerClass >& _rxListener )
192 OListenerContainer::impl_removeListener( _rxListener.get() );
195 // publish some otherwise hidden base functionality
196 using OListenerContainer::disposing;
197 using OListenerContainer::clear;
198 using OListenerContainer::empty;
199 using OListenerContainer::size;
200 using OListenerContainer::createIterator;
202 /// typed notification
203 inline bool notify( const EventClass& _rEvent, NotificationMethod _pNotify ) SAL_THROW(( ::com::sun::star::uno::Exception ));
205 protected:
206 inline virtual bool implNotify(
207 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& _rxListener,
208 const ::com::sun::star::lang::EventObject& _rEvent
209 ) SAL_THROW( ( ::com::sun::star::uno::Exception ) );
212 //--------------------------------------------------------------------
213 template< class LISTENER, class EVENT >
214 inline bool OSimpleListenerContainer< LISTENER, EVENT >::notify( const EventClass& _rEvent, NotificationMethod _pNotify ) SAL_THROW(( ::com::sun::star::uno::Exception ))
216 m_pNotificationMethod = _pNotify;
217 bool bRet = OListenerContainer::impl_notify( _rEvent );
218 m_pNotificationMethod = NULL;
219 return bRet;
222 //--------------------------------------------------------------------
223 template< class LISTENER, class EVENT >
224 inline bool OSimpleListenerContainer< LISTENER, EVENT >::implNotify(
225 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& _rxListener,
226 const ::com::sun::star::lang::EventObject& _rEvent ) SAL_THROW( ( ::com::sun::star::uno::Exception ) )
228 const EventClass& rTypedEvent( static_cast< const EventClass& >( _rEvent ) );
229 ListenerClass* pTypedListener( static_cast< ListenerClass* >( _rxListener.get() ) );
230 (pTypedListener->*m_pNotificationMethod)( rTypedEvent );
231 return true;
234 //====================================================================
235 //= OListenerContainerBase
236 //====================================================================
237 /** is a specialization of OListenerContainer which saves you some additional type casts,
238 by making the required listener and event types template arguments.
240 template< class LISTENER, class EVENT >
241 class OListenerContainerBase : public OListenerContainer
243 public:
244 typedef LISTENER ListenerClass;
245 typedef EVENT EventClass;
247 public:
248 inline OListenerContainerBase( ::osl::Mutex& _rMutex ) : OListenerContainer( _rMutex )
252 inline void addTypedListener( const ::com::sun::star::uno::Reference< ListenerClass >& _rxListener )
254 OListenerContainer::impl_addListener( _rxListener.get() );
257 inline void removeTypedListener( const ::com::sun::star::uno::Reference< ListenerClass >& _rxListener )
259 OListenerContainer::impl_removeListener( _rxListener.get() );
262 inline bool notify( const EventClass& _rEvent )
264 return OListenerContainer::impl_notify( _rEvent );
267 using OListenerContainer::impl_notify;
269 protected:
270 inline virtual bool implNotify(
271 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& _rxListener,
272 const ::com::sun::star::lang::EventObject& _rEvent
273 ) SAL_THROW( ( ::com::sun::star::uno::Exception ) );
275 virtual bool implTypedNotify(
276 const ::com::sun::star::uno::Reference< ListenerClass >& _rxListener,
277 const EventClass& _rEvent
278 ) SAL_THROW( ( ::com::sun::star::uno::Exception ) ) = 0;
281 template< class LISTENER, class EVENT >
282 inline bool OListenerContainerBase< LISTENER, EVENT >::implNotify(
283 const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener >& _rxListener,
284 const ::com::sun::star::lang::EventObject& _rEvent ) SAL_THROW( ( ::com::sun::star::uno::Exception ) )
286 return implTypedNotify(
287 ::com::sun::star::uno::Reference< ListenerClass >( static_cast< ListenerClass* >( _rxListener.get() ) ),
288 static_cast< const EventClass& >( _rEvent )
292 //........................................................................
293 } // namespace comphelper
294 //........................................................................
296 #endif // COMPHELPER_INC_COMPHELPER_LISTENERNOTIFICATION_HXX
298 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */