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 successfull, 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() throw (::com::sun::star::uno::RuntimeException)
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 ) throw (::com::sun::star::uno::RuntimeException)
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 ) throw (::com::sun::star::uno::RuntimeException)
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 ) throw ( Exception, RuntimeException )
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 wont be used later ... seee 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 ) throw (::com::sun::star::uno::RuntimeException)
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 ) throw (::com::sun::star::uno::RuntimeException)
866 {
867     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
868     m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XUIConfigurationListener >* ) NULL ), xListener );
869 }
870 
871 
872 // XUIConfigurationManager
reset()873 void UIConfigurationManagerImpl::reset() throw (::com::sun::star::uno::RuntimeException)
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 throw ( IllegalArgumentException, RuntimeException )
961 {
962     if (( ElementType < 0 ) || ( ElementType >= ::com::sun::star::ui::UIElementType::COUNT ))
963         throw IllegalArgumentException();
964 
965     ResetableGuard aGuard( m_aLock );
966     if ( m_bDisposed )
967         throw DisposedException();
968 
969     Sequence< Sequence< PropertyValue > > aElementInfoSeq;
970     UIElementInfoHashMap aUIElementInfoCollection;
971 
972     if ( ElementType == ::com::sun::star::ui::UIElementType::UNKNOWN )
973     {
974         for ( sal_Int16 i = 0; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
975             impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection, sal_Int16( i ) );
976     }
977     else
978         impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection, ElementType );
979 
980     Sequence< PropertyValue > aUIElementInfo( 2 );
981     aUIElementInfo[0].Name = m_aPropResourceURL;
982     aUIElementInfo[1].Name = m_aPropUIName;
983 
984     aElementInfoSeq.realloc( aUIElementInfoCollection.size() );
985     UIElementInfoHashMap::const_iterator pIter = aUIElementInfoCollection.begin();
986 
987     sal_Int32 n = 0;
988     while ( pIter != aUIElementInfoCollection.end() )
989     {
990         aUIElementInfo[0].Value <<= pIter->second.aResourceURL;
991         aUIElementInfo[1].Value <<= pIter->second.aUIName;
992         aElementInfoSeq[n++] = aUIElementInfo;
993         ++pIter;
994     }
995 
996     return aElementInfoSeq;
997 }
998 
createSettings()999 Reference< XIndexContainer > UIConfigurationManagerImpl::createSettings() throw (::com::sun::star::uno::RuntimeException)
1000 {
1001     ResetableGuard aGuard( m_aLock );
1002 
1003     if ( m_bDisposed )
1004         throw DisposedException();
1005 
1006     // Creates an empty item container which can be filled from outside
1007     return Reference< XIndexContainer >( static_cast< OWeakObject * >( new RootItemContainer() ), UNO_QUERY );
1008 }
1009 
hasSettings(const::rtl::OUString & ResourceURL)1010 sal_Bool UIConfigurationManagerImpl::hasSettings( const ::rtl::OUString& ResourceURL )
1011 throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
1012 {
1013     sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
1014 
1015     if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
1016         ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT   ))
1017         throw IllegalArgumentException();
1018     else
1019     {
1020         ResetableGuard aGuard( m_aLock );
1021 
1022         if ( m_bDisposed )
1023             throw DisposedException();
1024 
1025         UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType, false );
1026         if ( pDataSettings && ( m_bUseDefault || !pDataSettings->bDefault) )
1027             return sal_True;
1028     }
1029 
1030     return sal_False;
1031 }
1032 
getSettings(const::rtl::OUString & ResourceURL,sal_Bool bWriteable)1033 Reference< XIndexAccess > UIConfigurationManagerImpl::getSettings( const ::rtl::OUString& ResourceURL, sal_Bool bWriteable )
1034 throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
1035 {
1036     sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
1037 
1038     if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
1039         ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT   ))
1040         throw IllegalArgumentException();
1041     else
1042     {
1043         ResetableGuard aGuard( m_aLock );
1044 
1045         if ( m_bDisposed )
1046             throw DisposedException();
1047 
1048         UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType );
1049         if ( pDataSettings && ( m_bUseDefault || !pDataSettings->bDefault) )
1050         {
1051             // Create a copy of our data if someone wants to change the data.
1052             if ( bWriteable )
1053                 return Reference< XIndexAccess >( static_cast< OWeakObject * >( new RootItemContainer( pDataSettings->xSettings ) ), UNO_QUERY );
1054             else
1055                 return pDataSettings->xSettings;
1056         }
1057     }
1058 
1059     throw NoSuchElementException();
1060 }
1061 
replaceSettings(const::rtl::OUString & ResourceURL,const Reference<::com::sun::star::container::XIndexAccess> & aNewData)1062 void UIConfigurationManagerImpl::replaceSettings( const ::rtl::OUString& ResourceURL, const Reference< ::com::sun::star::container::XIndexAccess >& aNewData )
1063 throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException)
1064 {
1065     sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
1066 
1067     if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
1068         ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT   ))
1069         throw IllegalArgumentException();
1070     else if ( m_bReadOnly )
1071         throw IllegalAccessException();
1072     else
1073     {
1074         ResetableGuard aGuard( m_aLock );
1075 
1076         if ( m_bDisposed )
1077             throw DisposedException();
1078 
1079         UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType );
1080         if ( pDataSettings && ( m_bUseDefault || !pDataSettings->bDefault) )
1081         {
1082             if ( !m_bUseDefault || !pDataSettings->bDefaultNode )
1083             {
1084                 // we have a settings entry in our user-defined layer - replace
1085                 Reference< XIndexAccess > xOldSettings = pDataSettings->xSettings;
1086 
1087                 // Create a copy of the data if the container is not const
1088                 Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY );
1089                 if ( xReplace.is() )
1090                     pDataSettings->xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( aNewData ) ), UNO_QUERY );
1091                 else
1092                     pDataSettings->xSettings = aNewData;
1093                 pDataSettings->bDefault  = false;
1094                 pDataSettings->bModified = true;
1095                 m_bModified = true;
1096 
1097                 // Modify type container
1098                 UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType];
1099                 rElementType.bModified = true;
1100 
1101                 Reference< XUIConfigurationManager > xThis( m_xOwner, UNO_QUERY );
1102 
1103                 // Create event to notify listener about replaced element settings
1104                 ConfigurationEvent aEvent;
1105 
1106                 aEvent.ResourceURL = ResourceURL;
1107                 aEvent.Accessor <<= xThis;
1108                 aEvent.Source = m_xOwner;
1109                 aEvent.ReplacedElement <<= xOldSettings;
1110                 aEvent.Element <<= pDataSettings->xSettings;
1111 
1112                 aGuard.unlock();
1113 
1114                 implts_notifyContainerListener( aEvent, NotifyOp_Replace );
1115             }
1116             else
1117             {
1118                 // we have no settings in our user-defined layer - insert
1119                 UIElementData aUIElementData;
1120 
1121                 aUIElementData.bDefault     = false;
1122                 aUIElementData.bDefaultNode = false;
1123                 aUIElementData.bModified    = true;
1124 
1125                 // Create a copy of the data if the container is not const
1126                 Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY );
1127                 if ( xReplace.is() )
1128                     aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( aNewData ) ), UNO_QUERY );
1129                 else
1130                     aUIElementData.xSettings = aNewData;
1131                 aUIElementData.aName        = RetrieveNameFromResourceURL( ResourceURL ) + m_aXMLPostfix;
1132                 aUIElementData.aResourceURL = ResourceURL;
1133                 m_bModified = true;
1134 
1135                 // Modify type container
1136                 UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType];
1137                 rElementType.bModified = true;
1138 
1139                 UIElementDataHashMap& rElements = rElementType.aElementsHashMap;
1140 
1141                 // Check our user element settings hash map as it can already contain settings that have been set to default!
1142                 // If no node can be found, we have to insert it.
1143                 UIElementDataHashMap::iterator pIter = rElements.find( ResourceURL );
1144                 if ( pIter != rElements.end() )
1145                     pIter->second = aUIElementData;
1146                 else
1147                     rElements.insert( UIElementDataHashMap::value_type( ResourceURL, aUIElementData ));
1148 
1149                 Reference< XUIConfigurationManager > xThis( m_xOwner, UNO_QUERY );
1150 
1151                 // Create event to notify listener about replaced element settings
1152                 ConfigurationEvent aEvent;
1153 
1154                 aEvent.ResourceURL = ResourceURL;
1155                 aEvent.Accessor <<= xThis;
1156                 aEvent.Source = m_xOwner;
1157                 aEvent.ReplacedElement <<= pDataSettings->xSettings;
1158                 aEvent.Element <<= aUIElementData.xSettings;
1159 
1160                 aGuard.unlock();
1161 
1162                 implts_notifyContainerListener( aEvent, NotifyOp_Replace );
1163             }
1164         }
1165         else
1166             throw NoSuchElementException();
1167     }
1168 }
1169 
removeSettings(const::rtl::OUString & ResourceURL)1170 void UIConfigurationManagerImpl::removeSettings( const ::rtl::OUString& ResourceURL )
1171 throw ( NoSuchElementException, IllegalArgumentException, IllegalAccessException, RuntimeException)
1172 {
1173     sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
1174 
1175     if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
1176         ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT   ))
1177         throw IllegalArgumentException();
1178     else if ( m_bReadOnly )
1179         throw IllegalAccessException();
1180     else
1181     {
1182         ResetableGuard aGuard( m_aLock );
1183 
1184         if ( m_bDisposed )
1185             throw DisposedException();
1186 
1187         UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType );
1188         if ( pDataSettings )
1189         {
1190             // If element settings are default, we don't need to change anything!
1191             if ( pDataSettings->bDefault )
1192                 return;
1193             else
1194             {
1195                 Reference< XIndexAccess > xRemovedSettings = pDataSettings->xSettings;
1196                 pDataSettings->bDefault = true;
1197 
1198                 // check if this is a default layer node
1199                 if ( !m_bUseDefault || !pDataSettings->bDefaultNode )
1200                     pDataSettings->bModified = true; // we have to remove this node from the user layer!
1201                 pDataSettings->xSettings.clear();
1202                 m_bModified = true; // user layer must be written
1203 
1204                 // Modify type container
1205                 UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType];
1206                 rElementType.bModified = true;
1207 
1208                 Reference< XUIConfigurationManager > xThis( m_xOwner, UNO_QUERY );
1209                 // Check if we have settings in the default layer which replaces the user-defined one!
1210                 UIElementData* pDefaultDataSettings = m_bUseDefault ? impl_findUIElementData( ResourceURL, nElementType ) : NULL;
1211                 if ( pDefaultDataSettings )
1212                 {
1213                     // Create event to notify listener about replaced element settings
1214                     ConfigurationEvent aEvent;
1215 
1216                     aEvent.ResourceURL = ResourceURL;
1217                     aEvent.Accessor <<= xThis;
1218                     aEvent.Source = m_xOwner;
1219                     aEvent.Element <<= xRemovedSettings;
1220                     aEvent.ReplacedElement <<= pDefaultDataSettings->xSettings;
1221 
1222                     aGuard.unlock();
1223 
1224                     implts_notifyContainerListener( aEvent, NotifyOp_Replace );
1225                 }
1226                 else
1227                 {
1228                     // Create event to notify listener about removed element settings
1229                     ConfigurationEvent aEvent;
1230 
1231                     aEvent.ResourceURL = ResourceURL;
1232                     aEvent.Accessor <<= xThis;
1233                     aEvent.Source = m_xOwner;
1234                     aEvent.Element <<= xRemovedSettings;
1235 
1236                     aGuard.unlock();
1237 
1238                     implts_notifyContainerListener( aEvent, NotifyOp_Remove );
1239                 }
1240             }
1241         }
1242         else
1243             throw NoSuchElementException();
1244     }
1245 }
1246 
insertSettings(const::rtl::OUString & NewResourceURL,const Reference<XIndexAccess> & aNewData)1247 void UIConfigurationManagerImpl::insertSettings( const ::rtl::OUString& NewResourceURL, const Reference< XIndexAccess >& aNewData )
1248 throw ( ElementExistException, IllegalArgumentException, IllegalAccessException, RuntimeException )
1249 {
1250     sal_Int16 nElementType = RetrieveTypeFromResourceURL( NewResourceURL );
1251 
1252     if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
1253         ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT   ))
1254         throw IllegalArgumentException();
1255     else if ( m_bReadOnly )
1256         throw IllegalAccessException();
1257     else
1258     {
1259         ResetableGuard aGuard( m_aLock );
1260 
1261         if ( m_bDisposed )
1262             throw DisposedException();
1263 
1264         bool           bInsertData( false );
1265         UIElementData aUIElementData;
1266         UIElementData* pDataSettings = impl_findUIElementData( NewResourceURL, nElementType );
1267         if ( !m_bUseDefault )
1268         {
1269             if ( pDataSettings && !pDataSettings->bDefault )
1270                 throw ElementExistException();
1271             if ( !pDataSettings )
1272             {
1273                 pDataSettings = &aUIElementData;
1274                 bInsertData   = true;
1275             }
1276         }
1277         if ( !pDataSettings || !m_bUseDefault )
1278         {
1279             aUIElementData.bDefault     = false;
1280             if ( !m_bUseDefault )
1281                 aUIElementData.bDefaultNode = false;
1282             aUIElementData.bModified    = true;
1283 
1284             // Create a copy of the data if the container is not const
1285             Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY );
1286             if ( xReplace.is() )
1287                 aUIElementData.xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( aNewData ) ), UNO_QUERY );
1288             else
1289                 aUIElementData.xSettings = aNewData;
1290 
1291             m_bModified = true;
1292 
1293             UIElementType& rElementType = m_aUIElements[LAYER_USERDEFINED][nElementType];
1294             rElementType.bModified = true;
1295 
1296             if ( bInsertData )
1297             {
1298                 aUIElementData.aName        = RetrieveNameFromResourceURL( NewResourceURL ) + m_aXMLPostfix;
1299                 aUIElementData.aResourceURL = NewResourceURL;
1300                 UIElementDataHashMap& rElements = rElementType.aElementsHashMap;
1301                 rElements.insert( UIElementDataHashMap::value_type( NewResourceURL, aUIElementData ));
1302             }
1303 
1304             Reference< XIndexAccess > xInsertSettings( aUIElementData.xSettings );
1305             Reference< XUIConfigurationManager > xThis( m_xOwner, UNO_QUERY );
1306 
1307             // Create event to notify listener about removed element settings
1308             ConfigurationEvent aEvent;
1309 
1310             aEvent.ResourceURL = NewResourceURL;
1311             aEvent.Accessor <<= xThis;
1312             aEvent.Source = m_xOwner;
1313             aEvent.Element <<= xInsertSettings;
1314 
1315             aGuard.unlock();
1316 
1317             implts_notifyContainerListener( aEvent, NotifyOp_Insert );
1318         }
1319         else
1320             throw ElementExistException();
1321     }
1322 }
1323 
getImageManager()1324 Reference< XInterface > UIConfigurationManagerImpl::getImageManager() throw (::com::sun::star::uno::RuntimeException)
1325 {
1326     ResetableGuard aGuard( m_aLock );
1327 
1328     if ( m_bDisposed )
1329         throw DisposedException();
1330 
1331     if ( !m_xModuleImageManager.is() )
1332     {
1333         if ( m_bUseDefault )
1334             m_xModuleImageManager = Reference< XComponent >( static_cast< cppu::OWeakObject *>( new ModuleImageManager( m_xServiceManager )),
1335                                                          UNO_QUERY );
1336         else
1337             m_xModuleImageManager = Reference< XComponent >( static_cast< cppu::OWeakObject *>( new ImageManager( m_xServiceManager )),
1338                                                          UNO_QUERY );
1339         Reference< XInitialization > xInit( m_xModuleImageManager, UNO_QUERY );
1340 
1341         Sequence< Any > aPropSeq( m_bUseDefault ? 3 : 2 );
1342         PropertyValue aPropValue;
1343         aPropValue.Name  = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserConfigStorage" ));
1344         aPropValue.Value <<= m_xUserConfigStorage;
1345         aPropSeq[0] <<= aPropValue;
1346         aPropValue.Name  = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleIdentifier" ));
1347         aPropValue.Value <<= m_aModuleIdentifier;
1348         aPropSeq[1] <<= aPropValue;
1349         if ( m_bUseDefault )
1350         {
1351             aPropValue.Name  = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserRootCommit" ));
1352             aPropValue.Value <<= m_xUserRootCommit;
1353             aPropSeq[2] <<= aPropValue;
1354         }
1355 
1356         xInit->initialize( aPropSeq );
1357     }
1358 
1359     return Reference< XInterface >( m_xModuleImageManager, UNO_QUERY );
1360 
1361 //    return Reference< XInterface >();
1362 }
1363 
getShortCutManager()1364 Reference< XInterface > UIConfigurationManagerImpl::getShortCutManager() throw (::com::sun::star::uno::RuntimeException)
1365 {
1366     ResetableGuard aGuard( m_aLock );
1367     if ( !m_bUseDefault && m_xAccConfig.is())
1368         return m_xAccConfig;
1369 
1370     Reference< XMultiServiceFactory > xSMGR   = m_xServiceManager;
1371     ::rtl::OUString                   aModule = m_aModuleIdentifier;
1372     Reference< XStorage >             xDocumentRoot = m_xUserConfigStorage;
1373     aGuard.unlock();
1374     Reference< XInterface >      xManager = xSMGR->createInstance(m_bUseDefault ? SERVICENAME_MODULEACCELERATORCONFIGURATION : SERVICENAME_DOCUMENTACCELERATORCONFIGURATION );
1375     Reference< XInitialization > xInit    (xManager, UNO_QUERY_THROW);
1376 
1377     PropertyValue aProp;
1378     Sequence< Any > lArgs(1);
1379     if ( m_bUseDefault )
1380     {
1381         aProp.Name    = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ModuleIdentifier"));
1382         aProp.Value <<= aModule;
1383     } // if ( m_bUseDefault )
1384     else
1385     {
1386         aProp.Name    = ::rtl::OUString::createFromAscii("DocumentRoot");
1387         aProp.Value <<= xDocumentRoot;
1388     }
1389     lArgs[0] <<= aProp;
1390     xInit->initialize(lArgs);
1391 
1392     if ( !m_bUseDefault )
1393     {
1394         // SAFE ->
1395         aGuard.lock();
1396         m_xAccConfig = xManager;
1397         aGuard.unlock();
1398         // <- SAFE
1399     }
1400 
1401     return xManager;
1402 }
1403 
getEventsManager()1404 Reference< XInterface > UIConfigurationManagerImpl::getEventsManager() throw (::com::sun::star::uno::RuntimeException)
1405 {
1406     return Reference< XInterface >();
1407 }
1408 // XUIConfigurationStorage
setStorage(const Reference<XStorage> & Storage)1409 void UIConfigurationManagerImpl::setStorage( const Reference< XStorage >& Storage ) throw (::com::sun::star::uno::RuntimeException)
1410 {
1411     ResetableGuard aGuard( m_aLock );
1412 
1413     if ( m_bDisposed )
1414         throw DisposedException();
1415 
1416     if ( m_xUserConfigStorage.is() )
1417     {
1418         try
1419         {
1420             // Dispose old storage to be sure that it will be closed
1421             Reference< XComponent > xComponent( m_xUserConfigStorage, UNO_QUERY );
1422             if ( xComponent.is() )
1423                 xComponent->dispose();
1424         }
1425         catch ( Exception& )
1426         {
1427         }
1428     }
1429 
1430     // We store the new storage. Be careful it could be an empty reference!
1431     m_xUserConfigStorage = Storage;
1432     m_bReadOnly         = sal_True;
1433 
1434     Reference< XUIConfigurationStorage > xAccUpdate(m_xAccConfig, UNO_QUERY);
1435     if ( xAccUpdate.is() )
1436         xAccUpdate->setStorage( m_xUserConfigStorage );
1437 
1438     if ( m_xModuleImageManager.is() )
1439     {
1440         ImageManager* pImageManager = (ImageManager*)m_xModuleImageManager.get();
1441         if ( pImageManager )
1442             pImageManager->setStorage( m_xUserConfigStorage );
1443     }
1444 
1445     if ( m_xUserConfigStorage.is() )
1446     {
1447         ::rtl::OUString sEmpty;
1448         for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
1449         {
1450             rtl::OUString aResourceType;
1451             if ( i == ::com::sun::star::ui::UIElementType::MENUBAR )
1452                 aResourceType = PresetHandler::RESOURCETYPE_MENUBAR();
1453             else if ( i == ::com::sun::star::ui::UIElementType::TOOLBAR )
1454                 aResourceType = PresetHandler::RESOURCETYPE_TOOLBAR();
1455             else if ( i == ::com::sun::star::ui::UIElementType::STATUSBAR )
1456                 aResourceType = PresetHandler::RESOURCETYPE_STATUSBAR();
1457 
1458             //if ( aResourceType.getLength() > 0 )
1459             {
1460                 m_pStorageHandler[i] = new PresetHandler( m_xServiceManager );
1461                 m_pStorageHandler[i]->connectToResource( PresetHandler::E_DOCUMENT,
1462                                                          rtl::OUString::createFromAscii( UIELEMENTTYPENAMES[i] ), // this path wont be used later ... seee next lines!
1463                                                          sEmpty,
1464                                                          m_xUserConfigStorage);
1465             }
1466         }
1467         Reference< XPropertySet > xPropSet( m_xUserConfigStorage, UNO_QUERY );
1468         if ( xPropSet.is() )
1469         {
1470             try
1471             {
1472                 long nOpenMode = 0;
1473                 if ( xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenMode" ))) >>= nOpenMode )
1474                     m_bReadOnly = !( nOpenMode & ElementModes::WRITE );
1475             }
1476             catch ( com::sun::star::beans::UnknownPropertyException& )
1477             {
1478             }
1479 			catch ( com::sun::star::lang::WrappedTargetException& )
1480             {
1481             }
1482         }
1483     }
1484 
1485     impl_Initialize();
1486 }
1487 // -----------------------------------------------------------------------------
hasStorage()1488 sal_Bool UIConfigurationManagerImpl::hasStorage() throw (::com::sun::star::uno::RuntimeException)
1489 {
1490     ResetableGuard aGuard( m_aLock );
1491 
1492     if ( m_bDisposed )
1493         throw DisposedException();
1494 
1495     return ( m_xUserConfigStorage.is() );
1496 }
1497 
1498 // XUIConfigurationManagerImpl
isDefaultSettings(const::rtl::OUString & ResourceURL)1499 sal_Bool UIConfigurationManagerImpl::isDefaultSettings( const ::rtl::OUString& ResourceURL )
1500 throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
1501 {
1502     sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
1503 
1504     if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
1505         ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT   ))
1506         throw IllegalArgumentException();
1507     else
1508     {
1509         ResetableGuard aGuard( m_aLock );
1510 
1511         if ( m_bDisposed )
1512             throw DisposedException();
1513 
1514         UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType, false );
1515         if ( pDataSettings && pDataSettings->bDefaultNode )
1516             return sal_True;
1517     }
1518 
1519     return sal_False;
1520 }
1521 
getDefaultSettings(const::rtl::OUString & ResourceURL)1522 Reference< XIndexAccess > UIConfigurationManagerImpl::getDefaultSettings( const ::rtl::OUString& ResourceURL )
1523 throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
1524 {
1525     sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL );
1526 
1527     if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) ||
1528         ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT   ))
1529         throw IllegalArgumentException();
1530     else
1531     {
1532         ResetableGuard aGuard( m_aLock );
1533 
1534         if ( m_bDisposed )
1535             throw DisposedException();
1536 
1537         // preload list of element types on demand
1538         impl_preloadUIElementTypeList( LAYER_DEFAULT, nElementType );
1539 
1540         // Look into our default vector/hash_map combination
1541         UIElementDataHashMap& rDefaultHashMap = m_aUIElements[LAYER_DEFAULT][nElementType].aElementsHashMap;
1542         UIElementDataHashMap::iterator pIter = rDefaultHashMap.find( ResourceURL );
1543         if ( pIter != rDefaultHashMap.end() )
1544         {
1545             if ( !pIter->second.xSettings.is() )
1546                 impl_requestUIElementData( nElementType, LAYER_DEFAULT, pIter->second );
1547             return pIter->second.xSettings;
1548         }
1549     }
1550 
1551     // Nothing has been found!
1552     throw NoSuchElementException();
1553 }
1554 
1555 // XUIConfigurationPersistence
reload()1556 void UIConfigurationManagerImpl::reload() throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
1557 {
1558     ResetableGuard aGuard( m_aLock );
1559 
1560     if ( m_bDisposed )
1561         throw DisposedException();
1562 
1563     if ( m_xUserConfigStorage.is() && m_bModified && !m_bReadOnly )
1564     {
1565         // Try to access our module sub folder
1566         ConfigEventNotifyContainer aRemoveNotifyContainer;
1567         ConfigEventNotifyContainer aReplaceNotifyContainer;
1568         for ( sal_Int16 i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
1569         {
1570             try
1571             {
1572                 UIElementType& rUserElementType    = m_aUIElements[LAYER_USERDEFINED][i];
1573                 UIElementType& rDefaultElementType = m_aUIElements[LAYER_DEFAULT][i];
1574 
1575                 if ( rUserElementType.bModified )
1576                     impl_reloadElementTypeData( rUserElementType, rDefaultElementType, aRemoveNotifyContainer, aReplaceNotifyContainer );
1577             }
1578             catch ( Exception& )
1579             {
1580                 throw IOException();
1581             }
1582         }
1583 
1584         m_bModified = sal_False;
1585 
1586         // Unlock mutex before notify our listeners
1587         aGuard.unlock();
1588 
1589         // Notify our listeners
1590         ::std::for_each(aRemoveNotifyContainer.begin(),aRemoveNotifyContainer.end(),::boost::bind(&UIConfigurationManagerImpl::implts_notifyContainerListener,this,_1,NotifyOp_Remove));
1591         ::std::for_each(aReplaceNotifyContainer.begin(),aReplaceNotifyContainer.end(),::boost::bind(&UIConfigurationManagerImpl::implts_notifyContainerListener,this,_1,NotifyOp_Replace));
1592     }
1593 }
1594 
store()1595 void UIConfigurationManagerImpl::store() throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
1596 {
1597     ResetableGuard aGuard( m_aLock );
1598 
1599     if ( m_bDisposed )
1600         throw DisposedException();
1601 
1602     if ( m_xUserConfigStorage.is() && m_bModified && !m_bReadOnly )
1603     {
1604         // Try to access our module sub folder
1605         for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
1606         {
1607             try
1608             {
1609                 UIElementType&        rElementType = m_aUIElements[LAYER_USERDEFINED][i];
1610                 Reference< XStorage > xStorage( rElementType.xStorage, UNO_QUERY );
1611 
1612                 if ( rElementType.bModified && xStorage.is() )
1613                 {
1614                     impl_storeElementTypeData( xStorage, rElementType );
1615                     m_pStorageHandler[i]->commitUserChanges();
1616                 }
1617             }
1618             catch ( Exception& )
1619             {
1620                 throw IOException();
1621             }
1622         }
1623 
1624         m_bModified = false;
1625     }
1626 }
1627 
storeToStorage(const Reference<XStorage> & Storage)1628 void UIConfigurationManagerImpl::storeToStorage( const Reference< XStorage >& Storage ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
1629 {
1630     ResetableGuard aGuard( m_aLock );
1631 
1632     if ( m_bDisposed )
1633         throw DisposedException();
1634 
1635     if ( m_xUserConfigStorage.is() && m_bModified && !m_bReadOnly )
1636     {
1637         // Try to access our module sub folder
1638         for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ )
1639         {
1640             try
1641             {
1642                 Reference< XStorage > xElementTypeStorage( Storage->openStorageElement(
1643                                                             rtl::OUString::createFromAscii( UIELEMENTTYPENAMES[i] ), ElementModes::READWRITE ));
1644                 UIElementType&        rElementType = m_aUIElements[LAYER_USERDEFINED][i];
1645 
1646                 if ( rElementType.bModified && xElementTypeStorage.is() )
1647                     impl_storeElementTypeData( xElementTypeStorage, rElementType, false ); // store data to storage, but don't reset modify flag!
1648             }
1649             catch ( Exception& )
1650             {
1651                 throw IOException();
1652             }
1653         }
1654 
1655         Reference< XTransactedObject > xTransactedObject( Storage, UNO_QUERY );
1656 		if ( xTransactedObject.is() )
1657         	xTransactedObject->commit();
1658     }
1659 }
1660 
isModified()1661 sal_Bool UIConfigurationManagerImpl::isModified() throw (::com::sun::star::uno::RuntimeException)
1662 {
1663     ResetableGuard aGuard( m_aLock );
1664 
1665     return m_bModified;
1666 }
1667 
isReadOnly()1668 sal_Bool UIConfigurationManagerImpl::isReadOnly() throw (::com::sun::star::uno::RuntimeException)
1669 {
1670     ResetableGuard aGuard( m_aLock );
1671 
1672     return m_bReadOnly;
1673 }
1674 
implts_notifyContainerListener(const ConfigurationEvent & aEvent,NotifyOp eOp)1675 void UIConfigurationManagerImpl::implts_notifyContainerListener( const ConfigurationEvent& aEvent, NotifyOp eOp )
1676 {
1677     ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( ::getCppuType( ( const css::uno::Reference< ::com::sun::star::ui::XUIConfigurationListener >*) NULL ) );
1678     if ( pContainer != NULL )
1679 	{
1680         ::cppu::OInterfaceIteratorHelper pIterator( *pContainer );
1681         while ( pIterator.hasMoreElements() )
1682         {
1683             try
1684             {
1685                 switch ( eOp )
1686                 {
1687                     case NotifyOp_Replace:
1688                         ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementReplaced( aEvent );
1689                         break;
1690                     case NotifyOp_Insert:
1691                         ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementInserted( aEvent );
1692                         break;
1693                     case NotifyOp_Remove:
1694                         ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementRemoved( aEvent );
1695                         break;
1696                 }
1697             }
1698             catch( css::uno::RuntimeException& )
1699             {
1700                 pIterator.remove();
1701             }
1702         }
1703 	}
1704 }
1705 
1706 } // namespace framework
1707