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 #include "precompiled_sfx2.hxx" 23 24 #include "ResourceManager.hxx" 25 #include "sfx2/sidebar/Tools.hxx" 26 27 #include <unotools/confignode.hxx> 28 #include <comphelper/componentcontext.hxx> 29 #include <comphelper/processfactory.hxx> 30 #include <comphelper/namedvaluecollection.hxx> 31 #include <comphelper/types.hxx> 32 #include <comphelper/stlunosequence.hxx> 33 34 #include <rtl/ustrbuf.hxx> 35 #include <tools/diagnose_ex.h> 36 37 #include <com/sun/star/frame/XModuleManager.hpp> 38 39 #include <map> 40 41 42 43 using ::rtl::OUString; 44 using namespace css; 45 using namespace cssu; 46 47 namespace sfx2 { namespace sidebar { 48 49 #define gsPrivateResourceToolpanelPrefix "private:resource/toolpanel/" 50 51 52 53 class ResourceManager::Deleter 54 { 55 public: 56 void operator() (ResourceManager* pObject) 57 { 58 delete pObject; 59 } 60 }; 61 62 63 ResourceManager& ResourceManager::Instance (void) 64 { 65 static ResourceManager maInstance; 66 return maInstance; 67 } 68 69 70 71 72 ResourceManager::ResourceManager (void) 73 : maDecks(), 74 maPanels(), 75 maProcessedApplications() 76 { 77 ReadDeckList(); 78 ReadPanelList(); 79 } 80 81 82 83 84 ResourceManager::~ResourceManager (void) 85 { 86 maPanels.clear(); 87 maDecks.clear(); 88 } 89 90 91 92 93 const DeckDescriptor* ResourceManager::GetDeckDescriptor ( 94 const ::rtl::OUString& rsDeckId) const 95 { 96 for (DeckContainer::const_iterator 97 iDeck(maDecks.begin()), 98 iEnd(maDecks.end()); 99 iDeck!=iEnd; 100 ++iDeck) 101 { 102 if (iDeck->msId.equals(rsDeckId)) 103 return &*iDeck; 104 } 105 return NULL; 106 } 107 108 109 110 111 const PanelDescriptor* ResourceManager::GetPanelDescriptor ( 112 const ::rtl::OUString& rsPanelId) const 113 { 114 for (PanelContainer::const_iterator 115 iPanel(maPanels.begin()), 116 iEnd(maPanels.end()); 117 iPanel!=iEnd; 118 ++iPanel) 119 { 120 if (iPanel->msId.equals(rsPanelId)) 121 return &*iPanel; 122 } 123 return NULL; 124 } 125 126 127 128 129 void ResourceManager::SetIsDeckEnabled ( 130 const ::rtl::OUString& rsDeckId, 131 const bool bIsEnabled) 132 { 133 for (DeckContainer::iterator 134 iDeck(maDecks.begin()), 135 iEnd(maDecks.end()); 136 iDeck!=iEnd; 137 ++iDeck) 138 { 139 if (iDeck->msId.equals(rsDeckId)) 140 { 141 iDeck->mbIsEnabled = bIsEnabled; 142 return; 143 } 144 } 145 } 146 147 148 149 150 const ResourceManager::DeckContextDescriptorContainer& ResourceManager::GetMatchingDecks ( 151 DeckContextDescriptorContainer& rDecks, 152 const Context& rContext, 153 const bool bIsDocumentReadOnly, 154 const Reference<frame::XFrame>& rxFrame) 155 { 156 ReadLegacyAddons(rxFrame); 157 158 ::std::multimap<sal_Int32,DeckContextDescriptor> aOrderedIds; 159 for (DeckContainer::const_iterator 160 iDeck(maDecks.begin()), 161 iEnd (maDecks.end()); 162 iDeck!=iEnd; 163 ++iDeck) 164 { 165 const DeckDescriptor& rDeckDescriptor (*iDeck); 166 if (rDeckDescriptor.maContextList.GetMatch(rContext) == NULL) 167 continue; 168 DeckContextDescriptor aDeckContextDescriptor; 169 aDeckContextDescriptor.msId = rDeckDescriptor.msId; 170 aDeckContextDescriptor.mbIsEnabled = 171 ! bIsDocumentReadOnly 172 || IsDeckEnabled(rDeckDescriptor.msId, rContext, rxFrame); 173 aOrderedIds.insert(::std::multimap<sal_Int32,DeckContextDescriptor>::value_type( 174 rDeckDescriptor.mnOrderIndex, 175 aDeckContextDescriptor)); 176 } 177 178 for (::std::multimap<sal_Int32,DeckContextDescriptor>::const_iterator 179 iId(aOrderedIds.begin()), 180 iEnd(aOrderedIds.end()); 181 iId!=iEnd; 182 ++iId) 183 { 184 rDecks.push_back(iId->second); 185 } 186 187 return rDecks; 188 } 189 190 191 192 193 const ResourceManager::PanelContextDescriptorContainer& ResourceManager::GetMatchingPanels ( 194 PanelContextDescriptorContainer& rPanelIds, 195 const Context& rContext, 196 const ::rtl::OUString& rsDeckId, 197 const Reference<frame::XFrame>& rxFrame) 198 { 199 ReadLegacyAddons(rxFrame); 200 201 ::std::multimap<sal_Int32,PanelContextDescriptor> aOrderedIds; 202 for (PanelContainer::const_iterator 203 iPanel(maPanels.begin()), 204 iEnd(maPanels.end()); 205 iPanel!=iEnd; 206 ++iPanel) 207 { 208 const PanelDescriptor& rPanelDescriptor (*iPanel); 209 if ( ! rPanelDescriptor.msDeckId.equals(rsDeckId)) 210 continue; 211 212 const ContextList::Entry* pEntry = rPanelDescriptor.maContextList.GetMatch(rContext); 213 if (pEntry == NULL) 214 continue; 215 216 PanelContextDescriptor aPanelContextDescriptor; 217 aPanelContextDescriptor.msId = rPanelDescriptor.msId; 218 aPanelContextDescriptor.msMenuCommand = pEntry->msMenuCommand; 219 aPanelContextDescriptor.mbIsInitiallyVisible = pEntry->mbIsInitiallyVisible; 220 aPanelContextDescriptor.mbShowForReadOnlyDocuments = rPanelDescriptor.mbShowForReadOnlyDocuments; 221 aOrderedIds.insert(::std::multimap<sal_Int32,PanelContextDescriptor>::value_type( 222 rPanelDescriptor.mnOrderIndex, 223 aPanelContextDescriptor)); 224 } 225 226 for (::std::multimap<sal_Int32,PanelContextDescriptor>::const_iterator 227 iId(aOrderedIds.begin()), 228 iEnd(aOrderedIds.end()); 229 iId!=iEnd; 230 ++iId) 231 { 232 rPanelIds.push_back(iId->second); 233 } 234 235 return rPanelIds; 236 } 237 238 239 240 241 void ResourceManager::ReadDeckList (void) 242 { 243 const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory()); 244 const ::utl::OConfigurationTreeRoot aDeckRootNode ( 245 aContext, 246 A2S("org.openoffice.Office.UI.Sidebar/Content/DeckList"), 247 false); 248 if ( ! aDeckRootNode.isValid() ) 249 return; 250 251 const Sequence<OUString> aDeckNodeNames (aDeckRootNode.getNodeNames()); 252 const sal_Int32 nCount (aDeckNodeNames.getLength()); 253 maDecks.resize(nCount); 254 sal_Int32 nWriteIndex(0); 255 for (sal_Int32 nReadIndex(0); nReadIndex<nCount; ++nReadIndex) 256 { 257 const ::utl::OConfigurationNode aDeckNode (aDeckRootNode.openNode(aDeckNodeNames[nReadIndex])); 258 if ( ! aDeckNode.isValid()) 259 continue; 260 261 DeckDescriptor& rDeckDescriptor (maDecks[nWriteIndex++]); 262 263 rDeckDescriptor.msTitle = ::comphelper::getString( 264 aDeckNode.getNodeValue("Title")); 265 rDeckDescriptor.msId = ::comphelper::getString( 266 aDeckNode.getNodeValue("Id")); 267 rDeckDescriptor.msIconURL = ::comphelper::getString( 268 aDeckNode.getNodeValue("IconURL")); 269 rDeckDescriptor.msHighContrastIconURL = ::comphelper::getString( 270 aDeckNode.getNodeValue("HighContrastIconURL")); 271 rDeckDescriptor.msTitleBarIconURL = ::comphelper::getString( 272 aDeckNode.getNodeValue("TitleBarIconURL")); 273 rDeckDescriptor.msHighContrastTitleBarIconURL = ::comphelper::getString( 274 aDeckNode.getNodeValue("HighContrastTitleBarIconURL")); 275 rDeckDescriptor.msHelpURL = ::comphelper::getString( 276 aDeckNode.getNodeValue("HelpURL")); 277 rDeckDescriptor.msHelpText = rDeckDescriptor.msTitle; 278 rDeckDescriptor.mbIsEnabled = true; 279 rDeckDescriptor.mnOrderIndex = ::comphelper::getINT32( 280 aDeckNode.getNodeValue("OrderIndex")); 281 282 ReadContextList( 283 aDeckNode, 284 rDeckDescriptor.maContextList, 285 OUString()); 286 } 287 288 // When there where invalid nodes then we have to adapt the size 289 // of the deck vector. 290 if (nWriteIndex<nCount) 291 maDecks.resize(nWriteIndex); 292 } 293 294 295 296 297 void ResourceManager::ReadPanelList (void) 298 { 299 const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory()); 300 const ::utl::OConfigurationTreeRoot aPanelRootNode ( 301 aContext, 302 A2S("org.openoffice.Office.UI.Sidebar/Content/PanelList"), 303 false); 304 if ( ! aPanelRootNode.isValid() ) 305 return; 306 307 const Sequence<OUString> aPanelNodeNames (aPanelRootNode.getNodeNames()); 308 const sal_Int32 nCount (aPanelNodeNames.getLength()); 309 maPanels.resize(nCount); 310 sal_Int32 nWriteIndex (0); 311 for (sal_Int32 nReadIndex(0); nReadIndex<nCount; ++nReadIndex) 312 { 313 const ::utl::OConfigurationNode aPanelNode (aPanelRootNode.openNode(aPanelNodeNames[nReadIndex])); 314 if ( ! aPanelNode.isValid()) 315 continue; 316 317 PanelDescriptor& rPanelDescriptor (maPanels[nWriteIndex++]); 318 319 rPanelDescriptor.msTitle = ::comphelper::getString( 320 aPanelNode.getNodeValue("Title")); 321 rPanelDescriptor.mbIsTitleBarOptional = ::comphelper::getBOOL( 322 aPanelNode.getNodeValue("TitleBarIsOptional")); 323 rPanelDescriptor.msId = ::comphelper::getString( 324 aPanelNode.getNodeValue("Id")); 325 rPanelDescriptor.msDeckId = ::comphelper::getString( 326 aPanelNode.getNodeValue("DeckId")); 327 rPanelDescriptor.msTitleBarIconURL = ::comphelper::getString( 328 aPanelNode.getNodeValue("TitleBarIconURL")); 329 rPanelDescriptor.msHighContrastTitleBarIconURL = ::comphelper::getString( 330 aPanelNode.getNodeValue("HighContrastTitleBarIconURL")); 331 rPanelDescriptor.msHelpURL = ::comphelper::getString( 332 aPanelNode.getNodeValue("HelpURL")); 333 rPanelDescriptor.msImplementationURL = ::comphelper::getString( 334 aPanelNode.getNodeValue("ImplementationURL")); 335 rPanelDescriptor.mnOrderIndex = ::comphelper::getINT32( 336 aPanelNode.getNodeValue("OrderIndex")); 337 rPanelDescriptor.mbShowForReadOnlyDocuments = ::comphelper::getBOOL( 338 aPanelNode.getNodeValue("ShowForReadOnlyDocument")); 339 rPanelDescriptor.mbWantsCanvas = ::comphelper::getBOOL( 340 aPanelNode.getNodeValue("WantsCanvas")); 341 const OUString sDefaultMenuCommand (::comphelper::getString( 342 aPanelNode.getNodeValue("DefaultMenuCommand"))); 343 344 ReadContextList( 345 aPanelNode, 346 rPanelDescriptor.maContextList, 347 sDefaultMenuCommand); 348 } 349 350 // When there where invalid nodes then we have to adapt the size 351 // of the deck vector. 352 if (nWriteIndex<nCount) 353 maPanels.resize(nWriteIndex); 354 } 355 356 357 358 359 void ResourceManager::ReadContextList ( 360 const ::utl::OConfigurationNode& rParentNode, 361 ContextList& rContextList, 362 const OUString& rsDefaultMenuCommand) const 363 { 364 const Any aValue = rParentNode.getNodeValue("ContextList"); 365 Sequence<OUString> aValues; 366 sal_Int32 nCount; 367 if (aValue >>= aValues) 368 nCount = aValues.getLength(); 369 else 370 nCount = 0; 371 372 for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex) 373 { 374 const OUString sValue (aValues[nIndex]); 375 sal_Int32 nCharacterIndex (0); 376 const OUString sApplicationName (sValue.getToken(0, ',', nCharacterIndex).trim()); 377 if (nCharacterIndex < 0) 378 { 379 if (sApplicationName.getLength() == 0) 380 { 381 // This is a valid case: in the XML file the separator 382 // was used as terminator. Using it in the last line 383 // creates an additional but empty entry. 384 break; 385 } 386 else 387 { 388 OSL_ASSERT("expecting three or four values per ContextList entry, separated by comma"); 389 continue; 390 } 391 } 392 393 const OUString sContextName (sValue.getToken(0, ',', nCharacterIndex).trim()); 394 if (nCharacterIndex < 0) 395 { 396 OSL_ASSERT("expecting three or four values per ContextList entry, separated by comma"); 397 continue; 398 } 399 400 const OUString sInitialState (sValue.getToken(0, ',', nCharacterIndex).trim()); 401 402 // The fourth argument is optional. 403 const OUString sMenuCommandOverride ( 404 nCharacterIndex<0 405 ? OUString() 406 : sValue.getToken(0, ',', nCharacterIndex).trim()); 407 const OUString sMenuCommand ( 408 sMenuCommandOverride.getLength()>0 409 ? (sMenuCommandOverride.equalsAscii("none") 410 ? OUString() 411 : sMenuCommandOverride) 412 : rsDefaultMenuCommand); 413 414 // Setup a list of application enums. Note that the 415 // application name may result in more than one value (eg 416 // DrawImpress will result in two enums, one for Draw and one 417 // for Impress). 418 ::std::vector<EnumContext::Application> aApplications; 419 EnumContext::Application eApplication (EnumContext::GetApplicationEnum(sApplicationName)); 420 if (eApplication == EnumContext::Application_None 421 && !sApplicationName.equals(EnumContext::GetApplicationName(EnumContext::Application_None))) 422 { 423 // Handle some special names: abbreviations that make 424 // context descriptions more readable. 425 if (sApplicationName.equalsAscii("Writer")) 426 aApplications.push_back(EnumContext::Application_Writer); 427 else if (sApplicationName.equalsAscii("Calc")) 428 aApplications.push_back(EnumContext::Application_Calc); 429 else if (sApplicationName.equalsAscii("Draw")) 430 aApplications.push_back(EnumContext::Application_Draw); 431 else if (sApplicationName.equalsAscii("Impress")) 432 aApplications.push_back(EnumContext::Application_Impress); 433 else if (sApplicationName.equalsAscii("DrawImpress")) 434 { 435 // A special case among the special names: it is 436 // common to use the same context descriptions for 437 // both Draw and Impress. This special case helps to 438 // avoid duplication in the .xcu file. 439 aApplications.push_back(EnumContext::Application_Draw); 440 aApplications.push_back(EnumContext::Application_Impress); 441 } 442 else if (sApplicationName.equalsAscii("WriterVariants")) 443 { 444 // Another special case for all Writer variants. 445 aApplications.push_back(EnumContext::Application_Writer); 446 aApplications.push_back(EnumContext::Application_WriterGlobal); 447 aApplications.push_back(EnumContext::Application_WriterWeb); 448 aApplications.push_back(EnumContext::Application_WriterXML); 449 aApplications.push_back(EnumContext::Application_WriterForm); 450 aApplications.push_back(EnumContext::Application_WriterReport); 451 } 452 else 453 { 454 OSL_ASSERT("application name not recognized"); 455 continue; 456 } 457 } 458 else 459 { 460 // No conversion of the application name necessary. 461 aApplications.push_back(eApplication); 462 } 463 464 // Setup the actual context enum. 465 const EnumContext::Context eContext (EnumContext::GetContextEnum(sContextName)); 466 if (eContext == EnumContext::Context_Unknown) 467 { 468 OSL_ASSERT("context name not recognized"); 469 continue; 470 } 471 472 // Setup the flag that controls whether a deck/pane is 473 // initially visible/expanded. 474 bool bIsInitiallyVisible; 475 if (sInitialState.equalsAscii("visible")) 476 bIsInitiallyVisible = true; 477 else if (sInitialState.equalsAscii("hidden")) 478 bIsInitiallyVisible = false; 479 else 480 { 481 OSL_ASSERT("unrecognized state"); 482 continue; 483 } 484 485 // Add context descriptors. 486 for (::std::vector<EnumContext::Application>::const_iterator 487 iApplication(aApplications.begin()), 488 iEnd(aApplications.end()); 489 iApplication!=iEnd; 490 ++iApplication) 491 { 492 if (*iApplication != EnumContext::Application_None) 493 rContextList.AddContextDescription( 494 Context( 495 EnumContext::GetApplicationName(*iApplication), 496 EnumContext::GetContextName(eContext)), 497 bIsInitiallyVisible, 498 sMenuCommand); 499 } 500 } 501 } 502 503 504 505 506 void ResourceManager::ReadLegacyAddons (const Reference<frame::XFrame>& rxFrame) 507 { 508 // Get module name for given frame. 509 ::rtl::OUString sModuleName (GetModuleName(rxFrame)); 510 if (sModuleName.getLength() == 0) 511 return; 512 if (maProcessedApplications.find(sModuleName) != maProcessedApplications.end()) 513 { 514 // Addons for this application have already been read. 515 // There is nothing more to do. 516 return; 517 } 518 519 // Mark module as processed. Even when there is an error that 520 // prevents the configuration data from being read, this error 521 // will not be triggered a second time. 522 maProcessedApplications.insert(sModuleName); 523 524 // Get access to the configuration root node for the application. 525 ::utl::OConfigurationTreeRoot aLegacyRootNode (GetLegacyAddonRootNode(sModuleName)); 526 if ( ! aLegacyRootNode.isValid()) 527 return; 528 529 // Process child nodes. 530 ::std::vector<OUString> aMatchingNodeNames; 531 GetToolPanelNodeNames(aMatchingNodeNames, aLegacyRootNode); 532 const sal_Int32 nCount (aMatchingNodeNames.size()); 533 size_t nDeckWriteIndex (maDecks.size()); 534 size_t nPanelWriteIndex (maPanels.size()); 535 maDecks.resize(maDecks.size() + nCount); 536 maPanels.resize(maPanels.size() + nCount); 537 for (sal_Int32 nReadIndex(0); nReadIndex<nCount; ++nReadIndex) 538 { 539 const OUString& rsNodeName (aMatchingNodeNames[nReadIndex]); 540 const ::utl::OConfigurationNode aChildNode (aLegacyRootNode.openNode(rsNodeName)); 541 if ( ! aChildNode.isValid()) 542 continue; 543 544 DeckDescriptor& rDeckDescriptor (maDecks[nDeckWriteIndex++]); 545 rDeckDescriptor.msTitle = ::comphelper::getString(aChildNode.getNodeValue("UIName")); 546 rDeckDescriptor.msId = rsNodeName; 547 rDeckDescriptor.msIconURL = ::comphelper::getString(aChildNode.getNodeValue("ImageURL")); 548 rDeckDescriptor.msHighContrastIconURL = rDeckDescriptor.msIconURL; 549 rDeckDescriptor.msHelpURL = ::comphelper::getString(aChildNode.getNodeValue("HelpURL")); 550 rDeckDescriptor.msHelpText = rDeckDescriptor.msTitle; 551 rDeckDescriptor.maContextList.AddContextDescription(Context(sModuleName, A2S("any")), true, OUString()); 552 rDeckDescriptor.mbIsEnabled = true; 553 554 PanelDescriptor& rPanelDescriptor (maPanels[nPanelWriteIndex++]); 555 rPanelDescriptor.msTitle = ::comphelper::getString(aChildNode.getNodeValue("UIName")); 556 rPanelDescriptor.mbIsTitleBarOptional = true; 557 rPanelDescriptor.msId = rsNodeName; 558 rPanelDescriptor.msDeckId = rsNodeName; 559 rPanelDescriptor.msHelpURL = ::comphelper::getString(aChildNode.getNodeValue("HelpURL")); 560 rPanelDescriptor.maContextList.AddContextDescription(Context(sModuleName, A2S("any")), true, OUString()); 561 rPanelDescriptor.msImplementationURL = rsNodeName; 562 rPanelDescriptor.mbShowForReadOnlyDocuments = false; 563 } 564 565 // When there where invalid nodes then we have to adapt the size 566 // of the deck and panel vectors. 567 if (nDeckWriteIndex < maDecks.size()) 568 maDecks.resize(nDeckWriteIndex); 569 if (nPanelWriteIndex < maPanels.size()) 570 maPanels.resize(nPanelWriteIndex); 571 } 572 573 574 575 576 void ResourceManager::StorePanelExpansionState ( 577 const ::rtl::OUString& rsPanelId, 578 const bool bExpansionState, 579 const Context& rContext) 580 { 581 for (PanelContainer::iterator 582 iPanel(maPanels.begin()), 583 iEnd(maPanels.end()); 584 iPanel!=iEnd; 585 ++iPanel) 586 { 587 if (iPanel->msId.equals(rsPanelId)) 588 { 589 ContextList::Entry* pEntry ( 590 iPanel->maContextList.GetMatch (rContext)); 591 if (pEntry != NULL) 592 pEntry->mbIsInitiallyVisible = bExpansionState; 593 } 594 } 595 } 596 597 598 599 600 ::rtl::OUString ResourceManager::GetModuleName ( 601 const cssu::Reference<css::frame::XFrame>& rxFrame) 602 { 603 if ( ! rxFrame.is() || ! rxFrame->getController().is()) 604 return OUString(); 605 606 try 607 { 608 const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory()); 609 const Reference<frame::XModuleManager> xModuleManager ( 610 aContext.createComponent("com.sun.star.frame.ModuleManager"), 611 UNO_QUERY_THROW); 612 return xModuleManager->identify(rxFrame); 613 } 614 catch (const Exception&) 615 { 616 DBG_UNHANDLED_EXCEPTION(); 617 } 618 return OUString(); 619 } 620 621 622 623 624 ::utl::OConfigurationTreeRoot ResourceManager::GetLegacyAddonRootNode ( 625 const ::rtl::OUString& rsModuleName) const 626 { 627 try 628 { 629 const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory()); 630 const Reference<container::XNameAccess> xModuleAccess ( 631 aContext.createComponent("com.sun.star.frame.ModuleManager"), 632 UNO_QUERY_THROW); 633 const ::comphelper::NamedValueCollection aModuleProperties (xModuleAccess->getByName(rsModuleName)); 634 const ::rtl::OUString sWindowStateRef (aModuleProperties.getOrDefault( 635 "ooSetupFactoryWindowStateConfigRef", 636 ::rtl::OUString())); 637 638 ::rtl::OUStringBuffer aPathComposer; 639 aPathComposer.appendAscii("org.openoffice.Office.UI."); 640 aPathComposer.append(sWindowStateRef); 641 aPathComposer.appendAscii("/UIElements/States"); 642 643 return ::utl::OConfigurationTreeRoot(aContext, aPathComposer.makeStringAndClear(), false); 644 } 645 catch( const Exception& ) 646 { 647 DBG_UNHANDLED_EXCEPTION(); 648 } 649 650 return ::utl::OConfigurationTreeRoot(); 651 } 652 653 654 655 656 void ResourceManager::GetToolPanelNodeNames ( 657 ::std::vector<OUString>& rMatchingNames, 658 const ::utl::OConfigurationTreeRoot aRoot) const 659 { 660 Sequence<OUString> aChildNodeNames (aRoot.getNodeNames()); 661 const sal_Int32 nCount (aChildNodeNames.getLength()); 662 for (sal_Int32 nIndex(0); nIndex<nCount; ++nIndex) 663 { 664 if (aChildNodeNames[nIndex].matchAsciiL( 665 RTL_CONSTASCII_STRINGPARAM( "private:resource/toolpanel/"))) 666 rMatchingNames.push_back(aChildNodeNames[nIndex]); 667 } 668 } 669 670 671 672 673 bool ResourceManager::IsDeckEnabled ( 674 const OUString& rsDeckId, 675 const Context& rContext, 676 const Reference<frame::XFrame>& rxFrame) const 677 { 678 // Check if any panel that matches the current context can be 679 // displayed. 680 ResourceManager::PanelContextDescriptorContainer aPanelContextDescriptors; 681 ResourceManager::Instance().GetMatchingPanels( 682 aPanelContextDescriptors, 683 rContext, 684 rsDeckId, 685 rxFrame); 686 687 for (ResourceManager::PanelContextDescriptorContainer::const_iterator 688 iPanel(aPanelContextDescriptors.begin()), 689 iEnd(aPanelContextDescriptors.end()); 690 iPanel!=iEnd; 691 ++iPanel) 692 { 693 if (iPanel->mbShowForReadOnlyDocuments) 694 return true; 695 } 696 697 return false; 698 } 699 700 701 } } // end of namespace sfx2::sidebar 702