fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / framework / source / uiconfiguration / moduleuiconfigurationmanager.cxx
blobe4030b766d437da56c8915043f3951da196f840b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <accelerators/presethandler.hxx>
21 #include <uiconfiguration/moduleimagemanager.hxx>
22 #include <stdtypes.h>
23 #include <uielement/constitemcontainer.hxx>
24 #include <uielement/rootitemcontainer.hxx>
25 #include <uielement/uielementtypenames.hxx>
26 #include <framework/menuconfiguration.hxx>
27 #include <framework/toolboxconfiguration.hxx>
29 #include <framework/statusbarconfiguration.hxx>
31 #include <com/sun/star/ui/UIElementType.hpp>
32 #include <com/sun/star/ui/ConfigurationEvent.hpp>
33 #include <com/sun/star/ui/ModuleAcceleratorConfiguration.hpp>
34 #include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
35 #include <com/sun/star/ui/XModuleUIConfigurationManager2.hpp>
36 #include <com/sun/star/lang/DisposedException.hpp>
37 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
38 #include <com/sun/star/beans/XPropertySet.hpp>
39 #include <com/sun/star/embed/ElementModes.hpp>
40 #include <com/sun/star/embed/XTransactedObject.hpp>
41 #include <com/sun/star/container/XNameAccess.hpp>
42 #include <com/sun/star/container/XIndexContainer.hpp>
43 #include <com/sun/star/io/XStream.hpp>
44 #include <com/sun/star/lang/XServiceInfo.hpp>
45 #include <com/sun/star/lang/XComponent.hpp>
47 #include <cppuhelper/implbase3.hxx>
48 #include <cppuhelper/interfacecontainer.hxx>
49 #include <cppuhelper/supportsservice.hxx>
50 #include <vcl/svapp.hxx>
51 #include <rtl/ref.hxx>
52 #include <rtl/ustrbuf.hxx>
53 #include <comphelper/sequenceashashmap.hxx>
55 using namespace css;
56 using namespace com::sun::star::uno;
57 using namespace com::sun::star::io;
58 using namespace com::sun::star::embed;
59 using namespace com::sun::star::lang;
60 using namespace com::sun::star::container;
61 using namespace com::sun::star::beans;
62 using namespace framework;
64 #define RESOURCETYPE_MENUBAR "menubar"
65 #define RESOURCETYPE_TOOLBAR "toolbar"
66 #define RESOURCETYPE_STATUSBAR "statusbar"
68 namespace {
70 class ModuleUIConfigurationManager : public cppu::WeakImplHelper3<
71 css::lang::XServiceInfo,
72 css::lang::XComponent,
73 css::ui::XModuleUIConfigurationManager2 >
75 public:
76 ModuleUIConfigurationManager(
77 const css::uno::Reference< css::uno::XComponentContext >& xServiceManager,
78 const css::uno::Sequence< css::uno::Any >& aArguments);
80 virtual ~ModuleUIConfigurationManager();
82 virtual OUString SAL_CALL getImplementationName()
83 throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
85 return OUString("com.sun.star.comp.framework.ModuleUIConfigurationManager");
88 virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName)
89 throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
91 return cppu::supportsService(this, ServiceName);
94 virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames()
95 throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
97 css::uno::Sequence< OUString > aSeq(1);
98 aSeq[0] = "com.sun.star.ui.ModuleUIConfigurationManager";
99 return aSeq;
102 // XComponent
103 virtual void SAL_CALL dispose() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
104 virtual void SAL_CALL addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
105 virtual void SAL_CALL removeEventListener( const css::uno::Reference< css::lang::XEventListener >& aListener ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
107 // XUIConfiguration
108 virtual void SAL_CALL addConfigurationListener( const css::uno::Reference< css::ui::XUIConfigurationListener >& Listener ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
109 virtual void SAL_CALL removeConfigurationListener( const css::uno::Reference< css::ui::XUIConfigurationListener >& Listener ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
111 // XUIConfigurationManager
112 virtual void SAL_CALL reset() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
113 virtual css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > SAL_CALL getUIElementsInfo( sal_Int16 ElementType ) throw (css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
114 virtual css::uno::Reference< css::container::XIndexContainer > SAL_CALL createSettings( ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
115 virtual sal_Bool SAL_CALL hasSettings( const OUString& ResourceURL ) throw (css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
116 virtual css::uno::Reference< css::container::XIndexAccess > SAL_CALL getSettings( const OUString& ResourceURL, sal_Bool bWriteable ) throw (css::container::NoSuchElementException, css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
117 virtual void SAL_CALL replaceSettings( const OUString& ResourceURL, const css::uno::Reference< css::container::XIndexAccess >& aNewData ) throw (css::container::NoSuchElementException, css::lang::IllegalArgumentException, css::lang::IllegalAccessException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
118 virtual void SAL_CALL removeSettings( const OUString& ResourceURL ) throw (css::container::NoSuchElementException, css::lang::IllegalArgumentException, css::lang::IllegalAccessException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
119 virtual void SAL_CALL insertSettings( const OUString& NewResourceURL, const css::uno::Reference< css::container::XIndexAccess >& aNewData ) throw (css::container::ElementExistException, css::lang::IllegalArgumentException, css::lang::IllegalAccessException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
120 virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getImageManager() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
121 virtual css::uno::Reference< css::ui::XAcceleratorConfiguration > SAL_CALL getShortCutManager() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
122 virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getEventsManager() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
124 // XModuleUIConfigurationManager
125 virtual sal_Bool SAL_CALL isDefaultSettings( const OUString& ResourceURL ) throw (css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
126 virtual css::uno::Reference< css::container::XIndexAccess > SAL_CALL getDefaultSettings( const OUString& ResourceURL ) throw (css::container::NoSuchElementException, css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
128 // XUIConfigurationPersistence
129 virtual void SAL_CALL reload() throw (css::uno::Exception, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
130 virtual void SAL_CALL store() throw (css::uno::Exception, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
131 virtual void SAL_CALL storeToStorage( const css::uno::Reference< css::embed::XStorage >& Storage ) throw (css::uno::Exception, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
132 virtual sal_Bool SAL_CALL isModified() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
133 virtual sal_Bool SAL_CALL isReadOnly() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
135 private:
136 // private data types
137 enum Layer
139 LAYER_DEFAULT,
140 LAYER_USERDEFINED,
141 LAYER_COUNT
144 enum NotifyOp
146 NotifyOp_Remove,
147 NotifyOp_Insert,
148 NotifyOp_Replace
151 struct UIElementInfo
153 UIElementInfo( const OUString& rResourceURL, const OUString& rUIName ) :
154 aResourceURL( rResourceURL), aUIName( rUIName ) {}
155 OUString aResourceURL;
156 OUString aUIName;
159 struct UIElementData
161 UIElementData() : bModified( false ), bDefault( true ), bDefaultNode( true ) {};
163 OUString aResourceURL;
164 OUString aName;
165 bool bModified; // has been changed since last storing
166 bool bDefault; // default settings
167 bool bDefaultNode; // this is a default layer element data
168 css::uno::Reference< css::container::XIndexAccess > xSettings;
171 typedef std::unordered_map< OUString, UIElementData, OUStringHash, std::equal_to< OUString > > UIElementDataHashMap;
173 struct UIElementType
175 UIElementType() : bModified( false ),
176 bLoaded( false ),
177 bDefaultLayer( false ),
178 nElementType( css::ui::UIElementType::UNKNOWN ) {}
180 bool bModified;
181 bool bLoaded;
182 bool bDefaultLayer;
183 sal_Int16 nElementType;
184 UIElementDataHashMap aElementsHashMap;
185 css::uno::Reference< css::embed::XStorage > xStorage;
188 typedef std::vector< UIElementType > UIElementTypesVector;
189 typedef std::vector< css::ui::ConfigurationEvent > ConfigEventNotifyContainer;
190 typedef std::unordered_map< OUString, UIElementInfo, OUStringHash, std::equal_to< OUString > > UIElementInfoHashMap;
192 void impl_Initialize();
193 void implts_notifyContainerListener( const css::ui::ConfigurationEvent& aEvent, NotifyOp eOp );
194 void impl_fillSequenceWithElementTypeInfo( UIElementInfoHashMap& aUIElementInfoCollection, sal_Int16 nElementType );
195 void impl_preloadUIElementTypeList( Layer eLayer, sal_Int16 nElementType );
196 UIElementData* impl_findUIElementData( const OUString& aResourceURL, sal_Int16 nElementType, bool bLoad = true );
197 void impl_requestUIElementData( sal_Int16 nElementType, Layer eLayer, UIElementData& aUIElementData );
198 void impl_storeElementTypeData( css::uno::Reference< css::embed::XStorage > xStorage, UIElementType& rElementType, bool bResetModifyState = true );
199 void impl_resetElementTypeData( UIElementType& rUserElementType, UIElementType& rDefaultElementType, ConfigEventNotifyContainer& rRemoveNotifyContainer, ConfigEventNotifyContainer& rReplaceNotifyContainer );
200 void impl_reloadElementTypeData( UIElementType& rUserElementType, UIElementType& rDefaultElementType, ConfigEventNotifyContainer& rRemoveNotifyContainer, ConfigEventNotifyContainer& rReplaceNotifyContainer );
202 UIElementTypesVector m_aUIElements[LAYER_COUNT];
203 PresetHandler* m_pStorageHandler[css::ui::UIElementType::COUNT];
204 css::uno::Reference< css::embed::XStorage > m_xDefaultConfigStorage;
205 css::uno::Reference< css::embed::XStorage > m_xUserConfigStorage;
206 bool m_bReadOnly;
207 bool m_bModified;
208 bool m_bConfigRead;
209 bool m_bDisposed;
210 OUString m_aXMLPostfix;
211 OUString m_aPropUIName;
212 OUString m_aPropResourceURL;
213 OUString m_aModuleIdentifier;
214 OUString m_aModuleShortName;
215 css::uno::Reference< css::embed::XTransactedObject > m_xUserRootCommit;
216 css::uno::Reference< css::uno::XComponentContext > m_xContext;
217 osl::Mutex m_mutex;
218 ::cppu::OMultiTypeInterfaceContainerHelper m_aListenerContainer; /// container for ALL Listener
219 css::uno::Reference< css::lang::XComponent > m_xModuleImageManager;
220 css::uno::Reference< css::ui::XAcceleratorConfiguration > m_xModuleAcceleratorManager;
223 // important: The order and position of the elements must match the constant
224 // definition of "::com::sun::star::ui::UIElementType"
225 static const char* UIELEMENTTYPENAMES[] =
227 "", // Dummy value for unknown!
228 UIELEMENTTYPE_MENUBAR_NAME,
229 UIELEMENTTYPE_POPUPMENU_NAME,
230 UIELEMENTTYPE_TOOLBAR_NAME,
231 UIELEMENTTYPE_STATUSBAR_NAME,
232 UIELEMENTTYPE_FLOATINGWINDOW_NAME,
233 UIELEMENTTYPE_PROGRESSBAR_NAME,
234 UIELEMENTTYPE_TOOLPANEL_NAME
237 static const char RESOURCEURL_PREFIX[] = "private:resource/";
238 static const sal_Int32 RESOURCEURL_PREFIX_SIZE = 17;
239 static const char RESOURCEURL_CUSTOM_ELEMENT[] = "custom_";
241 static sal_Int16 RetrieveTypeFromResourceURL( const OUString& aResourceURL )
244 if (( aResourceURL.startsWith( RESOURCEURL_PREFIX ) ) &&
245 ( aResourceURL.getLength() > RESOURCEURL_PREFIX_SIZE ))
247 OUString aTmpStr = aResourceURL.copy( RESOURCEURL_PREFIX_SIZE );
248 sal_Int32 nIndex = aTmpStr.indexOf( '/' );
249 if (( nIndex > 0 ) && ( aTmpStr.getLength() > nIndex ))
251 OUString aTypeStr( aTmpStr.copy( 0, nIndex ));
252 for ( int i = 0; i < ui::UIElementType::COUNT; i++ )
254 if ( aTypeStr.equalsAscii( UIELEMENTTYPENAMES[i] ))
255 return sal_Int16( i );
260 return ui::UIElementType::UNKNOWN;
263 static OUString RetrieveNameFromResourceURL( const OUString& aResourceURL )
265 if (( aResourceURL.startsWith( RESOURCEURL_PREFIX ) ) &&
266 ( aResourceURL.getLength() > RESOURCEURL_PREFIX_SIZE ))
268 sal_Int32 nIndex = aResourceURL.lastIndexOf( '/' );
269 if (( nIndex > 0 ) && (( nIndex+1 ) < aResourceURL.getLength()))
270 return aResourceURL.copy( nIndex+1 );
273 return OUString();
276 void ModuleUIConfigurationManager::impl_fillSequenceWithElementTypeInfo( UIElementInfoHashMap& aUIElementInfoCollection, sal_Int16 nElementType )
278 // preload list of element types on demand
279 impl_preloadUIElementTypeList( LAYER_USERDEFINED, nElementType );
280 impl_preloadUIElementTypeList( LAYER_DEFAULT, nElementType );
282 UIElementDataHashMap& rUserElements = m_aUIElements[LAYER_USERDEFINED][nElementType].aElementsHashMap;
283 UIElementDataHashMap::const_iterator pUserIter = rUserElements.begin();
285 OUString aCustomUrlPrefix( RESOURCEURL_CUSTOM_ELEMENT );
286 while ( pUserIter != rUserElements.end() )
288 sal_Int32 nIndex = pUserIter->second.aResourceURL.indexOf( aCustomUrlPrefix, RESOURCEURL_PREFIX_SIZE );
289 if ( nIndex > RESOURCEURL_PREFIX_SIZE )
291 // Performance: Retrieve user interface name only for custom user interface elements.
292 // It's only used by them!
293 UIElementData* pDataSettings = impl_findUIElementData( pUserIter->second.aResourceURL, nElementType );
294 if ( pDataSettings )
296 // Retrieve user interface name from XPropertySet interface
297 OUString aUIName;
298 Reference< XPropertySet > xPropSet( pDataSettings->xSettings, UNO_QUERY );
299 if ( xPropSet.is() )
301 Any a = xPropSet->getPropertyValue( m_aPropUIName );
302 a >>= aUIName;
305 UIElementInfo aInfo( pUserIter->second.aResourceURL, aUIName );
306 aUIElementInfoCollection.insert( UIElementInfoHashMap::value_type( pUserIter->second.aResourceURL, aInfo ));
309 else
311 // The user interface name for standard user interface elements is stored in the WindowState.xcu file
312 UIElementInfo aInfo( pUserIter->second.aResourceURL, OUString() );
313 aUIElementInfoCollection.insert( UIElementInfoHashMap::value_type( pUserIter->second.aResourceURL, aInfo ));
315 ++pUserIter;
318 UIElementDataHashMap& rDefaultElements = m_aUIElements[LAYER_DEFAULT][nElementType].aElementsHashMap;
319 UIElementDataHashMap::const_iterator pDefIter = rDefaultElements.begin();
321 while ( pDefIter != rDefaultElements.end() )
323 UIElementInfoHashMap::const_iterator pIterInfo = aUIElementInfoCollection.find( pDefIter->second.aResourceURL );
324 if ( pIterInfo == aUIElementInfoCollection.end() )
326 sal_Int32 nIndex = pDefIter->second.aResourceURL.indexOf( aCustomUrlPrefix, RESOURCEURL_PREFIX_SIZE );
327 if ( nIndex > RESOURCEURL_PREFIX_SIZE )
329 // Performance: Retrieve user interface name only for custom user interface elements.
330 // It's only used by them!
331 UIElementData* pDataSettings = impl_findUIElementData( pDefIter->second.aResourceURL, nElementType );
332 if ( pDataSettings )
334 // Retrieve user interface name from XPropertySet interface
335 OUString aUIName;
336 Reference< XPropertySet > xPropSet( pDataSettings->xSettings, UNO_QUERY );
337 if ( xPropSet.is() )
339 Any a = xPropSet->getPropertyValue( m_aPropUIName );
340 a >>= aUIName;
343 UIElementInfo aInfo( pDefIter->second.aResourceURL, aUIName );
344 aUIElementInfoCollection.insert( UIElementInfoHashMap::value_type( pDefIter->second.aResourceURL, aInfo ));
347 else
349 // The user interface name for standard user interface elements is stored in the WindowState.xcu file
350 UIElementInfo aInfo( pDefIter->second.aResourceURL, OUString() );
351 aUIElementInfoCollection.insert( UIElementInfoHashMap::value_type( pDefIter->second.aResourceURL, aInfo ));
355 ++pDefIter;
359 void ModuleUIConfigurationManager::impl_preloadUIElementTypeList( Layer eLayer, sal_Int16 nElementType )
361 UIElementType& rElementTypeData = m_aUIElements[eLayer][nElementType];
363 if ( !rElementTypeData.bLoaded )
365 Reference< XStorage > xElementTypeStorage = rElementTypeData.xStorage;
366 if ( xElementTypeStorage.is() )
368 OUStringBuffer aBuf( RESOURCEURL_PREFIX_SIZE );
369 aBuf.appendAscii( RESOURCEURL_PREFIX );
370 aBuf.appendAscii( UIELEMENTTYPENAMES[ nElementType ] );
371 aBuf.appendAscii( "/" );
372 OUString aResURLPrefix( aBuf.makeStringAndClear() );
374 UIElementDataHashMap& rHashMap = rElementTypeData.aElementsHashMap;
375 Sequence< OUString > aUIElementNames = xElementTypeStorage->getElementNames();
376 for ( sal_Int32 n = 0; n < aUIElementNames.getLength(); n++ )
378 UIElementData aUIElementData;
380 // Resource name must be without ".xml"
381 sal_Int32 nIndex = aUIElementNames[n].lastIndexOf( '.' );
382 if (( nIndex > 0 ) && ( nIndex < aUIElementNames[n].getLength() ))
384 OUString aExtension( aUIElementNames[n].copy( nIndex+1 ));
385 OUString aUIElementName( aUIElementNames[n].copy( 0, nIndex ));
387 if (!aUIElementName.isEmpty() &&
388 ( aExtension.equalsIgnoreAsciiCase("xml")))
390 aUIElementData.aResourceURL = aResURLPrefix + aUIElementName;
391 aUIElementData.aName = aUIElementNames[n];
393 if ( eLayer == LAYER_USERDEFINED )
395 aUIElementData.bModified = false;
396 aUIElementData.bDefault = false;
397 aUIElementData.bDefaultNode = false;
400 // Create std::unordered_map entries for all user interface elements inside the storage. We don't load the
401 // settings to speed up the process.
402 rHashMap.insert( UIElementDataHashMap::value_type( aUIElementData.aResourceURL, aUIElementData ));
405 rElementTypeData.bLoaded = true;
412 void ModuleUIConfigurationManager::impl_requestUIElementData( sal_Int16 nElementType, Layer eLayer, UIElementData& aUIElementData )
414 UIElementType& rElementTypeData = m_aUIElements[eLayer][nElementType];
416 Reference< XStorage > xElementTypeStorage = rElementTypeData.xStorage;
417 if ( xElementTypeStorage.is() && !aUIElementData.aName.isEmpty() )
421 Reference< XStream > xStream = xElementTypeStorage->openStreamElement( aUIElementData.aName, ElementModes::READ );
422 Reference< XInputStream > xInputStream = xStream->getInputStream();
424 if ( xInputStream.is() )
426 switch ( nElementType )
428 case ::com::sun::star::ui::UIElementType::UNKNOWN:
429 break;
431 case ::com::sun::star::ui::UIElementType::MENUBAR:
435 MenuConfiguration aMenuCfg( m_xContext );
436 Reference< XIndexAccess > xContainer( aMenuCfg.CreateMenuBarConfigurationFromXML( xInputStream ));
437 RootItemContainer* pRootItemContainer = RootItemContainer::GetImplementation( xContainer );
438 if ( pRootItemContainer )
439 aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( pRootItemContainer, true ) ), UNO_QUERY );
440 else
441 aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( xContainer, true ) ), UNO_QUERY );
442 return;
444 catch ( const ::com::sun::star::lang::WrappedTargetException& )
448 break;
450 case ::com::sun::star::ui::UIElementType::POPUPMENU:
452 break;
455 case ::com::sun::star::ui::UIElementType::TOOLBAR:
459 Reference< XIndexContainer > xIndexContainer( static_cast< OWeakObject * >( new RootItemContainer() ), UNO_QUERY );
460 ToolBoxConfiguration::LoadToolBox( m_xContext, xInputStream, xIndexContainer );
461 RootItemContainer* pRootItemContainer = RootItemContainer::GetImplementation( xIndexContainer );
462 aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( pRootItemContainer, true ) ), UNO_QUERY );
463 return;
465 catch ( const ::com::sun::star::lang::WrappedTargetException& )
469 break;
472 case ::com::sun::star::ui::UIElementType::STATUSBAR:
476 Reference< XIndexContainer > xIndexContainer( static_cast< OWeakObject * >( new RootItemContainer() ), UNO_QUERY );
477 StatusBarConfiguration::LoadStatusBar( m_xContext, xInputStream, xIndexContainer );
478 RootItemContainer* pRootItemContainer = RootItemContainer::GetImplementation( xIndexContainer );
479 aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( pRootItemContainer, true ) ), UNO_QUERY );
480 return;
482 catch ( const ::com::sun::star::lang::WrappedTargetException& )
486 break;
489 case ::com::sun::star::ui::UIElementType::FLOATINGWINDOW:
491 break;
496 catch ( const ::com::sun::star::embed::InvalidStorageException& )
499 catch ( const ::com::sun::star::lang::IllegalArgumentException& )
502 catch ( const ::com::sun::star::io::IOException& )
505 catch ( const ::com::sun::star::embed::StorageWrappedTargetException& )
510 // At least we provide an empty settings container!
511 aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer() ), UNO_QUERY );
514 ModuleUIConfigurationManager::UIElementData* ModuleUIConfigurationManager::impl_findUIElementData( const OUString& aResourceURL, sal_Int16 nElementType, bool bLoad )
516 // preload list of element types on demand
517 impl_preloadUIElementTypeList( LAYER_USERDEFINED, nElementType );
518 impl_preloadUIElementTypeList( LAYER_DEFAULT, nElementType );
520 // first try to look into our user-defined vector/unordered_map combination
521 UIElementDataHashMap& rUserHashMap = m_aUIElements[LAYER_USERDEFINED][nElementType].aElementsHashMap;
522 UIElementDataHashMap::iterator pIter = rUserHashMap.find( aResourceURL );
523 if ( pIter != rUserHashMap.end() )
525 // Default data settings data must be retrieved from the default layer!
526 if ( !pIter->second.bDefault )
528 if ( !pIter->second.xSettings.is() && bLoad )
529 impl_requestUIElementData( nElementType, LAYER_USERDEFINED, pIter->second );
530 return &(pIter->second);
534 // Not successful, we have to look into our default vector/unordered_map combination
535 UIElementDataHashMap& rDefaultHashMap = m_aUIElements[LAYER_DEFAULT][nElementType].aElementsHashMap;
536 pIter = rDefaultHashMap.find( aResourceURL );
537 if ( pIter != rDefaultHashMap.end() )
539 if ( !pIter->second.xSettings.is() && bLoad )
540 impl_requestUIElementData( nElementType, LAYER_DEFAULT, pIter->second );
541 return &(pIter->second);
544 // Nothing has been found!
545 return NULL;
548 void ModuleUIConfigurationManager::impl_storeElementTypeData( Reference< XStorage > xStorage, UIElementType& rElementType, bool bResetModifyState )
550 UIElementDataHashMap& rHashMap = rElementType.aElementsHashMap;
551 UIElementDataHashMap::iterator pIter = rHashMap.begin();
553 while ( pIter != rHashMap.end() )
555 UIElementData& rElement = pIter->second;
556 if ( rElement.bModified )
558 if ( rElement.bDefault )
560 xStorage->removeElement( rElement.aName );
561 rElement.bModified = false; // mark as not modified
563 else
565 Reference< XStream > xStream( xStorage->openStreamElement( rElement.aName, ElementModes::WRITE|ElementModes::TRUNCATE ), UNO_QUERY );
566 Reference< XOutputStream > xOutputStream( xStream->getOutputStream() );
568 if ( xOutputStream.is() )
570 switch( rElementType.nElementType )
572 case ::com::sun::star::ui::UIElementType::MENUBAR:
576 MenuConfiguration aMenuCfg( m_xContext );
577 aMenuCfg.StoreMenuBarConfigurationToXML( rElement.xSettings, xOutputStream );
579 catch ( const ::com::sun::star::lang::WrappedTargetException& )
583 break;
585 case ::com::sun::star::ui::UIElementType::TOOLBAR:
589 ToolBoxConfiguration::StoreToolBox( m_xContext, xOutputStream, rElement.xSettings );
591 catch ( const ::com::sun::star::lang::WrappedTargetException& )
595 break;
597 case ::com::sun::star::ui::UIElementType::STATUSBAR:
601 StatusBarConfiguration::StoreStatusBar( m_xContext, xOutputStream, rElement.xSettings );
603 catch ( const ::com::sun::star::lang::WrappedTargetException& )
607 break;
609 default:
610 break;
614 // mark as not modified if we store to our own storage
615 if ( bResetModifyState )
616 rElement.bModified = false;
620 ++pIter;
623 // commit element type storage
624 Reference< XTransactedObject > xTransactedObject( xStorage, UNO_QUERY );
625 if ( xTransactedObject.is() )
626 xTransactedObject->commit();
628 // mark UIElementType as not modified if we store to our own storage
629 if ( bResetModifyState )
630 rElementType.bModified = false;
633 // This is only allowed to be called on the LAYER_USER_DEFINED!
634 void ModuleUIConfigurationManager::impl_resetElementTypeData(
635 UIElementType& rUserElementType,
636 UIElementType& rDefaultElementType,
637 ConfigEventNotifyContainer& rRemoveNotifyContainer,
638 ConfigEventNotifyContainer& rReplaceNotifyContainer )
640 UIElementDataHashMap& rHashMap = rUserElementType.aElementsHashMap;
641 UIElementDataHashMap::iterator pIter = rHashMap.begin();
643 Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
644 Reference< XInterface > xIfac( xThis, UNO_QUERY );
645 Reference< XNameAccess > xDefaultNameAccess( rDefaultElementType.xStorage, UNO_QUERY );
646 sal_Int16 nType = rUserElementType.nElementType;
648 // Make copies of the event structures to be thread-safe. We have to unlock our mutex before calling
649 // our listeners!
650 while ( pIter != rHashMap.end() )
652 UIElementData& rElement = pIter->second;
653 if ( !rElement.bDefault )
655 if ( xDefaultNameAccess->hasByName( rElement.aName ))
657 // Replace settings with data from default layer
658 Reference< XIndexAccess > xOldSettings( rElement.xSettings );
659 impl_requestUIElementData( nType, LAYER_DEFAULT, rElement );
661 ui::ConfigurationEvent aReplaceEvent;
662 aReplaceEvent.ResourceURL = rElement.aResourceURL;
663 aReplaceEvent.Accessor <<= xThis;
664 aReplaceEvent.Source = xIfac;
665 aReplaceEvent.ReplacedElement <<= xOldSettings;
666 aReplaceEvent.Element <<= rElement.xSettings;
668 rReplaceNotifyContainer.push_back( aReplaceEvent );
670 // Mark element as default and not modified. That means "not active"
671 // in the user layer anymore.
672 rElement.bModified = false;
673 rElement.bDefault = true;
675 else
677 // Remove user-defined settings from user layer
678 ui::ConfigurationEvent aEvent;
679 aEvent.ResourceURL = rElement.aResourceURL;
680 aEvent.Accessor <<= xThis;
681 aEvent.Source = xIfac;
682 aEvent.Element <<= rElement.xSettings;
684 rRemoveNotifyContainer.push_back( aEvent );
686 // Mark element as default and not modified. That means "not active"
687 // in the user layer anymore.
688 rElement.bModified = false;
689 rElement.bDefault = true;
693 ++pIter;
696 // Remove all settings from our user interface elements
697 rHashMap.clear();
700 void ModuleUIConfigurationManager::impl_reloadElementTypeData(
701 UIElementType& rUserElementType,
702 UIElementType& rDefaultElementType,
703 ConfigEventNotifyContainer& rRemoveNotifyContainer,
704 ConfigEventNotifyContainer& rReplaceNotifyContainer )
706 UIElementDataHashMap& rHashMap = rUserElementType.aElementsHashMap;
707 UIElementDataHashMap::iterator pIter = rHashMap.begin();
708 Reference< XStorage > xUserStorage( rUserElementType.xStorage );
709 Reference< XStorage > xDefaultStorage( rDefaultElementType.xStorage );
710 Reference< XNameAccess > xUserNameAccess( rUserElementType.xStorage, UNO_QUERY );
711 Reference< XNameAccess > xDefaultNameAccess( rDefaultElementType.xStorage, UNO_QUERY );
713 Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
714 Reference< XInterface > xIfac( xThis, UNO_QUERY );
715 sal_Int16 nType = rUserElementType.nElementType;
717 while ( pIter != rHashMap.end() )
719 UIElementData& rElement = pIter->second;
720 if ( rElement.bModified )
722 if ( xUserNameAccess->hasByName( rElement.aName ))
724 // Replace settings with data from user layer
725 Reference< XIndexAccess > xOldSettings( rElement.xSettings );
727 impl_requestUIElementData( nType, LAYER_USERDEFINED, rElement );
729 ui::ConfigurationEvent aReplaceEvent;
731 aReplaceEvent.ResourceURL = rElement.aResourceURL;
732 aReplaceEvent.Accessor <<= xThis;
733 aReplaceEvent.Source = xIfac;
734 aReplaceEvent.ReplacedElement <<= xOldSettings;
735 aReplaceEvent.Element <<= rElement.xSettings;
736 rReplaceNotifyContainer.push_back( aReplaceEvent );
738 rElement.bModified = false;
740 else if ( xDefaultNameAccess->hasByName( rElement.aName ))
742 // Replace settings with data from default layer
743 Reference< XIndexAccess > xOldSettings( rElement.xSettings );
745 impl_requestUIElementData( nType, LAYER_DEFAULT, rElement );
747 ui::ConfigurationEvent aReplaceEvent;
749 aReplaceEvent.ResourceURL = rElement.aResourceURL;
750 aReplaceEvent.Accessor <<= xThis;
751 aReplaceEvent.Source = xIfac;
752 aReplaceEvent.ReplacedElement <<= xOldSettings;
753 aReplaceEvent.Element <<= rElement.xSettings;
754 rReplaceNotifyContainer.push_back( aReplaceEvent );
756 // Mark element as default and not modified. That means "not active"
757 // in the user layer anymore.
758 rElement.bModified = false;
759 rElement.bDefault = true;
761 else
763 // Element settings are not in any storage => remove
764 ui::ConfigurationEvent aRemoveEvent;
766 aRemoveEvent.ResourceURL = rElement.aResourceURL;
767 aRemoveEvent.Accessor <<= xThis;
768 aRemoveEvent.Source = xIfac;
769 aRemoveEvent.Element <<= rElement.xSettings;
771 rRemoveNotifyContainer.push_back( aRemoveEvent );
773 // Mark element as default and not modified. That means "not active"
774 // in the user layer anymore.
775 rElement.bModified = false;
776 rElement.bDefault = true;
779 ++pIter;
782 rUserElementType.bModified = false;
785 void ModuleUIConfigurationManager::impl_Initialize()
787 // Initialize the top-level structures with the storage data
788 if ( m_xUserConfigStorage.is() )
790 // Try to access our module sub folder
791 for ( sal_Int16 i = 1; i < ::com::sun::star::ui::UIElementType::COUNT;
792 i++ )
794 Reference< XStorage > xElementTypeStorage;
797 if ( m_pStorageHandler[i] )
798 xElementTypeStorage = m_pStorageHandler[i]->getWorkingStorageUser();
800 catch ( const com::sun::star::container::NoSuchElementException& )
803 catch ( const ::com::sun::star::embed::InvalidStorageException& )
806 catch ( const ::com::sun::star::lang::IllegalArgumentException& )
809 catch ( const ::com::sun::star::io::IOException& )
812 catch ( const ::com::sun::star::embed::StorageWrappedTargetException& )
816 m_aUIElements[LAYER_USERDEFINED][i].nElementType = i;
817 m_aUIElements[LAYER_USERDEFINED][i].bModified = false;
818 m_aUIElements[LAYER_USERDEFINED][i].xStorage = xElementTypeStorage;
819 m_aUIElements[LAYER_USERDEFINED][i].bDefaultLayer = false;
823 if ( m_xDefaultConfigStorage.is() )
825 Reference< XNameAccess > xNameAccess( m_xDefaultConfigStorage, UNO_QUERY_THROW );
827 // Try to access our module sub folder
828 for ( sal_Int16 i = 1; i < ::com::sun::star::ui::UIElementType::COUNT;
829 i++ )
831 Reference< XStorage > xElementTypeStorage;
834 const OUString sName( OUString::createFromAscii( UIELEMENTTYPENAMES[i] ) );
835 if( xNameAccess->hasByName( sName ) )
836 xNameAccess->getByName( sName ) >>= xElementTypeStorage;
838 catch ( const com::sun::star::container::NoSuchElementException& )
842 m_aUIElements[LAYER_DEFAULT][i].nElementType = i;
843 m_aUIElements[LAYER_DEFAULT][i].bModified = false;
844 m_aUIElements[LAYER_DEFAULT][i].xStorage = xElementTypeStorage;
845 m_aUIElements[LAYER_DEFAULT][i].bDefaultLayer = true;
850 ModuleUIConfigurationManager::ModuleUIConfigurationManager(
851 const Reference< XComponentContext >& xContext,
852 const css::uno::Sequence< css::uno::Any >& aArguments)
853 : m_xDefaultConfigStorage( 0 )
854 , m_xUserConfigStorage( 0 )
855 , m_bReadOnly( true )
856 , m_bModified( false )
857 , m_bConfigRead( false )
858 , m_bDisposed( false )
859 , m_aXMLPostfix( ".xml" )
860 , m_aPropUIName( "UIName" )
861 , m_aPropResourceURL( "ResourceURL" )
862 , m_xContext( xContext )
863 , m_aListenerContainer( m_mutex )
865 for ( int i = 0; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
866 m_pStorageHandler[i] = 0;
868 // Make sure we have a default initialized entry for every layer and user interface element type!
869 // The following code depends on this!
870 m_aUIElements[LAYER_DEFAULT].resize( ::com::sun::star::ui::UIElementType::COUNT );
871 m_aUIElements[LAYER_USERDEFINED].resize( ::com::sun::star::ui::UIElementType::COUNT );
873 SolarMutexGuard g;
875 if( aArguments.getLength() == 2 && (aArguments[0] >>= m_aModuleShortName) && (aArguments[1] >>= m_aModuleIdentifier))
878 else
880 ::comphelper::SequenceAsHashMap lArgs(aArguments);
881 m_aModuleShortName = lArgs.getUnpackedValueOrDefault("ModuleShortName", OUString());
882 m_aModuleIdentifier = lArgs.getUnpackedValueOrDefault("ModuleIdentifier", OUString());
885 for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
887 OUString aResourceType;
888 if ( i == ::com::sun::star::ui::UIElementType::MENUBAR )
889 aResourceType = RESOURCETYPE_MENUBAR;
890 else if ( i == ::com::sun::star::ui::UIElementType::TOOLBAR )
891 aResourceType = RESOURCETYPE_TOOLBAR;
892 else if ( i == ::com::sun::star::ui::UIElementType::STATUSBAR )
893 aResourceType = RESOURCETYPE_STATUSBAR;
895 if ( !aResourceType.isEmpty() )
897 m_pStorageHandler[i] = new PresetHandler( m_xContext );
898 m_pStorageHandler[i]->connectToResource( PresetHandler::E_MODULES,
899 aResourceType, // this path wont be used later ... seee next lines!
900 m_aModuleShortName,
901 css::uno::Reference< css::embed::XStorage >()); // no document root used here!
905 // initialize root storages for all resource types
906 m_xUserRootCommit = css::uno::Reference< css::embed::XTransactedObject >(
907 m_pStorageHandler[::com::sun::star::ui::UIElementType::MENUBAR]->getOrCreateRootStorageUser(), css::uno::UNO_QUERY); // can be empty
908 m_xDefaultConfigStorage = m_pStorageHandler[::com::sun::star::ui::UIElementType::MENUBAR]->getParentStorageShare(
909 m_pStorageHandler[::com::sun::star::ui::UIElementType::MENUBAR]->getWorkingStorageShare());
910 m_xUserConfigStorage = m_pStorageHandler[::com::sun::star::ui::UIElementType::MENUBAR]->getParentStorageUser(
911 m_pStorageHandler[::com::sun::star::ui::UIElementType::MENUBAR]->getWorkingStorageUser());
913 if ( m_xUserConfigStorage.is() )
915 Reference< XPropertySet > xPropSet( m_xUserConfigStorage, UNO_QUERY );
916 if ( xPropSet.is() )
918 long nOpenMode = 0;
919 Any a = xPropSet->getPropertyValue("OpenMode");
920 if ( a >>= nOpenMode )
921 m_bReadOnly = !( nOpenMode & ElementModes::WRITE );
925 impl_Initialize();
928 ModuleUIConfigurationManager::~ModuleUIConfigurationManager()
930 for ( int i = 0; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
931 delete m_pStorageHandler[i];
934 // XComponent
935 void SAL_CALL ModuleUIConfigurationManager::dispose() throw (::com::sun::star::uno::RuntimeException, std::exception)
937 Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
939 css::lang::EventObject aEvent( xThis );
940 m_aListenerContainer.disposeAndClear( aEvent );
942 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
943 SolarMutexClearableGuard aGuard;
944 Reference< XComponent > xModuleImageManager( m_xModuleImageManager );
945 m_xModuleImageManager.clear();
946 Reference< XComponent > xCompMAM( m_xModuleAcceleratorManager, UNO_QUERY );
947 if ( xCompMAM.is() )
948 xCompMAM->dispose();
949 m_xModuleAcceleratorManager.clear();
950 m_aUIElements[LAYER_USERDEFINED].clear();
951 m_aUIElements[LAYER_DEFAULT].clear();
952 m_xDefaultConfigStorage.clear();
953 m_xUserConfigStorage.clear();
954 m_xUserRootCommit.clear();
955 m_bConfigRead = false;
956 m_bModified = false;
957 m_bDisposed = true;
958 aGuard.clear();
959 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
963 if ( xModuleImageManager.is() )
964 xModuleImageManager->dispose();
966 catch ( const Exception& )
971 void SAL_CALL ModuleUIConfigurationManager::addEventListener( const Reference< XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException, std::exception)
974 SolarMutexGuard g;
976 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
977 if ( m_bDisposed )
978 throw DisposedException();
981 m_aListenerContainer.addInterface( cppu::UnoType<XEventListener>::get(), xListener );
984 void SAL_CALL ModuleUIConfigurationManager::removeEventListener( const Reference< XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException, std::exception)
986 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
987 m_aListenerContainer.removeInterface( cppu::UnoType<XEventListener>::get(), xListener );
990 // XUIConfiguration
991 void SAL_CALL ModuleUIConfigurationManager::addConfigurationListener( const Reference< ::com::sun::star::ui::XUIConfigurationListener >& xListener ) throw (::com::sun::star::uno::RuntimeException, std::exception)
994 SolarMutexGuard g;
996 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
997 if ( m_bDisposed )
998 throw DisposedException();
1001 m_aListenerContainer.addInterface( cppu::UnoType<ui::XUIConfigurationListener>::get(), xListener );
1004 void SAL_CALL ModuleUIConfigurationManager::removeConfigurationListener( const Reference< ::com::sun::star::ui::XUIConfigurationListener >& xListener ) throw (::com::sun::star::uno::RuntimeException, std::exception)
1006 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1007 m_aListenerContainer.removeInterface( cppu::UnoType<ui::XUIConfigurationListener>::get(), xListener );
1010 // XUIConfigurationManager
1011 void SAL_CALL ModuleUIConfigurationManager::reset() throw (::com::sun::star::uno::RuntimeException, std::exception)
1013 SolarMutexClearableGuard aGuard;
1015 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1016 if ( m_bDisposed )
1017 throw DisposedException();
1019 if ( !isReadOnly() )
1021 // Remove all elements from our user-defined storage!
1024 for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
1026 UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][i];
1027 Reference< XStorage > xSubStorage( rElementType.xStorage, UNO_QUERY );
1029 if ( xSubStorage.is() )
1031 bool bCommitSubStorage( false );
1032 Sequence< OUString > aUIElementStreamNames = xSubStorage->getElementNames();
1033 for ( sal_Int32 j = 0; j < aUIElementStreamNames.getLength(); j++ )
1035 xSubStorage->removeElement( aUIElementStreamNames[j] );
1036 bCommitSubStorage = true;
1039 if ( bCommitSubStorage )
1041 Reference< XTransactedObject > xTransactedObject( xSubStorage, UNO_QUERY );
1042 if ( xTransactedObject.is() )
1043 xTransactedObject->commit();
1044 m_pStorageHandler[i]->commitUserChanges();
1049 // remove settings from user defined layer and notify listener about removed settings data!
1050 ConfigEventNotifyContainer aRemoveEventNotifyContainer;
1051 ConfigEventNotifyContainer aReplaceEventNotifyContainer;
1052 for ( sal_Int16 j = 1; j < ::com::sun::star::ui::UIElementType::COUNT; j++ )
1056 UIElementType& rUserElementType = m_aUIElements[LAYER_USERDEFINED][j];
1057 UIElementType& rDefaultElementType = m_aUIElements[LAYER_DEFAULT][j];
1059 impl_resetElementTypeData( rUserElementType, rDefaultElementType, aRemoveEventNotifyContainer, aReplaceEventNotifyContainer );
1060 rUserElementType.bModified = false;
1062 catch (const Exception& e)
1064 css::uno::Any a(e);
1065 throw css::lang::WrappedTargetRuntimeException(
1066 OUString("ModuleUIConfigurationManager::reset exception"),
1067 css::uno::Reference<css::uno::XInterface>(*this), a);
1071 m_bModified = false;
1073 // Unlock mutex before notify our listeners
1074 aGuard.clear();
1076 // Notify our listeners
1077 sal_uInt32 k = 0;
1078 for ( k = 0; k < aRemoveEventNotifyContainer.size(); k++ )
1079 implts_notifyContainerListener( aRemoveEventNotifyContainer[k], NotifyOp_Remove );
1080 for ( k = 0; k < aReplaceEventNotifyContainer.size(); k++ )
1081 implts_notifyContainerListener( aReplaceEventNotifyContainer[k], NotifyOp_Replace );
1083 catch ( const ::com::sun::star::lang::IllegalArgumentException& )
1086 catch ( const ::com::sun::star::container::NoSuchElementException& )
1089 catch ( const ::com::sun::star::embed::InvalidStorageException& )
1092 catch ( const ::com::sun::star::embed::StorageWrappedTargetException& )
1098 Sequence< Sequence< PropertyValue > > SAL_CALL ModuleUIConfigurationManager::getUIElementsInfo( sal_Int16 ElementType )
1099 throw ( IllegalArgumentException, RuntimeException, std::exception )
1101 if (( ElementType < 0 ) || ( ElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
1102 throw IllegalArgumentException();
1104 SolarMutexGuard g;
1105 if ( m_bDisposed )
1106 throw DisposedException();
1108 Sequence< Sequence< PropertyValue > > aElementInfoSeq;
1109 UIElementInfoHashMap aUIElementInfoCollection;
1111 if ( ElementType == ::com::sun::star::ui::UIElementType::UNKNOWN )
1113 for ( sal_Int16 i = 0; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
1114 impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection, sal_Int16( i ) );
1116 else
1117 impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection, ElementType );
1119 Sequence< PropertyValue > aUIElementInfo( 2 );
1120 aUIElementInfo[0].Name = m_aPropResourceURL;
1121 aUIElementInfo[1].Name = m_aPropUIName;
1123 aElementInfoSeq.realloc( aUIElementInfoCollection.size() );
1124 UIElementInfoHashMap::const_iterator pIter = aUIElementInfoCollection.begin();
1126 sal_Int32 n = 0;
1127 while ( pIter != aUIElementInfoCollection.end() )
1129 aUIElementInfo[0].Value <<= pIter->second.aResourceURL;
1130 aUIElementInfo[1].Value <<= pIter->second.aUIName;
1131 aElementInfoSeq[n++] = aUIElementInfo;
1132 ++pIter;
1135 return aElementInfoSeq;
1138 Reference< XIndexContainer > SAL_CALL ModuleUIConfigurationManager::createSettings() throw (::com::sun::star::uno::RuntimeException, std::exception)
1140 SolarMutexGuard g;
1142 if ( m_bDisposed )
1143 throw DisposedException();
1145 // Creates an empty item container which can be filled from outside
1146 return Reference< XIndexContainer >( static_cast< OWeakObject * >( new RootItemContainer() ), UNO_QUERY );
1149 sal_Bool SAL_CALL ModuleUIConfigurationManager::hasSettings( const OUString& ResourceURL )
1150 throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception)
1152 sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
1154 if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
1155 ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
1156 throw IllegalArgumentException();
1157 else
1159 SolarMutexGuard g;
1161 if ( m_bDisposed )
1162 throw DisposedException();
1164 UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType, false );
1165 if ( pDataSettings )
1166 return sal_True;
1169 return sal_False;
1172 Reference< XIndexAccess > SAL_CALL ModuleUIConfigurationManager::getSettings( const OUString& ResourceURL, sal_Bool bWriteable )
1173 throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception)
1175 sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
1177 if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
1178 ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
1179 throw IllegalArgumentException();
1180 else
1182 SolarMutexGuard g;
1184 if ( m_bDisposed )
1185 throw DisposedException();
1187 UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType );
1188 if ( pDataSettings )
1190 // Create a copy of our data if someone wants to change the data.
1191 if ( bWriteable )
1192 return Reference< XIndexAccess >( static_cast< OWeakObject * >( new RootItemContainer( pDataSettings->xSettings ) ), UNO_QUERY );
1193 else
1194 return pDataSettings->xSettings;
1198 throw NoSuchElementException();
1201 void SAL_CALL ModuleUIConfigurationManager::replaceSettings( const OUString& ResourceURL, const Reference< ::com::sun::star::container::XIndexAccess >& aNewData )
1202 throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException, std::exception)
1204 sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
1206 if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
1207 ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
1208 throw IllegalArgumentException();
1209 else if ( m_bReadOnly )
1210 throw IllegalAccessException();
1211 else
1213 SolarMutexClearableGuard aGuard;
1215 if ( m_bDisposed )
1216 throw DisposedException();
1218 UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType );
1219 if ( pDataSettings )
1221 if ( !pDataSettings->bDefaultNode )
1223 // we have a settings entry in our user-defined layer - replace
1224 Reference< XIndexAccess > xOldSettings = pDataSettings->xSettings;
1226 // Create a copy of the data if the container is not const
1227 Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY );
1228 if ( xReplace.is() )
1229 pDataSettings->xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( aNewData ) ), UNO_QUERY );
1230 else
1231 pDataSettings->xSettings = aNewData;
1232 pDataSettings->bDefault = false;
1233 pDataSettings->bModified = true;
1234 m_bModified = true;
1236 // Modify type container
1237 UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType];
1238 rElementType.bModified = true;
1240 Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
1241 Reference< XInterface > xIfac( xThis, UNO_QUERY );
1243 // Create event to notify listener about replaced element settings
1244 ui::ConfigurationEvent aEvent;
1245 aEvent.ResourceURL = ResourceURL;
1246 aEvent.Accessor <<= xThis;
1247 aEvent.Source = xIfac;
1248 aEvent.ReplacedElement <<= xOldSettings;
1249 aEvent.Element <<= pDataSettings->xSettings;
1251 aGuard.clear();
1253 implts_notifyContainerListener( aEvent, NotifyOp_Replace );
1255 else
1257 // we have no settings in our user-defined layer - insert
1258 UIElementData aUIElementData;
1260 aUIElementData.bDefault = false;
1261 aUIElementData.bDefaultNode = false;
1262 aUIElementData.bModified = true;
1264 // Create a copy of the data if the container is not const
1265 Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY );
1266 if ( xReplace.is() )
1267 aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( aNewData ) ), UNO_QUERY );
1268 else
1269 aUIElementData.xSettings = aNewData;
1270 aUIElementData.aName = RetrieveNameFromResourceURL( ResourceURL ) + m_aXMLPostfix;
1271 aUIElementData.aResourceURL = ResourceURL;
1272 m_bModified = true;
1274 // Modify type container
1275 UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType];
1276 rElementType.bModified = true;
1278 UIElementDataHashMap& rElements = rElementType.aElementsHashMap;
1280 // Check our user element settings hash map as it can already contain settings that have been set to default!
1281 // If no node can be found, we have to insert it.
1282 UIElementDataHashMap::iterator pIter = rElements.find( ResourceURL );
1283 if ( pIter != rElements.end() )
1284 pIter->second = aUIElementData;
1285 else
1286 rElements.insert( UIElementDataHashMap::value_type( ResourceURL, aUIElementData ));
1288 Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
1289 Reference< XInterface > xIfac( xThis, UNO_QUERY );
1291 // Create event to notify listener about replaced element settings
1292 ui::ConfigurationEvent aEvent;
1294 aEvent.ResourceURL = ResourceURL;
1295 aEvent.Accessor <<= xThis;
1296 aEvent.Source = xIfac;
1297 aEvent.ReplacedElement <<= pDataSettings->xSettings;
1298 aEvent.Element <<= aUIElementData.xSettings;
1300 aGuard.clear();
1302 implts_notifyContainerListener( aEvent, NotifyOp_Replace );
1305 else
1306 throw NoSuchElementException();
1310 void SAL_CALL ModuleUIConfigurationManager::removeSettings( const OUString& ResourceURL )
1311 throw ( NoSuchElementException, IllegalArgumentException, IllegalAccessException, RuntimeException, std::exception)
1313 sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
1315 if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
1316 ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
1317 throw IllegalArgumentException();
1318 else if ( m_bReadOnly )
1319 throw IllegalAccessException();
1320 else
1322 SolarMutexClearableGuard aGuard;
1324 if ( m_bDisposed )
1325 throw DisposedException();
1327 UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType );
1328 if ( pDataSettings )
1330 // If element settings are default, we don't need to change anything!
1331 if ( pDataSettings->bDefault )
1332 return;
1333 else
1335 Reference< XIndexAccess > xRemovedSettings = pDataSettings->xSettings;
1336 pDataSettings->bDefault = true;
1338 // check if this is a default layer node
1339 if ( !pDataSettings->bDefaultNode )
1340 pDataSettings->bModified = true; // we have to remove this node from the user layer!
1341 pDataSettings->xSettings.clear();
1342 m_bModified = true; // user layer must be written
1344 // Modify type container
1345 UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType];
1346 rElementType.bModified = true;
1348 Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
1349 Reference< XInterface > xIfac( xThis, UNO_QUERY );
1351 // Check if we have settings in the default layer which replaces the user-defined one!
1352 UIElementData* pDefaultDataSettings = impl_findUIElementData( ResourceURL, nElementType );
1353 if ( pDefaultDataSettings )
1355 // Create event to notify listener about replaced element settings
1356 ui::ConfigurationEvent aEvent;
1358 aEvent.ResourceURL = ResourceURL;
1359 aEvent.Accessor <<= xThis;
1360 aEvent.Source = xIfac;
1361 aEvent.Element <<= xRemovedSettings;
1362 aEvent.ReplacedElement <<= pDefaultDataSettings->xSettings;
1364 aGuard.clear();
1366 implts_notifyContainerListener( aEvent, NotifyOp_Replace );
1368 else
1370 // Create event to notify listener about removed element settings
1371 ui::ConfigurationEvent aEvent;
1373 aEvent.ResourceURL = ResourceURL;
1374 aEvent.Accessor <<= xThis;
1375 aEvent.Source = xIfac;
1376 aEvent.Element <<= xRemovedSettings;
1378 aGuard.clear();
1380 implts_notifyContainerListener( aEvent, NotifyOp_Remove );
1384 else
1385 throw NoSuchElementException();
1389 void SAL_CALL ModuleUIConfigurationManager::insertSettings( const OUString& NewResourceURL, const Reference< XIndexAccess >& aNewData )
1390 throw ( ElementExistException, IllegalArgumentException, IllegalAccessException, RuntimeException, std::exception )
1392 sal_Int16 nElementType = RetrieveTypeFromResourceURL( NewResourceURL );
1394 if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
1395 ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
1396 throw IllegalArgumentException();
1397 else if ( m_bReadOnly )
1398 throw IllegalAccessException();
1399 else
1401 SolarMutexClearableGuard aGuard;
1403 if ( m_bDisposed )
1404 throw DisposedException();
1406 UIElementData* pDataSettings = impl_findUIElementData( NewResourceURL, nElementType );
1407 if ( !pDataSettings )
1409 UIElementData aUIElementData;
1411 aUIElementData.bDefault = false;
1412 aUIElementData.bDefaultNode = false;
1413 aUIElementData.bModified = true;
1415 // Create a copy of the data if the container is not const
1416 Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY );
1417 if ( xReplace.is() )
1418 aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( aNewData ) ), UNO_QUERY );
1419 else
1420 aUIElementData.xSettings = aNewData;
1421 aUIElementData.aName = RetrieveNameFromResourceURL( NewResourceURL ) + m_aXMLPostfix;
1422 aUIElementData.aResourceURL = NewResourceURL;
1423 m_bModified = true;
1425 UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType];
1426 rElementType.bModified = true;
1428 UIElementDataHashMap& rElements = rElementType.aElementsHashMap;
1429 rElements.insert( UIElementDataHashMap::value_type( NewResourceURL, aUIElementData ));
1431 Reference< XIndexAccess > xInsertSettings( aUIElementData.xSettings );
1432 Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
1434 // Create event to notify listener about removed element settings
1435 ui::ConfigurationEvent aEvent;
1437 aEvent.ResourceURL = NewResourceURL;
1438 aEvent.Accessor <<= xThis;
1439 aEvent.Source = xThis;
1440 aEvent.Element <<= xInsertSettings;
1442 aGuard.clear();
1444 implts_notifyContainerListener( aEvent, NotifyOp_Insert );
1446 else
1447 throw ElementExistException();
1451 Reference< XInterface > SAL_CALL ModuleUIConfigurationManager::getImageManager() throw (::com::sun::star::uno::RuntimeException, std::exception)
1453 SolarMutexGuard g;
1455 if ( m_bDisposed )
1456 throw DisposedException();
1458 if ( !m_xModuleImageManager.is() )
1460 m_xModuleImageManager = Reference< XComponent >( static_cast< cppu::OWeakObject *>( new ModuleImageManager( m_xContext )),
1461 UNO_QUERY );
1462 Reference< XInitialization > xInit( m_xModuleImageManager, UNO_QUERY );
1464 Sequence< Any > aPropSeq( 3 );
1465 PropertyValue aPropValue;
1466 aPropValue.Name = "UserConfigStorage";
1467 aPropValue.Value = makeAny( m_xUserConfigStorage );
1468 aPropSeq[0] = makeAny( aPropValue );
1469 aPropValue.Name = "ModuleIdentifier";
1470 aPropValue.Value = makeAny( m_aModuleIdentifier );
1471 aPropSeq[1] = makeAny( aPropValue );
1472 aPropValue.Name = "UserRootCommit";
1473 aPropValue.Value = makeAny( m_xUserRootCommit );
1474 aPropSeq[2] = makeAny( aPropValue );
1476 xInit->initialize( aPropSeq );
1479 return Reference< XInterface >( m_xModuleImageManager, UNO_QUERY );
1482 Reference< ui::XAcceleratorConfiguration > SAL_CALL ModuleUIConfigurationManager::getShortCutManager() throw (::com::sun::star::uno::RuntimeException, std::exception)
1484 SolarMutexGuard g;
1486 if ( m_bDisposed )
1487 throw DisposedException();
1489 if ( !m_xModuleAcceleratorManager.is() ) try
1491 m_xModuleAcceleratorManager = ui::ModuleAcceleratorConfiguration::
1492 createWithModuleIdentifier(m_xContext, m_aModuleIdentifier);
1494 catch ( const css::uno::DeploymentException& )
1496 SAL_WARN("fwk.uiconfiguration", "ModuleAcceleratorConfiguration"
1497 " not available. This should happen only on mobile platforms.");
1500 return m_xModuleAcceleratorManager;
1503 Reference< XInterface > SAL_CALL ModuleUIConfigurationManager::getEventsManager() throw (::com::sun::star::uno::RuntimeException, std::exception)
1505 return Reference< XInterface >();
1508 // XModuleUIConfigurationManager
1509 sal_Bool SAL_CALL ModuleUIConfigurationManager::isDefaultSettings( const OUString& ResourceURL )
1510 throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception)
1512 sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
1514 if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
1515 ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
1516 throw IllegalArgumentException();
1517 else
1519 SolarMutexGuard g;
1521 if ( m_bDisposed )
1522 throw DisposedException();
1524 UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType, false );
1525 if ( pDataSettings && pDataSettings->bDefaultNode )
1526 return sal_True;
1529 return sal_False;
1532 Reference< XIndexAccess > SAL_CALL ModuleUIConfigurationManager::getDefaultSettings( const OUString& ResourceURL )
1533 throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception)
1535 sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
1537 if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
1538 ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
1539 throw IllegalArgumentException();
1540 else
1542 SolarMutexGuard g;
1544 if ( m_bDisposed )
1545 throw DisposedException();
1547 // preload list of element types on demand
1548 impl_preloadUIElementTypeList( LAYER_DEFAULT, nElementType );
1550 // Look into our default vector/unordered_map combination
1551 UIElementDataHashMap& rDefaultHashMap = m_aUIElements[LAYER_DEFAULT][nElementType].aElementsHashMap;
1552 UIElementDataHashMap::iterator pIter = rDefaultHashMap.find( ResourceURL );
1553 if ( pIter != rDefaultHashMap.end() )
1555 if ( !pIter->second.xSettings.is() )
1556 impl_requestUIElementData( nElementType, LAYER_DEFAULT, pIter->second );
1557 return pIter->second.xSettings;
1561 // Nothing has been found!
1562 throw NoSuchElementException();
1565 // XUIConfigurationPersistence
1566 void SAL_CALL ModuleUIConfigurationManager::reload() throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
1568 SolarMutexClearableGuard aGuard;
1570 if ( m_bDisposed )
1571 throw DisposedException();
1573 if ( m_xUserConfigStorage.is() && m_bModified && !m_bReadOnly )
1575 // Try to access our module sub folder
1576 ConfigEventNotifyContainer aRemoveNotifyContainer;
1577 ConfigEventNotifyContainer aReplaceNotifyContainer;
1578 for ( sal_Int16 i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
1582 UIElementType& rUserElementType = m_aUIElements[LAYER_USERDEFINED][i];
1583 UIElementType& rDefaultElementType = m_aUIElements[LAYER_DEFAULT][i];
1585 if ( rUserElementType.bModified )
1586 impl_reloadElementTypeData( rUserElementType, rDefaultElementType, aRemoveNotifyContainer, aReplaceNotifyContainer );
1588 catch ( const Exception& )
1590 throw IOException();
1594 m_bModified = false;
1596 // Unlock mutex before notify our listeners
1597 aGuard.clear();
1599 // Notify our listeners
1600 for ( sal_uInt32 j = 0; j < aRemoveNotifyContainer.size(); j++ )
1601 implts_notifyContainerListener( aRemoveNotifyContainer[j], NotifyOp_Remove );
1602 for ( sal_uInt32 k = 0; k < aReplaceNotifyContainer.size(); k++ )
1603 implts_notifyContainerListener( aReplaceNotifyContainer[k], NotifyOp_Replace );
1607 void SAL_CALL ModuleUIConfigurationManager::store() throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
1609 SolarMutexGuard g;
1611 if ( m_bDisposed )
1612 throw DisposedException();
1614 if ( m_xUserConfigStorage.is() && m_bModified && !m_bReadOnly )
1616 // Try to access our module sub folder
1617 for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
1621 UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][i];
1622 Reference< XStorage > xStorage( rElementType.xStorage, UNO_QUERY );
1624 if ( rElementType.bModified && xStorage.is() )
1626 impl_storeElementTypeData( xStorage, rElementType );
1627 m_pStorageHandler[i]->commitUserChanges();
1630 catch ( const Exception& )
1632 throw IOException();
1636 m_bModified = false;
1640 void SAL_CALL ModuleUIConfigurationManager::storeToStorage( const Reference< XStorage >& Storage ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
1642 SolarMutexGuard g;
1644 if ( m_bDisposed )
1645 throw DisposedException();
1647 if ( m_xUserConfigStorage.is() && m_bModified && !m_bReadOnly )
1649 // Try to access our module sub folder
1650 for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
1654 Reference< XStorage > xElementTypeStorage( Storage->openStorageElement(
1655 OUString::createFromAscii( UIELEMENTTYPENAMES[i] ), ElementModes::READWRITE ));
1656 UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][i];
1658 if ( rElementType.bModified && xElementTypeStorage.is() )
1659 impl_storeElementTypeData( xElementTypeStorage, rElementType, false ); // store data to storage, but don't reset modify flag!
1661 catch ( const Exception& )
1663 throw IOException();
1667 Reference< XTransactedObject > xTransactedObject( Storage, UNO_QUERY );
1668 if ( xTransactedObject.is() )
1669 xTransactedObject->commit();
1673 sal_Bool SAL_CALL ModuleUIConfigurationManager::isModified() throw (::com::sun::star::uno::RuntimeException, std::exception)
1675 SolarMutexGuard g;
1677 return m_bModified;
1680 sal_Bool SAL_CALL ModuleUIConfigurationManager::isReadOnly() throw (::com::sun::star::uno::RuntimeException, std::exception)
1682 SolarMutexGuard g;
1684 return m_bReadOnly;
1687 void ModuleUIConfigurationManager::implts_notifyContainerListener( const ui::ConfigurationEvent& aEvent, NotifyOp eOp )
1689 ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( cppu::UnoType<com::sun::star::ui::XUIConfigurationListener>::get());
1690 if ( pContainer != NULL )
1692 ::cppu::OInterfaceIteratorHelper pIterator( *pContainer );
1693 while ( pIterator.hasMoreElements() )
1697 switch ( eOp )
1699 case NotifyOp_Replace:
1700 static_cast< ::com::sun::star::ui::XUIConfigurationListener*>(pIterator.next())->elementReplaced( aEvent );
1701 break;
1702 case NotifyOp_Insert:
1703 static_cast< ::com::sun::star::ui::XUIConfigurationListener*>(pIterator.next())->elementInserted( aEvent );
1704 break;
1705 case NotifyOp_Remove:
1706 static_cast< ::com::sun::star::ui::XUIConfigurationListener*>(pIterator.next())->elementRemoved( aEvent );
1707 break;
1710 catch( const css::uno::RuntimeException& )
1712 pIterator.remove();
1720 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
1721 com_sun_star_comp_framework_ModuleUIConfigurationManager_get_implementation(
1722 css::uno::XComponentContext *context,
1723 css::uno::Sequence<css::uno::Any> const &arguments)
1725 return cppu::acquire(new ModuleUIConfigurationManager(context, arguments));
1728 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */