summaryrefslogtreecommitdiffstats
path: root/dbaccess/source/ui/inc/sbamultiplex.hxx
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dbaccess/source/ui/inc/sbamultiplex.hxx397
1 files changed, 397 insertions, 0 deletions
diff --git a/dbaccess/source/ui/inc/sbamultiplex.hxx b/dbaccess/source/ui/inc/sbamultiplex.hxx
new file mode 100644
index 000000000..c71c9cbbe
--- /dev/null
+++ b/dbaccess/source/ui/inc/sbamultiplex.hxx
@@ -0,0 +1,397 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_DBACCESS_SOURCE_UI_INC_SBAMULTIPLEX_HXX
+#define INCLUDED_DBACCESS_SOURCE_UI_INC_SBAMULTIPLEX_HXX
+
+#include <com/sun/star/beans/XVetoableChangeListener.hpp>
+#include <com/sun/star/form/XDatabaseParameterListener.hpp>
+#include <com/sun/star/form/XLoadListener.hpp>
+#include <com/sun/star/beans/XPropertiesChangeListener.hpp>
+#include <com/sun/star/beans/XPropertyChangeListener.hpp>
+#include <com/sun/star/form/XSubmitListener.hpp>
+#include <com/sun/star/form/XResetListener.hpp>
+#include <com/sun/star/sdb/XSQLErrorListener.hpp>
+#include <com/sun/star/sdb/XRowSetApproveListener.hpp>
+#include <com/sun/star/sdbc/XRowSetListener.hpp>
+#include <com/sun/star/frame/XStatusListener.hpp>
+#include <comphelper/uno3.hxx>
+#include <cppuhelper/interfacecontainer.hxx>
+#include <comphelper/interfacecontainer2.hxx>
+#include <cppuhelper/queryinterface.hxx>
+#include <cppuhelper/weak.hxx>
+
+namespace dbaui
+{
+ // TODO : replace this class if MM provides a WeakSubObject in cppu
+ class OSbaWeakSubObject : public ::cppu::OWeakObject
+ {
+ protected:
+ ::cppu::OWeakObject& m_rParent;
+
+ public:
+ OSbaWeakSubObject(::cppu::OWeakObject& rParent) : m_rParent(rParent) { }
+
+ virtual void SAL_CALL acquire() throw() override { m_rParent.acquire(); }
+ virtual void SAL_CALL release() throw() override { m_rParent.release(); }
+ };
+
+ // declaration of a listener multiplexer class
+ #define BEGIN_DECLARE_LISTENER_MULTIPLEXER(classname, listenerclass) \
+ class classname \
+ :public OSbaWeakSubObject \
+ ,public listenerclass \
+ ,public ::comphelper::OInterfaceContainerHelper2 \
+ { \
+ public: \
+ classname( ::cppu::OWeakObject& rSource, \
+ ::osl::Mutex& rMutex); \
+ DECLARE_UNO3_DEFAULTS(classname, OSbaWeakSubObject) \
+ virtual css::uno::Any SAL_CALL queryInterface( \
+ const css::uno::Type& _rType) override; \
+ \
+ /* css::lang::XEventListener */ \
+ virtual void SAL_CALL disposing(const css::lang::EventObject& Source) override; \
+
+ #define DECLARE_MULTIPLEXER_VOID_METHOD(methodname, eventtype) \
+ virtual void SAL_CALL methodname(const eventtype& e) override; \
+
+ #define DECLARE_MULTIPLEXER_BOOL_METHOD(methodname, eventtype) \
+ virtual sal_Bool SAL_CALL methodname(const eventtype& e) override; \
+
+ #define END_DECLARE_LISTENER_MULTIPLEXER() \
+ /* resolve ambiguity : both OWeakObject and OInterfaceContainerHelper2 have these memory operators */ \
+ using OSbaWeakSubObject::operator new; \
+ using OSbaWeakSubObject::operator delete; \
+ }; \
+
+ // implementation of a listener multiplexer class
+
+ #define IMPLEMENT_LISTENER_MULTIPLEXER_CORE(classname, listenerclass) \
+ \
+ classname::classname(::cppu::OWeakObject& rSource, ::osl::Mutex& _rMutex) \
+ :OSbaWeakSubObject(rSource) \
+ ,OInterfaceContainerHelper2(_rMutex) \
+ { \
+ } \
+ \
+ css::uno::Any SAL_CALL classname::queryInterface( \
+ const css::uno::Type& _rType) \
+ { \
+ css::uno::Any aReturn = \
+ OSbaWeakSubObject::queryInterface(_rType); \
+ if (!aReturn.hasValue()) \
+ aReturn = ::cppu::queryInterface(_rType, \
+ static_cast< listenerclass* >(this), \
+ static_cast< css::lang::XEventListener* >(static_cast< listenerclass* >(this)) \
+ ); \
+ \
+ return aReturn; \
+ } \
+ void SAL_CALL classname::disposing(const css::lang::EventObject& )\
+ { \
+ } \
+
+ #define IMPLEMENT_LISTENER_MULTIPLEXER_VOID_METHOD(classname, listenerclass, methodname, eventtype) \
+ void SAL_CALL classname::methodname(const eventtype& e) \
+ { \
+ eventtype aMulti(e); \
+ aMulti.Source = &m_rParent; \
+ ::comphelper::OInterfaceIteratorHelper2 aIt(*this); \
+ while (aIt.hasMoreElements()) \
+ static_cast< listenerclass*>(aIt.next())->methodname(aMulti); \
+ } \
+
+ #define IMPLEMENT_LISTENER_MULTIPLEXER_BOOL_METHOD(classname, listenerclass, methodname, eventtype) \
+ sal_Bool SAL_CALL classname::methodname(const eventtype& e) \
+ { \
+ eventtype aMulti(e); \
+ aMulti.Source = &m_rParent; \
+ ::comphelper::OInterfaceIteratorHelper2 aIt(*this); \
+ bool bResult = true; \
+ while (bResult && aIt.hasMoreElements()) \
+ bResult = static_cast< listenerclass*>(aIt.next())->methodname(aMulti); \
+ return bResult; \
+ } \
+
+ // helper for classes which do event multiplexing
+ #define IMPLEMENT_LISTENER_ADMINISTRATION(classname, listenernamespace, listenerdesc, multiplexer, broadcasterclass, broadcaster) \
+ void SAL_CALL classname::add##listenerdesc(const css::uno::Reference< css::listenernamespace::X##listenerdesc >& l)\
+ { \
+ multiplexer.addInterface(l); \
+ if (multiplexer.getLength() == 1) \
+ { \
+ css::uno::Reference< broadcasterclass > xBroadcaster(broadcaster, css::uno::UNO_QUERY); \
+ if (xBroadcaster.is()) \
+ xBroadcaster->add##listenerdesc(&multiplexer); \
+ } \
+ } \
+ void SAL_CALL classname::remove##listenerdesc(const css::uno::Reference< css::listenernamespace::X##listenerdesc >& l)\
+ { \
+ if (multiplexer.getLength() == 1) \
+ { \
+ css::uno::Reference< broadcasterclass > xBroadcaster(broadcaster, css::uno::UNO_QUERY); \
+ if (xBroadcaster.is()) \
+ xBroadcaster->remove##listenerdesc(&multiplexer); \
+ } \
+ multiplexer.removeInterface(l); \
+ } \
+
+ #define STOP_MULTIPLEXER_LISTENING(listenerdesc, multiplexer, broadcasterclass, broadcaster) \
+ if (multiplexer.getLength()) \
+ { \
+ css::uno::Reference< broadcasterclass > xBroadcaster(broadcaster, css::uno::UNO_QUERY); \
+ if (xBroadcaster.is()) \
+ xBroadcaster->remove##listenerdesc(&multiplexer); \
+ } \
+
+ #define START_MULTIPLEXER_LISTENING(listenerdesc, multiplexer, broadcasterclass, broadcaster) \
+ if (multiplexer.getLength()) \
+ { \
+ css::uno::Reference< broadcasterclass > xBroadcaster(broadcaster, css::uno::UNO_QUERY); \
+ if (xBroadcaster.is()) \
+ xBroadcaster->add##listenerdesc(&multiplexer); \
+ } \
+
+ // declaration of property listener multiplexers
+ // (with support for specialized and unspecialized property listeners)
+
+ #define DECLARE_PROPERTY_MULTIPLEXER(classname, listenerclass, methodname, eventtype) \
+ class classname final \
+ :public OSbaWeakSubObject \
+ ,public listenerclass \
+ { \
+ typedef ::cppu::OMultiTypeInterfaceContainerHelperVar< \
+ OUString > ListenerContainerMap; \
+ ListenerContainerMap m_aListeners; \
+ \
+ public: \
+ classname( ::cppu::OWeakObject& rSource, ::osl::Mutex& rMutex ); \
+ DECLARE_UNO3_DEFAULTS(classname, OSbaWeakSubObject) \
+ virtual css::uno::Any SAL_CALL queryInterface( \
+ const css::uno::Type& _rType) override; \
+ \
+ /* css::lang::XEventListener */ \
+ virtual void SAL_CALL disposing(const css::lang::EventObject& Source) override; \
+ \
+ virtual void SAL_CALL methodname(const eventtype& e) override; \
+ \
+ void addInterface(const OUString& rName, const css::uno::Reference< css::uno::XInterface >& rListener); \
+ void removeInterface(const OUString& rName, const css::uno::Reference< css::uno::XInterface >& rListener); \
+ \
+ void disposeAndClear(); \
+ \
+ sal_Int32 getOverallLen() const; \
+ \
+ ::cppu::OInterfaceContainerHelper* getContainer(const OUString& rName) \
+ { return m_aListeners.getContainer(rName); } \
+ \
+ private: \
+ void Notify(::cppu::OInterfaceContainerHelper& rListeners, const eventtype& e); \
+ }; \
+
+ // implementation of property listener multiplexers
+ #define IMPLEMENT_PROPERTY_MULTIPLEXER(classname, listenerclass, methodname, eventtype) \
+ classname::classname(::cppu::OWeakObject& rSource, ::osl::Mutex& rMutex) \
+ :OSbaWeakSubObject(rSource) \
+ ,m_aListeners(rMutex) \
+ { \
+ } \
+ \
+ css::uno::Any SAL_CALL classname::queryInterface( \
+ const css::uno::Type& _rType) \
+ { \
+ css::uno::Any aReturn = \
+ OSbaWeakSubObject::queryInterface(_rType); \
+ if (!aReturn.hasValue()) \
+ aReturn = ::cppu::queryInterface(_rType, \
+ static_cast< listenerclass* >(this), \
+ static_cast< css::lang::XEventListener* >(static_cast< listenerclass* >(this)) \
+ ); \
+ \
+ return aReturn; \
+ } \
+ void SAL_CALL classname::disposing(const css::lang::EventObject& )\
+ { \
+ } \
+ \
+ void SAL_CALL classname::methodname(const eventtype& e) \
+ { \
+ ::cppu::OInterfaceContainerHelper* pListeners = m_aListeners.getContainer(e.PropertyName); \
+ if (pListeners) \
+ Notify(*pListeners, e); \
+ \
+ /* do the notification for the unspecialized listeners, too */ \
+ pListeners = m_aListeners.getContainer(OUString()); \
+ if (pListeners) \
+ Notify(*pListeners, e); \
+ } \
+ \
+ void classname::addInterface(const OUString& rName, \
+ const css::uno::Reference< css::uno::XInterface > & rListener) \
+ { \
+ m_aListeners.addInterface(rName, rListener); \
+ } \
+ \
+ void classname::removeInterface(const OUString& rName, \
+ const css::uno::Reference< css::uno::XInterface > & rListener) \
+ { \
+ m_aListeners.removeInterface(rName, rListener); \
+ } \
+ \
+ void classname::disposeAndClear() \
+ { \
+ css::lang::EventObject aEvt(m_rParent); \
+ m_aListeners.disposeAndClear(aEvt); \
+ } \
+ \
+ sal_Int32 classname::getOverallLen() const \
+ { \
+ sal_Int32 nLen = 0; \
+ const css::uno::Sequence< OUString > aContained = m_aListeners.getContainedTypes(); \
+ for ( OUString const & s : aContained) \
+ { \
+ ::cppu::OInterfaceContainerHelper* pListeners = m_aListeners.getContainer(s); \
+ if (!pListeners) \
+ continue; \
+ nLen += pListeners->getLength(); \
+ } \
+ return nLen; \
+ } \
+ \
+ void classname::Notify(::cppu::OInterfaceContainerHelper& rListeners, const eventtype& e) \
+ { \
+ eventtype aMulti(e); \
+ aMulti.Source = &m_rParent; \
+ ::cppu::OInterfaceIteratorHelper aIt(rListeners); \
+ while (aIt.hasMoreElements()) \
+ static_cast< listenerclass*>(aIt.next())->methodname(aMulti); \
+ } \
+
+ // helper for classes which do property event multiplexing
+ #define IMPLEMENT_PROPERTY_LISTENER_ADMINISTRATION(classname, listenerdesc, multiplexer, broadcasterclass, broadcaster) \
+ void SAL_CALL classname::add##listenerdesc(const OUString& rName, const css::uno::Reference< css::beans::X##listenerdesc >& l )\
+ { \
+ multiplexer.addInterface(rName, l); \
+ if (multiplexer.getOverallLen() == 1) \
+ { \
+ css::uno::Reference< broadcasterclass > xBroadcaster(broadcaster, css::uno::UNO_QUERY); \
+ if (xBroadcaster.is()) \
+ xBroadcaster->add##listenerdesc(OUString(), &multiplexer); \
+ } \
+ } \
+ void SAL_CALL classname::remove##listenerdesc(const OUString& rName, const css::uno::Reference< css::beans::X##listenerdesc >& l )\
+ { \
+ if (multiplexer.getOverallLen() == 1) \
+ { \
+ css::uno::Reference< broadcasterclass > xBroadcaster(broadcaster, css::uno::UNO_QUERY); \
+ if (xBroadcaster.is()) \
+ xBroadcaster->remove##listenerdesc(OUString(), &multiplexer); \
+ } \
+ multiplexer.removeInterface(rName, l); \
+ } \
+
+ #define STOP_PROPERTY_MULTIPLEXER_LISTENING(listenerdesc, multiplexer, broadcasterclass, broadcaster) \
+ if (multiplexer.getOverallLen()) \
+ { \
+ css::uno::Reference< broadcasterclass > xBroadcaster(broadcaster, css::uno::UNO_QUERY); \
+ if (xBroadcaster.is()) \
+ xBroadcaster->remove##listenerdesc(OUString(), &multiplexer); \
+ } \
+
+ #define START_PROPERTY_MULTIPLEXER_LISTENING(listenerdesc, multiplexer, broadcasterclass, broadcaster) \
+ if (multiplexer.getOverallLen()) \
+ { \
+ css::uno::Reference< broadcasterclass > xBroadcaster(broadcaster, css::uno::UNO_QUERY); \
+ if (xBroadcaster.is()) \
+ xBroadcaster->add##listenerdesc(OUString(), &multiplexer); \
+ } \
+
+ // some listener multiplexers
+ // css::frame::XStatusListener
+ BEGIN_DECLARE_LISTENER_MULTIPLEXER(SbaXStatusMultiplexer, css::frame::XStatusListener)
+ DECLARE_MULTIPLEXER_VOID_METHOD(statusChanged, css::frame::FeatureStateEvent)
+
+ private:
+ css::frame::FeatureStateEvent m_aLastKnownStatus;
+ public: \
+ const css::frame::FeatureStateEvent& getLastEvent( ) const { return m_aLastKnownStatus; }
+ END_DECLARE_LISTENER_MULTIPLEXER()
+
+ // css::form::XLoadListener
+ BEGIN_DECLARE_LISTENER_MULTIPLEXER(SbaXLoadMultiplexer, css::form::XLoadListener)
+ DECLARE_MULTIPLEXER_VOID_METHOD(loaded, css::lang::EventObject)
+ DECLARE_MULTIPLEXER_VOID_METHOD(unloaded, css::lang::EventObject)
+ DECLARE_MULTIPLEXER_VOID_METHOD(unloading, css::lang::EventObject)
+ DECLARE_MULTIPLEXER_VOID_METHOD(reloading, css::lang::EventObject)
+ DECLARE_MULTIPLEXER_VOID_METHOD(reloaded, css::lang::EventObject)
+ END_DECLARE_LISTENER_MULTIPLEXER()
+
+ // css::form::XDatabaseParameterListener
+ BEGIN_DECLARE_LISTENER_MULTIPLEXER(SbaXParameterMultiplexer, css::form::XDatabaseParameterListener)
+ DECLARE_MULTIPLEXER_BOOL_METHOD(approveParameter, css::form::DatabaseParameterEvent)
+ END_DECLARE_LISTENER_MULTIPLEXER()
+
+ // css::form::XSubmitListener
+ BEGIN_DECLARE_LISTENER_MULTIPLEXER(SbaXSubmitMultiplexer, css::form::XSubmitListener)
+ DECLARE_MULTIPLEXER_BOOL_METHOD(approveSubmit, css::lang::EventObject)
+ END_DECLARE_LISTENER_MULTIPLEXER()
+
+ // css::form::XResetListener
+ BEGIN_DECLARE_LISTENER_MULTIPLEXER(SbaXResetMultiplexer, css::form::XResetListener)
+ DECLARE_MULTIPLEXER_BOOL_METHOD(approveReset, css::lang::EventObject)
+ DECLARE_MULTIPLEXER_VOID_METHOD(resetted, css::lang::EventObject)
+ END_DECLARE_LISTENER_MULTIPLEXER()
+
+ // css::sdbc::XRowSetListener
+ BEGIN_DECLARE_LISTENER_MULTIPLEXER(SbaXRowSetMultiplexer, css::sdbc::XRowSetListener)
+ DECLARE_MULTIPLEXER_VOID_METHOD(cursorMoved, css::lang::EventObject)
+ DECLARE_MULTIPLEXER_VOID_METHOD(rowChanged, css::lang::EventObject)
+ DECLARE_MULTIPLEXER_VOID_METHOD(rowSetChanged, css::lang::EventObject)
+ END_DECLARE_LISTENER_MULTIPLEXER()
+
+ // css::sdb::XRowSetApproveListener
+ BEGIN_DECLARE_LISTENER_MULTIPLEXER(SbaXRowSetApproveMultiplexer, css::sdb::XRowSetApproveListener)
+ DECLARE_MULTIPLEXER_BOOL_METHOD(approveCursorMove, css::lang::EventObject)
+ DECLARE_MULTIPLEXER_BOOL_METHOD(approveRowChange, css::sdb::RowChangeEvent)
+ DECLARE_MULTIPLEXER_BOOL_METHOD(approveRowSetChange, css::lang::EventObject)
+ END_DECLARE_LISTENER_MULTIPLEXER()
+
+ // css::sdb::XSQLErrorListener
+ BEGIN_DECLARE_LISTENER_MULTIPLEXER(SbaXSQLErrorMultiplexer, css::sdb::XSQLErrorListener)
+ DECLARE_MULTIPLEXER_VOID_METHOD(errorOccured, css::sdb::SQLErrorEvent)
+ END_DECLARE_LISTENER_MULTIPLEXER()
+
+ // css::beans::XPropertyChangeListener
+ DECLARE_PROPERTY_MULTIPLEXER(SbaXPropertyChangeMultiplexer, css::beans::XPropertyChangeListener, propertyChange, css::beans::PropertyChangeEvent)
+
+ // css::beans::XVetoableChangeListener
+ DECLARE_PROPERTY_MULTIPLEXER(SbaXVetoableChangeMultiplexer, css::beans::XVetoableChangeListener, vetoableChange, css::beans::PropertyChangeEvent)
+
+ // css::beans::XPropertiesChangeListener
+ BEGIN_DECLARE_LISTENER_MULTIPLEXER(SbaXPropertiesChangeMultiplexer, css::beans::XPropertiesChangeListener)
+ DECLARE_MULTIPLEXER_VOID_METHOD(propertiesChange, css::uno::Sequence< css::beans::PropertyChangeEvent >)
+ END_DECLARE_LISTENER_MULTIPLEXER()
+ // the SbaXPropertiesChangeMultiplexer doesn't care about the property names a listener logs on for, it simply
+ // forwards _all_ changes to _all_ listeners
+}
+
+#endif // _SBA_MULTIPLEXER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */