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