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