vcl: allow for overriding the default PDF rendering resolution
[LibreOffice.git] / sdext / source / presenter / PresenterTheme.cxx
blobcd82d1dcd90d32b07d87162fd584800d1e8cf313
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 { namespace 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 vector<sal_Int32> aSequence (4);
56 aSequence[0] = mnLeft == mnInvalidValue ? 0 : mnLeft;
57 aSequence[1] = mnTop == mnInvalidValue ? 0 : mnTop;
58 aSequence[2] = mnRight == mnInvalidValue ? 0 : mnRight;
59 aSequence[3] = mnBottom == mnInvalidValue ? 0 : mnBottom;
60 return aSequence;
63 void Merge (const BorderSize& rBorderSize)
65 if (mnLeft == mnInvalidValue)
66 mnLeft = rBorderSize.mnLeft;
67 if (mnTop == mnInvalidValue)
68 mnTop = rBorderSize.mnTop;
69 if (mnRight == mnInvalidValue)
70 mnRight = rBorderSize.mnRight;
71 if (mnBottom == mnInvalidValue)
72 mnBottom = rBorderSize.mnBottom;
76 /** Reading a theme from the configurations is done in various classes. The
77 ReadContext gives access to frequently used objects and functions to make
78 the configuration handling easier.
80 class ReadContext
82 public:
83 Reference<XComponentContext> mxComponentContext;
84 Reference<rendering::XCanvas> mxCanvas;
85 Reference<drawing::XPresenterHelper> mxPresenterHelper;
87 ReadContext (
88 const Reference<XComponentContext>& rxContext,
89 const Reference<rendering::XCanvas>& rxCanvas);
91 /** Read data describing a font from the node that can be reached from
92 the given root via the given path.
93 @param rsFontPath
94 May be empty.
96 static PresenterTheme::SharedFontDescriptor ReadFont (
97 const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxTheme,
98 const OUString& rsFontPath,
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 (const OUString& 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 const 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.get() != nullptr)
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, OUString(), 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 std::shared_ptr<PresenterConfigurationAccess> pConfiguration (
343 new PresenterConfigurationAccess(
344 mxContext,
345 "/org.openoffice.Office.PresenterScreen/",
346 PresenterConfigurationAccess::READ_WRITE));
348 // Get configuration node for the view style container of the current
349 // theme.
350 if (pConfiguration->GoToChild( OUString(
351 "Presenter/Themes/" + mpTheme->msConfigurationNodeName + "/ViewStyles")))
353 pConfiguration->GoToChild(
354 [&rsStyleName] (OUString const&, uno::Reference<beans::XPropertySet> const& xProps)
356 return PresenterConfigurationAccess::IsStringPropertyEqual(
357 rsStyleName, "StyleName", xProps);
360 return pConfiguration;
363 SharedBitmapDescriptor PresenterTheme::GetBitmap (
364 const OUString& rsStyleName,
365 const OUString& rsBitmapName) const
367 if (mpTheme != nullptr)
369 if (rsStyleName.isEmpty())
371 if (rsBitmapName == "Background")
373 std::shared_ptr<Theme> pTheme (mpTheme);
374 while (pTheme != nullptr && pTheme->mpBackground.get() == nullptr)
375 pTheme = pTheme->mpParentTheme;
376 if (pTheme != nullptr)
377 return pTheme->mpBackground;
378 else
379 return SharedBitmapDescriptor();
382 else
384 SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName));
385 if (pPaneStyle.get() != nullptr)
387 SharedBitmapDescriptor pBitmap (pPaneStyle->GetBitmap(rsBitmapName));
388 if (pBitmap.get() != nullptr)
389 return pBitmap;
392 SharedViewStyle pViewStyle (mpTheme->GetViewStyle(rsStyleName));
393 if (pViewStyle.get() != nullptr)
395 SharedBitmapDescriptor pBitmap (pViewStyle->GetBitmap(rsBitmapName));
396 if (pBitmap.get() != nullptr)
397 return pBitmap;
402 return SharedBitmapDescriptor();
405 SharedBitmapDescriptor PresenterTheme::GetBitmap (
406 const OUString& rsBitmapName) const
408 if (mpTheme != nullptr)
410 if (rsBitmapName == "Background")
412 std::shared_ptr<Theme> pTheme (mpTheme);
413 while (pTheme != nullptr && pTheme->mpBackground.get() == nullptr)
414 pTheme = pTheme->mpParentTheme;
415 if (pTheme != nullptr)
416 return pTheme->mpBackground;
417 else
418 return SharedBitmapDescriptor();
420 else
422 if (mpTheme->mpIconContainer != nullptr)
423 return mpTheme->mpIconContainer->GetBitmap(rsBitmapName);
427 return SharedBitmapDescriptor();
430 std::shared_ptr<PresenterBitmapContainer> PresenterTheme::GetBitmapContainer() const
432 if (mpTheme != nullptr)
433 return mpTheme->mpIconContainer;
434 else
435 return std::shared_ptr<PresenterBitmapContainer>();
438 PresenterTheme::SharedFontDescriptor PresenterTheme::GetFont (
439 const OUString& rsStyleName) const
441 if (mpTheme != nullptr)
443 SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName));
444 if (pPaneStyle.get() != nullptr)
445 return pPaneStyle->GetFont();
447 SharedViewStyle pViewStyle (mpTheme->GetViewStyle(rsStyleName));
448 if (pViewStyle.get() != nullptr)
449 return pViewStyle->GetFont();
451 std::shared_ptr<Theme> pTheme (mpTheme);
452 while (pTheme != nullptr)
454 Theme::FontContainer::const_iterator iFont (pTheme->maFontContainer.find(rsStyleName));
455 if (iFont != pTheme->maFontContainer.end())
456 return iFont->second;
458 pTheme = pTheme->mpParentTheme;
462 return SharedFontDescriptor();
465 //===== FontDescriptor ========================================================
467 PresenterTheme::FontDescriptor::FontDescriptor (
468 const std::shared_ptr<FontDescriptor>& rpDescriptor)
469 : msFamilyName(),
470 msStyleName(),
471 mnSize(12),
472 mnColor(0x00000000),
473 msAnchor(OUString("Left")),
474 mnXOffset(0),
475 mnYOffset(0)
477 if (rpDescriptor != nullptr)
479 msFamilyName = rpDescriptor->msFamilyName;
480 msStyleName = rpDescriptor->msStyleName;
481 mnSize = rpDescriptor->mnSize;
482 mnColor = rpDescriptor->mnColor;
483 msAnchor = rpDescriptor->msAnchor;
484 mnXOffset = rpDescriptor->mnXOffset;
485 mnYOffset = rpDescriptor->mnYOffset;
489 bool PresenterTheme::FontDescriptor::PrepareFont (
490 const Reference<rendering::XCanvas>& rxCanvas)
492 if (mxFont.is())
493 return true;
495 if ( ! rxCanvas.is())
496 return false;
498 const double nCellSize (GetCellSizeForDesignSize(rxCanvas, mnSize));
499 mxFont = CreateFont(rxCanvas, nCellSize);
501 return mxFont.is();
504 Reference<rendering::XCanvasFont> PresenterTheme::FontDescriptor::CreateFont (
505 const Reference<rendering::XCanvas>& rxCanvas,
506 const double nCellSize) const
508 rendering::FontRequest aFontRequest;
509 aFontRequest.FontDescription.FamilyName = msFamilyName;
510 if (msFamilyName.isEmpty())
511 aFontRequest.FontDescription.FamilyName = "Tahoma";
512 aFontRequest.FontDescription.StyleName = msStyleName;
513 aFontRequest.CellSize = nCellSize;
515 // Make an attempt at translating the style name(s)into a corresponding
516 // font description.
517 if (msStyleName == "Bold")
518 aFontRequest.FontDescription.FontDescription.Weight = rendering::PanoseWeight::HEAVY;
520 return rxCanvas->createFont(
521 aFontRequest,
522 Sequence<beans::PropertyValue>(),
523 geometry::Matrix2D(1,0,0,1));
526 double PresenterTheme::FontDescriptor::GetCellSizeForDesignSize (
527 const Reference<rendering::XCanvas>& rxCanvas,
528 const double nDesignSize) const
530 // Use the given design size as initial value in calculating the cell
531 // size.
532 double nCellSize (nDesignSize);
534 if ( ! rxCanvas.is())
536 // We need the canvas to do the conversion. Return the design size,
537 // it is the our best guess in this circumstance.
538 return nDesignSize;
541 Reference<rendering::XCanvasFont> xFont (CreateFont(rxCanvas, nCellSize));
542 if ( ! xFont.is())
543 return nDesignSize;
545 geometry::RealRectangle2D aBox (PresenterCanvasHelper::GetTextBoundingBox (xFont, "X"));
547 const double nAscent (-aBox.Y1);
548 //tdf#112408
549 if (nAscent == 0)
550 return nDesignSize;
551 const double nDescent (aBox.Y2);
552 const double nScale = (nAscent+nDescent) / nAscent;
553 return nDesignSize * nScale;
556 //===== Theme =================================================================
558 PresenterTheme::Theme::Theme (
559 const Reference<container::XHierarchicalNameAccess>& rxThemeRoot,
560 const OUString& rsNodeName)
561 : msConfigurationNodeName(rsNodeName),
562 mpParentTheme(),
563 maPaneStyles(),
564 maViewStyles(),
565 maStyleAssociations(),
566 mxThemeRoot(rxThemeRoot),
567 mpIconContainer()
571 void PresenterTheme::Theme::Read (
572 PresenterConfigurationAccess& rConfiguration,
573 ReadContext& rReadContext)
575 // Parent theme name.
576 OUString sParentThemeName;
577 if ((PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, "ParentTheme")
578 >>= sParentThemeName)
579 && !sParentThemeName.isEmpty())
581 mpParentTheme = rReadContext.ReadTheme(rConfiguration, sParentThemeName);
584 // Background.
585 mpBackground = PresenterBitmapContainer::LoadBitmap(
586 mxThemeRoot,
587 "Background",
588 rReadContext.mxPresenterHelper,
589 rReadContext.mxCanvas,
590 SharedBitmapDescriptor());
592 // Style associations.
593 maStyleAssociations.Read(mxThemeRoot);
595 // Pane styles.
596 maPaneStyles.Read(rReadContext, mxThemeRoot);
598 // View styles.
599 maViewStyles.Read(rReadContext, mxThemeRoot);
601 // Read bitmaps.
602 mpIconContainer.reset(new PresenterBitmapContainer(
603 Reference<container::XNameAccess>(
604 PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, "Bitmaps"), UNO_QUERY),
605 mpParentTheme != nullptr ? mpParentTheme->mpIconContainer
606 : std::shared_ptr<PresenterBitmapContainer>(),
607 rReadContext.mxComponentContext, rReadContext.mxCanvas));
609 // Read fonts.
610 Reference<container::XNameAccess> xFontNode(
611 PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, "Fonts"),
612 UNO_QUERY);
613 PresenterConfigurationAccess::ForAll(
614 xFontNode,
615 [this] (OUString const& rKey, uno::Reference<beans::XPropertySet> const& xProps)
617 return this->ProcessFont(rKey, xProps);
621 SharedPaneStyle PresenterTheme::Theme::GetPaneStyle (const OUString& rsStyleName) const
623 SharedPaneStyle pPaneStyle (maPaneStyles.GetPaneStyle(rsStyleName));
624 if (pPaneStyle.get() != nullptr)
625 return pPaneStyle;
626 else if (mpParentTheme != nullptr)
627 return mpParentTheme->GetPaneStyle(rsStyleName);
628 else
629 return SharedPaneStyle();
632 SharedViewStyle PresenterTheme::Theme::GetViewStyle (const OUString& rsStyleName) const
634 SharedViewStyle pViewStyle (maViewStyles.GetViewStyle(rsStyleName));
635 if (pViewStyle.get() != nullptr)
636 return pViewStyle;
637 else if (mpParentTheme != nullptr)
638 return mpParentTheme->GetViewStyle(rsStyleName);
639 else
640 return SharedViewStyle();
643 void PresenterTheme::Theme::ProcessFont(
644 const OUString& rsKey,
645 const Reference<beans::XPropertySet>& rxProperties)
647 maFontContainer[rsKey] = ReadContext::ReadFont(rxProperties, SharedFontDescriptor());
650 namespace {
652 //===== ReadContext ===========================================================
654 ReadContext::ReadContext (
655 const css::uno::Reference<css::uno::XComponentContext>& rxContext,
656 const Reference<rendering::XCanvas>& rxCanvas)
657 : mxComponentContext(rxContext),
658 mxCanvas(rxCanvas),
659 mxPresenterHelper()
661 Reference<lang::XMultiComponentFactory> xFactory (rxContext->getServiceManager());
662 if (xFactory.is())
664 mxPresenterHelper.set(
665 xFactory->createInstanceWithContext(
666 "com.sun.star.comp.Draw.PresenterHelper",
667 rxContext),
668 UNO_QUERY_THROW);
672 PresenterTheme::SharedFontDescriptor ReadContext::ReadFont (
673 const Reference<container::XHierarchicalNameAccess>& rxNode,
674 const OUString& rsFontPath,
675 const PresenterTheme::SharedFontDescriptor& rpDefault)
677 if ( ! rxNode.is())
678 return PresenterTheme::SharedFontDescriptor();
682 Reference<container::XHierarchicalNameAccess> xFont (
683 PresenterConfigurationAccess::GetConfigurationNode(
684 rxNode,
685 rsFontPath),
686 UNO_QUERY_THROW);
688 Reference<beans::XPropertySet> xProperties (xFont, UNO_QUERY_THROW);
689 return ReadFont(xProperties, rpDefault);
691 catch (Exception&)
693 OSL_ASSERT(false);
696 return PresenterTheme::SharedFontDescriptor();
699 PresenterTheme::SharedFontDescriptor ReadContext::ReadFont (
700 const Reference<beans::XPropertySet>& rxProperties,
701 const PresenterTheme::SharedFontDescriptor& rpDefault)
703 std::shared_ptr<PresenterTheme::FontDescriptor> pDescriptor (
704 new PresenterTheme::FontDescriptor(rpDefault));
706 PresenterConfigurationAccess::GetProperty(rxProperties, "FamilyName") >>= pDescriptor->msFamilyName;
707 PresenterConfigurationAccess::GetProperty(rxProperties, "Style") >>= pDescriptor->msStyleName;
708 PresenterConfigurationAccess::GetProperty(rxProperties, "Size") >>= pDescriptor->mnSize;
709 PresenterTheme::ConvertToColor(
710 PresenterConfigurationAccess::GetProperty(rxProperties, "Color"),
711 pDescriptor->mnColor);
712 PresenterConfigurationAccess::GetProperty(rxProperties, "Anchor") >>= pDescriptor->msAnchor;
713 PresenterConfigurationAccess::GetProperty(rxProperties, "XOffset") >>= pDescriptor->mnXOffset;
714 PresenterConfigurationAccess::GetProperty(rxProperties, "YOffset") >>= pDescriptor->mnYOffset;
716 return pDescriptor;
719 Any ReadContext::GetByName (
720 const Reference<container::XNameAccess>& rxNode,
721 const OUString& rsName)
723 OSL_ASSERT(rxNode.is());
724 if (rxNode->hasByName(rsName))
725 return rxNode->getByName(rsName);
726 else
727 return Any();
730 std::shared_ptr<PresenterTheme::Theme> ReadContext::ReadTheme (
731 PresenterConfigurationAccess& rConfiguration,
732 const OUString& rsThemeName)
734 std::shared_ptr<PresenterTheme::Theme> pTheme;
736 OUString sCurrentThemeName (rsThemeName);
737 if (sCurrentThemeName.isEmpty())
739 // No theme name given. Look up the CurrentTheme property.
740 rConfiguration.GetConfigurationNode("Presenter/CurrentTheme") >>= sCurrentThemeName;
741 if (sCurrentThemeName.isEmpty())
743 // Still no name. Use "DefaultTheme".
744 sCurrentThemeName = "DefaultTheme";
748 Reference<container::XNameAccess> xThemes (
749 rConfiguration.GetConfigurationNode("Presenter/Themes"),
750 UNO_QUERY);
751 if (xThemes.is())
753 // Iterate over all themes and search the one with the given name.
754 const Sequence<OUString> aKeys (xThemes->getElementNames());
755 for (const OUString& rsKey : aKeys)
757 Reference<container::XHierarchicalNameAccess> xTheme (
758 xThemes->getByName(rsKey), UNO_QUERY);
759 if (xTheme.is())
761 OUString sThemeName;
762 PresenterConfigurationAccess::GetConfigurationNode(xTheme, "ThemeName")
763 >>= sThemeName;
764 if (sThemeName == sCurrentThemeName)
766 pTheme.reset(new PresenterTheme::Theme(xTheme,rsKey));
767 break;
773 if (pTheme != nullptr)
775 pTheme->Read(rConfiguration, *this);
778 return pTheme;
781 BorderSize ReadContext::ReadBorderSize (const Reference<container::XNameAccess>& rxNode)
783 BorderSize aBorderSize;
785 if (rxNode.is())
787 GetByName(rxNode, "Left") >>= aBorderSize.mnLeft;
788 GetByName(rxNode, "Top") >>= aBorderSize.mnTop;
789 GetByName(rxNode, "Right") >>= aBorderSize.mnRight;
790 GetByName(rxNode, "Bottom") >>= aBorderSize.mnBottom;
793 return aBorderSize;
796 //===== PaneStyleContainer ====================================================
798 void PaneStyleContainer::Read (
799 const ReadContext& rReadContext,
800 const Reference<container::XHierarchicalNameAccess>& rxThemeRoot)
802 Reference<container::XNameAccess> xPaneStyleList (
803 PresenterConfigurationAccess::GetConfigurationNode(
804 rxThemeRoot,
805 "PaneStyles"),
806 UNO_QUERY);
807 if (!xPaneStyleList.is())
808 return;
810 ::std::vector<OUString> aProperties;
811 aProperties.reserve(6);
812 aProperties.emplace_back("StyleName");
813 aProperties.emplace_back("ParentStyle");
814 aProperties.emplace_back("TitleFont");
815 aProperties.emplace_back("InnerBorderSize");
816 aProperties.emplace_back("OuterBorderSize");
817 aProperties.emplace_back("BorderBitmapList");
818 PresenterConfigurationAccess::ForAll(
819 xPaneStyleList,
820 aProperties,
821 [this, &rReadContext] (std::vector<uno::Any> const& rValues)
823 return this->ProcessPaneStyle(rReadContext, rValues);
827 void PaneStyleContainer::ProcessPaneStyle(
828 ReadContext const & rReadContext,
829 const ::std::vector<Any>& rValues)
831 if (rValues.size() != 6)
832 return;
834 std::shared_ptr<PaneStyle> pStyle (new PaneStyle());
836 rValues[0] >>= pStyle->msStyleName;
838 OUString sParentStyleName;
839 if (rValues[1] >>= sParentStyleName)
841 // Find parent style.
842 auto iStyle = std::find_if(mStyles.begin(), mStyles.end(),
843 [&sParentStyleName](const SharedPaneStyle& rxStyle) { return rxStyle->msStyleName == sParentStyleName; });
844 if (iStyle != mStyles.end())
845 pStyle->mpParentStyle = *iStyle;
848 Reference<container::XHierarchicalNameAccess> xFontNode (rValues[2], UNO_QUERY);
849 pStyle->mpFont = ReadContext::ReadFont(
850 xFontNode, "", PresenterTheme::SharedFontDescriptor());
852 Reference<container::XNameAccess> xInnerBorderSizeNode (rValues[3], UNO_QUERY);
853 pStyle->maInnerBorderSize = ReadContext::ReadBorderSize(xInnerBorderSizeNode);
854 Reference<container::XNameAccess> xOuterBorderSizeNode (rValues[4], UNO_QUERY);
855 pStyle->maOuterBorderSize = ReadContext::ReadBorderSize(xOuterBorderSizeNode);
857 if (pStyle->mpParentStyle != nullptr)
859 pStyle->maInnerBorderSize.Merge(pStyle->mpParentStyle->maInnerBorderSize);
860 pStyle->maOuterBorderSize.Merge(pStyle->mpParentStyle->maOuterBorderSize);
863 if (rReadContext.mxCanvas.is())
865 Reference<container::XNameAccess> xBitmapsNode (rValues[5], UNO_QUERY);
866 pStyle->mpBitmaps.reset(new PresenterBitmapContainer(
867 xBitmapsNode,
868 pStyle->mpParentStyle != nullptr ? pStyle->mpParentStyle->mpBitmaps
869 : std::shared_ptr<PresenterBitmapContainer>(),
870 rReadContext.mxComponentContext, rReadContext.mxCanvas,
871 rReadContext.mxPresenterHelper));
874 mStyles.push_back(pStyle);
877 SharedPaneStyle PaneStyleContainer::GetPaneStyle (const OUString& rsStyleName) const
879 auto iStyle = std::find_if(mStyles.begin(), mStyles.end(),
880 [&rsStyleName](const SharedPaneStyle& rxStyle) { return rxStyle->msStyleName == rsStyleName; });
881 if (iStyle != mStyles.end())
882 return *iStyle;
883 return SharedPaneStyle();
886 //===== PaneStyle =============================================================
888 PaneStyle::PaneStyle()
889 : msStyleName(),
890 mpParentStyle(),
891 mpFont(),
892 maInnerBorderSize(),
893 maOuterBorderSize(),
894 mpBitmaps()
898 SharedBitmapDescriptor PaneStyle::GetBitmap (const OUString& rsBitmapName) const
900 if (mpBitmaps != nullptr)
902 SharedBitmapDescriptor pBitmap = mpBitmaps->GetBitmap(rsBitmapName);
903 if (pBitmap.get() != nullptr)
904 return pBitmap;
907 if (mpParentStyle != nullptr)
908 return mpParentStyle->GetBitmap(rsBitmapName);
909 else
910 return SharedBitmapDescriptor();
913 PresenterTheme::SharedFontDescriptor PaneStyle::GetFont() const
915 if (mpFont.get() != nullptr)
916 return mpFont;
917 else if (mpParentStyle != nullptr)
918 return mpParentStyle->GetFont();
919 else
920 return PresenterTheme::SharedFontDescriptor();
923 //===== ViewStyleContainer ====================================================
925 void ViewStyleContainer::Read (
926 const ReadContext& rReadContext,
927 const Reference<container::XHierarchicalNameAccess>& rxThemeRoot)
929 Reference<container::XNameAccess> xViewStyleList (
930 PresenterConfigurationAccess::GetConfigurationNode(
931 rxThemeRoot,
932 "ViewStyles"),
933 UNO_QUERY);
934 if (xViewStyleList.is())
936 PresenterConfigurationAccess::ForAll(
937 xViewStyleList,
938 [this, &rReadContext] (OUString const&, uno::Reference<beans::XPropertySet> const& xProps)
940 return this->ProcessViewStyle(rReadContext, xProps);
945 void ViewStyleContainer::ProcessViewStyle(
946 ReadContext const & rReadContext,
947 const Reference<beans::XPropertySet>& rxProperties)
949 std::shared_ptr<ViewStyle> pStyle (new ViewStyle());
951 PresenterConfigurationAccess::GetProperty(rxProperties, "StyleName")
952 >>= pStyle->msStyleName;
954 OUString sParentStyleName;
955 if (PresenterConfigurationAccess::GetProperty(rxProperties, "ParentStyle")
956 >>= sParentStyleName)
958 // Find parent style.
959 auto iStyle = std::find_if(mStyles.begin(), mStyles.end(),
960 [&sParentStyleName](const SharedViewStyle& rxStyle) { return rxStyle->msStyleName == sParentStyleName; });
961 if (iStyle != mStyles.end())
963 pStyle->mpParentStyle = *iStyle;
964 pStyle->mpFont = (*iStyle)->mpFont;
965 pStyle->mpBackground = (*iStyle)->mpBackground;
969 const OUString sPathToFont; // empty string
970 Reference<container::XHierarchicalNameAccess> xFontNode (
971 PresenterConfigurationAccess::GetProperty(rxProperties, "Font"), UNO_QUERY);
972 PresenterTheme::SharedFontDescriptor pFont (
973 ReadContext::ReadFont(xFontNode, sPathToFont, PresenterTheme::SharedFontDescriptor()));
974 if (pFont.get() != nullptr)
975 pStyle->mpFont = pFont;
977 Reference<container::XHierarchicalNameAccess> xBackgroundNode (
978 PresenterConfigurationAccess::GetProperty(rxProperties, "Background"),
979 UNO_QUERY);
980 SharedBitmapDescriptor pBackground (PresenterBitmapContainer::LoadBitmap(
981 xBackgroundNode,
982 OUString(),
983 rReadContext.mxPresenterHelper,
984 rReadContext.mxCanvas,
985 SharedBitmapDescriptor()));
986 if (pBackground.get() != nullptr && pBackground->GetNormalBitmap().is())
987 pStyle->mpBackground = pBackground;
989 mStyles.push_back(pStyle);
992 SharedViewStyle ViewStyleContainer::GetViewStyle (const OUString& rsStyleName) const
994 auto iStyle = std::find_if(mStyles.begin(), mStyles.end(),
995 [&rsStyleName](const SharedViewStyle& rxStyle) { return rxStyle->msStyleName == rsStyleName; });
996 if (iStyle != mStyles.end())
997 return *iStyle;
998 return SharedViewStyle();
1001 //===== ViewStyle =============================================================
1003 ViewStyle::ViewStyle()
1004 : msStyleName(),
1005 mpParentStyle(),
1006 mpFont(),
1007 mpBackground()
1011 SharedBitmapDescriptor ViewStyle::GetBitmap (const OUString& rsBitmapName) const
1013 if (rsBitmapName == "Background")
1014 return mpBackground;
1015 else
1016 return SharedBitmapDescriptor();
1019 PresenterTheme::SharedFontDescriptor ViewStyle::GetFont() const
1021 if (mpFont.get() != nullptr)
1022 return mpFont;
1023 else if (mpParentStyle != nullptr)
1024 return mpParentStyle->GetFont();
1025 else
1026 return PresenterTheme::SharedFontDescriptor();
1029 //===== StyleAssociationContainer =============================================
1031 void StyleAssociationContainer::Read (
1032 const Reference<container::XHierarchicalNameAccess>& rxThemeRoot)
1034 Reference<container::XNameAccess> xStyleAssociationList (
1035 PresenterConfigurationAccess::GetConfigurationNode(
1036 rxThemeRoot,
1037 "StyleAssociations"),
1038 UNO_QUERY);
1039 if (!xStyleAssociationList.is())
1040 return;
1042 ::std::vector<OUString> aProperties (2);
1043 aProperties[0] = "ResourceURL";
1044 aProperties[1] = "StyleName";
1045 PresenterConfigurationAccess::ForAll(
1046 xStyleAssociationList,
1047 aProperties,
1048 [this] (std::vector<uno::Any> const& rValues)
1050 return this->ProcessStyleAssociation(rValues);
1054 OUString StyleAssociationContainer::GetStyleName (const OUString& rsResourceName) const
1056 StyleAssociations::const_iterator iAssociation (maStyleAssociations.find(rsResourceName));
1057 if (iAssociation != maStyleAssociations.end())
1058 return iAssociation->second;
1059 else
1060 return OUString();
1063 void StyleAssociationContainer::ProcessStyleAssociation(
1064 const ::std::vector<Any>& rValues)
1066 if (rValues.size() != 2)
1067 return;
1069 OUString sResourceURL;
1070 OUString sStyleName;
1071 if ((rValues[0] >>= sResourceURL)
1072 && (rValues[1] >>= sStyleName))
1074 maStyleAssociations[sResourceURL] = sStyleName;
1078 } // end of anonymous namespace
1080 } } // end of namespace ::sdext::presenter
1082 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */