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