diff options
author | Kurt Zenker <kz@openoffice.org> | 2009-10-15 11:39:37 +0000 |
---|---|---|
committer | Kurt Zenker <kz@openoffice.org> | 2009-10-15 11:39:37 +0000 |
commit | 130da5cbf25fb3991c6f27f8afe51e3ca5943657 (patch) | |
tree | 299421d7430f907191128845871fd267d3270df6 /framework | |
parent | 99efc0ba1f080e9d04d7c2035cb0d92d7b8e448b (diff) |
CWS-TOOLING: integrate CWS fwk122
2009-10-06 09:16:04 +0200 mav r276693 : #i10000# let be compiled on all platforms
2009-10-05 17:02:17 +0200 cd r276688 : #i105343# Fix build problems under Linux/Mac
2009-10-05 16:23:29 +0200 cd r276687 : #i105489# Remove uiconfigurationmanagerimpl.obj from makefile.mk
2009-10-05 15:17:05 +0200 cd r276680 : #i105326# Fix crash when opening file with notes
2009-10-05 11:02:22 +0200 mav r276665 : #i105343# allow the view shell to disconnect from listener
2009-10-02 11:33:45 +0200 cd r276619 : #i105489# Revert changes done to aggregate sources due to too much regressions
Diffstat (limited to 'framework')
7 files changed, 2681 insertions, 87 deletions
diff --git a/framework/inc/uiconfiguration/moduleuiconfigurationmanager.hxx b/framework/inc/uiconfiguration/moduleuiconfigurationmanager.hxx index 62c0477a5169..a0dc92ae50d3 100644 --- a/framework/inc/uiconfiguration/moduleuiconfigurationmanager.hxx +++ b/framework/inc/uiconfiguration/moduleuiconfigurationmanager.hxx @@ -38,7 +38,6 @@ #include <vector> #include <list> #include <hash_map> -#include <memory> //_________________________________________________________________________________________________________________ // my own includes @@ -78,7 +77,6 @@ namespace framework { - class UIConfigurationManagerImpl; class ModuleUIConfigurationManager : public com::sun::star::lang::XTypeProvider , public com::sun::star::lang::XServiceInfo , public com::sun::star::lang::XComponent , @@ -87,6 +85,7 @@ namespace framework public ::com::sun::star::ui::XUIConfigurationManager , public ::com::sun::star::ui::XModuleUIConfigurationManager , public ::com::sun::star::ui::XUIConfigurationPersistence , + private ThreadHelpBase , // Struct for right initalization of mutex member! Must be first of baseclasses. public ::cppu::OWeakObject { public: @@ -135,7 +134,94 @@ namespace framework virtual sal_Bool SAL_CALL isReadOnly() throw (::com::sun::star::uno::RuntimeException); private: - ::std::auto_ptr<UIConfigurationManagerImpl> m_pImpl; + // private data types + enum Layer + { + LAYER_DEFAULT, + LAYER_USERDEFINED, + LAYER_COUNT + }; + + enum NotifyOp + { + NotifyOp_Remove, + NotifyOp_Insert, + NotifyOp_Replace + }; + + struct UIElementInfo + { + UIElementInfo( const rtl::OUString& rResourceURL, const rtl::OUString& rUIName ) : + aResourceURL( rResourceURL), aUIName( rUIName ) {} + rtl::OUString aResourceURL; + rtl::OUString aUIName; + }; + + struct UIElementData + { + UIElementData() : bModified( false ), bDefault( true ), bDefaultNode( true ) {}; + + rtl::OUString aResourceURL; + rtl::OUString aName; + bool bModified; // has been changed since last storing + bool bDefault; // default settings + bool bDefaultNode; // this is a default layer element data + com::sun::star::uno::Reference< com::sun::star::container::XIndexAccess > xSettings; + }; + + struct UIElementType; + friend struct UIElementType; + typedef ::std::hash_map< rtl::OUString, UIElementData, OUStringHashCode, ::std::equal_to< rtl::OUString > > UIElementDataHashMap; + + struct UIElementType + { + UIElementType() : bModified( false ), + bLoaded( false ), + bDefaultLayer( false ), + nElementType( ::com::sun::star::ui::UIElementType::UNKNOWN ) {} + + + bool bModified; + bool bLoaded; + bool bDefaultLayer; + sal_Int16 nElementType; + UIElementDataHashMap aElementsHashMap; + com::sun::star::uno::Reference< com::sun::star::embed::XStorage > xStorage; + }; + + typedef ::std::vector< UIElementType > UIElementTypesVector; + typedef ::std::vector< ::com::sun::star::ui::ConfigurationEvent > ConfigEventNotifyContainer; + typedef ::std::hash_map< rtl::OUString, UIElementInfo, OUStringHashCode, ::std::equal_to< rtl::OUString > > UIElementInfoHashMap; + + // private methods + void impl_Initialize(); + void implts_notifyContainerListener( const ::com::sun::star::ui::ConfigurationEvent& aEvent, NotifyOp eOp ); + void impl_fillSequenceWithElementTypeInfo( UIElementInfoHashMap& aUIElementInfoCollection, sal_Int16 nElementType ); + void impl_preloadUIElementTypeList( Layer eLayer, sal_Int16 nElementType ); + UIElementData* impl_findUIElementData( const rtl::OUString& aResourceURL, sal_Int16 nElementType, bool bLoad = true ); + void impl_requestUIElementData( sal_Int16 nElementType, Layer eLayer, UIElementData& aUIElementData ); + void impl_storeElementTypeData( com::sun::star::uno::Reference< com::sun::star::embed::XStorage > xStorage, UIElementType& rElementType, bool bResetModifyState = true ); + void impl_resetElementTypeData( UIElementType& rUserElementType, UIElementType& rDefaultElementType, ConfigEventNotifyContainer& rRemoveNotifyContainer, ConfigEventNotifyContainer& rReplaceNotifyContainer ); + void impl_reloadElementTypeData( UIElementType& rUserElementType, UIElementType& rDefaultElementType, ConfigEventNotifyContainer& rRemoveNotifyContainer, ConfigEventNotifyContainer& rReplaceNotifyContainer ); + + UIElementTypesVector m_aUIElements[LAYER_COUNT]; + PresetHandler* m_pStorageHandler[::com::sun::star::ui::UIElementType::COUNT]; + com::sun::star::uno::Reference< com::sun::star::embed::XStorage > m_xDefaultConfigStorage; + com::sun::star::uno::Reference< com::sun::star::embed::XStorage > m_xUserConfigStorage; + bool m_bReadOnly; + bool m_bInitialized; + bool m_bModified; + bool m_bConfigRead; + bool m_bDisposed; + rtl::OUString m_aXMLPostfix; + rtl::OUString m_aPropUIName; + rtl::OUString m_aPropResourceURL; + rtl::OUString m_aModuleIdentifier; + rtl::OUString m_aModuleShortName; + com::sun::star::uno::Reference< com::sun::star::embed::XTransactedObject > m_xUserRootCommit; + com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > m_xServiceManager; + ::cppu::OMultiTypeInterfaceContainerHelper m_aListenerContainer; /// container for ALL Listener + com::sun::star::uno::Reference< com::sun::star::lang::XComponent > m_xModuleImageManager; }; } diff --git a/framework/inc/uiconfiguration/uiconfigurationmanager.hxx b/framework/inc/uiconfiguration/uiconfigurationmanager.hxx index 39f1d9503513..e7ecec183570 100644 --- a/framework/inc/uiconfiguration/uiconfigurationmanager.hxx +++ b/framework/inc/uiconfiguration/uiconfigurationmanager.hxx @@ -38,7 +38,6 @@ #include <vector> #include <list> #include <hash_map> -#include <memory> //_________________________________________________________________________________________________________________ // my own includes @@ -78,7 +77,6 @@ namespace framework { - class UIConfigurationManagerImpl; class UIConfigurationManager : public com::sun::star::lang::XTypeProvider , public com::sun::star::lang::XServiceInfo , public com::sun::star::lang::XComponent , @@ -86,6 +84,7 @@ namespace framework public ::com::sun::star::ui::XUIConfigurationManager , public ::com::sun::star::ui::XUIConfigurationPersistence , public ::com::sun::star::ui::XUIConfigurationStorage , + private ThreadHelpBase , // Struct for right initalization of mutex member! Must be first of baseclasses. public ::cppu::OWeakObject { public: @@ -131,7 +130,83 @@ namespace framework virtual sal_Bool SAL_CALL hasStorage() throw (::com::sun::star::uno::RuntimeException); private: - ::std::auto_ptr<UIConfigurationManagerImpl> m_pImpl; + // private data types + enum NotifyOp + { + NotifyOp_Remove, + NotifyOp_Insert, + NotifyOp_Replace + }; + + struct UIElementInfo + { + UIElementInfo( const rtl::OUString& rResourceURL, const rtl::OUString& rUIName ) : + aResourceURL( rResourceURL), aUIName( rUIName ) {} + rtl::OUString aResourceURL; + rtl::OUString aUIName; + }; + + struct UIElementData + { + UIElementData() : bModified( false ), bDefault( true ) {}; + + rtl::OUString aResourceURL; + rtl::OUString aName; + bool bModified; // has been changed since last storing + bool bDefault; // default settings + com::sun::star::uno::Reference< com::sun::star::container::XIndexAccess > xSettings; + }; + + struct UIElementType; + friend struct UIElementType; + typedef ::std::hash_map< rtl::OUString, UIElementData, OUStringHashCode, ::std::equal_to< rtl::OUString > > UIElementDataHashMap; + + struct UIElementType + { + UIElementType() : bModified( false ), + bLoaded( false ), + bDefaultLayer( false ), + nElementType( ::com::sun::star::ui::UIElementType::UNKNOWN ) {} + + + bool bModified; + bool bLoaded; + bool bDefaultLayer; + sal_Int16 nElementType; + UIElementDataHashMap aElementsHashMap; + com::sun::star::uno::Reference< com::sun::star::embed::XStorage > xStorage; + }; + + typedef ::std::vector< UIElementType > UIElementTypesVector; + typedef ::std::vector< ::com::sun::star::ui::ConfigurationEvent > ConfigEventNotifyContainer; + typedef ::std::hash_map< rtl::OUString, UIElementInfo, OUStringHashCode, ::std::equal_to< rtl::OUString > > UIElementInfoHashMap; + + // private methods + void impl_Initialize(); + void implts_notifyContainerListener( const ::com::sun::star::ui::ConfigurationEvent& aEvent, NotifyOp eOp ); + void impl_fillSequenceWithElementTypeInfo( UIElementInfoHashMap& aUIElementInfoCollection, sal_Int16 nElementType ); + void impl_preloadUIElementTypeList( sal_Int16 nElementType ); + UIElementData* impl_findUIElementData( const rtl::OUString& aResourceURL, sal_Int16 nElementType, bool bLoad = true ); + void impl_requestUIElementData( sal_Int16 nElementType, UIElementData& aUIElementData ); + void impl_storeElementTypeData( com::sun::star::uno::Reference< com::sun::star::embed::XStorage >& xStorage, UIElementType& rElementType, bool bResetModifyState = true ); + void impl_resetElementTypeData( UIElementType& rDocElementType, ConfigEventNotifyContainer& rRemoveNotifyContainer ); + void impl_reloadElementTypeData( UIElementType& rDocElementType, ConfigEventNotifyContainer& rRemoveNotifyContainer, ConfigEventNotifyContainer& rReplaceNotifyContainer ); + + UIElementTypesVector m_aUIElements; + com::sun::star::uno::Reference< com::sun::star::embed::XStorage > m_xDocConfigStorage; + bool m_bReadOnly; + bool m_bInitialized; + bool m_bModified; + bool m_bConfigRead; + bool m_bDisposed; + rtl::OUString m_aXMLPostfix; + rtl::OUString m_aPropUIName; + rtl::OUString m_aPropResourceURL; + rtl::OUString m_aModuleIdentifier; + com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > m_xServiceManager; + ::cppu::OMultiTypeInterfaceContainerHelper m_aListenerContainer; /// container for ALL Listener + com::sun::star::uno::Reference< com::sun::star::lang::XComponent > m_xImageManager; + com::sun::star::uno::Reference< com::sun::star::uno::XInterface > m_xAccConfig; }; } diff --git a/framework/source/uiconfiguration/makefile.mk b/framework/source/uiconfiguration/makefile.mk index c7d6eb435d4f..3ef9006072a2 100644 --- a/framework/source/uiconfiguration/makefile.mk +++ b/framework/source/uiconfiguration/makefile.mk @@ -43,7 +43,6 @@ ENABLE_EXCEPTIONS= TRUE SLOFILES= \ $(SLO)$/uiconfigurationmanager.obj \ - $(SLO)$/uiconfigurationmanagerimpl.obj \ $(SLO)$/moduleuiconfigurationmanager.obj \ $(SLO)$/moduleuicfgsupplier.obj \ $(SLO)$/windowstateconfiguration.obj \ diff --git a/framework/source/uiconfiguration/moduleuiconfigurationmanager.cxx b/framework/source/uiconfiguration/moduleuiconfigurationmanager.cxx index 04c87a2c3946..663c2d0d6dd8 100644 --- a/framework/source/uiconfiguration/moduleuiconfigurationmanager.cxx +++ b/framework/source/uiconfiguration/moduleuiconfigurationmanager.cxx @@ -38,7 +38,6 @@ #include <uielement/uielementtypenames.hxx> #include <xml/menuconfiguration.hxx> #include <xml/toolboxconfiguration.hxx> -#include <uiconfigurationmanagerimpl.hxx> #ifndef __FRAMEWORK_XML_STATUSBARCONFIGURATION_HXX_ #include <xml/statusbarconfiguration.hxx> @@ -114,127 +113,1292 @@ DEFINE_XSERVICEINFO_MULTISERVICE ( ModuleUIConfigurationManager DEFINE_INIT_SERVICE ( ModuleUIConfigurationManager, {} ) -ModuleUIConfigurationManager::ModuleUIConfigurationManager( com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > xServiceManager ) -: m_pImpl( new UIConfigurationManagerImpl(xServiceManager,static_cast< OWeakObject* >(this),true) ) +// important: The order and position of the elements must match the constant +// definition of "::com::sun::star::ui::UIElementType" +static const char* UIELEMENTTYPENAMES[] = { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManager::ModuleUIConfigurationManager" ); + "", // Dummy value for unknown! + UIELEMENTTYPE_MENUBAR_NAME, + UIELEMENTTYPE_POPUPMENU_NAME, + UIELEMENTTYPE_TOOLBAR_NAME, + UIELEMENTTYPE_STATUSBAR_NAME, + UIELEMENTTYPE_FLOATINGWINDOW_NAME, + UIELEMENTTYPE_PROGRESSBAR_NAME +}; + +static const char RESOURCEURL_PREFIX[] = "private:resource/"; +static const sal_Int32 RESOURCEURL_PREFIX_SIZE = 17; +static const char RESOURCEURL_CUSTOM_ELEMENT[] = "custom_"; + +static sal_Int16 RetrieveTypeFromResourceURL( const rtl::OUString& aResourceURL ) +{ + + if (( aResourceURL.indexOf( OUString( RTL_CONSTASCII_USTRINGPARAM( RESOURCEURL_PREFIX ))) == 0 ) && + ( aResourceURL.getLength() > RESOURCEURL_PREFIX_SIZE )) + { + OUString aTmpStr = aResourceURL.copy( RESOURCEURL_PREFIX_SIZE ); + sal_Int32 nIndex = aTmpStr.indexOf( '/' ); + if (( nIndex > 0 ) && ( aTmpStr.getLength() > nIndex )) + { + OUString aTypeStr( aTmpStr.copy( 0, nIndex )); + for ( int i = 0; i < UIElementType::COUNT; i++ ) + { + if ( aTypeStr.equalsAscii( UIELEMENTTYPENAMES[i] )) + return sal_Int16( i ); + } + } + } + + return UIElementType::UNKNOWN; +} + +static OUString RetrieveNameFromResourceURL( const rtl::OUString& aResourceURL ) +{ + if (( aResourceURL.indexOf( OUString( RTL_CONSTASCII_USTRINGPARAM( RESOURCEURL_PREFIX ))) == 0 ) && + ( aResourceURL.getLength() > RESOURCEURL_PREFIX_SIZE )) + { + sal_Int32 nIndex = aResourceURL.lastIndexOf( '/' ); + if (( nIndex > 0 ) && (( nIndex+1 ) < aResourceURL.getLength())) + return aResourceURL.copy( nIndex+1 ); + } + + return OUString(); +} + +void ModuleUIConfigurationManager::impl_fillSequenceWithElementTypeInfo( UIElementInfoHashMap& aUIElementInfoCollection, sal_Int16 nElementType ) +{ + // preload list of element types on demand + impl_preloadUIElementTypeList( LAYER_USERDEFINED, nElementType ); + impl_preloadUIElementTypeList( LAYER_DEFAULT, nElementType ); + + UIElementDataHashMap& rUserElements = m_aUIElements[LAYER_USERDEFINED][nElementType].aElementsHashMap; + UIElementDataHashMap::const_iterator pUserIter = rUserElements.begin(); + + OUString aCustomUrlPrefix( RTL_CONSTASCII_USTRINGPARAM( RESOURCEURL_CUSTOM_ELEMENT )); + while ( pUserIter != rUserElements.end() ) + { + sal_Int32 nIndex = pUserIter->second.aResourceURL.indexOf( aCustomUrlPrefix, RESOURCEURL_PREFIX_SIZE ); + if ( nIndex > RESOURCEURL_PREFIX_SIZE ) + { + // Performance: Retrieve user interface name only for custom user interface elements. + // It's only used by them! + UIElementData* pDataSettings = impl_findUIElementData( pUserIter->second.aResourceURL, nElementType ); + if ( pDataSettings ) + { + // Retrieve user interface name from XPropertySet interface + rtl::OUString aUIName; + Reference< XPropertySet > xPropSet( pDataSettings->xSettings, UNO_QUERY ); + if ( xPropSet.is() ) + { + Any a = xPropSet->getPropertyValue( m_aPropUIName ); + a >>= aUIName; + } + + UIElementInfo aInfo( pUserIter->second.aResourceURL, aUIName ); + aUIElementInfoCollection.insert( UIElementInfoHashMap::value_type( pUserIter->second.aResourceURL, aInfo )); + } + } + else + { + // The user interface name for standard user interface elements is stored in the WindowState.xcu file + UIElementInfo aInfo( pUserIter->second.aResourceURL, OUString() ); + aUIElementInfoCollection.insert( UIElementInfoHashMap::value_type( pUserIter->second.aResourceURL, aInfo )); + } + ++pUserIter; + } + + UIElementDataHashMap& rDefaultElements = m_aUIElements[LAYER_DEFAULT][nElementType].aElementsHashMap; + UIElementDataHashMap::const_iterator pDefIter = rDefaultElements.begin(); + + while ( pDefIter != rDefaultElements.end() ) + { + UIElementInfoHashMap::const_iterator pIterInfo = aUIElementInfoCollection.find( pDefIter->second.aResourceURL ); + if ( pIterInfo == aUIElementInfoCollection.end() ) + { + sal_Int32 nIndex = pDefIter->second.aResourceURL.indexOf( aCustomUrlPrefix, RESOURCEURL_PREFIX_SIZE ); + if ( nIndex > RESOURCEURL_PREFIX_SIZE ) + { + // Performance: Retrieve user interface name only for custom user interface elements. + // It's only used by them! + UIElementData* pDataSettings = impl_findUIElementData( pDefIter->second.aResourceURL, nElementType ); + if ( pDataSettings ) + { + // Retrieve user interface name from XPropertySet interface + rtl::OUString aUIName; + Reference< XPropertySet > xPropSet( pDataSettings->xSettings, UNO_QUERY ); + if ( xPropSet.is() ) + { + Any a = xPropSet->getPropertyValue( m_aPropUIName ); + a >>= aUIName; + } + + UIElementInfo aInfo( pDefIter->second.aResourceURL, aUIName ); + aUIElementInfoCollection.insert( UIElementInfoHashMap::value_type( pDefIter->second.aResourceURL, aInfo )); + } + } + else + { + // The user interface name for standard user interface elements is stored in the WindowState.xcu file + UIElementInfo aInfo( pDefIter->second.aResourceURL, OUString() ); + aUIElementInfoCollection.insert( UIElementInfoHashMap::value_type( pDefIter->second.aResourceURL, aInfo )); + } + } + + ++pDefIter; + } +} + +void ModuleUIConfigurationManager::impl_preloadUIElementTypeList( Layer eLayer, sal_Int16 nElementType ) +{ + UIElementType& rElementTypeData = m_aUIElements[eLayer][nElementType]; + + if ( !rElementTypeData.bLoaded ) + { + Reference< XStorage > xElementTypeStorage = rElementTypeData.xStorage; + if ( xElementTypeStorage.is() ) + { + rtl::OUStringBuffer aBuf( RESOURCEURL_PREFIX_SIZE ); + aBuf.appendAscii( RESOURCEURL_PREFIX ); + aBuf.appendAscii( UIELEMENTTYPENAMES[ nElementType ] ); + aBuf.appendAscii( "/" ); + OUString aResURLPrefix( aBuf.makeStringAndClear() ); + + UIElementDataHashMap& rHashMap = rElementTypeData.aElementsHashMap; + Reference< XNameAccess > xNameAccess( xElementTypeStorage, UNO_QUERY ); + Sequence< OUString > aUIElementNames = xNameAccess->getElementNames(); + for ( sal_Int32 n = 0; n < aUIElementNames.getLength(); n++ ) + { + UIElementData aUIElementData; + + // Resource name must be without ".xml" + sal_Int32 nIndex = aUIElementNames[n].lastIndexOf( '.' ); + if (( nIndex > 0 ) && ( nIndex < aUIElementNames[n].getLength() )) + { + OUString aExtension( aUIElementNames[n].copy( nIndex+1 )); + OUString aUIElementName( aUIElementNames[n].copy( 0, nIndex )); + + if (( aUIElementName.getLength() > 0 ) && + ( aExtension.equalsIgnoreAsciiCaseAsciiL( "xml", 3 ))) + { + aUIElementData.aResourceURL = aResURLPrefix + aUIElementName; + aUIElementData.aName = aUIElementNames[n]; + + if ( eLayer == LAYER_USERDEFINED ) + { + aUIElementData.bModified = false; + aUIElementData.bDefault = false; + aUIElementData.bDefaultNode = false; + } + + // Create hash_map entries for all user interface elements inside the storage. We don't load the + // settings to speed up the process. + rHashMap.insert( UIElementDataHashMap::value_type( aUIElementData.aResourceURL, aUIElementData )); + } + } + } + } + } + + rElementTypeData.bLoaded = true; +} + +void ModuleUIConfigurationManager::impl_requestUIElementData( sal_Int16 nElementType, Layer eLayer, UIElementData& aUIElementData ) +{ + UIElementType& rElementTypeData = m_aUIElements[eLayer][nElementType]; + + Reference< XStorage > xElementTypeStorage = rElementTypeData.xStorage; + if ( xElementTypeStorage.is() && aUIElementData.aName.getLength() ) + { + try + { + Reference< XStream > xStream = xElementTypeStorage->openStreamElement( aUIElementData.aName, ElementModes::READ ); + Reference< XInputStream > xInputStream = xStream->getInputStream(); + + if ( xInputStream.is() ) + { + switch ( nElementType ) + { + case ::com::sun::star::ui::UIElementType::UNKNOWN: + break; + + case ::com::sun::star::ui::UIElementType::MENUBAR: + { + try + { + MenuConfiguration aMenuCfg( m_xServiceManager ); + Reference< XIndexAccess > xContainer( aMenuCfg.CreateMenuBarConfigurationFromXML( xInputStream )); + RootItemContainer* pRootItemContainer = RootItemContainer::GetImplementation( xContainer ); + if ( pRootItemContainer ) + aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( pRootItemContainer, sal_True ) ), UNO_QUERY ); + else + aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( xContainer, sal_True ) ), UNO_QUERY ); + return; + } + catch ( ::com::sun::star::lang::WrappedTargetException& ) + { + } + } + break; + + case ::com::sun::star::ui::UIElementType::POPUPMENU: + { + break; + } + + case ::com::sun::star::ui::UIElementType::TOOLBAR: + { + try + { + Reference< XIndexContainer > xIndexContainer( static_cast< OWeakObject * >( new RootItemContainer() ), UNO_QUERY ); + ToolBoxConfiguration::LoadToolBox( m_xServiceManager, xInputStream, xIndexContainer ); + RootItemContainer* pRootItemContainer = RootItemContainer::GetImplementation( xIndexContainer ); + aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( pRootItemContainer, sal_True ) ), UNO_QUERY ); + return; + } + catch ( ::com::sun::star::lang::WrappedTargetException& ) + { + } + + break; + } + + case ::com::sun::star::ui::UIElementType::STATUSBAR: + { + try + { + Reference< XIndexContainer > xIndexContainer( static_cast< OWeakObject * >( new RootItemContainer() ), UNO_QUERY ); + StatusBarConfiguration::LoadStatusBar( m_xServiceManager, xInputStream, xIndexContainer ); + RootItemContainer* pRootItemContainer = RootItemContainer::GetImplementation( xIndexContainer ); + aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( pRootItemContainer, sal_True ) ), UNO_QUERY ); + return; + } + catch ( ::com::sun::star::lang::WrappedTargetException& ) + { + } + + break; + } + + case ::com::sun::star::ui::UIElementType::FLOATINGWINDOW: + { + break; + } + } + } + } + catch ( ::com::sun::star::embed::InvalidStorageException& ) + { + } + catch ( ::com::sun::star::lang::IllegalArgumentException& ) + { + } + catch ( ::com::sun::star::io::IOException& ) + { + } + catch ( ::com::sun::star::embed::StorageWrappedTargetException& ) + { + } + } + + // At least we provide an empty settings container! + aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer() ), UNO_QUERY ); +} + +ModuleUIConfigurationManager::UIElementData* ModuleUIConfigurationManager::impl_findUIElementData( const rtl::OUString& aResourceURL, sal_Int16 nElementType, bool bLoad ) +{ + // preload list of element types on demand + impl_preloadUIElementTypeList( LAYER_USERDEFINED, nElementType ); + impl_preloadUIElementTypeList( LAYER_DEFAULT, nElementType ); + + // first try to look into our user-defined vector/hash_map combination + UIElementDataHashMap& rUserHashMap = m_aUIElements[LAYER_USERDEFINED][nElementType].aElementsHashMap; + UIElementDataHashMap::iterator pIter = rUserHashMap.find( aResourceURL ); + if ( pIter != rUserHashMap.end() ) + { + // Default data settings data must be retrieved from the default layer! + if ( !pIter->second.bDefault ) + { + if ( !pIter->second.xSettings.is() && bLoad ) + impl_requestUIElementData( nElementType, LAYER_USERDEFINED, pIter->second ); + return &(pIter->second); + } + } + + // Not successfull, we have to look into our default vector/hash_map combination + UIElementDataHashMap& rDefaultHashMap = m_aUIElements[LAYER_DEFAULT][nElementType].aElementsHashMap; + pIter = rDefaultHashMap.find( aResourceURL ); + if ( pIter != rDefaultHashMap.end() ) + { + if ( !pIter->second.xSettings.is() && bLoad ) + impl_requestUIElementData( nElementType, LAYER_DEFAULT, pIter->second ); + return &(pIter->second); + } + + // Nothing has been found! + return NULL; +} + +void ModuleUIConfigurationManager::impl_storeElementTypeData( Reference< XStorage > xStorage, UIElementType& rElementType, bool bResetModifyState ) +{ + UIElementDataHashMap& rHashMap = rElementType.aElementsHashMap; + UIElementDataHashMap::iterator pIter = rHashMap.begin(); + + while ( pIter != rHashMap.end() ) + { + UIElementData& rElement = pIter->second; + if ( rElement.bModified ) + { + if ( rElement.bDefault ) + { + xStorage->removeElement( rElement.aName ); + rElement.bModified = sal_False; // mark as not modified + } + else + { + Reference< XStream > xStream( xStorage->openStreamElement( rElement.aName, ElementModes::WRITE|ElementModes::TRUNCATE ), UNO_QUERY ); + Reference< XOutputStream > xOutputStream( xStream->getOutputStream() ); + + if ( xOutputStream.is() ) + { + switch( rElementType.nElementType ) + { + case ::com::sun::star::ui::UIElementType::MENUBAR: + { + try + { + MenuConfiguration aMenuCfg( m_xServiceManager ); + aMenuCfg.StoreMenuBarConfigurationToXML( rElement.xSettings, xOutputStream ); + } + catch ( ::com::sun::star::lang::WrappedTargetException& ) + { + } + } + break; + + case ::com::sun::star::ui::UIElementType::TOOLBAR: + { + try + { + ToolBoxConfiguration::StoreToolBox( m_xServiceManager, xOutputStream, rElement.xSettings ); + } + catch ( ::com::sun::star::lang::WrappedTargetException& ) + { + } + } + break; + + case ::com::sun::star::ui::UIElementType::STATUSBAR: + { + try + { + StatusBarConfiguration::StoreStatusBar( m_xServiceManager, xOutputStream, rElement.xSettings ); + } + catch ( ::com::sun::star::lang::WrappedTargetException& ) + { + } + } + break; + + default: + break; + } + } + + // mark as not modified if we store to our own storage + if ( bResetModifyState ) + rElement.bModified = sal_False; + } + } + + ++pIter; + } + + // commit element type storage + Reference< XTransactedObject > xTransactedObject( xStorage, UNO_QUERY ); + if ( xTransactedObject.is() ) + xTransactedObject->commit(); + + // mark UIElementType as not modified if we store to our own storage + if ( bResetModifyState ) + rElementType.bModified = sal_False; +} + +// This is only allowed to be called on the LAYER_USER_DEFINED! +void ModuleUIConfigurationManager::impl_resetElementTypeData( + UIElementType& rUserElementType, + UIElementType& rDefaultElementType, + ConfigEventNotifyContainer& rRemoveNotifyContainer, + ConfigEventNotifyContainer& rReplaceNotifyContainer ) +{ + UIElementDataHashMap& rHashMap = rUserElementType.aElementsHashMap; + UIElementDataHashMap::iterator pIter = rHashMap.begin(); + + Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY ); + Reference< XInterface > xIfac( xThis, UNO_QUERY ); + Reference< XNameAccess > xDefaultNameAccess( rDefaultElementType.xStorage, UNO_QUERY ); + sal_Int16 nType = rUserElementType.nElementType; + + // Make copies of the event structures to be thread-safe. We have to unlock our mutex before calling + // our listeners! + while ( pIter != rHashMap.end() ) + { + UIElementData& rElement = pIter->second; + if ( !rElement.bDefault ) + { + if ( xDefaultNameAccess->hasByName( rElement.aName )) + { + // Replace settings with data from default layer + Reference< XIndexAccess > xOldSettings( rElement.xSettings ); + impl_requestUIElementData( nType, LAYER_DEFAULT, rElement ); + + ConfigurationEvent aReplaceEvent; + aReplaceEvent.ResourceURL = rElement.aResourceURL; + aReplaceEvent.Accessor <<= xThis; + aReplaceEvent.Source = xIfac; + aReplaceEvent.ReplacedElement <<= xOldSettings; + aReplaceEvent.Element <<= rElement.xSettings; + + rReplaceNotifyContainer.push_back( aReplaceEvent ); + + // Mark element as default and not modified. That means "not active" + // in the user layer anymore. + rElement.bModified = false; + rElement.bDefault = true; + } + else + { + // Remove user-defined settings from user layer + ConfigurationEvent aEvent; + aEvent.ResourceURL = rElement.aResourceURL; + aEvent.Accessor <<= xThis; + aEvent.Source = xIfac; + aEvent.Element <<= rElement.xSettings; + + rRemoveNotifyContainer.push_back( aEvent ); + + // Mark element as default and not modified. That means "not active" + // in the user layer anymore. + rElement.bModified = false; + rElement.bDefault = true; + } + } + + ++pIter; + } + + // Remove all settings from our user interface elements + rHashMap.clear(); +} + +void ModuleUIConfigurationManager::impl_reloadElementTypeData( + UIElementType& rUserElementType, + UIElementType& rDefaultElementType, + ConfigEventNotifyContainer& rRemoveNotifyContainer, + ConfigEventNotifyContainer& rReplaceNotifyContainer ) +{ + UIElementDataHashMap& rHashMap = rUserElementType.aElementsHashMap; + UIElementDataHashMap::iterator pIter = rHashMap.begin(); + Reference< XStorage > xUserStorage( rUserElementType.xStorage ); + Reference< XStorage > xDefaultStorage( rDefaultElementType.xStorage ); + Reference< XNameAccess > xUserNameAccess( rUserElementType.xStorage, UNO_QUERY ); + Reference< XNameAccess > xDefaultNameAccess( rDefaultElementType.xStorage, UNO_QUERY ); + + Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY ); + Reference< XInterface > xIfac( xThis, UNO_QUERY ); + sal_Int16 nType = rUserElementType.nElementType; + + while ( pIter != rHashMap.end() ) + { + UIElementData& rElement = pIter->second; + if ( rElement.bModified ) + { + if ( xUserNameAccess->hasByName( rElement.aName )) + { + // Replace settings with data from user layer + Reference< XIndexAccess > xOldSettings( rElement.xSettings ); + + impl_requestUIElementData( nType, LAYER_USERDEFINED, rElement ); + + ConfigurationEvent aReplaceEvent; + + aReplaceEvent.ResourceURL = rElement.aResourceURL; + aReplaceEvent.Accessor <<= xThis; + aReplaceEvent.Source = xIfac; + aReplaceEvent.ReplacedElement <<= xOldSettings; + aReplaceEvent.Element <<= rElement.xSettings; + rReplaceNotifyContainer.push_back( aReplaceEvent ); + + rElement.bModified = false; + } + else if ( xDefaultNameAccess->hasByName( rElement.aName )) + { + // Replace settings with data from default layer + Reference< XIndexAccess > xOldSettings( rElement.xSettings ); + + impl_requestUIElementData( nType, LAYER_DEFAULT, rElement ); + + ConfigurationEvent aReplaceEvent; + + aReplaceEvent.ResourceURL = rElement.aResourceURL; + aReplaceEvent.Accessor <<= xThis; + aReplaceEvent.Source = xIfac; + aReplaceEvent.ReplacedElement <<= xOldSettings; + aReplaceEvent.Element <<= rElement.xSettings; + rReplaceNotifyContainer.push_back( aReplaceEvent ); + + // Mark element as default and not modified. That means "not active" + // in the user layer anymore. + rElement.bModified = false; + rElement.bDefault = true; + } + else + { + // Element settings are not in any storage => remove + ConfigurationEvent aRemoveEvent; + + aRemoveEvent.ResourceURL = rElement.aResourceURL; + aRemoveEvent.Accessor <<= xThis; + aRemoveEvent.Source = xIfac; + aRemoveEvent.Element <<= rElement.xSettings; + + rRemoveNotifyContainer.push_back( aRemoveEvent ); + + // Mark element as default and not modified. That means "not active" + // in the user layer anymore. + rElement.bModified = false; + rElement.bDefault = true; + } + } + ++pIter; + } + + rUserElementType.bModified = sal_False; +} + +void ModuleUIConfigurationManager::impl_Initialize() +{ + // Initialize the top-level structures with the storage data + if ( m_xUserConfigStorage.is() ) + { + // Try to access our module sub folder + for ( sal_Int16 i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; + i++ ) + { + Reference< XStorage > xElementTypeStorage; + try + { + if ( m_pStorageHandler[i] ) + xElementTypeStorage = m_pStorageHandler[i]->getWorkingStorageUser(); + } + catch ( com::sun::star::container::NoSuchElementException& ) + { + } + catch ( ::com::sun::star::embed::InvalidStorageException& ) + { + } + catch ( ::com::sun::star::lang::IllegalArgumentException& ) + { + } + catch ( ::com::sun::star::io::IOException& ) + { + } + catch ( ::com::sun::star::embed::StorageWrappedTargetException& ) + { + } + + m_aUIElements[LAYER_USERDEFINED][i].nElementType = i; + m_aUIElements[LAYER_USERDEFINED][i].bModified = false; + m_aUIElements[LAYER_USERDEFINED][i].xStorage = xElementTypeStorage; + m_aUIElements[LAYER_USERDEFINED][i].bDefaultLayer = false; + } + } + + if ( m_xDefaultConfigStorage.is() ) + { + Reference< XNameAccess > xNameAccess( m_xDefaultConfigStorage, UNO_QUERY_THROW ); + + // Try to access our module sub folder + for ( sal_Int16 i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; + i++ ) + { + Reference< XStorage > xElementTypeStorage; + try + { + Any a = xNameAccess->getByName( OUString::createFromAscii( UIELEMENTTYPENAMES[i] )); + a >>= xElementTypeStorage; + } + catch ( com::sun::star::container::NoSuchElementException& ) + { + } + + m_aUIElements[LAYER_DEFAULT][i].nElementType = i; + m_aUIElements[LAYER_DEFAULT][i].bModified = false; + m_aUIElements[LAYER_DEFAULT][i].xStorage = xElementTypeStorage; + m_aUIElements[LAYER_DEFAULT][i].bDefaultLayer = true; + } + } +} + +ModuleUIConfigurationManager::ModuleUIConfigurationManager( com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > xServiceManager ) : + ThreadHelpBase( &Application::GetSolarMutex() ) + , m_xDefaultConfigStorage( 0 ) + , m_xUserConfigStorage( 0 ) + , m_bReadOnly( true ) + , m_bInitialized( false ) + , m_bModified( false ) + , m_bConfigRead( false ) + , m_bDisposed( false ) + , m_aXMLPostfix( RTL_CONSTASCII_USTRINGPARAM( ".xml" )) + , m_aPropUIName( RTL_CONSTASCII_USTRINGPARAM( "UIName" )) + , m_aPropResourceURL( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" )) + , m_xServiceManager( xServiceManager ) + , m_aListenerContainer( m_aLock.getShareableOslMutex() ) +{ + for ( int i = 0; i < ::com::sun::star::ui::UIElementType::COUNT; i++ ) + m_pStorageHandler[i] = 0; + + // Make sure we have a default initialized entry for every layer and user interface element type! + // The following code depends on this! + m_aUIElements[LAYER_DEFAULT].resize( ::com::sun::star::ui::UIElementType::COUNT ); + m_aUIElements[LAYER_USERDEFINED].resize( ::com::sun::star::ui::UIElementType::COUNT ); } ModuleUIConfigurationManager::~ModuleUIConfigurationManager() { + for ( int i = 0; i < ::com::sun::star::ui::UIElementType::COUNT; i++ ) + delete m_pStorageHandler[i]; } // XComponent void SAL_CALL ModuleUIConfigurationManager::dispose() throw (::com::sun::star::uno::RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManager::dispose" ); - m_pImpl->dispose(); + Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY ); + + css::lang::EventObject aEvent( xThis ); + m_aListenerContainer.disposeAndClear( aEvent ); + + { + ResetableGuard aGuard( m_aLock ); + try + { + if ( m_xModuleImageManager.is() ) + m_xModuleImageManager->dispose(); + } + catch ( Exception& ) + { + } + + m_xModuleImageManager.clear(); + m_aUIElements[LAYER_USERDEFINED].clear(); + m_aUIElements[LAYER_DEFAULT].clear(); + m_xDefaultConfigStorage.clear(); + m_xUserConfigStorage.clear(); + m_xUserRootCommit.clear(); + m_bConfigRead = false; + m_bModified = false; + m_bDisposed = true; + } } void SAL_CALL ModuleUIConfigurationManager::addEventListener( const Reference< XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManager::addEventListener" ); - m_pImpl->addEventListener(xListener); + { + ResetableGuard aGuard( m_aLock ); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + if ( m_bDisposed ) + throw DisposedException(); + } + + m_aListenerContainer.addInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener ); } void SAL_CALL ModuleUIConfigurationManager::removeEventListener( const Reference< XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManager::removeEventListener" ); - m_pImpl->removeEventListener(xListener); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener ); } // XInitialization void SAL_CALL ModuleUIConfigurationManager::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException ) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManager::initialize" ); - m_pImpl->initialize(aArguments); + ResetableGuard aLock( m_aLock ); + + if ( !m_bInitialized ) + { + ::comphelper::SequenceAsHashMap lArgs(aArguments); + m_aModuleIdentifier = lArgs.getUnpackedValueOrDefault(::rtl::OUString::createFromAscii("ModuleIdentifier"), ::rtl::OUString()); + m_aModuleShortName = lArgs.getUnpackedValueOrDefault(::rtl::OUString::createFromAscii("ModuleShortName"), ::rtl::OUString()); + + for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ ) + { + rtl::OUString aResourceType; + if ( i == ::com::sun::star::ui::UIElementType::MENUBAR ) + aResourceType = PresetHandler::RESOURCETYPE_MENUBAR(); + else if ( i == ::com::sun::star::ui::UIElementType::TOOLBAR ) + aResourceType = PresetHandler::RESOURCETYPE_TOOLBAR(); + else if ( i == ::com::sun::star::ui::UIElementType::STATUSBAR ) + aResourceType = PresetHandler::RESOURCETYPE_STATUSBAR(); + + if ( aResourceType.getLength() > 0 ) + { + m_pStorageHandler[i] = new PresetHandler( m_xServiceManager ); + m_pStorageHandler[i]->connectToResource( PresetHandler::E_MODULES, + aResourceType, // this path wont be used later ... seee next lines! + m_aModuleShortName, + css::uno::Reference< css::embed::XStorage >()); // no document root used here! + } + } + + // initialize root storages for all resource types + m_xUserRootCommit = css::uno::Reference< css::embed::XTransactedObject >( + m_pStorageHandler[::com::sun::star::ui::UIElementType::MENUBAR]->getOrCreateRootStorageUser(), css::uno::UNO_QUERY); // can be empty + m_xDefaultConfigStorage = m_pStorageHandler[::com::sun::star::ui::UIElementType::MENUBAR]->getParentStorageShare( + m_pStorageHandler[::com::sun::star::ui::UIElementType::MENUBAR]->getWorkingStorageShare()); + m_xUserConfigStorage = m_pStorageHandler[::com::sun::star::ui::UIElementType::MENUBAR]->getParentStorageUser( + m_pStorageHandler[::com::sun::star::ui::UIElementType::MENUBAR]->getWorkingStorageUser()); + + if ( m_xUserConfigStorage.is() ) + { + Reference< XPropertySet > xPropSet( m_xUserConfigStorage, UNO_QUERY ); + if ( xPropSet.is() ) + { + long nOpenMode = 0; + Any a = xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenMode" ))); + if ( a >>= nOpenMode ) + m_bReadOnly = !( nOpenMode & ElementModes::WRITE ); + } + } + + impl_Initialize(); + + m_bInitialized = true; + } } // XUIConfiguration void SAL_CALL ModuleUIConfigurationManager::addConfigurationListener( const Reference< ::com::sun::star::ui::XUIConfigurationListener >& xListener ) throw (::com::sun::star::uno::RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManager::addConfigurationListener" ); - m_pImpl->addConfigurationListener(xListener); + { + ResetableGuard aGuard( m_aLock ); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + if ( m_bDisposed ) + throw DisposedException(); + } + + m_aListenerContainer.addInterface( ::getCppuType( ( const Reference< XUIConfigurationListener >* ) NULL ), xListener ); } void SAL_CALL ModuleUIConfigurationManager::removeConfigurationListener( const Reference< ::com::sun::star::ui::XUIConfigurationListener >& xListener ) throw (::com::sun::star::uno::RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManager::removeConfigurationListener" ); - m_pImpl->removeConfigurationListener(xListener); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XUIConfigurationListener >* ) NULL ), xListener ); } // XUIConfigurationManager void SAL_CALL ModuleUIConfigurationManager::reset() throw (::com::sun::star::uno::RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManager::reset" ); - m_pImpl->reset(); + ResetableGuard aGuard( m_aLock ); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + if ( m_bDisposed ) + throw DisposedException(); + + bool bResetStorage( false ); + + if ( !isReadOnly() ) + { + // Remove all elements from our user-defined storage! + try + { + for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ ) + { + UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][i]; + Reference< XStorage > xSubStorage( rElementType.xStorage, UNO_QUERY ); + + if ( xSubStorage.is() ) + { + bool bCommitSubStorage( false ); + Reference< XNameAccess > xSubStorageNameAccess( xSubStorage, UNO_QUERY ); + Sequence< OUString > aUIElementStreamNames = xSubStorageNameAccess->getElementNames(); + for ( sal_Int32 j = 0; j < aUIElementStreamNames.getLength(); j++ ) + { + xSubStorage->removeElement( aUIElementStreamNames[j] ); + bCommitSubStorage = true; + } + + if ( bCommitSubStorage ) + { + Reference< XTransactedObject > xTransactedObject( xSubStorage, UNO_QUERY ); + if ( xTransactedObject.is() ) + xTransactedObject->commit(); + m_pStorageHandler[i]->commitUserChanges(); + } + } + } + + bResetStorage = true; + + // remove settings from user defined layer and notify listener about removed settings data! + ConfigEventNotifyContainer aRemoveEventNotifyContainer; + ConfigEventNotifyContainer aReplaceEventNotifyContainer; + for ( sal_Int16 j = 1; j < ::com::sun::star::ui::UIElementType::COUNT; j++ ) + { + try + { + UIElementType& rUserElementType = m_aUIElements[LAYER_USERDEFINED][j]; + UIElementType& rDefaultElementType = m_aUIElements[LAYER_DEFAULT][j]; + + impl_resetElementTypeData( rUserElementType, rDefaultElementType, aRemoveEventNotifyContainer, aReplaceEventNotifyContainer ); + rUserElementType.bModified = sal_False; + } + catch ( Exception& ) + { + throw IOException(); + } + } + + m_bModified = sal_False; + + // Unlock mutex before notify our listeners + aGuard.unlock(); + + // Notify our listeners + sal_uInt32 k = 0; + for ( k = 0; k < aRemoveEventNotifyContainer.size(); k++ ) + implts_notifyContainerListener( aRemoveEventNotifyContainer[k], NotifyOp_Remove ); + for ( k = 0; k < aReplaceEventNotifyContainer.size(); k++ ) + implts_notifyContainerListener( aReplaceEventNotifyContainer[k], NotifyOp_Replace ); + } + catch ( ::com::sun::star::lang::IllegalArgumentException& ) + { + } + catch ( ::com::sun::star::container::NoSuchElementException& ) + { + } + catch ( ::com::sun::star::embed::InvalidStorageException& ) + { + } + catch ( ::com::sun::star::embed::StorageWrappedTargetException& ) + { + } + } } Sequence< Sequence< PropertyValue > > SAL_CALL ModuleUIConfigurationManager::getUIElementsInfo( sal_Int16 ElementType ) throw ( IllegalArgumentException, RuntimeException ) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManager::getUIElementsInfo" ); - return m_pImpl->getUIElementsInfo(ElementType); + if (( ElementType < 0 ) || ( ElementType >= ::com::sun::star::ui::UIElementType::COUNT )) + throw IllegalArgumentException(); + + ResetableGuard aGuard( m_aLock ); + if ( m_bDisposed ) + throw DisposedException(); + + Sequence< Sequence< PropertyValue > > aElementInfoSeq; + UIElementInfoHashMap aUIElementInfoCollection; + + if ( ElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) + { + for ( sal_Int16 i = 0; i < ::com::sun::star::ui::UIElementType::COUNT; i++ ) + impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection, sal_Int16( i ) ); + } + else + impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection, ElementType ); + + Sequence< PropertyValue > aUIElementInfo( 2 ); + aUIElementInfo[0].Name = m_aPropResourceURL; + aUIElementInfo[1].Name = m_aPropUIName; + + aElementInfoSeq.realloc( aUIElementInfoCollection.size() ); + UIElementInfoHashMap::const_iterator pIter = aUIElementInfoCollection.begin(); + + sal_Int32 n = 0; + while ( pIter != aUIElementInfoCollection.end() ) + { + aUIElementInfo[0].Value <<= pIter->second.aResourceURL; + aUIElementInfo[1].Value <<= pIter->second.aUIName; + aElementInfoSeq[n++] = aUIElementInfo; + ++pIter; + } + + return aElementInfoSeq; } Reference< XIndexContainer > SAL_CALL ModuleUIConfigurationManager::createSettings() throw (::com::sun::star::uno::RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManager::createSettings" ); + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + throw DisposedException(); // Creates an empty item container which can be filled from outside - return m_pImpl->createSettings(); + return Reference< XIndexContainer >( static_cast< OWeakObject * >( new RootItemContainer() ), UNO_QUERY ); } sal_Bool SAL_CALL ModuleUIConfigurationManager::hasSettings( const ::rtl::OUString& ResourceURL ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManager::hasSettings" ); - return m_pImpl->hasSettings(ResourceURL); + sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL ); + + if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) || + ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT )) + throw IllegalArgumentException(); + else + { + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + throw DisposedException(); + + UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType, false ); + if ( pDataSettings ) + return sal_True; + } + + return sal_False; } Reference< XIndexAccess > SAL_CALL ModuleUIConfigurationManager::getSettings( const ::rtl::OUString& ResourceURL, sal_Bool bWriteable ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManager::getSettings" ); - return m_pImpl->getSettings(ResourceURL,bWriteable); + sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL ); + + if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) || + ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT )) + throw IllegalArgumentException(); + else + { + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + throw DisposedException(); + + UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType ); + if ( pDataSettings ) + { + // Create a copy of our data if someone wants to change the data. + if ( bWriteable ) + return Reference< XIndexAccess >( static_cast< OWeakObject * >( new RootItemContainer( pDataSettings->xSettings ) ), UNO_QUERY ); + else + return pDataSettings->xSettings; + } + } + + throw NoSuchElementException(); } void SAL_CALL ModuleUIConfigurationManager::replaceSettings( const ::rtl::OUString& ResourceURL, const Reference< ::com::sun::star::container::XIndexAccess >& aNewData ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManager::replaceSettings" ); - return m_pImpl->replaceSettings(ResourceURL,aNewData); + sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL ); + + if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) || + ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT )) + throw IllegalArgumentException(); + else if ( m_bReadOnly ) + throw IllegalAccessException(); + else + { + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + throw DisposedException(); + + UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType ); + if ( pDataSettings ) + { + if ( !pDataSettings->bDefaultNode ) + { + // we have a settings entry in our user-defined layer - replace + Reference< XIndexAccess > xOldSettings = pDataSettings->xSettings; + + // Create a copy of the data if the container is not const + Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY ); + if ( xReplace.is() ) + pDataSettings->xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( aNewData ) ), UNO_QUERY ); + else + pDataSettings->xSettings = aNewData; + pDataSettings->bDefault = false; + pDataSettings->bModified = true; + m_bModified = true; + + // Modify type container + UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType]; + rElementType.bModified = true; + + Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY ); + + // Create event to notify listener about replaced element settings + ConfigurationEvent aEvent; + Reference< XInterface > xIfac( xThis, UNO_QUERY ); + + aEvent.ResourceURL = ResourceURL; + aEvent.Accessor <<= xThis; + aEvent.Source = xIfac; + aEvent.ReplacedElement <<= xOldSettings; + aEvent.Element <<= pDataSettings->xSettings; + + aGuard.unlock(); + + implts_notifyContainerListener( aEvent, NotifyOp_Replace ); + } + else + { + // we have no settings in our user-defined layer - insert + UIElementData aUIElementData; + + aUIElementData.bDefault = false; + aUIElementData.bDefaultNode = false; + aUIElementData.bModified = true; + + // Create a copy of the data if the container is not const + Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY ); + if ( xReplace.is() ) + aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( aNewData ) ), UNO_QUERY ); + else + aUIElementData.xSettings = aNewData; + aUIElementData.aName = RetrieveNameFromResourceURL( ResourceURL ) + m_aXMLPostfix; + aUIElementData.aResourceURL = ResourceURL; + m_bModified = true; + + // Modify type container + UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType]; + rElementType.bModified = true; + + UIElementDataHashMap& rElements = rElementType.aElementsHashMap; + + // Check our user element settings hash map as it can already contain settings that have been set to default! + // If no node can be found, we have to insert it. + UIElementDataHashMap::iterator pIter = rElements.find( ResourceURL ); + if ( pIter != rElements.end() ) + pIter->second = aUIElementData; + else + rElements.insert( UIElementDataHashMap::value_type( ResourceURL, aUIElementData )); + + Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY ); + Reference< XInterface > xIfac( xThis, UNO_QUERY ); + + // Create event to notify listener about replaced element settings + ConfigurationEvent aEvent; + + aEvent.ResourceURL = ResourceURL; + aEvent.Accessor <<= xThis; + aEvent.Source = xIfac; + aEvent.ReplacedElement <<= pDataSettings->xSettings; + aEvent.Element <<= aUIElementData.xSettings; + + aGuard.unlock(); + + implts_notifyContainerListener( aEvent, NotifyOp_Replace ); + } + } + else + throw NoSuchElementException(); + } } void SAL_CALL ModuleUIConfigurationManager::removeSettings( const ::rtl::OUString& ResourceURL ) throw ( NoSuchElementException, IllegalArgumentException, IllegalAccessException, RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManager::removeSettings" ); - m_pImpl->removeSettings(ResourceURL); + sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL ); + + if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) || + ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT )) + throw IllegalArgumentException(); + else if ( m_bReadOnly ) + throw IllegalAccessException(); + else + { + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + throw DisposedException(); + + UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType ); + if ( pDataSettings ) + { + // If element settings are default, we don't need to change anything! + if ( pDataSettings->bDefault ) + return; + else + { + Reference< XIndexAccess > xRemovedSettings = pDataSettings->xSettings; + pDataSettings->bDefault = true; + + // check if this is a default layer node + if ( !pDataSettings->bDefaultNode ) + pDataSettings->bModified = true; // we have to remove this node from the user layer! + pDataSettings->xSettings.clear(); + m_bModified = true; // user layer must be written + + // Modify type container + UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType]; + rElementType.bModified = true; + + Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY ); + Reference< XInterface > xIfac( xThis, UNO_QUERY ); + + // Check if we have settings in the default layer which replaces the user-defined one! + UIElementData* pDefaultDataSettings = impl_findUIElementData( ResourceURL, nElementType ); + if ( pDefaultDataSettings ) + { + // Create event to notify listener about replaced element settings + ConfigurationEvent aEvent; + + aEvent.ResourceURL = ResourceURL; + aEvent.Accessor <<= xThis; + aEvent.Source = xIfac; + aEvent.Element <<= xRemovedSettings; + aEvent.ReplacedElement <<= pDefaultDataSettings->xSettings; + + aGuard.unlock(); + + implts_notifyContainerListener( aEvent, NotifyOp_Replace ); + } + else + { + // Create event to notify listener about removed element settings + ConfigurationEvent aEvent; + + aEvent.ResourceURL = ResourceURL; + aEvent.Accessor <<= xThis; + aEvent.Source = xIfac; + aEvent.Element <<= xRemovedSettings; + + aGuard.unlock(); + + implts_notifyContainerListener( aEvent, NotifyOp_Remove ); + } + } + } + else + throw NoSuchElementException(); + } } void SAL_CALL ModuleUIConfigurationManager::insertSettings( const ::rtl::OUString& NewResourceURL, const Reference< XIndexAccess >& aNewData ) throw ( ElementExistException, IllegalArgumentException, IllegalAccessException, RuntimeException ) { - m_pImpl->insertSettings(NewResourceURL,aNewData); + sal_Int16 nElementType = RetrieveTypeFromResourceURL( NewResourceURL ); + + if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) || + ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT )) + throw IllegalArgumentException(); + else if ( m_bReadOnly ) + throw IllegalAccessException(); + else + { + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + throw DisposedException(); + + UIElementData* pDataSettings = impl_findUIElementData( NewResourceURL, nElementType ); + if ( !pDataSettings ) + { + UIElementData aUIElementData; + + aUIElementData.bDefault = false; + aUIElementData.bDefaultNode = false; + aUIElementData.bModified = true; + + // Create a copy of the data if the container is not const + Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY ); + if ( xReplace.is() ) + aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( aNewData ) ), UNO_QUERY ); + else + aUIElementData.xSettings = aNewData; + aUIElementData.aName = RetrieveNameFromResourceURL( NewResourceURL ) + m_aXMLPostfix; + aUIElementData.aResourceURL = NewResourceURL; + m_bModified = true; + + UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType]; + rElementType.bModified = true; + + UIElementDataHashMap& rElements = rElementType.aElementsHashMap; + rElements.insert( UIElementDataHashMap::value_type( NewResourceURL, aUIElementData )); + + Reference< XIndexAccess > xInsertSettings( aUIElementData.xSettings ); + Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY ); + Reference< XInterface > xIfac( xThis, UNO_QUERY ); + + // Create event to notify listener about removed element settings + ConfigurationEvent aEvent; + + aEvent.ResourceURL = NewResourceURL; + aEvent.Accessor <<= xThis; + aEvent.Source = xIfac; + aEvent.Element <<= xInsertSettings; + + aGuard.unlock(); + + implts_notifyContainerListener( aEvent, NotifyOp_Insert ); + } + else + throw ElementExistException(); + } } Reference< XInterface > SAL_CALL ModuleUIConfigurationManager::getImageManager() throw (::com::sun::star::uno::RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManager::getImageManager" ); - return m_pImpl->getImageManager(); + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + throw DisposedException(); + + if ( !m_xModuleImageManager.is() ) + { + m_xModuleImageManager = Reference< XComponent >( static_cast< cppu::OWeakObject *>( new ModuleImageManager( m_xServiceManager )), + UNO_QUERY ); + Reference< XInitialization > xInit( m_xModuleImageManager, UNO_QUERY ); + + Sequence< Any > aPropSeq( 3 ); + PropertyValue aPropValue; + aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserConfigStorage" )); + aPropValue.Value = makeAny( m_xUserConfigStorage ); + aPropSeq[0] = makeAny( aPropValue ); + aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleIdentifier" )); + aPropValue.Value = makeAny( m_aModuleIdentifier ); + aPropSeq[1] = makeAny( aPropValue ); + aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserRootCommit" )); + aPropValue.Value = makeAny( m_xUserRootCommit ); + aPropSeq[2] = makeAny( aPropValue ); + + xInit->initialize( aPropSeq ); + } + + return Reference< XInterface >( m_xModuleImageManager, UNO_QUERY ); + +// return Reference< XInterface >(); } Reference< XInterface > SAL_CALL ModuleUIConfigurationManager::getShortCutManager() throw (::com::sun::star::uno::RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManager::getShortCutManager" ); - return m_pImpl->getShortCutManager(); + ResetableGuard aGuard( m_aLock ); + Reference< XMultiServiceFactory > xSMGR = m_xServiceManager; + ::rtl::OUString aModule = /*m_aModuleShortName*/m_aModuleIdentifier; + aGuard.unlock(); + + Reference< XInterface > xManager = xSMGR->createInstance(SERVICENAME_MODULEACCELERATORCONFIGURATION); + Reference< XInitialization > xInit (xManager, UNO_QUERY_THROW); + + PropertyValue aProp; + aProp.Name = ::rtl::OUString::createFromAscii("ModuleIdentifier"); + aProp.Value <<= aModule; + + Sequence< Any > lArgs(1); + lArgs[0] <<= aProp; + + xInit->initialize(lArgs); + + return xManager; } Reference< XInterface > SAL_CALL ModuleUIConfigurationManager::getEventsManager() throw (::com::sun::star::uno::RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManager::getEventsManager" ); return Reference< XInterface >(); } @@ -242,46 +1406,210 @@ Reference< XInterface > SAL_CALL ModuleUIConfigurationManager::getEventsManager( sal_Bool SAL_CALL ModuleUIConfigurationManager::isDefaultSettings( const ::rtl::OUString& ResourceURL ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManager::isDefaultSettings" ); - return m_pImpl->isDefaultSettings(ResourceURL); + sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL ); + + if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) || + ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT )) + throw IllegalArgumentException(); + else + { + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + throw DisposedException(); + + UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType, false ); + if ( pDataSettings && pDataSettings->bDefaultNode ) + return sal_True; + } + + return sal_False; } Reference< XIndexAccess > SAL_CALL ModuleUIConfigurationManager::getDefaultSettings( const ::rtl::OUString& ResourceURL ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManager::getDefaultSettings" ); - return m_pImpl->getDefaultSettings(ResourceURL); + sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL ); + + if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) || + ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT )) + throw IllegalArgumentException(); + else + { + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + throw DisposedException(); + + // preload list of element types on demand + impl_preloadUIElementTypeList( LAYER_DEFAULT, nElementType ); + + // Look into our default vector/hash_map combination + UIElementDataHashMap& rDefaultHashMap = m_aUIElements[LAYER_DEFAULT][nElementType].aElementsHashMap; + UIElementDataHashMap::iterator pIter = rDefaultHashMap.find( ResourceURL ); + if ( pIter != rDefaultHashMap.end() ) + { + if ( !pIter->second.xSettings.is() ) + impl_requestUIElementData( nElementType, LAYER_DEFAULT, pIter->second ); + return pIter->second.xSettings; + } + } + + // Nothing has been found! + throw NoSuchElementException(); } // XUIConfigurationPersistence void SAL_CALL ModuleUIConfigurationManager::reload() throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManager::reload" ); - m_pImpl->reload(); + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + throw DisposedException(); + + if ( m_xUserConfigStorage.is() && m_bModified && !m_bReadOnly ) + { + // Try to access our module sub folder + ConfigEventNotifyContainer aRemoveNotifyContainer; + ConfigEventNotifyContainer aReplaceNotifyContainer; + for ( sal_Int16 i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ ) + { + try + { + UIElementType& rUserElementType = m_aUIElements[LAYER_USERDEFINED][i]; + UIElementType& rDefaultElementType = m_aUIElements[LAYER_DEFAULT][i]; + + if ( rUserElementType.bModified ) + impl_reloadElementTypeData( rUserElementType, rDefaultElementType, aRemoveNotifyContainer, aReplaceNotifyContainer ); + } + catch ( Exception& ) + { + throw IOException(); + } + } + + m_bModified = sal_False; + + // Unlock mutex before notify our listeners + aGuard.unlock(); + + // Notify our listeners + for ( sal_uInt32 j = 0; j < aRemoveNotifyContainer.size(); j++ ) + implts_notifyContainerListener( aRemoveNotifyContainer[j], NotifyOp_Remove ); + for ( sal_uInt32 k = 0; k < aReplaceNotifyContainer.size(); k++ ) + implts_notifyContainerListener( aReplaceNotifyContainer[k], NotifyOp_Replace ); + } } void SAL_CALL ModuleUIConfigurationManager::store() throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManager::store" ); - m_pImpl->store(); + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + throw DisposedException(); + + if ( m_xUserConfigStorage.is() && m_bModified && !m_bReadOnly ) + { + // Try to access our module sub folder + for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ ) + { + try + { + UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][i]; + Reference< XStorage > xStorage( rElementType.xStorage, UNO_QUERY ); + + if ( rElementType.bModified && xStorage.is() ) + { + impl_storeElementTypeData( xStorage, rElementType ); + m_pStorageHandler[i]->commitUserChanges(); + } + } + catch ( Exception& ) + { + throw IOException(); + } + } + + m_bModified = false; + } } void SAL_CALL ModuleUIConfigurationManager::storeToStorage( const Reference< XStorage >& Storage ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManager::storeToStorage" ); - m_pImpl->storeToStorage(Storage); + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + throw DisposedException(); + + if ( m_xUserConfigStorage.is() && m_bModified && !m_bReadOnly ) + { + // Try to access our module sub folder + for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ ) + { + try + { + Reference< XStorage > xElementTypeStorage( Storage->openStorageElement( + OUString::createFromAscii( UIELEMENTTYPENAMES[i] ), ElementModes::READWRITE )); + UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][i]; + + if ( rElementType.bModified && xElementTypeStorage.is() ) + impl_storeElementTypeData( xElementTypeStorage, rElementType, false ); // store data to storage, but don't reset modify flag! + } + catch ( Exception& ) + { + throw IOException(); + } + } + + Reference< XTransactedObject > xTransactedObject( Storage, UNO_QUERY ); + if ( xTransactedObject.is() ) + xTransactedObject->commit(); + } } sal_Bool SAL_CALL ModuleUIConfigurationManager::isModified() throw (::com::sun::star::uno::RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManager::isModified" ); - return m_pImpl->isModified(); + ResetableGuard aGuard( m_aLock ); + + return m_bModified; } sal_Bool SAL_CALL ModuleUIConfigurationManager::isReadOnly() throw (::com::sun::star::uno::RuntimeException) { - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManager::isReadOnly" ); - return m_pImpl->isReadOnly(); + ResetableGuard aGuard( m_aLock ); + + return m_bReadOnly; +} + +void ModuleUIConfigurationManager::implts_notifyContainerListener( const ConfigurationEvent& aEvent, NotifyOp eOp ) +{ + ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( ::getCppuType( ( const css::uno::Reference< ::com::sun::star::ui::XUIConfigurationListener >*) NULL ) ); + if ( pContainer != NULL ) + { + ::cppu::OInterfaceIteratorHelper pIterator( *pContainer ); + while ( pIterator.hasMoreElements() ) + { + try + { + switch ( eOp ) + { + case NotifyOp_Replace: + ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementReplaced( aEvent ); + break; + case NotifyOp_Insert: + ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementInserted( aEvent ); + break; + case NotifyOp_Remove: + ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementRemoved( aEvent ); + break; + } + } + catch( css::uno::RuntimeException& ) + { + pIterator.remove(); + } + } + } } } // namespace framework diff --git a/framework/source/uiconfiguration/uiconfigurationmanager.cxx b/framework/source/uiconfiguration/uiconfigurationmanager.cxx index 67049d9eb4dc..3309333fb327 100644 --- a/framework/source/uiconfiguration/uiconfigurationmanager.cxx +++ b/framework/source/uiconfiguration/uiconfigurationmanager.cxx @@ -38,7 +38,6 @@ #include <uielement/uielementtypenames.hxx> #include <xml/menuconfiguration.hxx> #include <xml/toolboxconfiguration.hxx> -#include <uiconfigurationmanagerimpl.hxx> #ifndef __FRAMEWORK_XML_STATUSBARCONFIGURATION_HXX_ #include <xml/statusbarconfiguration.hxx> @@ -111,9 +110,511 @@ DEFINE_XSERVICEINFO_MULTISERVICE ( UIConfigurationManager DEFINE_INIT_SERVICE ( UIConfigurationManager, {} ) -UIConfigurationManager::UIConfigurationManager( com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > xServiceManager ) -: m_pImpl( new UIConfigurationManagerImpl(xServiceManager,static_cast< OWeakObject* >(this),false) ) + +// important: The order and position of the elements must match the constant +// definition of "::com::sun::star::ui::UIElementType" +static const char* UIELEMENTTYPENAMES[] = +{ + "", // Dummy value for unknown! + UIELEMENTTYPE_MENUBAR_NAME, + UIELEMENTTYPE_POPUPMENU_NAME, + UIELEMENTTYPE_TOOLBAR_NAME, + UIELEMENTTYPE_STATUSBAR_NAME, + UIELEMENTTYPE_FLOATINGWINDOW_NAME, + UIELEMENTTYPE_PROGRESSBAR_NAME +}; + +static const char RESOURCEURL_PREFIX[] = "private:resource/"; +static const sal_Int32 RESOURCEURL_PREFIX_SIZE = 17; + +static sal_Int16 RetrieveTypeFromResourceURL( const rtl::OUString& aResourceURL ) +{ + + if (( aResourceURL.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( RESOURCEURL_PREFIX ))) == 0 ) && + ( aResourceURL.getLength() > RESOURCEURL_PREFIX_SIZE )) + { + rtl::OUString aTmpStr = aResourceURL.copy( RESOURCEURL_PREFIX_SIZE ); + sal_Int32 nIndex = aTmpStr.indexOf( '/' ); + if (( nIndex > 0 ) && ( aTmpStr.getLength() > nIndex )) + { + rtl::OUString aTypeStr( aTmpStr.copy( 0, nIndex )); + for ( int i = 0; i < UIElementType::COUNT; i++ ) + { + if ( aTypeStr.equalsAscii( UIELEMENTTYPENAMES[i] )) + return sal_Int16( i ); + } + } + } + + return UIElementType::UNKNOWN; +} + +static rtl::OUString RetrieveNameFromResourceURL( const rtl::OUString& aResourceURL ) +{ + if (( aResourceURL.indexOf( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( RESOURCEURL_PREFIX ))) == 0 ) && + ( aResourceURL.getLength() > RESOURCEURL_PREFIX_SIZE )) + { + sal_Int32 nIndex = aResourceURL.lastIndexOf( '/' ); + if (( nIndex > 0 ) && (( nIndex+1 ) < aResourceURL.getLength())) + return aResourceURL.copy( nIndex+1 ); + } + + return rtl::OUString(); +} + +void UIConfigurationManager::impl_fillSequenceWithElementTypeInfo( UIElementInfoHashMap& aUIElementInfoCollection, sal_Int16 nElementType ) { + // preload list of element types on demand + impl_preloadUIElementTypeList( nElementType ); + + UIElementDataHashMap& rUserElements = m_aUIElements[nElementType].aElementsHashMap; + UIElementDataHashMap::const_iterator pUserIter = rUserElements.begin(); + + while ( pUserIter != rUserElements.end() ) + { + UIElementData* pDataSettings = impl_findUIElementData( pUserIter->second.aResourceURL, nElementType ); + if ( pDataSettings && !pDataSettings->bDefault ) + { + // Retrieve user interface name from XPropertySet interface + rtl::OUString aUIName; + Reference< XPropertySet > xPropSet( pDataSettings->xSettings, UNO_QUERY ); + if ( xPropSet.is() ) + { + Any a = xPropSet->getPropertyValue( m_aPropUIName ); + a >>= aUIName; + } + + UIElementInfo aInfo( pUserIter->second.aResourceURL, aUIName ); + aUIElementInfoCollection.insert( UIElementInfoHashMap::value_type( pUserIter->second.aResourceURL, aInfo )); + } + ++pUserIter; + } +} + +void UIConfigurationManager::impl_preloadUIElementTypeList( sal_Int16 nElementType ) +{ + UIElementType& rElementTypeData = m_aUIElements[nElementType]; + + if ( !rElementTypeData.bLoaded ) + { + Reference< XStorage > xElementTypeStorage = rElementTypeData.xStorage; + if ( xElementTypeStorage.is() ) + { + rtl::OUStringBuffer aBuf( RESOURCEURL_PREFIX_SIZE ); + aBuf.appendAscii( RESOURCEURL_PREFIX ); + aBuf.appendAscii( UIELEMENTTYPENAMES[ nElementType ] ); + aBuf.appendAscii( "/" ); + rtl::OUString aResURLPrefix( aBuf.makeStringAndClear() ); + + UIElementDataHashMap& rHashMap = rElementTypeData.aElementsHashMap; + Reference< XNameAccess > xNameAccess( xElementTypeStorage, UNO_QUERY ); + Sequence< rtl::OUString > aUIElementNames = xNameAccess->getElementNames(); + for ( sal_Int32 n = 0; n < aUIElementNames.getLength(); n++ ) + { + UIElementData aUIElementData; + + // Resource name must be without ".xml" + sal_Int32 nIndex = aUIElementNames[n].lastIndexOf( '.' ); + if (( nIndex > 0 ) && ( nIndex < aUIElementNames[n].getLength() )) + { + rtl::OUString aExtension( aUIElementNames[n].copy( nIndex+1 )); + rtl::OUString aUIElementName( aUIElementNames[n].copy( 0, nIndex )); + + if (( aUIElementName.getLength() > 0 ) && + ( aExtension.equalsIgnoreAsciiCaseAsciiL( "xml", 3 ))) + { + aUIElementData.aResourceURL = aResURLPrefix + aUIElementName; + aUIElementData.aName = aUIElementNames[n]; + aUIElementData.bModified = false; + aUIElementData.bDefault = false; + + // Create hash_map entries for all user interface elements inside the storage. We don't load the + // settings to speed up the process. + rHashMap.insert( UIElementDataHashMap::value_type( aUIElementData.aResourceURL, aUIElementData )); + } + } + } + } + } + + rElementTypeData.bLoaded = true; +} + +void UIConfigurationManager::impl_requestUIElementData( sal_Int16 nElementType, UIElementData& aUIElementData ) +{ + UIElementType& rElementTypeData = m_aUIElements[nElementType]; + + Reference< XStorage > xElementTypeStorage = rElementTypeData.xStorage; + if ( xElementTypeStorage.is() && aUIElementData.aName.getLength() ) + { + try + { + Reference< XStream > xStream = xElementTypeStorage->openStreamElement( aUIElementData.aName, ElementModes::READ ); + Reference< XInputStream > xInputStream = xStream->getInputStream(); + + if ( xInputStream.is() ) + { + switch ( nElementType ) + { + case ::com::sun::star::ui::UIElementType::UNKNOWN: + break; + + case ::com::sun::star::ui::UIElementType::MENUBAR: + { + try + { + MenuConfiguration aMenuCfg( m_xServiceManager ); + Reference< XIndexAccess > xContainer( aMenuCfg.CreateMenuBarConfigurationFromXML( xInputStream )); + RootItemContainer* pRootItemContainer = RootItemContainer::GetImplementation( xContainer ); + if ( pRootItemContainer ) + aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( pRootItemContainer, sal_True ) ), UNO_QUERY ); + else + aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( xContainer, sal_True ) ), UNO_QUERY ); + return; + } + catch ( ::com::sun::star::lang::WrappedTargetException& ) + { + } + } + break; + + case ::com::sun::star::ui::UIElementType::POPUPMENU: + { + break; + } + + case ::com::sun::star::ui::UIElementType::TOOLBAR: + { + try + { + Reference< XIndexContainer > xIndexContainer( static_cast< OWeakObject * >( new RootItemContainer() ), UNO_QUERY ); + ToolBoxConfiguration::LoadToolBox( m_xServiceManager, xInputStream, xIndexContainer ); + RootItemContainer* pRootItemContainer = RootItemContainer::GetImplementation( xIndexContainer ); + aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( pRootItemContainer, sal_True ) ), UNO_QUERY ); + return; + } + catch ( ::com::sun::star::lang::WrappedTargetException& ) + { + } + + break; + } + + case ::com::sun::star::ui::UIElementType::STATUSBAR: + { + try + { + Reference< XIndexContainer > xIndexContainer( static_cast< OWeakObject * >( new RootItemContainer() ), UNO_QUERY ); + StatusBarConfiguration::LoadStatusBar( m_xServiceManager, xInputStream, xIndexContainer ); + RootItemContainer* pRootItemContainer = RootItemContainer::GetImplementation( xIndexContainer ); + aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( pRootItemContainer, sal_True ) ), UNO_QUERY ); + return; + } + catch ( ::com::sun::star::lang::WrappedTargetException& ) + { + } + + break; + } + + case ::com::sun::star::ui::UIElementType::FLOATINGWINDOW: + { + break; + } + } + } + } + catch ( ::com::sun::star::embed::InvalidStorageException& ) + { + } + catch ( ::com::sun::star::lang::IllegalArgumentException& ) + { + } + catch ( ::com::sun::star::io::IOException& ) + { + } + catch ( ::com::sun::star::embed::StorageWrappedTargetException& ) + { + } + } + + // At least we provide an empty settings container! + aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer()), UNO_QUERY ); +} + +UIConfigurationManager::UIElementData* UIConfigurationManager::impl_findUIElementData( const rtl::OUString& aResourceURL, sal_Int16 nElementType, bool bLoad ) +{ + // preload list of element types on demand + impl_preloadUIElementTypeList( nElementType ); + + // try to look into our document vector/hash_map combination + UIElementDataHashMap& rUserHashMap = m_aUIElements[nElementType].aElementsHashMap; + UIElementDataHashMap::iterator pIter = rUserHashMap.find( aResourceURL ); + if ( pIter != rUserHashMap.end() ) + { + // Default data settings data means removed! + if ( pIter->second.bDefault ) + return &(pIter->second); + else + { + if ( !pIter->second.xSettings.is() && bLoad ) + impl_requestUIElementData( nElementType, pIter->second ); + return &(pIter->second); + } + } + + // Nothing has been found! + return NULL; +} + +void UIConfigurationManager::impl_storeElementTypeData( Reference< XStorage >& xStorage, UIElementType& rElementType, bool bResetModifyState ) +{ + UIElementDataHashMap& rHashMap = rElementType.aElementsHashMap; + UIElementDataHashMap::iterator pIter = rHashMap.begin(); + + while ( pIter != rHashMap.end() ) + { + UIElementData& rElement = pIter->second; + if ( rElement.bModified ) + { + if ( rElement.bDefault ) + { + xStorage->removeElement( rElement.aName ); + rElement.bModified = sal_False; // mark as not modified + } + else + { + Reference< XStream > xStream( xStorage->openStreamElement( rElement.aName, ElementModes::WRITE|ElementModes::TRUNCATE ), UNO_QUERY ); + Reference< XOutputStream > xOutputStream( xStream->getOutputStream() ); + + if ( xOutputStream.is() ) + { + switch( rElementType.nElementType ) + { + case ::com::sun::star::ui::UIElementType::MENUBAR: + { + try + { + MenuConfiguration aMenuCfg( m_xServiceManager ); + aMenuCfg.StoreMenuBarConfigurationToXML( rElement.xSettings, xOutputStream ); + } + catch ( ::com::sun::star::lang::WrappedTargetException& ) + { + } + } + break; + + case ::com::sun::star::ui::UIElementType::TOOLBAR: + { + try + { + ToolBoxConfiguration::StoreToolBox( m_xServiceManager, xOutputStream, rElement.xSettings ); + } + catch ( ::com::sun::star::lang::WrappedTargetException& ) + { + } + } + break; + + case ::com::sun::star::ui::UIElementType::STATUSBAR: + { + try + { + StatusBarConfiguration::StoreStatusBar( m_xServiceManager, xOutputStream, rElement.xSettings ); + } + catch ( ::com::sun::star::lang::WrappedTargetException& ) + { + } + } + break; + + default: + break; + } + } + + // mark as not modified if we store to our own storage + if ( bResetModifyState ) + rElement.bModified = sal_False; + } + } + + ++pIter; + } + + // commit element type storage + Reference< XTransactedObject > xTransactedObject( xStorage, UNO_QUERY ); + if ( xTransactedObject.is() ) + xTransactedObject->commit(); + + // mark UIElementType as not modified if we store to our own storage + if ( bResetModifyState ) + rElementType.bModified = sal_False; +} + +void UIConfigurationManager::impl_resetElementTypeData( + UIElementType& rDocElementType, + ConfigEventNotifyContainer& rRemoveNotifyContainer ) +{ + UIElementDataHashMap& rHashMap = rDocElementType.aElementsHashMap; + UIElementDataHashMap::iterator pIter = rHashMap.begin(); + + Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY ); + Reference< XInterface > xIfac( xThis, UNO_QUERY ); + + // Make copies of the event structures to be thread-safe. We have to unlock our mutex before calling + // our listeners! + while ( pIter != rHashMap.end() ) + { + UIElementData& rElement = pIter->second; + if ( !rElement.bDefault ) + { + // Remove user-defined settings from document + ConfigurationEvent aEvent; + aEvent.ResourceURL = rElement.aResourceURL; + aEvent.Accessor <<= xThis; + aEvent.Source = xIfac; + aEvent.Element <<= rElement.xSettings; + + rRemoveNotifyContainer.push_back( aEvent ); + + // Mark element as default. + rElement.bModified = false; + rElement.bDefault = true; + } + else + rElement.bModified = false; + + ++pIter; + } + + // Remove all settings from our user interface elements + rHashMap.clear(); +} + +void UIConfigurationManager::impl_reloadElementTypeData( + UIElementType& rDocElementType, + ConfigEventNotifyContainer& rRemoveNotifyContainer, + ConfigEventNotifyContainer& rReplaceNotifyContainer ) +{ + UIElementDataHashMap& rHashMap = rDocElementType.aElementsHashMap; + UIElementDataHashMap::iterator pIter = rHashMap.begin(); + Reference< XStorage > xElementStorage( rDocElementType.xStorage ); + Reference< XNameAccess > xElementNameAccess( xElementStorage, UNO_QUERY ); + + Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY ); + Reference< XInterface > xIfac( xThis, UNO_QUERY ); + sal_Int16 nType = rDocElementType.nElementType; + + while ( pIter != rHashMap.end() ) + { + UIElementData& rElement = pIter->second; + if ( rElement.bModified ) + { + if ( xElementNameAccess->hasByName( rElement.aName )) + { + // Replace settings with data from user layer + Reference< XIndexAccess > xOldSettings( rElement.xSettings ); + + impl_requestUIElementData( nType, rElement ); + + ConfigurationEvent aReplaceEvent; + + aReplaceEvent.ResourceURL = rElement.aResourceURL; + aReplaceEvent.Accessor <<= xThis; + aReplaceEvent.Source = xIfac; + aReplaceEvent.ReplacedElement <<= xOldSettings; + aReplaceEvent.Element <<= rElement.xSettings; + rReplaceNotifyContainer.push_back( aReplaceEvent ); + + rElement.bModified = false; + } + else + { + // Element settings are not in any storage => remove + ConfigurationEvent aRemoveEvent; + + aRemoveEvent.ResourceURL = rElement.aResourceURL; + aRemoveEvent.Accessor <<= xThis; + aRemoveEvent.Source = xIfac; + aRemoveEvent.Element <<= rElement.xSettings; + + rRemoveNotifyContainer.push_back( aRemoveEvent ); + + // Mark element as default and not modified. That means "not active" in the document anymore + rElement.bModified = false; + rElement.bDefault = true; + } + } + ++pIter; + } + + rDocElementType.bModified = sal_False; +} + +void UIConfigurationManager::impl_Initialize() +{ + // Initialize the top-level structures with the storage data + if ( m_xDocConfigStorage.is() ) + { + long nModes = m_bReadOnly ? ElementModes::READ : ElementModes::READWRITE; + + // Try to access our module sub folder + for ( sal_Int16 i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; + i++ ) + { + Reference< XStorage > xElementTypeStorage; + try + { + xElementTypeStorage = m_xDocConfigStorage->openStorageElement( rtl::OUString::createFromAscii( UIELEMENTTYPENAMES[i] ), nModes ); + } + catch ( com::sun::star::container::NoSuchElementException& ) + { + } + catch ( ::com::sun::star::embed::InvalidStorageException& ) + { + } + catch ( ::com::sun::star::lang::IllegalArgumentException& ) + { + } + catch ( ::com::sun::star::io::IOException& ) + { + } + catch ( ::com::sun::star::embed::StorageWrappedTargetException& ) + { + } + + m_aUIElements[i].nElementType = i; + m_aUIElements[i].bModified = false; + m_aUIElements[i].xStorage = xElementTypeStorage; + m_aUIElements[i].bDefaultLayer = false; + } + } + else + { + // We have no storage, just initialize ui element types with empty storage! + for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ ) + m_aUIElements[i].xStorage = m_xDocConfigStorage; + } +} + +UIConfigurationManager::UIConfigurationManager( com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > xServiceManager ) : + ThreadHelpBase( &Application::GetSolarMutex() ) + , m_xDocConfigStorage( 0 ) + , m_bReadOnly( true ) + , m_bInitialized( false ) + , m_bModified( false ) + , m_bConfigRead( false ) + , m_bDisposed( false ) + , m_aXMLPostfix( RTL_CONSTASCII_USTRINGPARAM( ".xml" )) + , m_aPropUIName( RTL_CONSTASCII_USTRINGPARAM( "UIName" )) + , m_aPropResourceURL( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" )) + , m_xServiceManager( xServiceManager ) + , m_aListenerContainer( m_aLock.getShareableOslMutex() ) +{ + // Make sure we have a default initialized entry for every layer and user interface element type! + // The following code depends on this! + m_aUIElements.resize( ::com::sun::star::ui::UIElementType::COUNT ); } UIConfigurationManager::~UIConfigurationManager() @@ -123,86 +624,507 @@ UIConfigurationManager::~UIConfigurationManager() // XComponent void SAL_CALL UIConfigurationManager::dispose() throw (::com::sun::star::uno::RuntimeException) { - m_pImpl->dispose(); + Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY ); + + css::lang::EventObject aEvent( xThis ); + m_aListenerContainer.disposeAndClear( aEvent ); + + { + ResetableGuard aGuard( m_aLock ); + try + { + if ( m_xImageManager.is() ) + m_xImageManager->dispose(); + } + catch ( Exception& ) + { + } + + m_xImageManager.clear(); + m_aUIElements.clear(); + m_xDocConfigStorage.clear(); + m_bConfigRead = false; + m_bModified = false; + m_bDisposed = true; + } } void SAL_CALL UIConfigurationManager::addEventListener( const Reference< XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException) { + { + ResetableGuard aGuard( m_aLock ); - m_pImpl->addEventListener(xListener); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + if ( m_bDisposed ) + throw DisposedException(); + } + + m_aListenerContainer.addInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener ); } void SAL_CALL UIConfigurationManager::removeEventListener( const Reference< XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException) { - m_pImpl->removeEventListener(xListener); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener ); } // XUIConfigurationManager void SAL_CALL UIConfigurationManager::addConfigurationListener( const Reference< ::com::sun::star::ui::XUIConfigurationListener >& xListener ) throw (::com::sun::star::uno::RuntimeException) { - m_pImpl->addConfigurationListener(xListener); + { + ResetableGuard aGuard( m_aLock ); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + if ( m_bDisposed ) + throw DisposedException(); + } + + m_aListenerContainer.addInterface( ::getCppuType( ( const Reference< XUIConfigurationListener >* ) NULL ), xListener ); } void SAL_CALL UIConfigurationManager::removeConfigurationListener( const Reference< ::com::sun::star::ui::XUIConfigurationListener >& xListener ) throw (::com::sun::star::uno::RuntimeException) { - m_pImpl->removeConfigurationListener(xListener); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XUIConfigurationListener >* ) NULL ), xListener ); } void SAL_CALL UIConfigurationManager::reset() throw (::com::sun::star::uno::RuntimeException) { - m_pImpl->reset(); + ResetableGuard aGuard( m_aLock ); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + if ( m_bDisposed ) + throw DisposedException(); + + if ( isReadOnly() ) + return; + + bool bResetStorage( false ); + if ( m_xDocConfigStorage.is() ) + { + try + { + // Remove all elements from our user-defined storage! + bool bCommit( false ); + for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ ) + { + UIElementType& rElementType = m_aUIElements[i]; + Reference< XStorage > xSubStorage( rElementType.xStorage, UNO_QUERY ); + + if ( xSubStorage.is() ) + { + bool bCommitSubStorage( false ); + Reference< XNameAccess > xSubStorageNameAccess( xSubStorage, UNO_QUERY ); + Sequence< rtl::OUString > aUIElementStreamNames = xSubStorageNameAccess->getElementNames(); + for ( sal_Int32 j = 0; j < aUIElementStreamNames.getLength(); j++ ) + { + xSubStorage->removeElement( aUIElementStreamNames[j] ); + bCommitSubStorage = true; + bCommit = true; + } + + if ( bCommitSubStorage ) + { + Reference< XTransactedObject > xTransactedObject( xSubStorage, UNO_QUERY ); + if ( xTransactedObject.is() ) + xTransactedObject->commit(); + } + } + } + + // Commit changes + if ( bCommit ) + { + Reference< XTransactedObject > xTransactedObject( m_xDocConfigStorage, UNO_QUERY ); + if ( xTransactedObject.is() ) + xTransactedObject->commit(); + } + bResetStorage = true; + + // remove settings from user defined layer and notify listener about removed settings data! + // Try to access our module sub folder + ConfigEventNotifyContainer aRemoveEventNotifyContainer; + for ( sal_Int16 j = 1; j < ::com::sun::star::ui::UIElementType::COUNT; j++ ) + { + UIElementType& rDocElementType = m_aUIElements[j]; + + impl_resetElementTypeData( rDocElementType, aRemoveEventNotifyContainer ); + rDocElementType.bModified = sal_False; + } + + m_bModified = sal_False; + + // Unlock mutex before notify our listeners + aGuard.unlock(); + + // Notify our listeners + for ( sal_uInt32 k = 0; k < aRemoveEventNotifyContainer.size(); k++ ) + implts_notifyContainerListener( aRemoveEventNotifyContainer[k], NotifyOp_Remove ); + } + catch ( ::com::sun::star::lang::IllegalArgumentException& ) + { + } + catch ( ::com::sun::star::container::NoSuchElementException& ) + { + } + catch ( ::com::sun::star::embed::InvalidStorageException& ) + { + } + catch ( ::com::sun::star::embed::StorageWrappedTargetException& ) + { + } + } } Sequence< Sequence< PropertyValue > > SAL_CALL UIConfigurationManager::getUIElementsInfo( sal_Int16 ElementType ) throw ( IllegalArgumentException, RuntimeException ) { - return m_pImpl->getUIElementsInfo(ElementType); + if (( ElementType < 0 ) || ( ElementType >= ::com::sun::star::ui::UIElementType::COUNT )) + throw IllegalArgumentException(); + + ResetableGuard aGuard( m_aLock ); + if ( m_bDisposed ) + throw DisposedException(); + + Sequence< Sequence< PropertyValue > > aElementInfoSeq; + UIElementInfoHashMap aUIElementInfoCollection; + + if ( ElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) + { + for ( sal_Int16 i = 0; i < ::com::sun::star::ui::UIElementType::COUNT; i++ ) + impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection, sal_Int16( i ) ); + } + else + impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection, ElementType ); + + Sequence< PropertyValue > aUIElementInfo( 2 ); + aUIElementInfo[0].Name = m_aPropResourceURL; + aUIElementInfo[1].Name = m_aPropUIName; + + aElementInfoSeq.realloc( aUIElementInfoCollection.size() ); + UIElementInfoHashMap::const_iterator pIter = aUIElementInfoCollection.begin(); + + sal_Int32 n = 0; + while ( pIter != aUIElementInfoCollection.end() ) + { + aUIElementInfo[0].Value <<= pIter->second.aResourceURL; + aUIElementInfo[1].Value <<= pIter->second.aUIName; + aElementInfoSeq[n++] = aUIElementInfo; + ++pIter; + } + + return aElementInfoSeq; } Reference< XIndexContainer > SAL_CALL UIConfigurationManager::createSettings() throw (::com::sun::star::uno::RuntimeException) { - return m_pImpl->createSettings(); + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + throw DisposedException(); + + // Creates an empty item container which can be filled from outside + return Reference< XIndexContainer >( static_cast< OWeakObject * >( new RootItemContainer()), UNO_QUERY ); } sal_Bool SAL_CALL UIConfigurationManager::hasSettings( const ::rtl::OUString& ResourceURL ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) { - return m_pImpl->hasSettings(ResourceURL); + sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL ); + + if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) || + ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT )) + throw IllegalArgumentException(); + else + { + UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType, false ); + if ( pDataSettings && !pDataSettings->bDefault ) + return sal_True; + } + + return sal_False; } Reference< XIndexAccess > SAL_CALL UIConfigurationManager::getSettings( const ::rtl::OUString& ResourceURL, sal_Bool bWriteable ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) { - return m_pImpl->getSettings(ResourceURL,bWriteable); + sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL ); + + if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) || + ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT )) + throw IllegalArgumentException(); + else + { + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + throw DisposedException(); + + UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType ); + if ( pDataSettings && !pDataSettings->bDefault ) + { + // Create a copy of our data if someone wants to change the data. + if ( bWriteable ) + return Reference< XIndexAccess >( static_cast< OWeakObject * >( new RootItemContainer( pDataSettings->xSettings ) ), UNO_QUERY ); + else + return pDataSettings->xSettings; + } + } + + throw NoSuchElementException(); } void SAL_CALL UIConfigurationManager::replaceSettings( const ::rtl::OUString& ResourceURL, const Reference< ::com::sun::star::container::XIndexAccess >& aNewData ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException) { - return m_pImpl->replaceSettings(ResourceURL,aNewData); + sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL ); + + if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) || + ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT )) + throw IllegalArgumentException(); + else if ( m_bReadOnly ) + throw IllegalAccessException(); + else + { + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + throw DisposedException(); + + UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType ); + if ( pDataSettings && !pDataSettings->bDefault ) + { + // we have a settings entry in our user-defined layer - replace + Reference< XIndexAccess > xOldSettings = pDataSettings->xSettings; + + // Create a copy of the data if the container is not const + Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY ); + if ( xReplace.is() ) + pDataSettings->xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( aNewData ) ), UNO_QUERY ); + else + pDataSettings->xSettings = aNewData; + + pDataSettings->bDefault = false; + pDataSettings->bModified = true; + m_bModified = true; + + // Modify type container + UIElementType& rElementType = m_aUIElements[nElementType]; + rElementType.bModified = true; + + Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY ); + + // Create event to notify listener about replaced element settings + ConfigurationEvent aEvent; + Reference< XInterface > xIfac( xThis, UNO_QUERY ); + + aEvent.ResourceURL = ResourceURL; + aEvent.Accessor <<= xThis; + aEvent.Source = xIfac; + aEvent.ReplacedElement <<= xOldSettings; + aEvent.Element <<= pDataSettings->xSettings; + + aGuard.unlock(); + + implts_notifyContainerListener( aEvent, NotifyOp_Replace ); + } + else + throw NoSuchElementException(); + } } void SAL_CALL UIConfigurationManager::removeSettings( const ::rtl::OUString& ResourceURL ) throw ( NoSuchElementException, IllegalArgumentException, IllegalAccessException, RuntimeException) { - m_pImpl->removeSettings(ResourceURL); + sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL ); + + if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) || + ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT )) + throw IllegalArgumentException(); + else if ( m_bReadOnly ) + throw IllegalAccessException(); + else + { + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + throw DisposedException(); + + UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType ); + if ( pDataSettings ) + { + // If element settings are default, we don't need to change anything! + if ( pDataSettings->bDefault ) + return; + else + { + Reference< XIndexAccess > xRemovedSettings = pDataSettings->xSettings; + pDataSettings->bDefault = true; + + // check if this is a default layer node + pDataSettings->bModified = true; // we have to remove this node from the user layer! + pDataSettings->xSettings.clear(); + m_bModified = true; // user layer must be written + + // Modify type container + UIElementType& rElementType = m_aUIElements[nElementType]; + rElementType.bModified = true; + + Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY ); + Reference< XInterface > xIfac( xThis, UNO_QUERY ); + + // Create event to notify listener about removed element settings + ConfigurationEvent aEvent; + + aEvent.ResourceURL = ResourceURL; + aEvent.Accessor <<= xThis; + aEvent.Source = xIfac; + aEvent.Element <<= xRemovedSettings; + + aGuard.unlock(); + + implts_notifyContainerListener( aEvent, NotifyOp_Remove ); + } + } + else + throw NoSuchElementException(); + } } void SAL_CALL UIConfigurationManager::insertSettings( const ::rtl::OUString& NewResourceURL, const Reference< XIndexAccess >& aNewData ) throw ( ElementExistException, IllegalArgumentException, IllegalAccessException, RuntimeException ) { - m_pImpl->insertSettings(NewResourceURL,aNewData); + sal_Int16 nElementType = RetrieveTypeFromResourceURL( NewResourceURL ); + + if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) || + ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT )) + throw IllegalArgumentException(); + else if ( m_bReadOnly ) + throw IllegalAccessException(); + else + { + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + throw DisposedException(); + + bool bInsertData( false ); + UIElementData aUIElementData; + UIElementData* pDataSettings = impl_findUIElementData( NewResourceURL, nElementType ); + + if ( pDataSettings && !pDataSettings->bDefault ) + throw ElementExistException(); + + if ( !pDataSettings ) + { + pDataSettings = &aUIElementData; + bInsertData = true; + } + + { + pDataSettings->bDefault = false; + pDataSettings->bModified = true; + + // Create a copy of the data if the container is not const + Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY ); + if ( xReplace.is() ) + pDataSettings->xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( aNewData ) ), UNO_QUERY ); + else + pDataSettings->xSettings = aNewData; + + m_bModified = true; + + UIElementType& rElementType = m_aUIElements[nElementType]; + rElementType.bModified = true; + + if ( bInsertData ) + { + pDataSettings->aName = RetrieveNameFromResourceURL( NewResourceURL ) + m_aXMLPostfix; + pDataSettings->aResourceURL = NewResourceURL; + + UIElementDataHashMap& rElements = rElementType.aElementsHashMap; + rElements.insert( UIElementDataHashMap::value_type( NewResourceURL, *pDataSettings )); + } + + Reference< XIndexAccess > xInsertSettings( aUIElementData.xSettings ); + Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY ); + Reference< XInterface > xIfac( xThis, UNO_QUERY ); + + // Create event to notify listener about removed element settings + ConfigurationEvent aEvent; + + aEvent.ResourceURL = NewResourceURL; + aEvent.Accessor <<= xThis; + aEvent.Source = xIfac; + aEvent.Element <<= xInsertSettings; + + aGuard.unlock(); + + implts_notifyContainerListener( aEvent, NotifyOp_Insert ); + } + } } Reference< XInterface > SAL_CALL UIConfigurationManager::getImageManager() throw (::com::sun::star::uno::RuntimeException) { - return m_pImpl->getImageManager(); + if ( m_bDisposed ) + throw DisposedException(); + + if ( !m_xImageManager.is() ) + { + m_xImageManager = Reference< XComponent >( static_cast< cppu::OWeakObject *>( new ImageManager( m_xServiceManager )), + UNO_QUERY ); + Reference< XInitialization > xInit( m_xImageManager, UNO_QUERY ); + + Sequence< Any > aPropSeq( 2 ); + PropertyValue aPropValue; + aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserConfigStorage" )); + aPropValue.Value = makeAny( m_xDocConfigStorage ); + aPropSeq[0] = makeAny( aPropValue ); + aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleIdentifier" )); + aPropValue.Value = makeAny( m_aModuleIdentifier ); + aPropSeq[1] = makeAny( aPropValue ); + + xInit->initialize( aPropSeq ); + } + + return Reference< XInterface >( m_xImageManager, UNO_QUERY ); } Reference< XInterface > SAL_CALL UIConfigurationManager::getShortCutManager() throw (::com::sun::star::uno::RuntimeException) { - return m_pImpl->getShortCutManager(); + // SAFE -> + ResetableGuard aGuard( m_aLock ); + + if (m_xAccConfig.is()) + return m_xAccConfig; + + Reference< XMultiServiceFactory > xSMGR = m_xServiceManager; + Reference< XStorage > xDocumentRoot = m_xDocConfigStorage; + + aGuard.unlock(); + // <- SAFE + + Reference< XInterface > xAccConfig = xSMGR->createInstance(SERVICENAME_DOCUMENTACCELERATORCONFIGURATION); + Reference< XInitialization > xInit (xAccConfig, UNO_QUERY_THROW); + + PropertyValue aProp; + aProp.Name = ::rtl::OUString::createFromAscii("DocumentRoot"); + aProp.Value <<= xDocumentRoot; + + Sequence< Any > lArgs(1); + lArgs[0] <<= aProp; + + xInit->initialize(lArgs); + + // SAFE -> + aGuard.lock(); + m_xAccConfig = xAccConfig; + aGuard.unlock(); + // <- SAFE + + return xAccConfig; } Reference< XInterface > SAL_CALL UIConfigurationManager::getEventsManager() throw (::com::sun::star::uno::RuntimeException) @@ -213,38 +1135,223 @@ Reference< XInterface > SAL_CALL UIConfigurationManager::getEventsManager() thro // XUIConfigurationStorage void SAL_CALL UIConfigurationManager::setStorage( const Reference< XStorage >& Storage ) throw (::com::sun::star::uno::RuntimeException) { - m_pImpl->setStorage(Storage); + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + throw DisposedException(); + + if ( m_xDocConfigStorage.is() ) + { + try + { + // Dispose old storage to be sure that it will be closed + Reference< XComponent > xComponent( m_xDocConfigStorage, UNO_QUERY ); + if ( xComponent.is() ) + xComponent->dispose(); + } + catch ( Exception& ) + { + } + } + + // We store the new storage. Be careful it could be an empty reference! + m_xDocConfigStorage = Storage; + m_bReadOnly = sal_True; + + Reference< XUIConfigurationStorage > xAccUpdate(m_xAccConfig, UNO_QUERY); + if ( xAccUpdate.is() ) + xAccUpdate->setStorage( m_xDocConfigStorage ); + + if ( m_xImageManager.is() ) + { + ImageManager* pImageManager = (ImageManager*)m_xImageManager.get(); + if ( pImageManager ) + pImageManager->setStorage( m_xDocConfigStorage ); + } + + if ( m_xDocConfigStorage.is() ) + { + Reference< XPropertySet > xPropSet( m_xDocConfigStorage, UNO_QUERY ); + if ( xPropSet.is() ) + { + try + { + long nOpenMode = 0; + Any a = xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenMode" ))); + if ( a >>= nOpenMode ) + m_bReadOnly = !( nOpenMode & ElementModes::WRITE ); + } + catch ( com::sun::star::beans::UnknownPropertyException& ) + { + } + catch ( com::sun::star::lang::WrappedTargetException& ) + { + } + } + } + + impl_Initialize(); } sal_Bool SAL_CALL UIConfigurationManager::hasStorage() throw (::com::sun::star::uno::RuntimeException) { - return m_pImpl->hasStorage(); + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + throw DisposedException(); + + return ( m_xDocConfigStorage.is() ); } // XUIConfigurationPersistence void SAL_CALL UIConfigurationManager::reload() throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) { - m_pImpl->reload(); + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + throw DisposedException(); + + if ( m_xDocConfigStorage.is() && m_bModified && !m_bReadOnly ) + { + // Try to access our module sub folder + ConfigEventNotifyContainer aRemoveNotifyContainer; + ConfigEventNotifyContainer aReplaceNotifyContainer; + for ( sal_Int16 i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ ) + { + try + { + UIElementType& rDocElementType = m_aUIElements[i]; + if ( rDocElementType.bModified ) + impl_reloadElementTypeData( rDocElementType, aRemoveNotifyContainer, aReplaceNotifyContainer ); + } + catch ( Exception& ) + { + throw IOException(); + } + } + + m_bModified = sal_False; + + // Unlock mutex before notify our listeners + aGuard.unlock(); + + // Notify our listeners + for ( sal_uInt32 j = 0; j < aRemoveNotifyContainer.size(); j++ ) + implts_notifyContainerListener( aRemoveNotifyContainer[j], NotifyOp_Remove ); + for ( sal_uInt32 k = 0; k < aReplaceNotifyContainer.size(); k++ ) + implts_notifyContainerListener( aReplaceNotifyContainer[k], NotifyOp_Replace ); + } } void SAL_CALL UIConfigurationManager::store() throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) { - m_pImpl->store(); + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + throw DisposedException(); + + if ( m_xDocConfigStorage.is() && m_bModified && !m_bReadOnly ) + { + // Try to access our module sub folder + for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ ) + { + try + { + UIElementType& rElementType = m_aUIElements[i]; + Reference< XStorage > xStorage( rElementType.xStorage, UNO_QUERY ); + + if ( rElementType.bModified && xStorage.is() ) + impl_storeElementTypeData( xStorage, rElementType ); + } + catch ( Exception& ) + { + throw IOException(); + } + } + + m_bModified = false; + Reference< XTransactedObject > xTransactedObject( m_xDocConfigStorage, UNO_QUERY ); + if ( xTransactedObject.is() ) + xTransactedObject->commit(); + } } void SAL_CALL UIConfigurationManager::storeToStorage( const Reference< XStorage >& Storage ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) { - m_pImpl->storeToStorage(Storage); + ResetableGuard aGuard( m_aLock ); + + if ( m_bDisposed ) + throw DisposedException(); + + if ( m_xDocConfigStorage.is() && m_bModified && !m_bReadOnly ) + { + // Try to access our module sub folder + for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ ) + { + try + { + Reference< XStorage > xElementTypeStorage( Storage->openStorageElement( + rtl::OUString::createFromAscii( UIELEMENTTYPENAMES[i] ), ElementModes::READWRITE )); + UIElementType& rElementType = m_aUIElements[i]; + + if ( rElementType.bModified && xElementTypeStorage.is() ) + impl_storeElementTypeData( xElementTypeStorage, rElementType, false ); // store data to storage, but don't reset modify flag! + } + catch ( Exception& ) + { + throw IOException(); + } + } + + Reference< XTransactedObject > xTransactedObject( Storage, UNO_QUERY ); + if ( xTransactedObject.is() ) + xTransactedObject->commit(); + } } sal_Bool SAL_CALL UIConfigurationManager::isModified() throw (::com::sun::star::uno::RuntimeException) { - return m_pImpl->isModified(); + ResetableGuard aGuard( m_aLock ); + + return m_bModified; } sal_Bool SAL_CALL UIConfigurationManager::isReadOnly() throw (::com::sun::star::uno::RuntimeException) { - return m_pImpl->isReadOnly(); + ResetableGuard aGuard( m_aLock ); + + return m_bReadOnly; +} + +void UIConfigurationManager::implts_notifyContainerListener( const ConfigurationEvent& aEvent, NotifyOp eOp ) +{ + ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( ::getCppuType( ( const css::uno::Reference< ::com::sun::star::ui::XUIConfigurationListener >*) NULL ) ); + if ( pContainer != NULL ) + { + ::cppu::OInterfaceIteratorHelper pIterator( *pContainer ); + while ( pIterator.hasMoreElements() ) + { + try + { + switch ( eOp ) + { + case NotifyOp_Replace: + ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementReplaced( aEvent ); + break; + case NotifyOp_Insert: + ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementInserted( aEvent ); + break; + case NotifyOp_Remove: + ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementRemoved( aEvent ); + break; + } + } + catch( css::uno::RuntimeException& ) + { + pIterator.remove(); + } + } + } } } // namespace framework diff --git a/framework/source/uiconfiguration/uiconfigurationmanagerimpl.cxx b/framework/source/uiconfiguration/uiconfigurationmanagerimpl.cxx index 5b67b13d8805..40c2c3f10708 100755 --- a/framework/source/uiconfiguration/uiconfigurationmanagerimpl.cxx +++ b/framework/source/uiconfiguration/uiconfigurationmanagerimpl.cxx @@ -148,12 +148,12 @@ void UIConfigurationManagerImpl::impl_fillSequenceWithElementTypeInfo( UIElement while ( pUserIter != rUserElements.end() ) { sal_Int32 nIndex = pUserIter->second.aResourceURL.indexOf( aCustomUrlPrefix, RESOURCEURL_PREFIX_SIZE ); - if ( !m_bUseDefault && nIndex > RESOURCEURL_PREFIX_SIZE ) + if ( nIndex > RESOURCEURL_PREFIX_SIZE ) { // Performance: Retrieve user interface name only for custom user interface elements. // It's only used by them! UIElementData* pDataSettings = impl_findUIElementData( pUserIter->second.aResourceURL, nElementType ); - if ( pDataSettings && ( !m_bUseDefault || !pDataSettings->bDefault) ) + if ( pDataSettings && ( m_bUseDefault || !pDataSettings->bDefault )) { // Retrieve user interface name from XPropertySet interface rtl::OUString aUIName; @@ -1268,7 +1268,7 @@ throw ( ElementExistException, IllegalArgumentException, IllegalAccessException, if ( m_bDisposed ) throw DisposedException(); - bool bInsertData( m_bUseDefault ); + bool bInsertData( false ); UIElementData aUIElementData; UIElementData* pDataSettings = impl_findUIElementData( NewResourceURL, nElementType ); if ( !m_bUseDefault ) @@ -1281,7 +1281,7 @@ throw ( ElementExistException, IllegalArgumentException, IllegalAccessException, bInsertData = true; } } - if ( !pDataSettings || bInsertData ) + if ( !pDataSettings || !m_bUseDefault ) { aUIElementData.bDefault = false; if ( !m_bUseDefault ) diff --git a/framework/util/makefile.mk b/framework/util/makefile.mk index 60a44dba706f..0a07f3cf137d 100644 --- a/framework/util/makefile.mk +++ b/framework/util/makefile.mk @@ -334,7 +334,6 @@ SHL4OBJS= \ $(SLO)$/uicategorydescription.obj \ $(SLO)$/uicommanddescription.obj \ $(SLO)$/uiconfigurationmanager.obj \ - $(SLO)$/uiconfigurationmanagerimpl.obj \ $(SLO)$/uielementfactorymanager.obj \ $(SLO)$/urltransformer.obj \ $(SLO)$/vclstatusindicator.obj \ |