fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / framework / source / uiconfiguration / uiconfigurationmanager.cxx
blob2e720def5f4599d8e82c22cefdff8c3e4db68953
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 <uiconfiguration/imagemanager.hxx>
21 #include <uielement/rootitemcontainer.hxx>
22 #include <uielement/constitemcontainer.hxx>
23 #include <uielement/uielementtypenames.hxx>
24 #include <framework/menuconfiguration.hxx>
25 #include <framework/statusbarconfiguration.hxx>
26 #include <framework/toolboxconfiguration.hxx>
28 #include <com/sun/star/beans/XPropertySet.hpp>
29 #include <com/sun/star/container/XIndexContainer.hpp>
30 #include <com/sun/star/embed/ElementModes.hpp>
31 #include <com/sun/star/embed/XTransactedObject.hpp>
32 #include <com/sun/star/lang/XInitialization.hpp>
33 #include <com/sun/star/lang/DisposedException.hpp>
34 #include <com/sun/star/io/XStream.hpp>
35 #include <com/sun/star/ui/UIElementType.hpp>
36 #include <com/sun/star/ui/ConfigurationEvent.hpp>
37 #include <com/sun/star/ui/DocumentAcceleratorConfiguration.hpp>
38 #include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
39 #include <com/sun/star/ui/XUIConfigurationManager2.hpp>
40 #include <com/sun/star/lang/XComponent.hpp>
41 #include <com/sun/star/lang/XServiceInfo.hpp>
43 #include <cppuhelper/implbase2.hxx>
44 #include <cppuhelper/supportsservice.hxx>
45 #include <vcl/svapp.hxx>
46 #include <rtl/ref.hxx>
47 #include <rtl/ustrbuf.hxx>
49 #include <unordered_map>
51 using namespace com::sun::star::uno;
52 using namespace com::sun::star::io;
53 using namespace com::sun::star::embed;
54 using namespace com::sun::star::lang;
55 using namespace com::sun::star::container;
56 using namespace com::sun::star::beans;
57 using namespace com::sun::star::ui;
58 using namespace framework;
60 namespace {
62 class UIConfigurationManager : public ::cppu::WeakImplHelper2<
63 css::lang::XServiceInfo ,
64 css::ui::XUIConfigurationManager2 >
66 public:
67 virtual OUString SAL_CALL getImplementationName()
68 throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
70 return OUString("com.sun.star.comp.framework.UIConfigurationManager");
73 virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName)
74 throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
76 return cppu::supportsService(this, ServiceName);
79 virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames()
80 throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
82 css::uno::Sequence< OUString > aSeq(1);
83 aSeq[0] = "com.sun.star.ui.UIConfigurationManager";
84 return aSeq;
87 UIConfigurationManager( const css::uno::Reference< css::uno::XComponentContext > & rxContext );
88 virtual ~UIConfigurationManager();
90 // XComponent
91 virtual void SAL_CALL dispose() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
92 virtual void SAL_CALL addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
93 virtual void SAL_CALL removeEventListener( const css::uno::Reference< css::lang::XEventListener >& aListener ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
95 // XUIConfiguration
96 virtual void SAL_CALL addConfigurationListener( const css::uno::Reference< css::ui::XUIConfigurationListener >& Listener ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
97 virtual void SAL_CALL removeConfigurationListener( const css::uno::Reference< css::ui::XUIConfigurationListener >& Listener ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
99 // XUIConfigurationManager
100 virtual void SAL_CALL reset() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
101 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;
102 virtual css::uno::Reference< css::container::XIndexContainer > SAL_CALL createSettings( ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
103 virtual sal_Bool SAL_CALL hasSettings( const OUString& ResourceURL ) throw (css::lang::IllegalArgumentException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
104 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;
105 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;
106 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;
107 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;
108 virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getImageManager() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
109 virtual css::uno::Reference< css::ui::XAcceleratorConfiguration > SAL_CALL getShortCutManager() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
110 virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getEventsManager() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
112 // XUIConfigurationPersistence
113 virtual void SAL_CALL reload() throw (css::uno::Exception, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
114 virtual void SAL_CALL store() throw (css::uno::Exception, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
115 virtual void SAL_CALL storeToStorage( const css::uno::Reference< css::embed::XStorage >& Storage ) throw (css::uno::Exception, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
116 virtual sal_Bool SAL_CALL isModified() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
117 virtual sal_Bool SAL_CALL isReadOnly() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
119 // XUIConfigurationStorage
120 virtual void SAL_CALL setStorage( const css::uno::Reference< css::embed::XStorage >& Storage ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
121 virtual sal_Bool SAL_CALL hasStorage() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
123 private:
124 // private data types
125 enum NotifyOp
127 NotifyOp_Remove,
128 NotifyOp_Insert,
129 NotifyOp_Replace
132 struct UIElementInfo
134 UIElementInfo( const OUString& rResourceURL, const OUString& rUIName ) :
135 aResourceURL( rResourceURL), aUIName( rUIName ) {}
136 OUString aResourceURL;
137 OUString aUIName;
140 struct UIElementData
142 UIElementData() : bModified( false ), bDefault( true ) {};
144 OUString aResourceURL;
145 OUString aName;
146 bool bModified; // has been changed since last storing
147 bool bDefault; // default settings
148 css::uno::Reference< css::container::XIndexAccess > xSettings;
151 struct UIElementType;
152 friend struct UIElementType;
153 typedef std::unordered_map< OUString, UIElementData, OUStringHash, std::equal_to< OUString > > UIElementDataHashMap;
155 struct UIElementType
157 UIElementType() : bModified( false ),
158 bLoaded( false ),
159 bDefaultLayer( false ),
160 nElementType( css::ui::UIElementType::UNKNOWN ) {}
162 bool bModified;
163 bool bLoaded;
164 bool bDefaultLayer;
165 sal_Int16 nElementType;
166 UIElementDataHashMap aElementsHashMap;
167 css::uno::Reference< css::embed::XStorage > xStorage;
170 typedef std::vector< UIElementType > UIElementTypesVector;
171 typedef std::vector< css::ui::ConfigurationEvent > ConfigEventNotifyContainer;
172 typedef std::unordered_map< OUString, UIElementInfo, OUStringHash, std::equal_to< OUString > > UIElementInfoHashMap;
174 void impl_Initialize();
175 void implts_notifyContainerListener( const css::ui::ConfigurationEvent& aEvent, NotifyOp eOp );
176 void impl_fillSequenceWithElementTypeInfo( UIElementInfoHashMap& aUIElementInfoCollection, sal_Int16 nElementType );
177 void impl_preloadUIElementTypeList( sal_Int16 nElementType );
178 UIElementData* impl_findUIElementData( const OUString& aResourceURL, sal_Int16 nElementType, bool bLoad = true );
179 void impl_requestUIElementData( sal_Int16 nElementType, UIElementData& aUIElementData );
180 void impl_storeElementTypeData( css::uno::Reference< css::embed::XStorage >& xStorage, UIElementType& rElementType, bool bResetModifyState = true );
181 void impl_resetElementTypeData( UIElementType& rDocElementType, ConfigEventNotifyContainer& rRemoveNotifyContainer );
182 void impl_reloadElementTypeData( UIElementType& rDocElementType, ConfigEventNotifyContainer& rRemoveNotifyContainer, ConfigEventNotifyContainer& rReplaceNotifyContainer );
184 UIElementTypesVector m_aUIElements;
185 css::uno::Reference< css::embed::XStorage > m_xDocConfigStorage;
186 bool m_bReadOnly;
187 bool m_bModified;
188 bool m_bConfigRead;
189 bool m_bDisposed;
190 OUString m_aXMLPostfix;
191 OUString m_aPropUIName;
192 OUString m_aPropResourceURL;
193 OUString m_aModuleIdentifier;
194 css::uno::Reference< css::uno::XComponentContext > m_xContext;
195 osl::Mutex m_mutex;
196 cppu::OMultiTypeInterfaceContainerHelper m_aListenerContainer; /// container for ALL Listener
197 css::uno::Reference< css::lang::XComponent > m_xImageManager;
198 css::uno::Reference< css::ui::XAcceleratorConfiguration > m_xAccConfig;
201 // important: The order and position of the elements must match the constant
202 // definition of "::com::sun::star::ui::UIElementType"
203 static const char* UIELEMENTTYPENAMES[] =
205 "", // Dummy value for unknown!
206 UIELEMENTTYPE_MENUBAR_NAME,
207 UIELEMENTTYPE_POPUPMENU_NAME,
208 UIELEMENTTYPE_TOOLBAR_NAME,
209 UIELEMENTTYPE_STATUSBAR_NAME,
210 UIELEMENTTYPE_FLOATINGWINDOW_NAME,
211 UIELEMENTTYPE_PROGRESSBAR_NAME,
212 UIELEMENTTYPE_TOOLPANEL_NAME
215 static const char RESOURCEURL_PREFIX[] = "private:resource/";
216 static const sal_Int32 RESOURCEURL_PREFIX_SIZE = 17;
218 static sal_Int16 RetrieveTypeFromResourceURL( const OUString& aResourceURL )
221 if (( aResourceURL.startsWith( RESOURCEURL_PREFIX ) ) &&
222 ( aResourceURL.getLength() > RESOURCEURL_PREFIX_SIZE ))
224 OUString aTmpStr = aResourceURL.copy( RESOURCEURL_PREFIX_SIZE );
225 sal_Int32 nIndex = aTmpStr.indexOf( '/' );
226 if (( nIndex > 0 ) && ( aTmpStr.getLength() > nIndex ))
228 OUString aTypeStr( aTmpStr.copy( 0, nIndex ));
229 for ( int i = 0; i < UIElementType::COUNT; i++ )
231 if ( aTypeStr.equalsAscii( UIELEMENTTYPENAMES[i] ))
232 return sal_Int16( i );
237 return UIElementType::UNKNOWN;
240 static OUString RetrieveNameFromResourceURL( const OUString& aResourceURL )
242 if (( aResourceURL.startsWith( RESOURCEURL_PREFIX ) ) &&
243 ( aResourceURL.getLength() > RESOURCEURL_PREFIX_SIZE ))
245 sal_Int32 nIndex = aResourceURL.lastIndexOf( '/' );
246 if (( nIndex > 0 ) && (( nIndex+1 ) < aResourceURL.getLength()))
247 return aResourceURL.copy( nIndex+1 );
250 return OUString();
253 void UIConfigurationManager::impl_fillSequenceWithElementTypeInfo( UIElementInfoHashMap& aUIElementInfoCollection, sal_Int16 nElementType )
255 // preload list of element types on demand
256 impl_preloadUIElementTypeList( nElementType );
258 UIElementDataHashMap& rUserElements = m_aUIElements[nElementType].aElementsHashMap;
259 UIElementDataHashMap::const_iterator pUserIter = rUserElements.begin();
261 while ( pUserIter != rUserElements.end() )
263 UIElementData* pDataSettings = impl_findUIElementData( pUserIter->second.aResourceURL, nElementType );
264 if ( pDataSettings && !pDataSettings->bDefault )
266 // Retrieve user interface name from XPropertySet interface
267 OUString aUIName;
268 Reference< XPropertySet > xPropSet( pDataSettings->xSettings, UNO_QUERY );
269 if ( xPropSet.is() )
271 Any a = xPropSet->getPropertyValue( m_aPropUIName );
272 a >>= aUIName;
275 UIElementInfo aInfo( pUserIter->second.aResourceURL, aUIName );
276 aUIElementInfoCollection.insert( UIElementInfoHashMap::value_type( pUserIter->second.aResourceURL, aInfo ));
278 ++pUserIter;
282 void UIConfigurationManager::impl_preloadUIElementTypeList( sal_Int16 nElementType )
284 UIElementType& rElementTypeData = m_aUIElements[nElementType];
286 if ( !rElementTypeData.bLoaded )
288 Reference< XStorage > xElementTypeStorage = rElementTypeData.xStorage;
289 if ( xElementTypeStorage.is() )
291 OUStringBuffer aBuf( RESOURCEURL_PREFIX_SIZE );
292 aBuf.appendAscii( RESOURCEURL_PREFIX );
293 aBuf.appendAscii( UIELEMENTTYPENAMES[ nElementType ] );
294 aBuf.appendAscii( "/" );
295 OUString aResURLPrefix( aBuf.makeStringAndClear() );
297 UIElementDataHashMap& rHashMap = rElementTypeData.aElementsHashMap;
298 Sequence< OUString > aUIElementNames = xElementTypeStorage->getElementNames();
299 for ( sal_Int32 n = 0; n < aUIElementNames.getLength(); n++ )
301 UIElementData aUIElementData;
303 // Resource name must be without ".xml"
304 sal_Int32 nIndex = aUIElementNames[n].lastIndexOf( '.' );
305 if (( nIndex > 0 ) && ( nIndex < aUIElementNames[n].getLength() ))
307 OUString aExtension( aUIElementNames[n].copy( nIndex+1 ));
308 OUString aUIElementName( aUIElementNames[n].copy( 0, nIndex ));
310 if (!aUIElementName.isEmpty() &&
311 ( aExtension.equalsIgnoreAsciiCase("xml")))
313 aUIElementData.aResourceURL = aResURLPrefix + aUIElementName;
314 aUIElementData.aName = aUIElementNames[n];
315 aUIElementData.bModified = false;
316 aUIElementData.bDefault = false;
318 // Create unordered_map entries for all user interface elements inside the storage. We don't load the
319 // settings to speed up the process.
320 rHashMap.insert( UIElementDataHashMap::value_type( aUIElementData.aResourceURL, aUIElementData ));
327 rElementTypeData.bLoaded = true;
330 void UIConfigurationManager::impl_requestUIElementData( sal_Int16 nElementType, UIElementData& aUIElementData )
332 UIElementType& rElementTypeData = m_aUIElements[nElementType];
334 Reference< XStorage > xElementTypeStorage = rElementTypeData.xStorage;
335 if ( xElementTypeStorage.is() && !aUIElementData.aName.isEmpty() )
339 Reference< XStream > xStream = xElementTypeStorage->openStreamElement( aUIElementData.aName, ElementModes::READ );
340 Reference< XInputStream > xInputStream = xStream->getInputStream();
342 if ( xInputStream.is() )
344 switch ( nElementType )
346 case ::com::sun::star::ui::UIElementType::UNKNOWN:
347 break;
349 case ::com::sun::star::ui::UIElementType::MENUBAR:
353 MenuConfiguration aMenuCfg( m_xContext );
354 Reference< XIndexAccess > xContainer( aMenuCfg.CreateMenuBarConfigurationFromXML( xInputStream ));
355 RootItemContainer* pRootItemContainer = RootItemContainer::GetImplementation( xContainer );
356 if ( pRootItemContainer )
357 aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( pRootItemContainer, true ) ), UNO_QUERY );
358 else
359 aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( xContainer, true ) ), UNO_QUERY );
360 return;
362 catch ( const ::com::sun::star::lang::WrappedTargetException& )
366 break;
368 case ::com::sun::star::ui::UIElementType::POPUPMENU:
370 break;
373 case ::com::sun::star::ui::UIElementType::TOOLBAR:
377 Reference< XIndexContainer > xIndexContainer( static_cast< OWeakObject * >( new RootItemContainer() ), UNO_QUERY );
378 ToolBoxConfiguration::LoadToolBox( m_xContext, xInputStream, xIndexContainer );
379 RootItemContainer* pRootItemContainer = RootItemContainer::GetImplementation( xIndexContainer );
380 aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( pRootItemContainer, true ) ), UNO_QUERY );
381 return;
383 catch ( const ::com::sun::star::lang::WrappedTargetException& )
387 break;
390 case ::com::sun::star::ui::UIElementType::STATUSBAR:
394 Reference< XIndexContainer > xIndexContainer( static_cast< OWeakObject * >( new RootItemContainer() ), UNO_QUERY );
395 StatusBarConfiguration::LoadStatusBar( m_xContext, xInputStream, xIndexContainer );
396 RootItemContainer* pRootItemContainer = RootItemContainer::GetImplementation( xIndexContainer );
397 aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( pRootItemContainer, true ) ), UNO_QUERY );
398 return;
400 catch ( const ::com::sun::star::lang::WrappedTargetException& )
404 break;
407 case ::com::sun::star::ui::UIElementType::FLOATINGWINDOW:
409 break;
414 catch ( const ::com::sun::star::embed::InvalidStorageException& )
417 catch ( const ::com::sun::star::lang::IllegalArgumentException& )
420 catch ( const ::com::sun::star::io::IOException& )
423 catch ( const ::com::sun::star::embed::StorageWrappedTargetException& )
428 // At least we provide an empty settings container!
429 aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer()), UNO_QUERY );
432 UIConfigurationManager::UIElementData* UIConfigurationManager::impl_findUIElementData( const OUString& aResourceURL, sal_Int16 nElementType, bool bLoad )
434 // preload list of element types on demand
435 impl_preloadUIElementTypeList( nElementType );
437 // try to look into our document vector/unordered_map combination
438 UIElementDataHashMap& rUserHashMap = m_aUIElements[nElementType].aElementsHashMap;
439 UIElementDataHashMap::iterator pIter = rUserHashMap.find( aResourceURL );
440 if ( pIter != rUserHashMap.end() )
442 // Default data settings data means removed!
443 if ( pIter->second.bDefault )
444 return &(pIter->second);
445 else
447 if ( !pIter->second.xSettings.is() && bLoad )
448 impl_requestUIElementData( nElementType, pIter->second );
449 return &(pIter->second);
453 // Nothing has been found!
454 return NULL;
457 void UIConfigurationManager::impl_storeElementTypeData( Reference< XStorage >& xStorage, UIElementType& rElementType, bool bResetModifyState )
459 UIElementDataHashMap& rHashMap = rElementType.aElementsHashMap;
460 UIElementDataHashMap::iterator pIter = rHashMap.begin();
462 while ( pIter != rHashMap.end() )
464 UIElementData& rElement = pIter->second;
465 if ( rElement.bModified )
467 if ( rElement.bDefault )
469 xStorage->removeElement( rElement.aName );
470 rElement.bModified = false; // mark as not modified
472 else
474 Reference< XStream > xStream( xStorage->openStreamElement( rElement.aName, ElementModes::WRITE|ElementModes::TRUNCATE ), UNO_QUERY );
475 Reference< XOutputStream > xOutputStream( xStream->getOutputStream() );
477 if ( xOutputStream.is() )
479 switch( rElementType.nElementType )
481 case ::com::sun::star::ui::UIElementType::MENUBAR:
485 MenuConfiguration aMenuCfg( m_xContext );
486 aMenuCfg.StoreMenuBarConfigurationToXML( rElement.xSettings, xOutputStream );
488 catch ( const ::com::sun::star::lang::WrappedTargetException& )
492 break;
494 case ::com::sun::star::ui::UIElementType::TOOLBAR:
498 ToolBoxConfiguration::StoreToolBox( m_xContext, xOutputStream, rElement.xSettings );
500 catch ( const ::com::sun::star::lang::WrappedTargetException& )
504 break;
506 case ::com::sun::star::ui::UIElementType::STATUSBAR:
510 StatusBarConfiguration::StoreStatusBar( m_xContext, xOutputStream, rElement.xSettings );
512 catch ( const ::com::sun::star::lang::WrappedTargetException& )
516 break;
518 default:
519 break;
523 // mark as not modified if we store to our own storage
524 if ( bResetModifyState )
525 rElement.bModified = false;
529 ++pIter;
532 // commit element type storage
533 Reference< XTransactedObject > xTransactedObject( xStorage, UNO_QUERY );
534 if ( xTransactedObject.is() )
535 xTransactedObject->commit();
537 // mark UIElementType as not modified if we store to our own storage
538 if ( bResetModifyState )
539 rElementType.bModified = false;
542 void UIConfigurationManager::impl_resetElementTypeData(
543 UIElementType& rDocElementType,
544 ConfigEventNotifyContainer& rRemoveNotifyContainer )
546 UIElementDataHashMap& rHashMap = rDocElementType.aElementsHashMap;
547 UIElementDataHashMap::iterator pIter = rHashMap.begin();
549 Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
550 Reference< XInterface > xIfac( xThis, UNO_QUERY );
552 // Make copies of the event structures to be thread-safe. We have to unlock our mutex before calling
553 // our listeners!
554 while ( pIter != rHashMap.end() )
556 UIElementData& rElement = pIter->second;
557 if ( !rElement.bDefault )
559 // Remove user-defined settings from document
560 ConfigurationEvent aEvent;
561 aEvent.ResourceURL = rElement.aResourceURL;
562 aEvent.Accessor <<= xThis;
563 aEvent.Source = xIfac;
564 aEvent.Element <<= rElement.xSettings;
566 rRemoveNotifyContainer.push_back( aEvent );
568 // Mark element as default.
569 rElement.bModified = false;
570 rElement.bDefault = true;
572 else
573 rElement.bModified = false;
575 ++pIter;
578 // Remove all settings from our user interface elements
579 rHashMap.clear();
582 void UIConfigurationManager::impl_reloadElementTypeData(
583 UIElementType& rDocElementType,
584 ConfigEventNotifyContainer& rRemoveNotifyContainer,
585 ConfigEventNotifyContainer& rReplaceNotifyContainer )
587 UIElementDataHashMap& rHashMap = rDocElementType.aElementsHashMap;
588 UIElementDataHashMap::iterator pIter = rHashMap.begin();
589 Reference< XStorage > xElementStorage( rDocElementType.xStorage );
591 Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
592 Reference< XInterface > xIfac( xThis, UNO_QUERY );
593 sal_Int16 nType = rDocElementType.nElementType;
595 while ( pIter != rHashMap.end() )
597 UIElementData& rElement = pIter->second;
598 if ( rElement.bModified )
600 if ( xElementStorage->hasByName( rElement.aName ))
602 // Replace settings with data from user layer
603 Reference< XIndexAccess > xOldSettings( rElement.xSettings );
605 impl_requestUIElementData( nType, rElement );
607 ConfigurationEvent aReplaceEvent;
609 aReplaceEvent.ResourceURL = rElement.aResourceURL;
610 aReplaceEvent.Accessor <<= xThis;
611 aReplaceEvent.Source = xIfac;
612 aReplaceEvent.ReplacedElement <<= xOldSettings;
613 aReplaceEvent.Element <<= rElement.xSettings;
614 rReplaceNotifyContainer.push_back( aReplaceEvent );
616 rElement.bModified = false;
618 else
620 // Element settings are not in any storage => remove
621 ConfigurationEvent aRemoveEvent;
623 aRemoveEvent.ResourceURL = rElement.aResourceURL;
624 aRemoveEvent.Accessor <<= xThis;
625 aRemoveEvent.Source = xIfac;
626 aRemoveEvent.Element <<= rElement.xSettings;
628 rRemoveNotifyContainer.push_back( aRemoveEvent );
630 // Mark element as default and not modified. That means "not active" in the document anymore
631 rElement.bModified = false;
632 rElement.bDefault = true;
635 ++pIter;
638 rDocElementType.bModified = false;
641 void UIConfigurationManager::impl_Initialize()
643 // Initialize the top-level structures with the storage data
644 if ( m_xDocConfigStorage.is() )
646 long nModes = m_bReadOnly ? ElementModes::READ : ElementModes::READWRITE;
648 // Try to access our module sub folder
649 for ( sal_Int16 i = 1; i < ::com::sun::star::ui::UIElementType::COUNT;
650 i++ )
652 Reference< XStorage > xElementTypeStorage;
655 xElementTypeStorage = m_xDocConfigStorage->openStorageElement( OUString::createFromAscii( UIELEMENTTYPENAMES[i] ), nModes );
657 catch ( const com::sun::star::container::NoSuchElementException& )
660 catch ( const ::com::sun::star::embed::InvalidStorageException& )
663 catch ( const ::com::sun::star::lang::IllegalArgumentException& )
666 catch ( const ::com::sun::star::io::IOException& )
669 catch ( const ::com::sun::star::embed::StorageWrappedTargetException& )
673 m_aUIElements[i].nElementType = i;
674 m_aUIElements[i].bModified = false;
675 m_aUIElements[i].xStorage = xElementTypeStorage;
676 m_aUIElements[i].bDefaultLayer = false;
679 else
681 // We have no storage, just initialize ui element types with empty storage!
682 for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
683 m_aUIElements[i].xStorage = m_xDocConfigStorage;
687 UIConfigurationManager::UIConfigurationManager( const com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext > & rxContext ) :
688 m_xDocConfigStorage( 0 )
689 , m_bReadOnly( true )
690 , m_bModified( false )
691 , m_bConfigRead( false )
692 , m_bDisposed( false )
693 , m_aXMLPostfix( ".xml" )
694 , m_aPropUIName( "UIName" )
695 , m_aPropResourceURL( "ResourceURL" )
696 , m_xContext( rxContext )
697 , m_aListenerContainer( m_mutex )
699 // Make sure we have a default initialized entry for every layer and user interface element type!
700 // The following code depends on this!
701 m_aUIElements.resize( ::com::sun::star::ui::UIElementType::COUNT );
704 UIConfigurationManager::~UIConfigurationManager()
708 // XComponent
709 void SAL_CALL UIConfigurationManager::dispose() throw (::com::sun::star::uno::RuntimeException, std::exception)
711 Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
713 css::lang::EventObject aEvent( xThis );
714 m_aListenerContainer.disposeAndClear( aEvent );
717 SolarMutexGuard g;
720 if ( m_xImageManager.is() )
721 m_xImageManager->dispose();
723 catch ( const Exception& )
727 m_xImageManager.clear();
728 m_aUIElements.clear();
729 m_xDocConfigStorage.clear();
730 m_bConfigRead = false;
731 m_bModified = false;
732 m_bDisposed = true;
736 void SAL_CALL UIConfigurationManager::addEventListener( const Reference< XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException, std::exception)
739 SolarMutexGuard g;
741 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
742 if ( m_bDisposed )
743 throw DisposedException();
746 m_aListenerContainer.addInterface( cppu::UnoType<XEventListener>::get(), xListener );
749 void SAL_CALL UIConfigurationManager::removeEventListener( const Reference< XEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException, std::exception)
751 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
752 m_aListenerContainer.removeInterface( cppu::UnoType<XEventListener>::get(), xListener );
755 // XUIConfigurationManager
756 void SAL_CALL UIConfigurationManager::addConfigurationListener( const Reference< ::com::sun::star::ui::XUIConfigurationListener >& xListener ) throw (::com::sun::star::uno::RuntimeException, std::exception)
759 SolarMutexGuard g;
761 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
762 if ( m_bDisposed )
763 throw DisposedException();
766 m_aListenerContainer.addInterface( cppu::UnoType<XUIConfigurationListener>::get(), xListener );
769 void SAL_CALL UIConfigurationManager::removeConfigurationListener( const Reference< ::com::sun::star::ui::XUIConfigurationListener >& xListener ) throw (::com::sun::star::uno::RuntimeException, std::exception)
771 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
772 m_aListenerContainer.removeInterface( cppu::UnoType<XUIConfigurationListener>::get(), xListener );
775 void SAL_CALL UIConfigurationManager::reset() throw (::com::sun::star::uno::RuntimeException, std::exception)
777 SolarMutexClearableGuard aGuard;
779 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
780 if ( m_bDisposed )
781 throw DisposedException();
783 if ( isReadOnly() )
784 return;
786 if ( m_xDocConfigStorage.is() )
790 // Remove all elements from our user-defined storage!
791 bool bCommit( false );
792 for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
794 UIElementType& rElementType = m_aUIElements[i];
795 Reference< XStorage > xSubStorage( rElementType.xStorage, UNO_QUERY );
797 if ( xSubStorage.is() )
799 bool bCommitSubStorage( false );
800 Sequence< OUString > aUIElementStreamNames = xSubStorage->getElementNames();
801 for ( sal_Int32 j = 0; j < aUIElementStreamNames.getLength(); j++ )
803 xSubStorage->removeElement( aUIElementStreamNames[j] );
804 bCommitSubStorage = true;
805 bCommit = true;
808 if ( bCommitSubStorage )
810 Reference< XTransactedObject > xTransactedObject( xSubStorage, UNO_QUERY );
811 if ( xTransactedObject.is() )
812 xTransactedObject->commit();
817 // Commit changes
818 if ( bCommit )
820 Reference< XTransactedObject > xTransactedObject( m_xDocConfigStorage, UNO_QUERY );
821 if ( xTransactedObject.is() )
822 xTransactedObject->commit();
825 // remove settings from user defined layer and notify listener about removed settings data!
826 // Try to access our module sub folder
827 ConfigEventNotifyContainer aRemoveEventNotifyContainer;
828 for ( sal_Int16 j = 1; j < ::com::sun::star::ui::UIElementType::COUNT; j++ )
830 UIElementType& rDocElementType = m_aUIElements[j];
832 impl_resetElementTypeData( rDocElementType, aRemoveEventNotifyContainer );
833 rDocElementType.bModified = false;
836 m_bModified = false;
838 // Unlock mutex before notify our listeners
839 aGuard.clear();
841 // Notify our listeners
842 for ( sal_uInt32 k = 0; k < aRemoveEventNotifyContainer.size(); k++ )
843 implts_notifyContainerListener( aRemoveEventNotifyContainer[k], NotifyOp_Remove );
845 catch ( const ::com::sun::star::lang::IllegalArgumentException& )
848 catch ( const ::com::sun::star::container::NoSuchElementException& )
851 catch ( const ::com::sun::star::embed::InvalidStorageException& )
854 catch ( const ::com::sun::star::embed::StorageWrappedTargetException& )
860 Sequence< Sequence< PropertyValue > > SAL_CALL UIConfigurationManager::getUIElementsInfo( sal_Int16 ElementType )
861 throw ( IllegalArgumentException, RuntimeException, std::exception )
863 if (( ElementType < 0 ) || ( ElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
864 throw IllegalArgumentException();
866 SolarMutexGuard g;
867 if ( m_bDisposed )
868 throw DisposedException();
870 Sequence< Sequence< PropertyValue > > aElementInfoSeq;
871 UIElementInfoHashMap aUIElementInfoCollection;
873 if ( ElementType == ::com::sun::star::ui::UIElementType::UNKNOWN )
875 for ( sal_Int16 i = 0; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
876 impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection, sal_Int16( i ) );
878 else
879 impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection, ElementType );
881 Sequence< PropertyValue > aUIElementInfo( 2 );
882 aUIElementInfo[0].Name = m_aPropResourceURL;
883 aUIElementInfo[1].Name = m_aPropUIName;
885 aElementInfoSeq.realloc( aUIElementInfoCollection.size() );
886 UIElementInfoHashMap::const_iterator pIter = aUIElementInfoCollection.begin();
888 sal_Int32 n = 0;
889 while ( pIter != aUIElementInfoCollection.end() )
891 aUIElementInfo[0].Value <<= pIter->second.aResourceURL;
892 aUIElementInfo[1].Value <<= pIter->second.aUIName;
893 aElementInfoSeq[n++] = aUIElementInfo;
894 ++pIter;
897 return aElementInfoSeq;
900 Reference< XIndexContainer > SAL_CALL UIConfigurationManager::createSettings() throw (::com::sun::star::uno::RuntimeException, std::exception)
902 SolarMutexGuard g;
904 if ( m_bDisposed )
905 throw DisposedException();
907 // Creates an empty item container which can be filled from outside
908 return Reference< XIndexContainer >( static_cast< OWeakObject * >( new RootItemContainer()), UNO_QUERY );
911 sal_Bool SAL_CALL UIConfigurationManager::hasSettings( const OUString& ResourceURL )
912 throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception)
914 sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
916 if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
917 ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
918 throw IllegalArgumentException();
919 else
921 UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType, false );
922 if ( pDataSettings && !pDataSettings->bDefault )
923 return sal_True;
926 return sal_False;
929 Reference< XIndexAccess > SAL_CALL UIConfigurationManager::getSettings( const OUString& ResourceURL, sal_Bool bWriteable )
930 throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception)
932 sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
934 if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
935 ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
936 throw IllegalArgumentException();
937 else
939 SolarMutexGuard g;
941 if ( m_bDisposed )
942 throw DisposedException();
944 UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType );
945 if ( pDataSettings && !pDataSettings->bDefault )
947 // Create a copy of our data if someone wants to change the data.
948 if ( bWriteable )
949 return Reference< XIndexAccess >( static_cast< OWeakObject * >( new RootItemContainer( pDataSettings->xSettings ) ), UNO_QUERY );
950 else
951 return pDataSettings->xSettings;
955 throw NoSuchElementException();
958 void SAL_CALL UIConfigurationManager::replaceSettings( const OUString& ResourceURL, const Reference< ::com::sun::star::container::XIndexAccess >& aNewData )
959 throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException, std::exception)
961 sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
963 if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
964 ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
965 throw IllegalArgumentException();
966 else if ( m_bReadOnly )
967 throw IllegalAccessException();
968 else
970 SolarMutexClearableGuard aGuard;
972 if ( m_bDisposed )
973 throw DisposedException();
975 UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType );
976 if ( pDataSettings && !pDataSettings->bDefault )
978 // we have a settings entry in our user-defined layer - replace
979 Reference< XIndexAccess > xOldSettings = pDataSettings->xSettings;
981 // Create a copy of the data if the container is not const
982 Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY );
983 if ( xReplace.is() )
984 pDataSettings->xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( aNewData ) ), UNO_QUERY );
985 else
986 pDataSettings->xSettings = aNewData;
988 pDataSettings->bDefault = false;
989 pDataSettings->bModified = true;
990 m_bModified = true;
992 // Modify type container
993 UIElementType& rElementType = m_aUIElements[nElementType];
994 rElementType.bModified = true;
996 Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
997 Reference< XInterface > xIfac( xThis, UNO_QUERY );
999 // Create event to notify listener about replaced element settings
1000 ConfigurationEvent aEvent;
1002 aEvent.ResourceURL = ResourceURL;
1003 aEvent.Accessor <<= xThis;
1004 aEvent.Source = xIfac;
1005 aEvent.ReplacedElement <<= xOldSettings;
1006 aEvent.Element <<= pDataSettings->xSettings;
1008 aGuard.clear();
1010 implts_notifyContainerListener( aEvent, NotifyOp_Replace );
1012 else
1013 throw NoSuchElementException();
1017 void SAL_CALL UIConfigurationManager::removeSettings( const OUString& ResourceURL )
1018 throw ( NoSuchElementException, IllegalArgumentException, IllegalAccessException, RuntimeException, std::exception)
1020 sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
1022 if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
1023 ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
1024 throw IllegalArgumentException();
1025 else if ( m_bReadOnly )
1026 throw IllegalAccessException();
1027 else
1029 SolarMutexClearableGuard aGuard;
1031 if ( m_bDisposed )
1032 throw DisposedException();
1034 UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType );
1035 if ( pDataSettings )
1037 // If element settings are default, we don't need to change anything!
1038 if ( pDataSettings->bDefault )
1039 return;
1040 else
1042 Reference< XIndexAccess > xRemovedSettings = pDataSettings->xSettings;
1043 pDataSettings->bDefault = true;
1045 // check if this is a default layer node
1046 pDataSettings->bModified = true; // we have to remove this node from the user layer!
1047 pDataSettings->xSettings.clear();
1048 m_bModified = true; // user layer must be written
1050 // Modify type container
1051 UIElementType& rElementType = m_aUIElements[nElementType];
1052 rElementType.bModified = true;
1054 Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
1055 Reference< XInterface > xIfac( xThis, UNO_QUERY );
1057 // Create event to notify listener about removed element settings
1058 ConfigurationEvent aEvent;
1060 aEvent.ResourceURL = ResourceURL;
1061 aEvent.Accessor <<= xThis;
1062 aEvent.Source = xIfac;
1063 aEvent.Element <<= xRemovedSettings;
1065 aGuard.clear();
1067 implts_notifyContainerListener( aEvent, NotifyOp_Remove );
1070 else
1071 throw NoSuchElementException();
1075 void SAL_CALL UIConfigurationManager::insertSettings( const OUString& NewResourceURL, const Reference< XIndexAccess >& aNewData )
1076 throw ( ElementExistException, IllegalArgumentException, IllegalAccessException, RuntimeException, std::exception )
1078 sal_Int16 nElementType = RetrieveTypeFromResourceURL( NewResourceURL );
1080 if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
1081 ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
1082 throw IllegalArgumentException();
1083 else if ( m_bReadOnly )
1084 throw IllegalAccessException();
1085 else
1087 SolarMutexClearableGuard aGuard;
1089 if ( m_bDisposed )
1090 throw DisposedException();
1092 bool bInsertData( false );
1093 UIElementData aUIElementData;
1094 UIElementData* pDataSettings = impl_findUIElementData( NewResourceURL, nElementType );
1096 if ( pDataSettings && !pDataSettings->bDefault )
1097 throw ElementExistException();
1099 if ( !pDataSettings )
1101 pDataSettings = &aUIElementData;
1102 bInsertData = true;
1106 pDataSettings->bDefault = false;
1107 pDataSettings->bModified = true;
1109 // Create a copy of the data if the container is not const
1110 Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY );
1111 if ( xReplace.is() )
1112 pDataSettings->xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( aNewData ) ), UNO_QUERY );
1113 else
1114 pDataSettings->xSettings = aNewData;
1116 m_bModified = true;
1118 UIElementType& rElementType = m_aUIElements[nElementType];
1119 rElementType.bModified = true;
1121 if ( bInsertData )
1123 pDataSettings->aName = RetrieveNameFromResourceURL( NewResourceURL ) + m_aXMLPostfix;
1124 pDataSettings->aResourceURL = NewResourceURL;
1126 UIElementDataHashMap& rElements = rElementType.aElementsHashMap;
1127 rElements.insert( UIElementDataHashMap::value_type( NewResourceURL, *pDataSettings ));
1130 Reference< XIndexAccess > xInsertSettings( aUIElementData.xSettings );
1131 Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
1132 Reference< XInterface > xIfac( xThis, UNO_QUERY );
1134 // Create event to notify listener about removed element settings
1135 ConfigurationEvent aEvent;
1137 aEvent.ResourceURL = NewResourceURL;
1138 aEvent.Accessor <<= xThis;
1139 aEvent.Source = xIfac;
1140 aEvent.Element <<= xInsertSettings;
1142 aGuard.clear();
1144 implts_notifyContainerListener( aEvent, NotifyOp_Insert );
1149 Reference< XInterface > SAL_CALL UIConfigurationManager::getImageManager() throw (::com::sun::star::uno::RuntimeException, std::exception)
1151 if ( m_bDisposed )
1152 throw DisposedException();
1154 if ( !m_xImageManager.is() )
1156 m_xImageManager = Reference< XComponent >( static_cast< cppu::OWeakObject *>( new ImageManager( m_xContext )),
1157 UNO_QUERY );
1158 Reference< XInitialization > xInit( m_xImageManager, UNO_QUERY );
1160 Sequence< Any > aPropSeq( 2 );
1161 PropertyValue aPropValue;
1162 aPropValue.Name = "UserConfigStorage";
1163 aPropValue.Value = makeAny( m_xDocConfigStorage );
1164 aPropSeq[0] = makeAny( aPropValue );
1165 aPropValue.Name = "ModuleIdentifier";
1166 aPropValue.Value = makeAny( m_aModuleIdentifier );
1167 aPropSeq[1] = makeAny( aPropValue );
1169 xInit->initialize( aPropSeq );
1172 return Reference< XInterface >( m_xImageManager, UNO_QUERY );
1175 Reference< XAcceleratorConfiguration > SAL_CALL UIConfigurationManager::getShortCutManager() throw (::com::sun::star::uno::RuntimeException, std::exception)
1177 // SAFE ->
1178 SolarMutexGuard g;
1180 if (!m_xAccConfig.is()) try
1182 m_xAccConfig = DocumentAcceleratorConfiguration::
1183 createWithDocumentRoot(m_xContext, m_xDocConfigStorage);
1185 catch ( const css::uno::DeploymentException& )
1187 SAL_WARN("fwk.uiconfiguration", "DocumentAcceleratorConfiguration"
1188 " not available. This should happen only on mobile platforms.");
1191 return m_xAccConfig;
1194 Reference< XInterface > SAL_CALL UIConfigurationManager::getEventsManager() throw (::com::sun::star::uno::RuntimeException, std::exception)
1196 return Reference< XInterface >();
1199 // XUIConfigurationStorage
1200 void SAL_CALL UIConfigurationManager::setStorage( const Reference< XStorage >& Storage ) throw (::com::sun::star::uno::RuntimeException, std::exception)
1202 SolarMutexGuard g;
1204 if ( m_bDisposed )
1205 throw DisposedException();
1207 if ( m_xDocConfigStorage.is() )
1211 // Dispose old storage to be sure that it will be closed
1212 Reference< XComponent > xComponent( m_xDocConfigStorage, UNO_QUERY );
1213 if ( xComponent.is() )
1214 xComponent->dispose();
1216 catch ( const Exception& )
1221 // We store the new storage. Be careful it could be an empty reference!
1222 m_xDocConfigStorage = Storage;
1223 m_bReadOnly = true;
1225 Reference< XUIConfigurationStorage > xAccUpdate(m_xAccConfig, UNO_QUERY);
1226 if ( xAccUpdate.is() )
1227 xAccUpdate->setStorage( m_xDocConfigStorage );
1229 if ( m_xImageManager.is() )
1231 ImageManager* pImageManager = static_cast<ImageManager*>(m_xImageManager.get());
1232 if ( pImageManager )
1233 pImageManager->setStorage( m_xDocConfigStorage );
1236 if ( m_xDocConfigStorage.is() )
1238 Reference< XPropertySet > xPropSet( m_xDocConfigStorage, UNO_QUERY );
1239 if ( xPropSet.is() )
1243 long nOpenMode = 0;
1244 Any a = xPropSet->getPropertyValue("OpenMode");
1245 if ( a >>= nOpenMode )
1246 m_bReadOnly = !( nOpenMode & ElementModes::WRITE );
1248 catch ( const com::sun::star::beans::UnknownPropertyException& )
1251 catch ( const com::sun::star::lang::WrappedTargetException& )
1257 impl_Initialize();
1260 sal_Bool SAL_CALL UIConfigurationManager::hasStorage() throw (::com::sun::star::uno::RuntimeException, std::exception)
1262 SolarMutexGuard g;
1264 if ( m_bDisposed )
1265 throw DisposedException();
1267 return ( m_xDocConfigStorage.is() );
1270 // XUIConfigurationPersistence
1271 void SAL_CALL UIConfigurationManager::reload() throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
1273 SolarMutexClearableGuard aGuard;
1275 if ( m_bDisposed )
1276 throw DisposedException();
1278 if ( m_xDocConfigStorage.is() && m_bModified && !m_bReadOnly )
1280 // Try to access our module sub folder
1281 ConfigEventNotifyContainer aRemoveNotifyContainer;
1282 ConfigEventNotifyContainer aReplaceNotifyContainer;
1283 for ( sal_Int16 i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
1287 UIElementType& rDocElementType = m_aUIElements[i];
1288 if ( rDocElementType.bModified )
1289 impl_reloadElementTypeData( rDocElementType, aRemoveNotifyContainer, aReplaceNotifyContainer );
1291 catch ( const Exception& )
1293 throw IOException();
1297 m_bModified = false;
1299 // Unlock mutex before notify our listeners
1300 aGuard.clear();
1302 // Notify our listeners
1303 for ( sal_uInt32 j = 0; j < aRemoveNotifyContainer.size(); j++ )
1304 implts_notifyContainerListener( aRemoveNotifyContainer[j], NotifyOp_Remove );
1305 for ( sal_uInt32 k = 0; k < aReplaceNotifyContainer.size(); k++ )
1306 implts_notifyContainerListener( aReplaceNotifyContainer[k], NotifyOp_Replace );
1310 void SAL_CALL UIConfigurationManager::store() throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
1312 SolarMutexGuard g;
1314 if ( m_bDisposed )
1315 throw DisposedException();
1317 if ( m_xDocConfigStorage.is() && m_bModified && !m_bReadOnly )
1319 // Try to access our module sub folder
1320 for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
1324 UIElementType& rElementType = m_aUIElements[i];
1325 Reference< XStorage > xStorage( rElementType.xStorage, UNO_QUERY );
1327 if ( rElementType.bModified && xStorage.is() )
1328 impl_storeElementTypeData( xStorage, rElementType );
1330 catch ( const Exception& )
1332 throw IOException();
1336 m_bModified = false;
1337 Reference< XTransactedObject > xTransactedObject( m_xDocConfigStorage, UNO_QUERY );
1338 if ( xTransactedObject.is() )
1339 xTransactedObject->commit();
1343 void SAL_CALL UIConfigurationManager::storeToStorage( const Reference< XStorage >& Storage ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception)
1345 SolarMutexGuard g;
1347 if ( m_bDisposed )
1348 throw DisposedException();
1350 if ( m_xDocConfigStorage.is() && m_bModified && !m_bReadOnly )
1352 // Try to access our module sub folder
1353 for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
1357 Reference< XStorage > xElementTypeStorage( Storage->openStorageElement(
1358 OUString::createFromAscii( UIELEMENTTYPENAMES[i] ), ElementModes::READWRITE ));
1359 UIElementType& rElementType = m_aUIElements[i];
1361 if ( rElementType.bModified && xElementTypeStorage.is() )
1362 impl_storeElementTypeData( xElementTypeStorage, rElementType, false ); // store data to storage, but don't reset modify flag!
1364 catch ( const Exception& )
1366 throw IOException();
1370 Reference< XTransactedObject > xTransactedObject( Storage, UNO_QUERY );
1371 if ( xTransactedObject.is() )
1372 xTransactedObject->commit();
1376 sal_Bool SAL_CALL UIConfigurationManager::isModified() throw (::com::sun::star::uno::RuntimeException, std::exception)
1378 SolarMutexGuard g;
1380 return m_bModified;
1383 sal_Bool SAL_CALL UIConfigurationManager::isReadOnly() throw (::com::sun::star::uno::RuntimeException, std::exception)
1385 SolarMutexGuard g;
1387 return m_bReadOnly;
1390 void UIConfigurationManager::implts_notifyContainerListener( const ConfigurationEvent& aEvent, NotifyOp eOp )
1392 ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( cppu::UnoType<com::sun::star::ui::XUIConfigurationListener>::get());
1393 if ( pContainer != NULL )
1395 ::cppu::OInterfaceIteratorHelper pIterator( *pContainer );
1396 while ( pIterator.hasMoreElements() )
1400 switch ( eOp )
1402 case NotifyOp_Replace:
1403 static_cast< ::com::sun::star::ui::XUIConfigurationListener*>(pIterator.next())->elementReplaced( aEvent );
1404 break;
1405 case NotifyOp_Insert:
1406 static_cast< ::com::sun::star::ui::XUIConfigurationListener*>(pIterator.next())->elementInserted( aEvent );
1407 break;
1408 case NotifyOp_Remove:
1409 static_cast< ::com::sun::star::ui::XUIConfigurationListener*>(pIterator.next())->elementRemoved( aEvent );
1410 break;
1413 catch( const css::uno::RuntimeException& )
1415 pIterator.remove();
1423 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
1424 com_sun_star_comp_framework_UIConfigurationManager_get_implementation(
1425 css::uno::XComponentContext *context,
1426 css::uno::Sequence<css::uno::Any> const &)
1428 return cppu::acquire(new UIConfigurationManager(context));
1431 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */