/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ #include "precompiled_sfx2.hxx" #include "ResourceManager.hxx" #include #include #include #include #include #include #include #include #include #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString))) using ::rtl::OUString; using namespace css; using namespace cssu; namespace sfx2 { namespace sidebar { #define gsPrivateResourceToolpanelPrefix "private:resource/toolpanel/" class ResourceManager::Deleter { public: void operator() (ResourceManager* pObject) { delete pObject; } }; ResourceManager& ResourceManager::Instance (void) { static ResourceManager maInstance; return maInstance; } ResourceManager::ResourceManager (void) : maDecks(), maPanels(), maProcessedApplications() { ReadDeckList(); ReadPanelList(); } ResourceManager::~ResourceManager (void) { maPanels.clear(); maDecks.clear(); } const DeckDescriptor* ResourceManager::GetBestMatchingDeck ( const EnumContext& rContext, const Reference& rxFrame) { ReadLegacyAddons(rxFrame); sal_Int32 nBestMatch (EnumContext::NoMatch); const DeckContainer::const_iterator iEnd (maDecks.end()); DeckContainer::const_iterator iBestDeck (iEnd); for (DeckContainer::const_iterator iDeck(maDecks.begin()); iDeck!=iEnd; ++iDeck) { const sal_Int32 nMatch (rContext.EvaluateMatch(iDeck->maContexts)); if (nMatch < nBestMatch) { // Found a better matching deck. nBestMatch = nMatch; iBestDeck = iDeck; if (nBestMatch == EnumContext::OptimalMatch) { // We will not find a better match. break; } } } if (iBestDeck != iEnd) return &*iBestDeck; else return NULL; } const DeckDescriptor* ResourceManager::GetDeckDescriptor ( const ::rtl::OUString& rsDeckId) const { for (DeckContainer::const_iterator iDeck(maDecks.begin()), iEnd(maDecks.end()); iDeck!=iEnd; ++iDeck) { if (iDeck->msId.equals(rsDeckId)) return &*iDeck; } return NULL; } const PanelDescriptor* ResourceManager::GetPanelDescriptor ( const ::rtl::OUString& rsPanelId) const { for (PanelContainer::const_iterator iPanel(maPanels.begin()), iEnd(maPanels.end()); iPanel!=iEnd; ++iPanel) { if (iPanel->msId.equals(rsPanelId)) return &*iPanel; } return NULL; } void ResourceManager::SetIsDeckEnabled ( const ::rtl::OUString& rsDeckId, const bool bIsEnabled) { for (DeckContainer::iterator iDeck(maDecks.begin()), iEnd(maDecks.end()); iDeck!=iEnd; ++iDeck) { if (iDeck->msId.equals(rsDeckId)) { iDeck->mbIsEnabled = bIsEnabled; return; } } } const ResourceManager::IdContainer& ResourceManager::GetMatchingDecks ( IdContainer& rDeckIds, const EnumContext& rContext, const Reference& rxFrame) { ReadLegacyAddons(rxFrame); for (DeckContainer::const_iterator iDeck(maDecks.begin()), iEnd (maDecks.end()); iDeck!=iEnd; ++iDeck) { if (rContext.EvaluateMatch(iDeck->maContexts) != EnumContext::NoMatch) rDeckIds.push_back(iDeck->msId); } return rDeckIds; } const ResourceManager::IdContainer& ResourceManager::GetMatchingPanels ( IdContainer& rPanelIds, const EnumContext& rContext, const ::rtl::OUString& rsDeckId, const Reference& rxFrame) { ReadLegacyAddons(rxFrame); ::std::multimap aOrderedIds; for (PanelContainer::const_iterator iPanel(maPanels.begin()), iEnd(maPanels.end()); iPanel!=iEnd; ++iPanel) { const PanelDescriptor& rPanelDescriptor (*iPanel); if (rPanelDescriptor.msDeckId.equals(rsDeckId)) if (rContext.EvaluateMatch(rPanelDescriptor.maContexts) != EnumContext::NoMatch) aOrderedIds.insert(::std::multimap::value_type( iPanel->mnOrderIndex, iPanel->msId)); } for (::std::multimap::const_iterator iId(aOrderedIds.begin()), iEnd(aOrderedIds.end()); iId!=iEnd; ++iId) { rPanelIds.push_back(iId->second); } return rPanelIds; } void ResourceManager::ReadDeckList (void) { const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory()); const ::utl::OConfigurationTreeRoot aDeckRootNode ( aContext, A2S("org.openoffice.Office.UI.Sidebar/Content/DeckList"), false); if ( ! aDeckRootNode.isValid() ) return; const Sequence aDeckNodeNames (aDeckRootNode.getNodeNames()); const sal_Int32 nCount (aDeckNodeNames.getLength()); maDecks.resize(nCount); sal_Int32 nWriteIndex(0); for (sal_Int32 nReadIndex(0); nReadIndex aPanelNodeNames (aPanelRootNode.getNodeNames()); const sal_Int32 nCount (aPanelNodeNames.getLength()); maPanels.resize(nCount); sal_Int32 nWriteIndex (0); for (sal_Int32 nReadIndex(0); nReadIndex& rContextContainer) const { const Sequence aChildNodeNames (rNode.getNodeNames()); const sal_Int32 nCount (aChildNodeNames.getLength()); rContextContainer.resize(nCount); for (sal_Int32 nIndex(0); nIndex& rxFrame) { // Get module name for given frame. ::rtl::OUString sModuleName (GetModuleName(rxFrame)); if (sModuleName.getLength() == 0) return; if (maProcessedApplications.find(sModuleName) != maProcessedApplications.end()) { // Addons for this application have already been read. // There is nothing more to do. return; } // Mark module as processed. Even when there is an error that // prevents the configuration data from being read, this error // will not be triggered a second time. maProcessedApplications.insert(sModuleName); // Get access to the configuration root node for the application. ::utl::OConfigurationTreeRoot aLegacyRootNode (GetLegacyAddonRootNode(sModuleName)); if ( ! aLegacyRootNode.isValid()) return; // Process child nodes. ::std::vector aMatchingNodeNames; GetToolPanelNodeNames(aMatchingNodeNames, aLegacyRootNode); const sal_Int32 nCount (aMatchingNodeNames.size()); size_t nDeckWriteIndex (maDecks.size()); size_t nPanelWriteIndex (maPanels.size()); maDecks.resize(maDecks.size() + nCount); maPanels.resize(maPanels.size() + nCount); for (sal_Int32 nReadIndex(0); nReadIndex& rxFrame) { try { const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory()); const Reference xModuleManager ( aContext.createComponent("com.sun.star.frame.ModuleManager" ), UNO_QUERY_THROW ); return xModuleManager->identify(rxFrame); } catch (const Exception&) { DBG_UNHANDLED_EXCEPTION(); } return OUString(); } ::utl::OConfigurationTreeRoot ResourceManager::GetLegacyAddonRootNode ( const ::rtl::OUString& rsModuleName) const { try { const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory()); const Reference xModuleAccess ( aContext.createComponent("com.sun.star.frame.ModuleManager"), UNO_QUERY_THROW); const ::comphelper::NamedValueCollection aModuleProperties (xModuleAccess->getByName(rsModuleName)); const ::rtl::OUString sWindowStateRef (aModuleProperties.getOrDefault( "ooSetupFactoryWindowStateConfigRef", ::rtl::OUString())); ::rtl::OUStringBuffer aPathComposer; aPathComposer.appendAscii("org.openoffice.Office.UI."); aPathComposer.append(sWindowStateRef); aPathComposer.appendAscii("/UIElements/States"); return ::utl::OConfigurationTreeRoot(aContext, aPathComposer.makeStringAndClear(), false); } catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); } return ::utl::OConfigurationTreeRoot(); } void ResourceManager::GetToolPanelNodeNames ( ::std::vector& rMatchingNames, const ::utl::OConfigurationTreeRoot aRoot) const { Sequence aChildNodeNames (aRoot.getNodeNames()); const sal_Int32 nCount (aChildNodeNames.getLength()); for (sal_Int32 nIndex(0); nIndex