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"
25*54eaaa32SAndre Fischer #include "Tools.hxx"
26*54eaaa32SAndre 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")));
344*54eaaa32SAndre 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 
415f120fe41SAndre Fischer         EnumContext::Application eApplication (EnumContext::GetApplicationEnum(sApplicationName));
416f120fe41SAndre Fischer         bool bApplicationIsDrawAndImpress = false;
417f120fe41SAndre Fischer         if (eApplication == EnumContext::Application_None
418f120fe41SAndre Fischer             && !sApplicationName.equals(EnumContext::GetApplicationName(EnumContext::Application_None)))
419f120fe41SAndre Fischer         {
420f120fe41SAndre Fischer             // Handle some special names: abbreviations that make
421f120fe41SAndre Fischer             // context descriptions more readable.
422f120fe41SAndre Fischer             if (sApplicationName.equalsAscii("Writer"))
423f120fe41SAndre Fischer                 eApplication = EnumContext::Application_Writer;
424f120fe41SAndre Fischer             else if (sApplicationName.equalsAscii("Calc"))
425f120fe41SAndre Fischer                 eApplication = EnumContext::Application_Calc;
426f120fe41SAndre Fischer             else if (sApplicationName.equalsAscii("Draw"))
427f120fe41SAndre Fischer                 eApplication = EnumContext::Application_Draw;
428f120fe41SAndre Fischer             else if (sApplicationName.equalsAscii("Impress"))
429f120fe41SAndre Fischer                 eApplication = EnumContext::Application_Impress;
430f120fe41SAndre Fischer             else if (sApplicationName.equalsAscii("DrawImpress"))
431f120fe41SAndre Fischer             {
432f120fe41SAndre Fischer                 // A special case among the special names:  it is
433f120fe41SAndre Fischer                 // common to use the same context descriptions for
434f120fe41SAndre Fischer                 // both Draw and Impress.  This special case helps to
435f120fe41SAndre Fischer                 // avoid duplication in the .xcu file.
436f120fe41SAndre Fischer                 bApplicationIsDrawAndImpress = true;
437f120fe41SAndre Fischer             }
438f120fe41SAndre Fischer             else
439f120fe41SAndre Fischer             {
440f120fe41SAndre Fischer                 OSL_ASSERT("application name not recognized");
441f120fe41SAndre Fischer                 continue;
442f120fe41SAndre Fischer             }
4437a32b0c8SAndre Fischer         }
4447a32b0c8SAndre Fischer 
445f120fe41SAndre Fischer         const EnumContext::Context eContext (EnumContext::GetContextEnum(sContextName));
446f120fe41SAndre Fischer         if (eContext == EnumContext::Context_Unknown)
447f120fe41SAndre Fischer         {
448f120fe41SAndre Fischer             OSL_ASSERT("context name not recognized");
449f120fe41SAndre Fischer             continue;
450f120fe41SAndre Fischer         }
451f120fe41SAndre Fischer 
452f120fe41SAndre Fischer         bool bIsInitiallyVisible;
453f120fe41SAndre Fischer         if (sInitialState.equalsAscii("visible"))
454f120fe41SAndre Fischer             bIsInitiallyVisible = true;
455f120fe41SAndre Fischer         else if (sInitialState.equalsAscii("hidden"))
456f120fe41SAndre Fischer             bIsInitiallyVisible = false;
457f120fe41SAndre Fischer         else
458f120fe41SAndre Fischer         {
459f120fe41SAndre Fischer             OSL_ASSERT("unrecognized state");
460f120fe41SAndre Fischer             continue;
461f120fe41SAndre Fischer         }
462f120fe41SAndre Fischer 
463f120fe41SAndre Fischer         if (bApplicationIsDrawAndImpress)
464f120fe41SAndre Fischer         {
465f120fe41SAndre Fischer             // Add the context description for both Draw and Impress.
466f120fe41SAndre Fischer             rContextList.AddContextDescription(
467f120fe41SAndre Fischer                 Context(
468f120fe41SAndre Fischer                     EnumContext::GetApplicationName(EnumContext::Application_Draw),
469f120fe41SAndre Fischer                     EnumContext::GetContextName(eContext)),
470f120fe41SAndre Fischer                 bIsInitiallyVisible,
471f120fe41SAndre Fischer                 sMenuCommand);
472f120fe41SAndre Fischer             rContextList.AddContextDescription(
473f120fe41SAndre Fischer                 Context(
474f120fe41SAndre Fischer                     EnumContext::GetApplicationName(EnumContext::Application_Impress),
475f120fe41SAndre Fischer                     EnumContext::GetContextName(eContext)),
476f120fe41SAndre Fischer                 bIsInitiallyVisible,
477f120fe41SAndre Fischer                 sMenuCommand);
478f120fe41SAndre Fischer         }
479f120fe41SAndre Fischer         else
480*54eaaa32SAndre Fischer         {
481f120fe41SAndre Fischer             rContextList.AddContextDescription(
482f120fe41SAndre Fischer                 Context(
483f120fe41SAndre Fischer                     EnumContext::GetApplicationName(eApplication),
484f120fe41SAndre Fischer                     EnumContext::GetContextName(eContext)),
485f120fe41SAndre Fischer                 bIsInitiallyVisible,
486f120fe41SAndre Fischer                 sMenuCommand);
487*54eaaa32SAndre Fischer         }
488ff12d537SAndre Fischer     }
489ff12d537SAndre Fischer }
490ff12d537SAndre Fischer 
491ff12d537SAndre Fischer 
492ff12d537SAndre Fischer 
493ff12d537SAndre Fischer 
494ff12d537SAndre Fischer void ResourceManager::ReadLegacyAddons (const Reference<frame::XFrame>& rxFrame)
495ff12d537SAndre Fischer {
496ff12d537SAndre Fischer     // Get module name for given frame.
497ff12d537SAndre Fischer     ::rtl::OUString sModuleName (GetModuleName(rxFrame));
498ff12d537SAndre Fischer     if (sModuleName.getLength() == 0)
499ff12d537SAndre Fischer         return;
500ff12d537SAndre Fischer     if (maProcessedApplications.find(sModuleName) != maProcessedApplications.end())
501ff12d537SAndre Fischer     {
502ff12d537SAndre Fischer         // Addons for this application have already been read.
503ff12d537SAndre Fischer         // There is nothing more to do.
504ff12d537SAndre Fischer         return;
505ff12d537SAndre Fischer     }
506ff12d537SAndre Fischer 
507ff12d537SAndre Fischer     // Mark module as processed.  Even when there is an error that
508ff12d537SAndre Fischer     // prevents the configuration data from being read, this error
509ff12d537SAndre Fischer     // will not be triggered a second time.
510ff12d537SAndre Fischer     maProcessedApplications.insert(sModuleName);
511ff12d537SAndre Fischer 
512ff12d537SAndre Fischer     // Get access to the configuration root node for the application.
513ff12d537SAndre Fischer     ::utl::OConfigurationTreeRoot aLegacyRootNode (GetLegacyAddonRootNode(sModuleName));
514ff12d537SAndre Fischer     if ( ! aLegacyRootNode.isValid())
515ff12d537SAndre Fischer         return;
516ff12d537SAndre Fischer 
517ff12d537SAndre Fischer     // Process child nodes.
518ff12d537SAndre Fischer     ::std::vector<OUString> aMatchingNodeNames;
519ff12d537SAndre Fischer     GetToolPanelNodeNames(aMatchingNodeNames, aLegacyRootNode);
520ff12d537SAndre Fischer     const sal_Int32 nCount (aMatchingNodeNames.size());
52195a18594SAndre Fischer     size_t nDeckWriteIndex (maDecks.size());
52295a18594SAndre Fischer     size_t nPanelWriteIndex (maPanels.size());
523ff12d537SAndre Fischer     maDecks.resize(maDecks.size() + nCount);
524ff12d537SAndre Fischer     maPanels.resize(maPanels.size() + nCount);
525ff12d537SAndre Fischer     for (sal_Int32 nReadIndex(0); nReadIndex<nCount; ++nReadIndex)
526ff12d537SAndre Fischer     {
527ff12d537SAndre Fischer         const OUString& rsNodeName (aMatchingNodeNames[nReadIndex]);
528ff12d537SAndre Fischer         const ::utl::OConfigurationNode aChildNode (aLegacyRootNode.openNode(rsNodeName));
529ff12d537SAndre Fischer         if ( ! aChildNode.isValid())
530ff12d537SAndre Fischer             continue;
531ff12d537SAndre Fischer 
532ff12d537SAndre Fischer         DeckDescriptor& rDeckDescriptor (maDecks[nDeckWriteIndex++]);
533ff12d537SAndre Fischer         rDeckDescriptor.msTitle = ::comphelper::getString(aChildNode.getNodeValue("UIName"));
534ff12d537SAndre Fischer         rDeckDescriptor.msId = rsNodeName;
535ff12d537SAndre Fischer         rDeckDescriptor.msIconURL = ::comphelper::getString(aChildNode.getNodeValue("ImageURL"));
536ff12d537SAndre Fischer         rDeckDescriptor.msHighContrastIconURL = rDeckDescriptor.msIconURL;
537ff12d537SAndre Fischer         rDeckDescriptor.msHelpURL = ::comphelper::getString(aChildNode.getNodeValue("HelpURL"));
538ff12d537SAndre Fischer         rDeckDescriptor.msHelpText = rDeckDescriptor.msTitle;
539f120fe41SAndre Fischer         rDeckDescriptor.maContextList.AddContextDescription(Context(sModuleName, A2S("any")), true, OUString());
54095a18594SAndre Fischer         rDeckDescriptor.mbIsEnabled = true;
541ff12d537SAndre Fischer 
542ff12d537SAndre Fischer         PanelDescriptor& rPanelDescriptor (maPanels[nPanelWriteIndex++]);
543ff12d537SAndre Fischer         rPanelDescriptor.msTitle = ::comphelper::getString(aChildNode.getNodeValue("UIName"));
5447a32b0c8SAndre Fischer         rPanelDescriptor.mbIsTitleBarOptional = true;
545ff12d537SAndre Fischer         rPanelDescriptor.msId = rsNodeName;
546ff12d537SAndre Fischer         rPanelDescriptor.msDeckId = rsNodeName;
547ff12d537SAndre Fischer         rPanelDescriptor.msHelpURL = ::comphelper::getString(aChildNode.getNodeValue("HelpURL"));
548f120fe41SAndre Fischer         rPanelDescriptor.maContextList.AddContextDescription(Context(sModuleName, A2S("any")), true, OUString());
549ff12d537SAndre Fischer         rPanelDescriptor.msImplementationURL = rsNodeName;
550ff12d537SAndre Fischer     }
551ff12d537SAndre Fischer 
552ff12d537SAndre Fischer     // When there where invalid nodes then we have to adapt the size
553ff12d537SAndre Fischer     // of the deck and panel vectors.
554ff12d537SAndre Fischer     if (nDeckWriteIndex < maDecks.size())
555ff12d537SAndre Fischer         maDecks.resize(nDeckWriteIndex);
556ff12d537SAndre Fischer     if (nPanelWriteIndex < maPanels.size())
557ff12d537SAndre Fischer         maPanels.resize(nPanelWriteIndex);
558ff12d537SAndre Fischer }
559ff12d537SAndre Fischer 
560ff12d537SAndre Fischer 
561ff12d537SAndre Fischer 
562ff12d537SAndre Fischer 
563ff12d537SAndre Fischer ::rtl::OUString ResourceManager::GetModuleName (
56495a18594SAndre Fischer     const cssu::Reference<css::frame::XFrame>& rxFrame)
565ff12d537SAndre Fischer {
566ff12d537SAndre Fischer     try
567ff12d537SAndre Fischer     {
568ff12d537SAndre Fischer         const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory());
569ff12d537SAndre Fischer         const Reference<frame::XModuleManager> xModuleManager (
570ff12d537SAndre Fischer             aContext.createComponent("com.sun.star.frame.ModuleManager" ),
571ff12d537SAndre Fischer             UNO_QUERY_THROW );
572ff12d537SAndre Fischer         return xModuleManager->identify(rxFrame);
573ff12d537SAndre Fischer     }
574ff12d537SAndre Fischer     catch (const Exception&)
575ff12d537SAndre Fischer     {
576ff12d537SAndre Fischer         DBG_UNHANDLED_EXCEPTION();
577ff12d537SAndre Fischer     }
578ff12d537SAndre Fischer     return OUString();
579ff12d537SAndre Fischer }
580ff12d537SAndre Fischer 
581ff12d537SAndre Fischer 
582ff12d537SAndre Fischer 
583ff12d537SAndre Fischer 
584ff12d537SAndre Fischer ::utl::OConfigurationTreeRoot ResourceManager::GetLegacyAddonRootNode (
585ff12d537SAndre Fischer     const ::rtl::OUString& rsModuleName) const
586ff12d537SAndre Fischer {
587ff12d537SAndre Fischer     try
588ff12d537SAndre Fischer     {
589ff12d537SAndre Fischer         const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory());
590ff12d537SAndre Fischer         const Reference<container::XNameAccess> xModuleAccess (
591ff12d537SAndre Fischer             aContext.createComponent("com.sun.star.frame.ModuleManager"),
592ff12d537SAndre Fischer             UNO_QUERY_THROW);
593ff12d537SAndre Fischer         const ::comphelper::NamedValueCollection aModuleProperties (xModuleAccess->getByName(rsModuleName));
594ff12d537SAndre Fischer         const ::rtl::OUString sWindowStateRef (aModuleProperties.getOrDefault(
595ff12d537SAndre Fischer                 "ooSetupFactoryWindowStateConfigRef",
596ff12d537SAndre Fischer                 ::rtl::OUString()));
597ff12d537SAndre Fischer 
598ff12d537SAndre Fischer         ::rtl::OUStringBuffer aPathComposer;
599ff12d537SAndre Fischer         aPathComposer.appendAscii("org.openoffice.Office.UI.");
600ff12d537SAndre Fischer         aPathComposer.append(sWindowStateRef);
601ff12d537SAndre Fischer         aPathComposer.appendAscii("/UIElements/States");
602ff12d537SAndre Fischer 
603ff12d537SAndre Fischer         return ::utl::OConfigurationTreeRoot(aContext, aPathComposer.makeStringAndClear(), false);
604ff12d537SAndre Fischer     }
605ff12d537SAndre Fischer     catch( const Exception& )
606ff12d537SAndre Fischer     {
607ff12d537SAndre Fischer         DBG_UNHANDLED_EXCEPTION();
608ff12d537SAndre Fischer     }
609ff12d537SAndre Fischer 
610ff12d537SAndre Fischer     return ::utl::OConfigurationTreeRoot();
611ff12d537SAndre Fischer }
612ff12d537SAndre Fischer 
613ff12d537SAndre Fischer 
614ff12d537SAndre Fischer 
615ff12d537SAndre Fischer 
616ff12d537SAndre Fischer void ResourceManager::GetToolPanelNodeNames (
617ff12d537SAndre Fischer     ::std::vector<OUString>& rMatchingNames,
618ff12d537SAndre Fischer     const ::utl::OConfigurationTreeRoot aRoot) const
619ff12d537SAndre Fischer {
620ff12d537SAndre Fischer     Sequence<OUString> aChildNodeNames (aRoot.getNodeNames());
621ff12d537SAndre Fischer     const sal_Int32 nCount (aChildNodeNames.getLength());
622ff12d537SAndre Fischer     for (sal_Int32 nIndex(0); nIndex<nCount; ++nIndex)
623ff12d537SAndre Fischer     {
624ff12d537SAndre Fischer         if (aChildNodeNames[nIndex].matchAsciiL(
625ff12d537SAndre Fischer                 RTL_CONSTASCII_STRINGPARAM( "private:resource/toolpanel/")))
626ff12d537SAndre Fischer             rMatchingNames.push_back(aChildNodeNames[nIndex]);
627ff12d537SAndre Fischer     }
628ff12d537SAndre Fischer }
629ff12d537SAndre Fischer 
630ff12d537SAndre Fischer 
631ff12d537SAndre Fischer 
632ff12d537SAndre Fischer } } // end of namespace sfx2::sidebar
633