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() 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 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 ) 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 won't be used later ... see 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