1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 #include "precompiled_sfx2.hxx"
23 
24 #include "ResourceManager.hxx"
25 #include "sfx2/sidebar/Tools.hxx"
26 
27 #include <unotools/confignode.hxx>
28 #include <comphelper/componentcontext.hxx>
29 #include <comphelper/processfactory.hxx>
30 #include <comphelper/namedvaluecollection.hxx>
31 #include <comphelper/types.hxx>
32 #include <comphelper/stlunosequence.hxx>
33 
34 #include <rtl/ustrbuf.hxx>
35 #include <tools/diagnose_ex.h>
36 
37 #include <com/sun/star/frame/XModuleManager.hpp>
38 
39 #include <map>
40 
41 
42 
43 using ::rtl::OUString;
44 using namespace css;
45 using namespace cssu;
46 
47 namespace sfx2 { namespace sidebar {
48 
49 #define gsPrivateResourceToolpanelPrefix "private:resource/toolpanel/"
50 
51 
52 
53 class ResourceManager::Deleter
54 {
55 public:
operator ()(ResourceManager * pObject)56     void operator() (ResourceManager* pObject)
57     {
58         delete pObject;
59     }
60 };
61 
62 
Instance(void)63 ResourceManager& ResourceManager::Instance (void)
64 {
65     static ResourceManager maInstance;
66     return maInstance;
67 }
68 
69 
70 
71 
ResourceManager(void)72 ResourceManager::ResourceManager (void)
73     : maDecks(),
74       maPanels(),
75       maProcessedApplications()
76 {
77     ReadDeckList();
78     ReadPanelList();
79 }
80 
81 
82 
83 
~ResourceManager(void)84 ResourceManager::~ResourceManager (void)
85 {
86     maPanels.clear();
87     maDecks.clear();
88 }
89 
90 
91 
92 
GetDeckDescriptor(const::rtl::OUString & rsDeckId) const93 const DeckDescriptor* ResourceManager::GetDeckDescriptor (
94     const ::rtl::OUString& rsDeckId) const
95 {
96     for (DeckContainer::const_iterator
97              iDeck(maDecks.begin()),
98              iEnd(maDecks.end());
99          iDeck!=iEnd;
100          ++iDeck)
101     {
102         if (iDeck->msId.equals(rsDeckId))
103             return &*iDeck;
104     }
105     return NULL;
106 }
107 
108 
109 
110 
GetPanelDescriptor(const::rtl::OUString & rsPanelId) const111 const PanelDescriptor* ResourceManager::GetPanelDescriptor (
112     const ::rtl::OUString& rsPanelId) const
113 {
114     for (PanelContainer::const_iterator
115              iPanel(maPanels.begin()),
116              iEnd(maPanels.end());
117          iPanel!=iEnd;
118          ++iPanel)
119     {
120         if (iPanel->msId.equals(rsPanelId))
121             return &*iPanel;
122     }
123     return NULL;
124 }
125 
126 
127 
128 
SetIsDeckEnabled(const::rtl::OUString & rsDeckId,const bool bIsEnabled)129 void ResourceManager::SetIsDeckEnabled (
130     const ::rtl::OUString& rsDeckId,
131     const bool bIsEnabled)
132 {
133     for (DeckContainer::iterator
134              iDeck(maDecks.begin()),
135              iEnd(maDecks.end());
136          iDeck!=iEnd;
137          ++iDeck)
138     {
139         if (iDeck->msId.equals(rsDeckId))
140         {
141             iDeck->mbIsEnabled = bIsEnabled;
142             return;
143         }
144     }
145 }
146 
147 
148 
149 
GetMatchingDecks(DeckContextDescriptorContainer & rDecks,const Context & rContext,const bool bIsDocumentReadOnly,const Reference<frame::XFrame> & rxFrame)150 const ResourceManager::DeckContextDescriptorContainer& ResourceManager::GetMatchingDecks (
151     DeckContextDescriptorContainer& rDecks,
152     const Context& rContext,
153     const bool bIsDocumentReadOnly,
154     const Reference<frame::XFrame>& rxFrame)
155 {
156     ReadLegacyAddons(rxFrame);
157 
158     ::std::multimap<sal_Int32,DeckContextDescriptor> aOrderedIds;
159     for (DeckContainer::const_iterator
160              iDeck(maDecks.begin()),
161              iEnd (maDecks.end());
162          iDeck!=iEnd;
163          ++iDeck)
164     {
165         const DeckDescriptor& rDeckDescriptor (*iDeck);
166         if (rDeckDescriptor.maContextList.GetMatch(rContext) == NULL)
167             continue;
168         DeckContextDescriptor aDeckContextDescriptor;
169         aDeckContextDescriptor.msId = rDeckDescriptor.msId;
170         aDeckContextDescriptor.mbIsEnabled =
171             ! bIsDocumentReadOnly
172             || IsDeckEnabled(rDeckDescriptor.msId, rContext, rxFrame);
173         aOrderedIds.insert(::std::multimap<sal_Int32,DeckContextDescriptor>::value_type(
174                 rDeckDescriptor.mnOrderIndex,
175                 aDeckContextDescriptor));
176     }
177 
178     for (::std::multimap<sal_Int32,DeckContextDescriptor>::const_iterator
179              iId(aOrderedIds.begin()),
180              iEnd(aOrderedIds.end());
181          iId!=iEnd;
182          ++iId)
183     {
184         rDecks.push_back(iId->second);
185     }
186 
187     return rDecks;
188 }
189 
190 
191 
192 
GetMatchingPanels(PanelContextDescriptorContainer & rPanelIds,const Context & rContext,const::rtl::OUString & rsDeckId,const Reference<frame::XFrame> & rxFrame)193 const ResourceManager::PanelContextDescriptorContainer& ResourceManager::GetMatchingPanels (
194     PanelContextDescriptorContainer& rPanelIds,
195     const Context& rContext,
196     const ::rtl::OUString& rsDeckId,
197     const Reference<frame::XFrame>& rxFrame)
198 {
199     ReadLegacyAddons(rxFrame);
200 
201     ::std::multimap<sal_Int32,PanelContextDescriptor> aOrderedIds;
202     for (PanelContainer::const_iterator
203              iPanel(maPanels.begin()),
204              iEnd(maPanels.end());
205          iPanel!=iEnd;
206          ++iPanel)
207     {
208         const PanelDescriptor& rPanelDescriptor (*iPanel);
209         if ( ! rPanelDescriptor.msDeckId.equals(rsDeckId))
210             continue;
211 
212         const ContextList::Entry* pEntry = rPanelDescriptor.maContextList.GetMatch(rContext);
213         if (pEntry == NULL)
214             continue;
215 
216         PanelContextDescriptor aPanelContextDescriptor;
217         aPanelContextDescriptor.msId = rPanelDescriptor.msId;
218         aPanelContextDescriptor.msMenuCommand = pEntry->msMenuCommand;
219         aPanelContextDescriptor.mbIsInitiallyVisible = pEntry->mbIsInitiallyVisible;
220         aPanelContextDescriptor.mbShowForReadOnlyDocuments = rPanelDescriptor.mbShowForReadOnlyDocuments;
221         aOrderedIds.insert(::std::multimap<sal_Int32,PanelContextDescriptor>::value_type(
222                 rPanelDescriptor.mnOrderIndex,
223                 aPanelContextDescriptor));
224     }
225 
226     for (::std::multimap<sal_Int32,PanelContextDescriptor>::const_iterator
227              iId(aOrderedIds.begin()),
228              iEnd(aOrderedIds.end());
229          iId!=iEnd;
230          ++iId)
231     {
232         rPanelIds.push_back(iId->second);
233     }
234 
235     return rPanelIds;
236 }
237 
238 
239 
240 
ReadDeckList(void)241 void ResourceManager::ReadDeckList (void)
242 {
243     const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory());
244     const ::utl::OConfigurationTreeRoot aDeckRootNode (
245         aContext,
246         A2S("org.openoffice.Office.UI.Sidebar/Content/DeckList"),
247         false);
248     if ( ! aDeckRootNode.isValid() )
249         return;
250 
251     const Sequence<OUString> aDeckNodeNames (aDeckRootNode.getNodeNames());
252     const sal_Int32 nCount (aDeckNodeNames.getLength());
253     maDecks.resize(nCount);
254     sal_Int32 nWriteIndex(0);
255     for (sal_Int32 nReadIndex(0); nReadIndex<nCount; ++nReadIndex)
256     {
257         const ::utl::OConfigurationNode aDeckNode (aDeckRootNode.openNode(aDeckNodeNames[nReadIndex]));
258         if ( ! aDeckNode.isValid())
259             continue;
260 
261         DeckDescriptor& rDeckDescriptor (maDecks[nWriteIndex++]);
262 
263         rDeckDescriptor.msTitle = ::comphelper::getString(
264             aDeckNode.getNodeValue("Title"));
265         rDeckDescriptor.msId = ::comphelper::getString(
266             aDeckNode.getNodeValue("Id"));
267         rDeckDescriptor.msIconURL = ::comphelper::getString(
268             aDeckNode.getNodeValue("IconURL"));
269         rDeckDescriptor.msHighContrastIconURL = ::comphelper::getString(
270             aDeckNode.getNodeValue("HighContrastIconURL"));
271         rDeckDescriptor.msTitleBarIconURL = ::comphelper::getString(
272             aDeckNode.getNodeValue("TitleBarIconURL"));
273         rDeckDescriptor.msHighContrastTitleBarIconURL = ::comphelper::getString(
274             aDeckNode.getNodeValue("HighContrastTitleBarIconURL"));
275         rDeckDescriptor.msHelpURL = ::comphelper::getString(
276             aDeckNode.getNodeValue("HelpURL"));
277         rDeckDescriptor.msHelpText = rDeckDescriptor.msTitle;
278         rDeckDescriptor.mbIsEnabled = true;
279         rDeckDescriptor.mnOrderIndex = ::comphelper::getINT32(
280             aDeckNode.getNodeValue("OrderIndex"));
281 
282         ReadContextList(
283             aDeckNode,
284             rDeckDescriptor.maContextList,
285             OUString());
286     }
287 
288     // When there where invalid nodes then we have to adapt the size
289     // of the deck vector.
290     if (nWriteIndex<nCount)
291         maDecks.resize(nWriteIndex);
292 }
293 
294 
295 
296 
ReadPanelList(void)297 void ResourceManager::ReadPanelList (void)
298 {
299     const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory());
300     const ::utl::OConfigurationTreeRoot aPanelRootNode (
301         aContext,
302         A2S("org.openoffice.Office.UI.Sidebar/Content/PanelList"),
303         false);
304     if ( ! aPanelRootNode.isValid() )
305         return;
306 
307     const Sequence<OUString> aPanelNodeNames (aPanelRootNode.getNodeNames());
308     const sal_Int32 nCount (aPanelNodeNames.getLength());
309     maPanels.resize(nCount);
310     sal_Int32 nWriteIndex (0);
311     for (sal_Int32 nReadIndex(0); nReadIndex<nCount; ++nReadIndex)
312     {
313         const ::utl::OConfigurationNode aPanelNode (aPanelRootNode.openNode(aPanelNodeNames[nReadIndex]));
314         if ( ! aPanelNode.isValid())
315             continue;
316 
317         PanelDescriptor& rPanelDescriptor (maPanels[nWriteIndex++]);
318 
319         rPanelDescriptor.msTitle = ::comphelper::getString(
320             aPanelNode.getNodeValue("Title"));
321         rPanelDescriptor.mbIsTitleBarOptional = ::comphelper::getBOOL(
322             aPanelNode.getNodeValue("TitleBarIsOptional"));
323         rPanelDescriptor.msId = ::comphelper::getString(
324             aPanelNode.getNodeValue("Id"));
325         rPanelDescriptor.msDeckId = ::comphelper::getString(
326             aPanelNode.getNodeValue("DeckId"));
327         rPanelDescriptor.msTitleBarIconURL = ::comphelper::getString(
328             aPanelNode.getNodeValue("TitleBarIconURL"));
329         rPanelDescriptor.msHighContrastTitleBarIconURL = ::comphelper::getString(
330             aPanelNode.getNodeValue("HighContrastTitleBarIconURL"));
331         rPanelDescriptor.msHelpURL = ::comphelper::getString(
332             aPanelNode.getNodeValue("HelpURL"));
333         rPanelDescriptor.msImplementationURL = ::comphelper::getString(
334             aPanelNode.getNodeValue("ImplementationURL"));
335         rPanelDescriptor.mnOrderIndex = ::comphelper::getINT32(
336             aPanelNode.getNodeValue("OrderIndex"));
337         rPanelDescriptor.mbShowForReadOnlyDocuments = ::comphelper::getBOOL(
338             aPanelNode.getNodeValue("ShowForReadOnlyDocument"));
339         rPanelDescriptor.mbWantsCanvas = ::comphelper::getBOOL(
340             aPanelNode.getNodeValue("WantsCanvas"));
341         const OUString sDefaultMenuCommand (::comphelper::getString(
342                 aPanelNode.getNodeValue("DefaultMenuCommand")));
343 
344         ReadContextList(
345             aPanelNode,
346             rPanelDescriptor.maContextList,
347             sDefaultMenuCommand);
348     }
349 
350     // When there where invalid nodes then we have to adapt the size
351     // of the deck vector.
352     if (nWriteIndex<nCount)
353         maPanels.resize(nWriteIndex);
354 }
355 
356 
357 
358 
ReadContextList(const::utl::OConfigurationNode & rParentNode,ContextList & rContextList,const OUString & rsDefaultMenuCommand) const359 void ResourceManager::ReadContextList (
360     const ::utl::OConfigurationNode& rParentNode,
361     ContextList& rContextList,
362     const OUString& rsDefaultMenuCommand) const
363 {
364     const Any aValue = rParentNode.getNodeValue("ContextList");
365     Sequence<OUString> aValues;
366     sal_Int32 nCount;
367     if (aValue >>= aValues)
368         nCount = aValues.getLength();
369     else
370         nCount = 0;
371 
372     for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
373     {
374         const OUString sValue (aValues[nIndex]);
375         sal_Int32 nCharacterIndex (0);
376         const OUString sApplicationName (sValue.getToken(0, ',', nCharacterIndex).trim());
377         if (nCharacterIndex < 0)
378         {
379             if (sApplicationName.getLength() == 0)
380             {
381                 // This is a valid case: in the XML file the separator
382                 // was used as terminator.  Using it in the last line
383                 // creates an additional but empty entry.
384                 break;
385             }
386             else
387             {
388                 OSL_ASSERT("expecting three or four values per ContextList entry, separated by comma");
389                 continue;
390             }
391         }
392 
393         const OUString sContextName (sValue.getToken(0, ',', nCharacterIndex).trim());
394         if (nCharacterIndex < 0)
395         {
396             OSL_ASSERT("expecting three or four values per ContextList entry, separated by comma");
397             continue;
398         }
399 
400         const OUString sInitialState (sValue.getToken(0, ',', nCharacterIndex).trim());
401 
402         // The fourth argument is optional.
403         const OUString sMenuCommandOverride (
404             nCharacterIndex<0
405                 ? OUString()
406                 : sValue.getToken(0, ',', nCharacterIndex).trim());
407         const OUString sMenuCommand (
408             sMenuCommandOverride.getLength()>0
409                 ? (sMenuCommandOverride.equalsAscii("none")
410                     ? OUString()
411                     : sMenuCommandOverride)
412                 : rsDefaultMenuCommand);
413 
414         // Setup a list of application enums.  Note that the
415         // application name may result in more than one value (eg
416         // DrawImpress will result in two enums, one for Draw and one
417         // for Impress).
418         ::std::vector<EnumContext::Application> aApplications;
419         EnumContext::Application eApplication (EnumContext::GetApplicationEnum(sApplicationName));
420         if (eApplication == EnumContext::Application_None
421             && !sApplicationName.equals(EnumContext::GetApplicationName(EnumContext::Application_None)))
422         {
423             // Handle some special names: abbreviations that make
424             // context descriptions more readable.
425             if (sApplicationName.equalsAscii("Writer"))
426                 aApplications.push_back(EnumContext::Application_Writer);
427             else if (sApplicationName.equalsAscii("Calc"))
428                 aApplications.push_back(EnumContext::Application_Calc);
429             else if (sApplicationName.equalsAscii("Draw"))
430                 aApplications.push_back(EnumContext::Application_Draw);
431             else if (sApplicationName.equalsAscii("Impress"))
432                 aApplications.push_back(EnumContext::Application_Impress);
433             else if (sApplicationName.equalsAscii("DrawImpress"))
434             {
435                 // A special case among the special names:  it is
436                 // common to use the same context descriptions for
437                 // both Draw and Impress.  This special case helps to
438                 // avoid duplication in the .xcu file.
439                 aApplications.push_back(EnumContext::Application_Draw);
440                 aApplications.push_back(EnumContext::Application_Impress);
441             }
442             else if (sApplicationName.equalsAscii("WriterVariants"))
443             {
444                 // Another special case for all Writer variants.
445                 aApplications.push_back(EnumContext::Application_Writer);
446                 aApplications.push_back(EnumContext::Application_WriterGlobal);
447                 aApplications.push_back(EnumContext::Application_WriterWeb);
448                 aApplications.push_back(EnumContext::Application_WriterXML);
449                 aApplications.push_back(EnumContext::Application_WriterForm);
450                 aApplications.push_back(EnumContext::Application_WriterReport);
451             }
452             else
453             {
454                 OSL_ASSERT("application name not recognized");
455                 continue;
456             }
457         }
458         else
459         {
460             // No conversion of the application name necessary.
461             aApplications.push_back(eApplication);
462         }
463 
464         // Setup the actual context enum.
465         const EnumContext::Context eContext (EnumContext::GetContextEnum(sContextName));
466         if (eContext == EnumContext::Context_Unknown)
467         {
468             OSL_ASSERT("context name not recognized");
469             continue;
470         }
471 
472         // Setup the flag that controls whether a deck/pane is
473         // initially visible/expanded.
474         bool bIsInitiallyVisible;
475         if (sInitialState.equalsAscii("visible"))
476             bIsInitiallyVisible = true;
477         else if (sInitialState.equalsAscii("hidden"))
478             bIsInitiallyVisible = false;
479         else
480         {
481             OSL_ASSERT("unrecognized state");
482             continue;
483         }
484 
485         // Add context descriptors.
486         for (::std::vector<EnumContext::Application>::const_iterator
487                  iApplication(aApplications.begin()),
488                  iEnd(aApplications.end());
489              iApplication!=iEnd;
490              ++iApplication)
491         {
492             if (*iApplication != EnumContext::Application_None)
493                 rContextList.AddContextDescription(
494                     Context(
495                         EnumContext::GetApplicationName(*iApplication),
496                         EnumContext::GetContextName(eContext)),
497                     bIsInitiallyVisible,
498                     sMenuCommand);
499         }
500     }
501 }
502 
503 
504 
505 
ReadLegacyAddons(const Reference<frame::XFrame> & rxFrame)506 void ResourceManager::ReadLegacyAddons (const Reference<frame::XFrame>& rxFrame)
507 {
508     // Get module name for given frame.
509     ::rtl::OUString sModuleName (Tools::GetModuleName(rxFrame));
510     if (sModuleName.getLength() == 0)
511         return;
512     if (maProcessedApplications.find(sModuleName) != maProcessedApplications.end())
513     {
514         // Addons for this application have already been read.
515         // There is nothing more to do.
516         return;
517     }
518 
519     // Mark module as processed.  Even when there is an error that
520     // prevents the configuration data from being read, this error
521     // will not be triggered a second time.
522     maProcessedApplications.insert(sModuleName);
523 
524     // Get access to the configuration root node for the application.
525     ::utl::OConfigurationTreeRoot aLegacyRootNode (GetLegacyAddonRootNode(sModuleName));
526     if ( ! aLegacyRootNode.isValid())
527         return;
528 
529     // Process child nodes.
530     ::std::vector<OUString> aMatchingNodeNames;
531     GetToolPanelNodeNames(aMatchingNodeNames, aLegacyRootNode);
532     const sal_Int32 nCount (aMatchingNodeNames.size());
533     size_t nDeckWriteIndex (maDecks.size());
534     size_t nPanelWriteIndex (maPanels.size());
535     maDecks.resize(maDecks.size() + nCount);
536     maPanels.resize(maPanels.size() + nCount);
537     for (sal_Int32 nReadIndex(0); nReadIndex<nCount; ++nReadIndex)
538     {
539         const OUString& rsNodeName (aMatchingNodeNames[nReadIndex]);
540         const ::utl::OConfigurationNode aChildNode (aLegacyRootNode.openNode(rsNodeName));
541         if ( ! aChildNode.isValid())
542             continue;
543 
544         DeckDescriptor& rDeckDescriptor (maDecks[nDeckWriteIndex++]);
545         rDeckDescriptor.msTitle = ::comphelper::getString(aChildNode.getNodeValue("UIName"));
546         rDeckDescriptor.msId = rsNodeName;
547         rDeckDescriptor.msIconURL = ::comphelper::getString(aChildNode.getNodeValue("ImageURL"));
548         rDeckDescriptor.msHighContrastIconURL = rDeckDescriptor.msIconURL;
549         rDeckDescriptor.msTitleBarIconURL = OUString();
550         rDeckDescriptor.msHighContrastTitleBarIconURL = OUString();
551         rDeckDescriptor.msHelpURL = ::comphelper::getString(aChildNode.getNodeValue("HelpURL"));
552         rDeckDescriptor.msHelpText = rDeckDescriptor.msTitle;
553         rDeckDescriptor.mbIsEnabled = true;
554         rDeckDescriptor.mnOrderIndex = 100000 + nReadIndex;
555         rDeckDescriptor.maContextList.AddContextDescription(Context(sModuleName, A2S("any")), true, OUString());
556 
557         PanelDescriptor& rPanelDescriptor (maPanels[nPanelWriteIndex++]);
558         rPanelDescriptor.msTitle = ::comphelper::getString(aChildNode.getNodeValue("UIName"));
559         rPanelDescriptor.mbIsTitleBarOptional = true;
560         rPanelDescriptor.msId = rsNodeName;
561         rPanelDescriptor.msDeckId = rsNodeName;
562         rPanelDescriptor.msTitleBarIconURL = OUString();
563         rPanelDescriptor.msHighContrastTitleBarIconURL = OUString();
564         rPanelDescriptor.msHelpURL = ::comphelper::getString(aChildNode.getNodeValue("HelpURL"));
565         rPanelDescriptor.msImplementationURL = rsNodeName;
566         rPanelDescriptor.mnOrderIndex = 100000 + nReadIndex;
567         rPanelDescriptor.mbShowForReadOnlyDocuments = false;
568         rPanelDescriptor.mbWantsCanvas = false;
569         rPanelDescriptor.maContextList.AddContextDescription(Context(sModuleName, A2S("any")), true, OUString());
570     }
571 
572     // When there where invalid nodes then we have to adapt the size
573     // of the deck and panel vectors.
574     if (nDeckWriteIndex < maDecks.size())
575         maDecks.resize(nDeckWriteIndex);
576     if (nPanelWriteIndex < maPanels.size())
577         maPanels.resize(nPanelWriteIndex);
578 }
579 
580 
581 
582 
StorePanelExpansionState(const::rtl::OUString & rsPanelId,const bool bExpansionState,const Context & rContext)583 void ResourceManager::StorePanelExpansionState (
584     const ::rtl::OUString& rsPanelId,
585     const bool bExpansionState,
586     const Context& rContext)
587 {
588     for (PanelContainer::iterator
589              iPanel(maPanels.begin()),
590              iEnd(maPanels.end());
591          iPanel!=iEnd;
592          ++iPanel)
593     {
594         if (iPanel->msId.equals(rsPanelId))
595         {
596             ContextList::Entry* pEntry (
597                 iPanel->maContextList.GetMatch (rContext));
598             if (pEntry != NULL)
599                 pEntry->mbIsInitiallyVisible = bExpansionState;
600         }
601     }
602 }
603 
604 
605 
606 
GetLegacyAddonRootNode(const::rtl::OUString & rsModuleName) const607 ::utl::OConfigurationTreeRoot ResourceManager::GetLegacyAddonRootNode (
608     const ::rtl::OUString& rsModuleName) const
609 {
610     try
611     {
612         const ::comphelper::ComponentContext aContext (::comphelper::getProcessServiceFactory());
613         const Reference<container::XNameAccess> xModuleAccess (
614             aContext.createComponent("com.sun.star.frame.ModuleManager"),
615             UNO_QUERY_THROW);
616         const ::comphelper::NamedValueCollection aModuleProperties (xModuleAccess->getByName(rsModuleName));
617         const ::rtl::OUString sWindowStateRef (aModuleProperties.getOrDefault(
618                 "ooSetupFactoryWindowStateConfigRef",
619                 ::rtl::OUString()));
620 
621         ::rtl::OUStringBuffer aPathComposer;
622         aPathComposer.appendAscii("org.openoffice.Office.UI.");
623         aPathComposer.append(sWindowStateRef);
624         aPathComposer.appendAscii("/UIElements/States");
625 
626         return ::utl::OConfigurationTreeRoot(aContext, aPathComposer.makeStringAndClear(), false);
627     }
628     catch( const Exception& )
629     {
630         DBG_UNHANDLED_EXCEPTION();
631     }
632 
633     return ::utl::OConfigurationTreeRoot();
634 }
635 
636 
637 
638 
GetToolPanelNodeNames(::std::vector<OUString> & rMatchingNames,const::utl::OConfigurationTreeRoot aRoot) const639 void ResourceManager::GetToolPanelNodeNames (
640     ::std::vector<OUString>& rMatchingNames,
641     const ::utl::OConfigurationTreeRoot aRoot) const
642 {
643     Sequence<OUString> aChildNodeNames (aRoot.getNodeNames());
644     const sal_Int32 nCount (aChildNodeNames.getLength());
645     for (sal_Int32 nIndex(0); nIndex<nCount; ++nIndex)
646     {
647         if (aChildNodeNames[nIndex].matchAsciiL(
648                 RTL_CONSTASCII_STRINGPARAM( "private:resource/toolpanel/")))
649             rMatchingNames.push_back(aChildNodeNames[nIndex]);
650     }
651 }
652 
653 
654 
655 
IsDeckEnabled(const OUString & rsDeckId,const Context & rContext,const Reference<frame::XFrame> & rxFrame) const656 bool ResourceManager::IsDeckEnabled (
657     const OUString& rsDeckId,
658     const Context& rContext,
659     const Reference<frame::XFrame>& rxFrame) const
660 {
661     // Check if any panel that matches the current context can be
662     // displayed.
663     ResourceManager::PanelContextDescriptorContainer aPanelContextDescriptors;
664     ResourceManager::Instance().GetMatchingPanels(
665         aPanelContextDescriptors,
666         rContext,
667         rsDeckId,
668         rxFrame);
669 
670     for (ResourceManager::PanelContextDescriptorContainer::const_iterator
671              iPanel(aPanelContextDescriptors.begin()),
672              iEnd(aPanelContextDescriptors.end());
673          iPanel!=iEnd;
674          ++iPanel)
675     {
676         if (iPanel->mbShowForReadOnlyDocuments)
677             return true;
678     }
679 
680     return false;
681 }
682 
683 
684 } } // end of namespace sfx2::sidebar
685