1ff12d537SAndre Fischer /**************************************************************
2ff12d537SAndre Fischer  *
3ff12d537SAndre Fischer  * Licensed to the Apache Software Foundation (ASF) under one
4ff12d537SAndre Fischer  * or more contributor license agreements.  See the NOTICE file
5ff12d537SAndre Fischer  * distributed with this work for additional information
6ff12d537SAndre Fischer  * regarding copyright ownership.  The ASF licenses this file
7ff12d537SAndre Fischer  * to you under the Apache License, Version 2.0 (the
8ff12d537SAndre Fischer  * "License"); you may not use this file except in compliance
9ff12d537SAndre Fischer  * with the License.  You may obtain a copy of the License at
10ff12d537SAndre Fischer  *
11ff12d537SAndre Fischer  *   http://www.apache.org/licenses/LICENSE-2.0
12ff12d537SAndre Fischer  *
13ff12d537SAndre Fischer  * Unless required by applicable law or agreed to in writing,
14ff12d537SAndre Fischer  * software distributed under the License is distributed on an
15ff12d537SAndre Fischer  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16ff12d537SAndre Fischer  * KIND, either express or implied.  See the License for the
17ff12d537SAndre Fischer  * specific language governing permissions and limitations
18ff12d537SAndre Fischer  * under the License.
19ff12d537SAndre Fischer  *
20ff12d537SAndre Fischer  *************************************************************/
21ff12d537SAndre Fischer 
22ff12d537SAndre Fischer #include "precompiled_sfx2.hxx"
23ff12d537SAndre Fischer 
24ff12d537SAndre Fischer #include "ResourceManager.hxx"
25ff12d537SAndre Fischer #include <unotools/confignode.hxx>
26ff12d537SAndre Fischer #include <comphelper/componentcontext.hxx>
2795a18594SAndre Fischer #include <comphelper/processfactory.hxx>
28ff12d537SAndre Fischer #include <comphelper/namedvaluecollection.hxx>
2995a18594SAndre Fischer #include <comphelper/types.hxx>
307a32b0c8SAndre Fischer #include <comphelper/stlunosequence.hxx>
317a32b0c8SAndre Fischer 
3295a18594SAndre Fischer #include <rtl/ustrbuf.hxx>
33ff12d537SAndre Fischer #include <tools/diagnose_ex.h>
34ff12d537SAndre Fischer 
3595a18594SAndre Fischer #include <com/sun/star/frame/XModuleManager.hpp>
3695a18594SAndre Fischer 
3795a18594SAndre Fischer #include <map>
3895a18594SAndre Fischer 
39ff12d537SAndre Fischer 
40ff12d537SAndre Fischer #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
41ff12d537SAndre Fischer 
42ff12d537SAndre Fischer using ::rtl::OUString;
43ff12d537SAndre Fischer using namespace css;
44ff12d537SAndre Fischer using namespace cssu;
45ff12d537SAndre Fischer 
46ff12d537SAndre Fischer namespace sfx2 { namespace sidebar {
47ff12d537SAndre Fischer 
48ff12d537SAndre Fischer #define gsPrivateResourceToolpanelPrefix "private:resource/toolpanel/"
49ff12d537SAndre Fischer 
50ff12d537SAndre Fischer 
51ff12d537SAndre Fischer 
52ff12d537SAndre Fischer class ResourceManager::Deleter
53ff12d537SAndre Fischer {
54ff12d537SAndre Fischer public:
55ff12d537SAndre Fischer     void operator() (ResourceManager* pObject)
56ff12d537SAndre Fischer     {
57ff12d537SAndre Fischer         delete pObject;
58ff12d537SAndre Fischer     }
59ff12d537SAndre Fischer };
60ff12d537SAndre Fischer 
61ff12d537SAndre Fischer 
62ff12d537SAndre Fischer ResourceManager& ResourceManager::Instance (void)
63ff12d537SAndre Fischer {
64ff12d537SAndre Fischer     static ResourceManager maInstance;
65ff12d537SAndre Fischer     return maInstance;
66ff12d537SAndre Fischer }
67ff12d537SAndre Fischer 
68ff12d537SAndre Fischer 
69ff12d537SAndre Fischer 
70ff12d537SAndre Fischer 
71ff12d537SAndre Fischer ResourceManager::ResourceManager (void)
72ff12d537SAndre Fischer     : maDecks(),
73ff12d537SAndre Fischer       maPanels(),
74ff12d537SAndre Fischer       maProcessedApplications()
75ff12d537SAndre Fischer {
76ff12d537SAndre Fischer     ReadDeckList();
77ff12d537SAndre Fischer     ReadPanelList();
78ff12d537SAndre Fischer }
79ff12d537SAndre Fischer 
80ff12d537SAndre Fischer 
81ff12d537SAndre Fischer 
82ff12d537SAndre Fischer 
83ff12d537SAndre Fischer ResourceManager::~ResourceManager (void)
84ff12d537SAndre Fischer {
85ff12d537SAndre Fischer     maPanels.clear();
86ff12d537SAndre Fischer     maDecks.clear();
87ff12d537SAndre Fischer }
88ff12d537SAndre Fischer 
89ff12d537SAndre Fischer 
90ff12d537SAndre Fischer 
91ff12d537SAndre Fischer 
92ff12d537SAndre Fischer const DeckDescriptor* ResourceManager::GetBestMatchingDeck (
937a32b0c8SAndre Fischer     const Context& rContext,
94ff12d537SAndre Fischer     const Reference<frame::XFrame>& rxFrame)
95ff12d537SAndre Fischer {
96ff12d537SAndre Fischer     ReadLegacyAddons(rxFrame);
97ff12d537SAndre Fischer 
98*f120fe41SAndre Fischer     for (DeckContainer::const_iterator iDeck(maDecks.begin()), iEnd(maDecks.end());
99ff12d537SAndre Fischer          iDeck!=iEnd;
100ff12d537SAndre Fischer          ++iDeck)
101ff12d537SAndre Fischer     {
102*f120fe41SAndre Fischer         if (iDeck->maContextList.GetMatch(rContext) != NULL)
103*f120fe41SAndre Fischer             return &*iDeck;
104ff12d537SAndre Fischer     }
105*f120fe41SAndre Fischer     return NULL;
106ff12d537SAndre Fischer }
107ff12d537SAndre Fischer 
108ff12d537SAndre Fischer 
109ff12d537SAndre Fischer 
110ff12d537SAndre Fischer 
11195a18594SAndre Fischer const DeckDescriptor* ResourceManager::GetDeckDescriptor (
11295a18594SAndre Fischer     const ::rtl::OUString& rsDeckId) const
11395a18594SAndre Fischer {
11495a18594SAndre Fischer     for (DeckContainer::const_iterator
11595a18594SAndre Fischer              iDeck(maDecks.begin()),
11695a18594SAndre Fischer              iEnd(maDecks.end());
11795a18594SAndre Fischer          iDeck!=iEnd;
11895a18594SAndre Fischer          ++iDeck)
11995a18594SAndre Fischer     {
12095a18594SAndre Fischer         if (iDeck->msId.equals(rsDeckId))
12195a18594SAndre Fischer             return &*iDeck;
12295a18594SAndre Fischer     }
12395a18594SAndre Fischer     return NULL;
12495a18594SAndre Fischer }
12595a18594SAndre Fischer 
12695a18594SAndre Fischer 
12795a18594SAndre Fischer 
12895a18594SAndre Fischer 
12995a18594SAndre Fischer const PanelDescriptor* ResourceManager::GetPanelDescriptor (
13095a18594SAndre Fischer     const ::rtl::OUString& rsPanelId) const
13195a18594SAndre Fischer {
13295a18594SAndre Fischer     for (PanelContainer::const_iterator
13395a18594SAndre Fischer              iPanel(maPanels.begin()),
13495a18594SAndre Fischer              iEnd(maPanels.end());
13595a18594SAndre Fischer          iPanel!=iEnd;
13695a18594SAndre Fischer          ++iPanel)
13795a18594SAndre Fischer     {
13895a18594SAndre Fischer         if (iPanel->msId.equals(rsPanelId))
13995a18594SAndre Fischer             return &*iPanel;
14095a18594SAndre Fischer     }
14195a18594SAndre Fischer     return NULL;
14295a18594SAndre Fischer }
14395a18594SAndre Fischer 
14495a18594SAndre Fischer 
14595a18594SAndre Fischer 
14695a18594SAndre Fischer 
14795a18594SAndre Fischer void ResourceManager::SetIsDeckEnabled (
14895a18594SAndre Fischer     const ::rtl::OUString& rsDeckId,
14995a18594SAndre Fischer     const bool bIsEnabled)
15095a18594SAndre Fischer {
15195a18594SAndre Fischer     for (DeckContainer::iterator
15295a18594SAndre Fischer              iDeck(maDecks.begin()),
15395a18594SAndre Fischer              iEnd(maDecks.end());
15495a18594SAndre Fischer          iDeck!=iEnd;
15595a18594SAndre Fischer          ++iDeck)
15695a18594SAndre Fischer     {
15795a18594SAndre Fischer         if (iDeck->msId.equals(rsDeckId))
15895a18594SAndre Fischer         {
15995a18594SAndre Fischer             iDeck->mbIsEnabled = bIsEnabled;
16095a18594SAndre Fischer             return;
16195a18594SAndre Fischer         }
16295a18594SAndre Fischer     }
16395a18594SAndre Fischer }
16495a18594SAndre Fischer 
16595a18594SAndre Fischer 
16695a18594SAndre Fischer 
16795a18594SAndre Fischer 
16895a18594SAndre Fischer const ResourceManager::IdContainer& ResourceManager::GetMatchingDecks (
16995a18594SAndre Fischer     IdContainer& rDeckIds,
1707a32b0c8SAndre Fischer     const Context& rContext,
171ff12d537SAndre Fischer     const Reference<frame::XFrame>& rxFrame)
172ff12d537SAndre Fischer {
173ff12d537SAndre Fischer     ReadLegacyAddons(rxFrame);
174ff12d537SAndre Fischer 
1757a32b0c8SAndre Fischer     ::std::multimap<sal_Int32,OUString> aOrderedIds;
176ff12d537SAndre Fischer     for (DeckContainer::const_iterator
177ff12d537SAndre Fischer              iDeck(maDecks.begin()),
178ff12d537SAndre Fischer              iEnd (maDecks.end());
179ff12d537SAndre Fischer          iDeck!=iEnd;
180ff12d537SAndre Fischer          ++iDeck)
181ff12d537SAndre Fischer     {
1827a32b0c8SAndre Fischer         const DeckDescriptor& rDeckDescriptor (*iDeck);
183*f120fe41SAndre Fischer         if (rDeckDescriptor.maContextList.GetMatch(rContext) != NULL)
1847a32b0c8SAndre Fischer             aOrderedIds.insert(::std::multimap<sal_Int32,OUString>::value_type(
1857a32b0c8SAndre Fischer                     rDeckDescriptor.mnOrderIndex,
1867a32b0c8SAndre Fischer                     rDeckDescriptor.msId));
187ff12d537SAndre Fischer     }
188ff12d537SAndre Fischer 
1897a32b0c8SAndre Fischer     for (::std::multimap<sal_Int32,OUString>::const_iterator
1907a32b0c8SAndre Fischer              iId(aOrderedIds.begin()),
1917a32b0c8SAndre Fischer              iEnd(aOrderedIds.end());
1927a32b0c8SAndre Fischer          iId!=iEnd;
1937a32b0c8SAndre Fischer          ++iId)
1947a32b0c8SAndre Fischer     {
1957a32b0c8SAndre Fischer         rDeckIds.push_back(iId->second);
1967a32b0c8SAndre Fischer     }
1977a32b0c8SAndre Fischer 
19895a18594SAndre Fischer     return rDeckIds;
199ff12d537SAndre Fischer }
200ff12d537SAndre Fischer 
201ff12d537SAndre Fischer 
202ff12d537SAndre Fischer 
203ff12d537SAndre Fischer 
204*f120fe41SAndre Fischer const ResourceManager::PanelContextDescriptorContainer& ResourceManager::GetMatchingPanels (
205*f120fe41SAndre Fischer     PanelContextDescriptorContainer& rPanelIds,
2067a32b0c8SAndre Fischer     const Context& rContext,
207ff12d537SAndre Fischer     const ::rtl::OUString& rsDeckId,
208ff12d537SAndre Fischer     const Reference<frame::XFrame>& rxFrame)
209ff12d537SAndre Fischer {
210ff12d537SAndre Fischer     ReadLegacyAddons(rxFrame);
211ff12d537SAndre Fischer 
212*f120fe41SAndre Fischer     ::std::multimap<sal_Int32,PanelContextDescriptor> aOrderedIds;
213ff12d537SAndre Fischer     for (PanelContainer::const_iterator
214ff12d537SAndre Fischer              iPanel(maPanels.begin()),
215ff12d537SAndre Fischer              iEnd(maPanels.end());
216ff12d537SAndre Fischer          iPanel!=iEnd;
217ff12d537SAndre Fischer          ++iPanel)
218ff12d537SAndre Fischer     {
219ff12d537SAndre Fischer         const PanelDescriptor& rPanelDescriptor (*iPanel);
220ff12d537SAndre Fischer         if (rPanelDescriptor.msDeckId.equals(rsDeckId))
221*f120fe41SAndre Fischer         {
222*f120fe41SAndre Fischer             const ContextList::Entry* pEntry = rPanelDescriptor.maContextList.GetMatch(rContext);
223*f120fe41SAndre Fischer             if (pEntry != NULL)
224*f120fe41SAndre Fischer             {
225*f120fe41SAndre Fischer                 PanelContextDescriptor aPanelContextDescriptor;
226*f120fe41SAndre Fischer                 aPanelContextDescriptor.msId = rPanelDescriptor.msId;
227*f120fe41SAndre Fischer                 aPanelContextDescriptor.msMenuCommand = pEntry->msMenuCommand;
228*f120fe41SAndre Fischer                 aPanelContextDescriptor.mbIsInitiallyVisible = pEntry->mbIsInitiallyVisible;
229*f120fe41SAndre Fischer                 aOrderedIds.insert(::std::multimap<sal_Int32,PanelContextDescriptor>::value_type(
2307a32b0c8SAndre Fischer                         rPanelDescriptor.mnOrderIndex,
231*f120fe41SAndre Fischer                         aPanelContextDescriptor));
232*f120fe41SAndre Fischer             }
233*f120fe41SAndre Fischer         }
234ff12d537SAndre Fischer     }
235ff12d537SAndre Fischer 
236*f120fe41SAndre Fischer     for (::std::multimap<sal_Int32,PanelContextDescriptor>::const_iterator
23795a18594SAndre Fischer              iId(aOrderedIds.begin()),
23895a18594SAndre Fischer              iEnd(aOrderedIds.end());
23995a18594SAndre Fischer          iId!=iEnd;
24095a18594SAndre Fischer          ++iId)
24195a18594SAndre Fischer     {
24295a18594SAndre Fischer         rPanelIds.push_back(iId->second);
24395a18594SAndre Fischer     }
24495a18594SAndre Fischer 
24595a18594SAndre Fischer     return rPanelIds;
246ff12d537SAndre Fischer }
247ff12d537SAndre Fischer 
248ff12d537SAndre Fischer 
249ff12d537SAndre Fischer 
250ff12d537SAndre Fischer 
251ff12d537SAndre Fischer void ResourceManager::ReadDeckList (void)
252ff12d537SAndre Fischer {
253ff12d537SAndre Fischer     const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory());
254ff12d537SAndre Fischer     const ::utl::OConfigurationTreeRoot aDeckRootNode (
255ff12d537SAndre Fischer         aContext,
256ff12d537SAndre Fischer         A2S("org.openoffice.Office.UI.Sidebar/Content/DeckList"),
257ff12d537SAndre Fischer         false);
258ff12d537SAndre Fischer     if ( ! aDeckRootNode.isValid() )
259ff12d537SAndre Fischer         return;
260ff12d537SAndre Fischer 
261ff12d537SAndre Fischer     const Sequence<OUString> aDeckNodeNames (aDeckRootNode.getNodeNames());
262ff12d537SAndre Fischer     const sal_Int32 nCount (aDeckNodeNames.getLength());
263ff12d537SAndre Fischer     maDecks.resize(nCount);
264ff12d537SAndre Fischer     sal_Int32 nWriteIndex(0);
265ff12d537SAndre Fischer     for (sal_Int32 nReadIndex(0); nReadIndex<nCount; ++nReadIndex)
266ff12d537SAndre Fischer     {
267ff12d537SAndre Fischer         const ::utl::OConfigurationNode aDeckNode (aDeckRootNode.openNode(aDeckNodeNames[nReadIndex]));
268ff12d537SAndre Fischer         if ( ! aDeckNode.isValid())
269ff12d537SAndre Fischer             continue;
270ff12d537SAndre Fischer 
271ff12d537SAndre Fischer         DeckDescriptor& rDeckDescriptor (maDecks[nWriteIndex++]);
272ff12d537SAndre Fischer 
2737a32b0c8SAndre Fischer         rDeckDescriptor.msTitle = ::comphelper::getString(
2747a32b0c8SAndre Fischer             aDeckNode.getNodeValue("Title"));
2757a32b0c8SAndre Fischer         rDeckDescriptor.msId = ::comphelper::getString(
2767a32b0c8SAndre Fischer             aDeckNode.getNodeValue("Id"));
2777a32b0c8SAndre Fischer         rDeckDescriptor.msIconURL = ::comphelper::getString(
2787a32b0c8SAndre Fischer             aDeckNode.getNodeValue("IconURL"));
2797a32b0c8SAndre Fischer         rDeckDescriptor.msHighContrastIconURL = ::comphelper::getString(
2807a32b0c8SAndre Fischer             aDeckNode.getNodeValue("HighContrastIconURL"));
2817a32b0c8SAndre Fischer         rDeckDescriptor.msHelpURL = ::comphelper::getString(
2827a32b0c8SAndre Fischer             aDeckNode.getNodeValue("HelpURL"));
283ff12d537SAndre Fischer         rDeckDescriptor.msHelpText = rDeckDescriptor.msTitle;
28495a18594SAndre Fischer         rDeckDescriptor.mbIsEnabled = true;
2857a32b0c8SAndre Fischer         rDeckDescriptor.mnOrderIndex = ::comphelper::getINT32(
2867a32b0c8SAndre Fischer             aDeckNode.getNodeValue("OrderIndex"));
2877a32b0c8SAndre Fischer 
288*f120fe41SAndre Fischer         ReadContextList(
289*f120fe41SAndre Fischer             aDeckNode,
290*f120fe41SAndre Fischer             rDeckDescriptor.maContextList,
291*f120fe41SAndre Fischer             OUString());
292ff12d537SAndre Fischer     }
293ff12d537SAndre Fischer 
294ff12d537SAndre Fischer     // When there where invalid nodes then we have to adapt the size
295ff12d537SAndre Fischer     // of the deck vector.
296ff12d537SAndre Fischer     if (nWriteIndex<nCount)
297ff12d537SAndre Fischer         maDecks.resize(nWriteIndex);
298ff12d537SAndre Fischer }
299ff12d537SAndre Fischer 
300ff12d537SAndre Fischer 
301ff12d537SAndre Fischer 
302ff12d537SAndre Fischer 
303ff12d537SAndre Fischer void ResourceManager::ReadPanelList (void)
304ff12d537SAndre Fischer {
305ff12d537SAndre Fischer     const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory());
306ff12d537SAndre Fischer     const ::utl::OConfigurationTreeRoot aPanelRootNode (
307ff12d537SAndre Fischer         aContext,
308ff12d537SAndre Fischer         A2S("org.openoffice.Office.UI.Sidebar/Content/PanelList"),
309ff12d537SAndre Fischer         false);
310ff12d537SAndre Fischer     if ( ! aPanelRootNode.isValid() )
311ff12d537SAndre Fischer         return;
312ff12d537SAndre Fischer 
313ff12d537SAndre Fischer     const Sequence<OUString> aPanelNodeNames (aPanelRootNode.getNodeNames());
314ff12d537SAndre Fischer     const sal_Int32 nCount (aPanelNodeNames.getLength());
315ff12d537SAndre Fischer     maPanels.resize(nCount);
316ff12d537SAndre Fischer     sal_Int32 nWriteIndex (0);
317ff12d537SAndre Fischer     for (sal_Int32 nReadIndex(0); nReadIndex<nCount; ++nReadIndex)
318ff12d537SAndre Fischer     {
319ff12d537SAndre Fischer         const ::utl::OConfigurationNode aPanelNode (aPanelRootNode.openNode(aPanelNodeNames[nReadIndex]));
320ff12d537SAndre Fischer         if ( ! aPanelNode.isValid())
321ff12d537SAndre Fischer             continue;
322ff12d537SAndre Fischer 
323ff12d537SAndre Fischer         PanelDescriptor& rPanelDescriptor (maPanels[nWriteIndex++]);
324ff12d537SAndre Fischer 
325ff12d537SAndre Fischer         rPanelDescriptor.msTitle = ::comphelper::getString(
326ff12d537SAndre Fischer             aPanelNode.getNodeValue("Title"));
327ff12d537SAndre Fischer         rPanelDescriptor.mbIsTitleBarOptional = ::comphelper::getBOOL(
328ff12d537SAndre Fischer             aPanelNode.getNodeValue("TitleBarIsOptional"));
329ff12d537SAndre Fischer         rPanelDescriptor.msId = ::comphelper::getString(
330ff12d537SAndre Fischer             aPanelNode.getNodeValue("Id"));
331ff12d537SAndre Fischer         rPanelDescriptor.msDeckId = ::comphelper::getString(
332ff12d537SAndre Fischer             aPanelNode.getNodeValue("DeckId"));
333ff12d537SAndre Fischer         rPanelDescriptor.msHelpURL = ::comphelper::getString(
334ff12d537SAndre Fischer             aPanelNode.getNodeValue("HelpURL"));
335ff12d537SAndre Fischer         rPanelDescriptor.msImplementationURL = ::comphelper::getString(
336ff12d537SAndre Fischer             aPanelNode.getNodeValue("ImplementationURL"));
33795a18594SAndre Fischer         rPanelDescriptor.mnOrderIndex = ::comphelper::getINT32(
33895a18594SAndre Fischer             aPanelNode.getNodeValue("OrderIndex"));
3397a32b0c8SAndre Fischer         rPanelDescriptor.mbWantsCanvas = ::comphelper::getBOOL(
3407a32b0c8SAndre Fischer             aPanelNode.getNodeValue("WantsCanvas"));
341*f120fe41SAndre Fischer         const OUString sDefaultMenuCommand (::comphelper::getString(
342*f120fe41SAndre Fischer                 aPanelNode.getNodeValue("DefaultMenuCommand")));
343*f120fe41SAndre Fischer 
344*f120fe41SAndre Fischer         ReadContextList(
345*f120fe41SAndre Fischer             aPanelNode,
346*f120fe41SAndre Fischer             rPanelDescriptor.maContextList,
347*f120fe41SAndre Fischer             sDefaultMenuCommand);
348ff12d537SAndre Fischer     }
349ff12d537SAndre Fischer 
350ff12d537SAndre Fischer     // When there where invalid nodes then we have to adapt the size
351ff12d537SAndre Fischer     // of the deck vector.
352ff12d537SAndre Fischer     if (nWriteIndex<nCount)
353ff12d537SAndre Fischer         maPanels.resize(nWriteIndex);
354ff12d537SAndre Fischer }
355ff12d537SAndre Fischer 
356ff12d537SAndre Fischer 
357ff12d537SAndre Fischer 
358ff12d537SAndre Fischer 
359*f120fe41SAndre Fischer void ResourceManager::ReadContextList (
360*f120fe41SAndre Fischer     const ::utl::OConfigurationNode& rParentNode,
361*f120fe41SAndre Fischer     ContextList& rContextList,
362*f120fe41SAndre Fischer     const OUString& rsDefaultMenuCommand) const
363ff12d537SAndre Fischer {
364*f120fe41SAndre Fischer     const Any aValue = rParentNode.getNodeValue("ContextList");
365*f120fe41SAndre Fischer     Sequence<OUString> aValues;
366*f120fe41SAndre Fischer     sal_Int32 nCount;
367*f120fe41SAndre Fischer     if (aValue >>= aValues)
368*f120fe41SAndre Fischer         nCount = aValues.getLength();
369*f120fe41SAndre Fischer     else
370*f120fe41SAndre Fischer         nCount = 0;
371*f120fe41SAndre Fischer 
372*f120fe41SAndre Fischer     for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
373ff12d537SAndre Fischer     {
374*f120fe41SAndre Fischer         const OUString sValue (aValues[nIndex]);
375*f120fe41SAndre Fischer         sal_Int32 nCharacterIndex (0);
376*f120fe41SAndre Fischer         const OUString sApplicationName (sValue.getToken(0, ',', nCharacterIndex).trim());
377*f120fe41SAndre Fischer         if (nCharacterIndex < 0)
378*f120fe41SAndre Fischer         {
379*f120fe41SAndre Fischer             if (sApplicationName.getLength() == 0)
380*f120fe41SAndre Fischer             {
381*f120fe41SAndre Fischer                 // This is a valid case: in the XML file the separator
382*f120fe41SAndre Fischer                 // was used as terminator.  Using it in the last line
383*f120fe41SAndre Fischer                 // creates an additional but empty entry.
384*f120fe41SAndre Fischer                 break;
385*f120fe41SAndre Fischer             }
386*f120fe41SAndre Fischer             else
387*f120fe41SAndre Fischer             {
388*f120fe41SAndre Fischer                 OSL_ASSERT("expecting three or four values per ContextList entry, separated by comma");
389*f120fe41SAndre Fischer                 continue;
390*f120fe41SAndre Fischer             }
391*f120fe41SAndre Fischer         }
3927a32b0c8SAndre Fischer 
393*f120fe41SAndre Fischer         const OUString sContextName (sValue.getToken(0, ',', nCharacterIndex).trim());
394*f120fe41SAndre Fischer         if (nCharacterIndex < 0)
3957a32b0c8SAndre Fischer         {
396*f120fe41SAndre Fischer             OSL_ASSERT("expecting three or four values per ContextList entry, separated by comma");
397*f120fe41SAndre Fischer             continue;
398*f120fe41SAndre Fischer         }
399*f120fe41SAndre Fischer 
400*f120fe41SAndre Fischer         const OUString sInitialState (sValue.getToken(0, ',', nCharacterIndex).trim());
401*f120fe41SAndre Fischer 
402*f120fe41SAndre Fischer         // The fourth argument is optional.
403*f120fe41SAndre Fischer         const OUString sMenuCommandOverride (
404*f120fe41SAndre Fischer             nCharacterIndex<0
405*f120fe41SAndre Fischer                 ? OUString()
406*f120fe41SAndre Fischer                 : sValue.getToken(0, ',', nCharacterIndex).trim());
407*f120fe41SAndre Fischer         const OUString sMenuCommand (
408*f120fe41SAndre Fischer             sMenuCommandOverride.getLength()>0
409*f120fe41SAndre Fischer                 ? (sMenuCommandOverride.equalsAscii("none")
410*f120fe41SAndre Fischer                     ? OUString()
411*f120fe41SAndre Fischer                     : sMenuCommandOverride)
412*f120fe41SAndre Fischer                 : rsDefaultMenuCommand);
413*f120fe41SAndre Fischer 
414*f120fe41SAndre Fischer         EnumContext::Application eApplication (EnumContext::GetApplicationEnum(sApplicationName));
415*f120fe41SAndre Fischer         bool bApplicationIsDrawAndImpress = false;
416*f120fe41SAndre Fischer         if (eApplication == EnumContext::Application_None
417*f120fe41SAndre Fischer             && !sApplicationName.equals(EnumContext::GetApplicationName(EnumContext::Application_None)))
418*f120fe41SAndre Fischer         {
419*f120fe41SAndre Fischer             // Handle some special names: abbreviations that make
420*f120fe41SAndre Fischer             // context descriptions more readable.
421*f120fe41SAndre Fischer             if (sApplicationName.equalsAscii("Writer"))
422*f120fe41SAndre Fischer                 eApplication = EnumContext::Application_Writer;
423*f120fe41SAndre Fischer             else if (sApplicationName.equalsAscii("Calc"))
424*f120fe41SAndre Fischer                 eApplication = EnumContext::Application_Calc;
425*f120fe41SAndre Fischer             else if (sApplicationName.equalsAscii("Draw"))
426*f120fe41SAndre Fischer                 eApplication = EnumContext::Application_Draw;
427*f120fe41SAndre Fischer             else if (sApplicationName.equalsAscii("Impress"))
428*f120fe41SAndre Fischer                 eApplication = EnumContext::Application_Impress;
429*f120fe41SAndre Fischer             else if (sApplicationName.equalsAscii("DrawImpress"))
430*f120fe41SAndre Fischer             {
431*f120fe41SAndre Fischer                 // A special case among the special names:  it is
432*f120fe41SAndre Fischer                 // common to use the same context descriptions for
433*f120fe41SAndre Fischer                 // both Draw and Impress.  This special case helps to
434*f120fe41SAndre Fischer                 // avoid duplication in the .xcu file.
435*f120fe41SAndre Fischer                 bApplicationIsDrawAndImpress = true;
436*f120fe41SAndre Fischer             }
437*f120fe41SAndre Fischer             else
438*f120fe41SAndre Fischer             {
439*f120fe41SAndre Fischer                 OSL_ASSERT("application name not recognized");
440*f120fe41SAndre Fischer                 continue;
441*f120fe41SAndre Fischer             }
4427a32b0c8SAndre Fischer         }
4437a32b0c8SAndre Fischer 
444*f120fe41SAndre Fischer         const EnumContext::Context eContext (EnumContext::GetContextEnum(sContextName));
445*f120fe41SAndre Fischer         if (eContext == EnumContext::Context_Unknown)
446*f120fe41SAndre Fischer         {
447*f120fe41SAndre Fischer             OSL_ASSERT("context name not recognized");
448*f120fe41SAndre Fischer             continue;
449*f120fe41SAndre Fischer         }
450*f120fe41SAndre Fischer 
451*f120fe41SAndre Fischer         bool bIsInitiallyVisible;
452*f120fe41SAndre Fischer         if (sInitialState.equalsAscii("visible"))
453*f120fe41SAndre Fischer             bIsInitiallyVisible = true;
454*f120fe41SAndre Fischer         else if (sInitialState.equalsAscii("hidden"))
455*f120fe41SAndre Fischer             bIsInitiallyVisible = false;
456*f120fe41SAndre Fischer         else
457*f120fe41SAndre Fischer         {
458*f120fe41SAndre Fischer             OSL_ASSERT("unrecognized state");
459*f120fe41SAndre Fischer             continue;
460*f120fe41SAndre Fischer         }
461*f120fe41SAndre Fischer 
462*f120fe41SAndre Fischer         if (bApplicationIsDrawAndImpress)
463*f120fe41SAndre Fischer         {
464*f120fe41SAndre Fischer             // Add the context description for both Draw and Impress.
465*f120fe41SAndre Fischer             rContextList.AddContextDescription(
466*f120fe41SAndre Fischer                 Context(
467*f120fe41SAndre Fischer                     EnumContext::GetApplicationName(EnumContext::Application_Draw),
468*f120fe41SAndre Fischer                     EnumContext::GetContextName(eContext)),
469*f120fe41SAndre Fischer                 bIsInitiallyVisible,
470*f120fe41SAndre Fischer                 sMenuCommand);
471*f120fe41SAndre Fischer             rContextList.AddContextDescription(
472*f120fe41SAndre Fischer                 Context(
473*f120fe41SAndre Fischer                     EnumContext::GetApplicationName(EnumContext::Application_Impress),
474*f120fe41SAndre Fischer                     EnumContext::GetContextName(eContext)),
475*f120fe41SAndre Fischer                 bIsInitiallyVisible,
476*f120fe41SAndre Fischer                 sMenuCommand);
477*f120fe41SAndre Fischer         }
478*f120fe41SAndre Fischer         else
479*f120fe41SAndre Fischer             rContextList.AddContextDescription(
480*f120fe41SAndre Fischer                 Context(
481*f120fe41SAndre Fischer                     EnumContext::GetApplicationName(eApplication),
482*f120fe41SAndre Fischer                     EnumContext::GetContextName(eContext)),
483*f120fe41SAndre Fischer                 bIsInitiallyVisible,
484*f120fe41SAndre Fischer                 sMenuCommand);
485ff12d537SAndre Fischer     }
486ff12d537SAndre Fischer }
487ff12d537SAndre Fischer 
488ff12d537SAndre Fischer 
489ff12d537SAndre Fischer 
490ff12d537SAndre Fischer 
491ff12d537SAndre Fischer void ResourceManager::ReadLegacyAddons (const Reference<frame::XFrame>& rxFrame)
492ff12d537SAndre Fischer {
493ff12d537SAndre Fischer     // Get module name for given frame.
494ff12d537SAndre Fischer     ::rtl::OUString sModuleName (GetModuleName(rxFrame));
495ff12d537SAndre Fischer     if (sModuleName.getLength() == 0)
496ff12d537SAndre Fischer         return;
497ff12d537SAndre Fischer     if (maProcessedApplications.find(sModuleName) != maProcessedApplications.end())
498ff12d537SAndre Fischer     {
499ff12d537SAndre Fischer         // Addons for this application have already been read.
500ff12d537SAndre Fischer         // There is nothing more to do.
501ff12d537SAndre Fischer         return;
502ff12d537SAndre Fischer     }
503ff12d537SAndre Fischer 
504ff12d537SAndre Fischer     // Mark module as processed.  Even when there is an error that
505ff12d537SAndre Fischer     // prevents the configuration data from being read, this error
506ff12d537SAndre Fischer     // will not be triggered a second time.
507ff12d537SAndre Fischer     maProcessedApplications.insert(sModuleName);
508ff12d537SAndre Fischer 
509ff12d537SAndre Fischer     // Get access to the configuration root node for the application.
510ff12d537SAndre Fischer     ::utl::OConfigurationTreeRoot aLegacyRootNode (GetLegacyAddonRootNode(sModuleName));
511ff12d537SAndre Fischer     if ( ! aLegacyRootNode.isValid())
512ff12d537SAndre Fischer         return;
513ff12d537SAndre Fischer 
514ff12d537SAndre Fischer     // Process child nodes.
515ff12d537SAndre Fischer     ::std::vector<OUString> aMatchingNodeNames;
516ff12d537SAndre Fischer     GetToolPanelNodeNames(aMatchingNodeNames, aLegacyRootNode);
517ff12d537SAndre Fischer     const sal_Int32 nCount (aMatchingNodeNames.size());
51895a18594SAndre Fischer     size_t nDeckWriteIndex (maDecks.size());
51995a18594SAndre Fischer     size_t nPanelWriteIndex (maPanels.size());
520ff12d537SAndre Fischer     maDecks.resize(maDecks.size() + nCount);
521ff12d537SAndre Fischer     maPanels.resize(maPanels.size() + nCount);
522ff12d537SAndre Fischer     for (sal_Int32 nReadIndex(0); nReadIndex<nCount; ++nReadIndex)
523ff12d537SAndre Fischer     {
524ff12d537SAndre Fischer         const OUString& rsNodeName (aMatchingNodeNames[nReadIndex]);
525ff12d537SAndre Fischer         const ::utl::OConfigurationNode aChildNode (aLegacyRootNode.openNode(rsNodeName));
526ff12d537SAndre Fischer         if ( ! aChildNode.isValid())
527ff12d537SAndre Fischer             continue;
528ff12d537SAndre Fischer 
529ff12d537SAndre Fischer         DeckDescriptor& rDeckDescriptor (maDecks[nDeckWriteIndex++]);
530ff12d537SAndre Fischer         rDeckDescriptor.msTitle = ::comphelper::getString(aChildNode.getNodeValue("UIName"));
531ff12d537SAndre Fischer         rDeckDescriptor.msId = rsNodeName;
532ff12d537SAndre Fischer         rDeckDescriptor.msIconURL = ::comphelper::getString(aChildNode.getNodeValue("ImageURL"));
533ff12d537SAndre Fischer         rDeckDescriptor.msHighContrastIconURL = rDeckDescriptor.msIconURL;
534ff12d537SAndre Fischer         rDeckDescriptor.msHelpURL = ::comphelper::getString(aChildNode.getNodeValue("HelpURL"));
535ff12d537SAndre Fischer         rDeckDescriptor.msHelpText = rDeckDescriptor.msTitle;
536*f120fe41SAndre Fischer         rDeckDescriptor.maContextList.AddContextDescription(Context(sModuleName, A2S("any")), true, OUString());
53795a18594SAndre Fischer         rDeckDescriptor.mbIsEnabled = true;
538ff12d537SAndre Fischer 
539ff12d537SAndre Fischer         PanelDescriptor& rPanelDescriptor (maPanels[nPanelWriteIndex++]);
540ff12d537SAndre Fischer         rPanelDescriptor.msTitle = ::comphelper::getString(aChildNode.getNodeValue("UIName"));
5417a32b0c8SAndre Fischer         rPanelDescriptor.mbIsTitleBarOptional = true;
542ff12d537SAndre Fischer         rPanelDescriptor.msId = rsNodeName;
543ff12d537SAndre Fischer         rPanelDescriptor.msDeckId = rsNodeName;
544ff12d537SAndre Fischer         rPanelDescriptor.msHelpURL = ::comphelper::getString(aChildNode.getNodeValue("HelpURL"));
545*f120fe41SAndre Fischer         rPanelDescriptor.maContextList.AddContextDescription(Context(sModuleName, A2S("any")), true, OUString());
546ff12d537SAndre Fischer         rPanelDescriptor.msImplementationURL = rsNodeName;
547ff12d537SAndre Fischer     }
548ff12d537SAndre Fischer 
549ff12d537SAndre Fischer     // When there where invalid nodes then we have to adapt the size
550ff12d537SAndre Fischer     // of the deck and panel vectors.
551ff12d537SAndre Fischer     if (nDeckWriteIndex < maDecks.size())
552ff12d537SAndre Fischer         maDecks.resize(nDeckWriteIndex);
553ff12d537SAndre Fischer     if (nPanelWriteIndex < maPanels.size())
554ff12d537SAndre Fischer         maPanels.resize(nPanelWriteIndex);
555ff12d537SAndre Fischer }
556ff12d537SAndre Fischer 
557ff12d537SAndre Fischer 
558ff12d537SAndre Fischer 
559ff12d537SAndre Fischer 
560ff12d537SAndre Fischer ::rtl::OUString ResourceManager::GetModuleName (
56195a18594SAndre Fischer     const cssu::Reference<css::frame::XFrame>& rxFrame)
562ff12d537SAndre Fischer {
563ff12d537SAndre Fischer     try
564ff12d537SAndre Fischer     {
565ff12d537SAndre Fischer         const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory());
566ff12d537SAndre Fischer         const Reference<frame::XModuleManager> xModuleManager (
567ff12d537SAndre Fischer             aContext.createComponent("com.sun.star.frame.ModuleManager" ),
568ff12d537SAndre Fischer             UNO_QUERY_THROW );
569ff12d537SAndre Fischer         return xModuleManager->identify(rxFrame);
570ff12d537SAndre Fischer     }
571ff12d537SAndre Fischer     catch (const Exception&)
572ff12d537SAndre Fischer     {
573ff12d537SAndre Fischer         DBG_UNHANDLED_EXCEPTION();
574ff12d537SAndre Fischer     }
575ff12d537SAndre Fischer     return OUString();
576ff12d537SAndre Fischer }
577ff12d537SAndre Fischer 
578ff12d537SAndre Fischer 
579ff12d537SAndre Fischer 
580ff12d537SAndre Fischer 
581ff12d537SAndre Fischer ::utl::OConfigurationTreeRoot ResourceManager::GetLegacyAddonRootNode (
582ff12d537SAndre Fischer     const ::rtl::OUString& rsModuleName) const
583ff12d537SAndre Fischer {
584ff12d537SAndre Fischer     try
585ff12d537SAndre Fischer     {
586ff12d537SAndre Fischer         const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory());
587ff12d537SAndre Fischer         const Reference<container::XNameAccess> xModuleAccess (
588ff12d537SAndre Fischer             aContext.createComponent("com.sun.star.frame.ModuleManager"),
589ff12d537SAndre Fischer             UNO_QUERY_THROW);
590ff12d537SAndre Fischer         const ::comphelper::NamedValueCollection aModuleProperties (xModuleAccess->getByName(rsModuleName));
591ff12d537SAndre Fischer         const ::rtl::OUString sWindowStateRef (aModuleProperties.getOrDefault(
592ff12d537SAndre Fischer                 "ooSetupFactoryWindowStateConfigRef",
593ff12d537SAndre Fischer                 ::rtl::OUString()));
594ff12d537SAndre Fischer 
595ff12d537SAndre Fischer         ::rtl::OUStringBuffer aPathComposer;
596ff12d537SAndre Fischer         aPathComposer.appendAscii("org.openoffice.Office.UI.");
597ff12d537SAndre Fischer         aPathComposer.append(sWindowStateRef);
598ff12d537SAndre Fischer         aPathComposer.appendAscii("/UIElements/States");
599ff12d537SAndre Fischer 
600ff12d537SAndre Fischer         return ::utl::OConfigurationTreeRoot(aContext, aPathComposer.makeStringAndClear(), false);
601ff12d537SAndre Fischer     }
602ff12d537SAndre Fischer     catch( const Exception& )
603ff12d537SAndre Fischer     {
604ff12d537SAndre Fischer         DBG_UNHANDLED_EXCEPTION();
605ff12d537SAndre Fischer     }
606ff12d537SAndre Fischer 
607ff12d537SAndre Fischer     return ::utl::OConfigurationTreeRoot();
608ff12d537SAndre Fischer }
609ff12d537SAndre Fischer 
610ff12d537SAndre Fischer 
611ff12d537SAndre Fischer 
612ff12d537SAndre Fischer 
613ff12d537SAndre Fischer void ResourceManager::GetToolPanelNodeNames (
614ff12d537SAndre Fischer     ::std::vector<OUString>& rMatchingNames,
615ff12d537SAndre Fischer     const ::utl::OConfigurationTreeRoot aRoot) const
616ff12d537SAndre Fischer {
617ff12d537SAndre Fischer     Sequence<OUString> aChildNodeNames (aRoot.getNodeNames());
618ff12d537SAndre Fischer     const sal_Int32 nCount (aChildNodeNames.getLength());
619ff12d537SAndre Fischer     for (sal_Int32 nIndex(0); nIndex<nCount; ++nIndex)
620ff12d537SAndre Fischer     {
621ff12d537SAndre Fischer         if (aChildNodeNames[nIndex].matchAsciiL(
622ff12d537SAndre Fischer                 RTL_CONSTASCII_STRINGPARAM( "private:resource/toolpanel/")))
623ff12d537SAndre Fischer             rMatchingNames.push_back(aChildNodeNames[nIndex]);
624ff12d537SAndre Fischer     }
625ff12d537SAndre Fischer }
626ff12d537SAndre Fischer 
627ff12d537SAndre Fischer 
628ff12d537SAndre Fischer 
629ff12d537SAndre Fischer } } // end of namespace sfx2::sidebar
630