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 27 //_________________________________________________________________________________________________________________ 28 // my own includes 29 //_________________________________________________________________________________________________________________ 30 #include "uielement/uicommanddescription.hxx" 31 #include <threadhelp/resetableguard.hxx> 32 #include "services.h" 33 34 #include "properties.h" 35 36 //_________________________________________________________________________________________________________________ 37 // interface includes 38 //_________________________________________________________________________________________________________________ 39 #include <com/sun/star/beans/PropertyValue.hpp> 40 #include <com/sun/star/beans/XPropertySet.hpp> 41 #include <com/sun/star/container/XNameAccess.hpp> 42 #include <com/sun/star/container/XNameContainer.hpp> 43 #include <com/sun/star/container/XContainer.hpp> 44 45 //_________________________________________________________________________________________________________________ 46 // includes of other projects 47 //_________________________________________________________________________________________________________________ 48 #include <rtl/ustrbuf.hxx> 49 #include <cppuhelper/implbase2.hxx> 50 #include <unotools/configmgr.hxx> 51 #include <tools/string.hxx> 52 53 #ifndef _VCL_MNEMONIC_HXX_ 54 #include <vcl/mnemonic.hxx> 55 #endif 56 #include <comphelper/sequence.hxx> 57 #include <rtl/logfile.hxx> 58 59 //_________________________________________________________________________________________________________________ 60 // Defines 61 //_________________________________________________________________________________________________________________ 62 // 63 64 using namespace com::sun::star::uno; 65 using namespace com::sun::star::lang; 66 using namespace com::sun::star::beans; 67 using namespace com::sun::star::container; 68 using namespace ::com::sun::star::frame; 69 70 //_________________________________________________________________________________________________________________ 71 // Namespace 72 //_________________________________________________________________________________________________________________ 73 // 74 75 struct ModuleToCommands 76 { 77 const char* pModuleId; 78 const char* pCommands; 79 }; 80 81 static const char GENERIC_UICOMMANDS[] = "generic"; 82 static const char COMMANDS[] = "Commands"; 83 static const char CONFIGURATION_ROOT_ACCESS[] = "/org.openoffice.Office.UI."; 84 static const char CONFIGURATION_CMD_ELEMENT_ACCESS[] = "/UserInterface/Commands"; 85 static const char CONFIGURATION_POP_ELEMENT_ACCESS[] = "/UserInterface/Popups"; 86 static const char CONFIGURATION_PROPERTY_LABEL[] = "Label"; 87 static const char CONFIGURATION_PROPERTY_CONTEXT_LABEL[] = "ContextLabel"; 88 89 // Property names of the resulting Property Set 90 static const char PROPSET_LABEL[] = "Label"; 91 static const char PROPSET_NAME[] = "Name"; 92 static const char PROPSET_POPUP[] = "Popup"; 93 static const char PROPSET_PROPERTIES[] = "Properties"; 94 95 // Special resource URLs to retrieve additional information 96 static const char PRIVATE_RESOURCE_URL[] = "private:"; 97 98 const sal_Int32 COMMAND_PROPERTY_IMAGE = 1; 99 const sal_Int32 COMMAND_PROPERTY_ROTATE = 2; 100 const sal_Int32 COMMAND_PROPERTY_MIRROR = 4; 101 102 namespace framework 103 { 104 105 //***************************************************************************************************************** 106 // Configuration access class for PopupMenuControllerFactory implementation 107 //***************************************************************************************************************** 108 109 class ConfigurationAccess_UICommand : // Order is necessary for right initialization! 110 private ThreadHelpBase , 111 public ::cppu::WeakImplHelper2<XNameAccess,XContainerListener> 112 { 113 public: 114 ConfigurationAccess_UICommand( const ::rtl::OUString& aModuleName, const Reference< XNameAccess >& xGenericUICommands, const Reference< XMultiServiceFactory >& rServiceManager ); 115 virtual ~ConfigurationAccess_UICommand(); 116 117 // XNameAccess 118 virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ); 119 120 virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames(); 121 122 virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ); 123 124 // XElementAccess 125 virtual ::com::sun::star::uno::Type SAL_CALL getElementType(); 126 127 virtual sal_Bool SAL_CALL hasElements(); 128 129 // container.XContainerListener 130 virtual void SAL_CALL elementInserted( const ContainerEvent& aEvent ); 131 virtual void SAL_CALL elementRemoved ( const ContainerEvent& aEvent ); 132 virtual void SAL_CALL elementReplaced( const ContainerEvent& aEvent ); 133 134 // lang.XEventListener 135 virtual void SAL_CALL disposing( const EventObject& aEvent ); 136 137 protected: 138 virtual ::com::sun::star::uno::Any SAL_CALL getByNameImpl( const ::rtl::OUString& aName ); 139 140 struct CmdToInfoMap 141 { 142 CmdToInfoMap() : bPopup( false ), 143 bCommandNameCreated( false ), 144 nProperties( 0 ) {} 145 146 rtl::OUString aLabel; 147 rtl::OUString aContextLabel; 148 rtl::OUString aCommandName; 149 bool bPopup : 1, 150 bCommandNameCreated : 1; 151 sal_Int32 nProperties; 152 }; 153 154 Any getSequenceFromCache( const rtl::OUString& aCommandURL ); 155 Any getInfoFromCommand( const rtl::OUString& rCommandURL ); 156 void fillInfoFromResult( CmdToInfoMap& rCmdInfo, const rtl::OUString& aLabel ); 157 Any getUILabelFromCommand( const rtl::OUString& rCommandURL ); 158 Sequence< rtl::OUString > getAllCommands(); 159 sal_Bool fillCache(); 160 sal_Bool addGenericInfoToCache(); 161 void impl_fill(const Reference< XNameAccess >& _xConfigAccess,sal_Bool _bPopup, 162 std::vector< ::rtl::OUString >& aImageCommandVector, 163 std::vector< ::rtl::OUString >& aImageRotateVector, 164 std::vector< ::rtl::OUString >& aImageMirrorVector); 165 166 private: 167 typedef ::std::hash_map< ::rtl::OUString, 168 CmdToInfoMap, 169 rtl::OUStringHash, 170 ::std::equal_to< ::rtl::OUString > > CommandToInfoCache; 171 172 sal_Bool initializeConfigAccess(); 173 174 rtl::OUString m_aConfigCmdAccess; 175 rtl::OUString m_aConfigPopupAccess; 176 rtl::OUString m_aPropUILabel; 177 rtl::OUString m_aPropUIContextLabel; 178 rtl::OUString m_aPropLabel; 179 rtl::OUString m_aPropName; 180 rtl::OUString m_aPropPopup; 181 rtl::OUString m_aPropProperties; 182 rtl::OUString m_aBrandName; 183 rtl::OUString m_aXMLFileFormatVersion; 184 rtl::OUString m_aVersion; 185 rtl::OUString m_aExtension; 186 rtl::OUString m_aPrivateResourceURL; 187 Reference< XNameAccess > m_xGenericUICommands; 188 Reference< XMultiServiceFactory > m_xServiceManager; 189 Reference< XMultiServiceFactory > m_xConfigProvider; 190 //Reference< XMultiServiceFactory > m_xConfigProviderPopups; 191 Reference< XNameAccess > m_xConfigAccess; 192 Reference< XNameAccess > m_xConfigAccessPopups; 193 Sequence< rtl::OUString > m_aCommandImageList; 194 Sequence< rtl::OUString > m_aCommandRotateImageList; 195 Sequence< rtl::OUString > m_aCommandMirrorImageList; 196 CommandToInfoCache m_aCmdInfoCache; 197 sal_Bool m_bConfigAccessInitialized; 198 sal_Bool m_bCacheFilled; 199 sal_Bool m_bGenericDataRetrieved; 200 }; 201 202 //***************************************************************************************************************** 203 // XInterface, XTypeProvider 204 //***************************************************************************************************************** 205 ConfigurationAccess_UICommand::ConfigurationAccess_UICommand( const rtl::OUString& aModuleName, const Reference< XNameAccess >& rGenericUICommands, const Reference< XMultiServiceFactory >& rServiceManager ) : 206 ThreadHelpBase(), 207 m_aConfigCmdAccess( RTL_CONSTASCII_USTRINGPARAM( CONFIGURATION_ROOT_ACCESS )), 208 m_aConfigPopupAccess( RTL_CONSTASCII_USTRINGPARAM( CONFIGURATION_ROOT_ACCESS )), 209 m_aPropUILabel( RTL_CONSTASCII_USTRINGPARAM( CONFIGURATION_PROPERTY_LABEL )), 210 m_aPropUIContextLabel( RTL_CONSTASCII_USTRINGPARAM( CONFIGURATION_PROPERTY_CONTEXT_LABEL )), 211 m_aPropLabel( RTL_CONSTASCII_USTRINGPARAM( PROPSET_LABEL )), 212 m_aPropName( RTL_CONSTASCII_USTRINGPARAM( PROPSET_NAME )), 213 m_aPropPopup( RTL_CONSTASCII_USTRINGPARAM( PROPSET_POPUP )), 214 m_aPropProperties( RTL_CONSTASCII_USTRINGPARAM( PROPSET_PROPERTIES )), 215 m_aPrivateResourceURL( RTL_CONSTASCII_USTRINGPARAM( PRIVATE_RESOURCE_URL )), 216 m_xGenericUICommands( rGenericUICommands ), 217 m_xServiceManager( rServiceManager ), 218 m_bConfigAccessInitialized( sal_False ), 219 m_bCacheFilled( sal_False ), 220 m_bGenericDataRetrieved( sal_False ) 221 { 222 // Create configuration hierarchical access name 223 m_aConfigCmdAccess += aModuleName; 224 m_aConfigCmdAccess += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CONFIGURATION_CMD_ELEMENT_ACCESS )); 225 226 m_xConfigProvider = Reference< XMultiServiceFactory >( rServiceManager->createInstance(SERVICENAME_CFGPROVIDER),UNO_QUERY ); 227 228 m_aConfigPopupAccess += aModuleName; 229 m_aConfigPopupAccess += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( CONFIGURATION_POP_ELEMENT_ACCESS )); 230 //m_xConfigProviderPopups = Reference< XMultiServiceFactory >( rServiceManager->createInstance(SERVICENAME_CFGPROVIDER),UNO_QUERY ); 231 232 rtl::OUString aTmp; 233 ::utl::ConfigManager::GetDirectConfigProperty( ::utl::ConfigManager::PRODUCTNAME ) >>= aTmp; 234 m_aBrandName = aTmp; 235 } 236 237 ConfigurationAccess_UICommand::~ConfigurationAccess_UICommand() 238 { 239 // SAFE 240 ResetableGuard aLock( m_aLock ); 241 Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY ); 242 if ( xContainer.is() ) 243 xContainer->removeContainerListener( this ); 244 xContainer = Reference< XContainer >( m_xConfigAccessPopups, UNO_QUERY ); 245 if ( xContainer.is() ) 246 xContainer->removeContainerListener( this ); 247 } 248 249 250 // XNameAccess 251 Any SAL_CALL ConfigurationAccess_UICommand::getByNameImpl( const ::rtl::OUString& rCommandURL ) 252 { 253 static sal_Int32 nRequests = 0; 254 255 ResetableGuard aLock( m_aLock ); 256 if ( !m_bConfigAccessInitialized ) 257 { 258 initializeConfigAccess(); 259 m_bConfigAccessInitialized = sal_True; 260 fillCache(); 261 } 262 263 if ( rCommandURL.indexOf( m_aPrivateResourceURL ) == 0 ) 264 { 265 // special keys to retrieve information about a set of commands 266 // SAFE 267 addGenericInfoToCache(); 268 269 if ( rCommandURL.equalsIgnoreAsciiCaseAscii( UICOMMANDDESCRIPTION_NAMEACCESS_COMMANDIMAGELIST )) 270 return makeAny( m_aCommandImageList ); 271 else if ( rCommandURL.equalsIgnoreAsciiCaseAscii( UICOMMANDDESCRIPTION_NAMEACCESS_COMMANDROTATEIMAGELIST )) 272 return makeAny( m_aCommandRotateImageList ); 273 else if ( rCommandURL.equalsIgnoreAsciiCaseAscii( UICOMMANDDESCRIPTION_NAMEACCESS_COMMANDMIRRORIMAGELIST )) 274 return makeAny( m_aCommandMirrorImageList ); 275 else 276 return Any(); 277 } 278 else 279 { 280 // SAFE 281 ++nRequests; 282 return getInfoFromCommand( rCommandURL ); 283 } 284 } 285 286 Any SAL_CALL ConfigurationAccess_UICommand::getByName( const ::rtl::OUString& rCommandURL ) 287 { 288 Any aRet( getByNameImpl( rCommandURL ) ); 289 if( !aRet.hasValue() ) 290 throw NoSuchElementException(); 291 292 return aRet; 293 } 294 295 Sequence< ::rtl::OUString > SAL_CALL ConfigurationAccess_UICommand::getElementNames() 296 { 297 return getAllCommands(); 298 } 299 300 sal_Bool SAL_CALL ConfigurationAccess_UICommand::hasByName( const ::rtl::OUString& rCommandURL ) 301 { 302 return getByNameImpl( rCommandURL ).hasValue(); 303 } 304 305 // XElementAccess 306 Type SAL_CALL ConfigurationAccess_UICommand::getElementType() 307 { 308 return( ::getCppuType( (const Sequence< PropertyValue >*)NULL ) ); 309 } 310 311 sal_Bool SAL_CALL ConfigurationAccess_UICommand::hasElements() 312 { 313 // There must are global commands! 314 return sal_True; 315 } 316 317 void ConfigurationAccess_UICommand::fillInfoFromResult( CmdToInfoMap& rCmdInfo, const rtl::OUString& aLabel ) 318 { 319 String rStr( aLabel ); 320 if ( rStr.SearchAscii( "%PRODUCT" ) != STRING_NOTFOUND ) 321 rStr.SearchAndReplaceAllAscii( "%PRODUCTNAME", m_aBrandName ); 322 rCmdInfo.aLabel = ::rtl::OUString( rStr ); 323 rStr.EraseTrailingChars( '.' ); // Remove "..." from string 324 rCmdInfo.aCommandName = ::rtl::OUString( MnemonicGenerator::EraseAllMnemonicChars( rStr )); 325 rCmdInfo.bCommandNameCreated = sal_True; 326 } 327 328 Any ConfigurationAccess_UICommand::getSequenceFromCache( const ::rtl::OUString& aCommandURL ) 329 { 330 CommandToInfoCache::iterator pIter = m_aCmdInfoCache.find( aCommandURL ); 331 if ( pIter != m_aCmdInfoCache.end() ) 332 { 333 if ( !pIter->second.bCommandNameCreated ) 334 fillInfoFromResult( pIter->second, pIter->second.aLabel ); 335 336 Sequence< PropertyValue > aPropSeq( 4 ); 337 aPropSeq[0].Name = m_aPropLabel; 338 aPropSeq[0].Value = pIter->second.aContextLabel.getLength() ? 339 makeAny( pIter->second.aContextLabel ): makeAny( pIter->second.aLabel ); 340 aPropSeq[1].Name = m_aPropName; 341 aPropSeq[1].Value <<= pIter->second.aCommandName; 342 aPropSeq[2].Name = m_aPropPopup; 343 aPropSeq[2].Value <<= pIter->second.bPopup; 344 aPropSeq[3].Name = m_aPropProperties; 345 aPropSeq[3].Value <<= pIter->second.nProperties; 346 return makeAny( aPropSeq ); 347 } 348 349 return Any(); 350 } 351 void ConfigurationAccess_UICommand::impl_fill(const Reference< XNameAccess >& _xConfigAccess,sal_Bool _bPopup, 352 std::vector< ::rtl::OUString >& aImageCommandVector, 353 std::vector< ::rtl::OUString >& aImageRotateVector, 354 std::vector< ::rtl::OUString >& aImageMirrorVector) 355 { 356 if ( _xConfigAccess.is() ) 357 { 358 Sequence< ::rtl::OUString> aNameSeq = _xConfigAccess->getElementNames(); 359 const sal_Int32 nCount = aNameSeq.getLength(); 360 for ( sal_Int32 i = 0; i < nCount; i++ ) 361 { 362 try 363 { 364 Reference< XNameAccess > xNameAccess(_xConfigAccess->getByName( aNameSeq[i] ),UNO_QUERY); 365 if ( xNameAccess.is() ) 366 { 367 CmdToInfoMap aCmdToInfo; 368 369 aCmdToInfo.bPopup = _bPopup; 370 xNameAccess->getByName( m_aPropUILabel ) >>= aCmdToInfo.aLabel; 371 xNameAccess->getByName( m_aPropUIContextLabel ) >>= aCmdToInfo.aContextLabel; 372 xNameAccess->getByName( m_aPropProperties ) >>= aCmdToInfo.nProperties; 373 374 m_aCmdInfoCache.insert( CommandToInfoCache::value_type( aNameSeq[i], aCmdToInfo )); 375 376 if ( aCmdToInfo.nProperties & COMMAND_PROPERTY_IMAGE ) 377 aImageCommandVector.push_back( aNameSeq[i] ); 378 if ( aCmdToInfo.nProperties & COMMAND_PROPERTY_ROTATE ) 379 aImageRotateVector.push_back( aNameSeq[i] ); 380 if ( aCmdToInfo.nProperties & COMMAND_PROPERTY_MIRROR ) 381 aImageMirrorVector.push_back( aNameSeq[i] ); 382 } 383 } 384 catch ( com::sun::star::lang::WrappedTargetException& ) 385 { 386 } 387 catch ( com::sun::star::container::NoSuchElementException& ) 388 { 389 } 390 } 391 } // if ( m_xConfigAccessPopups.is() ) 392 } 393 sal_Bool ConfigurationAccess_UICommand::fillCache() 394 { 395 RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::ConfigurationAccess_UICommand::fillCache" ); 396 397 if ( m_bCacheFilled ) 398 return sal_True; 399 400 std::vector< ::rtl::OUString > aImageCommandVector; 401 std::vector< ::rtl::OUString > aImageRotateVector; 402 std::vector< ::rtl::OUString > aImageMirrorVector; 403 404 impl_fill(m_xConfigAccess,sal_False,aImageCommandVector,aImageRotateVector,aImageMirrorVector); 405 impl_fill(m_xConfigAccessPopups,sal_True,aImageCommandVector,aImageRotateVector,aImageMirrorVector); 406 // Create cached sequences for fast retrieving 407 m_aCommandImageList = comphelper::containerToSequence( aImageCommandVector ); 408 m_aCommandRotateImageList = comphelper::containerToSequence( aImageRotateVector ); 409 m_aCommandMirrorImageList = comphelper::containerToSequence( aImageMirrorVector ); 410 411 m_bCacheFilled = sal_True; 412 413 return sal_True; 414 } 415 416 sal_Bool ConfigurationAccess_UICommand::addGenericInfoToCache() 417 { 418 if ( m_xGenericUICommands.is() && !m_bGenericDataRetrieved ) 419 { 420 Sequence< rtl::OUString > aCommandNameSeq; 421 try 422 { 423 if ( m_xGenericUICommands->getByName( 424 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( UICOMMANDDESCRIPTION_NAMEACCESS_COMMANDROTATEIMAGELIST ))) >>= aCommandNameSeq ) 425 m_aCommandRotateImageList = comphelper::concatSequences< rtl::OUString >( m_aCommandRotateImageList, aCommandNameSeq ); 426 } 427 catch ( RuntimeException& e ) 428 { 429 throw e; 430 } 431 catch ( Exception& ) 432 { 433 } 434 435 try 436 { 437 if ( m_xGenericUICommands->getByName( 438 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( UICOMMANDDESCRIPTION_NAMEACCESS_COMMANDMIRRORIMAGELIST ))) >>= aCommandNameSeq ) 439 m_aCommandMirrorImageList = comphelper::concatSequences< rtl::OUString >( m_aCommandMirrorImageList, aCommandNameSeq ); 440 } 441 catch ( RuntimeException& e ) 442 { 443 throw e; 444 } 445 catch ( Exception& ) 446 { 447 } 448 449 m_bGenericDataRetrieved = sal_True; 450 } 451 452 return sal_True; 453 } 454 455 Any ConfigurationAccess_UICommand::getInfoFromCommand( const rtl::OUString& rCommandURL ) 456 { 457 Any a; 458 459 try 460 { 461 a = getSequenceFromCache( rCommandURL ); 462 if ( !a.hasValue() ) 463 { 464 // First try to ask our global commands configuration access. It also caches maybe 465 // we find the entry in its cache first. 466 if ( m_xGenericUICommands.is() && m_xGenericUICommands->hasByName( rCommandURL ) ) 467 { 468 try 469 { 470 return m_xGenericUICommands->getByName( rCommandURL ); 471 } 472 catch ( com::sun::star::lang::WrappedTargetException& ) 473 { 474 } 475 catch ( com::sun::star::container::NoSuchElementException& ) 476 { 477 } 478 } 479 } 480 } 481 catch( com::sun::star::container::NoSuchElementException& ) 482 { 483 } 484 catch ( com::sun::star::lang::WrappedTargetException& ) 485 { 486 } 487 488 return a; 489 } 490 491 Sequence< rtl::OUString > ConfigurationAccess_UICommand::getAllCommands() 492 { 493 // SAFE 494 ResetableGuard aLock( m_aLock ); 495 496 if ( !m_bConfigAccessInitialized ) 497 { 498 initializeConfigAccess(); 499 m_bConfigAccessInitialized = sal_True; 500 fillCache(); 501 } 502 503 if ( m_xConfigAccess.is() ) 504 { 505 Reference< XNameAccess > xNameAccess; 506 507 try 508 { 509 Sequence< ::rtl::OUString > aNameSeq = m_xConfigAccess->getElementNames(); 510 511 if ( m_xGenericUICommands.is() ) 512 { 513 // Create concat list of supported user interface commands of the module 514 Sequence< ::rtl::OUString > aGenericNameSeq = m_xGenericUICommands->getElementNames(); 515 sal_uInt32 nCount1 = aNameSeq.getLength(); 516 sal_uInt32 nCount2 = aGenericNameSeq.getLength(); 517 518 aNameSeq.realloc( nCount1 + nCount2 ); 519 ::rtl::OUString* pNameSeq = aNameSeq.getArray(); 520 const ::rtl::OUString* pGenericSeq = aGenericNameSeq.getConstArray(); 521 for ( sal_uInt32 i = 0; i < nCount2; i++ ) 522 pNameSeq[nCount1+i] = pGenericSeq[i]; 523 } 524 525 return aNameSeq; 526 } 527 catch( com::sun::star::container::NoSuchElementException& ) 528 { 529 } 530 catch ( com::sun::star::lang::WrappedTargetException& ) 531 { 532 } 533 } 534 535 return Sequence< rtl::OUString >(); 536 } 537 538 sal_Bool ConfigurationAccess_UICommand::initializeConfigAccess() 539 { 540 Sequence< Any > aArgs( 1 ); 541 PropertyValue aPropValue; 542 543 try 544 { 545 aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" )); 546 aPropValue.Value <<= m_aConfigCmdAccess; 547 aArgs[0] <<= aPropValue; 548 549 m_xConfigAccess = Reference< XNameAccess >( m_xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGREADACCESS,aArgs ),UNO_QUERY ); 550 if ( m_xConfigAccess.is() ) 551 { 552 // Add as container listener 553 Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY ); 554 if ( xContainer.is() ) 555 xContainer->addContainerListener( this ); 556 } 557 558 aPropValue.Value <<= m_aConfigPopupAccess; 559 aArgs[0] <<= aPropValue; 560 m_xConfigAccessPopups = Reference< XNameAccess >( m_xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGREADACCESS,aArgs ),UNO_QUERY ); 561 if ( m_xConfigAccessPopups.is() ) 562 { 563 // Add as container listener 564 Reference< XContainer > xContainer( m_xConfigAccessPopups, UNO_QUERY ); 565 if ( xContainer.is() ) 566 xContainer->addContainerListener( this ); 567 } 568 569 return sal_True; 570 } 571 catch ( WrappedTargetException& ) 572 { 573 } 574 catch ( Exception& ) 575 { 576 } 577 578 return sal_False; 579 } 580 581 // container.XContainerListener 582 void SAL_CALL ConfigurationAccess_UICommand::elementInserted( const ContainerEvent& ) 583 { 584 ResetableGuard aLock( m_aLock ); 585 m_bCacheFilled = sal_False; 586 fillCache(); 587 } 588 589 void SAL_CALL ConfigurationAccess_UICommand::elementRemoved( const ContainerEvent& ) 590 { 591 ResetableGuard aLock( m_aLock ); 592 m_bCacheFilled = sal_False; 593 fillCache(); 594 } 595 596 void SAL_CALL ConfigurationAccess_UICommand::elementReplaced( const ContainerEvent& ) 597 { 598 ResetableGuard aLock( m_aLock ); 599 m_bCacheFilled = sal_False; 600 fillCache(); 601 } 602 603 // lang.XEventListener 604 void SAL_CALL ConfigurationAccess_UICommand::disposing( const EventObject& aEvent ) 605 { 606 // SAFE 607 // remove our reference to the config access 608 ResetableGuard aLock( m_aLock ); 609 610 Reference< XInterface > xIfac1( aEvent.Source, UNO_QUERY ); 611 Reference< XInterface > xIfac2( m_xConfigAccess, UNO_QUERY ); 612 if ( xIfac1 == xIfac2 ) 613 m_xConfigAccess.clear(); 614 else 615 { 616 xIfac2 = Reference< XInterface >( m_xConfigAccessPopups, UNO_QUERY ); 617 if ( xIfac1 == xIfac2 ) 618 m_xConfigAccessPopups.clear(); 619 } 620 } 621 622 //***************************************************************************************************************** 623 // XInterface, XTypeProvider, XServiceInfo 624 //***************************************************************************************************************** 625 DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( UICommandDescription , 626 ::cppu::OWeakObject , 627 SERVICENAME_UICOMMANDDESCRIPTION , 628 IMPLEMENTATIONNAME_UICOMMANDDESCRIPTION 629 ) 630 631 DEFINE_INIT_SERVICE ( UICommandDescription, {} ) 632 633 UICommandDescription::UICommandDescription( const Reference< XMultiServiceFactory >& xServiceManager ) : 634 ThreadHelpBase(), 635 m_aPrivateResourceURL( RTL_CONSTASCII_USTRINGPARAM( PRIVATE_RESOURCE_URL )), 636 m_xServiceManager( xServiceManager ) 637 { 638 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UICommandDescription::UICommandDescription" ); 639 Reference< XNameAccess > xEmpty; 640 rtl::OUString aGenericUICommand( ::rtl::OUString::createFromAscii( "GenericCommands" )); 641 m_xGenericUICommands = new ConfigurationAccess_UICommand( aGenericUICommand, xEmpty, xServiceManager ); 642 643 impl_fillElements("ooSetupFactoryCommandConfigRef"); 644 645 // insert generic commands 646 UICommandsHashMap::iterator pIter = m_aUICommandsHashMap.find( aGenericUICommand ); 647 if ( pIter != m_aUICommandsHashMap.end() ) 648 pIter->second = m_xGenericUICommands; 649 } 650 UICommandDescription::UICommandDescription( const Reference< XMultiServiceFactory >& xServiceManager,bool ) : 651 ThreadHelpBase(), 652 m_xServiceManager( xServiceManager ) 653 { 654 } 655 UICommandDescription::~UICommandDescription() 656 { 657 ResetableGuard aLock( m_aLock ); 658 m_aModuleToCommandFileMap.clear(); 659 m_aUICommandsHashMap.clear(); 660 m_xGenericUICommands.clear(); 661 } 662 void UICommandDescription::impl_fillElements(const sal_Char* _pName) 663 { 664 m_xModuleManager.set( m_xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ),UNO_QUERY ); 665 Reference< XNameAccess > xNameAccess( m_xModuleManager, UNO_QUERY_THROW ); 666 Sequence< rtl::OUString > aElementNames = xNameAccess->getElementNames(); 667 Sequence< PropertyValue > aSeq; 668 ::rtl::OUString aModuleIdentifier; 669 670 for ( sal_Int32 i = 0; i < aElementNames.getLength(); i++ ) 671 { 672 aModuleIdentifier = aElementNames[i]; 673 if ( xNameAccess->getByName( aModuleIdentifier ) >>= aSeq ) 674 { 675 ::rtl::OUString aCommandStr; 676 for ( sal_Int32 y = 0; y < aSeq.getLength(); y++ ) 677 { 678 if ( aSeq[y].Name.equalsAscii(_pName) ) 679 { 680 aSeq[y].Value >>= aCommandStr; 681 break; 682 } 683 } 684 685 // Create first mapping ModuleIdentifier ==> Command File 686 m_aModuleToCommandFileMap.insert( ModuleToCommandFileMap::value_type( aModuleIdentifier, aCommandStr )); 687 688 // Create second mapping Command File ==> commands instance 689 UICommandsHashMap::iterator pIter = m_aUICommandsHashMap.find( aCommandStr ); 690 if ( pIter == m_aUICommandsHashMap.end() ) 691 m_aUICommandsHashMap.insert( UICommandsHashMap::value_type( aCommandStr, Reference< XNameAccess >() )); 692 } 693 } // for ( sal_Int32 i = 0; i < aElementNames.getLength(); i++ ) 694 } 695 Reference< XNameAccess > UICommandDescription::impl_createConfigAccess(const ::rtl::OUString& _sName) 696 { 697 return new ConfigurationAccess_UICommand( _sName,m_xGenericUICommands,m_xServiceManager ); 698 } 699 700 Any SAL_CALL UICommandDescription::getByName( const ::rtl::OUString& aName ) 701 { 702 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UICommandDescription::getByName" ); 703 Any a; 704 705 ResetableGuard aLock( m_aLock ); 706 707 ModuleToCommandFileMap::const_iterator pM2CIter = m_aModuleToCommandFileMap.find( aName ); 708 if ( pM2CIter != m_aModuleToCommandFileMap.end() ) 709 { 710 ::rtl::OUString aCommandFile( pM2CIter->second ); 711 UICommandsHashMap::iterator pIter = m_aUICommandsHashMap.find( aCommandFile ); 712 if ( pIter != m_aUICommandsHashMap.end() ) 713 { 714 if ( pIter->second.is() ) 715 a <<= pIter->second; 716 else 717 { 718 Reference< XNameAccess > xUICommands; 719 ConfigurationAccess_UICommand* pUICommands = new ConfigurationAccess_UICommand( aCommandFile, 720 m_xGenericUICommands, 721 m_xServiceManager ); 722 xUICommands = Reference< XNameAccess >( static_cast< cppu::OWeakObject* >( pUICommands ),UNO_QUERY ); 723 pIter->second = xUICommands; 724 a <<= xUICommands; 725 } 726 } 727 } 728 else if ( m_aPrivateResourceURL.getLength() && aName.indexOf( m_aPrivateResourceURL ) == 0 ) 729 { 730 // special keys to retrieve information about a set of commands 731 return m_xGenericUICommands->getByName( aName ); 732 } 733 else 734 { 735 throw NoSuchElementException(); 736 } 737 738 return a; 739 } 740 741 Sequence< ::rtl::OUString > SAL_CALL UICommandDescription::getElementNames() 742 { 743 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UICommandDescription::getElementNames" ); 744 ResetableGuard aLock( m_aLock ); 745 746 Sequence< rtl::OUString > aSeq( m_aModuleToCommandFileMap.size() ); 747 748 sal_Int32 n = 0; 749 ModuleToCommandFileMap::const_iterator pIter = m_aModuleToCommandFileMap.begin(); 750 while ( pIter != m_aModuleToCommandFileMap.end() ) 751 { 752 aSeq[n++] = pIter->first; 753 ++pIter; 754 } 755 756 return aSeq; 757 } 758 759 sal_Bool SAL_CALL UICommandDescription::hasByName( const ::rtl::OUString& aName ) 760 { 761 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UICommandDescription::hasByName" ); 762 ResetableGuard aLock( m_aLock ); 763 764 ModuleToCommandFileMap::const_iterator pIter = m_aModuleToCommandFileMap.find( aName ); 765 return ( pIter != m_aModuleToCommandFileMap.end() ); 766 } 767 768 // XElementAccess 769 Type SAL_CALL UICommandDescription::getElementType() 770 { 771 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UICommandDescription::getElementType" ); 772 return( ::getCppuType( (const Reference< XNameAccess >*)NULL ) ); 773 } 774 775 sal_Bool SAL_CALL UICommandDescription::hasElements() 776 { 777 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UICommandDescription::hasElements" ); 778 // generic UI commands are always available! 779 return sal_True; 780 } 781 782 } // namespace framework 783