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