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