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() throw (::com::sun::star::uno::RuntimeException) 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 ) throw (::com::sun::star::uno::RuntimeException) 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 ) throw (::com::sun::star::uno::RuntimeException) 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 ) throw (::com::sun::star::uno::RuntimeException) 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 ) throw (::com::sun::star::uno::RuntimeException) 680 { 681 /* SAFE AREA ----------------------------------------------------------------------------------------------- */ 682 m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XUIConfigurationListener >* ) NULL ), xListener ); 683 } 684 685 686 void SAL_CALL UIConfigurationManager::reset() throw (::com::sun::star::uno::RuntimeException) 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 throw ( IllegalArgumentException, RuntimeException ) 776 { 777 if (( ElementType < 0 ) || ( ElementType >= ::com::sun::star::ui::UIElementType::COUNT )) 778 throw IllegalArgumentException(); 779 780 ResetableGuard aGuard( m_aLock ); 781 if ( m_bDisposed ) 782 throw DisposedException(); 783 784 Sequence< Sequence< PropertyValue > > aElementInfoSeq; 785 UIElementInfoHashMap aUIElementInfoCollection; 786 787 if ( ElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) 788 { 789 for ( sal_Int16 i = 0; i < ::com::sun::star::ui::UIElementType::COUNT; i++ ) 790 impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection, sal_Int16( i ) ); 791 } 792 else 793 impl_fillSequenceWithElementTypeInfo( aUIElementInfoCollection, ElementType ); 794 795 Sequence< PropertyValue > aUIElementInfo( 2 ); 796 aUIElementInfo[0].Name = m_aPropResourceURL; 797 aUIElementInfo[1].Name = m_aPropUIName; 798 799 aElementInfoSeq.realloc( aUIElementInfoCollection.size() ); 800 UIElementInfoHashMap::const_iterator pIter = aUIElementInfoCollection.begin(); 801 802 sal_Int32 n = 0; 803 while ( pIter != aUIElementInfoCollection.end() ) 804 { 805 aUIElementInfo[0].Value <<= pIter->second.aResourceURL; 806 aUIElementInfo[1].Value <<= pIter->second.aUIName; 807 aElementInfoSeq[n++] = aUIElementInfo; 808 ++pIter; 809 } 810 811 return aElementInfoSeq; 812 } 813 814 Reference< XIndexContainer > SAL_CALL UIConfigurationManager::createSettings() throw (::com::sun::star::uno::RuntimeException) 815 { 816 ResetableGuard aGuard( m_aLock ); 817 818 if ( m_bDisposed ) 819 throw DisposedException(); 820 821 // Creates an empty item container which can be filled from outside 822 return Reference< XIndexContainer >( static_cast< OWeakObject * >( new RootItemContainer()), UNO_QUERY ); 823 } 824 825 sal_Bool SAL_CALL UIConfigurationManager::hasSettings( const ::rtl::OUString& ResourceURL ) 826 throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) 827 { 828 sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL ); 829 830 if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) || 831 ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT )) 832 throw IllegalArgumentException(); 833 else 834 { 835 UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType, false ); 836 if ( pDataSettings && !pDataSettings->bDefault ) 837 return sal_True; 838 } 839 840 return sal_False; 841 } 842 843 Reference< XIndexAccess > SAL_CALL UIConfigurationManager::getSettings( const ::rtl::OUString& ResourceURL, sal_Bool bWriteable ) 844 throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) 845 { 846 sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL ); 847 848 if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) || 849 ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT )) 850 throw IllegalArgumentException(); 851 else 852 { 853 ResetableGuard aGuard( m_aLock ); 854 855 if ( m_bDisposed ) 856 throw DisposedException(); 857 858 UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType ); 859 if ( pDataSettings && !pDataSettings->bDefault ) 860 { 861 // Create a copy of our data if someone wants to change the data. 862 if ( bWriteable ) 863 return Reference< XIndexAccess >( static_cast< OWeakObject * >( new RootItemContainer( pDataSettings->xSettings ) ), UNO_QUERY ); 864 else 865 return pDataSettings->xSettings; 866 } 867 } 868 869 throw NoSuchElementException(); 870 } 871 872 void SAL_CALL UIConfigurationManager::replaceSettings( const ::rtl::OUString& ResourceURL, const Reference< ::com::sun::star::container::XIndexAccess >& aNewData ) 873 throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException) 874 { 875 sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL ); 876 877 if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) || 878 ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT )) 879 throw IllegalArgumentException(); 880 else if ( m_bReadOnly ) 881 throw IllegalAccessException(); 882 else 883 { 884 ResetableGuard aGuard( m_aLock ); 885 886 if ( m_bDisposed ) 887 throw DisposedException(); 888 889 UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType ); 890 if ( pDataSettings && !pDataSettings->bDefault ) 891 { 892 // we have a settings entry in our user-defined layer - replace 893 Reference< XIndexAccess > xOldSettings = pDataSettings->xSettings; 894 895 // Create a copy of the data if the container is not const 896 Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY ); 897 if ( xReplace.is() ) 898 pDataSettings->xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( aNewData ) ), UNO_QUERY ); 899 else 900 pDataSettings->xSettings = aNewData; 901 902 pDataSettings->bDefault = false; 903 pDataSettings->bModified = true; 904 m_bModified = true; 905 906 // Modify type container 907 UIElementType& rElementType = m_aUIElements[nElementType]; 908 rElementType.bModified = true; 909 910 Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY ); 911 912 // Create event to notify listener about replaced element settings 913 ConfigurationEvent aEvent; 914 Reference< XInterface > xIfac( xThis, UNO_QUERY ); 915 916 aEvent.ResourceURL = ResourceURL; 917 aEvent.Accessor <<= xThis; 918 aEvent.Source = xIfac; 919 aEvent.ReplacedElement <<= xOldSettings; 920 aEvent.Element <<= pDataSettings->xSettings; 921 922 aGuard.unlock(); 923 924 implts_notifyContainerListener( aEvent, NotifyOp_Replace ); 925 } 926 else 927 throw NoSuchElementException(); 928 } 929 } 930 931 void SAL_CALL UIConfigurationManager::removeSettings( const ::rtl::OUString& ResourceURL ) 932 throw ( NoSuchElementException, IllegalArgumentException, IllegalAccessException, RuntimeException) 933 { 934 sal_Int16 nElementType = RetrieveTypeFromResourceURL( ResourceURL ); 935 936 if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) || 937 ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT )) 938 throw IllegalArgumentException(); 939 else if ( m_bReadOnly ) 940 throw IllegalAccessException(); 941 else 942 { 943 ResetableGuard aGuard( m_aLock ); 944 945 if ( m_bDisposed ) 946 throw DisposedException(); 947 948 UIElementData* pDataSettings = impl_findUIElementData( ResourceURL, nElementType ); 949 if ( pDataSettings ) 950 { 951 // If element settings are default, we don't need to change anything! 952 if ( pDataSettings->bDefault ) 953 return; 954 else 955 { 956 Reference< XIndexAccess > xRemovedSettings = pDataSettings->xSettings; 957 pDataSettings->bDefault = true; 958 959 // check if this is a default layer node 960 pDataSettings->bModified = true; // we have to remove this node from the user layer! 961 pDataSettings->xSettings.clear(); 962 m_bModified = true; // user layer must be written 963 964 // Modify type container 965 UIElementType& rElementType = m_aUIElements[nElementType]; 966 rElementType.bModified = true; 967 968 Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY ); 969 Reference< XInterface > xIfac( xThis, UNO_QUERY ); 970 971 // Create event to notify listener about removed element settings 972 ConfigurationEvent aEvent; 973 974 aEvent.ResourceURL = ResourceURL; 975 aEvent.Accessor <<= xThis; 976 aEvent.Source = xIfac; 977 aEvent.Element <<= xRemovedSettings; 978 979 aGuard.unlock(); 980 981 implts_notifyContainerListener( aEvent, NotifyOp_Remove ); 982 } 983 } 984 else 985 throw NoSuchElementException(); 986 } 987 } 988 989 void SAL_CALL UIConfigurationManager::insertSettings( const ::rtl::OUString& NewResourceURL, const Reference< XIndexAccess >& aNewData ) 990 throw ( ElementExistException, IllegalArgumentException, IllegalAccessException, RuntimeException ) 991 { 992 sal_Int16 nElementType = RetrieveTypeFromResourceURL( NewResourceURL ); 993 994 if (( nElementType == ::com::sun::star::ui::UIElementType::UNKNOWN ) || 995 ( nElementType >= ::com::sun::star::ui::UIElementType::COUNT )) 996 throw IllegalArgumentException(); 997 else if ( m_bReadOnly ) 998 throw IllegalAccessException(); 999 else 1000 { 1001 ResetableGuard aGuard( m_aLock ); 1002 1003 if ( m_bDisposed ) 1004 throw DisposedException(); 1005 1006 bool bInsertData( false ); 1007 UIElementData aUIElementData; 1008 UIElementData* pDataSettings = impl_findUIElementData( NewResourceURL, nElementType ); 1009 1010 if ( pDataSettings && !pDataSettings->bDefault ) 1011 throw ElementExistException(); 1012 1013 if ( !pDataSettings ) 1014 { 1015 pDataSettings = &aUIElementData; 1016 bInsertData = true; 1017 } 1018 1019 { 1020 pDataSettings->bDefault = false; 1021 pDataSettings->bModified = true; 1022 1023 // Create a copy of the data if the container is not const 1024 Reference< XIndexReplace > xReplace( aNewData, UNO_QUERY ); 1025 if ( xReplace.is() ) 1026 pDataSettings->xSettings = Reference< XIndexAccess >( static_cast< OWeakObject * >( new ConstItemContainer( aNewData ) ), UNO_QUERY ); 1027 else 1028 pDataSettings->xSettings = aNewData; 1029 1030 m_bModified = true; 1031 1032 UIElementType& rElementType = m_aUIElements[nElementType]; 1033 rElementType.bModified = true; 1034 1035 if ( bInsertData ) 1036 { 1037 pDataSettings->aName = RetrieveNameFromResourceURL( NewResourceURL ) + m_aXMLPostfix; 1038 pDataSettings->aResourceURL = NewResourceURL; 1039 1040 UIElementDataHashMap& rElements = rElementType.aElementsHashMap; 1041 rElements.insert( UIElementDataHashMap::value_type( NewResourceURL, *pDataSettings )); 1042 } 1043 1044 Reference< XIndexAccess > xInsertSettings( aUIElementData.xSettings ); 1045 Reference< XUIConfigurationManager > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY ); 1046 Reference< XInterface > xIfac( xThis, UNO_QUERY ); 1047 1048 // Create event to notify listener about removed element settings 1049 ConfigurationEvent aEvent; 1050 1051 aEvent.ResourceURL = NewResourceURL; 1052 aEvent.Accessor <<= xThis; 1053 aEvent.Source = xIfac; 1054 aEvent.Element <<= xInsertSettings; 1055 1056 aGuard.unlock(); 1057 1058 implts_notifyContainerListener( aEvent, NotifyOp_Insert ); 1059 } 1060 } 1061 } 1062 1063 Reference< XInterface > SAL_CALL UIConfigurationManager::getImageManager() throw (::com::sun::star::uno::RuntimeException) 1064 { 1065 if ( m_bDisposed ) 1066 throw DisposedException(); 1067 1068 if ( !m_xImageManager.is() ) 1069 { 1070 m_xImageManager = Reference< XComponent >( static_cast< cppu::OWeakObject *>( new ImageManager( m_xServiceManager )), 1071 UNO_QUERY ); 1072 Reference< XInitialization > xInit( m_xImageManager, UNO_QUERY ); 1073 1074 Sequence< Any > aPropSeq( 2 ); 1075 PropertyValue aPropValue; 1076 aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserConfigStorage" )); 1077 aPropValue.Value = makeAny( m_xDocConfigStorage ); 1078 aPropSeq[0] = makeAny( aPropValue ); 1079 aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleIdentifier" )); 1080 aPropValue.Value = makeAny( m_aModuleIdentifier ); 1081 aPropSeq[1] = makeAny( aPropValue ); 1082 1083 xInit->initialize( aPropSeq ); 1084 } 1085 1086 return Reference< XInterface >( m_xImageManager, UNO_QUERY ); 1087 } 1088 1089 Reference< XInterface > SAL_CALL UIConfigurationManager::getShortCutManager() throw (::com::sun::star::uno::RuntimeException) 1090 { 1091 // SAFE -> 1092 ResetableGuard aGuard( m_aLock ); 1093 1094 if (m_xAccConfig.is()) 1095 return m_xAccConfig; 1096 1097 Reference< XMultiServiceFactory > xSMGR = m_xServiceManager; 1098 Reference< XStorage > xDocumentRoot = m_xDocConfigStorage; 1099 1100 aGuard.unlock(); 1101 // <- SAFE 1102 1103 Reference< XInterface > xAccConfig = xSMGR->createInstance(SERVICENAME_DOCUMENTACCELERATORCONFIGURATION); 1104 Reference< XInitialization > xInit (xAccConfig, UNO_QUERY_THROW); 1105 1106 PropertyValue aProp; 1107 aProp.Name = ::rtl::OUString::createFromAscii("DocumentRoot"); 1108 aProp.Value <<= xDocumentRoot; 1109 1110 Sequence< Any > lArgs(1); 1111 lArgs[0] <<= aProp; 1112 1113 xInit->initialize(lArgs); 1114 1115 // SAFE -> 1116 aGuard.lock(); 1117 m_xAccConfig = xAccConfig; 1118 aGuard.unlock(); 1119 // <- SAFE 1120 1121 return xAccConfig; 1122 } 1123 1124 Reference< XInterface > SAL_CALL UIConfigurationManager::getEventsManager() throw (::com::sun::star::uno::RuntimeException) 1125 { 1126 return Reference< XInterface >(); 1127 } 1128 1129 // XUIConfigurationStorage 1130 void SAL_CALL UIConfigurationManager::setStorage( const Reference< XStorage >& Storage ) throw (::com::sun::star::uno::RuntimeException) 1131 { 1132 ResetableGuard aGuard( m_aLock ); 1133 1134 if ( m_bDisposed ) 1135 throw DisposedException(); 1136 1137 if ( m_xDocConfigStorage.is() ) 1138 { 1139 try 1140 { 1141 // Dispose old storage to be sure that it will be closed 1142 Reference< XComponent > xComponent( m_xDocConfigStorage, UNO_QUERY ); 1143 if ( xComponent.is() ) 1144 xComponent->dispose(); 1145 } 1146 catch ( Exception& ) 1147 { 1148 } 1149 } 1150 1151 // We store the new storage. Be careful it could be an empty reference! 1152 m_xDocConfigStorage = Storage; 1153 m_bReadOnly = sal_True; 1154 1155 Reference< XUIConfigurationStorage > xAccUpdate(m_xAccConfig, UNO_QUERY); 1156 if ( xAccUpdate.is() ) 1157 xAccUpdate->setStorage( m_xDocConfigStorage ); 1158 1159 if ( m_xImageManager.is() ) 1160 { 1161 ImageManager* pImageManager = (ImageManager*)m_xImageManager.get(); 1162 if ( pImageManager ) 1163 pImageManager->setStorage( m_xDocConfigStorage ); 1164 } 1165 1166 if ( m_xDocConfigStorage.is() ) 1167 { 1168 Reference< XPropertySet > xPropSet( m_xDocConfigStorage, UNO_QUERY ); 1169 if ( xPropSet.is() ) 1170 { 1171 try 1172 { 1173 long nOpenMode = 0; 1174 Any a = xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OpenMode" ))); 1175 if ( a >>= nOpenMode ) 1176 m_bReadOnly = !( nOpenMode & ElementModes::WRITE ); 1177 } 1178 catch ( com::sun::star::beans::UnknownPropertyException& ) 1179 { 1180 } 1181 catch ( com::sun::star::lang::WrappedTargetException& ) 1182 { 1183 } 1184 } 1185 } 1186 1187 impl_Initialize(); 1188 } 1189 1190 sal_Bool SAL_CALL UIConfigurationManager::hasStorage() throw (::com::sun::star::uno::RuntimeException) 1191 { 1192 ResetableGuard aGuard( m_aLock ); 1193 1194 if ( m_bDisposed ) 1195 throw DisposedException(); 1196 1197 return ( m_xDocConfigStorage.is() ); 1198 } 1199 1200 // XUIConfigurationPersistence 1201 void SAL_CALL UIConfigurationManager::reload() throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) 1202 { 1203 ResetableGuard aGuard( m_aLock ); 1204 1205 if ( m_bDisposed ) 1206 throw DisposedException(); 1207 1208 if ( m_xDocConfigStorage.is() && m_bModified && !m_bReadOnly ) 1209 { 1210 // Try to access our module sub folder 1211 ConfigEventNotifyContainer aRemoveNotifyContainer; 1212 ConfigEventNotifyContainer aReplaceNotifyContainer; 1213 for ( sal_Int16 i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ ) 1214 { 1215 try 1216 { 1217 UIElementType& rDocElementType = m_aUIElements[i]; 1218 if ( rDocElementType.bModified ) 1219 impl_reloadElementTypeData( rDocElementType, aRemoveNotifyContainer, aReplaceNotifyContainer ); 1220 } 1221 catch ( Exception& ) 1222 { 1223 throw IOException(); 1224 } 1225 } 1226 1227 m_bModified = sal_False; 1228 1229 // Unlock mutex before notify our listeners 1230 aGuard.unlock(); 1231 1232 // Notify our listeners 1233 for ( sal_uInt32 j = 0; j < aRemoveNotifyContainer.size(); j++ ) 1234 implts_notifyContainerListener( aRemoveNotifyContainer[j], NotifyOp_Remove ); 1235 for ( sal_uInt32 k = 0; k < aReplaceNotifyContainer.size(); k++ ) 1236 implts_notifyContainerListener( aReplaceNotifyContainer[k], NotifyOp_Replace ); 1237 } 1238 } 1239 1240 void SAL_CALL UIConfigurationManager::store() throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) 1241 { 1242 ResetableGuard aGuard( m_aLock ); 1243 1244 if ( m_bDisposed ) 1245 throw DisposedException(); 1246 1247 if ( m_xDocConfigStorage.is() && m_bModified && !m_bReadOnly ) 1248 { 1249 // Try to access our module sub folder 1250 for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ ) 1251 { 1252 try 1253 { 1254 UIElementType& rElementType = m_aUIElements[i]; 1255 Reference< XStorage > xStorage( rElementType.xStorage, UNO_QUERY ); 1256 1257 if ( rElementType.bModified && xStorage.is() ) 1258 impl_storeElementTypeData( xStorage, rElementType ); 1259 } 1260 catch ( Exception& ) 1261 { 1262 throw IOException(); 1263 } 1264 } 1265 1266 m_bModified = false; 1267 Reference< XTransactedObject > xTransactedObject( m_xDocConfigStorage, UNO_QUERY ); 1268 if ( xTransactedObject.is() ) 1269 xTransactedObject->commit(); 1270 } 1271 } 1272 1273 void SAL_CALL UIConfigurationManager::storeToStorage( const Reference< XStorage >& Storage ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException) 1274 { 1275 ResetableGuard aGuard( m_aLock ); 1276 1277 if ( m_bDisposed ) 1278 throw DisposedException(); 1279 1280 if ( m_xDocConfigStorage.is() && m_bModified && !m_bReadOnly ) 1281 { 1282 // Try to access our module sub folder 1283 for ( int i = 1; i < ::com::sun::star::ui::UIElementType::COUNT; i++ ) 1284 { 1285 try 1286 { 1287 Reference< XStorage > xElementTypeStorage( Storage->openStorageElement( 1288 rtl::OUString::createFromAscii( UIELEMENTTYPENAMES[i] ), ElementModes::READWRITE )); 1289 UIElementType& rElementType = m_aUIElements[i]; 1290 1291 if ( rElementType.bModified && xElementTypeStorage.is() ) 1292 impl_storeElementTypeData( xElementTypeStorage, rElementType, false ); // store data to storage, but don't reset modify flag! 1293 } 1294 catch ( Exception& ) 1295 { 1296 throw IOException(); 1297 } 1298 } 1299 1300 Reference< XTransactedObject > xTransactedObject( Storage, UNO_QUERY ); 1301 if ( xTransactedObject.is() ) 1302 xTransactedObject->commit(); 1303 } 1304 } 1305 1306 sal_Bool SAL_CALL UIConfigurationManager::isModified() throw (::com::sun::star::uno::RuntimeException) 1307 { 1308 ResetableGuard aGuard( m_aLock ); 1309 1310 return m_bModified; 1311 } 1312 1313 sal_Bool SAL_CALL UIConfigurationManager::isReadOnly() throw (::com::sun::star::uno::RuntimeException) 1314 { 1315 ResetableGuard aGuard( m_aLock ); 1316 1317 return m_bReadOnly; 1318 } 1319 1320 void UIConfigurationManager::implts_notifyContainerListener( const ConfigurationEvent& aEvent, NotifyOp eOp ) 1321 { 1322 ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( ::getCppuType( ( const css::uno::Reference< ::com::sun::star::ui::XUIConfigurationListener >*) NULL ) ); 1323 if ( pContainer != NULL ) 1324 { 1325 ::cppu::OInterfaceIteratorHelper pIterator( *pContainer ); 1326 while ( pIterator.hasMoreElements() ) 1327 { 1328 try 1329 { 1330 switch ( eOp ) 1331 { 1332 case NotifyOp_Replace: 1333 ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementReplaced( aEvent ); 1334 break; 1335 case NotifyOp_Insert: 1336 ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementInserted( aEvent ); 1337 break; 1338 case NotifyOp_Remove: 1339 ((::com::sun::star::ui::XUIConfigurationListener*)pIterator.next())->elementRemoved( aEvent ); 1340 break; 1341 } 1342 } 1343 catch( css::uno::RuntimeException& ) 1344 { 1345 pIterator.remove(); 1346 } 1347 } 1348 } 1349 } 1350 1351 } // namespace framework 1352