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