UnoControls/inc/multiplexer.hxx | 138 ++++++++++++++--------- UnoControls/source/base/basecontrol.cxx | 24 ++-- UnoControls/source/base/multiplexer.cxx | 190 ++------------------------------ 3 files changed, 110 insertions(+), 242 deletions(-)
New commits: commit dcd7be141f6f7f55b9fbf583a014b3add4d08dfe Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Sat Nov 9 19:50:21 2024 +0500 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Sat Nov 9 19:33:09 2024 +0100 XTopWindowListener is unused here Change-Id: Ib4c1464d709c41f019d1910000e71075c9f5e037 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176310 Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> Tested-by: Jenkins diff --git a/UnoControls/inc/multiplexer.hxx b/UnoControls/inc/multiplexer.hxx index c321a4644b69..f5f02b0abebb 100644 --- a/UnoControls/inc/multiplexer.hxx +++ b/UnoControls/inc/multiplexer.hxx @@ -24,8 +24,6 @@ #include <com/sun/star/awt/XMouseMotionListener.hpp> #include <com/sun/star/awt/XWindow.hpp> #include <com/sun/star/awt/XWindowListener.hpp> -#include <com/sun/star/awt/XTopWindow.hpp> -#include <com/sun/star/awt/XTopWindowListener.hpp> #include <com/sun/star/awt/XMouseListener.hpp> #include <com/sun/star/awt/XFocusListener.hpp> #include <comphelper/compbase.hxx> @@ -57,9 +55,6 @@ template <> constexpr inline auto Remove<css::awt::XMouseMotionListener> = &css: template <> constexpr inline auto Add<css::awt::XPaintListener> = &css::awt::XWindow::addPaintListener; template <> constexpr inline auto Remove<css::awt::XPaintListener> = &css::awt::XWindow::removePaintListener; -template <> constexpr inline auto Add<css::awt::XTopWindowListener> = &css::awt::XTopWindow::addTopWindowListener; -template <> constexpr inline auto Remove<css::awt::XTopWindowListener> = &css::awt::XTopWindow::removeTopWindowListener; - template <class Ifc> class Listeners { protected: @@ -72,17 +67,12 @@ class ContainersHolder : public comphelper::WeakImplHelper<Ifc...>, public Liste protected: template <typename F> void for_each_container(F f) { (..., f(Listeners<Ifc>::list)); } - template <class WinIfc, class Ifc1> + template <class Ifc1> void notifyPeer(const css::uno::Reference<css::awt::XWindow>& peer, - void (SAL_CALL WinIfc::*func)(const css::uno::Reference<Ifc1>&)) + void (SAL_CALL css::awt::XWindow::*func)(const css::uno::Reference<Ifc1>&)) { - if constexpr (std::is_same_v<WinIfc, css::awt::XWindow>) - { - if (peer) - (peer.get()->*func)(this); - } - else if (auto cast_peer = peer.query<WinIfc>()) - (cast_peer.get()->*func)(this); + if (peer) + (peer.get()->*func)(this); } template <class Ifc1> @@ -114,8 +104,7 @@ class OMRCListenerMultiplexerHelper final : public ContainersHolder< css::awt::X , css::awt::XKeyListener , css::awt::XMouseListener , css::awt::XMouseMotionListener - , css::awt::XPaintListener - , css::awt::XTopWindowListener > + , css::awt::XPaintListener > { public: @@ -214,22 +203,6 @@ public: virtual void SAL_CALL windowPaint(const css::awt::PaintEvent& aEvent ) override; - // XTopWindowListener - - virtual void SAL_CALL windowOpened( const css::lang::EventObject& aEvent ) override; - - virtual void SAL_CALL windowClosing( const css::lang::EventObject& aEvent ) override; - - virtual void SAL_CALL windowClosed( const css::lang::EventObject& aEvent ) override; - - virtual void SAL_CALL windowMinimized( const css::lang::EventObject& aEvent ) override; - - virtual void SAL_CALL windowNormalized( const css::lang::EventObject& aEvent ) override; - - virtual void SAL_CALL windowActivated( const css::lang::EventObject& aEvent ) override; - - virtual void SAL_CALL windowDeactivated( const css::lang::EventObject& aEvent ) override; - private: template <class Interface, typename Event> void Multiplex(void (SAL_CALL Interface::*method)(const Event&), const Event& event); diff --git a/UnoControls/source/base/multiplexer.cxx b/UnoControls/source/base/multiplexer.cxx index 158a1f82dfb6..12d3b12d721f 100644 --- a/UnoControls/source/base/multiplexer.cxx +++ b/UnoControls/source/base/multiplexer.cxx @@ -211,55 +211,6 @@ void OMRCListenerMultiplexerHelper::windowPaint(const PaintEvent& aEvent) Multiplex(&XPaintListener::windowPaint, aEvent); } -// XTopWindowListener - -void OMRCListenerMultiplexerHelper::windowOpened(const EventObject& aEvent) -{ - Multiplex(&XTopWindowListener::windowOpened, aEvent); -} - -// XTopWindowListener - -void OMRCListenerMultiplexerHelper::windowClosing( const EventObject& aEvent ) -{ - Multiplex(&XTopWindowListener::windowClosing, aEvent); -} - -// XTopWindowListener - -void OMRCListenerMultiplexerHelper::windowClosed( const EventObject& aEvent ) -{ - Multiplex(&XTopWindowListener::windowClosed, aEvent); -} - -// XTopWindowListener - -void OMRCListenerMultiplexerHelper::windowMinimized( const EventObject& aEvent ) -{ - Multiplex(&XTopWindowListener::windowMinimized, aEvent); -} - -// XTopWindowListener - -void OMRCListenerMultiplexerHelper::windowNormalized( const EventObject& aEvent ) -{ - Multiplex(&XTopWindowListener::windowNormalized, aEvent); -} - -// XTopWindowListener - -void OMRCListenerMultiplexerHelper::windowActivated( const EventObject& aEvent ) -{ - Multiplex(&XTopWindowListener::windowActivated, aEvent); -} - -// XTopWindowListener - -void OMRCListenerMultiplexerHelper::windowDeactivated( const EventObject& aEvent ) -{ - Multiplex(&XTopWindowListener::windowDeactivated, aEvent); -} - } // namespace unocontrols /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit ce310aa33ad2c13776298b3b0ec282c098262aa9 Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Sat Nov 9 16:31:55 2024 +0500 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Sat Nov 9 19:33:03 2024 +0100 Use OInterfaceContainerHelper4 per listener class for type safety Change-Id: I919fef7e981d2dbdd69eb3cce34b3236dd6ed7ad Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176309 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> diff --git a/UnoControls/inc/multiplexer.hxx b/UnoControls/inc/multiplexer.hxx index 095e316797e8..c321a4644b69 100644 --- a/UnoControls/inc/multiplexer.hxx +++ b/UnoControls/inc/multiplexer.hxx @@ -22,29 +22,100 @@ #include <com/sun/star/awt/XKeyListener.hpp> #include <com/sun/star/awt/XPaintListener.hpp> #include <com/sun/star/awt/XMouseMotionListener.hpp> +#include <com/sun/star/awt/XWindow.hpp> #include <com/sun/star/awt/XWindowListener.hpp> +#include <com/sun/star/awt/XTopWindow.hpp> #include <com/sun/star/awt/XTopWindowListener.hpp> #include <com/sun/star/awt/XMouseListener.hpp> #include <com/sun/star/awt/XFocusListener.hpp> #include <comphelper/compbase.hxx> +#include <comphelper/interfacecontainer4.hxx> #include <cppuhelper/weakref.hxx> -#include <comphelper/multiinterfacecontainer4.hxx> -namespace com::sun::star::awt { class XWindow; } -namespace com::sun::star::awt { struct KeyEvent; } -namespace com::sun::star::awt { struct MouseEvent; } -namespace com::sun::star::awt { struct PaintEvent; } -namespace com::sun::star::awt { struct WindowEvent; } +#include <type_traits> namespace unocontrols { -class OMRCListenerMultiplexerHelper final : public comphelper::WeakImplHelper< css::awt::XFocusListener - , css::awt::XWindowListener - , css::awt::XKeyListener - , css::awt::XMouseListener - , css::awt::XMouseMotionListener - , css::awt::XPaintListener - , css::awt::XTopWindowListener > +template <class Listener> extern int Add; // dummy +template <class Listener> extern int Remove; // dummy + +template <> constexpr inline auto Add<css::awt::XFocusListener> = &css::awt::XWindow::addFocusListener; +template <> constexpr inline auto Remove<css::awt::XFocusListener> = &css::awt::XWindow::removeFocusListener; + +template <> constexpr inline auto Add<css::awt::XWindowListener> = &css::awt::XWindow::addWindowListener; +template <> constexpr inline auto Remove<css::awt::XWindowListener> = &css::awt::XWindow::removeWindowListener; + +template <> constexpr inline auto Add<css::awt::XKeyListener> = &css::awt::XWindow::addKeyListener; +template <> constexpr inline auto Remove<css::awt::XKeyListener> = &css::awt::XWindow::removeKeyListener; + +template <> constexpr inline auto Add<css::awt::XMouseListener> = &css::awt::XWindow::addMouseListener; +template <> constexpr inline auto Remove<css::awt::XMouseListener> = &css::awt::XWindow::removeMouseListener; + +template <> constexpr inline auto Add<css::awt::XMouseMotionListener> = &css::awt::XWindow::addMouseMotionListener; +template <> constexpr inline auto Remove<css::awt::XMouseMotionListener> = &css::awt::XWindow::removeMouseMotionListener; + +template <> constexpr inline auto Add<css::awt::XPaintListener> = &css::awt::XWindow::addPaintListener; +template <> constexpr inline auto Remove<css::awt::XPaintListener> = &css::awt::XWindow::removePaintListener; + +template <> constexpr inline auto Add<css::awt::XTopWindowListener> = &css::awt::XTopWindow::addTopWindowListener; +template <> constexpr inline auto Remove<css::awt::XTopWindowListener> = &css::awt::XTopWindow::removeTopWindowListener; + +template <class Ifc> class Listeners +{ +protected: + comphelper::OInterfaceContainerHelper4<Ifc> list; +}; + +template <class... Ifc> +class ContainersHolder : public comphelper::WeakImplHelper<Ifc...>, public Listeners<Ifc>... +{ +protected: + template <typename F> void for_each_container(F f) { (..., f(Listeners<Ifc>::list)); } + + template <class WinIfc, class Ifc1> + void notifyPeer(const css::uno::Reference<css::awt::XWindow>& peer, + void (SAL_CALL WinIfc::*func)(const css::uno::Reference<Ifc1>&)) + { + if constexpr (std::is_same_v<WinIfc, css::awt::XWindow>) + { + if (peer) + (peer.get()->*func)(this); + } + else if (auto cast_peer = peer.query<WinIfc>()) + (cast_peer.get()->*func)(this); + } + + template <class Ifc1> + void add(std::unique_lock<std::mutex>& guard, const css::uno::Reference<Ifc1>& listener, + const css::uno::Reference<css::awt::XWindow>& peer) + { + assert(listener); + if (Listeners<Ifc1>::list.addInterface(guard, listener) == 1) + { + // the first listener is added + notifyPeer(peer, Add<Ifc1>); + } + } + + template <class Ifc1> + void remove(std::unique_lock<std::mutex>& guard, const css::uno::Reference<Ifc1>& listener, + const css::uno::Reference<css::awt::XWindow>& peer) + { + if (Listeners<Ifc1>::list.removeInterface(guard, listener) == 0) + { + // the last listener is removed + notifyPeer(peer, Remove<Ifc1>); + } + } +}; + +class OMRCListenerMultiplexerHelper final : public ContainersHolder< css::awt::XFocusListener + , css::awt::XWindowListener + , css::awt::XKeyListener + , css::awt::XMouseListener + , css::awt::XMouseMotionListener + , css::awt::XPaintListener + , css::awt::XTopWindowListener > { public: @@ -81,15 +152,21 @@ public: @short Add the specified listener to the source. */ - void advise( const css::uno::Type& aType , - const css::uno::Reference< css::lang::XEventListener >& xListener ); + template <class Interface> void advise(const css::uno::Reference<Interface>& xListener) + { + std::unique_lock aGuard(m_aMutex); + add(aGuard, xListener, m_xPeer); + } /** @short Remove the specified listener from the source. */ - void unadvise( const css::uno::Type& aType , - const css::uno::Reference< css::lang::XEventListener >& xListener ); + template <class Interface> void unadvise(const css::uno::Reference<Interface>& xListener) + { + std::unique_lock aGuard(m_aMutex); + remove(aGuard, xListener, m_xPeer); + } // XEventListener @@ -154,25 +231,6 @@ public: virtual void SAL_CALL windowDeactivated( const css::lang::EventObject& aEvent ) override; private: - - /** - @short Remove the listener from the peer. - @param xPeer The peer from which the listener is removed. - @param rType The listener type, which specify the type of the listener. - */ - - void impl_adviseToPeer( const css::uno::Reference< css::awt::XWindow >& xPeer , - const css::uno::Type& aType ); - - /** - @short Add the listener to the peer. - @param xPeer The peer to which the listener is added. - @param rType The listener type, which specify the type of the listener. - */ - - void impl_unadviseFromPeer( const css::uno::Reference< css::awt::XWindow >& xPeer , - const css::uno::Type& aType ); - template <class Interface, typename Event> void Multiplex(void (SAL_CALL Interface::*method)(const Event&), const Event& event); @@ -181,7 +239,6 @@ private: private: css::uno::Reference< css::awt::XWindow > m_xPeer; /// The source of the events. Normally this is the peer object. css::uno::WeakReference< css::awt::XWindow > m_xControl; - comphelper::OMultiTypeInterfaceContainerHelperVar4<css::uno::Type, css::lang::XEventListener> m_aListenerHolder; }; } diff --git a/UnoControls/source/base/basecontrol.cxx b/UnoControls/source/base/basecontrol.cxx index 9f84547fe510..247142e5c151 100644 --- a/UnoControls/source/base/basecontrol.cxx +++ b/UnoControls/source/base/basecontrol.cxx @@ -442,84 +442,84 @@ Rectangle SAL_CALL BaseControl::getPosSize() void SAL_CALL BaseControl::addWindowListener( const Reference< XWindowListener >& xListener ) { - impl_getMultiplexer()->advise( cppu::UnoType<XWindowListener>::get(), xListener ); + impl_getMultiplexer()->advise(xListener); } // XWindow void SAL_CALL BaseControl::addFocusListener( const Reference< XFocusListener >& xListener ) { - impl_getMultiplexer()->advise( cppu::UnoType<XFocusListener>::get(), xListener ); + impl_getMultiplexer()->advise(xListener); } // XWindow void SAL_CALL BaseControl::addKeyListener( const Reference< XKeyListener >& xListener ) { - impl_getMultiplexer()->advise( cppu::UnoType<XKeyListener>::get(), xListener ); + impl_getMultiplexer()->advise(xListener); } // XWindow void SAL_CALL BaseControl::addMouseListener( const Reference< XMouseListener >& xListener ) { - impl_getMultiplexer()->advise( cppu::UnoType<XMouseListener>::get(), xListener ); + impl_getMultiplexer()->advise(xListener); } // XWindow void SAL_CALL BaseControl::addMouseMotionListener( const Reference< XMouseMotionListener >& xListener ) { - impl_getMultiplexer()->advise( cppu::UnoType<XMouseMotionListener>::get(), xListener ); + impl_getMultiplexer()->advise(xListener); } // XWindow void SAL_CALL BaseControl::addPaintListener( const Reference< XPaintListener >& xListener ) { - impl_getMultiplexer()->advise( cppu::UnoType<XPaintListener>::get(), xListener ); + impl_getMultiplexer()->advise(xListener); } // XWindow void SAL_CALL BaseControl::removeWindowListener( const Reference< XWindowListener >& xListener ) { - impl_getMultiplexer()->unadvise( cppu::UnoType<XWindowListener>::get(), xListener ); + impl_getMultiplexer()->unadvise(xListener); } // XWindow void SAL_CALL BaseControl::removeFocusListener( const Reference< XFocusListener >& xListener ) { - impl_getMultiplexer()->unadvise( cppu::UnoType<XFocusListener>::get(), xListener ); + impl_getMultiplexer()->unadvise(xListener); } // XWindow void SAL_CALL BaseControl::removeKeyListener( const Reference< XKeyListener >& xListener ) { - impl_getMultiplexer()->unadvise( cppu::UnoType<XKeyListener>::get(), xListener ); + impl_getMultiplexer()->unadvise(xListener); } // XWindow void SAL_CALL BaseControl::removeMouseListener( const Reference< XMouseListener >& xListener ) { - impl_getMultiplexer()->unadvise( cppu::UnoType<XMouseListener>::get(), xListener ); + impl_getMultiplexer()->unadvise(xListener); } // XWindow void SAL_CALL BaseControl::removeMouseMotionListener( const Reference< XMouseMotionListener >& xListener ) { - impl_getMultiplexer()->unadvise( cppu::UnoType<XMouseMotionListener>::get(), xListener ); + impl_getMultiplexer()->unadvise(xListener); } // XWindow void SAL_CALL BaseControl::removePaintListener( const Reference< XPaintListener >& xListener ) { - impl_getMultiplexer()->unadvise( cppu::UnoType<XPaintListener>::get(), xListener ); + impl_getMultiplexer()->unadvise(xListener); } // XView diff --git a/UnoControls/source/base/multiplexer.cxx b/UnoControls/source/base/multiplexer.cxx index ec53697276e3..158a1f82dfb6 100644 --- a/UnoControls/source/base/multiplexer.cxx +++ b/UnoControls/source/base/multiplexer.cxx @@ -22,9 +22,6 @@ #include <osl/diagnose.h> #include <cppuhelper/queryinterface.hxx> -#include <com/sun/star/awt/XWindow.hpp> -#include <com/sun/star/awt/XTopWindow.hpp> - using namespace ::cppu; using namespace ::osl; using namespace ::com::sun::star::uno; @@ -38,33 +35,14 @@ void OMRCListenerMultiplexerHelper::Multiplex(void (SAL_CALL Interface::*method) const Event& event) { std::unique_lock aGuard(m_aMutex); - /* First get all interfaces from container with right type.*/ - auto* pContainer = m_aListenerHolder.getContainer(aGuard, cppu::UnoType<Interface>::get()); - /* Do the follow only, if elements in container exist.*/ - if (!pContainer) - return; - comphelper::OInterfaceIteratorHelper4 aIterator(aGuard, *pContainer); Event aLocalEvent = event; /* Remark: The control is the event source not the peer.*/ /* We must change the source of the event. */ aLocalEvent.Source = m_xControl; - aGuard.unlock(); /* Is the control not destroyed? */ if (!aLocalEvent.Source) return; - while (aIterator.hasMoreElements()) - { - auto* pListener = aIterator.next().get(); - assert(dynamic_cast<Interface*>(pListener)); - try - { - (static_cast<Interface*>(pListener)->*method)(aLocalEvent); - } - catch (const RuntimeException&) - { - /* Ignore all system exceptions from the listener! */ - } - } + Listeners<Interface>::list.notifyEach(aGuard, method, aLocalEvent); } // construct/destruct @@ -90,20 +68,22 @@ void OMRCListenerMultiplexerHelper::setPeer( const Reference< XWindow >& xPeer ) if( m_xPeer.is() ) { - // get all types from the listener added to the peer - const std::vector< Type > aContainedTypes = m_aListenerHolder.getContainedTypes(aGuard); - // loop over all listener types and remove the listeners from the peer - for( const auto& rContainedType : aContainedTypes ) - impl_unadviseFromPeer( m_xPeer, rContainedType ); + for_each_container( + [this, &aGuard]<class Ifc>(const comphelper::OInterfaceContainerHelper4<Ifc>& c) + { + if (c.getLength(aGuard) > 0) + notifyPeer(m_xPeer, Remove<Ifc>); + }); } m_xPeer = xPeer; if( m_xPeer.is() ) { - // get all types from the listener added to the peer - const std::vector< Type > aContainedTypes = m_aListenerHolder.getContainedTypes(aGuard); - // loop over all listener types and add the listeners to the peer - for( const auto& rContainedType : aContainedTypes ) - impl_adviseToPeer( m_xPeer, rContainedType ); + for_each_container( + [this, &aGuard]<class Ifc>(const comphelper::OInterfaceContainerHelper4<Ifc>& c) + { + if (c.getLength(aGuard) > 0) + notifyPeer(m_xPeer, Add<Ifc>); + }); } } @@ -114,40 +94,7 @@ void OMRCListenerMultiplexerHelper::disposeAndClear() std::unique_lock aGuard(m_aMutex); EventObject aEvent; aEvent.Source = m_xControl; - m_aListenerHolder.disposeAndClear(aGuard, aEvent); -} - -// container method - -void OMRCListenerMultiplexerHelper::advise( const Type& aType , - const Reference< XEventListener >& xListener ) -{ - assert(xListener && xListener->queryInterface(aType).getValue()); - std::unique_lock aGuard(m_aMutex); - if (m_aListenerHolder.addInterface(aGuard, aType, xListener) == 1) - { - // the first listener is added - if( m_xPeer.is() ) - { - impl_adviseToPeer( m_xPeer, aType ); - } - } -} - -// container method - -void OMRCListenerMultiplexerHelper::unadvise( const Type& aType , - const Reference< XEventListener >& xListener ) -{ - std::unique_lock aGuard(m_aMutex); - if (m_aListenerHolder.removeInterface(aGuard, aType, xListener) == 0) - { - // the last listener is removed - if ( m_xPeer.is() ) - { - impl_unadviseFromPeer( m_xPeer, aType ); - } - } + for_each_container([&aGuard, &aEvent](auto& c) { c.disposeAndClear(aGuard, aEvent); }); } // XEventListener @@ -313,66 +260,6 @@ void OMRCListenerMultiplexerHelper::windowDeactivated( const EventObject& aEvent Multiplex(&XTopWindowListener::windowDeactivated, aEvent); } -// protected method - -void OMRCListenerMultiplexerHelper::impl_adviseToPeer( const Reference< XWindow >& xPeer , - const Type& aType ) -{ - // add a listener to the source (peer) - if( aType == cppu::UnoType<XWindowListener>::get()) - xPeer->addWindowListener( this ); - else if( aType == cppu::UnoType<XKeyListener>::get()) - xPeer->addKeyListener( this ); - else if( aType == cppu::UnoType<XFocusListener>::get()) - xPeer->addFocusListener( this ); - else if( aType == cppu::UnoType<XMouseListener>::get()) - xPeer->addMouseListener( this ); - else if( aType == cppu::UnoType<XMouseMotionListener>::get()) - xPeer->addMouseMotionListener( this ); - else if( aType == cppu::UnoType<XPaintListener>::get()) - xPeer->addPaintListener( this ); - else if( aType == cppu::UnoType<XTopWindowListener>::get()) - { - Reference< XTopWindow > xTop( xPeer, UNO_QUERY ); - if( xTop.is() ) - xTop->addTopWindowListener( this ); - } - else - { - OSL_FAIL( "unknown listener" ); - } -} - -// protected method - -void OMRCListenerMultiplexerHelper::impl_unadviseFromPeer( const Reference< XWindow >& xPeer , - const Type& aType ) -{ - // the last listener is removed, remove the listener from the source (peer) - if( aType == cppu::UnoType<XWindowListener>::get()) - xPeer->removeWindowListener( this ); - else if( aType == cppu::UnoType<XKeyListener>::get()) - xPeer->removeKeyListener( this ); - else if( aType == cppu::UnoType<XFocusListener>::get()) - xPeer->removeFocusListener( this ); - else if( aType == cppu::UnoType<XMouseListener>::get()) - xPeer->removeMouseListener( this ); - else if( aType == cppu::UnoType<XMouseMotionListener>::get()) - xPeer->removeMouseMotionListener( this ); - else if( aType == cppu::UnoType<XPaintListener>::get()) - xPeer->removePaintListener( this ); - else if( aType == cppu::UnoType<XTopWindowListener>::get()) - { - Reference< XTopWindow > xTop( xPeer, UNO_QUERY ); - if( xTop.is() ) - xTop->removeTopWindowListener( this ); - } - else - { - OSL_FAIL( "unknown listener" ); - } -} - } // namespace unocontrols /* vim:set shiftwidth=4 softtabstop=4 expandtab: */