update credits
[LibreOffice.git] / sdext / source / presenter / PresenterTheme.cxx
blobbf911dd970c42ccd5268c604a638543a6fa5dac6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 "PresenterTheme.hxx"
21 #include "PresenterBitmapContainer.hxx"
22 #include "PresenterCanvasHelper.hxx"
23 #include "PresenterConfigurationAccess.hxx"
24 #include <com/sun/star/drawing/XPresenterHelper.hpp>
25 #include <com/sun/star/rendering/PanoseWeight.hpp>
26 #include <osl/diagnose.h>
27 #include <map>
28 #include <numeric>
30 using namespace ::com::sun::star;
31 using namespace ::com::sun::star::uno;
32 using namespace ::std;
34 namespace sdext::presenter {
36 namespace {
38 class BorderSize
40 public:
41 const static sal_Int32 mnInvalidValue = -10000;
43 BorderSize() : mnLeft(mnInvalidValue),
44 mnTop(mnInvalidValue),
45 mnRight(mnInvalidValue),
46 mnBottom(mnInvalidValue) {}
48 sal_Int32 mnLeft;
49 sal_Int32 mnTop;
50 sal_Int32 mnRight;
51 sal_Int32 mnBottom;
53 vector<sal_Int32> ToVector()
55 return
57 mnLeft == mnInvalidValue ? 0 : mnLeft,
58 mnTop == mnInvalidValue ? 0 : mnTop,
59 mnRight == mnInvalidValue ? 0 : mnRight,
60 mnBottom == mnInvalidValue ? 0 : mnBottom
64 void Merge (const BorderSize& rBorderSize)
66 if (mnLeft == mnInvalidValue)
67 mnLeft = rBorderSize.mnLeft;
68 if (mnTop == mnInvalidValue)
69 mnTop = rBorderSize.mnTop;
70 if (mnRight == mnInvalidValue)
71 mnRight = rBorderSize.mnRight;
72 if (mnBottom == mnInvalidValue)
73 mnBottom = rBorderSize.mnBottom;
77 /** Reading a theme from the configurations is done in various classes. The
78 ReadContext gives access to frequently used objects and functions to make
79 the configuration handling easier.
81 class ReadContext
83 public:
84 Reference<XComponentContext> mxComponentContext;
85 Reference<rendering::XCanvas> mxCanvas;
86 Reference<drawing::XPresenterHelper> mxPresenterHelper;
88 ReadContext (
89 const Reference<XComponentContext>& rxContext,
90 const Reference<rendering::XCanvas>& rxCanvas);
92 /** Read data describing a font from the node that can be reached from
93 the given root via the given path.
94 @param rsFontPath
95 May be empty.
97 static PresenterTheme::SharedFontDescriptor ReadFont (
98 const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxTheme,
99 const PresenterTheme::SharedFontDescriptor& rpDefault);
100 static PresenterTheme::SharedFontDescriptor ReadFont (
101 const Reference<beans::XPropertySet>& rxFontProperties,
102 const PresenterTheme::SharedFontDescriptor& rpDefault);
104 std::shared_ptr<PresenterTheme::Theme> ReadTheme (
105 PresenterConfigurationAccess& rConfiguration,
106 const OUString& rsThemeName);
108 static BorderSize ReadBorderSize (const Reference<container::XNameAccess>& rxNode);
110 private:
111 static Any GetByName (
112 const Reference<container::XNameAccess>& rxNode,
113 const OUString& rsName);
116 /** A PaneStyle describes how a pane is rendered.
118 class PaneStyle
120 public:
121 PaneStyle();
123 SharedBitmapDescriptor GetBitmap (const OUString& sBitmapName) const;
125 OUString msStyleName;
126 std::shared_ptr<PaneStyle> mpParentStyle;
127 PresenterTheme::SharedFontDescriptor mpFont;
128 BorderSize maInnerBorderSize;
129 BorderSize maOuterBorderSize;
130 std::shared_ptr<PresenterBitmapContainer> mpBitmaps;
132 PresenterTheme::SharedFontDescriptor GetFont() const;
135 typedef std::shared_ptr<PaneStyle> SharedPaneStyle;
137 class PaneStyleContainer
139 private:
140 ::std::vector<SharedPaneStyle> mStyles;
142 public:
143 void Read (
144 const ReadContext& rReadContext,
145 const Reference<container::XHierarchicalNameAccess>& rThemeRoot);
147 SharedPaneStyle GetPaneStyle (const OUString& rsStyleName) const;
149 private:
150 void ProcessPaneStyle (
151 ReadContext const & rReadContext,
152 const ::std::vector<css::uno::Any>& rValues);
155 /** A ViewStyle describes how a view is displayed.
157 class ViewStyle
159 public:
160 ViewStyle();
162 SharedBitmapDescriptor GetBitmap (std::u16string_view sBitmapName) const;
164 PresenterTheme::SharedFontDescriptor GetFont() const;
166 OUString msStyleName;
167 std::shared_ptr<ViewStyle> mpParentStyle;
168 PresenterTheme::SharedFontDescriptor mpFont;
169 SharedBitmapDescriptor mpBackground;
172 typedef std::shared_ptr<ViewStyle> SharedViewStyle;
174 class ViewStyleContainer
176 private:
177 ::std::vector<SharedViewStyle> mStyles;
179 public:
180 void Read (
181 const ReadContext& rReadContext,
182 const Reference<container::XHierarchicalNameAccess>& rThemeRoot);
184 SharedViewStyle GetViewStyle (const OUString& rsStyleName) const;
186 private:
187 void ProcessViewStyle(
188 ReadContext const & rReadContext,
189 const Reference<beans::XPropertySet>& rxProperties);
192 class StyleAssociationContainer
194 public:
195 void Read (
196 const Reference<container::XHierarchicalNameAccess>& rThemeRoot);
198 OUString GetStyleName (const OUString& rsResourceName) const;
200 private:
201 typedef map<OUString, OUString> StyleAssociations;
202 StyleAssociations maStyleAssociations;
204 void ProcessStyleAssociation(
205 const ::std::vector<css::uno::Any>& rValues);
208 } // end of anonymous namespace
210 class PresenterTheme::Theme
212 public:
213 Theme (
214 const Reference<container::XHierarchicalNameAccess>& rThemeRoot,
215 const OUString& rsNodeName);
217 void Read (
218 PresenterConfigurationAccess& rConfiguration,
219 ReadContext& rReadContext);
221 OUString msConfigurationNodeName;
222 std::shared_ptr<Theme> mpParentTheme;
223 SharedBitmapDescriptor mpBackground;
224 PaneStyleContainer maPaneStyles;
225 ViewStyleContainer maViewStyles;
226 StyleAssociationContainer maStyleAssociations;
227 Reference<container::XHierarchicalNameAccess> mxThemeRoot;
228 std::shared_ptr<PresenterBitmapContainer> mpIconContainer;
229 typedef map<OUString,SharedFontDescriptor> FontContainer;
230 FontContainer maFontContainer;
232 SharedPaneStyle GetPaneStyle (const OUString& rsStyleName) const;
233 SharedViewStyle GetViewStyle (const OUString& rsStyleName) const;
235 private:
236 void ProcessFont(
237 const OUString& rsKey,
238 const Reference<beans::XPropertySet>& rxProperties);
241 //===== PresenterTheme ========================================================
243 PresenterTheme::PresenterTheme (
244 const css::uno::Reference<css::uno::XComponentContext>& rxContext,
245 const css::uno::Reference<css::rendering::XCanvas>& rxCanvas)
246 : mxContext(rxContext),
247 mpTheme(),
248 mxCanvas(rxCanvas)
250 mpTheme = ReadTheme();
253 PresenterTheme::~PresenterTheme()
257 std::shared_ptr<PresenterTheme::Theme> PresenterTheme::ReadTheme()
259 ReadContext aReadContext(mxContext, mxCanvas);
261 PresenterConfigurationAccess aConfiguration (
262 mxContext,
263 "/org.openoffice.Office.PresenterScreen/",
264 PresenterConfigurationAccess::READ_ONLY);
266 return aReadContext.ReadTheme(aConfiguration, OUString());
269 bool PresenterTheme::HasCanvas() const
271 return mxCanvas.is();
274 void PresenterTheme::ProvideCanvas (const Reference<rendering::XCanvas>& rxCanvas)
276 if ( ! mxCanvas.is() && rxCanvas.is())
278 mxCanvas = rxCanvas;
279 ReadTheme();
283 OUString PresenterTheme::GetStyleName (const OUString& rsResourceURL) const
285 OUString sStyleName;
286 std::shared_ptr<Theme> pTheme (mpTheme);
287 while (sStyleName.isEmpty() && pTheme != nullptr)
289 sStyleName = pTheme->maStyleAssociations.GetStyleName(rsResourceURL);
290 pTheme = pTheme->mpParentTheme;
292 return sStyleName;
295 ::std::vector<sal_Int32> PresenterTheme::GetBorderSize (
296 const OUString& rsStyleName,
297 const bool bOuter) const
299 OSL_ASSERT(mpTheme != nullptr);
301 SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName));
302 if (pPaneStyle)
303 if (bOuter)
304 return pPaneStyle->maOuterBorderSize.ToVector();
305 else
306 return pPaneStyle->maInnerBorderSize.ToVector();
307 else
309 return ::std::vector<sal_Int32>(4,0);
313 PresenterTheme::SharedFontDescriptor PresenterTheme::ReadFont (
314 const Reference<container::XHierarchicalNameAccess>& rxNode,
315 const PresenterTheme::SharedFontDescriptor& rpDefault)
317 return ReadContext::ReadFont(rxNode, rpDefault);
320 bool PresenterTheme::ConvertToColor (
321 const Any& rColorSequence,
322 sal_uInt32& rColor)
324 Sequence<sal_Int8> aByteSequence;
325 if (rColorSequence >>= aByteSequence)
327 rColor = std::accumulate(aByteSequence.begin(), aByteSequence.end(), sal_uInt32(0),
328 [](const sal_uInt32 nRes, const sal_uInt8 nByte) { return (nRes << 8) | nByte; });
329 return true;
331 else
332 return false;
335 std::shared_ptr<PresenterConfigurationAccess> PresenterTheme::GetNodeForViewStyle (
336 const OUString& rsStyleName) const
338 if (mpTheme == nullptr)
339 return std::shared_ptr<PresenterConfigurationAccess>();
341 // Open configuration for writing.
342 auto pConfiguration = std::make_shared<PresenterConfigurationAccess>(
343 mxContext,
344 "/org.openoffice.Office.PresenterScreen/",
345 PresenterConfigurationAccess::READ_WRITE);
347 // Get configuration node for the view style container of the current
348 // theme.
349 if (pConfiguration->GoToChild( OUString(
350 "Presenter/Themes/" + mpTheme->msConfigurationNodeName + "/ViewStyles")))
352 pConfiguration->GoToChild(
353 [&rsStyleName] (OUString const&, uno::Reference<beans::XPropertySet> const& xProps)
355 return PresenterConfigurationAccess::IsStringPropertyEqual(
356 rsStyleName, "StyleName", xProps);
359 return pConfiguration;
362 SharedBitmapDescriptor PresenterTheme::GetBitmap (
363 const OUString& rsStyleName,
364 const OUString& rsBitmapName) const
366 if (mpTheme != nullptr)
368 if (rsStyleName.isEmpty())
370 if (rsBitmapName == "Background")
372 std::shared_ptr<Theme> pTheme (mpTheme);
373 while (pTheme != nullptr && !pTheme->mpBackground)
374 pTheme = pTheme->mpParentTheme;
375 if (pTheme != nullptr)
376 return pTheme->mpBackground;
377 else
378 return SharedBitmapDescriptor();
381 else
383 SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName));
384 if (pPaneStyle)
386 SharedBitmapDescriptor pBitmap (pPaneStyle->GetBitmap(rsBitmapName));
387 if (pBitmap)
388 return pBitmap;
391 SharedViewStyle pViewStyle (mpTheme->GetViewStyle(rsStyleName));
392 if (pViewStyle)
394 SharedBitmapDescriptor pBitmap (pViewStyle->GetBitmap(rsBitmapName));
395 if (pBitmap)
396 return pBitmap;
401 return SharedBitmapDescriptor();
404 SharedBitmapDescriptor PresenterTheme::GetBitmap (
405 const OUString& rsBitmapName) const
407 if (mpTheme != nullptr)
409 if (rsBitmapName == "Background")
411 std::shared_ptr<Theme> pTheme (mpTheme);
412 while (pTheme != nullptr && !pTheme->mpBackground)
413 pTheme = pTheme->mpParentTheme;
414 if (pTheme != nullptr)
415 return pTheme->mpBackground;
416 else
417 return SharedBitmapDescriptor();
419 else
421 if (mpTheme->mpIconContainer != nullptr)
422 return mpTheme->mpIconContainer->GetBitmap(rsBitmapName);
426 return SharedBitmapDescriptor();
429 std::shared_ptr<PresenterBitmapContainer> PresenterTheme::GetBitmapContainer() const
431 if (mpTheme != nullptr)
432 return mpTheme->mpIconContainer;
433 else
434 return std::shared_ptr<PresenterBitmapContainer>();
437 PresenterTheme::SharedFontDescriptor PresenterTheme::GetFont (
438 const OUString& rsStyleName) const
440 if (mpTheme != nullptr)
442 SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName));
443 if (pPaneStyle)
444 return pPaneStyle->GetFont();
446 SharedViewStyle pViewStyle (mpTheme->GetViewStyle(rsStyleName));
447 if (pViewStyle)
448 return pViewStyle->GetFont();
450 std::shared_ptr<Theme> pTheme (mpTheme);
451 while (pTheme != nullptr)
453 Theme::FontContainer::const_iterator iFont (pTheme->maFontContainer.find(rsStyleName));
454 if (iFont != pTheme->maFontContainer.end())
455 return iFont->second;
457 pTheme = pTheme->mpParentTheme;
461 return SharedFontDescriptor();
464 //===== FontDescriptor ========================================================
466 PresenterTheme::FontDescriptor::FontDescriptor (
467 const std::shared_ptr<FontDescriptor>& rpDescriptor)
468 : msFamilyName(),
469 msStyleName(),
470 mnSize(12),
471 mnColor(0x00000000),
472 msAnchor(OUString("Left")),
473 mnXOffset(0),
474 mnYOffset(0)
476 if (rpDescriptor != nullptr)
478 msFamilyName = rpDescriptor->msFamilyName;
479 msStyleName = rpDescriptor->msStyleName;
480 mnSize = rpDescriptor->mnSize;
481 mnColor = rpDescriptor->mnColor;
482 msAnchor = rpDescriptor->msAnchor;
483 mnXOffset = rpDescriptor->mnXOffset;
484 mnYOffset = rpDescriptor->mnYOffset;
488 bool PresenterTheme::FontDescriptor::PrepareFont (
489 const Reference<rendering::XCanvas>& rxCanvas)
491 if (mxFont.is())
492 return true;
494 if ( ! rxCanvas.is())
495 return false;
497 const double nCellSize (GetCellSizeForDesignSize(rxCanvas, mnSize));
498 mxFont = CreateFont(rxCanvas, nCellSize);
500 return mxFont.is();
503 Reference<rendering::XCanvasFont> PresenterTheme::FontDescriptor::CreateFont (
504 const Reference<rendering::XCanvas>& rxCanvas,
505 const double nCellSize) const
507 rendering::FontRequest aFontRequest;
508 aFontRequest.FontDescription.FamilyName = msFamilyName;
509 if (msFamilyName.isEmpty())
510 aFontRequest.FontDescription.FamilyName = "Tahoma";
511 aFontRequest.FontDescription.StyleName = msStyleName;
512 aFontRequest.CellSize = nCellSize;
514 // Make an attempt at translating the style name(s)into a corresponding
515 // font description.
516 if (msStyleName == "Bold")
517 aFontRequest.FontDescription.FontDescription.Weight = rendering::PanoseWeight::HEAVY;
519 return rxCanvas->createFont(
520 aFontRequest,
521 Sequence<beans::PropertyValue>(),
522 geometry::Matrix2D(1,0,0,1));
525 double PresenterTheme::FontDescriptor::GetCellSizeForDesignSize (
526 const Reference<rendering::XCanvas>& rxCanvas,
527 const double nDesignSize) const
529 // Use the given design size as initial value in calculating the cell
530 // size.
531 double nCellSize (nDesignSize);
533 if ( ! rxCanvas.is())
535 // We need the canvas to do the conversion. Return the design size,
536 // it is the our best guess in this circumstance.
537 return nDesignSize;
540 Reference<rendering::XCanvasFont> xFont (CreateFont(rxCanvas, nCellSize));
541 if ( ! xFont.is())
542 return nDesignSize;
544 geometry::RealRectangle2D aBox (PresenterCanvasHelper::GetTextBoundingBox (xFont, "X"));
546 const double nAscent (-aBox.Y1);
547 //tdf#112408
548 if (nAscent == 0)
549 return nDesignSize;
550 const double nDescent (aBox.Y2);
551 const double nScale = (nAscent+nDescent) / nAscent;
552 return nDesignSize * nScale;
555 //===== Theme =================================================================
557 PresenterTheme::Theme::Theme (
558 const Reference<container::XHierarchicalNameAccess>& rxThemeRoot,
559 const OUString& rsNodeName)
560 : msConfigurationNodeName(rsNodeName),
561 mpParentTheme(),
562 maPaneStyles(),
563 maViewStyles(),
564 maStyleAssociations(),
565 mxThemeRoot(rxThemeRoot),
566 mpIconContainer()
570 void PresenterTheme::Theme::Read (
571 PresenterConfigurationAccess& rConfiguration,
572 ReadContext& rReadContext)
574 // Parent theme name.
575 OUString sParentThemeName;
576 if ((PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, "ParentTheme")
577 >>= sParentThemeName)
578 && !sParentThemeName.isEmpty())
580 mpParentTheme = rReadContext.ReadTheme(rConfiguration, sParentThemeName);
583 // Background.
584 mpBackground = PresenterBitmapContainer::LoadBitmap(
585 mxThemeRoot,
586 "Background",
587 rReadContext.mxPresenterHelper,
588 rReadContext.mxCanvas,
589 SharedBitmapDescriptor());
591 // Style associations.
592 maStyleAssociations.Read(mxThemeRoot);
594 // Pane styles.
595 maPaneStyles.Read(rReadContext, mxThemeRoot);
597 // View styles.
598 maViewStyles.Read(rReadContext, mxThemeRoot);
600 // Read bitmaps.
601 mpIconContainer = std::make_shared<PresenterBitmapContainer>(
602 Reference<container::XNameAccess>(
603 PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, "Bitmaps"), UNO_QUERY),
604 mpParentTheme != nullptr ? mpParentTheme->mpIconContainer
605 : std::shared_ptr<PresenterBitmapContainer>(),
606 rReadContext.mxComponentContext, rReadContext.mxCanvas);
608 // Read fonts.
609 Reference<container::XNameAccess> xFontNode(
610 PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, "Fonts"),
611 UNO_QUERY);
612 PresenterConfigurationAccess::ForAll(
613 xFontNode,
614 [this] (OUString const& rKey, uno::Reference<beans::XPropertySet> const& xProps)
616 return this->ProcessFont(rKey, xProps);
620 SharedPaneStyle PresenterTheme::Theme::GetPaneStyle (const OUString& rsStyleName) const
622 SharedPaneStyle pPaneStyle (maPaneStyles.GetPaneStyle(rsStyleName));
623 if (pPaneStyle)
624 return pPaneStyle;
625 else if (mpParentTheme != nullptr)
626 return mpParentTheme->GetPaneStyle(rsStyleName);
627 else
628 return SharedPaneStyle();
631 SharedViewStyle PresenterTheme::Theme::GetViewStyle (const OUString& rsStyleName) const
633 SharedViewStyle pViewStyle (maViewStyles.GetViewStyle(rsStyleName));
634 if (pViewStyle)
635 return pViewStyle;
636 else if (mpParentTheme != nullptr)
637 return mpParentTheme->GetViewStyle(rsStyleName);
638 else
639 return SharedViewStyle();
642 void PresenterTheme::Theme::ProcessFont(
643 const OUString& rsKey,
644 const Reference<beans::XPropertySet>& rxProperties)
646 maFontContainer[rsKey] = ReadContext::ReadFont(rxProperties, SharedFontDescriptor());
649 namespace {
651 //===== ReadContext ===========================================================
653 ReadContext::ReadContext (
654 const css::uno::Reference<css::uno::XComponentContext>& rxContext,
655 const Reference<rendering::XCanvas>& rxCanvas)
656 : mxComponentContext(rxContext),
657 mxCanvas(rxCanvas),
658 mxPresenterHelper()
660 Reference<lang::XMultiComponentFactory> xFactory (rxContext->getServiceManager());
661 if (xFactory.is())
663 mxPresenterHelper.set(
664 xFactory->createInstanceWithContext(
665 "com.sun.star.comp.Draw.PresenterHelper",
666 rxContext),
667 UNO_QUERY_THROW);
671 PresenterTheme::SharedFontDescriptor ReadContext::ReadFont (
672 const Reference<container::XHierarchicalNameAccess>& rxNode,
673 const PresenterTheme::SharedFontDescriptor& rpDefault)
675 if ( ! rxNode.is())
676 return PresenterTheme::SharedFontDescriptor();
680 Reference<container::XHierarchicalNameAccess> xFont (
681 PresenterConfigurationAccess::GetConfigurationNode(
682 rxNode,
683 /*rsFontPath*/""),
684 UNO_QUERY_THROW);
686 Reference<beans::XPropertySet> xProperties (xFont, UNO_QUERY_THROW);
687 return ReadFont(xProperties, rpDefault);
689 catch (Exception&)
691 OSL_ASSERT(false);
694 return PresenterTheme::SharedFontDescriptor();
697 PresenterTheme::SharedFontDescriptor ReadContext::ReadFont (
698 const Reference<beans::XPropertySet>& rxProperties,
699 const PresenterTheme::SharedFontDescriptor& rpDefault)
701 auto pDescriptor = std::make_shared<PresenterTheme::FontDescriptor>(rpDefault);
703 PresenterConfigurationAccess::GetProperty(rxProperties, "FamilyName") >>= pDescriptor->msFamilyName;
704 PresenterConfigurationAccess::GetProperty(rxProperties, "Style") >>= pDescriptor->msStyleName;
705 PresenterConfigurationAccess::GetProperty(rxProperties, "Size") >>= pDescriptor->mnSize;
706 PresenterTheme::ConvertToColor(
707 PresenterConfigurationAccess::GetProperty(rxProperties, "Color"),
708 pDescriptor->mnColor);
709 PresenterConfigurationAccess::GetProperty(rxProperties, "Anchor") >>= pDescriptor->msAnchor;
710 PresenterConfigurationAccess::GetProperty(rxProperties, "XOffset") >>= pDescriptor->mnXOffset;
711 PresenterConfigurationAccess::GetProperty(rxProperties, "YOffset") >>= pDescriptor->mnYOffset;
713 return pDescriptor;
716 Any ReadContext::GetByName (
717 const Reference<container::XNameAccess>& rxNode,
718 const OUString& rsName)
720 OSL_ASSERT(rxNode.is());
721 if (rxNode->hasByName(rsName))
722 return rxNode->getByName(rsName);
723 else
724 return Any();
727 std::shared_ptr<PresenterTheme::Theme> ReadContext::ReadTheme (
728 PresenterConfigurationAccess& rConfiguration,
729 const OUString& rsThemeName)
731 std::shared_ptr<PresenterTheme::Theme> pTheme;
733 OUString sCurrentThemeName (rsThemeName);
734 if (sCurrentThemeName.isEmpty())
736 // No theme name given. Look up the CurrentTheme property.
737 rConfiguration.GetConfigurationNode("Presenter/CurrentTheme") >>= sCurrentThemeName;
738 if (sCurrentThemeName.isEmpty())
740 // Still no name. Use "DefaultTheme".
741 sCurrentThemeName = "DefaultTheme";
745 Reference<container::XNameAccess> xThemes (
746 rConfiguration.GetConfigurationNode("Presenter/Themes"),
747 UNO_QUERY);
748 if (xThemes.is())
750 // Iterate over all themes and search the one with the given name.
751 const Sequence<OUString> aKeys (xThemes->getElementNames());
752 for (const OUString& rsKey : aKeys)
754 Reference<container::XHierarchicalNameAccess> xTheme (
755 xThemes->getByName(rsKey), UNO_QUERY);
756 if (xTheme.is())
758 OUString sThemeName;
759 PresenterConfigurationAccess::GetConfigurationNode(xTheme, "ThemeName")
760 >>= sThemeName;
761 if (sThemeName == sCurrentThemeName)
763 pTheme = std::make_shared<PresenterTheme::Theme>(xTheme,rsKey);
764 break;
770 if (pTheme != nullptr)
772 pTheme->Read(rConfiguration, *this);
775 return pTheme;
778 BorderSize ReadContext::ReadBorderSize (const Reference<container::XNameAccess>& rxNode)
780 BorderSize aBorderSize;
782 if (rxNode.is())
784 GetByName(rxNode, "Left") >>= aBorderSize.mnLeft;
785 GetByName(rxNode, "Top") >>= aBorderSize.mnTop;
786 GetByName(rxNode, "Right") >>= aBorderSize.mnRight;
787 GetByName(rxNode, "Bottom") >>= aBorderSize.mnBottom;
790 return aBorderSize;
793 //===== PaneStyleContainer ====================================================
795 void PaneStyleContainer::Read (
796 const ReadContext& rReadContext,
797 const Reference<container::XHierarchicalNameAccess>& rxThemeRoot)
799 Reference<container::XNameAccess> xPaneStyleList (
800 PresenterConfigurationAccess::GetConfigurationNode(
801 rxThemeRoot,
802 "PaneStyles"),
803 UNO_QUERY);
804 if (!xPaneStyleList.is())
805 return;
807 ::std::vector<OUString> aProperties;
808 aProperties.reserve(6);
809 aProperties.emplace_back("StyleName");
810 aProperties.emplace_back("ParentStyle");
811 aProperties.emplace_back("TitleFont");
812 aProperties.emplace_back("InnerBorderSize");
813 aProperties.emplace_back("OuterBorderSize");
814 aProperties.emplace_back("BorderBitmapList");
815 PresenterConfigurationAccess::ForAll(
816 xPaneStyleList,
817 aProperties,
818 [this, &rReadContext] (std::vector<uno::Any> const& rValues)
820 return this->ProcessPaneStyle(rReadContext, rValues);
824 void PaneStyleContainer::ProcessPaneStyle(
825 ReadContext const & rReadContext,
826 const ::std::vector<Any>& rValues)
828 if (rValues.size() != 6)
829 return;
831 auto pStyle = std::make_shared<PaneStyle>();
833 rValues[0] >>= pStyle->msStyleName;
835 OUString sParentStyleName;
836 if (rValues[1] >>= sParentStyleName)
838 // Find parent style.
839 auto iStyle = std::find_if(mStyles.begin(), mStyles.end(),
840 [&sParentStyleName](const SharedPaneStyle& rxStyle) { return rxStyle->msStyleName == sParentStyleName; });
841 if (iStyle != mStyles.end())
842 pStyle->mpParentStyle = *iStyle;
845 Reference<container::XHierarchicalNameAccess> xFontNode (rValues[2], UNO_QUERY);
846 pStyle->mpFont = ReadContext::ReadFont(
847 xFontNode, PresenterTheme::SharedFontDescriptor());
849 Reference<container::XNameAccess> xInnerBorderSizeNode (rValues[3], UNO_QUERY);
850 pStyle->maInnerBorderSize = ReadContext::ReadBorderSize(xInnerBorderSizeNode);
851 Reference<container::XNameAccess> xOuterBorderSizeNode (rValues[4], UNO_QUERY);
852 pStyle->maOuterBorderSize = ReadContext::ReadBorderSize(xOuterBorderSizeNode);
854 if (pStyle->mpParentStyle != nullptr)
856 pStyle->maInnerBorderSize.Merge(pStyle->mpParentStyle->maInnerBorderSize);
857 pStyle->maOuterBorderSize.Merge(pStyle->mpParentStyle->maOuterBorderSize);
860 if (rReadContext.mxCanvas.is())
862 Reference<container::XNameAccess> xBitmapsNode (rValues[5], UNO_QUERY);
863 pStyle->mpBitmaps = std::make_shared<PresenterBitmapContainer>(
864 xBitmapsNode,
865 pStyle->mpParentStyle != nullptr ? pStyle->mpParentStyle->mpBitmaps
866 : std::shared_ptr<PresenterBitmapContainer>(),
867 rReadContext.mxComponentContext, rReadContext.mxCanvas,
868 rReadContext.mxPresenterHelper);
871 mStyles.push_back(pStyle);
874 SharedPaneStyle PaneStyleContainer::GetPaneStyle (const OUString& rsStyleName) const
876 auto iStyle = std::find_if(mStyles.begin(), mStyles.end(),
877 [&rsStyleName](const SharedPaneStyle& rxStyle) { return rxStyle->msStyleName == rsStyleName; });
878 if (iStyle != mStyles.end())
879 return *iStyle;
880 return SharedPaneStyle();
883 //===== PaneStyle =============================================================
885 PaneStyle::PaneStyle()
886 : msStyleName(),
887 mpParentStyle(),
888 mpFont(),
889 maInnerBorderSize(),
890 maOuterBorderSize(),
891 mpBitmaps()
895 SharedBitmapDescriptor PaneStyle::GetBitmap (const OUString& rsBitmapName) const
897 if (mpBitmaps != nullptr)
899 SharedBitmapDescriptor pBitmap = mpBitmaps->GetBitmap(rsBitmapName);
900 if (pBitmap)
901 return pBitmap;
904 if (mpParentStyle != nullptr)
905 return mpParentStyle->GetBitmap(rsBitmapName);
906 else
907 return SharedBitmapDescriptor();
910 PresenterTheme::SharedFontDescriptor PaneStyle::GetFont() const
912 if (mpFont)
913 return mpFont;
914 else if (mpParentStyle != nullptr)
915 return mpParentStyle->GetFont();
916 else
917 return PresenterTheme::SharedFontDescriptor();
920 //===== ViewStyleContainer ====================================================
922 void ViewStyleContainer::Read (
923 const ReadContext& rReadContext,
924 const Reference<container::XHierarchicalNameAccess>& rxThemeRoot)
926 Reference<container::XNameAccess> xViewStyleList (
927 PresenterConfigurationAccess::GetConfigurationNode(
928 rxThemeRoot,
929 "ViewStyles"),
930 UNO_QUERY);
931 if (xViewStyleList.is())
933 PresenterConfigurationAccess::ForAll(
934 xViewStyleList,
935 [this, &rReadContext] (OUString const&, uno::Reference<beans::XPropertySet> const& xProps)
937 return this->ProcessViewStyle(rReadContext, xProps);
942 void ViewStyleContainer::ProcessViewStyle(
943 ReadContext const & rReadContext,
944 const Reference<beans::XPropertySet>& rxProperties)
946 auto pStyle = std::make_shared<ViewStyle>();
948 PresenterConfigurationAccess::GetProperty(rxProperties, "StyleName")
949 >>= pStyle->msStyleName;
951 OUString sParentStyleName;
952 if (PresenterConfigurationAccess::GetProperty(rxProperties, "ParentStyle")
953 >>= sParentStyleName)
955 // Find parent style.
956 auto iStyle = std::find_if(mStyles.begin(), mStyles.end(),
957 [&sParentStyleName](const SharedViewStyle& rxStyle) { return rxStyle->msStyleName == sParentStyleName; });
958 if (iStyle != mStyles.end())
960 pStyle->mpParentStyle = *iStyle;
961 pStyle->mpFont = (*iStyle)->mpFont;
962 pStyle->mpBackground = (*iStyle)->mpBackground;
966 Reference<container::XHierarchicalNameAccess> xFontNode (
967 PresenterConfigurationAccess::GetProperty(rxProperties, "Font"), UNO_QUERY);
968 PresenterTheme::SharedFontDescriptor pFont (
969 ReadContext::ReadFont(xFontNode, PresenterTheme::SharedFontDescriptor()));
970 if (pFont)
971 pStyle->mpFont = pFont;
973 Reference<container::XHierarchicalNameAccess> xBackgroundNode (
974 PresenterConfigurationAccess::GetProperty(rxProperties, "Background"),
975 UNO_QUERY);
976 SharedBitmapDescriptor pBackground (PresenterBitmapContainer::LoadBitmap(
977 xBackgroundNode,
978 OUString(),
979 rReadContext.mxPresenterHelper,
980 rReadContext.mxCanvas,
981 SharedBitmapDescriptor()));
982 if (pBackground && pBackground->GetNormalBitmap().is())
983 pStyle->mpBackground = pBackground;
985 mStyles.push_back(pStyle);
988 SharedViewStyle ViewStyleContainer::GetViewStyle (const OUString& rsStyleName) const
990 auto iStyle = std::find_if(mStyles.begin(), mStyles.end(),
991 [&rsStyleName](const SharedViewStyle& rxStyle) { return rxStyle->msStyleName == rsStyleName; });
992 if (iStyle != mStyles.end())
993 return *iStyle;
994 return SharedViewStyle();
997 //===== ViewStyle =============================================================
999 ViewStyle::ViewStyle()
1000 : msStyleName(),
1001 mpParentStyle(),
1002 mpFont(),
1003 mpBackground()
1007 SharedBitmapDescriptor ViewStyle::GetBitmap (std::u16string_view rsBitmapName) const
1009 if (rsBitmapName == u"Background")
1010 return mpBackground;
1011 else
1012 return SharedBitmapDescriptor();
1015 PresenterTheme::SharedFontDescriptor ViewStyle::GetFont() const
1017 if (mpFont)
1018 return mpFont;
1019 else if (mpParentStyle != nullptr)
1020 return mpParentStyle->GetFont();
1021 else
1022 return PresenterTheme::SharedFontDescriptor();
1025 //===== StyleAssociationContainer =============================================
1027 void StyleAssociationContainer::Read (
1028 const Reference<container::XHierarchicalNameAccess>& rxThemeRoot)
1030 Reference<container::XNameAccess> xStyleAssociationList (
1031 PresenterConfigurationAccess::GetConfigurationNode(
1032 rxThemeRoot,
1033 "StyleAssociations"),
1034 UNO_QUERY);
1035 if (!xStyleAssociationList.is())
1036 return;
1038 ::std::vector<OUString> aProperties { "ResourceURL", "StyleName" };
1039 PresenterConfigurationAccess::ForAll(
1040 xStyleAssociationList,
1041 aProperties,
1042 [this] (std::vector<uno::Any> const& rValues)
1044 return this->ProcessStyleAssociation(rValues);
1048 OUString StyleAssociationContainer::GetStyleName (const OUString& rsResourceName) const
1050 StyleAssociations::const_iterator iAssociation (maStyleAssociations.find(rsResourceName));
1051 if (iAssociation != maStyleAssociations.end())
1052 return iAssociation->second;
1053 else
1054 return OUString();
1057 void StyleAssociationContainer::ProcessStyleAssociation(
1058 const ::std::vector<Any>& rValues)
1060 if (rValues.size() != 2)
1061 return;
1063 OUString sResourceURL;
1064 OUString sStyleName;
1065 if ((rValues[0] >>= sResourceURL)
1066 && (rValues[1] >>= sStyleName))
1068 maStyleAssociations[sResourceURL] = sStyleName;
1072 } // end of anonymous namespace
1074 } // end of namespace ::sdext::presenter
1076 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */