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"
25f35c6d02SAndre Fischer #include "sfx2/sidebar/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 
9395a18594SAndre Fischer const DeckDescriptor* ResourceManager::GetDeckDescriptor (
9495a18594SAndre Fischer     const ::rtl::OUString& rsDeckId) const
9595a18594SAndre Fischer {
9695a18594SAndre Fischer     for (DeckContainer::const_iterator
9795a18594SAndre Fischer              iDeck(maDecks.begin()),
9895a18594SAndre Fischer              iEnd(maDecks.end());
9995a18594SAndre Fischer          iDeck!=iEnd;
10095a18594SAndre Fischer          ++iDeck)
10195a18594SAndre Fischer     {
10295a18594SAndre Fischer         if (iDeck->msId.equals(rsDeckId))
10395a18594SAndre Fischer             return &*iDeck;
10495a18594SAndre Fischer     }
10595a18594SAndre Fischer     return NULL;
10695a18594SAndre Fischer }
10795a18594SAndre Fischer 
10895a18594SAndre Fischer 
10995a18594SAndre Fischer 
11095a18594SAndre Fischer 
11195a18594SAndre Fischer const PanelDescriptor* ResourceManager::GetPanelDescriptor (
11295a18594SAndre Fischer     const ::rtl::OUString& rsPanelId) const
11395a18594SAndre Fischer {
11495a18594SAndre Fischer     for (PanelContainer::const_iterator
11595a18594SAndre Fischer              iPanel(maPanels.begin()),
11695a18594SAndre Fischer              iEnd(maPanels.end());
11795a18594SAndre Fischer          iPanel!=iEnd;
11895a18594SAndre Fischer          ++iPanel)
11995a18594SAndre Fischer     {
12095a18594SAndre Fischer         if (iPanel->msId.equals(rsPanelId))
12195a18594SAndre Fischer             return &*iPanel;
12295a18594SAndre Fischer     }
12395a18594SAndre Fischer     return NULL;
12495a18594SAndre Fischer }
12595a18594SAndre Fischer 
12695a18594SAndre Fischer 
12795a18594SAndre Fischer 
12895a18594SAndre Fischer 
12995a18594SAndre Fischer void ResourceManager::SetIsDeckEnabled (
13095a18594SAndre Fischer     const ::rtl::OUString& rsDeckId,
13195a18594SAndre Fischer     const bool bIsEnabled)
13295a18594SAndre Fischer {
13395a18594SAndre Fischer     for (DeckContainer::iterator
13495a18594SAndre Fischer              iDeck(maDecks.begin()),
13595a18594SAndre Fischer              iEnd(maDecks.end());
13695a18594SAndre Fischer          iDeck!=iEnd;
13795a18594SAndre Fischer          ++iDeck)
13895a18594SAndre Fischer     {
13995a18594SAndre Fischer         if (iDeck->msId.equals(rsDeckId))
14095a18594SAndre Fischer         {
14195a18594SAndre Fischer             iDeck->mbIsEnabled = bIsEnabled;
14295a18594SAndre Fischer             return;
14395a18594SAndre Fischer         }
14495a18594SAndre Fischer     }
14595a18594SAndre Fischer }
14695a18594SAndre Fischer 
14795a18594SAndre Fischer 
14895a18594SAndre Fischer 
14995a18594SAndre Fischer 
15013e1c3b4SAndre Fischer const ResourceManager::DeckContextDescriptorContainer& ResourceManager::GetMatchingDecks (
15113e1c3b4SAndre Fischer     DeckContextDescriptorContainer& rDecks,
1527a32b0c8SAndre Fischer     const Context& rContext,
15313e1c3b4SAndre Fischer     const bool bIsDocumentReadOnly,
154ff12d537SAndre Fischer     const Reference<frame::XFrame>& rxFrame)
155ff12d537SAndre Fischer {
156ff12d537SAndre Fischer     ReadLegacyAddons(rxFrame);
157ff12d537SAndre Fischer 
15813e1c3b4SAndre Fischer     ::std::multimap<sal_Int32,DeckContextDescriptor> aOrderedIds;
159ff12d537SAndre Fischer     for (DeckContainer::const_iterator
160ff12d537SAndre Fischer              iDeck(maDecks.begin()),
161ff12d537SAndre Fischer              iEnd (maDecks.end());
162ff12d537SAndre Fischer          iDeck!=iEnd;
163ff12d537SAndre Fischer          ++iDeck)
164ff12d537SAndre Fischer     {
1657a32b0c8SAndre Fischer         const DeckDescriptor& rDeckDescriptor (*iDeck);
16613e1c3b4SAndre Fischer         if (rDeckDescriptor.maContextList.GetMatch(rContext) == NULL)
16713e1c3b4SAndre Fischer             continue;
16813e1c3b4SAndre Fischer         DeckContextDescriptor aDeckContextDescriptor;
16913e1c3b4SAndre Fischer         aDeckContextDescriptor.msId = rDeckDescriptor.msId;
17013e1c3b4SAndre Fischer         aDeckContextDescriptor.mbIsEnabled =
17113e1c3b4SAndre Fischer             ! bIsDocumentReadOnly
17213e1c3b4SAndre Fischer             || IsDeckEnabled(rDeckDescriptor.msId, rContext, rxFrame);
17313e1c3b4SAndre Fischer         aOrderedIds.insert(::std::multimap<sal_Int32,DeckContextDescriptor>::value_type(
17413e1c3b4SAndre Fischer                 rDeckDescriptor.mnOrderIndex,
17513e1c3b4SAndre Fischer                 aDeckContextDescriptor));
176ff12d537SAndre Fischer     }
177ff12d537SAndre Fischer 
17813e1c3b4SAndre Fischer     for (::std::multimap<sal_Int32,DeckContextDescriptor>::const_iterator
1797a32b0c8SAndre Fischer              iId(aOrderedIds.begin()),
1807a32b0c8SAndre Fischer              iEnd(aOrderedIds.end());
1817a32b0c8SAndre Fischer          iId!=iEnd;
1827a32b0c8SAndre Fischer          ++iId)
1837a32b0c8SAndre Fischer     {
18413e1c3b4SAndre Fischer         rDecks.push_back(iId->second);
1857a32b0c8SAndre Fischer     }
1867a32b0c8SAndre Fischer 
18713e1c3b4SAndre Fischer     return rDecks;
188ff12d537SAndre Fischer }
189ff12d537SAndre Fischer 
190ff12d537SAndre Fischer 
191ff12d537SAndre Fischer 
192ff12d537SAndre Fischer 
193f120fe41SAndre Fischer const ResourceManager::PanelContextDescriptorContainer& ResourceManager::GetMatchingPanels (
194f120fe41SAndre Fischer     PanelContextDescriptorContainer& rPanelIds,
1957a32b0c8SAndre Fischer     const Context& rContext,
196ff12d537SAndre Fischer     const ::rtl::OUString& rsDeckId,
197ff12d537SAndre Fischer     const Reference<frame::XFrame>& rxFrame)
198ff12d537SAndre Fischer {
199ff12d537SAndre Fischer     ReadLegacyAddons(rxFrame);
200ff12d537SAndre Fischer 
201f120fe41SAndre Fischer     ::std::multimap<sal_Int32,PanelContextDescriptor> aOrderedIds;
202ff12d537SAndre Fischer     for (PanelContainer::const_iterator
203ff12d537SAndre Fischer              iPanel(maPanels.begin()),
204ff12d537SAndre Fischer              iEnd(maPanels.end());
205ff12d537SAndre Fischer          iPanel!=iEnd;
206ff12d537SAndre Fischer          ++iPanel)
207ff12d537SAndre Fischer     {
208ff12d537SAndre Fischer         const PanelDescriptor& rPanelDescriptor (*iPanel);
20913e1c3b4SAndre Fischer         if ( ! rPanelDescriptor.msDeckId.equals(rsDeckId))
21013e1c3b4SAndre Fischer             continue;
21113e1c3b4SAndre Fischer 
21213e1c3b4SAndre Fischer         const ContextList::Entry* pEntry = rPanelDescriptor.maContextList.GetMatch(rContext);
21313e1c3b4SAndre Fischer         if (pEntry == NULL)
21413e1c3b4SAndre Fischer             continue;
21513e1c3b4SAndre Fischer 
21613e1c3b4SAndre Fischer         PanelContextDescriptor aPanelContextDescriptor;
21713e1c3b4SAndre Fischer         aPanelContextDescriptor.msId = rPanelDescriptor.msId;
21813e1c3b4SAndre Fischer         aPanelContextDescriptor.msMenuCommand = pEntry->msMenuCommand;
21913e1c3b4SAndre Fischer         aPanelContextDescriptor.mbIsInitiallyVisible = pEntry->mbIsInitiallyVisible;
22013e1c3b4SAndre Fischer         aPanelContextDescriptor.mbShowForReadOnlyDocuments = rPanelDescriptor.mbShowForReadOnlyDocuments;
22113e1c3b4SAndre Fischer         aOrderedIds.insert(::std::multimap<sal_Int32,PanelContextDescriptor>::value_type(
22213e1c3b4SAndre Fischer                 rPanelDescriptor.mnOrderIndex,
22313e1c3b4SAndre Fischer                 aPanelContextDescriptor));
224ff12d537SAndre Fischer     }
225ff12d537SAndre Fischer 
226f120fe41SAndre Fischer     for (::std::multimap<sal_Int32,PanelContextDescriptor>::const_iterator
22795a18594SAndre Fischer              iId(aOrderedIds.begin()),
22895a18594SAndre Fischer              iEnd(aOrderedIds.end());
22995a18594SAndre Fischer          iId!=iEnd;
23095a18594SAndre Fischer          ++iId)
23195a18594SAndre Fischer     {
23295a18594SAndre Fischer         rPanelIds.push_back(iId->second);
23395a18594SAndre Fischer     }
23495a18594SAndre Fischer 
23595a18594SAndre Fischer     return rPanelIds;
236ff12d537SAndre Fischer }
237ff12d537SAndre Fischer 
238ff12d537SAndre Fischer 
239ff12d537SAndre Fischer 
240ff12d537SAndre Fischer 
241ff12d537SAndre Fischer void ResourceManager::ReadDeckList (void)
242ff12d537SAndre Fischer {
243ff12d537SAndre Fischer     const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory());
244ff12d537SAndre Fischer     const ::utl::OConfigurationTreeRoot aDeckRootNode (
245ff12d537SAndre Fischer         aContext,
246ff12d537SAndre Fischer         A2S("org.openoffice.Office.UI.Sidebar/Content/DeckList"),
247ff12d537SAndre Fischer         false);
248ff12d537SAndre Fischer     if ( ! aDeckRootNode.isValid() )
249ff12d537SAndre Fischer         return;
250ff12d537SAndre Fischer 
251ff12d537SAndre Fischer     const Sequence<OUString> aDeckNodeNames (aDeckRootNode.getNodeNames());
252ff12d537SAndre Fischer     const sal_Int32 nCount (aDeckNodeNames.getLength());
253ff12d537SAndre Fischer     maDecks.resize(nCount);
254ff12d537SAndre Fischer     sal_Int32 nWriteIndex(0);
255ff12d537SAndre Fischer     for (sal_Int32 nReadIndex(0); nReadIndex<nCount; ++nReadIndex)
256ff12d537SAndre Fischer     {
257ff12d537SAndre Fischer         const ::utl::OConfigurationNode aDeckNode (aDeckRootNode.openNode(aDeckNodeNames[nReadIndex]));
258ff12d537SAndre Fischer         if ( ! aDeckNode.isValid())
259ff12d537SAndre Fischer             continue;
260ff12d537SAndre Fischer 
261ff12d537SAndre Fischer         DeckDescriptor& rDeckDescriptor (maDecks[nWriteIndex++]);
262ff12d537SAndre Fischer 
2637a32b0c8SAndre Fischer         rDeckDescriptor.msTitle = ::comphelper::getString(
2647a32b0c8SAndre Fischer             aDeckNode.getNodeValue("Title"));
2657a32b0c8SAndre Fischer         rDeckDescriptor.msId = ::comphelper::getString(
2667a32b0c8SAndre Fischer             aDeckNode.getNodeValue("Id"));
2677a32b0c8SAndre Fischer         rDeckDescriptor.msIconURL = ::comphelper::getString(
2687a32b0c8SAndre Fischer             aDeckNode.getNodeValue("IconURL"));
2697a32b0c8SAndre Fischer         rDeckDescriptor.msHighContrastIconURL = ::comphelper::getString(
2707a32b0c8SAndre Fischer             aDeckNode.getNodeValue("HighContrastIconURL"));
2714e21436dSAndre Fischer         rDeckDescriptor.msTitleBarIconURL = ::comphelper::getString(
2724e21436dSAndre Fischer             aDeckNode.getNodeValue("TitleBarIconURL"));
2734e21436dSAndre Fischer         rDeckDescriptor.msHighContrastTitleBarIconURL = ::comphelper::getString(
2744e21436dSAndre Fischer             aDeckNode.getNodeValue("HighContrastTitleBarIconURL"));
2757a32b0c8SAndre Fischer         rDeckDescriptor.msHelpURL = ::comphelper::getString(
2767a32b0c8SAndre Fischer             aDeckNode.getNodeValue("HelpURL"));
277ff12d537SAndre Fischer         rDeckDescriptor.msHelpText = rDeckDescriptor.msTitle;
27895a18594SAndre Fischer         rDeckDescriptor.mbIsEnabled = true;
2797a32b0c8SAndre Fischer         rDeckDescriptor.mnOrderIndex = ::comphelper::getINT32(
2807a32b0c8SAndre Fischer             aDeckNode.getNodeValue("OrderIndex"));
2817a32b0c8SAndre Fischer 
282f120fe41SAndre Fischer         ReadContextList(
283f120fe41SAndre Fischer             aDeckNode,
284f120fe41SAndre Fischer             rDeckDescriptor.maContextList,
285f120fe41SAndre Fischer             OUString());
286ff12d537SAndre Fischer     }
287ff12d537SAndre Fischer 
288ff12d537SAndre Fischer     // When there where invalid nodes then we have to adapt the size
289ff12d537SAndre Fischer     // of the deck vector.
290ff12d537SAndre Fischer     if (nWriteIndex<nCount)
291ff12d537SAndre Fischer         maDecks.resize(nWriteIndex);
292ff12d537SAndre Fischer }
293ff12d537SAndre Fischer 
294ff12d537SAndre Fischer 
295ff12d537SAndre Fischer 
296ff12d537SAndre Fischer 
297ff12d537SAndre Fischer void ResourceManager::ReadPanelList (void)
298ff12d537SAndre Fischer {
299ff12d537SAndre Fischer     const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory());
300ff12d537SAndre Fischer     const ::utl::OConfigurationTreeRoot aPanelRootNode (
301ff12d537SAndre Fischer         aContext,
302ff12d537SAndre Fischer         A2S("org.openoffice.Office.UI.Sidebar/Content/PanelList"),
303ff12d537SAndre Fischer         false);
304ff12d537SAndre Fischer     if ( ! aPanelRootNode.isValid() )
305ff12d537SAndre Fischer         return;
306ff12d537SAndre Fischer 
307ff12d537SAndre Fischer     const Sequence<OUString> aPanelNodeNames (aPanelRootNode.getNodeNames());
308ff12d537SAndre Fischer     const sal_Int32 nCount (aPanelNodeNames.getLength());
309ff12d537SAndre Fischer     maPanels.resize(nCount);
310ff12d537SAndre Fischer     sal_Int32 nWriteIndex (0);
311ff12d537SAndre Fischer     for (sal_Int32 nReadIndex(0); nReadIndex<nCount; ++nReadIndex)
312ff12d537SAndre Fischer     {
313ff12d537SAndre Fischer         const ::utl::OConfigurationNode aPanelNode (aPanelRootNode.openNode(aPanelNodeNames[nReadIndex]));
314ff12d537SAndre Fischer         if ( ! aPanelNode.isValid())
315ff12d537SAndre Fischer             continue;
316ff12d537SAndre Fischer 
317ff12d537SAndre Fischer         PanelDescriptor& rPanelDescriptor (maPanels[nWriteIndex++]);
318ff12d537SAndre Fischer 
319ff12d537SAndre Fischer         rPanelDescriptor.msTitle = ::comphelper::getString(
320ff12d537SAndre Fischer             aPanelNode.getNodeValue("Title"));
321ff12d537SAndre Fischer         rPanelDescriptor.mbIsTitleBarOptional = ::comphelper::getBOOL(
322ff12d537SAndre Fischer             aPanelNode.getNodeValue("TitleBarIsOptional"));
323ff12d537SAndre Fischer         rPanelDescriptor.msId = ::comphelper::getString(
324ff12d537SAndre Fischer             aPanelNode.getNodeValue("Id"));
325ff12d537SAndre Fischer         rPanelDescriptor.msDeckId = ::comphelper::getString(
326ff12d537SAndre Fischer             aPanelNode.getNodeValue("DeckId"));
3274e21436dSAndre Fischer         rPanelDescriptor.msTitleBarIconURL = ::comphelper::getString(
3284e21436dSAndre Fischer             aPanelNode.getNodeValue("TitleBarIconURL"));
3294e21436dSAndre Fischer         rPanelDescriptor.msHighContrastTitleBarIconURL = ::comphelper::getString(
3304e21436dSAndre Fischer             aPanelNode.getNodeValue("HighContrastTitleBarIconURL"));
331ff12d537SAndre Fischer         rPanelDescriptor.msHelpURL = ::comphelper::getString(
332ff12d537SAndre Fischer             aPanelNode.getNodeValue("HelpURL"));
333ff12d537SAndre Fischer         rPanelDescriptor.msImplementationURL = ::comphelper::getString(
334ff12d537SAndre Fischer             aPanelNode.getNodeValue("ImplementationURL"));
33595a18594SAndre Fischer         rPanelDescriptor.mnOrderIndex = ::comphelper::getINT32(
33695a18594SAndre Fischer             aPanelNode.getNodeValue("OrderIndex"));
33713e1c3b4SAndre Fischer         rPanelDescriptor.mbShowForReadOnlyDocuments = ::comphelper::getBOOL(
33813e1c3b4SAndre Fischer             aPanelNode.getNodeValue("ShowForReadOnlyDocument"));
3397a32b0c8SAndre Fischer         rPanelDescriptor.mbWantsCanvas = ::comphelper::getBOOL(
3407a32b0c8SAndre Fischer             aPanelNode.getNodeValue("WantsCanvas"));
341f120fe41SAndre Fischer         const OUString sDefaultMenuCommand (::comphelper::getString(
342f120fe41SAndre Fischer                 aPanelNode.getNodeValue("DefaultMenuCommand")));
34354eaaa32SAndre Fischer 
344f120fe41SAndre Fischer         ReadContextList(
345f120fe41SAndre Fischer             aPanelNode,
346f120fe41SAndre Fischer             rPanelDescriptor.maContextList,
347f120fe41SAndre Fischer             sDefaultMenuCommand);
348ff12d537SAndre Fischer     }
349ff12d537SAndre Fischer 
350ff12d537SAndre Fischer     // When there where invalid nodes then we have to adapt the size
351ff12d537SAndre Fischer     // of the deck vector.
352ff12d537SAndre Fischer     if (nWriteIndex<nCount)
353ff12d537SAndre Fischer         maPanels.resize(nWriteIndex);
354ff12d537SAndre Fischer }
355ff12d537SAndre Fischer 
356ff12d537SAndre Fischer 
357ff12d537SAndre Fischer 
358ff12d537SAndre Fischer 
359f120fe41SAndre Fischer void ResourceManager::ReadContextList (
360f120fe41SAndre Fischer     const ::utl::OConfigurationNode& rParentNode,
361f120fe41SAndre Fischer     ContextList& rContextList,
362f120fe41SAndre Fischer     const OUString& rsDefaultMenuCommand) const
363ff12d537SAndre Fischer {
364f120fe41SAndre Fischer     const Any aValue = rParentNode.getNodeValue("ContextList");
365f120fe41SAndre Fischer     Sequence<OUString> aValues;
366f120fe41SAndre Fischer     sal_Int32 nCount;
367f120fe41SAndre Fischer     if (aValue >>= aValues)
368f120fe41SAndre Fischer         nCount = aValues.getLength();
369f120fe41SAndre Fischer     else
370f120fe41SAndre Fischer         nCount = 0;
371f120fe41SAndre Fischer 
372f120fe41SAndre Fischer     for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
373ff12d537SAndre Fischer     {
374f120fe41SAndre Fischer         const OUString sValue (aValues[nIndex]);
375f120fe41SAndre Fischer         sal_Int32 nCharacterIndex (0);
376f120fe41SAndre Fischer         const OUString sApplicationName (sValue.getToken(0, ',', nCharacterIndex).trim());
377f120fe41SAndre Fischer         if (nCharacterIndex < 0)
378f120fe41SAndre Fischer         {
379f120fe41SAndre Fischer             if (sApplicationName.getLength() == 0)
380f120fe41SAndre Fischer             {
381f120fe41SAndre Fischer                 // This is a valid case: in the XML file the separator
382f120fe41SAndre Fischer                 // was used as terminator.  Using it in the last line
383f120fe41SAndre Fischer                 // creates an additional but empty entry.
384f120fe41SAndre Fischer                 break;
385f120fe41SAndre Fischer             }
386f120fe41SAndre Fischer             else
387f120fe41SAndre Fischer             {
388f120fe41SAndre Fischer                 OSL_ASSERT("expecting three or four values per ContextList entry, separated by comma");
389f120fe41SAndre Fischer                 continue;
390f120fe41SAndre Fischer             }
391f120fe41SAndre Fischer         }
3927a32b0c8SAndre Fischer 
393f120fe41SAndre Fischer         const OUString sContextName (sValue.getToken(0, ',', nCharacterIndex).trim());
394f120fe41SAndre Fischer         if (nCharacterIndex < 0)
3957a32b0c8SAndre Fischer         {
396f120fe41SAndre Fischer             OSL_ASSERT("expecting three or four values per ContextList entry, separated by comma");
397f120fe41SAndre Fischer             continue;
398f120fe41SAndre Fischer         }
399f120fe41SAndre Fischer 
400f120fe41SAndre Fischer         const OUString sInitialState (sValue.getToken(0, ',', nCharacterIndex).trim());
401f120fe41SAndre Fischer 
402f120fe41SAndre Fischer         // The fourth argument is optional.
403f120fe41SAndre Fischer         const OUString sMenuCommandOverride (
404f120fe41SAndre Fischer             nCharacterIndex<0
405f120fe41SAndre Fischer                 ? OUString()
406f120fe41SAndre Fischer                 : sValue.getToken(0, ',', nCharacterIndex).trim());
407f120fe41SAndre Fischer         const OUString sMenuCommand (
408f120fe41SAndre Fischer             sMenuCommandOverride.getLength()>0
409f120fe41SAndre Fischer                 ? (sMenuCommandOverride.equalsAscii("none")
410f120fe41SAndre Fischer                     ? OUString()
411f120fe41SAndre Fischer                     : sMenuCommandOverride)
412f120fe41SAndre Fischer                 : rsDefaultMenuCommand);
413f120fe41SAndre Fischer 
41485f1aca2SAndre Fischer         // Setup a list of application enums.  Note that the
41585f1aca2SAndre Fischer         // application name may result in more than one value (eg
41685f1aca2SAndre Fischer         // DrawImpress will result in two enums, one for Draw and one
41785f1aca2SAndre Fischer         // for Impress).
41885f1aca2SAndre Fischer         ::std::vector<EnumContext::Application> aApplications;
419f120fe41SAndre Fischer         EnumContext::Application eApplication (EnumContext::GetApplicationEnum(sApplicationName));
420f120fe41SAndre Fischer         if (eApplication == EnumContext::Application_None
421f120fe41SAndre Fischer             && !sApplicationName.equals(EnumContext::GetApplicationName(EnumContext::Application_None)))
422f120fe41SAndre Fischer         {
423f120fe41SAndre Fischer             // Handle some special names: abbreviations that make
424f120fe41SAndre Fischer             // context descriptions more readable.
425f120fe41SAndre Fischer             if (sApplicationName.equalsAscii("Writer"))
42685f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_Writer);
427f120fe41SAndre Fischer             else if (sApplicationName.equalsAscii("Calc"))
42885f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_Calc);
429f120fe41SAndre Fischer             else if (sApplicationName.equalsAscii("Draw"))
43085f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_Draw);
431f120fe41SAndre Fischer             else if (sApplicationName.equalsAscii("Impress"))
43285f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_Impress);
433f120fe41SAndre Fischer             else if (sApplicationName.equalsAscii("DrawImpress"))
434f120fe41SAndre Fischer             {
435f120fe41SAndre Fischer                 // A special case among the special names:  it is
436f120fe41SAndre Fischer                 // common to use the same context descriptions for
437f120fe41SAndre Fischer                 // both Draw and Impress.  This special case helps to
438f120fe41SAndre Fischer                 // avoid duplication in the .xcu file.
43985f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_Draw);
44085f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_Impress);
441dfbb0ba8SAndre Fischer             }
44285f1aca2SAndre Fischer             else if (sApplicationName.equalsAscii("WriterVariants"))
443dfbb0ba8SAndre Fischer             {
44485f1aca2SAndre Fischer                 // Another special case for all Writer variants.
44585f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_Writer);
44685f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_WriterGlobal);
44785f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_WriterWeb);
44885f1aca2SAndre Fischer                 aApplications.push_back(EnumContext::Application_WriterXML);
44965d25098SAndre Fischer                 aApplications.push_back(EnumContext::Application_WriterForm);
450f120fe41SAndre Fischer             }
451f120fe41SAndre Fischer             else
452f120fe41SAndre Fischer             {
453f120fe41SAndre Fischer                 OSL_ASSERT("application name not recognized");
454f120fe41SAndre Fischer                 continue;
455f120fe41SAndre Fischer             }
4567a32b0c8SAndre Fischer         }
45785f1aca2SAndre Fischer         else
45885f1aca2SAndre Fischer         {
45985f1aca2SAndre Fischer             // No conversion of the application name necessary.
46085f1aca2SAndre Fischer             aApplications.push_back(eApplication);
46185f1aca2SAndre Fischer         }
46285f1aca2SAndre Fischer 
46385f1aca2SAndre 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 
47185f1aca2SAndre Fischer         // Setup the flag that controls whether a deck/pane is
47285f1aca2SAndre 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 
48485f1aca2SAndre Fischer         // Add context descriptors.
48585f1aca2SAndre Fischer         for (::std::vector<EnumContext::Application>::const_iterator
48685f1aca2SAndre Fischer                  iApplication(aApplications.begin()),
48785f1aca2SAndre Fischer                  iEnd(aApplications.end());
48885f1aca2SAndre Fischer              iApplication!=iEnd;
48985f1aca2SAndre Fischer              ++iApplication)
49085f1aca2SAndre Fischer         {
49185f1aca2SAndre Fischer             if (*iApplication != EnumContext::Application_None)
49285f1aca2SAndre Fischer                 rContextList.AddContextDescription(
49385f1aca2SAndre Fischer                     Context(
49485f1aca2SAndre Fischer                         EnumContext::GetApplicationName(*iApplication),
49585f1aca2SAndre Fischer                         EnumContext::GetContextName(eContext)),
49685f1aca2SAndre Fischer                     bIsInitiallyVisible,
49785f1aca2SAndre Fischer                     sMenuCommand);
49885f1aca2SAndre 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());
56013e1c3b4SAndre Fischer         rPanelDescriptor.msImplementationURL = rsNodeName;
56113e1c3b4SAndre Fischer         rPanelDescriptor.mbShowForReadOnlyDocuments = false;
562ff12d537SAndre Fischer     }
563ff12d537SAndre Fischer 
564ff12d537SAndre Fischer     // When there where invalid nodes then we have to adapt the size
565ff12d537SAndre Fischer     // of the deck and panel vectors.
566ff12d537SAndre Fischer     if (nDeckWriteIndex < maDecks.size())
567ff12d537SAndre Fischer         maDecks.resize(nDeckWriteIndex);
568ff12d537SAndre Fischer     if (nPanelWriteIndex < maPanels.size())
569ff12d537SAndre Fischer         maPanels.resize(nPanelWriteIndex);
570ff12d537SAndre Fischer }
571ff12d537SAndre Fischer 
572ff12d537SAndre Fischer 
573ff12d537SAndre Fischer 
574ff12d537SAndre Fischer 
575*7e429a12SAndre Fischer void ResourceManager::StorePanelExpansionState (
576*7e429a12SAndre Fischer     const ::rtl::OUString& rsPanelId,
577*7e429a12SAndre Fischer     const bool bExpansionState,
578*7e429a12SAndre Fischer     const Context& rContext)
579*7e429a12SAndre Fischer {
580*7e429a12SAndre Fischer     for (PanelContainer::iterator
581*7e429a12SAndre Fischer              iPanel(maPanels.begin()),
582*7e429a12SAndre Fischer              iEnd(maPanels.end());
583*7e429a12SAndre Fischer          iPanel!=iEnd;
584*7e429a12SAndre Fischer          ++iPanel)
585*7e429a12SAndre Fischer     {
586*7e429a12SAndre Fischer         if (iPanel->msId.equals(rsPanelId))
587*7e429a12SAndre Fischer         {
588*7e429a12SAndre Fischer             ContextList::Entry* pEntry (
589*7e429a12SAndre Fischer                 iPanel->maContextList.GetMatch (rContext));
590*7e429a12SAndre Fischer             if (pEntry != NULL)
591*7e429a12SAndre Fischer                 pEntry->mbIsInitiallyVisible = bExpansionState;
592*7e429a12SAndre Fischer         }
593*7e429a12SAndre Fischer     }
594*7e429a12SAndre Fischer }
595*7e429a12SAndre Fischer 
596*7e429a12SAndre Fischer 
597*7e429a12SAndre Fischer 
598*7e429a12SAndre Fischer 
599ff12d537SAndre Fischer ::rtl::OUString ResourceManager::GetModuleName (
60095a18594SAndre Fischer     const cssu::Reference<css::frame::XFrame>& rxFrame)
601ff12d537SAndre Fischer {
602e56b0a16SAndre Fischer     if ( ! rxFrame.is() || ! rxFrame->getController().is())
603e56b0a16SAndre Fischer         return OUString();
604e56b0a16SAndre Fischer 
605ff12d537SAndre Fischer     try
606ff12d537SAndre Fischer     {
607ff12d537SAndre Fischer         const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory());
608ff12d537SAndre Fischer         const Reference<frame::XModuleManager> xModuleManager (
609e56b0a16SAndre Fischer             aContext.createComponent("com.sun.star.frame.ModuleManager"),
610e56b0a16SAndre Fischer             UNO_QUERY_THROW);
611ff12d537SAndre Fischer         return xModuleManager->identify(rxFrame);
612ff12d537SAndre Fischer     }
613ff12d537SAndre Fischer     catch (const Exception&)
614ff12d537SAndre Fischer     {
615ff12d537SAndre Fischer         DBG_UNHANDLED_EXCEPTION();
616ff12d537SAndre Fischer     }
617ff12d537SAndre Fischer     return OUString();
618ff12d537SAndre Fischer }
619ff12d537SAndre Fischer 
620ff12d537SAndre Fischer 
621ff12d537SAndre Fischer 
622ff12d537SAndre Fischer 
623ff12d537SAndre Fischer ::utl::OConfigurationTreeRoot ResourceManager::GetLegacyAddonRootNode (
624ff12d537SAndre Fischer     const ::rtl::OUString& rsModuleName) const
625ff12d537SAndre Fischer {
626ff12d537SAndre Fischer     try
627ff12d537SAndre Fischer     {
628ff12d537SAndre Fischer         const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory());
629ff12d537SAndre Fischer         const Reference<container::XNameAccess> xModuleAccess (
630ff12d537SAndre Fischer             aContext.createComponent("com.sun.star.frame.ModuleManager"),
631ff12d537SAndre Fischer             UNO_QUERY_THROW);
632ff12d537SAndre Fischer         const ::comphelper::NamedValueCollection aModuleProperties (xModuleAccess->getByName(rsModuleName));
633ff12d537SAndre Fischer         const ::rtl::OUString sWindowStateRef (aModuleProperties.getOrDefault(
634ff12d537SAndre Fischer                 "ooSetupFactoryWindowStateConfigRef",
635ff12d537SAndre Fischer                 ::rtl::OUString()));
636ff12d537SAndre Fischer 
637ff12d537SAndre Fischer         ::rtl::OUStringBuffer aPathComposer;
638ff12d537SAndre Fischer         aPathComposer.appendAscii("org.openoffice.Office.UI.");
639ff12d537SAndre Fischer         aPathComposer.append(sWindowStateRef);
640ff12d537SAndre Fischer         aPathComposer.appendAscii("/UIElements/States");
641ff12d537SAndre Fischer 
642ff12d537SAndre Fischer         return ::utl::OConfigurationTreeRoot(aContext, aPathComposer.makeStringAndClear(), false);
643ff12d537SAndre Fischer     }
644ff12d537SAndre Fischer     catch( const Exception& )
645ff12d537SAndre Fischer     {
646ff12d537SAndre Fischer         DBG_UNHANDLED_EXCEPTION();
647ff12d537SAndre Fischer     }
648ff12d537SAndre Fischer 
649ff12d537SAndre Fischer     return ::utl::OConfigurationTreeRoot();
650ff12d537SAndre Fischer }
651ff12d537SAndre Fischer 
652ff12d537SAndre Fischer 
653ff12d537SAndre Fischer 
654ff12d537SAndre Fischer 
655ff12d537SAndre Fischer void ResourceManager::GetToolPanelNodeNames (
656ff12d537SAndre Fischer     ::std::vector<OUString>& rMatchingNames,
657ff12d537SAndre Fischer     const ::utl::OConfigurationTreeRoot aRoot) const
658ff12d537SAndre Fischer {
659ff12d537SAndre Fischer     Sequence<OUString> aChildNodeNames (aRoot.getNodeNames());
660ff12d537SAndre Fischer     const sal_Int32 nCount (aChildNodeNames.getLength());
661ff12d537SAndre Fischer     for (sal_Int32 nIndex(0); nIndex<nCount; ++nIndex)
662ff12d537SAndre Fischer     {
663ff12d537SAndre Fischer         if (aChildNodeNames[nIndex].matchAsciiL(
664ff12d537SAndre Fischer                 RTL_CONSTASCII_STRINGPARAM( "private:resource/toolpanel/")))
665ff12d537SAndre Fischer             rMatchingNames.push_back(aChildNodeNames[nIndex]);
666ff12d537SAndre Fischer     }
667ff12d537SAndre Fischer }
668ff12d537SAndre Fischer 
669ff12d537SAndre Fischer 
670ff12d537SAndre Fischer 
67113e1c3b4SAndre Fischer 
67213e1c3b4SAndre Fischer bool ResourceManager::IsDeckEnabled (
67313e1c3b4SAndre Fischer     const OUString& rsDeckId,
67413e1c3b4SAndre Fischer     const Context& rContext,
67513e1c3b4SAndre Fischer     const Reference<frame::XFrame>& rxFrame) const
67613e1c3b4SAndre Fischer {
67713e1c3b4SAndre Fischer     // Check if any panel that matches the current context can be
67813e1c3b4SAndre Fischer     // displayed.
67913e1c3b4SAndre Fischer     ResourceManager::PanelContextDescriptorContainer aPanelContextDescriptors;
68013e1c3b4SAndre Fischer     ResourceManager::Instance().GetMatchingPanels(
68113e1c3b4SAndre Fischer         aPanelContextDescriptors,
68213e1c3b4SAndre Fischer         rContext,
68313e1c3b4SAndre Fischer         rsDeckId,
68413e1c3b4SAndre Fischer         rxFrame);
68513e1c3b4SAndre Fischer 
68613e1c3b4SAndre Fischer     for (ResourceManager::PanelContextDescriptorContainer::const_iterator
68713e1c3b4SAndre Fischer              iPanel(aPanelContextDescriptors.begin()),
68813e1c3b4SAndre Fischer              iEnd(aPanelContextDescriptors.end());
68913e1c3b4SAndre Fischer          iPanel!=iEnd;
69013e1c3b4SAndre Fischer          ++iPanel)
69113e1c3b4SAndre Fischer     {
69213e1c3b4SAndre Fischer         if (iPanel->mbShowForReadOnlyDocuments)
69313e1c3b4SAndre Fischer             return true;
69413e1c3b4SAndre Fischer     }
69513e1c3b4SAndre Fischer 
69613e1c3b4SAndre Fischer     return false;
69713e1c3b4SAndre Fischer }
69813e1c3b4SAndre Fischer 
69913e1c3b4SAndre Fischer 
700ff12d537SAndre Fischer } } // end of namespace sfx2::sidebar
701