LCOV - code coverage report
Current view: top level - framework/source/uiconfiguration - moduleuiconfigurationmanager.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 499 776 64.3 %
Date: 2015-06-13 12:38:46 Functions: 45 53 84.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <accelerators/presethandler.hxx>
      21             : #include <uiconfiguration/moduleimagemanager.hxx>
      22             : #include <stdtypes.h>
      23             : #include <uielement/constitemcontainer.hxx>
      24             : #include <uielement/rootitemcontainer.hxx>
      25             : #include <uielement/uielementtypenames.hxx>
      26             : #include <framework/menuconfiguration.hxx>
      27             : #include <framework/toolboxconfiguration.hxx>
      28             : 
      29             : #include <framework/statusbarconfiguration.hxx>
      30             : 
      31             : #include <com/sun/star/ui/UIElementType.hpp>
      32             : #include <com/sun/star/ui/ConfigurationEvent.hpp>
      33             : #include <com/sun/star/ui/ModuleAcceleratorConfiguration.hpp>
      34             : #include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
      35             : #include <com/sun/star/ui/XModuleUIConfigurationManager2.hpp>
      36             : #include <com/sun/star/lang/DisposedException.hpp>
      37             : #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
      38             : #include <com/sun/star/beans/XPropertySet.hpp>
      39             : #include <com/sun/star/embed/ElementModes.hpp>
      40             : #include <com/sun/star/embed/XTransactedObject.hpp>
      41             : #include <com/sun/star/container/XNameAccess.hpp>
      42             : #include <com/sun/star/container/XIndexContainer.hpp>
      43             : #include <com/sun/star/io/XStream.hpp>
      44             : #include <com/sun/star/lang/XServiceInfo.hpp>
      45             : #include <com/sun/star/lang/XComponent.hpp>
      46             : 
      47             : #include <cppuhelper/implbase3.hxx>
      48             : #include <cppuhelper/interfacecontainer.hxx>
      49             : #include <cppuhelper/supportsservice.hxx>
      50             : #include <vcl/svapp.hxx>
      51             : #include <rtl/ref.hxx>
      52             : #include <rtl/ustrbuf.hxx>
      53             : #include <comphelper/sequenceashashmap.hxx>
      54             : 
      55             : using namespace css;
      56             : using namespace com::sun::star::uno;
      57             : using namespace com::sun::star::io;
      58             : using namespace com::sun::star::embed;
      59             : using namespace com::sun::star::lang;
      60             : using namespace com::sun::star::container;
      61             : using namespace com::sun::star::beans;
      62             : using namespace framework;
      63             : 
      64             : #define RESOURCETYPE_MENUBAR   "menubar"
      65             : #define RESOURCETYPE_TOOLBAR   "toolbar"
      66             : #define RESOURCETYPE_STATUSBAR "statusbar"
      67             : 
      68             : namespace {
      69             : 
      70             : class ModuleUIConfigurationManager : public cppu::WeakImplHelper3<
      71             :                                        css::lang::XServiceInfo,
      72             :                                        css::lang::XComponent,
      73             :                                        css::ui::XModuleUIConfigurationManager2 >
      74             : {
      75             : public:
      76             :     ModuleUIConfigurationManager(
      77             :             const css::uno::Reference< css::uno::XComponentContext >& xServiceManager,
      78             :             const css::uno::Sequence< css::uno::Any >& aArguments);
      79             : 
      80             :     virtual ~ModuleUIConfigurationManager();
      81             : 
      82           3 :     virtual OUString SAL_CALL getImplementationName()
      83             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
      84             :     {
      85           3 :         return OUString("com.sun.star.comp.framework.ModuleUIConfigurationManager");
      86             :     }
      87             : 
      88           0 :     virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName)
      89             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
      90             :     {
      91           0 :         return cppu::supportsService(this, ServiceName);
      92             :     }
      93             : 
      94           0 :     virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames()
      95             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
      96             :     {
      97           0 :         css::uno::Sequence< OUString > aSeq(1);
      98           0 :         aSeq[0] = "com.sun.star.ui.ModuleUIConfigurationManager";
      99           0 :         return aSeq;
     100             :     }
     101             : 
     102             :     // XComponent
     103             :     virtual void SAL_CALL dispose() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     104             :     virtual void SAL_CALL addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     105             :     virtual void SAL_CALL removeEventListener( const css::uno::Reference< css::lang::XEventListener >& aListener ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     106             : 
     107             :     // XUIConfiguration
     108             :     virtual void SAL_CALL addConfigurationListener( const css::uno::Reference< css::ui::XUIConfigurationListener >& Listener ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     109             :     virtual void SAL_CALL removeConfigurationListener( const css::uno::Reference< css::ui::XUIConfigurationListener >& Listener ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     110             : 
     111             :     // XUIConfigurationManager
     112             :     virtual void SAL_CALL reset() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     113             :     virtual css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > SAL_CALL getUIElementsInfo( sal_Int16 ElementType ) throw (css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     114             :     virtual css::uno::Reference< css::container::XIndexContainer > SAL_CALL createSettings(  ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     115             :     virtual sal_Bool SAL_CALL hasSettings( const OUString& ResourceURL ) throw (css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     116             :     virtual css::uno::Reference< css::container::XIndexAccess > SAL_CALL getSettings( const OUString& ResourceURL, sal_Bool bWriteable ) throw (css::container::NoSuchElementException, css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     117             :     virtual void SAL_CALL replaceSettings( const OUString& ResourceURL, const css::uno::Reference< css::container::XIndexAccess >& aNewData ) throw (css::container::NoSuchElementException, css::lang::IllegalArgumentException, css::lang::IllegalAccessException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     118             :     virtual void SAL_CALL removeSettings( const OUString& ResourceURL ) throw (css::container::NoSuchElementException, css::lang::IllegalArgumentException, css::lang::IllegalAccessException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     119             :     virtual void SAL_CALL insertSettings( const OUString& NewResourceURL, const css::uno::Reference< css::container::XIndexAccess >& aNewData ) throw (css::container::ElementExistException, css::lang::IllegalArgumentException, css::lang::IllegalAccessException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     120             :     virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getImageManager() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     121             :     virtual css::uno::Reference< css::ui::XAcceleratorConfiguration > SAL_CALL getShortCutManager() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     122             :     virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getEventsManager() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     123             : 
     124             :     // XModuleUIConfigurationManager
     125             :     virtual sal_Bool SAL_CALL isDefaultSettings( const OUString& ResourceURL ) throw (css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     126             :     virtual css::uno::Reference< css::container::XIndexAccess > SAL_CALL getDefaultSettings( const OUString& ResourceURL ) throw (css::container::NoSuchElementException, css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     127             : 
     128             :     // XUIConfigurationPersistence
     129             :     virtual void SAL_CALL reload() throw (css::uno::Exception, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     130             :     virtual void SAL_CALL store() throw (css::uno::Exception, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     131             :     virtual void SAL_CALL storeToStorage( const css::uno::Reference< css::embed::XStorage >& Storage ) throw (css::uno::Exception, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     132             :     virtual sal_Bool SAL_CALL isModified() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     133             :     virtual sal_Bool SAL_CALL isReadOnly() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     134             : 
     135             : private:
     136             :     // private data types
     137             :     enum Layer
     138             :     {
     139             :         LAYER_DEFAULT,
     140             :         LAYER_USERDEFINED,
     141             :         LAYER_COUNT
     142             :     };
     143             : 
     144             :     enum NotifyOp
     145             :     {
     146             :         NotifyOp_Remove,
     147             :         NotifyOp_Insert,
     148             :         NotifyOp_Replace
     149             :     };
     150             : 
     151      112985 :     struct UIElementInfo
     152             :     {
     153       22597 :         UIElementInfo( const OUString& rResourceURL, const OUString& rUIName ) :
     154       22597 :             aResourceURL( rResourceURL), aUIName( rUIName ) {}
     155             :         OUString   aResourceURL;
     156             :         OUString   aUIName;
     157             :     };
     158             : 
     159       11204 :     struct UIElementData
     160             :     {
     161        2250 :         UIElementData() : bModified( false ), bDefault( true ), bDefaultNode( true ) {};
     162             : 
     163             :         OUString aResourceURL;
     164             :         OUString aName;
     165             :         bool          bModified;        // has been changed since last storing
     166             :         bool          bDefault;         // default settings
     167             :         bool          bDefaultNode;     // this is a default layer element data
     168             :         css::uno::Reference< css::container::XIndexAccess > xSettings;
     169             :     };
     170             : 
     171             :     typedef std::unordered_map< OUString, UIElementData, OUStringHash, std::equal_to< OUString > > UIElementDataHashMap;
     172             : 
     173        2208 :     struct UIElementType
     174             :     {
     175        2240 :         UIElementType() : bModified( false ),
     176             :                           bLoaded( false ),
     177             :                           bDefaultLayer( false ),
     178        2240 :                           nElementType( css::ui::UIElementType::UNKNOWN ) {}
     179             : 
     180             :         bool                                                              bModified;
     181             :         bool                                                              bLoaded;
     182             :         bool                                                              bDefaultLayer;
     183             :         sal_Int16                                                         nElementType;
     184             :         UIElementDataHashMap                                              aElementsHashMap;
     185             :         css::uno::Reference< css::embed::XStorage > xStorage;
     186             :     };
     187             : 
     188             :     typedef std::vector< UIElementType > UIElementTypesVector;
     189             :     typedef std::vector< css::ui::ConfigurationEvent > ConfigEventNotifyContainer;
     190             :     typedef std::unordered_map< OUString, UIElementInfo, OUStringHash, std::equal_to< OUString > > UIElementInfoHashMap;
     191             : 
     192             :     void            impl_Initialize();
     193             :     void            implts_notifyContainerListener( const css::ui::ConfigurationEvent& aEvent, NotifyOp eOp );
     194             :     void            impl_fillSequenceWithElementTypeInfo( UIElementInfoHashMap& aUIElementInfoCollection, sal_Int16 nElementType );
     195             :     void            impl_preloadUIElementTypeList( Layer eLayer, sal_Int16 nElementType );
     196             :     UIElementData*  impl_findUIElementData( const OUString& aResourceURL, sal_Int16 nElementType, bool bLoad = true );
     197             :     void            impl_requestUIElementData( sal_Int16 nElementType, Layer eLayer, UIElementData& aUIElementData );
     198             :     void            impl_storeElementTypeData( css::uno::Reference< css::embed::XStorage > xStorage, UIElementType& rElementType, bool bResetModifyState = true );
     199             :     void            impl_resetElementTypeData( UIElementType& rUserElementType, UIElementType& rDefaultElementType, ConfigEventNotifyContainer& rRemoveNotifyContainer, ConfigEventNotifyContainer& rReplaceNotifyContainer );
     200             :     void            impl_reloadElementTypeData( UIElementType& rUserElementType, UIElementType& rDefaultElementType, ConfigEventNotifyContainer& rRemoveNotifyContainer, ConfigEventNotifyContainer& rReplaceNotifyContainer );
     201             : 
     202             :     UIElementTypesVector                                                            m_aUIElements[LAYER_COUNT];
     203             :     PresetHandler*                                                                  m_pStorageHandler[css::ui::UIElementType::COUNT];
     204             :     css::uno::Reference< css::embed::XStorage >               m_xDefaultConfigStorage;
     205             :     css::uno::Reference< css::embed::XStorage >               m_xUserConfigStorage;
     206             :     bool                                                                            m_bReadOnly;
     207             :     bool                                                                            m_bModified;
     208             :     bool                                                                            m_bConfigRead;
     209             :     bool                                                                            m_bDisposed;
     210             :     OUString                                                                   m_aXMLPostfix;
     211             :     OUString                                                                   m_aPropUIName;
     212             :     OUString                                                                   m_aPropResourceURL;
     213             :     OUString                                                                   m_aModuleIdentifier;
     214             :     OUString                                                                   m_aModuleShortName;
     215             :     css::uno::Reference< css::embed::XTransactedObject >      m_xUserRootCommit;
     216             :     css::uno::Reference< css::uno::XComponentContext >        m_xContext;
     217             :     osl::Mutex m_mutex;
     218             :     ::cppu::OMultiTypeInterfaceContainerHelper                                      m_aListenerContainer;   /// container for ALL Listener
     219             :     css::uno::Reference< css::lang::XComponent >              m_xModuleImageManager;
     220             :     css::uno::Reference< css::ui::XAcceleratorConfiguration > m_xModuleAcceleratorManager;
     221             : };
     222             : 
     223             : // important: The order and position of the elements must match the constant
     224             : // definition of "::com::sun::star::ui::UIElementType"
     225             : static const char* UIELEMENTTYPENAMES[] =
     226             : {
     227             :     "",  // Dummy value for unknown!
     228             :     UIELEMENTTYPE_MENUBAR_NAME,
     229             :     UIELEMENTTYPE_POPUPMENU_NAME,
     230             :     UIELEMENTTYPE_TOOLBAR_NAME,
     231             :     UIELEMENTTYPE_STATUSBAR_NAME,
     232             :     UIELEMENTTYPE_FLOATINGWINDOW_NAME,
     233             :     UIELEMENTTYPE_PROGRESSBAR_NAME,
     234             :     UIELEMENTTYPE_TOOLPANEL_NAME
     235             : };
     236             : 
     237             : static const char       RESOURCEURL_PREFIX[] = "private:resource/";
     238             : static const sal_Int32  RESOURCEURL_PREFIX_SIZE = 17;
     239             : static const char       RESOURCEURL_CUSTOM_ELEMENT[] = "custom_";
     240             : 
     241       26368 : static sal_Int16 RetrieveTypeFromResourceURL( const OUString& aResourceURL )
     242             : {
     243             : 
     244       52736 :     if (( aResourceURL.startsWith( RESOURCEURL_PREFIX ) ) &&
     245       26368 :         ( aResourceURL.getLength() > RESOURCEURL_PREFIX_SIZE ))
     246             :     {
     247       26368 :         OUString    aTmpStr     = aResourceURL.copy( RESOURCEURL_PREFIX_SIZE );
     248       26368 :         sal_Int32   nIndex      = aTmpStr.indexOf( '/' );
     249       26368 :         if (( nIndex > 0 ) &&  ( aTmpStr.getLength() > nIndex ))
     250             :         {
     251       26368 :             OUString aTypeStr( aTmpStr.copy( 0, nIndex ));
     252       99070 :             for ( int i = 0; i < ui::UIElementType::COUNT; i++ )
     253             :             {
     254       99070 :                 if ( aTypeStr.equalsAscii( UIELEMENTTYPENAMES[i] ))
     255       26368 :                     return sal_Int16( i );
     256           0 :             }
     257           0 :         }
     258             :     }
     259             : 
     260           0 :     return ui::UIElementType::UNKNOWN;
     261             : }
     262             : 
     263           4 : static OUString RetrieveNameFromResourceURL( const OUString& aResourceURL )
     264             : {
     265           8 :     if (( aResourceURL.startsWith( RESOURCEURL_PREFIX ) ) &&
     266           4 :         ( aResourceURL.getLength() > RESOURCEURL_PREFIX_SIZE ))
     267             :     {
     268           4 :         sal_Int32 nIndex = aResourceURL.lastIndexOf( '/' );
     269           4 :         if (( nIndex > 0 ) && (( nIndex+1 ) < aResourceURL.getLength()))
     270           4 :             return aResourceURL.copy( nIndex+1 );
     271             :     }
     272             : 
     273           0 :     return OUString();
     274             : }
     275             : 
     276        3294 : void ModuleUIConfigurationManager::impl_fillSequenceWithElementTypeInfo( UIElementInfoHashMap& aUIElementInfoCollection, sal_Int16 nElementType )
     277             : {
     278             :     // preload list of element types on demand
     279        3294 :     impl_preloadUIElementTypeList( LAYER_USERDEFINED, nElementType );
     280        3294 :     impl_preloadUIElementTypeList( LAYER_DEFAULT, nElementType );
     281             : 
     282        3294 :     UIElementDataHashMap& rUserElements = m_aUIElements[LAYER_USERDEFINED][nElementType].aElementsHashMap;
     283        3294 :     UIElementDataHashMap::const_iterator pUserIter = rUserElements.begin();
     284             : 
     285        3294 :     OUString aCustomUrlPrefix( RESOURCEURL_CUSTOM_ELEMENT );
     286        6588 :     while ( pUserIter != rUserElements.end() )
     287             :     {
     288           0 :         sal_Int32 nIndex = pUserIter->second.aResourceURL.indexOf( aCustomUrlPrefix, RESOURCEURL_PREFIX_SIZE );
     289           0 :         if ( nIndex > RESOURCEURL_PREFIX_SIZE )
     290             :         {
     291             :             // Performance: Retrieve user interface name only for custom user interface elements.
     292             :             // It's only used by them!
     293           0 :             UIElementData* pDataSettings = impl_findUIElementData( pUserIter->second.aResourceURL, nElementType );
     294           0 :             if ( pDataSettings )
     295             :             {
     296             :                 // Retrieve user interface name from XPropertySet interface
     297           0 :                 OUString aUIName;
     298           0 :                 Reference< XPropertySet > xPropSet( pDataSettings->xSettings, UNO_QUERY );
     299           0 :                 if ( xPropSet.is() )
     300             :                 {
     301           0 :                     Any a = xPropSet->getPropertyValue( m_aPropUIName );
     302           0 :                     a >>= aUIName;
     303             :                 }
     304             : 
     305           0 :                 UIElementInfo aInfo( pUserIter->second.aResourceURL, aUIName );
     306           0 :                 aUIElementInfoCollection.insert( UIElementInfoHashMap::value_type( pUserIter->second.aResourceURL, aInfo ));
     307             :             }
     308             :         }
     309             :         else
     310             :         {
     311             :             // The user interface name for standard user interface elements is stored in the WindowState.xcu file
     312           0 :             UIElementInfo aInfo( pUserIter->second.aResourceURL, OUString() );
     313           0 :             aUIElementInfoCollection.insert( UIElementInfoHashMap::value_type( pUserIter->second.aResourceURL, aInfo ));
     314             :         }
     315           0 :         ++pUserIter;
     316             :     }
     317             : 
     318        3294 :     UIElementDataHashMap& rDefaultElements = m_aUIElements[LAYER_DEFAULT][nElementType].aElementsHashMap;
     319        3294 :     UIElementDataHashMap::const_iterator pDefIter = rDefaultElements.begin();
     320             : 
     321       29185 :     while ( pDefIter != rDefaultElements.end() )
     322             :     {
     323       22597 :         UIElementInfoHashMap::const_iterator pIterInfo = aUIElementInfoCollection.find( pDefIter->second.aResourceURL );
     324       22597 :         if ( pIterInfo == aUIElementInfoCollection.end() )
     325             :         {
     326       22597 :             sal_Int32 nIndex = pDefIter->second.aResourceURL.indexOf( aCustomUrlPrefix, RESOURCEURL_PREFIX_SIZE );
     327       22597 :             if ( nIndex > RESOURCEURL_PREFIX_SIZE )
     328             :             {
     329             :                 // Performance: Retrieve user interface name only for custom user interface elements.
     330             :                 // It's only used by them!
     331           0 :                 UIElementData* pDataSettings = impl_findUIElementData( pDefIter->second.aResourceURL, nElementType );
     332           0 :                 if ( pDataSettings )
     333             :                 {
     334             :                     // Retrieve user interface name from XPropertySet interface
     335           0 :                     OUString aUIName;
     336           0 :                     Reference< XPropertySet > xPropSet( pDataSettings->xSettings, UNO_QUERY );
     337           0 :                     if ( xPropSet.is() )
     338             :                     {
     339           0 :                         Any a = xPropSet->getPropertyValue( m_aPropUIName );
     340           0 :                         a >>= aUIName;
     341             :                     }
     342             : 
     343           0 :                     UIElementInfo aInfo( pDefIter->second.aResourceURL, aUIName );
     344           0 :                     aUIElementInfoCollection.insert( UIElementInfoHashMap::value_type( pDefIter->second.aResourceURL, aInfo ));
     345             :                 }
     346             :             }
     347             :             else
     348             :             {
     349             :                 // The user interface name for standard user interface elements is stored in the WindowState.xcu file
     350       22597 :                 UIElementInfo aInfo( pDefIter->second.aResourceURL, OUString() );
     351       22597 :                 aUIElementInfoCollection.insert( UIElementInfoHashMap::value_type( pDefIter->second.aResourceURL, aInfo ));
     352             :             }
     353             :         }
     354             : 
     355       22597 :         ++pDefIter;
     356        3294 :     }
     357        3294 : }
     358             : 
     359       59325 : void ModuleUIConfigurationManager::impl_preloadUIElementTypeList( Layer eLayer, sal_Int16 nElementType )
     360             : {
     361       59325 :     UIElementType& rElementTypeData = m_aUIElements[eLayer][nElementType];
     362             : 
     363       59325 :     if ( !rElementTypeData.bLoaded )
     364             :     {
     365       53890 :         Reference< XStorage > xElementTypeStorage = rElementTypeData.xStorage;
     366       53890 :         if ( xElementTypeStorage.is() )
     367             :         {
     368       53722 :             OUStringBuffer aBuf( RESOURCEURL_PREFIX_SIZE );
     369       53722 :             aBuf.appendAscii( RESOURCEURL_PREFIX );
     370       53722 :             aBuf.appendAscii( UIELEMENTTYPENAMES[ nElementType ] );
     371       53722 :             aBuf.appendAscii( "/" );
     372      107444 :             OUString aResURLPrefix( aBuf.makeStringAndClear() );
     373             : 
     374       53722 :             UIElementDataHashMap& rHashMap = rElementTypeData.aElementsHashMap;
     375      107444 :             Sequence< OUString > aUIElementNames = xElementTypeStorage->getElementNames();
     376       55968 :             for ( sal_Int32 n = 0; n < aUIElementNames.getLength(); n++ )
     377             :             {
     378        2246 :                 UIElementData aUIElementData;
     379             : 
     380             :                 // Resource name must be without ".xml"
     381        2246 :                 sal_Int32 nIndex = aUIElementNames[n].lastIndexOf( '.' );
     382        2246 :                 if (( nIndex > 0 ) && ( nIndex < aUIElementNames[n].getLength() ))
     383             :                 {
     384        2246 :                     OUString aExtension( aUIElementNames[n].copy( nIndex+1 ));
     385        4492 :                     OUString aUIElementName( aUIElementNames[n].copy( 0, nIndex ));
     386             : 
     387        4492 :                     if (!aUIElementName.isEmpty() &&
     388        2246 :                         ( aExtension.equalsIgnoreAsciiCase("xml")))
     389             :                     {
     390        2246 :                         aUIElementData.aResourceURL = aResURLPrefix + aUIElementName;
     391        2246 :                         aUIElementData.aName        = aUIElementNames[n];
     392             : 
     393        2246 :                         if ( eLayer == LAYER_USERDEFINED )
     394             :                         {
     395           0 :                             aUIElementData.bModified    = false;
     396           0 :                             aUIElementData.bDefault     = false;
     397           0 :                             aUIElementData.bDefaultNode = false;
     398             :                         }
     399             : 
     400             :                         // Create std::unordered_map entries for all user interface elements inside the storage. We don't load the
     401             :                         // settings to speed up the process.
     402        2246 :                         rHashMap.insert( UIElementDataHashMap::value_type( aUIElementData.aResourceURL, aUIElementData ));
     403        2246 :                     }
     404             :                 }
     405        2246 :                 rElementTypeData.bLoaded = true;
     406       55968 :             }
     407       53890 :         }
     408             :     }
     409             : 
     410       59325 : }
     411             : 
     412         244 : void ModuleUIConfigurationManager::impl_requestUIElementData( sal_Int16 nElementType, Layer eLayer, UIElementData& aUIElementData )
     413             : {
     414         244 :     UIElementType& rElementTypeData = m_aUIElements[eLayer][nElementType];
     415             : 
     416         244 :     Reference< XStorage > xElementTypeStorage = rElementTypeData.xStorage;
     417         244 :     if ( xElementTypeStorage.is() && !aUIElementData.aName.isEmpty() )
     418             :     {
     419             :         try
     420             :         {
     421         244 :             Reference< XStream > xStream = xElementTypeStorage->openStreamElement( aUIElementData.aName, ElementModes::READ );
     422         244 :             Reference< XInputStream > xInputStream = xStream->getInputStream();
     423             : 
     424         244 :             if ( xInputStream.is() )
     425             :             {
     426         244 :                 switch ( nElementType )
     427             :                 {
     428             :                     case ::com::sun::star::ui::UIElementType::UNKNOWN:
     429           0 :                     break;
     430             : 
     431             :                     case ::com::sun::star::ui::UIElementType::MENUBAR:
     432             :                     {
     433             :                         try
     434             :                         {
     435          61 :                             MenuConfiguration aMenuCfg( m_xContext );
     436         122 :                             Reference< XIndexAccess > xContainer( aMenuCfg.CreateMenuBarConfigurationFromXML( xInputStream ));
     437          61 :                             RootItemContainer* pRootItemContainer = RootItemContainer::GetImplementation( xContainer );
     438          61 :                             if ( pRootItemContainer )
     439          61 :                                 aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( pRootItemContainer, true ) ), UNO_QUERY );
     440             :                             else
     441           0 :                                 aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( xContainer, true ) ), UNO_QUERY );
     442         122 :                             return;
     443             :                         }
     444           0 :                         catch ( const ::com::sun::star::lang::WrappedTargetException& )
     445             :                         {
     446             :                         }
     447             :                     }
     448           0 :                     break;
     449             : 
     450             :                     case ::com::sun::star::ui::UIElementType::POPUPMENU:
     451             :                     {
     452           0 :                         break;
     453             :                     }
     454             : 
     455             :                     case ::com::sun::star::ui::UIElementType::TOOLBAR:
     456             :                     {
     457             :                         try
     458             :                         {
     459         125 :                             Reference< XIndexContainer > xIndexContainer( static_cast< OWeakObject * >( new RootItemContainer() ), UNO_QUERY );
     460         125 :                             ToolBoxConfiguration::LoadToolBox( m_xContext, xInputStream, xIndexContainer );
     461         125 :                             RootItemContainer* pRootItemContainer = RootItemContainer::GetImplementation( xIndexContainer );
     462         125 :                             aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( pRootItemContainer, true ) ), UNO_QUERY );
     463         125 :                             return;
     464             :                         }
     465           0 :                         catch ( const ::com::sun::star::lang::WrappedTargetException& )
     466             :                         {
     467             :                         }
     468             : 
     469           0 :                         break;
     470             :                     }
     471             : 
     472             :                     case ::com::sun::star::ui::UIElementType::STATUSBAR:
     473             :                     {
     474             :                         try
     475             :                         {
     476          58 :                             Reference< XIndexContainer > xIndexContainer( static_cast< OWeakObject * >( new RootItemContainer() ), UNO_QUERY );
     477          58 :                             StatusBarConfiguration::LoadStatusBar( m_xContext, xInputStream, xIndexContainer );
     478          58 :                             RootItemContainer* pRootItemContainer = RootItemContainer::GetImplementation( xIndexContainer );
     479          58 :                             aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( pRootItemContainer, true ) ), UNO_QUERY );
     480          58 :                             return;
     481             :                         }
     482           0 :                         catch ( const ::com::sun::star::lang::WrappedTargetException& )
     483             :                         {
     484             :                         }
     485             : 
     486           0 :                         break;
     487             :                     }
     488             : 
     489             :                     case ::com::sun::star::ui::UIElementType::FLOATINGWINDOW:
     490             :                     {
     491           0 :                         break;
     492             :                     }
     493             :                 }
     494           0 :             }
     495             :         }
     496           0 :         catch ( const ::com::sun::star::embed::InvalidStorageException& )
     497             :         {
     498             :         }
     499           0 :         catch ( const ::com::sun::star::lang::IllegalArgumentException& )
     500             :         {
     501             :         }
     502           0 :         catch ( const ::com::sun::star::io::IOException& )
     503             :         {
     504             :         }
     505           0 :         catch ( const ::com::sun::star::embed::StorageWrappedTargetException& )
     506             :         {
     507             :         }
     508             :     }
     509             : 
     510             :     // At least we provide an empty settings container!
     511           0 :     aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer() ), UNO_QUERY );
     512             : }
     513             : 
     514       26368 : ModuleUIConfigurationManager::UIElementData*  ModuleUIConfigurationManager::impl_findUIElementData( const OUString& aResourceURL, sal_Int16 nElementType, bool bLoad )
     515             : {
     516             :     // preload list of element types on demand
     517       26368 :     impl_preloadUIElementTypeList( LAYER_USERDEFINED, nElementType );
     518       26368 :     impl_preloadUIElementTypeList( LAYER_DEFAULT, nElementType );
     519             : 
     520             :     // first try to look into our user-defined vector/unordered_map combination
     521       26368 :     UIElementDataHashMap& rUserHashMap = m_aUIElements[LAYER_USERDEFINED][nElementType].aElementsHashMap;
     522       26368 :     UIElementDataHashMap::iterator pIter = rUserHashMap.find( aResourceURL );
     523       26368 :     if ( pIter != rUserHashMap.end() )
     524             :     {
     525             :         // Default data settings data must be retrieved from the default layer!
     526           6 :         if ( !pIter->second.bDefault )
     527             :         {
     528           5 :             if ( !pIter->second.xSettings.is() && bLoad )
     529           0 :                 impl_requestUIElementData( nElementType, LAYER_USERDEFINED, pIter->second );
     530           5 :             return &(pIter->second);
     531             :         }
     532             :     }
     533             : 
     534             :     // Not successful, we have to look into our default vector/unordered_map combination
     535       26363 :     UIElementDataHashMap& rDefaultHashMap = m_aUIElements[LAYER_DEFAULT][nElementType].aElementsHashMap;
     536       26363 :     pIter = rDefaultHashMap.find( aResourceURL );
     537       26363 :     if ( pIter != rDefaultHashMap.end() )
     538             :     {
     539        4876 :         if ( !pIter->second.xSettings.is() && bLoad )
     540         241 :             impl_requestUIElementData( nElementType, LAYER_DEFAULT, pIter->second );
     541        4876 :         return &(pIter->second);
     542             :     }
     543             : 
     544             :     // Nothing has been found!
     545       21487 :     return NULL;
     546             : }
     547             : 
     548           0 : void ModuleUIConfigurationManager::impl_storeElementTypeData( Reference< XStorage > xStorage, UIElementType& rElementType, bool bResetModifyState )
     549             : {
     550           0 :     UIElementDataHashMap& rHashMap          = rElementType.aElementsHashMap;
     551           0 :     UIElementDataHashMap::iterator pIter    = rHashMap.begin();
     552             : 
     553           0 :     while ( pIter != rHashMap.end() )
     554             :     {
     555           0 :         UIElementData& rElement = pIter->second;
     556           0 :         if ( rElement.bModified )
     557             :         {
     558           0 :             if ( rElement.bDefault )
     559             :             {
     560           0 :                 xStorage->removeElement( rElement.aName );
     561           0 :                 rElement.bModified = false; // mark as not modified
     562             :             }
     563             :             else
     564             :             {
     565           0 :                 Reference< XStream > xStream( xStorage->openStreamElement( rElement.aName, ElementModes::WRITE|ElementModes::TRUNCATE ), UNO_QUERY );
     566           0 :                 Reference< XOutputStream > xOutputStream( xStream->getOutputStream() );
     567             : 
     568           0 :                 if ( xOutputStream.is() )
     569             :                 {
     570           0 :                     switch( rElementType.nElementType )
     571             :                     {
     572             :                         case ::com::sun::star::ui::UIElementType::MENUBAR:
     573             :                         {
     574             :                             try
     575             :                             {
     576           0 :                                 MenuConfiguration aMenuCfg( m_xContext );
     577           0 :                                 aMenuCfg.StoreMenuBarConfigurationToXML( rElement.xSettings, xOutputStream );
     578             :                             }
     579           0 :                             catch ( const ::com::sun::star::lang::WrappedTargetException& )
     580             :                             {
     581             :                             }
     582             :                         }
     583           0 :                         break;
     584             : 
     585             :                         case ::com::sun::star::ui::UIElementType::TOOLBAR:
     586             :                         {
     587             :                             try
     588             :                             {
     589           0 :                                 ToolBoxConfiguration::StoreToolBox( m_xContext, xOutputStream, rElement.xSettings );
     590             :                             }
     591           0 :                             catch ( const ::com::sun::star::lang::WrappedTargetException& )
     592             :                             {
     593             :                             }
     594             :                         }
     595           0 :                         break;
     596             : 
     597             :                         case ::com::sun::star::ui::UIElementType::STATUSBAR:
     598             :                         {
     599             :                             try
     600             :                             {
     601           0 :                                 StatusBarConfiguration::StoreStatusBar( m_xContext, xOutputStream, rElement.xSettings );
     602             :                             }
     603           0 :                             catch ( const ::com::sun::star::lang::WrappedTargetException& )
     604             :                             {
     605             :                             }
     606             :                         }
     607           0 :                         break;
     608             : 
     609             :                         default:
     610           0 :                         break;
     611             :                     }
     612             :                 }
     613             : 
     614             :                 // mark as not modified if we store to our own storage
     615           0 :                 if ( bResetModifyState )
     616           0 :                     rElement.bModified = false;
     617             :             }
     618             :         }
     619             : 
     620           0 :         ++pIter;
     621             :     }
     622             : 
     623             :     // commit element type storage
     624           0 :     Reference< XTransactedObject > xTransactedObject( xStorage, UNO_QUERY );
     625           0 :     if ( xTransactedObject.is() )
     626           0 :         xTransactedObject->commit();
     627             : 
     628             :     // mark UIElementType as not modified if we store to our own storage
     629           0 :     if ( bResetModifyState )
     630           0 :         rElementType.bModified = false;
     631           0 : }
     632             : 
     633             : // This is only allowed to be called on the LAYER_USER_DEFINED!
     634          21 : void ModuleUIConfigurationManager::impl_resetElementTypeData(
     635             :     UIElementType& rUserElementType,
     636             :     UIElementType& rDefaultElementType,
     637             :     ConfigEventNotifyContainer& rRemoveNotifyContainer,
     638             :     ConfigEventNotifyContainer& rReplaceNotifyContainer )
     639             : {
     640          21 :     UIElementDataHashMap& rHashMap          = rUserElementType.aElementsHashMap;
     641          21 :     UIElementDataHashMap::iterator pIter    = rHashMap.begin();
     642             : 
     643          21 :     Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
     644          42 :     Reference< XInterface >  xIfac( xThis, UNO_QUERY );
     645          42 :     Reference< XNameAccess > xDefaultNameAccess( rDefaultElementType.xStorage, UNO_QUERY );
     646          21 :     sal_Int16 nType = rUserElementType.nElementType;
     647             : 
     648             :     // Make copies of the event structures to be thread-safe. We have to unlock our mutex before calling
     649             :     // our listeners!
     650          46 :     while ( pIter != rHashMap.end() )
     651             :     {
     652           4 :         UIElementData& rElement = pIter->second;
     653           4 :         if ( !rElement.bDefault )
     654             :         {
     655           3 :             if ( xDefaultNameAccess->hasByName( rElement.aName ))
     656             :             {
     657             :                 // Replace settings with data from default layer
     658           3 :                 Reference< XIndexAccess > xOldSettings( rElement.xSettings );
     659           3 :                 impl_requestUIElementData( nType, LAYER_DEFAULT, rElement );
     660             : 
     661           6 :                 ui::ConfigurationEvent aReplaceEvent;
     662           3 :                 aReplaceEvent.ResourceURL = rElement.aResourceURL;
     663           3 :                 aReplaceEvent.Accessor <<= xThis;
     664           3 :                 aReplaceEvent.Source = xIfac;
     665           3 :                 aReplaceEvent.ReplacedElement <<= xOldSettings;
     666           3 :                 aReplaceEvent.Element <<= rElement.xSettings;
     667             : 
     668           3 :                 rReplaceNotifyContainer.push_back( aReplaceEvent );
     669             : 
     670             :                 // Mark element as default and not modified. That means "not active"
     671             :                 // in the user layer anymore.
     672           3 :                 rElement.bModified = false;
     673           6 :                 rElement.bDefault  = true;
     674             :             }
     675             :             else
     676             :             {
     677             :                 // Remove user-defined settings from user layer
     678           0 :                 ui::ConfigurationEvent aEvent;
     679           0 :                 aEvent.ResourceURL = rElement.aResourceURL;
     680           0 :                 aEvent.Accessor <<= xThis;
     681           0 :                 aEvent.Source = xIfac;
     682           0 :                 aEvent.Element <<= rElement.xSettings;
     683             : 
     684           0 :                 rRemoveNotifyContainer.push_back( aEvent );
     685             : 
     686             :                 // Mark element as default and not modified. That means "not active"
     687             :                 // in the user layer anymore.
     688           0 :                 rElement.bModified = false;
     689           0 :                 rElement.bDefault  = true;
     690             :             }
     691             :         }
     692             : 
     693           4 :         ++pIter;
     694             :     }
     695             : 
     696             :     // Remove all settings from our user interface elements
     697          42 :     rHashMap.clear();
     698          21 : }
     699             : 
     700           0 : void ModuleUIConfigurationManager::impl_reloadElementTypeData(
     701             :     UIElementType&              rUserElementType,
     702             :     UIElementType&              rDefaultElementType,
     703             :     ConfigEventNotifyContainer& rRemoveNotifyContainer,
     704             :     ConfigEventNotifyContainer& rReplaceNotifyContainer )
     705             : {
     706           0 :     UIElementDataHashMap& rHashMap          = rUserElementType.aElementsHashMap;
     707           0 :     UIElementDataHashMap::iterator pIter    = rHashMap.begin();
     708           0 :     Reference< XStorage > xUserStorage( rUserElementType.xStorage );
     709           0 :     Reference< XStorage > xDefaultStorage( rDefaultElementType.xStorage );
     710           0 :     Reference< XNameAccess > xUserNameAccess( rUserElementType.xStorage, UNO_QUERY );
     711           0 :     Reference< XNameAccess > xDefaultNameAccess( rDefaultElementType.xStorage, UNO_QUERY );
     712             : 
     713           0 :     Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
     714           0 :     Reference< XInterface > xIfac( xThis, UNO_QUERY );
     715           0 :     sal_Int16 nType = rUserElementType.nElementType;
     716             : 
     717           0 :     while ( pIter != rHashMap.end() )
     718             :     {
     719           0 :         UIElementData& rElement = pIter->second;
     720           0 :         if ( rElement.bModified )
     721             :         {
     722           0 :             if ( xUserNameAccess->hasByName( rElement.aName ))
     723             :             {
     724             :                 // Replace settings with data from user layer
     725           0 :                 Reference< XIndexAccess > xOldSettings( rElement.xSettings );
     726             : 
     727           0 :                 impl_requestUIElementData( nType, LAYER_USERDEFINED, rElement );
     728             : 
     729           0 :                 ui::ConfigurationEvent aReplaceEvent;
     730             : 
     731           0 :                 aReplaceEvent.ResourceURL = rElement.aResourceURL;
     732           0 :                 aReplaceEvent.Accessor <<= xThis;
     733           0 :                 aReplaceEvent.Source = xIfac;
     734           0 :                 aReplaceEvent.ReplacedElement <<= xOldSettings;
     735           0 :                 aReplaceEvent.Element <<= rElement.xSettings;
     736           0 :                 rReplaceNotifyContainer.push_back( aReplaceEvent );
     737             : 
     738           0 :                 rElement.bModified = false;
     739             :             }
     740           0 :             else if ( xDefaultNameAccess->hasByName( rElement.aName ))
     741             :             {
     742             :                 // Replace settings with data from default layer
     743           0 :                 Reference< XIndexAccess > xOldSettings( rElement.xSettings );
     744             : 
     745           0 :                 impl_requestUIElementData( nType, LAYER_DEFAULT, rElement );
     746             : 
     747           0 :                 ui::ConfigurationEvent aReplaceEvent;
     748             : 
     749           0 :                 aReplaceEvent.ResourceURL = rElement.aResourceURL;
     750           0 :                 aReplaceEvent.Accessor <<= xThis;
     751           0 :                 aReplaceEvent.Source = xIfac;
     752           0 :                 aReplaceEvent.ReplacedElement <<= xOldSettings;
     753           0 :                 aReplaceEvent.Element <<= rElement.xSettings;
     754           0 :                 rReplaceNotifyContainer.push_back( aReplaceEvent );
     755             : 
     756             :                 // Mark element as default and not modified. That means "not active"
     757             :                 // in the user layer anymore.
     758           0 :                 rElement.bModified = false;
     759           0 :                 rElement.bDefault  = true;
     760             :             }
     761             :             else
     762             :             {
     763             :                 // Element settings are not in any storage => remove
     764           0 :                 ui::ConfigurationEvent aRemoveEvent;
     765             : 
     766           0 :                 aRemoveEvent.ResourceURL = rElement.aResourceURL;
     767           0 :                 aRemoveEvent.Accessor <<= xThis;
     768           0 :                 aRemoveEvent.Source = xIfac;
     769           0 :                 aRemoveEvent.Element <<= rElement.xSettings;
     770             : 
     771           0 :                 rRemoveNotifyContainer.push_back( aRemoveEvent );
     772             : 
     773             :                 // Mark element as default and not modified. That means "not active"
     774             :                 // in the user layer anymore.
     775           0 :                 rElement.bModified = false;
     776           0 :                 rElement.bDefault  = true;
     777             :             }
     778             :         }
     779           0 :         ++pIter;
     780             :     }
     781             : 
     782           0 :     rUserElementType.bModified = false;
     783           0 : }
     784             : 
     785         131 : void ModuleUIConfigurationManager::impl_Initialize()
     786             : {
     787             :     // Initialize the top-level structures with the storage data
     788         131 :     if ( m_xUserConfigStorage.is() )
     789             :     {
     790             :         // Try to access our module sub folder
     791        1032 :         for ( sal_Int16 i = 1; i < ::com::sun::star::ui::UIElementType::COUNT;
     792             :               i++ )
     793             :         {
     794         903 :             Reference< XStorage > xElementTypeStorage;
     795             :             try
     796             :             {
     797         903 :                 if ( m_pStorageHandler[i] )
     798         387 :                     xElementTypeStorage = m_pStorageHandler[i]->getWorkingStorageUser();
     799             :             }
     800           0 :             catch ( const com::sun::star::container::NoSuchElementException& )
     801             :             {
     802             :             }
     803           0 :             catch ( const ::com::sun::star::embed::InvalidStorageException& )
     804             :             {
     805             :             }
     806           0 :             catch ( const ::com::sun::star::lang::IllegalArgumentException& )
     807             :             {
     808             :             }
     809           0 :             catch ( const ::com::sun::star::io::IOException& )
     810             :             {
     811             :             }
     812           0 :             catch ( const ::com::sun::star::embed::StorageWrappedTargetException& )
     813             :             {
     814             :             }
     815             : 
     816         903 :             m_aUIElements[LAYER_USERDEFINED][i].nElementType = i;
     817         903 :             m_aUIElements[LAYER_USERDEFINED][i].bModified = false;
     818         903 :             m_aUIElements[LAYER_USERDEFINED][i].xStorage = xElementTypeStorage;
     819         903 :             m_aUIElements[LAYER_USERDEFINED][i].bDefaultLayer = false;
     820         903 :         }
     821             :     }
     822             : 
     823         131 :     if ( m_xDefaultConfigStorage.is() )
     824             :     {
     825         126 :         Reference< XNameAccess > xNameAccess( m_xDefaultConfigStorage, UNO_QUERY_THROW );
     826             : 
     827             :         // Try to access our module sub folder
     828        1008 :         for ( sal_Int16 i = 1; i < ::com::sun::star::ui::UIElementType::COUNT;
     829             :               i++ )
     830             :         {
     831         882 :             Reference< XStorage > xElementTypeStorage;
     832             :             try
     833             :             {
     834         882 :                 const OUString sName( OUString::createFromAscii( UIELEMENTTYPENAMES[i] ) );
     835         882 :                 if( xNameAccess->hasByName( sName ) )
     836         377 :                     xNameAccess->getByName( sName ) >>= xElementTypeStorage;
     837             :             }
     838           0 :             catch ( const com::sun::star::container::NoSuchElementException& )
     839             :             {
     840             :             }
     841             : 
     842         882 :             m_aUIElements[LAYER_DEFAULT][i].nElementType = i;
     843         882 :             m_aUIElements[LAYER_DEFAULT][i].bModified = false;
     844         882 :             m_aUIElements[LAYER_DEFAULT][i].xStorage = xElementTypeStorage;
     845         882 :             m_aUIElements[LAYER_DEFAULT][i].bDefaultLayer = true;
     846        1008 :         }
     847             :     }
     848         131 : }
     849             : 
     850         140 : ModuleUIConfigurationManager::ModuleUIConfigurationManager(
     851             :         const Reference< XComponentContext >& xContext,
     852             :         const css::uno::Sequence< css::uno::Any >& aArguments)
     853             :     : m_xDefaultConfigStorage( 0 )
     854             :     , m_xUserConfigStorage( 0 )
     855             :     , m_bReadOnly( true )
     856             :     , m_bModified( false )
     857             :     , m_bConfigRead( false )
     858             :     , m_bDisposed( false )
     859             :     , m_aXMLPostfix( ".xml" )
     860             :     , m_aPropUIName( "UIName" )
     861             :     , m_aPropResourceURL( "ResourceURL" )
     862             :     , m_xContext( xContext )
     863         149 :     , m_aListenerContainer( m_mutex )
     864             : {
     865        1260 :     for ( int i = 0; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
     866        1120 :         m_pStorageHandler[i] = 0;
     867             : 
     868             :     // Make sure we have a default initialized entry for every layer and user interface element type!
     869             :     // The following code depends on this!
     870         140 :     m_aUIElements[LAYER_DEFAULT].resize( ::com::sun::star::ui::UIElementType::COUNT );
     871         140 :     m_aUIElements[LAYER_USERDEFINED].resize( ::com::sun::star::ui::UIElementType::COUNT );
     872             : 
     873         140 :     SolarMutexGuard g;
     874             : 
     875         140 :     if( aArguments.getLength() == 2 && (aArguments[0] >>= m_aModuleShortName) && (aArguments[1] >>= m_aModuleIdentifier))
     876             :     {
     877             :     }
     878             :     else
     879             :     {
     880           0 :         ::comphelper::SequenceAsHashMap lArgs(aArguments);
     881           0 :         m_aModuleShortName  = lArgs.getUnpackedValueOrDefault("ModuleShortName", OUString());
     882           0 :         m_aModuleIdentifier = lArgs.getUnpackedValueOrDefault("ModuleIdentifier", OUString());
     883             :     }
     884             : 
     885        1057 :     for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
     886             :     {
     887         926 :         OUString aResourceType;
     888         926 :         if ( i == ::com::sun::star::ui::UIElementType::MENUBAR )
     889         140 :             aResourceType = RESOURCETYPE_MENUBAR;
     890         786 :         else if ( i == ::com::sun::star::ui::UIElementType::TOOLBAR )
     891         131 :             aResourceType = RESOURCETYPE_TOOLBAR;
     892         655 :         else if ( i == ::com::sun::star::ui::UIElementType::STATUSBAR )
     893         131 :             aResourceType = RESOURCETYPE_STATUSBAR;
     894             : 
     895         926 :         if ( !aResourceType.isEmpty() )
     896             :         {
     897         402 :             m_pStorageHandler[i] = new PresetHandler( m_xContext );
     898         402 :             m_pStorageHandler[i]->connectToResource( PresetHandler::E_MODULES,
     899             :                                                      aResourceType, // this path wont be used later ... seee next lines!
     900             :                                                      m_aModuleShortName,
     901         813 :                                                      css::uno::Reference< css::embed::XStorage >()); // no document root used here!
     902             :         }
     903         926 :     }
     904             : 
     905             :     // initialize root storages for all resource types
     906         262 :     m_xUserRootCommit       = css::uno::Reference< css::embed::XTransactedObject >(
     907         262 :                                 m_pStorageHandler[::com::sun::star::ui::UIElementType::MENUBAR]->getOrCreateRootStorageUser(), css::uno::UNO_QUERY); // can be empty
     908         262 :     m_xDefaultConfigStorage = m_pStorageHandler[::com::sun::star::ui::UIElementType::MENUBAR]->getParentStorageShare(
     909         262 :                                 m_pStorageHandler[::com::sun::star::ui::UIElementType::MENUBAR]->getWorkingStorageShare());
     910         262 :     m_xUserConfigStorage    = m_pStorageHandler[::com::sun::star::ui::UIElementType::MENUBAR]->getParentStorageUser(
     911         262 :                                 m_pStorageHandler[::com::sun::star::ui::UIElementType::MENUBAR]->getWorkingStorageUser());
     912             : 
     913         131 :     if ( m_xUserConfigStorage.is() )
     914             :     {
     915         129 :         Reference< XPropertySet > xPropSet( m_xUserConfigStorage, UNO_QUERY );
     916         129 :         if ( xPropSet.is() )
     917             :         {
     918         129 :             long nOpenMode = 0;
     919         129 :             Any a = xPropSet->getPropertyValue("OpenMode");
     920         129 :             if ( a >>= nOpenMode )
     921         129 :                 m_bReadOnly = !( nOpenMode & ElementModes::WRITE );
     922         129 :         }
     923             :     }
     924             : 
     925         140 :     impl_Initialize();
     926         131 : }
     927             : 
     928         366 : ModuleUIConfigurationManager::~ModuleUIConfigurationManager()
     929             : {
     930        1098 :     for ( int i = 0; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
     931         976 :         delete m_pStorageHandler[i];
     932         244 : }
     933             : 
     934             : // XComponent
     935         129 : void SAL_CALL ModuleUIConfigurationManager::dispose() throw (::com::sun::star::uno::RuntimeException, std::exception)
     936             : {
     937         129 :     Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
     938             : 
     939         258 :     css::lang::EventObject aEvent( xThis );
     940         129 :     m_aListenerContainer.disposeAndClear( aEvent );
     941             : 
     942             :     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
     943         258 :     SolarMutexClearableGuard aGuard;
     944         258 :     Reference< XComponent > xModuleImageManager( m_xModuleImageManager );
     945         129 :     m_xModuleImageManager.clear();
     946         258 :     Reference< XComponent > xCompMAM( m_xModuleAcceleratorManager, UNO_QUERY );
     947         129 :     if ( xCompMAM.is() )
     948          66 :         xCompMAM->dispose();
     949         129 :     m_xModuleAcceleratorManager.clear();
     950         129 :     m_aUIElements[LAYER_USERDEFINED].clear();
     951         129 :     m_aUIElements[LAYER_DEFAULT].clear();
     952         129 :     m_xDefaultConfigStorage.clear();
     953         129 :     m_xUserConfigStorage.clear();
     954         129 :     m_xUserRootCommit.clear();
     955         129 :     m_bConfigRead = false;
     956         129 :     m_bModified = false;
     957         129 :     m_bDisposed = true;
     958         129 :     aGuard.clear();
     959             :     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
     960             : 
     961             :     try
     962             :     {
     963         129 :         if ( xModuleImageManager.is() )
     964         124 :             xModuleImageManager->dispose();
     965             :     }
     966           0 :     catch ( const Exception& )
     967             :     {
     968         129 :     }
     969         129 : }
     970             : 
     971           0 : void SAL_CALL ModuleUIConfigurationManager::addEventListener( const Reference< XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException, std::exception)
     972             : {
     973             :     {
     974           0 :         SolarMutexGuard g;
     975             : 
     976             :         /* SAFE AREA ----------------------------------------------------------------------------------------------- */
     977           0 :         if ( m_bDisposed )
     978           0 :             throw DisposedException();
     979             :     }
     980             : 
     981           0 :     m_aListenerContainer.addInterface( cppu::UnoType<XEventListener>::get(), xListener );
     982           0 : }
     983             : 
     984           0 : void SAL_CALL ModuleUIConfigurationManager::removeEventListener( const Reference< XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException, std::exception)
     985             : {
     986             :     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
     987           0 :     m_aListenerContainer.removeInterface( cppu::UnoType<XEventListener>::get(), xListener );
     988           0 : }
     989             : 
     990             : // XUIConfiguration
     991        3287 : void SAL_CALL ModuleUIConfigurationManager::addConfigurationListener( const Reference< ::com::sun::star::ui::XUIConfigurationListener >& xListener ) throw (::com::sun::star::uno::RuntimeException, std::exception)
     992             : {
     993             :     {
     994        3287 :         SolarMutexGuard g;
     995             : 
     996             :         /* SAFE AREA ----------------------------------------------------------------------------------------------- */
     997        3287 :         if ( m_bDisposed )
     998           0 :             throw DisposedException();
     999             :     }
    1000             : 
    1001        3287 :     m_aListenerContainer.addInterface( cppu::UnoType<ui::XUIConfigurationListener>::get(), xListener );
    1002        3287 : }
    1003             : 
    1004        3278 : void SAL_CALL ModuleUIConfigurationManager::removeConfigurationListener( const Reference< ::com::sun::star::ui::XUIConfigurationListener >& xListener ) throw (::com::sun::star::uno::RuntimeException, std::exception)
    1005             : {
    1006             :     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
    1007        3278 :     m_aListenerContainer.removeInterface( cppu::UnoType<ui::XUIConfigurationListener>::get(), xListener );
    1008        3278 : }
    1009             : 
    1010             : // XUIConfigurationManager
    1011           3 : void SAL_CALL ModuleUIConfigurationManager::reset() throw (::com::sun::star::uno::RuntimeException, std::exception)
    1012             : {
    1013           3 :     SolarMutexClearableGuard aGuard;
    1014             : 
    1015             :     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
    1016           3 :     if ( m_bDisposed )
    1017           0 :         throw DisposedException();
    1018             : 
    1019           3 :     if ( !isReadOnly() )
    1020             :     {
    1021             :         // Remove all elements from our user-defined storage!
    1022             :         try
    1023             :         {
    1024          24 :             for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
    1025             :             {
    1026          21 :                 UIElementType&        rElementType = m_aUIElements[LAYER_USERDEFINED][i];
    1027          21 :                 Reference< XStorage > xSubStorage( rElementType.xStorage, UNO_QUERY );
    1028             : 
    1029          21 :                 if ( xSubStorage.is() )
    1030             :                 {
    1031           9 :                     bool bCommitSubStorage( false );
    1032           9 :                     Sequence< OUString > aUIElementStreamNames = xSubStorage->getElementNames();
    1033           9 :                     for ( sal_Int32 j = 0; j < aUIElementStreamNames.getLength(); j++ )
    1034             :                     {
    1035           0 :                         xSubStorage->removeElement( aUIElementStreamNames[j] );
    1036           0 :                         bCommitSubStorage = true;
    1037             :                     }
    1038             : 
    1039           9 :                     if ( bCommitSubStorage )
    1040             :                     {
    1041           0 :                         Reference< XTransactedObject > xTransactedObject( xSubStorage, UNO_QUERY );
    1042           0 :                         if ( xTransactedObject.is() )
    1043           0 :                             xTransactedObject->commit();
    1044           0 :                         m_pStorageHandler[i]->commitUserChanges();
    1045           9 :                     }
    1046             :                 }
    1047          21 :             }
    1048             : 
    1049             :             // remove settings from user defined layer and notify listener about removed settings data!
    1050           3 :             ConfigEventNotifyContainer aRemoveEventNotifyContainer;
    1051           6 :             ConfigEventNotifyContainer aReplaceEventNotifyContainer;
    1052          24 :             for ( sal_Int16 j = 1; j < ::com::sun::star::ui::UIElementType::COUNT; j++ )
    1053             :             {
    1054             :                 try
    1055             :                 {
    1056          21 :                     UIElementType& rUserElementType     = m_aUIElements[LAYER_USERDEFINED][j];
    1057          21 :                     UIElementType& rDefaultElementType  = m_aUIElements[LAYER_DEFAULT][j];
    1058             : 
    1059          21 :                     impl_resetElementTypeData( rUserElementType, rDefaultElementType, aRemoveEventNotifyContainer, aReplaceEventNotifyContainer );
    1060          21 :                     rUserElementType.bModified = false;
    1061             :                 }
    1062           0 :                 catch (const Exception& e)
    1063             :                 {
    1064           0 :                     css::uno::Any a(e);
    1065             :                     throw css::lang::WrappedTargetRuntimeException(
    1066             :                             OUString("ModuleUIConfigurationManager::reset exception"),
    1067           0 :                             css::uno::Reference<css::uno::XInterface>(*this), a);
    1068             :                 }
    1069             :             }
    1070             : 
    1071           3 :             m_bModified = false;
    1072             : 
    1073             :             // Unlock mutex before notify our listeners
    1074           3 :             aGuard.clear();
    1075             : 
    1076             :             // Notify our listeners
    1077           3 :             sal_uInt32 k = 0;
    1078           3 :             for ( k = 0; k < aRemoveEventNotifyContainer.size(); k++ )
    1079           0 :                 implts_notifyContainerListener( aRemoveEventNotifyContainer[k], NotifyOp_Remove );
    1080           6 :             for ( k = 0; k < aReplaceEventNotifyContainer.size(); k++ )
    1081           6 :                 implts_notifyContainerListener( aReplaceEventNotifyContainer[k], NotifyOp_Replace );
    1082             :         }
    1083           0 :         catch ( const ::com::sun::star::lang::IllegalArgumentException& )
    1084             :         {
    1085             :         }
    1086           0 :         catch ( const ::com::sun::star::container::NoSuchElementException& )
    1087             :         {
    1088             :         }
    1089           0 :         catch ( const ::com::sun::star::embed::InvalidStorageException& )
    1090             :         {
    1091             :         }
    1092           0 :         catch ( const ::com::sun::star::embed::StorageWrappedTargetException& )
    1093             :         {
    1094             :         }
    1095           3 :     }
    1096           3 : }
    1097             : 
    1098        3287 : Sequence< Sequence< PropertyValue > > SAL_CALL ModuleUIConfigurationManager::getUIElementsInfo( sal_Int16 ElementType )
    1099             : throw ( IllegalArgumentException, RuntimeException, std::exception )
    1100             : {
    1101        3287 :     if (( ElementType < 0 ) || ( ElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
    1102           0 :         throw IllegalArgumentException();
    1103             : 
    1104        3287 :     SolarMutexGuard g;
    1105        3287 :     if ( m_bDisposed )
    1106           0 :         throw DisposedException();
    1107             : 
    1108        3287 :     Sequence< Sequence< PropertyValue > > aElementInfoSeq;
    1109        6574 :     UIElementInfoHashMap aUIElementInfoCollection;
    1110             : 
    1111        3287 :     if ( ElementType == ::com::sun::star::ui::UIElementType::UNKNOWN )
    1112             :     {
    1113           9 :         for ( sal_Int16 i = 0; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
    1114           8 :             impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection, sal_Int16( i ) );
    1115             :     }
    1116             :     else
    1117        3286 :         impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection, ElementType );
    1118             : 
    1119        6574 :     Sequence< PropertyValue > aUIElementInfo( 2 );
    1120        3287 :     aUIElementInfo[0].Name = m_aPropResourceURL;
    1121        3287 :     aUIElementInfo[1].Name = m_aPropUIName;
    1122             : 
    1123        3287 :     aElementInfoSeq.realloc( aUIElementInfoCollection.size() );
    1124        3287 :     UIElementInfoHashMap::const_iterator pIter = aUIElementInfoCollection.begin();
    1125             : 
    1126        3287 :     sal_Int32 n = 0;
    1127       29171 :     while ( pIter != aUIElementInfoCollection.end() )
    1128             :     {
    1129       22597 :         aUIElementInfo[0].Value <<= pIter->second.aResourceURL;
    1130       22597 :         aUIElementInfo[1].Value <<= pIter->second.aUIName;
    1131       22597 :         aElementInfoSeq[n++] = aUIElementInfo;
    1132       22597 :         ++pIter;
    1133             :     }
    1134             : 
    1135        6574 :     return aElementInfoSeq;
    1136             : }
    1137             : 
    1138           1 : Reference< XIndexContainer > SAL_CALL ModuleUIConfigurationManager::createSettings() throw (::com::sun::star::uno::RuntimeException, std::exception)
    1139             : {
    1140           1 :     SolarMutexGuard g;
    1141             : 
    1142           1 :     if ( m_bDisposed )
    1143           0 :         throw DisposedException();
    1144             : 
    1145             :     // Creates an empty item container which can be filled from outside
    1146           1 :     return Reference< XIndexContainer >( static_cast< OWeakObject * >( new RootItemContainer() ), UNO_QUERY );
    1147             : }
    1148             : 
    1149       13175 : sal_Bool SAL_CALL ModuleUIConfigurationManager::hasSettings( const OUString& ResourceURL )
    1150             : throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception)
    1151             : {
    1152       13175 :     sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
    1153             : 
    1154       13175 :     if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
    1155             :         ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT   ))
    1156           0 :         throw IllegalArgumentException();
    1157             :     else
    1158             :     {
    1159       13175 :         SolarMutexGuard g;
    1160             : 
    1161       13175 :         if ( m_bDisposed )
    1162           0 :             throw DisposedException();
    1163             : 
    1164       13175 :         UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType, false );
    1165       13175 :         if ( pDataSettings )
    1166        2433 :             return sal_True;
    1167             :     }
    1168             : 
    1169       10742 :     return sal_False;
    1170             : }
    1171             : 
    1172       13185 : Reference< XIndexAccess > SAL_CALL ModuleUIConfigurationManager::getSettings( const OUString& ResourceURL, sal_Bool bWriteable )
    1173             : throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception)
    1174             : {
    1175       13185 :     sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
    1176             : 
    1177       13185 :     if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
    1178             :         ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT   ))
    1179           0 :         throw IllegalArgumentException();
    1180             :     else
    1181             :     {
    1182       13185 :         SolarMutexGuard g;
    1183             : 
    1184       13185 :         if ( m_bDisposed )
    1185           0 :             throw DisposedException();
    1186             : 
    1187       13185 :         UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType );
    1188       13185 :         if ( pDataSettings )
    1189             :         {
    1190             :             // Create a copy of our data if someone wants to change the data.
    1191        2443 :             if ( bWriteable )
    1192           4 :                 return Reference< XIndexAccess >( static_cast< OWeakObject * >( new RootItemContainer( pDataSettings->xSettings ) ), UNO_QUERY );
    1193             :             else
    1194        2439 :                 return pDataSettings->xSettings;
    1195       10742 :         }
    1196             :     }
    1197             : 
    1198       10742 :     throw NoSuchElementException();
    1199             : }
    1200             : 
    1201           3 : void SAL_CALL ModuleUIConfigurationManager::replaceSettings( const OUString& ResourceURL, const Reference< ::com::sun::star::container::XIndexAccess >& aNewData )
    1202             : throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException, std::exception)
    1203             : {
    1204           3 :     sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
    1205             : 
    1206           3 :     if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
    1207             :         ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT   ))
    1208           0 :         throw IllegalArgumentException();
    1209           3 :     else if ( m_bReadOnly )
    1210           0 :         throw IllegalAccessException();
    1211             :     else
    1212             :     {
    1213           3 :         SolarMutexClearableGuard aGuard;
    1214             : 
    1215           3 :         if ( m_bDisposed )
    1216           0 :             throw DisposedException();
    1217             : 
    1218           3 :         UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType );
    1219           3 :         if ( pDataSettings )
    1220             :         {
    1221           3 :             if ( !pDataSettings->bDefaultNode )
    1222             :             {
    1223             :                 // we have a settings entry in our user-defined layer - replace
    1224           0 :                 Reference< XIndexAccess > xOldSettings = pDataSettings->xSettings;
    1225             : 
    1226             :                 // Create a copy of the data if the container is not const
    1227           0 :                 Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY );
    1228           0 :                 if ( xReplace.is() )
    1229           0 :                     pDataSettings->xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( aNewData ) ), UNO_QUERY );
    1230             :                 else
    1231           0 :                     pDataSettings->xSettings = aNewData;
    1232           0 :                 pDataSettings->bDefault  = false;
    1233           0 :                 pDataSettings->bModified = true;
    1234           0 :                 m_bModified = true;
    1235             : 
    1236             :                 // Modify type container
    1237           0 :                 UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType];
    1238           0 :                 rElementType.bModified = true;
    1239             : 
    1240           0 :                 Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
    1241           0 :                 Reference< XInterface > xIfac( xThis, UNO_QUERY );
    1242             : 
    1243             :                 // Create event to notify listener about replaced element settings
    1244           0 :                 ui::ConfigurationEvent aEvent;
    1245           0 :                 aEvent.ResourceURL = ResourceURL;
    1246           0 :                 aEvent.Accessor <<= xThis;
    1247           0 :                 aEvent.Source = xIfac;
    1248           0 :                 aEvent.ReplacedElement <<= xOldSettings;
    1249           0 :                 aEvent.Element <<= pDataSettings->xSettings;
    1250             : 
    1251           0 :                 aGuard.clear();
    1252             : 
    1253           0 :                 implts_notifyContainerListener( aEvent, NotifyOp_Replace );
    1254             :             }
    1255             :             else
    1256             :             {
    1257             :                 // we have no settings in our user-defined layer - insert
    1258           3 :                 UIElementData aUIElementData;
    1259             : 
    1260           3 :                 aUIElementData.bDefault     = false;
    1261           3 :                 aUIElementData.bDefaultNode = false;
    1262           3 :                 aUIElementData.bModified    = true;
    1263             : 
    1264             :                 // Create a copy of the data if the container is not const
    1265           6 :                 Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY );
    1266           3 :                 if ( xReplace.is() )
    1267           3 :                     aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( aNewData ) ), UNO_QUERY );
    1268             :                 else
    1269           0 :                     aUIElementData.xSettings = aNewData;
    1270           3 :                 aUIElementData.aName        = RetrieveNameFromResourceURL( ResourceURL ) + m_aXMLPostfix;
    1271           3 :                 aUIElementData.aResourceURL = ResourceURL;
    1272           3 :                 m_bModified = true;
    1273             : 
    1274             :                 // Modify type container
    1275           3 :                 UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType];
    1276           3 :                 rElementType.bModified = true;
    1277             : 
    1278           3 :                 UIElementDataHashMap& rElements = rElementType.aElementsHashMap;
    1279             : 
    1280             :                 // Check our user element settings hash map as it can already contain settings that have been set to default!
    1281             :                 // If no node can be found, we have to insert it.
    1282           3 :                 UIElementDataHashMap::iterator pIter = rElements.find( ResourceURL );
    1283           3 :                 if ( pIter != rElements.end() )
    1284           0 :                     pIter->second = aUIElementData;
    1285             :                 else
    1286           3 :                     rElements.insert( UIElementDataHashMap::value_type( ResourceURL, aUIElementData ));
    1287             : 
    1288           6 :                 Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
    1289           6 :                 Reference< XInterface > xIfac( xThis, UNO_QUERY );
    1290             : 
    1291             :                 // Create event to notify listener about replaced element settings
    1292           6 :                 ui::ConfigurationEvent aEvent;
    1293             : 
    1294           3 :                 aEvent.ResourceURL = ResourceURL;
    1295           3 :                 aEvent.Accessor <<= xThis;
    1296           3 :                 aEvent.Source = xIfac;
    1297           3 :                 aEvent.ReplacedElement <<= pDataSettings->xSettings;
    1298           3 :                 aEvent.Element <<= aUIElementData.xSettings;
    1299             : 
    1300           3 :                 aGuard.clear();
    1301             : 
    1302           6 :                 implts_notifyContainerListener( aEvent, NotifyOp_Replace );
    1303             :             }
    1304             :         }
    1305             :         else
    1306           0 :             throw NoSuchElementException();
    1307             :     }
    1308           3 : }
    1309             : 
    1310           1 : void SAL_CALL ModuleUIConfigurationManager::removeSettings( const OUString& ResourceURL )
    1311             : throw ( NoSuchElementException, IllegalArgumentException, IllegalAccessException, RuntimeException, std::exception)
    1312             : {
    1313           1 :     sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
    1314             : 
    1315           1 :     if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
    1316             :         ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT   ))
    1317           0 :         throw IllegalArgumentException();
    1318           1 :     else if ( m_bReadOnly )
    1319           0 :         throw IllegalAccessException();
    1320             :     else
    1321             :     {
    1322           1 :         SolarMutexClearableGuard aGuard;
    1323             : 
    1324           1 :         if ( m_bDisposed )
    1325           0 :             throw DisposedException();
    1326             : 
    1327           1 :         UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType );
    1328           1 :         if ( pDataSettings )
    1329             :         {
    1330             :             // If element settings are default, we don't need to change anything!
    1331           1 :             if ( pDataSettings->bDefault )
    1332           1 :                 return;
    1333             :             else
    1334             :             {
    1335           1 :                 Reference< XIndexAccess > xRemovedSettings = pDataSettings->xSettings;
    1336           1 :                 pDataSettings->bDefault = true;
    1337             : 
    1338             :                 // check if this is a default layer node
    1339           1 :                 if ( !pDataSettings->bDefaultNode )
    1340           1 :                     pDataSettings->bModified = true; // we have to remove this node from the user layer!
    1341           1 :                 pDataSettings->xSettings.clear();
    1342           1 :                 m_bModified = true; // user layer must be written
    1343             : 
    1344             :                 // Modify type container
    1345           1 :                 UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType];
    1346           1 :                 rElementType.bModified = true;
    1347             : 
    1348           2 :                 Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
    1349           2 :                 Reference< XInterface > xIfac( xThis, UNO_QUERY );
    1350             : 
    1351             :                 // Check if we have settings in the default layer which replaces the user-defined one!
    1352           1 :                 UIElementData* pDefaultDataSettings = impl_findUIElementData( ResourceURL, nElementType );
    1353           1 :                 if ( pDefaultDataSettings )
    1354             :                 {
    1355             :                     // Create event to notify listener about replaced element settings
    1356           0 :                     ui::ConfigurationEvent aEvent;
    1357             : 
    1358           0 :                     aEvent.ResourceURL = ResourceURL;
    1359           0 :                     aEvent.Accessor <<= xThis;
    1360           0 :                     aEvent.Source = xIfac;
    1361           0 :                     aEvent.Element <<= xRemovedSettings;
    1362           0 :                     aEvent.ReplacedElement <<= pDefaultDataSettings->xSettings;
    1363             : 
    1364           0 :                     aGuard.clear();
    1365             : 
    1366           0 :                     implts_notifyContainerListener( aEvent, NotifyOp_Replace );
    1367             :                 }
    1368             :                 else
    1369             :                 {
    1370             :                     // Create event to notify listener about removed element settings
    1371           1 :                     ui::ConfigurationEvent aEvent;
    1372             : 
    1373           1 :                     aEvent.ResourceURL = ResourceURL;
    1374           1 :                     aEvent.Accessor <<= xThis;
    1375           1 :                     aEvent.Source = xIfac;
    1376           1 :                     aEvent.Element <<= xRemovedSettings;
    1377             : 
    1378           1 :                     aGuard.clear();
    1379             : 
    1380           1 :                     implts_notifyContainerListener( aEvent, NotifyOp_Remove );
    1381           1 :                 }
    1382             :             }
    1383             :         }
    1384             :         else
    1385           0 :             throw NoSuchElementException();
    1386             :     }
    1387             : }
    1388             : 
    1389           1 : void SAL_CALL ModuleUIConfigurationManager::insertSettings( const OUString& NewResourceURL, const Reference< XIndexAccess >& aNewData )
    1390             : throw ( ElementExistException, IllegalArgumentException, IllegalAccessException, RuntimeException, std::exception )
    1391             : {
    1392           1 :     sal_Int16 nElementType = RetrieveTypeFromResourceURL( NewResourceURL );
    1393             : 
    1394           1 :     if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
    1395             :         ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT   ))
    1396           0 :         throw IllegalArgumentException();
    1397           1 :     else if ( m_bReadOnly )
    1398           0 :         throw IllegalAccessException();
    1399             :     else
    1400             :     {
    1401           1 :         SolarMutexClearableGuard aGuard;
    1402             : 
    1403           1 :         if ( m_bDisposed )
    1404           0 :             throw DisposedException();
    1405             : 
    1406           1 :         UIElementData* pDataSettings = impl_findUIElementData( NewResourceURL, nElementType );
    1407           1 :         if ( !pDataSettings )
    1408             :         {
    1409           1 :             UIElementData aUIElementData;
    1410             : 
    1411           1 :             aUIElementData.bDefault     = false;
    1412           1 :             aUIElementData.bDefaultNode = false;
    1413           1 :             aUIElementData.bModified    = true;
    1414             : 
    1415             :             // Create a copy of the data if the container is not const
    1416           2 :             Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY );
    1417           1 :             if ( xReplace.is() )
    1418           1 :                 aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( aNewData ) ), UNO_QUERY );
    1419             :             else
    1420           0 :                 aUIElementData.xSettings = aNewData;
    1421           1 :             aUIElementData.aName        = RetrieveNameFromResourceURL( NewResourceURL ) + m_aXMLPostfix;
    1422           1 :             aUIElementData.aResourceURL = NewResourceURL;
    1423           1 :             m_bModified = true;
    1424             : 
    1425           1 :             UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType];
    1426           1 :             rElementType.bModified = true;
    1427             : 
    1428           1 :             UIElementDataHashMap& rElements = rElementType.aElementsHashMap;
    1429           1 :             rElements.insert( UIElementDataHashMap::value_type( NewResourceURL, aUIElementData ));
    1430             : 
    1431           2 :             Reference< XIndexAccess > xInsertSettings( aUIElementData.xSettings );
    1432           2 :             Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
    1433             : 
    1434             :             // Create event to notify listener about removed element settings
    1435           2 :             ui::ConfigurationEvent aEvent;
    1436             : 
    1437           1 :             aEvent.ResourceURL = NewResourceURL;
    1438           1 :             aEvent.Accessor <<= xThis;
    1439           1 :             aEvent.Source = xThis;
    1440           1 :             aEvent.Element <<= xInsertSettings;
    1441             : 
    1442           1 :             aGuard.clear();
    1443             : 
    1444           2 :             implts_notifyContainerListener( aEvent, NotifyOp_Insert );
    1445             :         }
    1446             :         else
    1447           0 :             throw ElementExistException();
    1448             :     }
    1449           1 : }
    1450             : 
    1451       52446 : Reference< XInterface > SAL_CALL ModuleUIConfigurationManager::getImageManager() throw (::com::sun::star::uno::RuntimeException, std::exception)
    1452             : {
    1453       52446 :     SolarMutexGuard g;
    1454             : 
    1455       52446 :     if ( m_bDisposed )
    1456           0 :         throw DisposedException();
    1457             : 
    1458       52446 :     if ( !m_xModuleImageManager.is() )
    1459             :     {
    1460         250 :         m_xModuleImageManager = Reference< XComponent >( static_cast< cppu::OWeakObject *>( new ModuleImageManager( m_xContext )),
    1461         125 :                                                          UNO_QUERY );
    1462         125 :         Reference< XInitialization > xInit( m_xModuleImageManager, UNO_QUERY );
    1463             : 
    1464         250 :         Sequence< Any > aPropSeq( 3 );
    1465         250 :         PropertyValue aPropValue;
    1466         125 :         aPropValue.Name  = "UserConfigStorage";
    1467         125 :         aPropValue.Value = makeAny( m_xUserConfigStorage );
    1468         125 :         aPropSeq[0] = makeAny( aPropValue );
    1469         125 :         aPropValue.Name  = "ModuleIdentifier";
    1470         125 :         aPropValue.Value = makeAny( m_aModuleIdentifier );
    1471         125 :         aPropSeq[1] = makeAny( aPropValue );
    1472         125 :         aPropValue.Name  = "UserRootCommit";
    1473         125 :         aPropValue.Value = makeAny( m_xUserRootCommit );
    1474         125 :         aPropSeq[2] = makeAny( aPropValue );
    1475             : 
    1476         250 :         xInit->initialize( aPropSeq );
    1477             :     }
    1478             : 
    1479       52446 :     return Reference< XInterface >( m_xModuleImageManager, UNO_QUERY );
    1480             : }
    1481             : 
    1482        1790 : Reference< ui::XAcceleratorConfiguration > SAL_CALL ModuleUIConfigurationManager::getShortCutManager() throw (::com::sun::star::uno::RuntimeException, std::exception)
    1483             : {
    1484        1790 :     SolarMutexGuard g;
    1485             : 
    1486        1790 :     if ( m_bDisposed )
    1487           0 :         throw DisposedException();
    1488             : 
    1489        1790 :     if ( !m_xModuleAcceleratorManager.is() ) try
    1490             :     {
    1491         134 :         m_xModuleAcceleratorManager = ui::ModuleAcceleratorConfiguration::
    1492          67 :             createWithModuleIdentifier(m_xContext, m_aModuleIdentifier);
    1493             :     }
    1494           0 :     catch ( const css::uno::DeploymentException& )
    1495             :     {
    1496             :         SAL_WARN("fwk.uiconfiguration", "ModuleAcceleratorConfiguration"
    1497             :                 " not available. This should happen only on mobile platforms.");
    1498             :     }
    1499             : 
    1500        1790 :     return m_xModuleAcceleratorManager;
    1501             : }
    1502             : 
    1503           1 : Reference< XInterface > SAL_CALL ModuleUIConfigurationManager::getEventsManager() throw (::com::sun::star::uno::RuntimeException, std::exception)
    1504             : {
    1505           1 :     return Reference< XInterface >();
    1506             : }
    1507             : 
    1508             : // XModuleUIConfigurationManager
    1509           2 : sal_Bool SAL_CALL ModuleUIConfigurationManager::isDefaultSettings( const OUString& ResourceURL )
    1510             : throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception)
    1511             : {
    1512           2 :     sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
    1513             : 
    1514           2 :     if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
    1515             :         ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT   ))
    1516           0 :         throw IllegalArgumentException();
    1517             :     else
    1518             :     {
    1519           2 :         SolarMutexGuard g;
    1520             : 
    1521           2 :         if ( m_bDisposed )
    1522           0 :             throw DisposedException();
    1523             : 
    1524           2 :         UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType, false );
    1525           2 :         if ( pDataSettings && pDataSettings->bDefaultNode )
    1526           1 :             return sal_True;
    1527             :     }
    1528             : 
    1529           1 :     return sal_False;
    1530             : }
    1531             : 
    1532           1 : Reference< XIndexAccess > SAL_CALL ModuleUIConfigurationManager::getDefaultSettings( const OUString& ResourceURL )
    1533             : throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception)
    1534             : {
    1535           1 :     sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
    1536             : 
    1537           1 :     if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
    1538             :         ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT   ))
    1539           0 :         throw IllegalArgumentException();
    1540             :     else
    1541             :     {
    1542           1 :         SolarMutexGuard g;
    1543             : 
    1544           1 :         if ( m_bDisposed )
    1545           0 :             throw DisposedException();
    1546             : 
    1547             :         // preload list of element types on demand
    1548           1 :         impl_preloadUIElementTypeList( LAYER_DEFAULT, nElementType );
    1549             : 
    1550             :         // Look into our default vector/unordered_map combination
    1551           1 :         UIElementDataHashMap& rDefaultHashMap = m_aUIElements[LAYER_DEFAULT][nElementType].aElementsHashMap;
    1552           1 :         UIElementDataHashMap::iterator pIter = rDefaultHashMap.find( ResourceURL );
    1553           1 :         if ( pIter != rDefaultHashMap.end() )
    1554             :         {
    1555           1 :             if ( !pIter->second.xSettings.is() )
    1556           0 :                 impl_requestUIElementData( nElementType, LAYER_DEFAULT, pIter->second );
    1557           2 :             return pIter->second.xSettings;
    1558           0 :         }
    1559             :     }
    1560             : 
    1561             :     // Nothing has been found!
    1562           0 :     throw NoSuchElementException();
    1563             : }
    1564             : 
    1565             : // XUIConfigurationPersistence
    1566           1 : void SAL_CALL ModuleUIConfigurationManager::reload() throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
    1567             : {
    1568           1 :     SolarMutexClearableGuard aGuard;
    1569             : 
    1570           1 :     if ( m_bDisposed )
    1571           0 :         throw DisposedException();
    1572             : 
    1573           1 :     if ( m_xUserConfigStorage.is() && m_bModified && !m_bReadOnly )
    1574             :     {
    1575             :         // Try to access our module sub folder
    1576           0 :         ConfigEventNotifyContainer aRemoveNotifyContainer;
    1577           0 :         ConfigEventNotifyContainer aReplaceNotifyContainer;
    1578           0 :         for ( sal_Int16 i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
    1579             :         {
    1580             :             try
    1581             :             {
    1582           0 :                 UIElementType& rUserElementType    = m_aUIElements[LAYER_USERDEFINED][i];
    1583           0 :                 UIElementType& rDefaultElementType = m_aUIElements[LAYER_DEFAULT][i];
    1584             : 
    1585           0 :                 if ( rUserElementType.bModified )
    1586           0 :                     impl_reloadElementTypeData( rUserElementType, rDefaultElementType, aRemoveNotifyContainer, aReplaceNotifyContainer );
    1587             :             }
    1588           0 :             catch ( const Exception& )
    1589             :             {
    1590           0 :                 throw IOException();
    1591             :             }
    1592             :         }
    1593             : 
    1594           0 :         m_bModified = false;
    1595             : 
    1596             :         // Unlock mutex before notify our listeners
    1597           0 :         aGuard.clear();
    1598             : 
    1599             :         // Notify our listeners
    1600           0 :         for ( size_t j = 0; j < aRemoveNotifyContainer.size(); j++ )
    1601           0 :             implts_notifyContainerListener( aRemoveNotifyContainer[j], NotifyOp_Remove );
    1602           0 :         for ( size_t k = 0; k < aReplaceNotifyContainer.size(); k++ )
    1603           0 :             implts_notifyContainerListener( aReplaceNotifyContainer[k], NotifyOp_Replace );
    1604           1 :     }
    1605           1 : }
    1606             : 
    1607           1 : void SAL_CALL ModuleUIConfigurationManager::store() throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
    1608             : {
    1609           1 :     SolarMutexGuard g;
    1610             : 
    1611           1 :     if ( m_bDisposed )
    1612           0 :         throw DisposedException();
    1613             : 
    1614           1 :     if ( m_xUserConfigStorage.is() && m_bModified && !m_bReadOnly )
    1615             :     {
    1616             :         // Try to access our module sub folder
    1617           0 :         for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
    1618             :         {
    1619             :             try
    1620             :             {
    1621           0 :                 UIElementType&        rElementType = m_aUIElements[LAYER_USERDEFINED][i];
    1622           0 :                 Reference< XStorage > xStorage( rElementType.xStorage, UNO_QUERY );
    1623             : 
    1624           0 :                 if ( rElementType.bModified && xStorage.is() )
    1625             :                 {
    1626           0 :                     impl_storeElementTypeData( xStorage, rElementType );
    1627           0 :                     m_pStorageHandler[i]->commitUserChanges();
    1628           0 :                 }
    1629             :             }
    1630           0 :             catch ( const Exception& )
    1631             :             {
    1632           0 :                 throw IOException();
    1633             :             }
    1634             :         }
    1635             : 
    1636           0 :         m_bModified = false;
    1637           1 :     }
    1638           1 : }
    1639             : 
    1640           1 : void SAL_CALL ModuleUIConfigurationManager::storeToStorage( const Reference< XStorage >& Storage ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
    1641             : {
    1642           1 :     SolarMutexGuard g;
    1643             : 
    1644           1 :     if ( m_bDisposed )
    1645           0 :         throw DisposedException();
    1646             : 
    1647           1 :     if ( m_xUserConfigStorage.is() && m_bModified && !m_bReadOnly )
    1648             :     {
    1649             :         // Try to access our module sub folder
    1650           0 :         for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
    1651             :         {
    1652             :             try
    1653             :             {
    1654           0 :                 Reference< XStorage > xElementTypeStorage( Storage->openStorageElement(
    1655           0 :                                                             OUString::createFromAscii( UIELEMENTTYPENAMES[i] ), ElementModes::READWRITE ));
    1656           0 :                 UIElementType&        rElementType = m_aUIElements[LAYER_USERDEFINED][i];
    1657             : 
    1658           0 :                 if ( rElementType.bModified && xElementTypeStorage.is() )
    1659           0 :                     impl_storeElementTypeData( xElementTypeStorage, rElementType, false ); // store data to storage, but don't reset modify flag!
    1660             :             }
    1661           0 :             catch ( const Exception& )
    1662             :             {
    1663           0 :                 throw IOException();
    1664             :             }
    1665             :         }
    1666             : 
    1667           0 :         Reference< XTransactedObject > xTransactedObject( Storage, UNO_QUERY );
    1668           0 :         if ( xTransactedObject.is() )
    1669           0 :             xTransactedObject->commit();
    1670           1 :     }
    1671           1 : }
    1672             : 
    1673           1 : sal_Bool SAL_CALL ModuleUIConfigurationManager::isModified() throw (::com::sun::star::uno::RuntimeException, std::exception)
    1674             : {
    1675           1 :     SolarMutexGuard g;
    1676             : 
    1677           1 :     return m_bModified;
    1678             : }
    1679             : 
    1680           4 : sal_Bool SAL_CALL ModuleUIConfigurationManager::isReadOnly() throw (::com::sun::star::uno::RuntimeException, std::exception)
    1681             : {
    1682           4 :     SolarMutexGuard g;
    1683             : 
    1684           4 :     return m_bReadOnly;
    1685             : }
    1686             : 
    1687           8 : void ModuleUIConfigurationManager::implts_notifyContainerListener( const ui::ConfigurationEvent& aEvent, NotifyOp eOp )
    1688             : {
    1689           8 :     ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( cppu::UnoType<com::sun::star::ui::XUIConfigurationListener>::get());
    1690           8 :     if ( pContainer != NULL )
    1691             :     {
    1692           8 :         ::cppu::OInterfaceIteratorHelper pIterator( *pContainer );
    1693          26 :         while ( pIterator.hasMoreElements() )
    1694             :         {
    1695             :             try
    1696             :             {
    1697          10 :                 switch ( eOp )
    1698             :                 {
    1699             :                     case NotifyOp_Replace:
    1700           8 :                         static_cast< ::com::sun::star::ui::XUIConfigurationListener*>(pIterator.next())->elementReplaced( aEvent );
    1701           8 :                         break;
    1702             :                     case NotifyOp_Insert:
    1703           1 :                         static_cast< ::com::sun::star::ui::XUIConfigurationListener*>(pIterator.next())->elementInserted( aEvent );
    1704           1 :                         break;
    1705             :                     case NotifyOp_Remove:
    1706           1 :                         static_cast< ::com::sun::star::ui::XUIConfigurationListener*>(pIterator.next())->elementRemoved( aEvent );
    1707           1 :                         break;
    1708             :                 }
    1709             :             }
    1710           0 :             catch( const css::uno::RuntimeException& )
    1711             :             {
    1712           0 :                 pIterator.remove();
    1713             :             }
    1714           8 :         }
    1715             :     }
    1716           8 : }
    1717             : 
    1718             : }
    1719             : 
    1720             : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
    1721         140 : com_sun_star_comp_framework_ModuleUIConfigurationManager_get_implementation(
    1722             :     css::uno::XComponentContext *context,
    1723             :     css::uno::Sequence<css::uno::Any> const &arguments)
    1724             : {
    1725         140 :     return cppu::acquire(new ModuleUIConfigurationManager(context, arguments));
    1726             : }
    1727             : 
    1728             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11