1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sidebar/DeckDescriptor.hxx>
21 #include <sidebar/PanelDescriptor.hxx>
22 #include <sfx2/sidebar/ResourceManager.hxx>
23 #include <sidebar/Tools.hxx>
25 #include <officecfg/Office/Common.hxx>
26 #include <officecfg/Office/UI/Sidebar.hxx>
27 #include <unotools/confignode.hxx>
28 #include <comphelper/lok.hxx>
29 #include <comphelper/processfactory.hxx>
30 #include <comphelper/namedvaluecollection.hxx>
31 #include <comphelper/sequence.hxx>
32 #include <comphelper/types.hxx>
34 #include <tools/diagnose_ex.h>
35 #include <sal/log.hxx>
36 #include <vcl/EnumContext.hxx>
38 #include <com/sun/star/frame/ModuleManager.hpp>
39 #include <com/sun/star/ui/XSidebarPanel.hpp>
40 #include <com/sun/star/ui/XUpdateModel.hpp>
45 using namespace css::uno
;
47 namespace sfx2::sidebar
{
52 OUString
getString(utl::OConfigurationNode
const & aNode
, const char* pNodeName
)
54 return comphelper::getString(aNode
.getNodeValue(pNodeName
));
56 sal_Int32
getInt32(utl::OConfigurationNode
const & aNode
, const char* pNodeName
)
58 return comphelper::getINT32(aNode
.getNodeValue(pNodeName
));
60 bool getBool(utl::OConfigurationNode
const & aNode
, const char* pNodeName
)
62 return comphelper::getBOOL(aNode
.getNodeValue(pNodeName
));
65 css::uno::Sequence
<OUString
> BuildContextList (const ContextList
& rContextList
)
67 const ::std::vector
<ContextList::Entry
>& entries
= rContextList
.GetEntries();
69 css::uno::Sequence
<OUString
> result(entries
.size());
70 auto resultRange
= asNonConstRange(result
);
73 for (auto const& entry
: entries
)
75 OUString appName
= entry
.maContext
.msApplication
;
76 OUString contextName
= entry
.maContext
.msContext
;
77 OUString menuCommand
= entry
.msMenuCommand
;
80 if (entry
.mbIsInitiallyVisible
)
81 visibility
= "visible";
83 visibility
= "hidden";
85 OUString element
= appName
+ ", " + contextName
+", " + visibility
;
87 if (!menuCommand
.isEmpty())
88 element
+= ", "+menuCommand
;
90 resultRange
[i
] = element
;
99 } //end anonymous namespace
101 ResourceManager::ResourceManager()
108 ResourceManager::~ResourceManager()
112 void ResourceManager::InitDeckContext(const Context
& rContext
)
114 for (auto const& deck
: maDecks
)
116 const ContextList::Entry
* pMatchingEntry
= deck
->maContextList
.GetMatch(rContext
);
120 bIsEnabled
= pMatchingEntry
->mbIsInitiallyVisible
;
124 deck
->mbIsEnabled
= bIsEnabled
;
128 std::shared_ptr
<DeckDescriptor
> ResourceManager::ImplGetDeckDescriptor(std::u16string_view rsDeckId
) const
130 for (auto const& deck
: maDecks
)
132 if (deck
->mbExperimental
&& !officecfg::Office::Common::Misc::ExperimentalMode::get())
134 if (deck
->msId
== rsDeckId
)
140 std::shared_ptr
<DeckDescriptor
> ResourceManager::GetDeckDescriptor(std::u16string_view rsDeckId
) const
142 return ImplGetDeckDescriptor( rsDeckId
);
145 std::shared_ptr
<PanelDescriptor
> ResourceManager::ImplGetPanelDescriptor(std::u16string_view rsPanelId
) const
147 for (auto const& panel
: maPanels
)
149 if (panel
->msId
== rsPanelId
)
155 std::shared_ptr
<PanelDescriptor
> ResourceManager::GetPanelDescriptor(std::u16string_view rsPanelId
) const
157 return ImplGetPanelDescriptor( rsPanelId
);
160 const ResourceManager::DeckContextDescriptorContainer
& ResourceManager::GetMatchingDecks (
161 DeckContextDescriptorContainer
& rDecks
,
162 const Context
& rContext
,
163 const bool bIsDocumentReadOnly
,
164 const Reference
<frame::XController
>& rxController
)
166 ReadLegacyAddons(rxController
);
168 std::multimap
<sal_Int32
,DeckContextDescriptor
> aOrderedIds
;
169 for (auto const& deck
: maDecks
)
171 if (deck
->mbExperimental
&& !officecfg::Office::Common::Misc::ExperimentalMode::get())
174 const DeckDescriptor
& rDeckDescriptor (*deck
);
175 if (rDeckDescriptor
.maContextList
.GetMatch(rContext
) == nullptr)
178 DeckContextDescriptor aDeckContextDescriptor
;
179 aDeckContextDescriptor
.msId
= rDeckDescriptor
.msId
;
181 aDeckContextDescriptor
.mbIsEnabled
= (! bIsDocumentReadOnly
|| IsDeckEnabled(rDeckDescriptor
.msId
, rContext
, rxController
) )
182 && rDeckDescriptor
.mbIsEnabled
;
185 aOrderedIds
.emplace(rDeckDescriptor
.mnOrderIndex
, aDeckContextDescriptor
);
188 for (auto const& orderId
: aOrderedIds
)
190 rDecks
.push_back(orderId
.second
);
196 const ResourceManager::PanelContextDescriptorContainer
& ResourceManager::GetMatchingPanels (
197 PanelContextDescriptorContainer
& rPanelIds
,
198 const Context
& rContext
,
199 std::u16string_view sDeckId
,
200 const Reference
<frame::XController
>& rxController
)
202 ReadLegacyAddons(rxController
);
204 std::multimap
<sal_Int32
, PanelContextDescriptor
> aOrderedIds
;
205 for (auto const& panel
: maPanels
)
207 const PanelDescriptor
& rPanelDescriptor (*panel
);
208 if (rPanelDescriptor
.mbExperimental
&& !officecfg::Office::Common::Misc::ExperimentalMode::get())
210 if ( rPanelDescriptor
.msDeckId
!= sDeckId
)
213 const ContextList::Entry
* pEntry
= rPanelDescriptor
.maContextList
.GetMatch(rContext
);
214 if (pEntry
== nullptr)
217 PanelContextDescriptor aPanelContextDescriptor
;
218 aPanelContextDescriptor
.msId
= rPanelDescriptor
.msId
;
219 aPanelContextDescriptor
.msMenuCommand
= pEntry
->msMenuCommand
;
220 aPanelContextDescriptor
.mbIsInitiallyVisible
= pEntry
->mbIsInitiallyVisible
;
221 aPanelContextDescriptor
.mbShowForReadOnlyDocuments
= rPanelDescriptor
.mbShowForReadOnlyDocuments
;
222 aOrderedIds
.emplace(rPanelDescriptor
.mnOrderIndex
, aPanelContextDescriptor
);
225 for (auto const& orderId
: aOrderedIds
)
227 rPanelIds
.push_back(orderId
.second
);
233 const OUString
& ResourceManager::GetLastActiveDeck( const Context
& rContext
)
235 if( maLastActiveDecks
.find( rContext
.msApplication
) == maLastActiveDecks
.end())
236 return maLastActiveDecks
["any"];
238 return maLastActiveDecks
[rContext
.msApplication
];
241 void ResourceManager::SetLastActiveDeck( const Context
& rContext
, const OUString
&rsDeckId
)
243 maLastActiveDecks
[rContext
.msApplication
] = rsDeckId
;
246 void ResourceManager::ReadDeckList()
248 const utl::OConfigurationTreeRoot
aDeckRootNode(
249 comphelper::getProcessComponentContext(),
250 "org.openoffice.Office.UI.Sidebar/Content/DeckList",
252 if (!aDeckRootNode
.isValid())
255 const Sequence
<OUString
> aDeckNodeNames (aDeckRootNode
.getNodeNames());
257 for (const OUString
& aDeckName
: aDeckNodeNames
)
259 if (comphelper::LibreOfficeKit::isActive())
261 // Hide these decks in LOK as they aren't fully functional.
262 if (aDeckName
== "GalleryDeck" || aDeckName
== "NavigatorDeck"
263 || aDeckName
== "StyleListDeck")
267 const utl::OConfigurationNode
aDeckNode(aDeckRootNode
.openNode(aDeckName
));
268 if (!aDeckNode
.isValid())
271 maDecks
.push_back(std::make_shared
<DeckDescriptor
>());
272 DeckDescriptor
& rDeckDescriptor (*maDecks
.back());
274 rDeckDescriptor
.msTitle
= getString(aDeckNode
, "Title");
275 rDeckDescriptor
.msId
= getString(aDeckNode
, "Id");
276 rDeckDescriptor
.msIconURL
= getString(aDeckNode
, "IconURL");
277 rDeckDescriptor
.msHighContrastIconURL
= getString(aDeckNode
, "HighContrastIconURL");
278 rDeckDescriptor
.msTitleBarIconURL
= getString(aDeckNode
, "TitleBarIconURL");
279 rDeckDescriptor
.msHighContrastTitleBarIconURL
= getString(aDeckNode
, "HighContrastTitleBarIconURL");
280 rDeckDescriptor
.msHelpText
= rDeckDescriptor
.msTitle
;
281 rDeckDescriptor
.mnOrderIndex
= getInt32(aDeckNode
, "OrderIndex");
282 rDeckDescriptor
.mbExperimental
= getBool(aDeckNode
, "IsExperimental");
284 rDeckDescriptor
.msNodeName
= aDeckName
;
288 rDeckDescriptor
.maContextList
,
294 void ResourceManager::SaveDecksSettings(const Context
& rContext
)
296 for (auto const& deck
: maDecks
)
298 const ContextList::Entry
* pMatchingEntry
= deck
->maContextList
.GetMatch(rContext
);
301 std::shared_ptr
<DeckDescriptor
> xDeckDesc
= GetDeckDescriptor(deck
->msId
);
303 SaveDeckSettings(xDeckDesc
.get());
309 void ResourceManager::SaveDeckSettings(const DeckDescriptor
* pDeckDesc
)
311 const utl::OConfigurationTreeRoot
aDeckRootNode(
312 comphelper::getProcessComponentContext(),
313 "org.openoffice.Office.UI.Sidebar/Content/DeckList",
315 if (!aDeckRootNode
.isValid())
318 // save deck settings
320 ::uno::Sequence
< OUString
> sContextList
= BuildContextList(pDeckDesc
->maContextList
);
322 utl::OConfigurationNode
aDeckNode (aDeckRootNode
.openNode(pDeckDesc
->msNodeName
));
324 css::uno::Any
aTitle(makeAny(pDeckDesc
->msTitle
));
325 css::uno::Any
aOrder(makeAny(pDeckDesc
->mnOrderIndex
));
326 css::uno::Any
aContextList(makeAny(sContextList
));
328 bool bChanged
= false;
329 if (aTitle
!= aDeckNode
.getNodeValue("Title"))
331 aDeckNode
.setNodeValue("Title", aTitle
);
334 if (aOrder
!= aDeckNode
.getNodeValue("OrderIndex"))
336 aDeckNode
.setNodeValue("OrderIndex", aOrder
);
339 if (aContextList
!= aDeckNode
.getNodeValue("ContextList"))
341 aDeckNode
.setNodeValue("ContextList", aContextList
);
346 aDeckRootNode
.commit();
348 // save panel settings
350 const utl::OConfigurationTreeRoot
aPanelRootNode(
351 comphelper::getProcessComponentContext(),
352 "org.openoffice.Office.UI.Sidebar/Content/PanelList",
355 if (!aPanelRootNode
.isValid())
358 if (!pDeckDesc
->mpDeck
) // the deck has not been edited
361 SharedPanelContainer rPanels
= pDeckDesc
->mpDeck
->GetPanels();
364 for (auto const& panel
: rPanels
)
366 OUString panelId
= panel
->GetId();
367 std::shared_ptr
<PanelDescriptor
> xPanelDesc
= GetPanelDescriptor(panelId
);
369 ::uno::Sequence
< OUString
> sPanelContextList
= BuildContextList(xPanelDesc
->maContextList
);
371 utl::OConfigurationNode
aPanelNode (aPanelRootNode
.openNode(xPanelDesc
->msNodeName
));
373 aTitle
<<= xPanelDesc
->msTitle
;
374 aOrder
<<= xPanelDesc
->mnOrderIndex
;
375 aContextList
<<= sPanelContextList
;
377 if (aTitle
!= aPanelNode
.getNodeValue("Title"))
379 aPanelNode
.setNodeValue("Title", aTitle
);
382 if (aOrder
!= aPanelNode
.getNodeValue("OrderIndex"))
384 aPanelNode
.setNodeValue("OrderIndex", aOrder
);
387 if (aContextList
!= aPanelNode
.getNodeValue("ContextList"))
389 aPanelNode
.setNodeValue("ContextList", aContextList
);
395 aPanelRootNode
.commit();
398 void ResourceManager::SaveLastActiveDeck(const Context
& rContext
, const OUString
& rActiveDeck
)
400 maLastActiveDecks
[rContext
.msApplication
] = rActiveDeck
;
402 std::set
<OUString
> aLastActiveDecks
;
403 for ( auto const & rEntry
: maLastActiveDecks
)
404 aLastActiveDecks
.insert( rEntry
.first
+ "," + rEntry
.second
);
406 std::shared_ptr
<comphelper::ConfigurationChanges
> cfgWriter( comphelper::ConfigurationChanges::create() );
408 officecfg::Office::UI::Sidebar::Content::LastActiveDeck::set(comphelper::containerToSequence(aLastActiveDecks
), cfgWriter
);
413 void ResourceManager::ReadPanelList()
415 const utl::OConfigurationTreeRoot
aPanelRootNode(
416 comphelper::getProcessComponentContext(),
417 "org.openoffice.Office.UI.Sidebar/Content/PanelList",
419 if (!aPanelRootNode
.isValid())
422 const Sequence
<OUString
> aPanelNodeNames (aPanelRootNode
.getNodeNames());
424 for (const auto& rPanelNodeName
: aPanelNodeNames
)
426 const utl::OConfigurationNode
aPanelNode (aPanelRootNode
.openNode(rPanelNodeName
));
427 if (!aPanelNode
.isValid())
430 if (comphelper::LibreOfficeKit::isActive())
432 // Hide these panels in LOK as they aren't fully functional.
433 OUString aPanelId
= getString(aPanelNode
, "Id");
434 if (aPanelId
== "PageStylesPanel" || aPanelId
== "PageHeaderPanel"
435 || aPanelId
== "PageFooterPanel")
439 maPanels
.push_back(std::make_shared
<PanelDescriptor
>());
440 PanelDescriptor
& rPanelDescriptor(*maPanels
.back());
442 rPanelDescriptor
.msTitle
= getString(aPanelNode
, "Title");
443 rPanelDescriptor
.mbIsTitleBarOptional
= getBool(aPanelNode
, "TitleBarIsOptional");
444 rPanelDescriptor
.msId
= getString(aPanelNode
, "Id");
445 rPanelDescriptor
.msDeckId
= getString(aPanelNode
, "DeckId");
446 rPanelDescriptor
.msTitleBarIconURL
= getString(aPanelNode
, "TitleBarIconURL");
447 rPanelDescriptor
.msHighContrastTitleBarIconURL
= getString(aPanelNode
, "HighContrastTitleBarIconURL");
448 rPanelDescriptor
.msImplementationURL
= getString(aPanelNode
, "ImplementationURL");
449 rPanelDescriptor
.mnOrderIndex
= getInt32(aPanelNode
, "OrderIndex");
450 rPanelDescriptor
.mbShowForReadOnlyDocuments
= getBool(aPanelNode
, "ShowForReadOnlyDocument");
451 rPanelDescriptor
.mbWantsCanvas
= getBool(aPanelNode
, "WantsCanvas");
452 rPanelDescriptor
.mbWantsAWT
= getBool(aPanelNode
, "WantsAWT");
453 rPanelDescriptor
.mbExperimental
= getBool(aPanelNode
, "IsExperimental");
454 const OUString
sDefaultMenuCommand(getString(aPanelNode
, "DefaultMenuCommand"));
456 rPanelDescriptor
.msNodeName
= rPanelNodeName
;
458 ReadContextList(aPanelNode
, rPanelDescriptor
.maContextList
, sDefaultMenuCommand
);
462 void ResourceManager::ReadLastActive()
464 const Sequence
<OUString
> aLastActive (officecfg::Office::UI::Sidebar::Content::LastActiveDeck::get());
466 for (const auto& rDeckInfo
: aLastActive
)
468 sal_Int32 nCharIdx
= rDeckInfo
.lastIndexOf(',');
469 if ( nCharIdx
<= 0 || (nCharIdx
== rDeckInfo
.getLength() - 1) )
471 SAL_WARN("sfx.sidebar", "Expecting 2 values separated by comma");
475 const OUString sApplicationName
= rDeckInfo
.copy( 0, nCharIdx
);
476 vcl::EnumContext::Application
eApplication (vcl::EnumContext::GetApplicationEnum(sApplicationName
));
477 const OUString sLastUsed
= rDeckInfo
.copy( nCharIdx
+ 1 );
479 // guard against garbage in place of application
480 if (eApplication
!= vcl::EnumContext::Application::NONE
)
481 maLastActiveDecks
.insert( std::make_pair(sApplicationName
, sLastUsed
) );
484 // Set up a default for Math - will do nothing if already set
485 maLastActiveDecks
.emplace(
486 vcl::EnumContext::GetApplicationName(vcl::EnumContext::Application::Formula
),
490 void ResourceManager::ReadContextList (
491 const utl::OConfigurationNode
& rParentNode
,
492 ContextList
& rContextList
,
493 const OUString
& rsDefaultMenuCommand
)
495 const Any aValue
= rParentNode
.getNodeValue("ContextList");
496 Sequence
<OUString
> aValues
;
497 if (!(aValue
>>= aValues
))
500 for (const OUString
& sValue
: std::as_const(aValues
))
502 sal_Int32
nCharacterIndex (0);
503 const OUString
sApplicationName (sValue
.getToken(0, ',', nCharacterIndex
).trim());
504 if (nCharacterIndex
< 0)
506 if (sApplicationName
.getLength() == 0)
508 // This is a valid case: in the XML file the separator
509 // was used as terminator. Using it in the last line
510 // creates an additional but empty entry.
515 OSL_FAIL("expecting three or four values per ContextList entry, separated by comma");
520 const OUString
sContextName(sValue
.getToken(0, ',', nCharacterIndex
).trim());
521 if (nCharacterIndex
< 0)
523 OSL_FAIL("expecting three or four values per ContextList entry, separated by comma");
527 const OUString
sInitialState(sValue
.getToken(0, ',', nCharacterIndex
).trim());
529 // The fourth argument is optional.
530 const OUString
sMenuCommandOverride(
533 : sValue
.getToken(0, ',', nCharacterIndex
).trim());
535 const OUString
sMenuCommand(
536 sMenuCommandOverride
.getLength() > 0
537 ? (sMenuCommandOverride
== "none"
539 : sMenuCommandOverride
)
540 : rsDefaultMenuCommand
);
542 // Setup a list of application enums. Note that the
543 // application name may result in more than one value (eg
544 // DrawImpress will result in two enums, one for Draw and one
546 std::vector
<vcl::EnumContext::Application
> aApplications
;
547 vcl::EnumContext::Application
eApplication (vcl::EnumContext::GetApplicationEnum(sApplicationName
));
549 if (eApplication
== vcl::EnumContext::Application::NONE
550 && sApplicationName
!= vcl::EnumContext::GetApplicationName(vcl::EnumContext::Application::NONE
))
552 // Handle some special names: abbreviations that make
553 // context descriptions more readable.
554 if (sApplicationName
== "Writer")
555 aApplications
.push_back(vcl::EnumContext::Application::Writer
);
556 else if (sApplicationName
== "Calc")
557 aApplications
.push_back(vcl::EnumContext::Application::Calc
);
558 else if (sApplicationName
== "Draw")
559 aApplications
.push_back(vcl::EnumContext::Application::Draw
);
560 else if (sApplicationName
== "Impress")
561 aApplications
.push_back(vcl::EnumContext::Application::Impress
);
562 else if (sApplicationName
== "Chart")
563 aApplications
.push_back(vcl::EnumContext::Application::Chart
);
564 else if (sApplicationName
== "Math")
565 aApplications
.push_back(vcl::EnumContext::Application::Formula
);
566 else if (sApplicationName
== "DrawImpress")
568 // A special case among the special names: it is
569 // common to use the same context descriptions for
570 // both Draw and Impress. This special case helps to
571 // avoid duplication in the .xcu file.
572 aApplications
.push_back(vcl::EnumContext::Application::Draw
);
573 aApplications
.push_back(vcl::EnumContext::Application::Impress
);
575 else if (sApplicationName
== "WriterVariants")
577 // Another special case for all Writer variants.
578 aApplications
.push_back(vcl::EnumContext::Application::Writer
);
579 aApplications
.push_back(vcl::EnumContext::Application::WriterGlobal
);
580 aApplications
.push_back(vcl::EnumContext::Application::WriterWeb
);
581 aApplications
.push_back(vcl::EnumContext::Application::WriterXML
);
582 aApplications
.push_back(vcl::EnumContext::Application::WriterForm
);
583 aApplications
.push_back(vcl::EnumContext::Application::WriterReport
);
587 SAL_WARN("sfx.sidebar", "application name " << sApplicationName
<< " not recognized");
593 // No conversion of the application name necessary.
594 aApplications
.push_back(eApplication
);
597 // Setup the actual context enum.
598 const vcl::EnumContext::Context
eContext (vcl::EnumContext::GetContextEnum(sContextName
));
599 if (eContext
== vcl::EnumContext::Context::Unknown
)
601 SAL_WARN("sfx.sidebar", "context name " << sContextName
<< " not recognized");
605 // Setup the flag that controls whether a deck/pane is
606 // initially visible/expanded.
607 bool bIsInitiallyVisible
;
608 if (sInitialState
== "visible")
609 bIsInitiallyVisible
= true;
610 else if (sInitialState
== "hidden")
611 bIsInitiallyVisible
= false;
614 OSL_FAIL("unrecognized state");
619 // Add context descriptors.
620 for (auto const& application
: aApplications
)
622 if (application
!= vcl::EnumContext::Application::NONE
)
624 rContextList
.AddContextDescription(
626 vcl::EnumContext::GetApplicationName(application
),
627 vcl::EnumContext::GetContextName(eContext
)),
635 void ResourceManager::ReadLegacyAddons (const Reference
<frame::XController
>& rxController
)
637 // Get module name for given frame.
638 OUString
sModuleName (Tools::GetModuleName(rxController
));
639 if (sModuleName
.getLength() == 0)
641 if (maProcessedApplications
.find(sModuleName
) != maProcessedApplications
.end())
643 // Addons for this application have already been read.
644 // There is nothing more to do.
648 // Mark module as processed. Even when there is an error that
649 // prevents the configuration data from being read, this error
650 // will not be triggered a second time.
651 maProcessedApplications
.insert(sModuleName
);
653 // Get access to the configuration root node for the application.
654 utl::OConfigurationTreeRoot
aLegacyRootNode (GetLegacyAddonRootNode(sModuleName
));
655 if (!aLegacyRootNode
.isValid())
658 // Process child nodes.
659 std::vector
<OUString
> aMatchingNodeNames
;
660 GetToolPanelNodeNames(aMatchingNodeNames
, aLegacyRootNode
);
661 const sal_Int32
nCount (aMatchingNodeNames
.size());
662 for (sal_Int32
nReadIndex(0); nReadIndex
<nCount
; ++nReadIndex
)
664 const OUString
& rsNodeName (aMatchingNodeNames
[nReadIndex
]);
665 const utl::OConfigurationNode
aChildNode (aLegacyRootNode
.openNode(rsNodeName
));
666 if (!aChildNode
.isValid())
669 if ( rsNodeName
== "private:resource/toolpanel/DrawingFramework/CustomAnimations" ||
670 rsNodeName
== "private:resource/toolpanel/DrawingFramework/Layouts" ||
671 rsNodeName
== "private:resource/toolpanel/DrawingFramework/MasterPages" ||
672 rsNodeName
== "private:resource/toolpanel/DrawingFramework/SlideTransitions" ||
673 rsNodeName
== "private:resource/toolpanel/DrawingFramework/TableDesign" )
676 maDecks
.push_back(std::make_shared
<DeckDescriptor
>());
677 DeckDescriptor
& rDeckDescriptor(*maDecks
.back());
678 rDeckDescriptor
.msTitle
= getString(aChildNode
, "UIName");
679 rDeckDescriptor
.msId
= rsNodeName
;
680 rDeckDescriptor
.msIconURL
= getString(aChildNode
, "ImageURL");
681 rDeckDescriptor
.msHighContrastIconURL
= rDeckDescriptor
.msIconURL
;
682 rDeckDescriptor
.msTitleBarIconURL
.clear();
683 rDeckDescriptor
.msHighContrastTitleBarIconURL
.clear();
684 rDeckDescriptor
.msHelpText
= rDeckDescriptor
.msTitle
;
685 rDeckDescriptor
.mbIsEnabled
= true;
686 rDeckDescriptor
.mnOrderIndex
= 100000 + nReadIndex
;
687 rDeckDescriptor
.maContextList
.AddContextDescription(Context(sModuleName
, "any"), true, OUString());
689 maPanels
.push_back(std::make_shared
<PanelDescriptor
>());
690 PanelDescriptor
& rPanelDescriptor(*maPanels
.back());
691 rPanelDescriptor
.msTitle
= getString(aChildNode
, "UIName");
692 rPanelDescriptor
.mbIsTitleBarOptional
= true;
693 rPanelDescriptor
.msId
= rsNodeName
;
694 rPanelDescriptor
.msDeckId
= rsNodeName
;
695 rPanelDescriptor
.msTitleBarIconURL
.clear();
696 rPanelDescriptor
.msHighContrastTitleBarIconURL
.clear();
697 rPanelDescriptor
.msImplementationURL
= rsNodeName
;
698 rPanelDescriptor
.mnOrderIndex
= 100000 + nReadIndex
;
699 rPanelDescriptor
.mbShowForReadOnlyDocuments
= false;
700 rPanelDescriptor
.mbWantsCanvas
= false;
701 rPanelDescriptor
.mbWantsAWT
= true;
702 fprintf(stderr
, "THIS PLACE\n");
703 rPanelDescriptor
.maContextList
.AddContextDescription(Context(sModuleName
, "any"), true, OUString());
707 void ResourceManager::StorePanelExpansionState (
708 std::u16string_view rsPanelId
,
709 const bool bExpansionState
,
710 const Context
& rContext
)
712 for (auto const& panel
: maPanels
)
714 if (panel
->msId
== rsPanelId
)
716 ContextList::Entry
* pEntry(panel
->maContextList
.GetMatch(rContext
));
717 if (pEntry
!= nullptr)
718 pEntry
->mbIsInitiallyVisible
= bExpansionState
;
723 utl::OConfigurationTreeRoot
ResourceManager::GetLegacyAddonRootNode (const OUString
& rsModuleName
)
727 const Reference
<XComponentContext
> xContext(comphelper::getProcessComponentContext());
728 const Reference
<frame::XModuleManager2
> xModuleAccess
= frame::ModuleManager::create(xContext
);
729 const comphelper::NamedValueCollection
aModuleProperties(xModuleAccess
->getByName(rsModuleName
));
730 const OUString
sWindowStateRef(aModuleProperties
.getOrDefault(
731 "ooSetupFactoryWindowStateConfigRef",
734 OUString aPathComposer
= "org.openoffice.Office.UI." + sWindowStateRef
+
735 "/UIElements/States";
737 return utl::OConfigurationTreeRoot(xContext
, aPathComposer
, false);
739 catch (const Exception
&)
741 DBG_UNHANDLED_EXCEPTION("sfx.sidebar");
744 return utl::OConfigurationTreeRoot();
747 void ResourceManager::GetToolPanelNodeNames (
748 std::vector
<OUString
>& rMatchingNames
,
749 const utl::OConfigurationTreeRoot
& aRoot
)
751 const Sequence
<OUString
> aChildNodeNames (aRoot
.getNodeNames());
752 std::copy_if(aChildNodeNames
.begin(), aChildNodeNames
.end(), std::back_inserter(rMatchingNames
),
753 [](const OUString
& rChildNodeName
) { return rChildNodeName
.startsWith( "private:resource/toolpanel/" ); });
756 bool ResourceManager::IsDeckEnabled (
757 std::u16string_view rsDeckId
,
758 const Context
& rContext
,
759 const Reference
<frame::XController
>& rxController
)
762 // Check if any panel that matches the current context can be
764 PanelContextDescriptorContainer aPanelContextDescriptors
;
766 GetMatchingPanels(aPanelContextDescriptors
, rContext
, rsDeckId
, rxController
);
768 for (auto const& panelContextDescriptor
: aPanelContextDescriptors
)
770 if (panelContextDescriptor
.mbShowForReadOnlyDocuments
)
776 void ResourceManager::UpdateModel(const css::uno::Reference
<css::frame::XModel
>& xModel
)
778 for (auto const& deck
: maDecks
)
783 const SharedPanelContainer
& rContainer
= deck
->mpDeck
->GetPanels();
785 for (auto const& elem
: rContainer
)
787 css::uno::Reference
<css::ui::XUpdateModel
> xPanel(elem
->GetPanelComponent(), css::uno::UNO_QUERY
);
788 if (xPanel
.is()) // tdf#108814 interface is optional
790 xPanel
->updateModel(xModel
);
796 void ResourceManager::disposeDecks()
798 for (auto const& deck
: maDecks
)
800 deck
->mpDeck
.disposeAndClear();
804 } // end of namespace sfx2::sidebar
806 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */