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