[Libreoffice-commits] .: 2 commits - comphelper/inc comphelper/source configmgr/source cui/source offapi/com

Stephan Bergmann sbergmann at kemper.freedesktop.org
Wed Jul 25 10:11:17 PDT 2012


 comphelper/inc/comphelper/configuration.hxx           |    2 
 comphelper/source/misc/configuration.cxx              |  109 +++---
 configmgr/source/access.cxx                           |   75 ++++
 configmgr/source/childaccess.cxx                      |   76 ----
 configmgr/source/configmgr.component                  |    2 
 configmgr/source/readonlyaccess.cxx                   |   64 ++-
 configmgr/source/readwriteaccess.cxx                  |   74 +++-
 cui/source/inc/treeopt.hxx                            |    9 
 cui/source/options/treeopt.cxx                        |  318 ++++++++----------
 offapi/com/sun/star/configuration/ReadOnlyAccess.idl  |   15 
 offapi/com/sun/star/configuration/ReadWriteAccess.idl |   15 
 11 files changed, 421 insertions(+), 338 deletions(-)

New commits:
commit cef66a3eed301ab77e02be6d6ba148142051e13d
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Wed Jul 25 19:06:42 2012 +0200

    Revert "fdo#52232 ConfigurationSet wrapper unusable for localized properties"
    
    This reverts commit aebf5bf22304c73e121b16dc0b51f909c5f34c28, now that
    e397a9cfabc2928cd5571309f5b634a7e78098ec "Make comphelper/configuration.hxx
    work for localized properties" fixes the original problem.
    
    Change-Id: If4e187b911510d5932d52cec08d43cb73f6e339c

diff --git a/cui/source/inc/treeopt.hxx b/cui/source/inc/treeopt.hxx
index 64d2b9b..38700e6 100644
--- a/cui/source/inc/treeopt.hxx
+++ b/cui/source/inc/treeopt.hxx
@@ -138,7 +138,6 @@ struct LastPageSaver
 // class OfaTreeOptionsDialog --------------------------------------------
 
 namespace com { namespace sun { namespace star { namespace frame { class XFrame; } } } }
-namespace com { namespace sun { namespace star { namespace container { class XNameAccess; } } } }
 namespace com { namespace sun { namespace star { namespace lang { class XMultiServiceFactory; } } } }
 namespace com { namespace sun { namespace star { namespace awt { class XContainerWindowProvider; } } } }
 
@@ -192,12 +191,8 @@ private:
                                             com::sun::star::lang::XMultiServiceFactory >& xMFac,
                                          const com::sun::star::uno::Reference<
                                             com::sun::star::frame::XFrame >& xFrame );
-    Module*         LoadModule( const rtl::OUString& rModuleIdentifier,
-                                const com::sun::star::uno::Reference<
-                                    com::sun::star::container::XNameAccess >& xRoot );
-    void            LoadNodes( const com::sun::star::uno::Reference<
-                                    com::sun::star::container::XNameAccess >& xRoot,
-                               Module* pModule,
+    Module*         LoadModule( const rtl::OUString& rModuleIdentifier );
+    void            LoadNodes( Module* pModule,
                                const rtl::OUString& rExtensionId,
                                VectorOfNodes& rOutNodeList );
     void            InsertNodes( const VectorOfNodes& rNodeList );
diff --git a/cui/source/options/treeopt.cxx b/cui/source/options/treeopt.cxx
index ce34083..9db1841 100644
--- a/cui/source/options/treeopt.cxx
+++ b/cui/source/options/treeopt.cxx
@@ -67,11 +67,11 @@
 #include <com/sun/star/frame/XModuleManager.hpp>
 #include <com/sun/star/loader/CannotActivateFactoryException.hpp>
 #include <com/sun/star/util/XMacroExpander.hpp>
-#include <comphelper/configurationhelper.hxx>
 #include <comphelper/processfactory.hxx>
 #include <editeng/optitems.hxx>
 #include <editeng/unolingu.hxx>
 #include <linguistic/misc.hxx>
+#include <officecfg/Office/OptionsDialog.hxx>
 #include <osl/module.hxx>
 #include <osl/process.h>
 #include <rtl/bootstrap.hxx>
@@ -1927,18 +1927,12 @@ void OfaTreeOptionsDialog::LoadExtensionOptions( const rtl::OUString& rExtension
 {
     Module* pModule = NULL;
     Reference< XMultiServiceFactory > xMSFac = comphelper::getProcessServiceFactory();
-    // open optionsdialog.xcu
-    Reference< XNameAccess > xRoot(
-        ::comphelper::ConfigurationHelper::openConfig(
-            xMSFac, C2U("org.openoffice.Office.OptionsDialog"),
-            ::comphelper::ConfigurationHelper::E_READONLY ), UNO_QUERY );
-    DBG_ASSERT( xRoot.is(), "OfaTreeOptionsDialog::LoadExtensionOptions(): no config" );
     // when called by Tools - Options then load nodes of active module
     if ( rExtensionId.isEmpty() )
-        pModule = LoadModule( GetModuleIdentifier( xMSFac, Reference< XFrame >() ), xRoot );
+        pModule = LoadModule( GetModuleIdentifier( xMSFac, Reference< XFrame >() ) );
 
     VectorOfNodes aNodeList;
-    LoadNodes( xRoot, pModule, rExtensionId, aNodeList );
+    LoadNodes( pModule, rExtensionId, aNodeList );
     InsertNodes( aNodeList );
 }
 
@@ -1977,64 +1971,58 @@ rtl::OUString OfaTreeOptionsDialog::GetModuleIdentifier(
 }
 
 Module* OfaTreeOptionsDialog::LoadModule(
-    const rtl::OUString& rModuleIdentifier, const Reference< XNameAccess >& xRoot )
+    const rtl::OUString& rModuleIdentifier )
 {
     Module* pModule = NULL;
-    Reference< XNameAccess > xSet;
+    Reference< XNameAccess > xSet(
+        officecfg::Office::OptionsDialog::Modules::get());
 
-    if ( xRoot->hasByName( C2U("Modules") ) )
+    Sequence< rtl::OUString > seqNames = xSet->getElementNames();
+    for ( int i = 0; i < seqNames.getLength(); ++i )
     {
-        xRoot->getByName( C2U("Modules") ) >>= xSet;
-        if ( xSet.is() )
+        rtl::OUString sModule( seqNames[i] );
+        if ( rModuleIdentifier == sModule )
         {
-            Sequence< rtl::OUString > seqNames = xSet->getElementNames();
-            for ( int i = 0; i < seqNames.getLength(); ++i )
+            // current active module found
+            pModule = new Module( sModule );
+            pModule->m_bActive = true;
+
+            Reference< XNameAccess > xModAccess;
+            xSet->getByName( seqNames[i] ) >>= xModAccess;
+            if ( xModAccess.is() )
             {
-                rtl::OUString sModule( seqNames[i] );
-                if ( rModuleIdentifier == sModule )
+                // load the nodes of this module
+                Reference< XNameAccess > xNodeAccess;
+                xModAccess->getByName( C2U("Nodes") ) >>= xNodeAccess;
+                if ( xNodeAccess.is() )
                 {
-                    // current active module found
-                    pModule = new Module( sModule );
-                    pModule->m_bActive = true;
-
-                    Reference< XNameAccess > xModAccess;
-                    xSet->getByName( seqNames[i] ) >>= xModAccess;
-                    if ( xModAccess.is() )
+                    Sequence< rtl::OUString > xTemp = xNodeAccess->getElementNames();
+                    Reference< XNameAccess > xAccess;
+                    sal_Int32 nIndex = -1;
+                    for ( int x = 0; x < xTemp.getLength(); ++x )
                     {
-                        // load the nodes of this module
-                        Reference< XNameAccess > xNodeAccess;
-                        xModAccess->getByName( C2U("Nodes") ) >>= xNodeAccess;
-                        if ( xNodeAccess.is() )
+                        xNodeAccess->getByName( xTemp[x] ) >>= xAccess;
+                        if ( xAccess.is() )
                         {
-                            Sequence< rtl::OUString > xTemp = xNodeAccess->getElementNames();
-                            Reference< XNameAccess > xAccess;
-                            sal_Int32 nIndex = -1;
-                            for ( int x = 0; x < xTemp.getLength(); ++x )
+                            xAccess->getByName( C2U("Index") ) >>= nIndex;
+                            if ( nIndex < 0 )
+                                // append nodes with index < 0
+                                pModule->m_aNodeList.push_back(
+                                    new OrderedEntry( nIndex, xTemp[x] ) );
+                            else
                             {
-                                xNodeAccess->getByName( xTemp[x] ) >>= xAccess;
-                                if ( xAccess.is() )
+                                // search position of the node
+                                sal_uInt32 y = 0;
+                                for ( ; y < pModule->m_aNodeList.size(); ++y )
                                 {
-                                    xAccess->getByName( C2U("Index") ) >>= nIndex;
-                                    if ( nIndex < 0 )
-                                        // append nodes with index < 0
-                                        pModule->m_aNodeList.push_back(
-                                            new OrderedEntry( nIndex, xTemp[x] ) );
-                                    else
-                                    {
-                                        // search position of the node
-                                        sal_uInt32 y = 0;
-                                        for ( ; y < pModule->m_aNodeList.size(); ++y )
-                                        {
-                                            sal_Int32 nNodeIdx = pModule->m_aNodeList[y]->m_nIndex;
-                                            if ( nNodeIdx < 0 || nNodeIdx > nIndex )
-                                                break;
-                                        }
-                                        // and insert the node on this position
-                                        pModule->m_aNodeList.insert(
-                                            pModule->m_aNodeList.begin() + y,
-                                            new OrderedEntry( nIndex, xTemp[x] ) );
-                                    }
+                                    sal_Int32 nNodeIdx = pModule->m_aNodeList[y]->m_nIndex;
+                                    if ( nNodeIdx < 0 || nNodeIdx > nIndex )
+                                        break;
                                 }
+                                // and insert the node on this position
+                                pModule->m_aNodeList.insert(
+                                    pModule->m_aNodeList.begin() + y,
+                                    new OrderedEntry( nIndex, xTemp[x] ) );
                             }
                         }
                     }
@@ -2046,151 +2034,145 @@ Module* OfaTreeOptionsDialog::LoadModule(
 }
 
 void OfaTreeOptionsDialog::LoadNodes(
-    const Reference< XNameAccess >& xRoot, Module* pModule,
-    const rtl::OUString& rExtensionId, VectorOfNodes& rOutNodeList )
+    Module* pModule, const rtl::OUString& rExtensionId,
+    VectorOfNodes& rOutNodeList )
 {
-    Reference< XNameAccess > xSet;
-    if ( xRoot->hasByName( C2U("Nodes") ) )
+    Reference< XNameAccess > xSet(
+        officecfg::Office::OptionsDialog::Nodes::get());
+    VectorOfNodes aNodeList;
+    Sequence< rtl::OUString > seqNames = xSet->getElementNames();
+
+    for ( int i = 0; i < seqNames.getLength(); ++i )
     {
-        xRoot->getByName( C2U("Nodes") ) >>= xSet;
-        if ( xSet.is() )
+        String sGroupName( seqNames[i] );
+        Reference< XNameAccess > xNodeAccess;
+        xSet->getByName( seqNames[i] ) >>= xNodeAccess;
+
+        if ( xNodeAccess.is() )
         {
-            VectorOfNodes aNodeList;
-            Sequence< rtl::OUString > seqNames = xSet->getElementNames();
+            rtl::OUString sNodeId, sLabel, sPageURL, sGroupId;
+            bool bAllModules = false;
+            sal_Int32 nGroupIndex = 0;
+
+            sNodeId = seqNames[i];
+            xNodeAccess->getByName( C2U("Label") ) >>= sLabel;
+            xNodeAccess->getByName( C2U("OptionsPage") ) >>= sPageURL;
+            xNodeAccess->getByName( C2U("AllModules") ) >>= bAllModules;
+            xNodeAccess->getByName( C2U("GroupId") ) >>= sGroupId;
+            xNodeAccess->getByName( C2U("GroupIndex") ) >>= nGroupIndex;
 
-            for ( int i = 0; i < seqNames.getLength(); ++i )
+            if ( sLabel.isEmpty() )
+                sLabel = sGroupName;
+            String sTemp = getGroupName( sLabel, !rExtensionId.isEmpty() );
+            if ( sTemp.Len() > 0 )
+                sLabel = sTemp;
+            OptionsNode* pNode =
+                new OptionsNode( sNodeId, sLabel, sPageURL, bAllModules, sGroupId, nGroupIndex );
+
+            if ( rExtensionId.isEmpty() && !isNodeActive( pNode, pModule ) )
             {
-                String sGroupName( seqNames[i] );
-                Reference< XNameAccess > xNodeAccess;
-                xSet->getByName( seqNames[i] ) >>= xNodeAccess;
+                delete pNode;
+                continue;
+            }
 
-                if ( xNodeAccess.is() )
+            Reference< XNameAccess > xLeavesSet;
+            xNodeAccess->getByName( C2U( "Leaves" ) ) >>= xLeavesSet;
+            if ( xLeavesSet.is() )
+            {
+                Sequence< rtl::OUString > seqLeaves = xLeavesSet->getElementNames();
+                for ( int j = 0; j < seqLeaves.getLength(); ++j )
                 {
-                    rtl::OUString sNodeId, sLabel, sPageURL, sGroupId;
-                    bool bAllModules = false;
-                    sal_Int32 nGroupIndex = 0;
-
-                    sNodeId = seqNames[i];
-                    xNodeAccess->getByName( C2U("Label") ) >>= sLabel;
-                    xNodeAccess->getByName( C2U("OptionsPage") ) >>= sPageURL;
-                    xNodeAccess->getByName( C2U("AllModules") ) >>= bAllModules;
-                    xNodeAccess->getByName( C2U("GroupId") ) >>= sGroupId;
-                    xNodeAccess->getByName( C2U("GroupIndex") ) >>= nGroupIndex;
-
-                    if ( sLabel.isEmpty() )
-                        sLabel = sGroupName;
-                    String sTemp = getGroupName( sLabel, !rExtensionId.isEmpty() );
-                    if ( sTemp.Len() > 0 )
-                        sLabel = sTemp;
-                    OptionsNode* pNode =
-                        new OptionsNode( sNodeId, sLabel, sPageURL, bAllModules, sGroupId, nGroupIndex );
-
-                    if ( rExtensionId.isEmpty() && !isNodeActive( pNode, pModule ) )
-                    {
-                        delete pNode;
-                        continue;
-                    }
+                    Reference< XNameAccess > xLeaveAccess;
+                    xLeavesSet->getByName( seqLeaves[j] ) >>= xLeaveAccess;
 
-                    Reference< XNameAccess > xLeavesSet;
-                    xNodeAccess->getByName( C2U( "Leaves" ) ) >>= xLeavesSet;
-                    if ( xLeavesSet.is() )
+                    if ( xLeaveAccess.is() )
                     {
-                        Sequence< rtl::OUString > seqLeaves = xLeavesSet->getElementNames();
-                        for ( int j = 0; j < seqLeaves.getLength(); ++j )
-                        {
-                            Reference< XNameAccess > xLeaveAccess;
-                            xLeavesSet->getByName( seqLeaves[j] ) >>= xLeaveAccess;
+                        rtl::OUString sId, sLeafLabel, sEventHdl, sLeafURL, sLeafGrpId;
+                        sal_Int32 nLeafGrpIdx = 0;
 
-                            if ( xLeaveAccess.is() )
-                            {
-                                rtl::OUString sId, sLeafLabel, sEventHdl, sLeafURL, sLeafGrpId;
-                                sal_Int32 nLeafGrpIdx = 0;
+                        xLeaveAccess->getByName( C2U("Id") ) >>= sId;
+                        xLeaveAccess->getByName( C2U("Label") ) >>= sLeafLabel;
+                        xLeaveAccess->getByName( C2U("OptionsPage") ) >>= sLeafURL;
+                        xLeaveAccess->getByName( C2U("EventHandlerService") ) >>= sEventHdl;
+                        xLeaveAccess->getByName( C2U("GroupId") ) >>= sLeafGrpId;
+                        xLeaveAccess->getByName( C2U("GroupIndex") ) >>= nLeafGrpIdx;
 
-                                xLeaveAccess->getByName( C2U("Id") ) >>= sId;
-                                xLeaveAccess->getByName( C2U("Label") ) >>= sLeafLabel;
-                                xLeaveAccess->getByName( C2U("OptionsPage") ) >>= sLeafURL;
-                                xLeaveAccess->getByName( C2U("EventHandlerService") ) >>= sEventHdl;
-                                xLeaveAccess->getByName( C2U("GroupId") ) >>= sLeafGrpId;
-                                xLeaveAccess->getByName( C2U("GroupIndex") ) >>= nLeafGrpIdx;
+                        if ( rExtensionId.isEmpty() || sId == rExtensionId )
+                        {
+                            OptionsLeaf* pLeaf = new OptionsLeaf(
+                                sId, sLeafLabel, sLeafURL, sEventHdl, sLeafGrpId, nLeafGrpIdx );
 
-                                if ( rExtensionId.isEmpty() || sId == rExtensionId )
+                            if ( !sLeafGrpId.isEmpty() )
+                            {
+                                bool bAlreadyOpened = false;
+                                if ( pNode->m_aGroupedLeaves.size() > 0 )
                                 {
-                                    OptionsLeaf* pLeaf = new OptionsLeaf(
-                                        sId, sLeafLabel, sLeafURL, sEventHdl, sLeafGrpId, nLeafGrpIdx );
-
-                                    if ( !sLeafGrpId.isEmpty() )
+                                    for ( sal_uInt32 k = 0;
+                                          k < pNode->m_aGroupedLeaves.size(); ++k )
                                     {
-                                        bool bAlreadyOpened = false;
-                                        if ( pNode->m_aGroupedLeaves.size() > 0 )
+                                        if ( pNode->m_aGroupedLeaves[k].size() > 0 &&
+                                             pNode->m_aGroupedLeaves[k][0]->m_sGroupId
+                                             == sLeafGrpId )
                                         {
-                                            for ( sal_uInt32 k = 0;
-                                                    k < pNode->m_aGroupedLeaves.size(); ++k )
+                                            sal_uInt32 l = 0;
+                                            for ( ; l < pNode->m_aGroupedLeaves[k].size(); ++l )
                                             {
-                                                if ( pNode->m_aGroupedLeaves[k].size() > 0 &&
-                                                     pNode->m_aGroupedLeaves[k][0]->m_sGroupId
-                                                        == sLeafGrpId )
-                                                {
-                                                    sal_uInt32 l = 0;
-                                                    for ( ; l < pNode->m_aGroupedLeaves[k].size(); ++l )
-                                                    {
-                                                        if ( pNode->m_aGroupedLeaves[k][l]->
-                                                                m_nGroupIndex >= nLeafGrpIdx )
-                                                            break;
-                                                    }
-                                                    pNode->m_aGroupedLeaves[k].insert(
-                                                        pNode->m_aGroupedLeaves[k].begin() + l, pLeaf );
-                                                    bAlreadyOpened = true;
+                                                if ( pNode->m_aGroupedLeaves[k][l]->
+                                                     m_nGroupIndex >= nLeafGrpIdx )
                                                     break;
-                                                }
                                             }
-                                        }
-                                        if ( !bAlreadyOpened )
-                                        {
-                                            VectorOfLeaves aGroupedLeaves;
-                                            aGroupedLeaves.push_back( pLeaf );
-                                            pNode->m_aGroupedLeaves.push_back( aGroupedLeaves );
+                                            pNode->m_aGroupedLeaves[k].insert(
+                                                pNode->m_aGroupedLeaves[k].begin() + l, pLeaf );
+                                            bAlreadyOpened = true;
+                                            break;
                                         }
                                     }
-                                    else
-                                        pNode->m_aLeaves.push_back(
-                                            new OptionsLeaf(
-                                                sId, sLeafLabel, sLeafURL,
-                                                sEventHdl, sLeafGrpId, nLeafGrpIdx ) );
+                                }
+                                if ( !bAlreadyOpened )
+                                {
+                                    VectorOfLeaves aGroupedLeaves;
+                                    aGroupedLeaves.push_back( pLeaf );
+                                    pNode->m_aGroupedLeaves.push_back( aGroupedLeaves );
                                 }
                             }
+                            else
+                                pNode->m_aLeaves.push_back(
+                                    new OptionsLeaf(
+                                        sId, sLeafLabel, sLeafURL,
+                                        sEventHdl, sLeafGrpId, nLeafGrpIdx ) );
                         }
                     }
-
-                    // do not insert nodes without leaves
-                    if ( pNode->m_aLeaves.size() > 0 || pNode->m_aGroupedLeaves.size() > 0 )
-                    {
-                        pModule ? aNodeList.push_back( pNode ) : rOutNodeList.push_back( pNode );
-                    }
                 }
             }
 
-            if ( pModule && aNodeList.size() > 0 )
+            // do not insert nodes without leaves
+            if ( pNode->m_aLeaves.size() > 0 || pNode->m_aGroupedLeaves.size() > 0 )
             {
-                sal_uInt32 i = 0, j = 0;
-                for ( ; i < pModule->m_aNodeList.size(); ++i )
+                pModule ? aNodeList.push_back( pNode ) : rOutNodeList.push_back( pNode );
+            }
+        }
+    }
+
+    if ( pModule && aNodeList.size() > 0 )
+    {
+        sal_uInt32 i = 0, j = 0;
+        for ( ; i < pModule->m_aNodeList.size(); ++i )
+        {
+            rtl::OUString sNodeId = pModule->m_aNodeList[i]->m_sId;
+            for ( j = 0; j < aNodeList.size(); ++j )
+            {
+                OptionsNode* pNode = aNodeList[j];
+                if ( pNode->m_sId == sNodeId )
                 {
-                    rtl::OUString sNodeId = pModule->m_aNodeList[i]->m_sId;
-                    for ( j = 0; j < aNodeList.size(); ++j )
-                    {
-                        OptionsNode* pNode = aNodeList[j];
-                        if ( pNode->m_sId == sNodeId )
-                        {
-                            rOutNodeList.push_back( pNode );
-                            aNodeList.erase( aNodeList.begin() + j );
-                            break;
-                        }
-                    }
+                    rOutNodeList.push_back( pNode );
+                    aNodeList.erase( aNodeList.begin() + j );
+                    break;
                 }
-
-                for ( i = 0; i < aNodeList.size(); ++i )
-                    rOutNodeList.push_back( aNodeList[i] );
             }
         }
+
+        for ( i = 0; i < aNodeList.size(); ++i )
+            rOutNodeList.push_back( aNodeList[i] );
     }
 }
 
commit cf7c9599e776eba8e14614cecb528d3da5778190
Author: Stephan Bergmann <sbergman at redhat.com>
Date:   Wed Jul 25 18:54:38 2012 +0200

    Make comphelper/configuration.hxx work for localized properties
    
    See aebf5bf22304c73e121b16dc0b51f909c5f34c28 "fdo#52232 ConfigurationSet wrapper
    unusable for localized properties" for a discussion of the problems with the
    original design.
    
    1  Redesigned configmgr's localized property access to understand ['*<locale>']
    paths that select the best existing value match for the requested <locale>.
    Adapted ConfigurationWrapper::getLocalizedPropertyValue accordingly.
    
    2  Redesigned ConfigurationChanges to fix the locale at instantiation time.
    That takes care of ConfigurationWrapper::setLocalizedPropertyValue,
    ConfigurationWrapper::getGroupReadWrite, and
    ConfigurationWrapper::getSetReadWrite.  (This required an additional constructor
    parameter for the ReadWriteAccess service, to specify a locale at instantiation
    time.)
    
    3  Redesigned ReadOnlyAccess to be a service that fixes the locale at
    instantiation time.  That allows to take care of
    ConfigurationWrapper::getGroupReadOnly and ConfigurationWrapper::getSetReadOnly.
    
    Change-Id: I2ae7342b278b6f4222a0189a1deb2a53e204059f

diff --git a/comphelper/inc/comphelper/configuration.hxx b/comphelper/inc/comphelper/configuration.hxx
index 1cf4a26..d70b390 100644
--- a/comphelper/inc/comphelper/configuration.hxx
+++ b/comphelper/inc/comphelper/configuration.hxx
@@ -148,8 +148,6 @@ public:
     boost::shared_ptr< ConfigurationChanges > createChanges() const;
 
 private:
-    rtl::OUString extendLocalizedPath(rtl::OUString const & path) const;
-
     com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
         context_;
 
diff --git a/comphelper/source/misc/configuration.cxx b/comphelper/source/misc/configuration.cxx
index 383e35f..01ec08f 100644
--- a/comphelper/source/misc/configuration.cxx
+++ b/comphelper/source/misc/configuration.cxx
@@ -64,6 +64,51 @@ struct TheConfigurationWrapper:
         TheConfigurationWrapper >
 {};
 
+OUString getDefaultLocale(
+    css::uno::Reference< css::uno::XComponentContext > const & context)
+{
+    css::lang::Locale locale(
+        css::uno::Reference< css::lang::XLocalizable >(
+            css::configuration::theDefaultProvider::get(context),
+            css::uno::UNO_QUERY_THROW)->
+        getLocale());
+    OUStringBuffer buf;
+    SAL_WARN_IF(
+        locale.Language.indexOf('-') != -1, "comphelper",
+        "Locale language \"" << locale.Language << "\" contains \"-\"");
+    buf.append(locale.Language);
+    SAL_WARN_IF(
+        locale.Country.isEmpty() && !locale.Variant.isEmpty(), "comphelper",
+        "Locale has empty country but non-empty variant \"" << locale.Variant
+            << '"');
+    if (!locale.Country.isEmpty()) {
+        buf.append('-');
+        SAL_WARN_IF(
+            locale.Country.indexOf('-') != -1, "comphelper",
+            "Locale language \"" << locale.Country << "\" contains \"-\"");
+        buf.append(locale.Country);
+        if (!locale.Variant.isEmpty()) {
+            buf.append('-');
+            buf.append(locale.Variant);
+        }
+    }
+    return buf.makeStringAndClear();
+}
+
+OUString extendLocalizedPath(OUString const & path, OUString const & locale) {
+    rtl::OUStringBuffer buf(path);
+    buf.append("/['*");
+    SAL_WARN_IF(
+        locale.match("*"), "comphelper",
+        "Locale \"" << locale << "\" starts with \"-\"");
+    assert(locale.indexOf('&') == -1);
+    assert(locale.indexOf('"') == -1);
+    assert(locale.indexOf('\'') == -1);
+    buf.append(locale);
+    buf.append("']");
+    return buf.makeStringAndClear();
+}
+
 }
 
 boost::shared_ptr< comphelper::ConfigurationChanges >
@@ -82,7 +127,9 @@ void comphelper::ConfigurationChanges::commit() const {
 
 comphelper::ConfigurationChanges::ConfigurationChanges(
     css::uno::Reference< css::uno::XComponentContext > const & context):
-    access_(css::configuration::ReadWriteAccess::create(context))
+    access_(
+        css::configuration::ReadWriteAccess::create(
+            context, getDefaultLocale(context)))
 {}
 
 void comphelper::ConfigurationChanges::setPropertyValue(
@@ -114,7 +161,8 @@ comphelper::detail::ConfigurationWrapper::get(
 
 comphelper::detail::ConfigurationWrapper::ConfigurationWrapper(
     css::uno::Reference< css::uno::XComponentContext > const & context):
-    context_(context), access_(css::configuration::ReadOnlyAccess::get(context))
+    context_(context),
+    access_(css::configuration::ReadOnlyAccess::create(context, "*"))
 {}
 
 comphelper::detail::ConfigurationWrapper::~ConfigurationWrapper() {}
@@ -137,7 +185,8 @@ css::uno::Any
 comphelper::detail::ConfigurationWrapper::getLocalizedPropertyValue(
     rtl::OUString const & path) const
 {
-    return access_->getByHierarchicalName(extendLocalizedPath(path));
+    return access_->getByHierarchicalName(
+        extendLocalizedPath(path, getDefaultLocale(context_)));
 }
 
 void comphelper::detail::ConfigurationWrapper::setLocalizedPropertyValue(
@@ -145,7 +194,7 @@ void comphelper::detail::ConfigurationWrapper::setLocalizedPropertyValue(
     rtl::OUString const & path, com::sun::star::uno::Any const & value) const
 {
     assert(batch.get() != 0);
-    batch->setPropertyValue(extendLocalizedPath(path), value);
+    batch->setPropertyValue(path, value);
 }
 
 css::uno::Reference< css::container::XHierarchicalNameAccess >
@@ -153,7 +202,10 @@ comphelper::detail::ConfigurationWrapper::getGroupReadOnly(
     rtl::OUString const & path) const
 {
     return css::uno::Reference< css::container::XHierarchicalNameAccess >(
-        access_->getByHierarchicalName(path), css::uno::UNO_QUERY_THROW);
+        (css::configuration::ReadOnlyAccess::create(
+            context_, getDefaultLocale(context_))->
+         getByHierarchicalName(path)),
+        css::uno::UNO_QUERY_THROW);
 }
 
 css::uno::Reference< css::container::XHierarchicalNameReplace >
@@ -170,7 +222,10 @@ comphelper::detail::ConfigurationWrapper::getSetReadOnly(
     rtl::OUString const & path) const
 {
     return css::uno::Reference< css::container::XNameAccess >(
-        access_->getByHierarchicalName(path), css::uno::UNO_QUERY_THROW);
+        (css::configuration::ReadOnlyAccess::create(
+            context_, getDefaultLocale(context_))->
+         getByHierarchicalName(path)),
+        css::uno::UNO_QUERY_THROW);
 }
 
 css::uno::Reference< css::container::XNameContainer >
@@ -188,46 +243,4 @@ comphelper::detail::ConfigurationWrapper::createChanges() const {
         new ConfigurationChanges(context_));
 }
 
-rtl::OUString comphelper::detail::ConfigurationWrapper::extendLocalizedPath(
-    rtl::OUString const & path) const
-{
-    rtl::OUStringBuffer buf(path);
-    buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("/['"));
-    css::lang::Locale locale(
-        css::uno::Reference< css::lang::XLocalizable >(
-            css::configuration::theDefaultProvider::get(context_),
-            css::uno::UNO_QUERY_THROW)->
-        getLocale());
-    SAL_WARN_IF(
-        locale.Language.indexOf('-') != -1, "comphelper",
-        "Locale language \"" << locale.Language << "\" contains \"-\"");
-    assert(locale.Language.indexOf('&') == -1);
-    assert(locale.Language.indexOf('"') == -1);
-    assert(locale.Language.indexOf('\'') == -1);
-    buf.append(locale.Language);
-    SAL_WARN_IF(
-        locale.Country.isEmpty() && !locale.Variant.isEmpty(), "comphelper",
-        "Locale has empty country but non-empty variant \"" << locale.Variant
-            << '"');
-    if (!locale.Country.isEmpty()) {
-        buf.append('-');
-        SAL_WARN_IF(
-            locale.Country.indexOf('-') != -1, "comphelper",
-            "Locale language \"" << locale.Country << "\" contains \"-\"");
-        assert(locale.Country.indexOf('&') == -1);
-        assert(locale.Country.indexOf('"') == -1);
-        assert(locale.Country.indexOf('\'') == -1);
-        buf.append(locale.Country);
-        if (!locale.Variant.isEmpty()) {
-            buf.append('-');
-            assert(locale.Variant.indexOf('&') == -1);
-            assert(locale.Variant.indexOf('"') == -1);
-            assert(locale.Variant.indexOf('\'') == -1);
-            buf.append(locale.Variant);
-        }
-    }
-    buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("']"));
-    return buf.makeStringAndClear();
-}
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/configmgr/source/access.cxx b/configmgr/source/access.cxx
index 30d0542..8d6d9cf 100644
--- a/configmgr/source/access.cxx
+++ b/configmgr/source/access.cxx
@@ -1484,6 +1484,81 @@ rtl::Reference< Node > Access::getParentNode() {
 }
 
 rtl::Reference< ChildAccess > Access::getChild(rtl::OUString const & name) {
+    if (getNode()->kind() == Node::KIND_LOCALIZED_PROPERTY && name.match("*")) {
+        OUString locale(name.copy(1));
+        if (locale.match("*")) {
+            SAL_WARN(
+                "configmgr",
+                ("access best-matching localized property value via"
+                 " \"*<locale>\" with <locale> \"")
+                    << locale << "\" recursively starting with \"*\"");
+            return getChild(locale);
+        }
+        SAL_WARN_IF(
+            locale.isEmpty(), "configmgr",
+            ("access best-matching localized property value via \"*<locale>\""
+             " with empty <locale>; falling back to defaults"));
+        if (!locale.isEmpty()) {
+            // Find best match using an adaption of RFC 4647 lookup matching
+            // rules, removing "-" or "_" delimited segments from the end:
+            for (;;) {
+                rtl::Reference< ChildAccess > child(getChild(locale));
+                if (child.is()) {
+                    return child;
+                }
+                sal_Int32 i = locale.getLength() - 1;
+                while (i > 0 && locale[i] != '-' && locale[i] != '_') {
+                    --i;
+                }
+                if (i <= 0) {
+                    break;
+                }
+                locale = locale.copy(0, i);
+            }
+            // As a workaround for broken xcu data that does not use shortest
+            // xml:lang attributes, look for the first entry with the same first
+            // segment as the requested language tag before falling back to
+            // defaults (see fdo#33638):
+            assert(
+                !locale.isEmpty() && locale.indexOf('-') == -1 &&
+                locale.indexOf('_') == -1);
+            std::vector< rtl::Reference< ChildAccess > > children(
+                getAllChildren());
+            for (std::vector< rtl::Reference< ChildAccess > >::iterator i(
+                     children.begin());
+                 i != children.end(); ++i)
+            {
+                OUString name2((*i)->getNameInternal());
+                if (name2.match(locale) &&
+                    (name2.getLength() == locale.getLength() ||
+                     name2[locale.getLength()] == '-' ||
+                     name2[locale.getLength()] == '_'))
+                {
+                    return *i;
+                }
+            }
+        }
+        // Defaults are the "en-US" locale, the "en" locale, the empty string
+        // locale, the first child (if any), or a null ChildAccess, in that
+        // order:
+        rtl::Reference< ChildAccess > child(getChild("en-US"));
+        if (child.is()) {
+            return child;
+        }
+        child = getChild("en");
+        if (child.is()) {
+            return child;
+        }
+        child = getChild(OUString());
+        if (child.is()) {
+            return child;
+        }
+        std::vector< rtl::Reference< ChildAccess > > children(getAllChildren());
+        if (!children.empty()) {
+            return children.front();
+        }
+        return rtl::Reference< ChildAccess >();
+    }
     ModifiedChildren::iterator i(modifiedChildren_.find(name));
     return i == modifiedChildren_.end()
         ? getUnmodifiedChild(name) : getModifiedChild(i);
diff --git a/configmgr/source/childaccess.cxx b/configmgr/source/childaccess.cxx
index 3b5a8e2..99c4d2d 100644
--- a/configmgr/source/childaccess.cxx
+++ b/configmgr/source/childaccess.cxx
@@ -259,17 +259,6 @@ void ChildAccess::setProperty(
     localModifications->add(getRelativePath());
 }
 
-namespace
-{
-    rtl::OUString lcl_StripSegment(const rtl::OUString &rLocale)
-    {
-        sal_Int32 i = !rLocale.isEmpty() ? rLocale.getLength() - 1 : 0;
-        while (i > 0 && rLocale[i] != '-' && rLocale[i] != '_')
-            --i;
-        return rLocale.copy(0, i);
-    }
-}
-
 css::uno::Any ChildAccess::asValue() {
     if (changedValue_.get() != 0) {
         return *changedValue_;
@@ -280,66 +269,11 @@ css::uno::Any ChildAccess::asValue() {
             getComponents());
     case Node::KIND_LOCALIZED_PROPERTY:
         {
-            rtl::OUString sLocale(getRootAccess()->getLocale());
-            if (!Components::allLocales(sLocale))
-            {
-                rtl::Reference< ChildAccess > child;
-                // Find best match using an adaption of RFC 4647 lookup matching
-                // rules, removing "-" or "_" delimited segments from the end
-                while (1)
-                {
-                    child = getChild(sLocale);
-                    if (child.is())
-                        break;
-                    rtl::OUString sTmpLocale = lcl_StripSegment(sLocale);
-                    if (sTmpLocale.isEmpty())
-                        break;
-                    sLocale = sTmpLocale;
-                }
-
-                //Resolves: fdo#33638 Look for the first entry with the same
-                //first segment as the requested language tag, before falling
-                //back to en-US, etc.
-                typedef std::vector< rtl::Reference< ChildAccess > > ChildVector;
-                if (!child.is())
-                {
-                    const ChildVector &rAllChildren = getAllChildren();
-                    for (ChildVector::const_iterator aI = rAllChildren.begin(),
-                         aEnd = rAllChildren.end(); aI != aEnd; ++aI)
-                    {
-                        rtl::OUString sLanguage = lcl_StripSegment((*aI)->getNameInternal());
-                        if (sLocale == sLanguage)
-                        {
-                            child = *aI;
-                            break;
-                        }
-                    }
-                }
-
-                // defaults are the "en-US" locale, the "en" locale, the empty
-                // string locale, the first child (if any), or a nil value (even
-                // though it may be illegal for the given property), in that
-                // order:
-                if (!child.is())
-                {
-                    child = getChild(
-                        rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en-US")));
-                    if (!child.is())
-                    {
-                        child = getChild(
-                            rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en")));
-                        if (!child.is())
-                        {
-                            child = getChild(rtl::OUString());
-                            if (!child.is())
-                            {
-                                ChildVector all(getAllChildren());
-                                if (!all.empty())
-                                    child = all.front();
-                            }
-                        }
-                    }
-                }
+            OUString locale(getRootAccess()->getLocale());
+            if (!Components::allLocales(locale)) {
+                rtl::Reference< ChildAccess > child(getChild("*" + locale));
+                // As a last resort, return a nil value even though it may be
+                // illegal for the given property:
                 return child.is() ? child->asValue() : css::uno::Any();
             }
         }
diff --git a/configmgr/source/configmgr.component b/configmgr/source/configmgr.component
index 34d0399..b409478 100644
--- a/configmgr/source/configmgr.component
+++ b/configmgr/source/configmgr.component
@@ -30,7 +30,7 @@
     <singleton name="com.sun.star.configuration.theDefaultProvider"/>
   </implementation>
   <implementation name="com.sun.star.comp.configuration.ReadOnlyAccess">
-    <singleton name="com.sun.star.configuration.ReadOnlyAccess"/>
+    <service name="com.sun.star.configuration.ReadOnlyAccess"/>
   </implementation>
   <implementation name="com.sun.star.comp.configuration.ReadWriteAccess">
     <service name="com.sun.star.configuration.ReadWriteAccess"/>
diff --git a/configmgr/source/readonlyaccess.cxx b/configmgr/source/readonlyaccess.cxx
index d9ab2dc..264eae1 100644
--- a/configmgr/source/readonlyaccess.cxx
+++ b/configmgr/source/readonlyaccess.cxx
@@ -30,15 +30,21 @@
 #include "sal/config.h"
 
 #include "boost/noncopyable.hpp"
-#include "cppuhelper/implbase2.hxx"
-#include "com/sun/star/lang/XServiceInfo.hpp"
 #include "com/sun/star/container/NoSuchElementException.hpp"
 #include "com/sun/star/container/XHierarchicalNameAccess.hpp"
+#include "com/sun/star/lang/IllegalArgumentException.hpp"
+#include "com/sun/star/lang/NotInitializedException.hpp"
+#include "com/sun/star/lang/XInitialization.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/uno/Any.hxx"
+#include "com/sun/star/uno/Exception.hpp"
 #include "com/sun/star/uno/Reference.hxx"
 #include "com/sun/star/uno/RuntimeException.hpp"
 #include "com/sun/star/uno/Sequence.hxx"
 #include "com/sun/star/uno/XComponentContext.hpp"
 #include "com/sun/star/uno/XInterface.hpp"
+#include "cppuhelper/implbase3.hxx"
+#include "cppuhelper/weak.hxx"
 #include "osl/mutex.hxx"
 #include "rtl/ref.hxx"
 #include "rtl/ustring.h"
@@ -57,12 +63,15 @@ namespace {
 namespace css = com::sun::star;
 
 class Service:
-    public cppu::WeakImplHelper2<
-        css::lang::XServiceInfo, css::container::XHierarchicalNameAccess >,
+    public cppu::WeakImplHelper3<
+        css::lang::XServiceInfo, css::lang::XInitialization,
+        css::container::XHierarchicalNameAccess >,
     private boost::noncopyable
 {
 public:
-    Service(css::uno::Reference< css::uno::XComponentContext > const & context);
+    explicit Service(
+        css::uno::Reference< css::uno::XComponentContext > const & context):
+        context_(context) {}
 
 private:
     virtual ~Service() {}
@@ -79,30 +88,57 @@ private:
     getSupportedServiceNames() throw (css::uno::RuntimeException)
     { return read_only_access::getSupportedServiceNames(); }
 
+    virtual void SAL_CALL initialize(
+        css::uno::Sequence< css::uno::Any > const & aArguments)
+        throw (css::uno::Exception, css::uno::RuntimeException);
+
     virtual css::uno::Any SAL_CALL getByHierarchicalName(
         rtl::OUString const & aName)
         throw (
             css::container::NoSuchElementException, css::uno::RuntimeException)
-    { return root_->getByHierarchicalName(aName); }
+    { return getRoot()->getByHierarchicalName(aName); }
 
     virtual sal_Bool SAL_CALL hasByHierarchicalName(rtl::OUString const & aName)
         throw (css::uno::RuntimeException)
-    { return root_->hasByHierarchicalName(aName); }
+    { return getRoot()->hasByHierarchicalName(aName); }
+
+    rtl::Reference< RootAccess > getRoot();
 
+    css::uno::Reference< css::uno::XComponentContext > context_;
+
+    osl::Mutex mutex_;
     rtl::Reference< RootAccess > root_;
 };
 
-Service::Service(
-    css::uno::Reference< css::uno::XComponentContext > const & context)
+void Service::initialize(css::uno::Sequence< css::uno::Any > const & aArguments)
+    throw (css::uno::Exception, css::uno::RuntimeException)
 {
-    osl::MutexGuard guard(*lock());
-    Components & components = Components::getSingleton(context);
-    root_ = new RootAccess(
-        components, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")),
-        rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*")), false);
+    OUString locale;
+    if (aArguments.getLength() != 1 || !(aArguments[0] >>= locale)) {
+        throw css::lang::IllegalArgumentException(
+            "not exactly one string argument",
+            static_cast< cppu::OWeakObject * >(this), -1);
+    }
+    osl::MutexGuard g1(mutex_);
+    if (root_.is()) {
+        throw css::uno::RuntimeException(
+            "already initialized", static_cast< cppu::OWeakObject * >(this));
+    }
+    osl::MutexGuard g2(*lock());
+    Components & components = Components::getSingleton(context_);
+    root_ = new RootAccess(components, "/", locale, false);
     components.addRootAccess(root_);
 }
 
+rtl::Reference< RootAccess > Service::getRoot() {
+    osl::MutexGuard g(mutex_);
+    if (!root_.is()) {
+        throw css::lang::NotInitializedException(
+            "not initialized", static_cast< cppu::OWeakObject * >(this));
+    }
+    return root_;
+}
+
 }
 
 css::uno::Reference< css::uno::XInterface > create(
diff --git a/configmgr/source/readwriteaccess.cxx b/configmgr/source/readwriteaccess.cxx
index 0e4415f..5d8d1de 100644
--- a/configmgr/source/readwriteaccess.cxx
+++ b/configmgr/source/readwriteaccess.cxx
@@ -30,18 +30,24 @@
 #include "sal/config.h"
 
 #include "boost/noncopyable.hpp"
-#include "cppuhelper/implbase2.hxx"
+#include "com/sun/star/configuration/XReadWriteAccess.hpp"
+#include "com/sun/star/container/NoSuchElementException.hpp"
 #include "com/sun/star/lang/IllegalArgumentException.hpp"
+#include "com/sun/star/lang/NotInitializedException.hpp"
 #include "com/sun/star/lang/WrappedTargetException.hpp"
+#include "com/sun/star/lang/XInitialization.hpp"
 #include "com/sun/star/lang/XServiceInfo.hpp"
-#include "com/sun/star/container/NoSuchElementException.hpp"
-#include "com/sun/star/configuration/XReadWriteAccess.hpp"
+#include "com/sun/star/uno/Any.hxx"
+#include "com/sun/star/uno/Exception.hpp"
 #include "com/sun/star/uno/Reference.hxx"
 #include "com/sun/star/uno/RuntimeException.hpp"
 #include "com/sun/star/uno/Sequence.hxx"
 #include "com/sun/star/uno/XComponentContext.hpp"
 #include "com/sun/star/uno/XInterface.hpp"
 #include "com/sun/star/util/ChangesSet.hpp"
+#include "cppuhelper/implbase3.hxx"
+#include "cppuhelper/weak.hxx"
+#include "osl/mutex.hxx"
 #include "rtl/ref.hxx"
 #include "rtl/ustring.h"
 #include "rtl/ustring.hxx"
@@ -59,12 +65,15 @@ namespace {
 namespace css = com::sun::star;
 
 class Service:
-    public cppu::WeakImplHelper2<
-        css::lang::XServiceInfo, css::configuration::XReadWriteAccess >,
+    public cppu::WeakImplHelper3<
+        css::lang::XServiceInfo, css::lang::XInitialization,
+        css::configuration::XReadWriteAccess >,
     private boost::noncopyable
 {
 public:
-    Service(css::uno::Reference< css::uno::XComponentContext > const & context);
+    explicit Service(
+        css::uno::Reference< css::uno::XComponentContext > const & context):
+        context_(context) {}
 
 private:
     virtual ~Service() {}
@@ -81,15 +90,19 @@ private:
     getSupportedServiceNames() throw (css::uno::RuntimeException)
     { return read_write_access::getSupportedServiceNames(); }
 
+    virtual void SAL_CALL initialize(
+        css::uno::Sequence< css::uno::Any > const & aArguments)
+        throw (css::uno::Exception, css::uno::RuntimeException);
+
     virtual css::uno::Any SAL_CALL getByHierarchicalName(
         rtl::OUString const & aName)
         throw (
             css::container::NoSuchElementException, css::uno::RuntimeException)
-    { return root_->getByHierarchicalName(aName); }
+    { return getRoot()->getByHierarchicalName(aName); }
 
     virtual sal_Bool SAL_CALL hasByHierarchicalName(rtl::OUString const & aName)
         throw (css::uno::RuntimeException)
-    { return root_->hasByHierarchicalName(aName); }
+    { return getRoot()->hasByHierarchicalName(aName); }
 
     virtual void SAL_CALL replaceByHierarchicalName(
         rtl::OUString const & aName, css::uno::Any const & aElement)
@@ -97,34 +110,57 @@ private:
             css::lang::IllegalArgumentException,
             css::container::NoSuchElementException,
             css::lang::WrappedTargetException, css::uno::RuntimeException)
-    { root_->replaceByHierarchicalName(aName, aElement); }
+    { getRoot()->replaceByHierarchicalName(aName, aElement); }
 
     virtual void SAL_CALL commitChanges()
         throw (css::lang::WrappedTargetException, css::uno::RuntimeException)
-    { root_->commitChanges(); }
+    { getRoot()->commitChanges(); }
 
     virtual sal_Bool SAL_CALL hasPendingChanges()
         throw (css::uno::RuntimeException)
-    { return root_->hasPendingChanges(); }
+    { return getRoot()->hasPendingChanges(); }
 
     virtual css::util::ChangesSet SAL_CALL getPendingChanges()
         throw (css::uno::RuntimeException)
-    { return root_->getPendingChanges(); }
+    { return getRoot()->getPendingChanges(); }
 
+    rtl::Reference< RootAccess > getRoot();
+
+    css::uno::Reference< css::uno::XComponentContext > context_;
+
+    osl::Mutex mutex_;
     rtl::Reference< RootAccess > root_;
 };
 
-Service::Service(
-    css::uno::Reference< css::uno::XComponentContext > const & context)
+void Service::initialize(css::uno::Sequence< css::uno::Any > const & aArguments)
+    throw (css::uno::Exception, css::uno::RuntimeException)
 {
-    osl::MutexGuard guard(*lock());
-    Components & components = Components::getSingleton(context);
-    root_ = new RootAccess(
-        components, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")),
-        rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("*")), true);
+    OUString locale;
+    if (aArguments.getLength() != 1 || !(aArguments[0] >>= locale)) {
+        throw css::lang::IllegalArgumentException(
+            "not exactly one string argument",
+            static_cast< cppu::OWeakObject * >(this), -1);
+    }
+    osl::MutexGuard g1(mutex_);
+    if (root_.is()) {
+        throw css::uno::RuntimeException(
+            "already initialized", static_cast< cppu::OWeakObject * >(this));
+    }
+    osl::MutexGuard g2(*lock());
+    Components & components = Components::getSingleton(context_);
+    root_ = new RootAccess(components, "/", locale, true);
     components.addRootAccess(root_);
 }
 
+rtl::Reference< RootAccess > Service::getRoot() {
+    osl::MutexGuard g(mutex_);
+    if (!root_.is()) {
+        throw css::lang::NotInitializedException(
+            "not initialized", static_cast< cppu::OWeakObject * >(this));
+    }
+    return root_;
+}
+
 }
 
 css::uno::Reference< css::uno::XInterface > create(
diff --git a/offapi/com/sun/star/configuration/ReadOnlyAccess.idl b/offapi/com/sun/star/configuration/ReadOnlyAccess.idl
index aaeb6da..1da0593 100644
--- a/offapi/com/sun/star/configuration/ReadOnlyAccess.idl
+++ b/offapi/com/sun/star/configuration/ReadOnlyAccess.idl
@@ -34,13 +34,20 @@
 
 module com { module sun { module star { module configuration {
 
-/* Provides easy read-only access to the complete configuration.
+/** Provides easy read-only access to the complete configuration.
 
-   <p>This singleton is still unpublished and unstable.</p>
+    <p>This service is still unpublished and unstable.</p>
 
-   @since LibreOffice 3.6
+    @since LibreOffice 3.7
 */
-singleton ReadOnlyAccess: com::sun::star::container::XHierarchicalNameAccess;
+service ReadOnlyAccess: com::sun::star::container::XHierarchicalNameAccess {
+    /** Service constructor.
+
+        @param locale a string representation of the locale to use for localized
+        properties; use <code>*</code> for all-locale access
+    */
+    create([in] string locale);
+};
 
 }; }; }; };
 
diff --git a/offapi/com/sun/star/configuration/ReadWriteAccess.idl b/offapi/com/sun/star/configuration/ReadWriteAccess.idl
index bae50bc..2522baa 100644
--- a/offapi/com/sun/star/configuration/ReadWriteAccess.idl
+++ b/offapi/com/sun/star/configuration/ReadWriteAccess.idl
@@ -34,13 +34,20 @@
 
 module com { module sun { module star { module configuration {
 
-/* Provides easy read/write access to the complete configuration.
+/** Provides easy read/write access to the complete configuration.
 
-   <p>This service is still unpublished and unstable.</p>
+    <p>This service is still unpublished and unstable.</p>
 
-   @since LibreOffice 3.6
+    @since LibreOffice 3.7
 */
-service ReadWriteAccess: com::sun::star::configuration::XReadWriteAccess;
+service ReadWriteAccess: com::sun::star::configuration::XReadWriteAccess {
+    /** Service constructor.
+
+        @param locale a string representation of the locale to use for localized
+        properties; use <code>*</code> for all-locale access
+    */
+    create([in] string locale);
+};
 
 }; }; }; };
 


More information about the Libreoffice-commits mailing list