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"
2554eaaa32SAndre Fischer #include "Tools.hxx"
2654eaaa32SAndre Fischer 
27ff12d537SAndre Fischer #include <unotools/confignode.hxx>
28ff12d537SAndre Fischer #include <comphelper/componentcontext.hxx>
2995a18594SAndre Fischer #include <comphelper/processfactory.hxx>
30ff12d537SAndre Fischer #include <comphelper/namedvaluecollection.hxx>
3195a18594SAndre Fischer #include <comphelper/types.hxx>
327a32b0c8SAndre Fischer #include <comphelper/stlunosequence.hxx>
337a32b0c8SAndre Fischer 
3495a18594SAndre Fischer #include <rtl/ustrbuf.hxx>
35ff12d537SAndre Fischer #include <tools/diagnose_ex.h>
36ff12d537SAndre Fischer 
3795a18594SAndre Fischer #include <com/sun/star/frame/XModuleManager.hpp>
3895a18594SAndre Fischer 
3995a18594SAndre Fischer #include <map>
4095a18594SAndre Fischer 
41ff12d537SAndre Fischer 
42ff12d537SAndre Fischer 
43ff12d537SAndre Fischer using ::rtl::OUString;
44ff12d537SAndre Fischer using namespace css;
45ff12d537SAndre Fischer using namespace cssu;
46ff12d537SAndre Fischer 
47ff12d537SAndre Fischer namespace sfx2 { namespace sidebar {
48ff12d537SAndre Fischer 
49ff12d537SAndre Fischer #define gsPrivateResourceToolpanelPrefix "private:resource/toolpanel/"
50ff12d537SAndre Fischer 
51ff12d537SAndre Fischer 
52ff12d537SAndre Fischer 
53ff12d537SAndre Fischer class ResourceManager::Deleter
54ff12d537SAndre Fischer {
55ff12d537SAndre Fischer public:
56ff12d537SAndre Fischer     void operator() (ResourceManager* pObject)
57ff12d537SAndre Fischer     {
58ff12d537SAndre Fischer         delete pObject;
59ff12d537SAndre Fischer     }
60ff12d537SAndre Fischer };
61ff12d537SAndre Fischer 
62ff12d537SAndre Fischer 
63ff12d537SAndre Fischer ResourceManager& ResourceManager::Instance (void)
64ff12d537SAndre Fischer {
65ff12d537SAndre Fischer     static ResourceManager maInstance;
66ff12d537SAndre Fischer     return maInstance;
67ff12d537SAndre Fischer }
68ff12d537SAndre Fischer 
69ff12d537SAndre Fischer 
70ff12d537SAndre Fischer 
71ff12d537SAndre Fischer 
72ff12d537SAndre Fischer ResourceManager::ResourceManager (void)
73ff12d537SAndre Fischer     : maDecks(),
74ff12d537SAndre Fischer       maPanels(),
75ff12d537SAndre Fischer       maProcessedApplications()
76ff12d537SAndre Fischer {
77ff12d537SAndre Fischer     ReadDeckList();
78ff12d537SAndre Fischer     ReadPanelList();
79ff12d537SAndre Fischer }
80ff12d537SAndre Fischer 
81ff12d537SAndre Fischer 
82ff12d537SAndre Fischer 
83ff12d537SAndre Fischer 
84ff12d537SAndre Fischer ResourceManager::~ResourceManager (void)
85ff12d537SAndre Fischer {
86ff12d537SAndre Fischer     maPanels.clear();
87ff12d537SAndre Fischer     maDecks.clear();
88ff12d537SAndre Fischer }
89ff12d537SAndre Fischer 
90ff12d537SAndre Fischer 
91ff12d537SAndre Fischer 
92ff12d537SAndre Fischer 
93ff12d537SAndre Fischer const DeckDescriptor* ResourceManager::GetBestMatchingDeck (
947a32b0c8SAndre Fischer     const Context& rContext,
95ff12d537SAndre Fischer     const Reference<frame::XFrame>& rxFrame)
96ff12d537SAndre Fischer {
97ff12d537SAndre Fischer     ReadLegacyAddons(rxFrame);
98ff12d537SAndre Fischer 
99f120fe41SAndre Fischer     for (DeckContainer::const_iterator iDeck(maDecks.begin()), iEnd(maDecks.end());
100ff12d537SAndre Fischer          iDeck!=iEnd;
101ff12d537SAndre Fischer          ++iDeck)
102ff12d537SAndre Fischer     {
103f120fe41SAndre Fischer         if (iDeck->maContextList.GetMatch(rContext) != NULL)
104f120fe41SAndre Fischer             return &*iDeck;
105ff12d537SAndre Fischer     }
106f120fe41SAndre Fischer     return NULL;
107ff12d537SAndre Fischer }
108ff12d537SAndre Fischer 
109ff12d537SAndre Fischer 
110ff12d537SAndre Fischer 
111ff12d537SAndre Fischer 
11295a18594SAndre Fischer const DeckDescriptor* ResourceManager::GetDeckDescriptor (
11395a18594SAndre Fischer     const ::rtl::OUString& rsDeckId) const
11495a18594SAndre Fischer {
11595a18594SAndre Fischer     for (DeckContainer::const_iterator
11695a18594SAndre Fischer              iDeck(maDecks.begin()),
11795a18594SAndre Fischer              iEnd(maDecks.end());
11895a18594SAndre Fischer          iDeck!=iEnd;
11995a18594SAndre Fischer          ++iDeck)
12095a18594SAndre Fischer     {
12195a18594SAndre Fischer         if (iDeck->msId.equals(rsDeckId))
12295a18594SAndre Fischer             return &*iDeck;
12395a18594SAndre Fischer     }
12495a18594SAndre Fischer     return NULL;
12595a18594SAndre Fischer }
12695a18594SAndre Fischer 
12795a18594SAndre Fischer 
12895a18594SAndre Fischer 
12995a18594SAndre Fischer 
13095a18594SAndre Fischer const PanelDescriptor* ResourceManager::GetPanelDescriptor (
13195a18594SAndre Fischer     const ::rtl::OUString& rsPanelId) const
13295a18594SAndre Fischer {
13395a18594SAndre Fischer     for (PanelContainer::const_iterator
13495a18594SAndre Fischer              iPanel(maPanels.begin()),
13595a18594SAndre Fischer              iEnd(maPanels.end());
13695a18594SAndre Fischer          iPanel!=iEnd;
13795a18594SAndre Fischer          ++iPanel)
13895a18594SAndre Fischer     {
13995a18594SAndre Fischer         if (iPanel->msId.equals(rsPanelId))
14095a18594SAndre Fischer             return &*iPanel;
14195a18594SAndre Fischer     }
14295a18594SAndre Fischer     return NULL;
14395a18594SAndre Fischer }
14495a18594SAndre Fischer 
14595a18594SAndre Fischer 
14695a18594SAndre Fischer 
14795a18594SAndre Fischer 
14895a18594SAndre Fischer void ResourceManager::SetIsDeckEnabled (
14995a18594SAndre Fischer     const ::rtl::OUString& rsDeckId,
15095a18594SAndre Fischer     const bool bIsEnabled)
15195a18594SAndre Fischer {
15295a18594SAndre Fischer     for (DeckContainer::iterator
15395a18594SAndre Fischer              iDeck(maDecks.begin()),
15495a18594SAndre Fischer              iEnd(maDecks.end());
15595a18594SAndre Fischer          iDeck!=iEnd;
15695a18594SAndre Fischer          ++iDeck)
15795a18594SAndre Fischer     {
15895a18594SAndre Fischer         if (iDeck->msId.equals(rsDeckId))
15995a18594SAndre Fischer         {
16095a18594SAndre Fischer             iDeck->mbIsEnabled = bIsEnabled;
16195a18594SAndre Fischer             return;
16295a18594SAndre Fischer         }
16395a18594SAndre Fischer     }
16495a18594SAndre Fischer }
16595a18594SAndre Fischer 
16695a18594SAndre Fischer 
16795a18594SAndre Fischer 
16895a18594SAndre Fischer 
16995a18594SAndre Fischer const ResourceManager::IdContainer& ResourceManager::GetMatchingDecks (
17095a18594SAndre Fischer     IdContainer& rDeckIds,
1717a32b0c8SAndre Fischer     const Context& rContext,
172ff12d537SAndre Fischer     const Reference<frame::XFrame>& rxFrame)
173ff12d537SAndre Fischer {
174ff12d537SAndre Fischer     ReadLegacyAddons(rxFrame);
175ff12d537SAndre Fischer 
1767a32b0c8SAndre Fischer     ::std::multimap<sal_Int32,OUString> aOrderedIds;
177ff12d537SAndre Fischer     for (DeckContainer::const_iterator
178ff12d537SAndre Fischer              iDeck(maDecks.begin()),
179ff12d537SAndre Fischer              iEnd (maDecks.end());
180ff12d537SAndre Fischer          iDeck!=iEnd;
181ff12d537SAndre Fischer          ++iDeck)
182ff12d537SAndre Fischer     {
1837a32b0c8SAndre Fischer         const DeckDescriptor& rDeckDescriptor (*iDeck);
184f120fe41SAndre Fischer         if (rDeckDescriptor.maContextList.GetMatch(rContext) != NULL)
1857a32b0c8SAndre Fischer             aOrderedIds.insert(::std::multimap<sal_Int32,OUString>::value_type(
1867a32b0c8SAndre Fischer                     rDeckDescriptor.mnOrderIndex,
1877a32b0c8SAndre Fischer                     rDeckDescriptor.msId));
188ff12d537SAndre Fischer     }
189ff12d537SAndre Fischer 
1907a32b0c8SAndre Fischer     for (::std::multimap<sal_Int32,OUString>::const_iterator
1917a32b0c8SAndre Fischer              iId(aOrderedIds.begin()),
1927a32b0c8SAndre Fischer              iEnd(aOrderedIds.end());
1937a32b0c8SAndre Fischer          iId!=iEnd;
1947a32b0c8SAndre Fischer          ++iId)
1957a32b0c8SAndre Fischer     {
1967a32b0c8SAndre Fischer         rDeckIds.push_back(iId->second);
1977a32b0c8SAndre Fischer     }
1987a32b0c8SAndre Fischer 
19995a18594SAndre Fischer     return rDeckIds;
200ff12d537SAndre Fischer }
201ff12d537SAndre Fischer 
202ff12d537SAndre Fischer 
203ff12d537SAndre Fischer 
204ff12d537SAndre Fischer 
205f120fe41SAndre Fischer const ResourceManager::PanelContextDescriptorContainer& ResourceManager::GetMatchingPanels (
206f120fe41SAndre Fischer     PanelContextDescriptorContainer& rPanelIds,
2077a32b0c8SAndre Fischer     const Context& rContext,
208ff12d537SAndre Fischer     const ::rtl::OUString& rsDeckId,
209ff12d537SAndre Fischer     const Reference<frame::XFrame>& rxFrame)
210ff12d537SAndre Fischer {
211ff12d537SAndre Fischer     ReadLegacyAddons(rxFrame);
212ff12d537SAndre Fischer 
213f120fe41SAndre Fischer     ::std::multimap<sal_Int32,PanelContextDescriptor> aOrderedIds;
214ff12d537SAndre Fischer     for (PanelContainer::const_iterator
215ff12d537SAndre Fischer              iPanel(maPanels.begin()),
216ff12d537SAndre Fischer              iEnd(maPanels.end());
217ff12d537SAndre Fischer          iPanel!=iEnd;
218ff12d537SAndre Fischer          ++iPanel)
219ff12d537SAndre Fischer     {
220ff12d537SAndre Fischer         const PanelDescriptor& rPanelDescriptor (*iPanel);
221ff12d537SAndre Fischer         if (rPanelDescriptor.msDeckId.equals(rsDeckId))
222f120fe41SAndre Fischer         {
223f120fe41SAndre Fischer             const ContextList::Entry* pEntry = rPanelDescriptor.maContextList.GetMatch(rContext);
224f120fe41SAndre Fischer             if (pEntry != NULL)
225f120fe41SAndre Fischer             {
226f120fe41SAndre Fischer                 PanelContextDescriptor aPanelContextDescriptor;
227f120fe41SAndre Fischer                 aPanelContextDescriptor.msId = rPanelDescriptor.msId;
228f120fe41SAndre Fischer                 aPanelContextDescriptor.msMenuCommand = pEntry->msMenuCommand;
229f120fe41SAndre Fischer                 aPanelContextDescriptor.mbIsInitiallyVisible = pEntry->mbIsInitiallyVisible;
230f120fe41SAndre Fischer                 aOrderedIds.insert(::std::multimap<sal_Int32,PanelContextDescriptor>::value_type(
2317a32b0c8SAndre Fischer                         rPanelDescriptor.mnOrderIndex,
232f120fe41SAndre Fischer                         aPanelContextDescriptor));
233f120fe41SAndre Fischer             }
234f120fe41SAndre Fischer         }
235ff12d537SAndre Fischer     }
236ff12d537SAndre Fischer 
237f120fe41SAndre Fischer     for (::std::multimap<sal_Int32,PanelContextDescriptor>::const_iterator
23895a18594SAndre Fischer              iId(aOrderedIds.begin()),
23995a18594SAndre Fischer              iEnd(aOrderedIds.end());
24095a18594SAndre Fischer          iId!=iEnd;
24195a18594SAndre Fischer          ++iId)
24295a18594SAndre Fischer     {
24395a18594SAndre Fischer         rPanelIds.push_back(iId->second);
24495a18594SAndre Fischer     }
24595a18594SAndre Fischer 
24695a18594SAndre Fischer     return rPanelIds;
247ff12d537SAndre Fischer }
248ff12d537SAndre Fischer 
249ff12d537SAndre Fischer 
250ff12d537SAndre Fischer 
251ff12d537SAndre Fischer 
252ff12d537SAndre Fischer void ResourceManager::ReadDeckList (void)
253ff12d537SAndre Fischer {
254ff12d537SAndre Fischer     const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory());
255ff12d537SAndre Fischer     const ::utl::OConfigurationTreeRoot aDeckRootNode (
256ff12d537SAndre Fischer         aContext,
257ff12d537SAndre Fischer         A2S("org.openoffice.Office.UI.Sidebar/Content/DeckList"),
258ff12d537SAndre Fischer         false);
259ff12d537SAndre Fischer     if ( ! aDeckRootNode.isValid() )
260ff12d537SAndre Fischer         return;
261ff12d537SAndre Fischer 
262ff12d537SAndre Fischer     const Sequence<OUString> aDeckNodeNames (aDeckRootNode.getNodeNames());
263ff12d537SAndre Fischer     const sal_Int32 nCount (aDeckNodeNames.getLength());
264ff12d537SAndre Fischer     maDecks.resize(nCount);
265ff12d537SAndre Fischer     sal_Int32 nWriteIndex(0);
266ff12d537SAndre Fischer     for (sal_Int32 nReadIndex(0); nReadIndex<nCount; ++nReadIndex)
267ff12d537SAndre Fischer     {
268ff12d537SAndre Fischer         const ::utl::OConfigurationNode aDeckNode (aDeckRootNode.openNode(aDeckNodeNames[nReadIndex]));
269ff12d537SAndre Fischer         if ( ! aDeckNode.isValid())
270ff12d537SAndre Fischer             continue;
271ff12d537SAndre Fischer 
272ff12d537SAndre Fischer         DeckDescriptor& rDeckDescriptor (maDecks[nWriteIndex++]);
273ff12d537SAndre Fischer 
2747a32b0c8SAndre Fischer         rDeckDescriptor.msTitle = ::comphelper::getString(
2757a32b0c8SAndre Fischer             aDeckNode.getNodeValue("Title"));
2767a32b0c8SAndre Fischer         rDeckDescriptor.msId = ::comphelper::getString(
2777a32b0c8SAndre Fischer             aDeckNode.getNodeValue("Id"));
2787a32b0c8SAndre Fischer         rDeckDescriptor.msIconURL = ::comphelper::getString(
2797a32b0c8SAndre Fischer             aDeckNode.getNodeValue("IconURL"));
2807a32b0c8SAndre Fischer         rDeckDescriptor.msHighContrastIconURL = ::comphelper::getString(
2817a32b0c8SAndre Fischer             aDeckNode.getNodeValue("HighContrastIconURL"));
2827a32b0c8SAndre Fischer         rDeckDescriptor.msHelpURL = ::comphelper::getString(
2837a32b0c8SAndre Fischer             aDeckNode.getNodeValue("HelpURL"));
284ff12d537SAndre Fischer         rDeckDescriptor.msHelpText = rDeckDescriptor.msTitle;
28595a18594SAndre Fischer         rDeckDescriptor.mbIsEnabled = true;
2867a32b0c8SAndre Fischer         rDeckDescriptor.mnOrderIndex = ::comphelper::getINT32(
2877a32b0c8SAndre Fischer             aDeckNode.getNodeValue("OrderIndex"));
2887a32b0c8SAndre Fischer 
289f120fe41SAndre Fischer         ReadContextList(
290f120fe41SAndre Fischer             aDeckNode,
291f120fe41SAndre Fischer             rDeckDescriptor.maContextList,
292f120fe41SAndre Fischer             OUString());
293ff12d537SAndre Fischer     }
294ff12d537SAndre Fischer 
295ff12d537SAndre Fischer     // When there where invalid nodes then we have to adapt the size
296ff12d537SAndre Fischer     // of the deck vector.
297ff12d537SAndre Fischer     if (nWriteIndex<nCount)
298ff12d537SAndre Fischer         maDecks.resize(nWriteIndex);
299ff12d537SAndre Fischer }
300ff12d537SAndre Fischer 
301ff12d537SAndre Fischer 
302ff12d537SAndre Fischer 
303ff12d537SAndre Fischer 
304ff12d537SAndre Fischer void ResourceManager::ReadPanelList (void)
305ff12d537SAndre Fischer {
306ff12d537SAndre Fischer     const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory());
307ff12d537SAndre Fischer     const ::utl::OConfigurationTreeRoot aPanelRootNode (
308ff12d537SAndre Fischer         aContext,
309ff12d537SAndre Fischer         A2S("org.openoffice.Office.UI.Sidebar/Content/PanelList"),
310ff12d537SAndre Fischer         false);
311ff12d537SAndre Fischer     if ( ! aPanelRootNode.isValid() )
312ff12d537SAndre Fischer         return;
313ff12d537SAndre Fischer 
314ff12d537SAndre Fischer     const Sequence<OUString> aPanelNodeNames (aPanelRootNode.getNodeNames());
315ff12d537SAndre Fischer     const sal_Int32 nCount (aPanelNodeNames.getLength());
316ff12d537SAndre Fischer     maPanels.resize(nCount);
317ff12d537SAndre Fischer     sal_Int32 nWriteIndex (0);
318ff12d537SAndre Fischer     for (sal_Int32 nReadIndex(0); nReadIndex<nCount; ++nReadIndex)
319ff12d537SAndre Fischer     {
320ff12d537SAndre Fischer         const ::utl::OConfigurationNode aPanelNode (aPanelRootNode.openNode(aPanelNodeNames[nReadIndex]));
321ff12d537SAndre Fischer         if ( ! aPanelNode.isValid())
322ff12d537SAndre Fischer             continue;
323ff12d537SAndre Fischer 
324ff12d537SAndre Fischer         PanelDescriptor& rPanelDescriptor (maPanels[nWriteIndex++]);
325ff12d537SAndre Fischer 
326ff12d537SAndre Fischer         rPanelDescriptor.msTitle = ::comphelper::getString(
327ff12d537SAndre Fischer             aPanelNode.getNodeValue("Title"));
328ff12d537SAndre Fischer         rPanelDescriptor.mbIsTitleBarOptional = ::comphelper::getBOOL(
329ff12d537SAndre Fischer             aPanelNode.getNodeValue("TitleBarIsOptional"));
330ff12d537SAndre Fischer         rPanelDescriptor.msId = ::comphelper::getString(
331ff12d537SAndre Fischer             aPanelNode.getNodeValue("Id"));
332ff12d537SAndre Fischer         rPanelDescriptor.msDeckId = ::comphelper::getString(
333ff12d537SAndre Fischer             aPanelNode.getNodeValue("DeckId"));
334ff12d537SAndre Fischer         rPanelDescriptor.msHelpURL = ::comphelper::getString(
335ff12d537SAndre Fischer             aPanelNode.getNodeValue("HelpURL"));
336ff12d537SAndre Fischer         rPanelDescriptor.msImplementationURL = ::comphelper::getString(
337ff12d537SAndre Fischer             aPanelNode.getNodeValue("ImplementationURL"));
33895a18594SAndre Fischer         rPanelDescriptor.mnOrderIndex = ::comphelper::getINT32(
33995a18594SAndre Fischer             aPanelNode.getNodeValue("OrderIndex"));
3407a32b0c8SAndre Fischer         rPanelDescriptor.mbWantsCanvas = ::comphelper::getBOOL(
3417a32b0c8SAndre Fischer             aPanelNode.getNodeValue("WantsCanvas"));
342f120fe41SAndre Fischer         const OUString sDefaultMenuCommand (::comphelper::getString(
343f120fe41SAndre Fischer                 aPanelNode.getNodeValue("DefaultMenuCommand")));
34454eaaa32SAndre Fischer 
345f120fe41SAndre Fischer         ReadContextList(
346f120fe41SAndre Fischer             aPanelNode,
347f120fe41SAndre Fischer             rPanelDescriptor.maContextList,
348f120fe41SAndre Fischer             sDefaultMenuCommand);
349ff12d537SAndre Fischer     }
350ff12d537SAndre Fischer 
351ff12d537SAndre Fischer     // When there where invalid nodes then we have to adapt the size
352ff12d537SAndre Fischer     // of the deck vector.
353ff12d537SAndre Fischer     if (nWriteIndex<nCount)
354ff12d537SAndre Fischer         maPanels.resize(nWriteIndex);
355ff12d537SAndre Fischer }
356ff12d537SAndre Fischer 
357ff12d537SAndre Fischer 
358ff12d537SAndre Fischer 
359ff12d537SAndre Fischer 
360f120fe41SAndre Fischer void ResourceManager::ReadContextList (
361f120fe41SAndre Fischer     const ::utl::OConfigurationNode& rParentNode,
362f120fe41SAndre Fischer     ContextList& rContextList,
363f120fe41SAndre Fischer     const OUString& rsDefaultMenuCommand) const
364ff12d537SAndre Fischer {
365f120fe41SAndre Fischer     const Any aValue = rParentNode.getNodeValue("ContextList");
366f120fe41SAndre Fischer     Sequence<OUString> aValues;
367f120fe41SAndre Fischer     sal_Int32 nCount;
368f120fe41SAndre Fischer     if (aValue >>= aValues)
369f120fe41SAndre Fischer         nCount = aValues.getLength();
370f120fe41SAndre Fischer     else
371f120fe41SAndre Fischer         nCount = 0;
372f120fe41SAndre Fischer 
373f120fe41SAndre Fischer     for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
374ff12d537SAndre Fischer     {
375f120fe41SAndre Fischer         const OUString sValue (aValues[nIndex]);
376f120fe41SAndre Fischer         sal_Int32 nCharacterIndex (0);
377f120fe41SAndre Fischer         const OUString sApplicationName (sValue.getToken(0, ',', nCharacterIndex).trim());
378f120fe41SAndre Fischer         if (nCharacterIndex < 0)
379f120fe41SAndre Fischer         {
380f120fe41SAndre Fischer             if (sApplicationName.getLength() == 0)
381f120fe41SAndre Fischer             {
382f120fe41SAndre Fischer                 // This is a valid case: in the XML file the separator
383f120fe41SAndre Fischer                 // was used as terminator.  Using it in the last line
384f120fe41SAndre Fischer                 // creates an additional but empty entry.
385f120fe41SAndre Fischer                 break;
386f120fe41SAndre Fischer             }
387f120fe41SAndre Fischer             else
388f120fe41SAndre Fischer             {
389f120fe41SAndre Fischer                 OSL_ASSERT("expecting three or four values per ContextList entry, separated by comma");
390f120fe41SAndre Fischer                 continue;
391f120fe41SAndre Fischer             }
392f120fe41SAndre Fischer         }
3937a32b0c8SAndre Fischer 
394f120fe41SAndre Fischer         const OUString sContextName (sValue.getToken(0, ',', nCharacterIndex).trim());
395f120fe41SAndre Fischer         if (nCharacterIndex < 0)
3967a32b0c8SAndre Fischer         {
397f120fe41SAndre Fischer             OSL_ASSERT("expecting three or four values per ContextList entry, separated by comma");
398f120fe41SAndre Fischer             continue;
399f120fe41SAndre Fischer         }
400f120fe41SAndre Fischer 
401f120fe41SAndre Fischer         const OUString sInitialState (sValue.getToken(0, ',', nCharacterIndex).trim());
402f120fe41SAndre Fischer 
403f120fe41SAndre Fischer         // The fourth argument is optional.
404f120fe41SAndre Fischer         const OUString sMenuCommandOverride (
405f120fe41SAndre Fischer             nCharacterIndex<0
406f120fe41SAndre Fischer                 ? OUString()
407f120fe41SAndre Fischer                 : sValue.getToken(0, ',', nCharacterIndex).trim());
408f120fe41SAndre Fischer         const OUString sMenuCommand (
409f120fe41SAndre Fischer             sMenuCommandOverride.getLength()>0
410f120fe41SAndre Fischer                 ? (sMenuCommandOverride.equalsAscii("none")
411f120fe41SAndre Fischer                     ? OUString()
412f120fe41SAndre Fischer                     : sMenuCommandOverride)
413f120fe41SAndre Fischer                 : rsDefaultMenuCommand);
414f120fe41SAndre Fischer 
415*85f1aca2SAndre Fischer         // Setup a list of application enums.  Note that the
416*85f1aca2SAndre Fischer         // application name may result in more than one value (eg
417*85f1aca2SAndre Fischer         // DrawImpress will result in two enums, one for Draw and one
418*85f1aca2SAndre Fischer         // for Impress).
419*85f1aca2SAndre Fischer         ::std::vector<EnumContext::Application> aApplications;
420f120fe41SAndre Fischer         EnumContext::Application eApplication (EnumContext::GetApplicationEnum(sApplicationName));
421f120fe41SAndre Fischer         if (eApplication == EnumContext::Application_None
422f120fe41SAndre Fischer             && !sApplicationName.equals(EnumContext::GetApplicationName(EnumContext::Application_None)))
423f120fe41SAndre Fischer         {
424f120fe41SAndre Fischer             // Handle some special names: abbreviations that make
425f120fe41SAndre Fischer             // context descriptions more readable.
426f120fe41SAndre Fischer             if (sApplicationName.equalsAscii("Writer"))
427*85f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_Writer);
428f120fe41SAndre Fischer             else if (sApplicationName.equalsAscii("Calc"))
429*85f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_Calc);
430f120fe41SAndre Fischer             else if (sApplicationName.equalsAscii("Draw"))
431*85f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_Draw);
432f120fe41SAndre Fischer             else if (sApplicationName.equalsAscii("Impress"))
433*85f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_Impress);
434f120fe41SAndre Fischer             else if (sApplicationName.equalsAscii("DrawImpress"))
435f120fe41SAndre Fischer             {
436f120fe41SAndre Fischer                 // A special case among the special names:  it is
437f120fe41SAndre Fischer                 // common to use the same context descriptions for
438f120fe41SAndre Fischer                 // both Draw and Impress.  This special case helps to
439f120fe41SAndre Fischer                 // avoid duplication in the .xcu file.
440*85f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_Draw);
441*85f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_Impress);
442dfbb0ba8SAndre Fischer             }
443*85f1aca2SAndre Fischer             else if (sApplicationName.equalsAscii("WriterVariants"))
444dfbb0ba8SAndre Fischer             {
445*85f1aca2SAndre Fischer                 // Another special case for all Writer variants.
446*85f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_Writer);
447*85f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_WriterGlobal);
448*85f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_WriterWeb);
449*85f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_WriterXML);
450f120fe41SAndre Fischer             }
451f120fe41SAndre Fischer             else
452f120fe41SAndre Fischer             {
453f120fe41SAndre Fischer                 OSL_ASSERT("application name not recognized");
454f120fe41SAndre Fischer                 continue;
455f120fe41SAndre Fischer             }
4567a32b0c8SAndre Fischer         }
457*85f1aca2SAndre Fischer         else
458*85f1aca2SAndre Fischer         {
459*85f1aca2SAndre Fischer             // No conversion of the application name necessary.
460*85f1aca2SAndre Fischer             aApplications.push_back(eApplication);
461*85f1aca2SAndre Fischer         }
462*85f1aca2SAndre Fischer 
463*85f1aca2SAndre Fischer         // Setup the actual context enum.
464f120fe41SAndre Fischer         const EnumContext::Context eContext (EnumContext::GetContextEnum(sContextName));
465f120fe41SAndre Fischer         if (eContext == EnumContext::Context_Unknown)
466f120fe41SAndre Fischer         {
467f120fe41SAndre Fischer             OSL_ASSERT("context name not recognized");
468f120fe41SAndre Fischer             continue;
469f120fe41SAndre Fischer         }
470f120fe41SAndre Fischer 
471*85f1aca2SAndre Fischer         // Setup the flag that controls whether a deck/pane is
472*85f1aca2SAndre Fischer         // initially visible/expanded.
473f120fe41SAndre Fischer         bool bIsInitiallyVisible;
474f120fe41SAndre Fischer         if (sInitialState.equalsAscii("visible"))
475f120fe41SAndre Fischer             bIsInitiallyVisible = true;
476f120fe41SAndre Fischer         else if (sInitialState.equalsAscii("hidden"))
477f120fe41SAndre Fischer             bIsInitiallyVisible = false;
478f120fe41SAndre Fischer         else
479f120fe41SAndre Fischer         {
480f120fe41SAndre Fischer             OSL_ASSERT("unrecognized state");
481f120fe41SAndre Fischer             continue;
482f120fe41SAndre Fischer         }
483f120fe41SAndre Fischer 
484*85f1aca2SAndre Fischer         // Add context descriptors.
485*85f1aca2SAndre Fischer         for (::std::vector<EnumContext::Application>::const_iterator
486*85f1aca2SAndre Fischer                  iApplication(aApplications.begin()),
487*85f1aca2SAndre Fischer                  iEnd(aApplications.end());
488*85f1aca2SAndre Fischer              iApplication!=iEnd;
489*85f1aca2SAndre Fischer              ++iApplication)
490*85f1aca2SAndre Fischer         {
491*85f1aca2SAndre Fischer             if (*iApplication != EnumContext::Application_None)
492*85f1aca2SAndre Fischer                 rContextList.AddContextDescription(
493*85f1aca2SAndre Fischer                     Context(
494*85f1aca2SAndre Fischer                         EnumContext::GetApplicationName(*iApplication),
495*85f1aca2SAndre Fischer                         EnumContext::GetContextName(eContext)),
496*85f1aca2SAndre Fischer                     bIsInitiallyVisible,
497*85f1aca2SAndre Fischer                     sMenuCommand);
498*85f1aca2SAndre Fischer         }
499ff12d537SAndre Fischer     }
500ff12d537SAndre Fischer }
501ff12d537SAndre Fischer 
502ff12d537SAndre Fischer 
503ff12d537SAndre Fischer 
504ff12d537SAndre Fischer 
505ff12d537SAndre Fischer void ResourceManager::ReadLegacyAddons (const Reference<frame::XFrame>& rxFrame)
506ff12d537SAndre Fischer {
507ff12d537SAndre Fischer     // Get module name for given frame.
508ff12d537SAndre Fischer     ::rtl::OUString sModuleName (GetModuleName(rxFrame));
509ff12d537SAndre Fischer     if (sModuleName.getLength() == 0)
510ff12d537SAndre Fischer         return;
511ff12d537SAndre Fischer     if (maProcessedApplications.find(sModuleName) != maProcessedApplications.end())
512ff12d537SAndre Fischer     {
513ff12d537SAndre Fischer         // Addons for this application have already been read.
514ff12d537SAndre Fischer         // There is nothing more to do.
515ff12d537SAndre Fischer         return;
516ff12d537SAndre Fischer     }
517ff12d537SAndre Fischer 
518ff12d537SAndre Fischer     // Mark module as processed.  Even when there is an error that
519ff12d537SAndre Fischer     // prevents the configuration data from being read, this error
520ff12d537SAndre Fischer     // will not be triggered a second time.
521ff12d537SAndre Fischer     maProcessedApplications.insert(sModuleName);
522ff12d537SAndre Fischer 
523ff12d537SAndre Fischer     // Get access to the configuration root node for the application.
524ff12d537SAndre Fischer     ::utl::OConfigurationTreeRoot aLegacyRootNode (GetLegacyAddonRootNode(sModuleName));
525ff12d537SAndre Fischer     if ( ! aLegacyRootNode.isValid())
526ff12d537SAndre Fischer         return;
527ff12d537SAndre Fischer 
528ff12d537SAndre Fischer     // Process child nodes.
529ff12d537SAndre Fischer     ::std::vector<OUString> aMatchingNodeNames;
530ff12d537SAndre Fischer     GetToolPanelNodeNames(aMatchingNodeNames, aLegacyRootNode);
531ff12d537SAndre Fischer     const sal_Int32 nCount (aMatchingNodeNames.size());
53295a18594SAndre Fischer     size_t nDeckWriteIndex (maDecks.size());
53395a18594SAndre Fischer     size_t nPanelWriteIndex (maPanels.size());
534ff12d537SAndre Fischer     maDecks.resize(maDecks.size() + nCount);
535ff12d537SAndre Fischer     maPanels.resize(maPanels.size() + nCount);
536ff12d537SAndre Fischer     for (sal_Int32 nReadIndex(0); nReadIndex<nCount; ++nReadIndex)
537ff12d537SAndre Fischer     {
538ff12d537SAndre Fischer         const OUString& rsNodeName (aMatchingNodeNames[nReadIndex]);
539ff12d537SAndre Fischer         const ::utl::OConfigurationNode aChildNode (aLegacyRootNode.openNode(rsNodeName));
540ff12d537SAndre Fischer         if ( ! aChildNode.isValid())
541ff12d537SAndre Fischer             continue;
542ff12d537SAndre Fischer 
543ff12d537SAndre Fischer         DeckDescriptor& rDeckDescriptor (maDecks[nDeckWriteIndex++]);
544ff12d537SAndre Fischer         rDeckDescriptor.msTitle = ::comphelper::getString(aChildNode.getNodeValue("UIName"));
545ff12d537SAndre Fischer         rDeckDescriptor.msId = rsNodeName;
546ff12d537SAndre Fischer         rDeckDescriptor.msIconURL = ::comphelper::getString(aChildNode.getNodeValue("ImageURL"));
547ff12d537SAndre Fischer         rDeckDescriptor.msHighContrastIconURL = rDeckDescriptor.msIconURL;
548ff12d537SAndre Fischer         rDeckDescriptor.msHelpURL = ::comphelper::getString(aChildNode.getNodeValue("HelpURL"));
549ff12d537SAndre Fischer         rDeckDescriptor.msHelpText = rDeckDescriptor.msTitle;
550f120fe41SAndre Fischer         rDeckDescriptor.maContextList.AddContextDescription(Context(sModuleName, A2S("any")), true, OUString());
55195a18594SAndre Fischer         rDeckDescriptor.mbIsEnabled = true;
552ff12d537SAndre Fischer 
553ff12d537SAndre Fischer         PanelDescriptor& rPanelDescriptor (maPanels[nPanelWriteIndex++]);
554ff12d537SAndre Fischer         rPanelDescriptor.msTitle = ::comphelper::getString(aChildNode.getNodeValue("UIName"));
5557a32b0c8SAndre Fischer         rPanelDescriptor.mbIsTitleBarOptional = true;
556ff12d537SAndre Fischer         rPanelDescriptor.msId = rsNodeName;
557ff12d537SAndre Fischer         rPanelDescriptor.msDeckId = rsNodeName;
558ff12d537SAndre Fischer         rPanelDescriptor.msHelpURL = ::comphelper::getString(aChildNode.getNodeValue("HelpURL"));
559f120fe41SAndre Fischer         rPanelDescriptor.maContextList.AddContextDescription(Context(sModuleName, A2S("any")), true, OUString());
560ff12d537SAndre Fischer         rPanelDescriptor.msImplementationURL = rsNodeName;
561ff12d537SAndre Fischer     }
562ff12d537SAndre Fischer 
563ff12d537SAndre Fischer     // When there where invalid nodes then we have to adapt the size
564ff12d537SAndre Fischer     // of the deck and panel vectors.
565ff12d537SAndre Fischer     if (nDeckWriteIndex < maDecks.size())
566ff12d537SAndre Fischer         maDecks.resize(nDeckWriteIndex);
567ff12d537SAndre Fischer     if (nPanelWriteIndex < maPanels.size())
568ff12d537SAndre Fischer         maPanels.resize(nPanelWriteIndex);
569ff12d537SAndre Fischer }
570ff12d537SAndre Fischer 
571ff12d537SAndre Fischer 
572ff12d537SAndre Fischer 
573ff12d537SAndre Fischer 
574ff12d537SAndre Fischer ::rtl::OUString ResourceManager::GetModuleName (
57595a18594SAndre Fischer     const cssu::Reference<css::frame::XFrame>& rxFrame)
576ff12d537SAndre Fischer {
577e56b0a16SAndre Fischer     if ( ! rxFrame.is() || ! rxFrame->getController().is())
578e56b0a16SAndre Fischer         return OUString();
579e56b0a16SAndre Fischer 
580ff12d537SAndre Fischer     try
581ff12d537SAndre Fischer     {
582ff12d537SAndre Fischer         const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory());
583ff12d537SAndre Fischer         const Reference<frame::XModuleManager> xModuleManager (
584e56b0a16SAndre Fischer             aContext.createComponent("com.sun.star.frame.ModuleManager"),
585e56b0a16SAndre Fischer             UNO_QUERY_THROW);
586ff12d537SAndre Fischer         return xModuleManager->identify(rxFrame);
587ff12d537SAndre Fischer     }
588ff12d537SAndre Fischer     catch (const Exception&)
589ff12d537SAndre Fischer     {
590ff12d537SAndre Fischer         DBG_UNHANDLED_EXCEPTION();
591ff12d537SAndre Fischer     }
592ff12d537SAndre Fischer     return OUString();
593ff12d537SAndre Fischer }
594ff12d537SAndre Fischer 
595ff12d537SAndre Fischer 
596ff12d537SAndre Fischer 
597ff12d537SAndre Fischer 
598ff12d537SAndre Fischer ::utl::OConfigurationTreeRoot ResourceManager::GetLegacyAddonRootNode (
599ff12d537SAndre Fischer     const ::rtl::OUString& rsModuleName) const
600ff12d537SAndre Fischer {
601ff12d537SAndre Fischer     try
602ff12d537SAndre Fischer     {
603ff12d537SAndre Fischer         const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory());
604ff12d537SAndre Fischer         const Reference<container::XNameAccess> xModuleAccess (
605ff12d537SAndre Fischer             aContext.createComponent("com.sun.star.frame.ModuleManager"),
606ff12d537SAndre Fischer             UNO_QUERY_THROW);
607ff12d537SAndre Fischer         const ::comphelper::NamedValueCollection aModuleProperties (xModuleAccess->getByName(rsModuleName));
608ff12d537SAndre Fischer         const ::rtl::OUString sWindowStateRef (aModuleProperties.getOrDefault(
609ff12d537SAndre Fischer                 "ooSetupFactoryWindowStateConfigRef",
610ff12d537SAndre Fischer                 ::rtl::OUString()));
611ff12d537SAndre Fischer 
612ff12d537SAndre Fischer         ::rtl::OUStringBuffer aPathComposer;
613ff12d537SAndre Fischer         aPathComposer.appendAscii("org.openoffice.Office.UI.");
614ff12d537SAndre Fischer         aPathComposer.append(sWindowStateRef);
615ff12d537SAndre Fischer         aPathComposer.appendAscii("/UIElements/States");
616ff12d537SAndre Fischer 
617ff12d537SAndre Fischer         return ::utl::OConfigurationTreeRoot(aContext, aPathComposer.makeStringAndClear(), false);
618ff12d537SAndre Fischer     }
619ff12d537SAndre Fischer     catch( const Exception& )
620ff12d537SAndre Fischer     {
621ff12d537SAndre Fischer         DBG_UNHANDLED_EXCEPTION();
622ff12d537SAndre Fischer     }
623ff12d537SAndre Fischer 
624ff12d537SAndre Fischer     return ::utl::OConfigurationTreeRoot();
625ff12d537SAndre Fischer }
626ff12d537SAndre Fischer 
627ff12d537SAndre Fischer 
628ff12d537SAndre Fischer 
629ff12d537SAndre Fischer 
630ff12d537SAndre Fischer void ResourceManager::GetToolPanelNodeNames (
631ff12d537SAndre Fischer     ::std::vector<OUString>& rMatchingNames,
632ff12d537SAndre Fischer     const ::utl::OConfigurationTreeRoot aRoot) const
633ff12d537SAndre Fischer {
634ff12d537SAndre Fischer     Sequence<OUString> aChildNodeNames (aRoot.getNodeNames());
635ff12d537SAndre Fischer     const sal_Int32 nCount (aChildNodeNames.getLength());
636ff12d537SAndre Fischer     for (sal_Int32 nIndex(0); nIndex<nCount; ++nIndex)
637ff12d537SAndre Fischer     {
638ff12d537SAndre Fischer         if (aChildNodeNames[nIndex].matchAsciiL(
639ff12d537SAndre Fischer                 RTL_CONSTASCII_STRINGPARAM( "private:resource/toolpanel/")))
640ff12d537SAndre Fischer             rMatchingNames.push_back(aChildNodeNames[nIndex]);
641ff12d537SAndre Fischer     }
642ff12d537SAndre Fischer }
643ff12d537SAndre Fischer 
644ff12d537SAndre Fischer 
645ff12d537SAndre Fischer 
646ff12d537SAndre Fischer } } // end of namespace sfx2::sidebar
647