[Libreoffice-commits] core.git: comphelper/source configmgr/CppunitTest_configmgr_unit.mk configmgr/qa include/comphelper

Michael Meeks michael.meeks at collabora.com
Fri Oct 9 01:43:10 PDT 2015


 comphelper/source/misc/configuration.cxx     |   51 +++++++++++
 configmgr/CppunitTest_configmgr_unit.mk      |    4 
 configmgr/qa/unit/test.cxx                   |   47 ++++++++++
 include/comphelper/configurationlistener.hxx |  118 +++++++++++++++++++++++++++
 4 files changed, 220 insertions(+)

New commits:
commit ccf8bdcf929e842ef42ae968e4f0532282357277
Author: Michael Meeks <michael.meeks at collabora.com>
Date:   Mon Oct 5 18:08:02 2015 +0100

    Create a wrapper to make listening for configmgr changes easy.
    
    Change-Id: Ib58d04f9e046e604b24e0e338796a7a60aa1d6fd
    Reviewed-on: https://gerrit.libreoffice.org/19253
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Michael Meeks <michael.meeks at collabora.com>

diff --git a/comphelper/source/misc/configuration.cxx b/comphelper/source/misc/configuration.cxx
index 6280fdc..e5bf8b8 100644
--- a/comphelper/source/misc/configuration.cxx
+++ b/comphelper/source/misc/configuration.cxx
@@ -27,6 +27,7 @@
 #include <com/sun/star/uno/Reference.hxx>
 #include <com/sun/star/uno/XComponentContext.hpp>
 #include <comphelper/configuration.hxx>
+#include <comphelper/configurationlistener.hxx>
 #include <rtl/instance.hxx>
 #include <rtl/ustrbuf.hxx>
 #include <rtl/ustring.hxx>
@@ -209,4 +210,54 @@ comphelper::detail::ConfigurationWrapper::createChanges() const {
         new ConfigurationChanges(context_));
 }
 
+void comphelper::ConfigurationListener::addListener(ConfigurationListenerPropertyBase *pListener)
+{
+    maListeners.push_back( pListener );
+    mxConfig->addPropertyChangeListener( pListener->maName, this );
+    pListener->setProperty( mxConfig->getPropertyValue( pListener->maName ) );
+}
+
+void comphelper::ConfigurationListener::removeListener(ConfigurationListenerPropertyBase *pListener)
+{
+    auto it = maListeners.begin();
+    it = std::find( maListeners.begin(), maListeners.end(), pListener );
+    if ( it != maListeners.end() )
+    {
+        maListeners.erase( it );
+        mxConfig->removePropertyChangeListener( pListener->maName, this );
+    }
+}
+
+void comphelper::ConfigurationListener::dispose()
+{
+    for (auto it = maListeners.begin(); it != maListeners.end(); ++it)
+    {
+        mxConfig->removePropertyChangeListener( (*it)->maName, this );
+        (*it)->dispose();
+    }
+    maListeners.clear();
+}
+
+void SAL_CALL comphelper::ConfigurationListener::disposing(css::lang::EventObject const &)
+    throw (css::uno::RuntimeException, std::exception)
+{
+    dispose();
+}
+
+void SAL_CALL comphelper::ConfigurationListener::propertyChange(
+    css::beans::PropertyChangeEvent const &rEvt )
+    throw (css::uno::RuntimeException, std::exception)
+{
+    assert( rEvt.Source == mxConfig );
+    for ( auto it = maListeners.begin(); it != maListeners.end(); ++it )
+    {
+        if ( (*it)->maName == rEvt.PropertyName )
+        {
+            // ignore rEvt.NewValue - in theory it could be stale => not set.
+            css::uno::Any aValue = mxConfig->getPropertyValue( (*it)->maName );
+            (*it)->setProperty( aValue );
+        }
+    }
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/configmgr/CppunitTest_configmgr_unit.mk b/configmgr/CppunitTest_configmgr_unit.mk
index e8bddc2..ca9653f 100644
--- a/configmgr/CppunitTest_configmgr_unit.mk
+++ b/configmgr/CppunitTest_configmgr_unit.mk
@@ -21,6 +21,10 @@ $(eval $(call gb_CppunitTest_use_library_objects,configmgr_unit,configmgr))
 
 $(eval $(call gb_CppunitTest_use_sdk_api,configmgr_unit,))
 
+$(eval $(call gb_CppunitTest_use_custom_headers,configmgr_unit,\
+        officecfg/registry \
+))
+
 $(eval $(call gb_CppunitTest_use_libraries,configmgr_unit, \
 	    comphelper \
 	    cppu \
diff --git a/configmgr/qa/unit/test.cxx b/configmgr/qa/unit/test.cxx
index a9f609b..6985cab 100644
--- a/configmgr/qa/unit/test.cxx
+++ b/configmgr/qa/unit/test.cxx
@@ -55,7 +55,11 @@
 #include <rtl/ustring.hxx>
 #include <sal/types.h>
 #include <comphelper/processfactory.hxx>
+#include <comphelper/configuration.hxx>
+#include <comphelper/configurationlistener.hxx>
+#include <comphelper/configurationlistener.hxx>
 #include <unotest/bootstrapfixturebase.hxx>
+#include <officecfg/Office/Math.hxx>
 
 namespace {
 
@@ -70,6 +74,7 @@ public:
     void testSetSetMemberName();
     void testInsertSetMember();
     void testReadCommands();
+    void testListener();
 #if 0
     void testThreads();
 #endif
@@ -98,6 +103,7 @@ public:
     CPPUNIT_TEST(testSetSetMemberName);
     CPPUNIT_TEST(testInsertSetMember);
     CPPUNIT_TEST(testReadCommands);
+    CPPUNIT_TEST(testListener);
 #if 0
     CPPUNIT_TEST(testThreads);
 #endif
@@ -356,6 +362,47 @@ void Test::testReadCommands()
         access, css::uno::UNO_QUERY_THROW)->dispose();
 }
 
+void Test::testListener()
+{
+    OUString aRandomPath = "/org.openoffice.Office.Math/View";
+
+    // test with no props.
+    {
+        rtl::Reference<comphelper::ConfigurationListener> xListener(
+            new comphelper::ConfigurationListener(aRandomPath));
+        xListener->dispose();
+    }
+
+    // test some changes
+    {
+        rtl::Reference<comphelper::ConfigurationListener> xListener(
+            new comphelper::ConfigurationListener(aRandomPath));
+
+        comphelper::ConfigurationListenerProperty<bool> aSetting(xListener, "AutoRedraw");
+        CPPUNIT_ASSERT_MESSAGE("check AutoRedraw defaults to true", aSetting.get());
+
+        // set to false
+        {
+            std::shared_ptr< comphelper::ConfigurationChanges > xChanges(
+                comphelper::ConfigurationChanges::create());
+            officecfg::Office::Math::View::AutoRedraw::set(false, xChanges);
+            xChanges->commit();
+        }
+        CPPUNIT_ASSERT_MESSAGE("listener failed to trigger", !aSetting.get());
+
+        // set to true
+        {
+            std::shared_ptr< comphelper::ConfigurationChanges > xChanges(
+                comphelper::ConfigurationChanges::create());
+            officecfg::Office::Math::View::AutoRedraw::set(true, xChanges);
+            xChanges->commit();
+        }
+        CPPUNIT_ASSERT_MESSAGE("listener failed to trigger", aSetting.get());
+
+        xListener->dispose();
+    }
+}
+
 void Test::testRecursive()
 {
     bool destroyed = false;
diff --git a/include/comphelper/configurationlistener.hxx b/include/comphelper/configurationlistener.hxx
new file mode 100644
index 0000000..658b84b
--- /dev/null
+++ b/include/comphelper/configurationlistener.hxx
@@ -0,0 +1,118 @@
+/* -*- 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/.
+ */
+
+#ifndef INCLUDED_COMPHELPER_CONFIGURATIONLISTENER_HXX
+#define INCLUDED_COMPHELPER_CONFIGURATIONLISTENER_HXX
+
+#include <algorithm>
+#include <vector>
+#include <iterator>
+#include <comphelper/comphelperdllapi.h>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyChangeEvent.hpp>
+#include <com/sun/star/beans/XPropertyChangeListener.hpp>
+#include <rtl/ref.hxx>
+#include <cppuhelper/implbase.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/configurationhelper.hxx>
+
+namespace comphelper {
+
+class ConfigurationListener;
+
+class COMPHELPER_DLLPUBLIC ConfigurationListenerPropertyBase {
+public:
+    OUString maName;
+    rtl::Reference<ConfigurationListener> mxListener;
+
+    virtual ~ConfigurationListenerPropertyBase() {}
+    virtual void setProperty(const css::uno::Any &aProperty) = 0;
+    void dispose() { mxListener.clear(); }
+};
+
+template< typename uno_type > class ConfigurationListenerProperty : public ConfigurationListenerPropertyBase
+{
+    uno_type maValue;
+protected:
+    virtual void setProperty(const css::uno::Any &aProperty) SAL_OVERRIDE
+    {
+        aProperty >>= maValue;
+    }
+public:
+    /**
+     * Provide a mirror of the configmgr's version of this property
+     * for the lifecycle of this property. The property value tracks
+     * the same value in the configuration.
+     */
+    inline ConfigurationListenerProperty(const rtl::Reference< ConfigurationListener > &xListener,
+                                             const OUString &rProp );
+
+    inline ~ConfigurationListenerProperty();
+
+    uno_type get() { return maValue; }
+};
+
+class COMPHELPER_DLLPUBLIC ConfigurationListener :
+        public cppu::WeakImplHelper< css::beans::XPropertyChangeListener >
+{
+    css::uno::Reference< css::beans::XPropertySet > mxConfig;
+    std::vector< ConfigurationListenerPropertyBase * > maListeners;
+public:
+    /// Public health warning, you -must- dispose this if you use it.
+    ConfigurationListener(const OUString &rPath,
+                          com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
+                          const & xContext = comphelper::getProcessComponentContext())
+        : mxConfig( ConfigurationHelper::openConfig( xContext, rPath,
+                        ConfigurationHelper::EConfigurationModes::E_READONLY ),
+                  css::uno::UNO_QUERY_THROW )
+    { }
+
+    virtual ~ConfigurationListener()
+    {
+        dispose();
+    }
+
+    /// Listen for the specific property denoted by the listener
+    void addListener(ConfigurationListenerPropertyBase *pListener);
+
+    /// Stop listening.
+    void removeListener(ConfigurationListenerPropertyBase *pListener);
+
+    /// Release various circular references
+    void dispose();
+
+    // XPropertyChangeListener implementation
+    virtual void SAL_CALL disposing(css::lang::EventObject const &)
+        throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
+
+    /// Notify of the property change
+    virtual void SAL_CALL propertyChange(
+        css::beans::PropertyChangeEvent const &rEvt )
+        throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
+};
+
+template< typename uno_type > ConfigurationListenerProperty< uno_type >::ConfigurationListenerProperty(const rtl::Reference< ConfigurationListener > &xListener, const OUString &rProp )
+{
+    maName = rProp;
+    mxListener = xListener;
+    mxListener->addListener(this);
+}
+
+template< typename uno_type > ConfigurationListenerProperty< uno_type >::~ConfigurationListenerProperty()
+{
+    if (mxListener.is())
+        mxListener->removeListener(this);
+}
+
+} // namespace comphelper
+
+#endif // INCLUDED_COMPHELPER_CONFIGURATIONLISTENER_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */


More information about the Libreoffice-commits mailing list