1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 INCLUDED_DBACCESS_SOURCE_UI_INC_SBAMULTIPLEX_HXX
21 #define INCLUDED_DBACCESS_SOURCE_UI_INC_SBAMULTIPLEX_HXX
23 #include <com/sun/star/beans/XVetoableChangeListener.hpp>
24 #include <com/sun/star/form/XUpdateListener.hpp>
25 #include <com/sun/star/form/XErrorListener.hpp>
26 #include <com/sun/star/form/XRestoreListener.hpp>
27 #include <com/sun/star/form/XInsertListener.hpp>
28 #include <com/sun/star/form/XDeleteListener.hpp>
29 #include <com/sun/star/form/XPositioningListener.hpp>
30 #include <com/sun/star/form/XDatabaseParameterListener.hpp>
31 #include <com/sun/star/form/XLoadListener.hpp>
32 #include <com/sun/star/beans/XPropertyStateChangeListener.hpp>
33 #include <com/sun/star/beans/XPropertiesChangeListener.hpp>
34 #include <com/sun/star/beans/XPropertyChangeListener.hpp>
35 #include <com/sun/star/form/XSubmitListener.hpp>
36 #include <com/sun/star/form/XResetListener.hpp>
37 #include <com/sun/star/util/XRefreshListener.hpp>
38 #include <com/sun/star/sdb/XSQLErrorListener.hpp>
39 #include <com/sun/star/sdb/XRowSetApproveListener.hpp>
40 #include <com/sun/star/sdbc/XRowSetListener.hpp>
41 #include <com/sun/star/frame/XStatusListener.hpp>
42 #include <comphelper/uno3.hxx>
43 #include <cppuhelper/interfacecontainer.hxx>
44 #include <cppuhelper/queryinterface.hxx>
45 #include <cppuhelper/weak.hxx>
49 // TODO : replace this class if MM provides an WeakSubObject in cppu
50 class OSbaWeakSubObject
: public ::cppu::OWeakObject
53 ::cppu::OWeakObject
& m_rParent
;
56 OSbaWeakSubObject(::cppu::OWeakObject
& rParent
) : m_rParent(rParent
) { }
58 virtual void SAL_CALL
acquire() throw() SAL_OVERRIDE
{ m_rParent
.acquire(); }
59 virtual void SAL_CALL
release() throw() SAL_OVERRIDE
{ m_rParent
.release(); }
62 // declaration of a listener multiplexer class
63 #define BEGIN_DECLARE_LISTENER_MULTIPLEXER(classname, listenerclass) \
65 :public OSbaWeakSubObject \
66 ,public listenerclass \
67 ,public ::cppu::OInterfaceContainerHelper \
70 classname( ::cppu::OWeakObject& rSource, \
71 ::osl::Mutex& rMutex); \
72 DECLARE_UNO3_DEFAULTS(classname, OSbaWeakSubObject) \
73 virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( \
74 const ::com::sun::star::uno::Type& _rType) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; \
76 /* ::com::sun::star::lang::XEventListener */ \
77 virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; \
79 #define DECLARE_MULTIPLEXER_VOID_METHOD(methodname, eventtype) \
80 virtual void SAL_CALL methodname(const eventtype& e) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; \
82 #define DECLARE_MULTIPLEXER_BOOL_METHOD(methodname, eventtype) \
83 virtual sal_Bool SAL_CALL methodname(const eventtype& e) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; \
85 #define END_DECLARE_LISTENER_MULTIPLEXER() \
86 /* resolve ambiguity : both OWeakObject and OInterfaceContainerHelper have these memory operators */ \
87 void * SAL_CALL operator new( size_t size ) throw() { return OSbaWeakSubObject::operator new(size); } \
88 void SAL_CALL operator delete( void * p ) throw() { OSbaWeakSubObject::operator delete(p); } \
91 // implementation of a listener multiplexer class
93 #define IMPLEMENT_LISTENER_MULTIPLEXER_CORE(classname, listenerclass) \
95 classname::classname(::cppu::OWeakObject& rSource, ::osl::Mutex& _rMutex) \
96 :OSbaWeakSubObject(rSource) \
97 ,OInterfaceContainerHelper(_rMutex) \
101 ::com::sun::star::uno::Any SAL_CALL classname::queryInterface( \
102 const ::com::sun::star::uno::Type& _rType) throw (::com::sun::star::uno::RuntimeException, std::exception) \
104 ::com::sun::star::uno::Any aReturn = \
105 OSbaWeakSubObject::queryInterface(_rType); \
106 if (!aReturn.hasValue()) \
107 aReturn = ::cppu::queryInterface(_rType, \
108 static_cast< listenerclass* >(this), \
109 static_cast< ::com::sun::star::lang::XEventListener* >(static_cast< listenerclass* >(this)) \
114 void SAL_CALL classname::disposing(const ::com::sun::star::lang::EventObject& ) throw(::com::sun::star::uno::RuntimeException, std::exception)\
118 #define IMPLEMENT_LISTENER_MULTIPLEXER_VOID_METHOD(classname, listenerclass, methodname, eventtype) \
119 void SAL_CALL classname::methodname(const eventtype& e) throw (::com::sun::star::uno::RuntimeException, std::exception) \
121 eventtype aMulti(e); \
122 aMulti.Source = &m_rParent; \
123 ::cppu::OInterfaceIteratorHelper aIt(*this); \
124 while (aIt.hasMoreElements()) \
125 static_cast< listenerclass*>(aIt.next())->methodname(aMulti); \
128 #define IMPLEMENT_LISTENER_MULTIPLEXER_BOOL_METHOD(classname, listenerclass, methodname, eventtype) \
129 sal_Bool SAL_CALL classname::methodname(const eventtype& e) throw (::com::sun::star::uno::RuntimeException, std::exception) \
131 eventtype aMulti(e); \
132 aMulti.Source = &m_rParent; \
133 ::cppu::OInterfaceIteratorHelper aIt(*this); \
134 bool bResult = true; \
135 while (bResult && aIt.hasMoreElements()) \
136 bResult = static_cast< listenerclass*>(aIt.next())->methodname(aMulti); \
140 // helper for classes which do event multiplexing
141 #define IMPLEMENT_LISTENER_ADMINISTRATION(classname, listenernamespace, listenerdesc, multiplexer, braodcasterclass, broadcaster) \
142 void SAL_CALL classname::add##listenerdesc(const ::com::sun::star::uno::Reference< ::com::sun::star::listenernamespace::X##listenerdesc >& l) throw(::com::sun::star::uno::RuntimeException, std::exception)\
144 multiplexer.addInterface(l); \
145 if (multiplexer.getLength() == 1) \
147 ::com::sun::star::uno::Reference< braodcasterclass > xBroadcaster(broadcaster, ::com::sun::star::uno::UNO_QUERY); \
148 if (xBroadcaster.is()) \
149 xBroadcaster->add##listenerdesc(&multiplexer); \
152 void SAL_CALL classname::remove##listenerdesc(const ::com::sun::star::uno::Reference< ::com::sun::star::listenernamespace::X##listenerdesc >& l) throw(::com::sun::star::uno::RuntimeException, std::exception)\
154 if (multiplexer.getLength() == 1) \
156 ::com::sun::star::uno::Reference< braodcasterclass > xBroadcaster(broadcaster, ::com::sun::star::uno::UNO_QUERY); \
157 if (xBroadcaster.is()) \
158 xBroadcaster->remove##listenerdesc(&multiplexer); \
160 multiplexer.removeInterface(l); \
163 #define STOP_MULTIPLEXER_LISTENING(listenerdesc, multiplexer, braodcasterclass, broadcaster) \
164 if (multiplexer.getLength()) \
166 ::com::sun::star::uno::Reference< braodcasterclass > xBroadcaster(broadcaster, ::com::sun::star::uno::UNO_QUERY); \
167 if (xBroadcaster.is()) \
168 xBroadcaster->remove##listenerdesc(&multiplexer); \
171 #define START_MULTIPLEXER_LISTENING(listenerdesc, multiplexer, braodcasterclass, broadcaster) \
172 if (multiplexer.getLength()) \
174 ::com::sun::star::uno::Reference< braodcasterclass > xBroadcaster(broadcaster, ::com::sun::star::uno::UNO_QUERY); \
175 if (xBroadcaster.is()) \
176 xBroadcaster->add##listenerdesc(&multiplexer); \
179 // declaration of property listener multiplexers
180 // (with support for specialized and unspecialized property listeners)
182 #define DECLARE_PROPERTY_MULTIPLEXER(classname, listenerclass, methodname, eventtype, exceptions) \
184 :public OSbaWeakSubObject \
185 ,public listenerclass \
187 typedef ::cppu::OMultiTypeInterfaceContainerHelperVar< \
188 OUString > ListenerContainerMap; \
189 ListenerContainerMap m_aListeners; \
192 classname( ::cppu::OWeakObject& rSource, ::osl::Mutex& rMutex ); \
193 DECLARE_UNO3_DEFAULTS(classname, OSbaWeakSubObject) \
194 virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( \
195 const ::com::sun::star::uno::Type& _rType) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; \
197 /* ::com::sun::star::lang::XEventListener */ \
198 virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; \
200 virtual void SAL_CALL methodname(const eventtype& e) throw exceptions SAL_OVERRIDE; \
203 void addInterface(const OUString& rName, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rListener); \
204 void removeInterface(const OUString& rName, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rListener); \
206 void disposeAndClear(); \
208 sal_Int32 getOverallLen() const; \
210 ::cppu::OInterfaceContainerHelper* getContainer(const OUString& rName) \
211 { return m_aListeners.getContainer(rName); } \
214 void Notify(::cppu::OInterfaceContainerHelper& rListeners, const eventtype& e); \
217 // implementation of property listener multiplexers
218 #define IMPLEMENT_PROPERTY_MULTIPLEXER(classname, listenerclass, methodname, eventtype, exceptions) \
219 classname::classname(::cppu::OWeakObject& rSource, ::osl::Mutex& rMutex) \
220 :OSbaWeakSubObject(rSource) \
221 ,m_aListeners(rMutex) \
225 ::com::sun::star::uno::Any SAL_CALL classname::queryInterface( \
226 const ::com::sun::star::uno::Type& _rType) throw (::com::sun::star::uno::RuntimeException, std::exception) \
228 ::com::sun::star::uno::Any aReturn = \
229 OSbaWeakSubObject::queryInterface(_rType); \
230 if (!aReturn.hasValue()) \
231 aReturn = ::cppu::queryInterface(_rType, \
232 static_cast< listenerclass* >(this), \
233 static_cast< ::com::sun::star::lang::XEventListener* >(static_cast< listenerclass* >(this)) \
238 void SAL_CALL classname::disposing(const ::com::sun::star::lang::EventObject& ) throw(::com::sun::star::uno::RuntimeException, std::exception)\
242 void SAL_CALL classname::methodname(const eventtype& e) throw exceptions \
244 ::cppu::OInterfaceContainerHelper* pListeners = m_aListeners.getContainer(e.PropertyName); \
246 Notify(*pListeners, e); \
248 /* do the notification for the unspecialized listeners, too */ \
249 pListeners = m_aListeners.getContainer(OUString()); \
251 Notify(*pListeners, e); \
254 void classname::addInterface(const OUString& rName, \
255 const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & rListener) \
257 m_aListeners.addInterface(rName, rListener); \
260 void classname::removeInterface(const OUString& rName, \
261 const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > & rListener) \
263 m_aListeners.removeInterface(rName, rListener); \
266 void classname::disposeAndClear() \
268 ::com::sun::star::lang::EventObject aEvt(m_rParent); \
269 m_aListeners.disposeAndClear(aEvt); \
272 sal_Int32 classname::getOverallLen() const \
274 sal_Int32 nLen = 0; \
275 ::com::sun::star::uno::Sequence< OUString > aContained = m_aListeners.getContainedTypes(); \
276 const OUString* pContained = aContained.getConstArray(); \
277 for ( sal_Int32 i=0; i<aContained.getLength(); ++i, ++pContained) \
279 ::cppu::OInterfaceContainerHelper* pListeners = m_aListeners.getContainer(*pContained); \
282 nLen += pListeners->getLength(); \
287 void classname::Notify(::cppu::OInterfaceContainerHelper& rListeners, const eventtype& e) \
289 eventtype aMulti(e); \
290 aMulti.Source = &m_rParent; \
291 ::cppu::OInterfaceIteratorHelper aIt(rListeners); \
292 while (aIt.hasMoreElements()) \
293 static_cast< listenerclass*>(aIt.next())->methodname(aMulti); \
296 // helper for classes which do property event multiplexing
297 #define IMPLEMENT_PROPERTY_LISTENER_ADMINISTRATION(classname, listenerdesc, multiplexer, braodcasterclass, broadcaster) \
298 void SAL_CALL classname::add##listenerdesc(const OUString& rName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::X##listenerdesc >& l ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception)\
300 multiplexer.addInterface(rName, l); \
301 if (multiplexer.getOverallLen() == 1) \
303 ::com::sun::star::uno::Reference< braodcasterclass > xBroadcaster(broadcaster, ::com::sun::star::uno::UNO_QUERY); \
304 if (xBroadcaster.is()) \
305 xBroadcaster->add##listenerdesc(OUString(), &multiplexer); \
308 void SAL_CALL classname::remove##listenerdesc(const OUString& rName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::X##listenerdesc >& l ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception)\
310 if (multiplexer.getOverallLen() == 1) \
312 ::com::sun::star::uno::Reference< braodcasterclass > xBroadcaster(broadcaster, ::com::sun::star::uno::UNO_QUERY); \
313 if (xBroadcaster.is()) \
314 xBroadcaster->remove##listenerdesc(OUString(), &multiplexer); \
316 multiplexer.removeInterface(rName, l); \
319 #define STOP_PROPERTY_MULTIPLEXER_LISTENING(listenerdesc, multiplexer, braodcasterclass, broadcaster) \
320 if (multiplexer.getOverallLen()) \
322 ::com::sun::star::uno::Reference< braodcasterclass > xBroadcaster(broadcaster, ::com::sun::star::uno::UNO_QUERY); \
323 if (xBroadcaster.is()) \
324 xBroadcaster->remove##listenerdesc(OUString(), &multiplexer); \
327 #define START_PROPERTY_MULTIPLEXER_LISTENING(listenerdesc, multiplexer, braodcasterclass, broadcaster) \
328 if (multiplexer.getOverallLen()) \
330 ::com::sun::star::uno::Reference< braodcasterclass > xBroadcaster(broadcaster, ::com::sun::star::uno::UNO_QUERY); \
331 if (xBroadcaster.is()) \
332 xBroadcaster->add##listenerdesc(OUString(), &multiplexer); \
335 // some listener multiplexers
336 // ::com::sun::star::frame::XStatusListener
337 BEGIN_DECLARE_LISTENER_MULTIPLEXER(SbaXStatusMultiplexer
, ::com::sun::star::frame::XStatusListener
)
338 DECLARE_MULTIPLEXER_VOID_METHOD(statusChanged
, ::com::sun::star::frame::FeatureStateEvent
)
341 ::com::sun::star::frame::FeatureStateEvent m_aLastKnownStatus
;
343 inline ::com::sun::star::frame::FeatureStateEvent
getLastEvent( ) const { return m_aLastKnownStatus
; }
344 END_DECLARE_LISTENER_MULTIPLEXER()
346 // ::com::sun::star::form::XLoadListener
347 BEGIN_DECLARE_LISTENER_MULTIPLEXER(SbaXLoadMultiplexer
, ::com::sun::star::form::XLoadListener
)
348 DECLARE_MULTIPLEXER_VOID_METHOD(loaded
, ::com::sun::star::lang::EventObject
)
349 DECLARE_MULTIPLEXER_VOID_METHOD(unloaded
, ::com::sun::star::lang::EventObject
)
350 DECLARE_MULTIPLEXER_VOID_METHOD(unloading
, ::com::sun::star::lang::EventObject
)
351 DECLARE_MULTIPLEXER_VOID_METHOD(reloading
, ::com::sun::star::lang::EventObject
)
352 DECLARE_MULTIPLEXER_VOID_METHOD(reloaded
, ::com::sun::star::lang::EventObject
)
353 END_DECLARE_LISTENER_MULTIPLEXER()
355 // ::com::sun::star::form::XDatabaseParameterListener
356 BEGIN_DECLARE_LISTENER_MULTIPLEXER(SbaXParameterMultiplexer
, ::com::sun::star::form::XDatabaseParameterListener
)
357 DECLARE_MULTIPLEXER_BOOL_METHOD(approveParameter
, ::com::sun::star::form::DatabaseParameterEvent
)
358 END_DECLARE_LISTENER_MULTIPLEXER()
360 // ::com::sun::star::form::XSubmitListener
361 BEGIN_DECLARE_LISTENER_MULTIPLEXER(SbaXSubmitMultiplexer
, ::com::sun::star::form::XSubmitListener
)
362 DECLARE_MULTIPLEXER_BOOL_METHOD(approveSubmit
, ::com::sun::star::lang::EventObject
)
363 END_DECLARE_LISTENER_MULTIPLEXER()
365 // ::com::sun::star::form::XResetListener
366 BEGIN_DECLARE_LISTENER_MULTIPLEXER(SbaXResetMultiplexer
, ::com::sun::star::form::XResetListener
)
367 DECLARE_MULTIPLEXER_BOOL_METHOD(approveReset
, ::com::sun::star::lang::EventObject
)
368 DECLARE_MULTIPLEXER_VOID_METHOD(resetted
, ::com::sun::star::lang::EventObject
)
369 END_DECLARE_LISTENER_MULTIPLEXER()
371 // ::com::sun::star::sdbc::XRowSetListener
372 BEGIN_DECLARE_LISTENER_MULTIPLEXER(SbaXRowSetMultiplexer
, ::com::sun::star::sdbc::XRowSetListener
)
373 DECLARE_MULTIPLEXER_VOID_METHOD(cursorMoved
, ::com::sun::star::lang::EventObject
)
374 DECLARE_MULTIPLEXER_VOID_METHOD(rowChanged
, ::com::sun::star::lang::EventObject
)
375 DECLARE_MULTIPLEXER_VOID_METHOD(rowSetChanged
, ::com::sun::star::lang::EventObject
)
376 END_DECLARE_LISTENER_MULTIPLEXER()
378 // ::com::sun::star::sdb::XRowSetApproveListener
379 BEGIN_DECLARE_LISTENER_MULTIPLEXER(SbaXRowSetApproveMultiplexer
, ::com::sun::star::sdb::XRowSetApproveListener
)
380 DECLARE_MULTIPLEXER_BOOL_METHOD(approveCursorMove
, ::com::sun::star::lang::EventObject
)
381 DECLARE_MULTIPLEXER_BOOL_METHOD(approveRowChange
, ::com::sun::star::sdb::RowChangeEvent
)
382 DECLARE_MULTIPLEXER_BOOL_METHOD(approveRowSetChange
, ::com::sun::star::lang::EventObject
)
383 END_DECLARE_LISTENER_MULTIPLEXER()
385 // ::com::sun::star::sdb::XSQLErrorListener
386 BEGIN_DECLARE_LISTENER_MULTIPLEXER(SbaXSQLErrorMultiplexer
, ::com::sun::star::sdb::XSQLErrorListener
)
387 DECLARE_MULTIPLEXER_VOID_METHOD(errorOccured
, ::com::sun::star::sdb::SQLErrorEvent
)
388 END_DECLARE_LISTENER_MULTIPLEXER()
390 // ::com::sun::star::beans::XPropertyChangeListener
391 DECLARE_PROPERTY_MULTIPLEXER(SbaXPropertyChangeMultiplexer
, ::com::sun::star::beans::XPropertyChangeListener
, propertyChange
, ::com::sun::star::beans::PropertyChangeEvent
, (::com::sun::star::uno::RuntimeException
, std::exception
))
393 // ::com::sun::star::beans::XVetoableChangeListener
394 DECLARE_PROPERTY_MULTIPLEXER(SbaXVetoableChangeMultiplexer
, ::com::sun::star::beans::XVetoableChangeListener
, vetoableChange
, ::com::sun::star::beans::PropertyChangeEvent
, (::com::sun::star::beans::PropertyVetoException
, ::com::sun::star::uno::RuntimeException
, std::exception
))
396 // ::com::sun::star::beans::XPropertiesChangeListener
397 BEGIN_DECLARE_LISTENER_MULTIPLEXER(SbaXPropertiesChangeMultiplexer
, ::com::sun::star::beans::XPropertiesChangeListener
)
398 DECLARE_MULTIPLEXER_VOID_METHOD(propertiesChange
, ::com::sun::star::uno::Sequence
< ::com::sun::star::beans::PropertyChangeEvent
>)
399 END_DECLARE_LISTENER_MULTIPLEXER()
400 // the SbaXPropertiesChangeMultiplexer doesn't care about the property names a listener logs on for, it simply
401 // forwards _all_ changes to _all_ listeners
404 #endif // _SBA_MULTIPLEXER_HXX
406 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */