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"));
282*4e21436dSAndre Fischer         rDeckDescriptor.msTitleBarIconURL = ::comphelper::getString(
283*4e21436dSAndre Fischer             aDeckNode.getNodeValue("TitleBarIconURL"));
284*4e21436dSAndre Fischer         rDeckDescriptor.msHighContrastTitleBarIconURL = ::comphelper::getString(
285*4e21436dSAndre Fischer             aDeckNode.getNodeValue("HighContrastTitleBarIconURL"));
2867a32b0c8SAndre Fischer         rDeckDescriptor.msHelpURL = ::comphelper::getString(
2877a32b0c8SAndre Fischer             aDeckNode.getNodeValue("HelpURL"));
288ff12d537SAndre Fischer         rDeckDescriptor.msHelpText = rDeckDescriptor.msTitle;
28995a18594SAndre Fischer         rDeckDescriptor.mbIsEnabled = true;
2907a32b0c8SAndre Fischer         rDeckDescriptor.mnOrderIndex = ::comphelper::getINT32(
2917a32b0c8SAndre Fischer             aDeckNode.getNodeValue("OrderIndex"));
2927a32b0c8SAndre Fischer 
293f120fe41SAndre Fischer         ReadContextList(
294f120fe41SAndre Fischer             aDeckNode,
295f120fe41SAndre Fischer             rDeckDescriptor.maContextList,
296f120fe41SAndre Fischer             OUString());
297ff12d537SAndre Fischer     }
298ff12d537SAndre Fischer 
299ff12d537SAndre Fischer     // When there where invalid nodes then we have to adapt the size
300ff12d537SAndre Fischer     // of the deck vector.
301ff12d537SAndre Fischer     if (nWriteIndex<nCount)
302ff12d537SAndre Fischer         maDecks.resize(nWriteIndex);
303ff12d537SAndre Fischer }
304ff12d537SAndre Fischer 
305ff12d537SAndre Fischer 
306ff12d537SAndre Fischer 
307ff12d537SAndre Fischer 
308ff12d537SAndre Fischer void ResourceManager::ReadPanelList (void)
309ff12d537SAndre Fischer {
310ff12d537SAndre Fischer     const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory());
311ff12d537SAndre Fischer     const ::utl::OConfigurationTreeRoot aPanelRootNode (
312ff12d537SAndre Fischer         aContext,
313ff12d537SAndre Fischer         A2S("org.openoffice.Office.UI.Sidebar/Content/PanelList"),
314ff12d537SAndre Fischer         false);
315ff12d537SAndre Fischer     if ( ! aPanelRootNode.isValid() )
316ff12d537SAndre Fischer         return;
317ff12d537SAndre Fischer 
318ff12d537SAndre Fischer     const Sequence<OUString> aPanelNodeNames (aPanelRootNode.getNodeNames());
319ff12d537SAndre Fischer     const sal_Int32 nCount (aPanelNodeNames.getLength());
320ff12d537SAndre Fischer     maPanels.resize(nCount);
321ff12d537SAndre Fischer     sal_Int32 nWriteIndex (0);
322ff12d537SAndre Fischer     for (sal_Int32 nReadIndex(0); nReadIndex<nCount; ++nReadIndex)
323ff12d537SAndre Fischer     {
324ff12d537SAndre Fischer         const ::utl::OConfigurationNode aPanelNode (aPanelRootNode.openNode(aPanelNodeNames[nReadIndex]));
325ff12d537SAndre Fischer         if ( ! aPanelNode.isValid())
326ff12d537SAndre Fischer             continue;
327ff12d537SAndre Fischer 
328ff12d537SAndre Fischer         PanelDescriptor& rPanelDescriptor (maPanels[nWriteIndex++]);
329ff12d537SAndre Fischer 
330ff12d537SAndre Fischer         rPanelDescriptor.msTitle = ::comphelper::getString(
331ff12d537SAndre Fischer             aPanelNode.getNodeValue("Title"));
332ff12d537SAndre Fischer         rPanelDescriptor.mbIsTitleBarOptional = ::comphelper::getBOOL(
333ff12d537SAndre Fischer             aPanelNode.getNodeValue("TitleBarIsOptional"));
334ff12d537SAndre Fischer         rPanelDescriptor.msId = ::comphelper::getString(
335ff12d537SAndre Fischer             aPanelNode.getNodeValue("Id"));
336ff12d537SAndre Fischer         rPanelDescriptor.msDeckId = ::comphelper::getString(
337ff12d537SAndre Fischer             aPanelNode.getNodeValue("DeckId"));
338*4e21436dSAndre Fischer         rPanelDescriptor.msTitleBarIconURL = ::comphelper::getString(
339*4e21436dSAndre Fischer             aPanelNode.getNodeValue("TitleBarIconURL"));
340*4e21436dSAndre Fischer         rPanelDescriptor.msHighContrastTitleBarIconURL = ::comphelper::getString(
341*4e21436dSAndre Fischer             aPanelNode.getNodeValue("HighContrastTitleBarIconURL"));
342ff12d537SAndre Fischer         rPanelDescriptor.msHelpURL = ::comphelper::getString(
343ff12d537SAndre Fischer             aPanelNode.getNodeValue("HelpURL"));
344ff12d537SAndre Fischer         rPanelDescriptor.msImplementationURL = ::comphelper::getString(
345ff12d537SAndre Fischer             aPanelNode.getNodeValue("ImplementationURL"));
34695a18594SAndre Fischer         rPanelDescriptor.mnOrderIndex = ::comphelper::getINT32(
34795a18594SAndre Fischer             aPanelNode.getNodeValue("OrderIndex"));
3487a32b0c8SAndre Fischer         rPanelDescriptor.mbWantsCanvas = ::comphelper::getBOOL(
3497a32b0c8SAndre Fischer             aPanelNode.getNodeValue("WantsCanvas"));
350f120fe41SAndre Fischer         const OUString sDefaultMenuCommand (::comphelper::getString(
351f120fe41SAndre Fischer                 aPanelNode.getNodeValue("DefaultMenuCommand")));
35254eaaa32SAndre Fischer 
353f120fe41SAndre Fischer         ReadContextList(
354f120fe41SAndre Fischer             aPanelNode,
355f120fe41SAndre Fischer             rPanelDescriptor.maContextList,
356f120fe41SAndre Fischer             sDefaultMenuCommand);
357ff12d537SAndre Fischer     }
358ff12d537SAndre Fischer 
359ff12d537SAndre Fischer     // When there where invalid nodes then we have to adapt the size
360ff12d537SAndre Fischer     // of the deck vector.
361ff12d537SAndre Fischer     if (nWriteIndex<nCount)
362ff12d537SAndre Fischer         maPanels.resize(nWriteIndex);
363ff12d537SAndre Fischer }
364ff12d537SAndre Fischer 
365ff12d537SAndre Fischer 
366ff12d537SAndre Fischer 
367ff12d537SAndre Fischer 
368f120fe41SAndre Fischer void ResourceManager::ReadContextList (
369f120fe41SAndre Fischer     const ::utl::OConfigurationNode& rParentNode,
370f120fe41SAndre Fischer     ContextList& rContextList,
371f120fe41SAndre Fischer     const OUString& rsDefaultMenuCommand) const
372ff12d537SAndre Fischer {
373f120fe41SAndre Fischer     const Any aValue = rParentNode.getNodeValue("ContextList");
374f120fe41SAndre Fischer     Sequence<OUString> aValues;
375f120fe41SAndre Fischer     sal_Int32 nCount;
376f120fe41SAndre Fischer     if (aValue >>= aValues)
377f120fe41SAndre Fischer         nCount = aValues.getLength();
378f120fe41SAndre Fischer     else
379f120fe41SAndre Fischer         nCount = 0;
380f120fe41SAndre Fischer 
381f120fe41SAndre Fischer     for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
382ff12d537SAndre Fischer     {
383f120fe41SAndre Fischer         const OUString sValue (aValues[nIndex]);
384f120fe41SAndre Fischer         sal_Int32 nCharacterIndex (0);
385f120fe41SAndre Fischer         const OUString sApplicationName (sValue.getToken(0, ',', nCharacterIndex).trim());
386f120fe41SAndre Fischer         if (nCharacterIndex < 0)
387f120fe41SAndre Fischer         {
388f120fe41SAndre Fischer             if (sApplicationName.getLength() == 0)
389f120fe41SAndre Fischer             {
390f120fe41SAndre Fischer                 // This is a valid case: in the XML file the separator
391f120fe41SAndre Fischer                 // was used as terminator.  Using it in the last line
392f120fe41SAndre Fischer                 // creates an additional but empty entry.
393f120fe41SAndre Fischer                 break;
394f120fe41SAndre Fischer             }
395f120fe41SAndre Fischer             else
396f120fe41SAndre Fischer             {
397f120fe41SAndre Fischer                 OSL_ASSERT("expecting three or four values per ContextList entry, separated by comma");
398f120fe41SAndre Fischer                 continue;
399f120fe41SAndre Fischer             }
400f120fe41SAndre Fischer         }
4017a32b0c8SAndre Fischer 
402f120fe41SAndre Fischer         const OUString sContextName (sValue.getToken(0, ',', nCharacterIndex).trim());
403f120fe41SAndre Fischer         if (nCharacterIndex < 0)
4047a32b0c8SAndre Fischer         {
405f120fe41SAndre Fischer             OSL_ASSERT("expecting three or four values per ContextList entry, separated by comma");
406f120fe41SAndre Fischer             continue;
407f120fe41SAndre Fischer         }
408f120fe41SAndre Fischer 
409f120fe41SAndre Fischer         const OUString sInitialState (sValue.getToken(0, ',', nCharacterIndex).trim());
410f120fe41SAndre Fischer 
411f120fe41SAndre Fischer         // The fourth argument is optional.
412f120fe41SAndre Fischer         const OUString sMenuCommandOverride (
413f120fe41SAndre Fischer             nCharacterIndex<0
414f120fe41SAndre Fischer                 ? OUString()
415f120fe41SAndre Fischer                 : sValue.getToken(0, ',', nCharacterIndex).trim());
416f120fe41SAndre Fischer         const OUString sMenuCommand (
417f120fe41SAndre Fischer             sMenuCommandOverride.getLength()>0
418f120fe41SAndre Fischer                 ? (sMenuCommandOverride.equalsAscii("none")
419f120fe41SAndre Fischer                     ? OUString()
420f120fe41SAndre Fischer                     : sMenuCommandOverride)
421f120fe41SAndre Fischer                 : rsDefaultMenuCommand);
422f120fe41SAndre Fischer 
42385f1aca2SAndre Fischer         // Setup a list of application enums.  Note that the
42485f1aca2SAndre Fischer         // application name may result in more than one value (eg
42585f1aca2SAndre Fischer         // DrawImpress will result in two enums, one for Draw and one
42685f1aca2SAndre Fischer         // for Impress).
42785f1aca2SAndre Fischer         ::std::vector<EnumContext::Application> aApplications;
428f120fe41SAndre Fischer         EnumContext::Application eApplication (EnumContext::GetApplicationEnum(sApplicationName));
429f120fe41SAndre Fischer         if (eApplication == EnumContext::Application_None
430f120fe41SAndre Fischer             && !sApplicationName.equals(EnumContext::GetApplicationName(EnumContext::Application_None)))
431f120fe41SAndre Fischer         {
432f120fe41SAndre Fischer             // Handle some special names: abbreviations that make
433f120fe41SAndre Fischer             // context descriptions more readable.
434f120fe41SAndre Fischer             if (sApplicationName.equalsAscii("Writer"))
43585f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_Writer);
436f120fe41SAndre Fischer             else if (sApplicationName.equalsAscii("Calc"))
43785f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_Calc);
438f120fe41SAndre Fischer             else if (sApplicationName.equalsAscii("Draw"))
43985f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_Draw);
440f120fe41SAndre Fischer             else if (sApplicationName.equalsAscii("Impress"))
44185f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_Impress);
442f120fe41SAndre Fischer             else if (sApplicationName.equalsAscii("DrawImpress"))
443f120fe41SAndre Fischer             {
444f120fe41SAndre Fischer                 // A special case among the special names:  it is
445f120fe41SAndre Fischer                 // common to use the same context descriptions for
446f120fe41SAndre Fischer                 // both Draw and Impress.  This special case helps to
447f120fe41SAndre Fischer                 // avoid duplication in the .xcu file.
44885f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_Draw);
44985f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_Impress);
450dfbb0ba8SAndre Fischer             }
45185f1aca2SAndre Fischer             else if (sApplicationName.equalsAscii("WriterVariants"))
452dfbb0ba8SAndre Fischer             {
45385f1aca2SAndre Fischer                 // Another special case for all Writer variants.
45485f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_Writer);
45585f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_WriterGlobal);
45685f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_WriterWeb);
45785f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_WriterXML);
458f120fe41SAndre Fischer             }
459f120fe41SAndre Fischer             else
460f120fe41SAndre Fischer             {
461f120fe41SAndre Fischer                 OSL_ASSERT("application name not recognized");
462f120fe41SAndre Fischer                 continue;
463f120fe41SAndre Fischer             }
4647a32b0c8SAndre Fischer         }
46585f1aca2SAndre Fischer         else
46685f1aca2SAndre Fischer         {
46785f1aca2SAndre Fischer             // No conversion of the application name necessary.
46885f1aca2SAndre Fischer             aApplications.push_back(eApplication);
46985f1aca2SAndre Fischer         }
47085f1aca2SAndre Fischer 
47185f1aca2SAndre Fischer         // Setup the actual context enum.
472f120fe41SAndre Fischer         const EnumContext::Context eContext (EnumContext::GetContextEnum(sContextName));
473f120fe41SAndre Fischer         if (eContext == EnumContext::Context_Unknown)
474f120fe41SAndre Fischer         {
475f120fe41SAndre Fischer             OSL_ASSERT("context name not recognized");
476f120fe41SAndre Fischer             continue;
477f120fe41SAndre Fischer         }
478f120fe41SAndre Fischer 
47985f1aca2SAndre Fischer         // Setup the flag that controls whether a deck/pane is
48085f1aca2SAndre Fischer         // initially visible/expanded.
481f120fe41SAndre Fischer         bool bIsInitiallyVisible;
482f120fe41SAndre Fischer         if (sInitialState.equalsAscii("visible"))
483f120fe41SAndre Fischer             bIsInitiallyVisible = true;
484f120fe41SAndre Fischer         else if (sInitialState.equalsAscii("hidden"))
485f120fe41SAndre Fischer             bIsInitiallyVisible = false;
486f120fe41SAndre Fischer         else
487f120fe41SAndre Fischer         {
488f120fe41SAndre Fischer             OSL_ASSERT("unrecognized state");
489f120fe41SAndre Fischer             continue;
490f120fe41SAndre Fischer         }
491f120fe41SAndre Fischer 
49285f1aca2SAndre Fischer         // Add context descriptors.
49385f1aca2SAndre Fischer         for (::std::vector<EnumContext::Application>::const_iterator
49485f1aca2SAndre Fischer                  iApplication(aApplications.begin()),
49585f1aca2SAndre Fischer                  iEnd(aApplications.end());
49685f1aca2SAndre Fischer              iApplication!=iEnd;
49785f1aca2SAndre Fischer              ++iApplication)
49885f1aca2SAndre Fischer         {
49985f1aca2SAndre Fischer             if (*iApplication != EnumContext::Application_None)
50085f1aca2SAndre Fischer                 rContextList.AddContextDescription(
50185f1aca2SAndre Fischer                     Context(
50285f1aca2SAndre Fischer                         EnumContext::GetApplicationName(*iApplication),
50385f1aca2SAndre Fischer                         EnumContext::GetContextName(eContext)),
50485f1aca2SAndre Fischer                     bIsInitiallyVisible,
50585f1aca2SAndre Fischer                     sMenuCommand);
50685f1aca2SAndre Fischer         }
507ff12d537SAndre Fischer     }
508ff12d537SAndre Fischer }
509ff12d537SAndre Fischer 
510ff12d537SAndre Fischer 
511ff12d537SAndre Fischer 
512ff12d537SAndre Fischer 
513ff12d537SAndre Fischer void ResourceManager::ReadLegacyAddons (const Reference<frame::XFrame>& rxFrame)
514ff12d537SAndre Fischer {
515ff12d537SAndre Fischer     // Get module name for given frame.
516ff12d537SAndre Fischer     ::rtl::OUString sModuleName (GetModuleName(rxFrame));
517ff12d537SAndre Fischer     if (sModuleName.getLength() == 0)
518ff12d537SAndre Fischer         return;
519ff12d537SAndre Fischer     if (maProcessedApplications.find(sModuleName) != maProcessedApplications.end())
520ff12d537SAndre Fischer     {
521ff12d537SAndre Fischer         // Addons for this application have already been read.
522ff12d537SAndre Fischer         // There is nothing more to do.
523ff12d537SAndre Fischer         return;
524ff12d537SAndre Fischer     }
525ff12d537SAndre Fischer 
526ff12d537SAndre Fischer     // Mark module as processed.  Even when there is an error that
527ff12d537SAndre Fischer     // prevents the configuration data from being read, this error
528ff12d537SAndre Fischer     // will not be triggered a second time.
529ff12d537SAndre Fischer     maProcessedApplications.insert(sModuleName);
530ff12d537SAndre Fischer 
531ff12d537SAndre Fischer     // Get access to the configuration root node for the application.
532ff12d537SAndre Fischer     ::utl::OConfigurationTreeRoot aLegacyRootNode (GetLegacyAddonRootNode(sModuleName));
533ff12d537SAndre Fischer     if ( ! aLegacyRootNode.isValid())
534ff12d537SAndre Fischer         return;
535ff12d537SAndre Fischer 
536ff12d537SAndre Fischer     // Process child nodes.
537ff12d537SAndre Fischer     ::std::vector<OUString> aMatchingNodeNames;
538ff12d537SAndre Fischer     GetToolPanelNodeNames(aMatchingNodeNames, aLegacyRootNode);
539ff12d537SAndre Fischer     const sal_Int32 nCount (aMatchingNodeNames.size());
54095a18594SAndre Fischer     size_t nDeckWriteIndex (maDecks.size());
54195a18594SAndre Fischer     size_t nPanelWriteIndex (maPanels.size());
542ff12d537SAndre Fischer     maDecks.resize(maDecks.size() + nCount);
543ff12d537SAndre Fischer     maPanels.resize(maPanels.size() + nCount);
544ff12d537SAndre Fischer     for (sal_Int32 nReadIndex(0); nReadIndex<nCount; ++nReadIndex)
545ff12d537SAndre Fischer     {
546ff12d537SAndre Fischer         const OUString& rsNodeName (aMatchingNodeNames[nReadIndex]);
547ff12d537SAndre Fischer         const ::utl::OConfigurationNode aChildNode (aLegacyRootNode.openNode(rsNodeName));
548ff12d537SAndre Fischer         if ( ! aChildNode.isValid())
549ff12d537SAndre Fischer             continue;
550ff12d537SAndre Fischer 
551ff12d537SAndre Fischer         DeckDescriptor& rDeckDescriptor (maDecks[nDeckWriteIndex++]);
552ff12d537SAndre Fischer         rDeckDescriptor.msTitle = ::comphelper::getString(aChildNode.getNodeValue("UIName"));
553ff12d537SAndre Fischer         rDeckDescriptor.msId = rsNodeName;
554ff12d537SAndre Fischer         rDeckDescriptor.msIconURL = ::comphelper::getString(aChildNode.getNodeValue("ImageURL"));
555ff12d537SAndre Fischer         rDeckDescriptor.msHighContrastIconURL = rDeckDescriptor.msIconURL;
556ff12d537SAndre Fischer         rDeckDescriptor.msHelpURL = ::comphelper::getString(aChildNode.getNodeValue("HelpURL"));
557ff12d537SAndre Fischer         rDeckDescriptor.msHelpText = rDeckDescriptor.msTitle;
558f120fe41SAndre Fischer         rDeckDescriptor.maContextList.AddContextDescription(Context(sModuleName, A2S("any")), true, OUString());
55995a18594SAndre Fischer         rDeckDescriptor.mbIsEnabled = true;
560ff12d537SAndre Fischer 
561ff12d537SAndre Fischer         PanelDescriptor& rPanelDescriptor (maPanels[nPanelWriteIndex++]);
562ff12d537SAndre Fischer         rPanelDescriptor.msTitle = ::comphelper::getString(aChildNode.getNodeValue("UIName"));
5637a32b0c8SAndre Fischer         rPanelDescriptor.mbIsTitleBarOptional = true;
564ff12d537SAndre Fischer         rPanelDescriptor.msId = rsNodeName;
565ff12d537SAndre Fischer         rPanelDescriptor.msDeckId = rsNodeName;
566ff12d537SAndre Fischer         rPanelDescriptor.msHelpURL = ::comphelper::getString(aChildNode.getNodeValue("HelpURL"));
567f120fe41SAndre Fischer         rPanelDescriptor.maContextList.AddContextDescription(Context(sModuleName, A2S("any")), true, OUString());
568ff12d537SAndre Fischer         rPanelDescriptor.msImplementationURL = rsNodeName;
569ff12d537SAndre Fischer     }
570ff12d537SAndre Fischer 
571ff12d537SAndre Fischer     // When there where invalid nodes then we have to adapt the size
572ff12d537SAndre Fischer     // of the deck and panel vectors.
573ff12d537SAndre Fischer     if (nDeckWriteIndex < maDecks.size())
574ff12d537SAndre Fischer         maDecks.resize(nDeckWriteIndex);
575ff12d537SAndre Fischer     if (nPanelWriteIndex < maPanels.size())
576ff12d537SAndre Fischer         maPanels.resize(nPanelWriteIndex);
577ff12d537SAndre Fischer }
578ff12d537SAndre Fischer 
579ff12d537SAndre Fischer 
580ff12d537SAndre Fischer 
581ff12d537SAndre Fischer 
582ff12d537SAndre Fischer ::rtl::OUString ResourceManager::GetModuleName (
58395a18594SAndre Fischer     const cssu::Reference<css::frame::XFrame>& rxFrame)
584ff12d537SAndre Fischer {
585e56b0a16SAndre Fischer     if ( ! rxFrame.is() || ! rxFrame->getController().is())
586e56b0a16SAndre Fischer         return OUString();
587e56b0a16SAndre Fischer 
588ff12d537SAndre Fischer     try
589ff12d537SAndre Fischer     {
590ff12d537SAndre Fischer         const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory());
591ff12d537SAndre Fischer         const Reference<frame::XModuleManager> xModuleManager (
592e56b0a16SAndre Fischer             aContext.createComponent("com.sun.star.frame.ModuleManager"),
593e56b0a16SAndre Fischer             UNO_QUERY_THROW);
594ff12d537SAndre Fischer         return xModuleManager->identify(rxFrame);
595ff12d537SAndre Fischer     }
596ff12d537SAndre Fischer     catch (const Exception&)
597ff12d537SAndre Fischer     {
598ff12d537SAndre Fischer         DBG_UNHANDLED_EXCEPTION();
599ff12d537SAndre Fischer     }
600ff12d537SAndre Fischer     return OUString();
601ff12d537SAndre Fischer }
602ff12d537SAndre Fischer 
603ff12d537SAndre Fischer 
604ff12d537SAndre Fischer 
605ff12d537SAndre Fischer 
606ff12d537SAndre Fischer ::utl::OConfigurationTreeRoot ResourceManager::GetLegacyAddonRootNode (
607ff12d537SAndre Fischer     const ::rtl::OUString& rsModuleName) const
608ff12d537SAndre Fischer {
609ff12d537SAndre Fischer     try
610ff12d537SAndre Fischer     {
611ff12d537SAndre Fischer         const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory());
612ff12d537SAndre Fischer         const Reference<container::XNameAccess> xModuleAccess (
613ff12d537SAndre Fischer             aContext.createComponent("com.sun.star.frame.ModuleManager"),
614ff12d537SAndre Fischer             UNO_QUERY_THROW);
615ff12d537SAndre Fischer         const ::comphelper::NamedValueCollection aModuleProperties (xModuleAccess->getByName(rsModuleName));
616ff12d537SAndre Fischer         const ::rtl::OUString sWindowStateRef (aModuleProperties.getOrDefault(
617ff12d537SAndre Fischer                 "ooSetupFactoryWindowStateConfigRef",
618ff12d537SAndre Fischer                 ::rtl::OUString()));
619ff12d537SAndre Fischer 
620ff12d537SAndre Fischer         ::rtl::OUStringBuffer aPathComposer;
621ff12d537SAndre Fischer         aPathComposer.appendAscii("org.openoffice.Office.UI.");
622ff12d537SAndre Fischer         aPathComposer.append(sWindowStateRef);
623ff12d537SAndre Fischer         aPathComposer.appendAscii("/UIElements/States");
624ff12d537SAndre Fischer 
625ff12d537SAndre Fischer         return ::utl::OConfigurationTreeRoot(aContext, aPathComposer.makeStringAndClear(), false);
626ff12d537SAndre Fischer     }
627ff12d537SAndre Fischer     catch( const Exception& )
628ff12d537SAndre Fischer     {
629ff12d537SAndre Fischer         DBG_UNHANDLED_EXCEPTION();
630ff12d537SAndre Fischer     }
631ff12d537SAndre Fischer 
632ff12d537SAndre Fischer     return ::utl::OConfigurationTreeRoot();
633ff12d537SAndre Fischer }
634ff12d537SAndre Fischer 
635ff12d537SAndre Fischer 
636ff12d537SAndre Fischer 
637ff12d537SAndre Fischer 
638ff12d537SAndre Fischer void ResourceManager::GetToolPanelNodeNames (
639ff12d537SAndre Fischer     ::std::vector<OUString>& rMatchingNames,
640ff12d537SAndre Fischer     const ::utl::OConfigurationTreeRoot aRoot) const
641ff12d537SAndre Fischer {
642ff12d537SAndre Fischer     Sequence<OUString> aChildNodeNames (aRoot.getNodeNames());
643ff12d537SAndre Fischer     const sal_Int32 nCount (aChildNodeNames.getLength());
644ff12d537SAndre Fischer     for (sal_Int32 nIndex(0); nIndex<nCount; ++nIndex)
645ff12d537SAndre Fischer     {
646ff12d537SAndre Fischer         if (aChildNodeNames[nIndex].matchAsciiL(
647ff12d537SAndre Fischer                 RTL_CONSTASCII_STRINGPARAM( "private:resource/toolpanel/")))
648ff12d537SAndre Fischer             rMatchingNames.push_back(aChildNodeNames[nIndex]);
649ff12d537SAndre Fischer     }
650ff12d537SAndre Fischer }
651ff12d537SAndre Fischer 
652ff12d537SAndre Fischer 
653ff12d537SAndre Fischer 
654ff12d537SAndre Fischer } } // end of namespace sfx2::sidebar
655