LibreOffice Module sdext (master)  1
PresenterTheme.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include "PresenterTheme.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>
29 
30 using namespace ::com::sun::star;
31 using namespace ::com::sun::star::uno;
32 using namespace ::std;
33 
34 namespace sdext { namespace presenter {
35 
36 namespace {
37 
38 class BorderSize
39 {
40 public:
41  const static sal_Int32 mnInvalidValue = -10000;
42 
43  BorderSize() : mnLeft(mnInvalidValue),
44  mnTop(mnInvalidValue),
45  mnRight(mnInvalidValue),
46  mnBottom(mnInvalidValue) {}
47 
48  sal_Int32 mnLeft;
49  sal_Int32 mnTop;
50  sal_Int32 mnRight;
51  sal_Int32 mnBottom;
52 
53  vector<sal_Int32> ToVector()
54  {
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;
61  };
62 
63  void Merge (const BorderSize& rBorderSize)
64  {
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;
73  }
74 };
75 
80 class ReadContext
81 {
82 public:
84  Reference<rendering::XCanvas> mxCanvas;
85  Reference<drawing::XPresenterHelper> mxPresenterHelper;
86 
87  ReadContext (
88  const Reference<XComponentContext>& rxContext,
89  const Reference<rendering::XCanvas>& rxCanvas);
90 
97  const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxTheme,
98  const OUString& rsFontPath,
99  const PresenterTheme::SharedFontDescriptor& rpDefault);
101  const Reference<beans::XPropertySet>& rxFontProperties,
102  const PresenterTheme::SharedFontDescriptor& rpDefault);
103 
104  std::shared_ptr<PresenterTheme::Theme> ReadTheme (
105  PresenterConfigurationAccess& rConfiguration,
106  const OUString& rsThemeName);
107 
108  static BorderSize ReadBorderSize (const Reference<container::XNameAccess>& rxNode);
109 
110 private:
111  static Any GetByName (
112  const Reference<container::XNameAccess>& rxNode,
113  const OUString& rsName);
114 };
115 
118 class PaneStyle
119 {
120 public:
121  PaneStyle();
122 
123  SharedBitmapDescriptor GetBitmap (const OUString& sBitmapName) const;
124 
125  OUString msStyleName;
126  std::shared_ptr<PaneStyle> mpParentStyle;
128  BorderSize maInnerBorderSize;
129  BorderSize maOuterBorderSize;
130  std::shared_ptr<PresenterBitmapContainer> mpBitmaps;
131 
132  PresenterTheme::SharedFontDescriptor GetFont() const;
133 };
134 
135 typedef std::shared_ptr<PaneStyle> SharedPaneStyle;
136 
137 class PaneStyleContainer
138 {
139 private:
140  ::std::vector<SharedPaneStyle> mStyles;
141 
142 public:
143  void Read (
144  const ReadContext& rReadContext,
145  const Reference<container::XHierarchicalNameAccess>& rThemeRoot);
146 
147  SharedPaneStyle GetPaneStyle (const OUString& rsStyleName) const;
148 
149 private:
150  void ProcessPaneStyle (
151  ReadContext const & rReadContext,
152  const ::std::vector<css::uno::Any>& rValues);
153 };
154 
157 class ViewStyle
158 {
159 public:
160  ViewStyle();
161 
162  SharedBitmapDescriptor GetBitmap (const OUString& sBitmapName) const;
163 
164  PresenterTheme::SharedFontDescriptor GetFont() const;
165 
166  OUString msStyleName;
167  std::shared_ptr<ViewStyle> mpParentStyle;
170 };
171 
172 typedef std::shared_ptr<ViewStyle> SharedViewStyle;
173 
174 class ViewStyleContainer
175 {
176 private:
177  ::std::vector<SharedViewStyle> mStyles;
178 
179 public:
180  void Read (
181  const ReadContext& rReadContext,
182  const Reference<container::XHierarchicalNameAccess>& rThemeRoot);
183 
184  SharedViewStyle GetViewStyle (const OUString& rsStyleName) const;
185 
186 private:
187  void ProcessViewStyle(
188  ReadContext const & rReadContext,
189  const Reference<beans::XPropertySet>& rxProperties);
190 };
191 
192 class StyleAssociationContainer
193 {
194 public:
195  void Read (
196  const Reference<container::XHierarchicalNameAccess>& rThemeRoot);
197 
198  OUString GetStyleName (const OUString& rsResourceName) const;
199 
200 private:
201  typedef map<OUString, OUString> StyleAssociations;
202  StyleAssociations maStyleAssociations;
203 
204  void ProcessStyleAssociation(
205  const ::std::vector<css::uno::Any>& rValues);
206 };
207 
208 } // end of anonymous namespace
209 
211 {
212 public:
213  Theme (
214  const Reference<container::XHierarchicalNameAccess>& rThemeRoot,
215  const OUString& rsNodeName);
216 
217  void Read (
218  PresenterConfigurationAccess& rConfiguration,
219  ReadContext& rReadContext);
220 
221  OUString const msConfigurationNodeName;
222  std::shared_ptr<Theme> mpParentTheme;
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;
231 
232  SharedPaneStyle GetPaneStyle (const OUString& rsStyleName) const;
233  SharedViewStyle GetViewStyle (const OUString& rsStyleName) const;
234 
235 private:
236  void ProcessFont(
237  const OUString& rsKey,
238  const Reference<beans::XPropertySet>& rxProperties);
239 };
240 
241 //===== PresenterTheme ========================================================
242 
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)
249 {
250  mpTheme = ReadTheme();
251 }
252 
254 {
255 }
256 
257 std::shared_ptr<PresenterTheme::Theme> PresenterTheme::ReadTheme()
258 {
259  ReadContext aReadContext(mxContext, mxCanvas);
260 
261  PresenterConfigurationAccess aConfiguration (
262  mxContext,
263  "/org.openoffice.Office.PresenterScreen/",
265 
266  return aReadContext.ReadTheme(aConfiguration, OUString());
267 }
268 
270 {
271  return mxCanvas.is();
272 }
273 
274 void PresenterTheme::ProvideCanvas (const Reference<rendering::XCanvas>& rxCanvas)
275 {
276  if ( ! mxCanvas.is() && rxCanvas.is())
277  {
278  mxCanvas = rxCanvas;
279  ReadTheme();
280  }
281 }
282 
283 OUString PresenterTheme::GetStyleName (const OUString& rsResourceURL) const
284 {
285  OUString sStyleName;
286  std::shared_ptr<Theme> pTheme (mpTheme);
287  while (sStyleName.isEmpty() && pTheme != nullptr)
288  {
289  sStyleName = pTheme->maStyleAssociations.GetStyleName(rsResourceURL);
290  pTheme = pTheme->mpParentTheme;
291  }
292  return sStyleName;
293 }
294 
295 ::std::vector<sal_Int32> PresenterTheme::GetBorderSize (
296  const OUString& rsStyleName,
297  const bool bOuter) const
298 {
299  OSL_ASSERT(mpTheme != nullptr);
300 
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
308  {
309  return ::std::vector<sal_Int32>(4,0);
310  }
311 }
312 
314  const Reference<container::XHierarchicalNameAccess>& rxNode,
315  const PresenterTheme::SharedFontDescriptor& rpDefault)
316 {
317  return ReadContext::ReadFont(rxNode, OUString(), rpDefault);
318 }
319 
321  const Any& rColorSequence,
322  sal_uInt32& rColor)
323 {
324  Sequence<sal_Int8> aByteSequence;
325  if (rColorSequence >>= aByteSequence)
326  {
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;
330  }
331  else
332  return false;
333 }
334 
335 std::shared_ptr<PresenterConfigurationAccess> PresenterTheme::GetNodeForViewStyle (
336  const OUString& rsStyleName) const
337 {
338  if (mpTheme == nullptr)
339  return std::shared_ptr<PresenterConfigurationAccess>();
340 
341  // Open configuration for writing.
342  auto pConfiguration = std::make_shared<PresenterConfigurationAccess>(
343  mxContext,
344  "/org.openoffice.Office.PresenterScreen/",
346 
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")))
351  {
352  pConfiguration->GoToChild(
353  [&rsStyleName] (OUString const&, uno::Reference<beans::XPropertySet> const& xProps)
354  {
356  rsStyleName, "StyleName", xProps);
357  });
358  }
359  return pConfiguration;
360 }
361 
363  const OUString& rsStyleName,
364  const OUString& rsBitmapName) const
365 {
366  if (mpTheme != nullptr)
367  {
368  if (rsStyleName.isEmpty())
369  {
370  if (rsBitmapName == "Background")
371  {
372  std::shared_ptr<Theme> pTheme (mpTheme);
373  while (pTheme != nullptr && pTheme->mpBackground.get() == nullptr)
374  pTheme = pTheme->mpParentTheme;
375  if (pTheme != nullptr)
376  return pTheme->mpBackground;
377  else
378  return SharedBitmapDescriptor();
379  }
380  }
381  else
382  {
383  SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName));
384  if (pPaneStyle.get() != nullptr)
385  {
386  SharedBitmapDescriptor pBitmap (pPaneStyle->GetBitmap(rsBitmapName));
387  if (pBitmap.get() != nullptr)
388  return pBitmap;
389  }
390 
391  SharedViewStyle pViewStyle (mpTheme->GetViewStyle(rsStyleName));
392  if (pViewStyle.get() != nullptr)
393  {
394  SharedBitmapDescriptor pBitmap (pViewStyle->GetBitmap(rsBitmapName));
395  if (pBitmap.get() != nullptr)
396  return pBitmap;
397  }
398  }
399  }
400 
401  return SharedBitmapDescriptor();
402 }
403 
405  const OUString& rsBitmapName) const
406 {
407  if (mpTheme != nullptr)
408  {
409  if (rsBitmapName == "Background")
410  {
411  std::shared_ptr<Theme> pTheme (mpTheme);
412  while (pTheme != nullptr && pTheme->mpBackground.get() == nullptr)
413  pTheme = pTheme->mpParentTheme;
414  if (pTheme != nullptr)
415  return pTheme->mpBackground;
416  else
417  return SharedBitmapDescriptor();
418  }
419  else
420  {
421  if (mpTheme->mpIconContainer != nullptr)
422  return mpTheme->mpIconContainer->GetBitmap(rsBitmapName);
423  }
424  }
425 
426  return SharedBitmapDescriptor();
427 }
428 
429 std::shared_ptr<PresenterBitmapContainer> PresenterTheme::GetBitmapContainer() const
430 {
431  if (mpTheme != nullptr)
432  return mpTheme->mpIconContainer;
433  else
434  return std::shared_ptr<PresenterBitmapContainer>();
435 }
436 
438  const OUString& rsStyleName) const
439 {
440  if (mpTheme != nullptr)
441  {
442  SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName));
443  if (pPaneStyle.get() != nullptr)
444  return pPaneStyle->GetFont();
445 
446  SharedViewStyle pViewStyle (mpTheme->GetViewStyle(rsStyleName));
447  if (pViewStyle.get() != nullptr)
448  return pViewStyle->GetFont();
449 
450  std::shared_ptr<Theme> pTheme (mpTheme);
451  while (pTheme != nullptr)
452  {
453  Theme::FontContainer::const_iterator iFont (pTheme->maFontContainer.find(rsStyleName));
454  if (iFont != pTheme->maFontContainer.end())
455  return iFont->second;
456 
457  pTheme = pTheme->mpParentTheme;
458  }
459  }
460 
461  return SharedFontDescriptor();
462 }
463 
464 //===== FontDescriptor ========================================================
465 
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)
475 {
476  if (rpDescriptor != nullptr)
477  {
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;
485  }
486 }
487 
489  const Reference<rendering::XCanvas>& rxCanvas)
490 {
491  if (mxFont.is())
492  return true;
493 
494  if ( ! rxCanvas.is())
495  return false;
496 
497  const double nCellSize (GetCellSizeForDesignSize(rxCanvas, mnSize));
498  mxFont = CreateFont(rxCanvas, nCellSize);
499 
500  return mxFont.is();
501 }
502 
503 Reference<rendering::XCanvasFont> PresenterTheme::FontDescriptor::CreateFont (
504  const Reference<rendering::XCanvas>& rxCanvas,
505  const double nCellSize) const
506 {
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;
513 
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;
518 
519  return rxCanvas->createFont(
520  aFontRequest,
522  geometry::Matrix2D(1,0,0,1));
523 }
524 
526  const Reference<rendering::XCanvas>& rxCanvas,
527  const double nDesignSize) const
528 {
529  // Use the given design size as initial value in calculating the cell
530  // size.
531  double nCellSize (nDesignSize);
532 
533  if ( ! rxCanvas.is())
534  {
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;
538  }
539 
540  Reference<rendering::XCanvasFont> xFont (CreateFont(rxCanvas, nCellSize));
541  if ( ! xFont.is())
542  return nDesignSize;
543 
544  geometry::RealRectangle2D aBox (PresenterCanvasHelper::GetTextBoundingBox (xFont, "X"));
545 
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;
553 }
554 
555 //===== Theme =================================================================
556 
558  const Reference<container::XHierarchicalNameAccess>& rxThemeRoot,
559  const OUString& rsNodeName)
560  : msConfigurationNodeName(rsNodeName),
561  mpParentTheme(),
562  maPaneStyles(),
563  maViewStyles(),
565  mxThemeRoot(rxThemeRoot),
566  mpIconContainer()
567 {
568 }
569 
571  PresenterConfigurationAccess& rConfiguration,
572  ReadContext& rReadContext)
573 {
574  // Parent theme name.
575  OUString sParentThemeName;
576  if ((PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, "ParentTheme")
577  >>= sParentThemeName)
578  && !sParentThemeName.isEmpty())
579  {
580  mpParentTheme = rReadContext.ReadTheme(rConfiguration, sParentThemeName);
581  }
582 
583  // Background.
585  mxThemeRoot,
586  "Background",
587  rReadContext.mxPresenterHelper,
588  rReadContext.mxCanvas,
590 
591  // Style associations.
592  maStyleAssociations.Read(mxThemeRoot);
593 
594  // Pane styles.
595  maPaneStyles.Read(rReadContext, mxThemeRoot);
596 
597  // View styles.
598  maViewStyles.Read(rReadContext, mxThemeRoot);
599 
600  // Read bitmaps.
601  mpIconContainer.reset(new PresenterBitmapContainer(
603  PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, "Bitmaps"), UNO_QUERY),
604  mpParentTheme != nullptr ? mpParentTheme->mpIconContainer
605  : std::shared_ptr<PresenterBitmapContainer>(),
606  rReadContext.mxComponentContext, rReadContext.mxCanvas));
607 
608  // Read fonts.
611  UNO_QUERY);
613  xFontNode,
614  [this] (OUString const& rKey, uno::Reference<beans::XPropertySet> const& xProps)
615  {
616  return this->ProcessFont(rKey, xProps);
617  });
618 }
619 
620 SharedPaneStyle PresenterTheme::Theme::GetPaneStyle (const OUString& rsStyleName) const
621 {
622  SharedPaneStyle pPaneStyle (maPaneStyles.GetPaneStyle(rsStyleName));
623  if (pPaneStyle.get() != nullptr)
624  return pPaneStyle;
625  else if (mpParentTheme != nullptr)
626  return mpParentTheme->GetPaneStyle(rsStyleName);
627  else
628  return SharedPaneStyle();
629 }
630 
631 SharedViewStyle PresenterTheme::Theme::GetViewStyle (const OUString& rsStyleName) const
632 {
633  SharedViewStyle pViewStyle (maViewStyles.GetViewStyle(rsStyleName));
634  if (pViewStyle.get() != nullptr)
635  return pViewStyle;
636  else if (mpParentTheme != nullptr)
637  return mpParentTheme->GetViewStyle(rsStyleName);
638  else
639  return SharedViewStyle();
640 }
641 
643  const OUString& rsKey,
644  const Reference<beans::XPropertySet>& rxProperties)
645 {
646  maFontContainer[rsKey] = ReadContext::ReadFont(rxProperties, SharedFontDescriptor());
647 }
648 
649 namespace {
650 
651 //===== ReadContext ===========================================================
652 
653 ReadContext::ReadContext (
654  const css::uno::Reference<css::uno::XComponentContext>& rxContext,
655  const Reference<rendering::XCanvas>& rxCanvas)
656  : mxComponentContext(rxContext),
657  mxCanvas(rxCanvas),
659 {
660  Reference<lang::XMultiComponentFactory> xFactory (rxContext->getServiceManager());
661  if (xFactory.is())
662  {
663  mxPresenterHelper.set(
664  xFactory->createInstanceWithContext(
665  "com.sun.star.comp.Draw.PresenterHelper",
666  rxContext),
667  UNO_QUERY_THROW);
668  }
669 }
670 
671 PresenterTheme::SharedFontDescriptor ReadContext::ReadFont (
672  const Reference<container::XHierarchicalNameAccess>& rxNode,
673  const OUString& rsFontPath,
674  const PresenterTheme::SharedFontDescriptor& rpDefault)
675 {
676  if ( ! rxNode.is())
678 
679  try
680  {
681  Reference<container::XHierarchicalNameAccess> xFont (
683  rxNode,
684  rsFontPath),
685  UNO_QUERY_THROW);
686 
687  Reference<beans::XPropertySet> xProperties (xFont, UNO_QUERY_THROW);
688  return ReadFont(xProperties, rpDefault);
689  }
690  catch (Exception&)
691  {
692  OSL_ASSERT(false);
693  }
694 
696 }
697 
698 PresenterTheme::SharedFontDescriptor ReadContext::ReadFont (
699  const Reference<beans::XPropertySet>& rxProperties,
700  const PresenterTheme::SharedFontDescriptor& rpDefault)
701 {
702  auto pDescriptor = std::make_shared<PresenterTheme::FontDescriptor>(rpDefault);
703 
704  PresenterConfigurationAccess::GetProperty(rxProperties, "FamilyName") >>= pDescriptor->msFamilyName;
705  PresenterConfigurationAccess::GetProperty(rxProperties, "Style") >>= pDescriptor->msStyleName;
706  PresenterConfigurationAccess::GetProperty(rxProperties, "Size") >>= pDescriptor->mnSize;
708  PresenterConfigurationAccess::GetProperty(rxProperties, "Color"),
709  pDescriptor->mnColor);
710  PresenterConfigurationAccess::GetProperty(rxProperties, "Anchor") >>= pDescriptor->msAnchor;
711  PresenterConfigurationAccess::GetProperty(rxProperties, "XOffset") >>= pDescriptor->mnXOffset;
712  PresenterConfigurationAccess::GetProperty(rxProperties, "YOffset") >>= pDescriptor->mnYOffset;
713 
714  return pDescriptor;
715 }
716 
717 Any ReadContext::GetByName (
718  const Reference<container::XNameAccess>& rxNode,
719  const OUString& rsName)
720 {
721  OSL_ASSERT(rxNode.is());
722  if (rxNode->hasByName(rsName))
723  return rxNode->getByName(rsName);
724  else
725  return Any();
726 }
727 
728 std::shared_ptr<PresenterTheme::Theme> ReadContext::ReadTheme (
729  PresenterConfigurationAccess& rConfiguration,
730  const OUString& rsThemeName)
731 {
732  std::shared_ptr<PresenterTheme::Theme> pTheme;
733 
734  OUString sCurrentThemeName (rsThemeName);
735  if (sCurrentThemeName.isEmpty())
736  {
737  // No theme name given. Look up the CurrentTheme property.
738  rConfiguration.GetConfigurationNode("Presenter/CurrentTheme") >>= sCurrentThemeName;
739  if (sCurrentThemeName.isEmpty())
740  {
741  // Still no name. Use "DefaultTheme".
742  sCurrentThemeName = "DefaultTheme";
743  }
744  }
745 
747  rConfiguration.GetConfigurationNode("Presenter/Themes"),
748  UNO_QUERY);
749  if (xThemes.is())
750  {
751  // Iterate over all themes and search the one with the given name.
752  const Sequence<OUString> aKeys (xThemes->getElementNames());
753  for (const OUString& rsKey : aKeys)
754  {
755  Reference<container::XHierarchicalNameAccess> xTheme (
756  xThemes->getByName(rsKey), UNO_QUERY);
757  if (xTheme.is())
758  {
759  OUString sThemeName;
761  >>= sThemeName;
762  if (sThemeName == sCurrentThemeName)
763  {
764  pTheme.reset(new PresenterTheme::Theme(xTheme,rsKey));
765  break;
766  }
767  }
768  }
769  }
770 
771  if (pTheme != nullptr)
772  {
773  pTheme->Read(rConfiguration, *this);
774  }
775 
776  return pTheme;
777 }
778 
779 BorderSize ReadContext::ReadBorderSize (const Reference<container::XNameAccess>& rxNode)
780 {
781  BorderSize aBorderSize;
782 
783  if (rxNode.is())
784  {
785  GetByName(rxNode, "Left") >>= aBorderSize.mnLeft;
786  GetByName(rxNode, "Top") >>= aBorderSize.mnTop;
787  GetByName(rxNode, "Right") >>= aBorderSize.mnRight;
788  GetByName(rxNode, "Bottom") >>= aBorderSize.mnBottom;
789  }
790 
791  return aBorderSize;
792 }
793 
794 //===== PaneStyleContainer ====================================================
795 
796 void PaneStyleContainer::Read (
797  const ReadContext& rReadContext,
798  const Reference<container::XHierarchicalNameAccess>& rxThemeRoot)
799 {
800  Reference<container::XNameAccess> xPaneStyleList (
802  rxThemeRoot,
803  "PaneStyles"),
804  UNO_QUERY);
805  if (!xPaneStyleList.is())
806  return;
807 
808  ::std::vector<OUString> aProperties;
809  aProperties.reserve(6);
810  aProperties.emplace_back("StyleName");
811  aProperties.emplace_back("ParentStyle");
812  aProperties.emplace_back("TitleFont");
813  aProperties.emplace_back("InnerBorderSize");
814  aProperties.emplace_back("OuterBorderSize");
815  aProperties.emplace_back("BorderBitmapList");
817  xPaneStyleList,
818  aProperties,
819  [this, &rReadContext] (std::vector<uno::Any> const& rValues)
820  {
821  return this->ProcessPaneStyle(rReadContext, rValues);
822  });
823 }
824 
825 void PaneStyleContainer::ProcessPaneStyle(
826  ReadContext const & rReadContext,
827  const ::std::vector<Any>& rValues)
828 {
829  if (rValues.size() != 6)
830  return;
831 
832  auto pStyle = std::make_shared<PaneStyle>();
833 
834  rValues[0] >>= pStyle->msStyleName;
835 
836  OUString sParentStyleName;
837  if (rValues[1] >>= sParentStyleName)
838  {
839  // Find parent style.
840  auto iStyle = std::find_if(mStyles.begin(), mStyles.end(),
841  [&sParentStyleName](const SharedPaneStyle& rxStyle) { return rxStyle->msStyleName == sParentStyleName; });
842  if (iStyle != mStyles.end())
843  pStyle->mpParentStyle = *iStyle;
844  }
845 
846  Reference<container::XHierarchicalNameAccess> xFontNode (rValues[2], UNO_QUERY);
847  pStyle->mpFont = ReadContext::ReadFont(
848  xFontNode, "", PresenterTheme::SharedFontDescriptor());
849 
850  Reference<container::XNameAccess> xInnerBorderSizeNode (rValues[3], UNO_QUERY);
851  pStyle->maInnerBorderSize = ReadContext::ReadBorderSize(xInnerBorderSizeNode);
852  Reference<container::XNameAccess> xOuterBorderSizeNode (rValues[4], UNO_QUERY);
853  pStyle->maOuterBorderSize = ReadContext::ReadBorderSize(xOuterBorderSizeNode);
854 
855  if (pStyle->mpParentStyle != nullptr)
856  {
857  pStyle->maInnerBorderSize.Merge(pStyle->mpParentStyle->maInnerBorderSize);
858  pStyle->maOuterBorderSize.Merge(pStyle->mpParentStyle->maOuterBorderSize);
859  }
860 
861  if (rReadContext.mxCanvas.is())
862  {
863  Reference<container::XNameAccess> xBitmapsNode (rValues[5], UNO_QUERY);
864  pStyle->mpBitmaps.reset(new PresenterBitmapContainer(
865  xBitmapsNode,
866  pStyle->mpParentStyle != nullptr ? pStyle->mpParentStyle->mpBitmaps
867  : std::shared_ptr<PresenterBitmapContainer>(),
868  rReadContext.mxComponentContext, rReadContext.mxCanvas,
869  rReadContext.mxPresenterHelper));
870  }
871 
872  mStyles.push_back(pStyle);
873 }
874 
875 SharedPaneStyle PaneStyleContainer::GetPaneStyle (const OUString& rsStyleName) const
876 {
877  auto iStyle = std::find_if(mStyles.begin(), mStyles.end(),
878  [&rsStyleName](const SharedPaneStyle& rxStyle) { return rxStyle->msStyleName == rsStyleName; });
879  if (iStyle != mStyles.end())
880  return *iStyle;
881  return SharedPaneStyle();
882 }
883 
884 //===== PaneStyle =============================================================
885 
886 PaneStyle::PaneStyle()
887  : msStyleName(),
888  mpParentStyle(),
889  mpFont(),
892  mpBitmaps()
893 {
894 }
895 
896 SharedBitmapDescriptor PaneStyle::GetBitmap (const OUString& rsBitmapName) const
897 {
898  if (mpBitmaps != nullptr)
899  {
900  SharedBitmapDescriptor pBitmap = mpBitmaps->GetBitmap(rsBitmapName);
901  if (pBitmap.get() != nullptr)
902  return pBitmap;
903  }
904 
905  if (mpParentStyle != nullptr)
906  return mpParentStyle->GetBitmap(rsBitmapName);
907  else
908  return SharedBitmapDescriptor();
909 }
910 
911 PresenterTheme::SharedFontDescriptor PaneStyle::GetFont() const
912 {
913  if (mpFont.get() != nullptr)
914  return mpFont;
915  else if (mpParentStyle != nullptr)
916  return mpParentStyle->GetFont();
917  else
919 }
920 
921 //===== ViewStyleContainer ====================================================
922 
923 void ViewStyleContainer::Read (
924  const ReadContext& rReadContext,
925  const Reference<container::XHierarchicalNameAccess>& rxThemeRoot)
926 {
927  Reference<container::XNameAccess> xViewStyleList (
929  rxThemeRoot,
930  "ViewStyles"),
931  UNO_QUERY);
932  if (xViewStyleList.is())
933  {
935  xViewStyleList,
936  [this, &rReadContext] (OUString const&, uno::Reference<beans::XPropertySet> const& xProps)
937  {
938  return this->ProcessViewStyle(rReadContext, xProps);
939  });
940  }
941 }
942 
943 void ViewStyleContainer::ProcessViewStyle(
944  ReadContext const & rReadContext,
945  const Reference<beans::XPropertySet>& rxProperties)
946 {
947  auto pStyle = std::make_shared<ViewStyle>();
948 
949  PresenterConfigurationAccess::GetProperty(rxProperties, "StyleName")
950  >>= pStyle->msStyleName;
951 
952  OUString sParentStyleName;
953  if (PresenterConfigurationAccess::GetProperty(rxProperties, "ParentStyle")
954  >>= sParentStyleName)
955  {
956  // Find parent style.
957  auto iStyle = std::find_if(mStyles.begin(), mStyles.end(),
958  [&sParentStyleName](const SharedViewStyle& rxStyle) { return rxStyle->msStyleName == sParentStyleName; });
959  if (iStyle != mStyles.end())
960  {
961  pStyle->mpParentStyle = *iStyle;
962  pStyle->mpFont = (*iStyle)->mpFont;
963  pStyle->mpBackground = (*iStyle)->mpBackground;
964  }
965  }
966 
967  const OUString sPathToFont; // empty string
968  Reference<container::XHierarchicalNameAccess> xFontNode (
969  PresenterConfigurationAccess::GetProperty(rxProperties, "Font"), UNO_QUERY);
971  ReadContext::ReadFont(xFontNode, sPathToFont, PresenterTheme::SharedFontDescriptor()));
972  if (pFont.get() != nullptr)
973  pStyle->mpFont = pFont;
974 
975  Reference<container::XHierarchicalNameAccess> xBackgroundNode (
976  PresenterConfigurationAccess::GetProperty(rxProperties, "Background"),
977  UNO_QUERY);
979  xBackgroundNode,
980  OUString(),
981  rReadContext.mxPresenterHelper,
982  rReadContext.mxCanvas,
984  if (pBackground.get() != nullptr && pBackground->GetNormalBitmap().is())
985  pStyle->mpBackground = pBackground;
986 
987  mStyles.push_back(pStyle);
988 }
989 
990 SharedViewStyle ViewStyleContainer::GetViewStyle (const OUString& rsStyleName) const
991 {
992  auto iStyle = std::find_if(mStyles.begin(), mStyles.end(),
993  [&rsStyleName](const SharedViewStyle& rxStyle) { return rxStyle->msStyleName == rsStyleName; });
994  if (iStyle != mStyles.end())
995  return *iStyle;
996  return SharedViewStyle();
997 }
998 
999 //===== ViewStyle =============================================================
1000 
1001 ViewStyle::ViewStyle()
1002  : msStyleName(),
1003  mpParentStyle(),
1004  mpFont(),
1005  mpBackground()
1006 {
1007 }
1008 
1009 SharedBitmapDescriptor ViewStyle::GetBitmap (const OUString& rsBitmapName) const
1010 {
1011  if (rsBitmapName == "Background")
1012  return mpBackground;
1013  else
1014  return SharedBitmapDescriptor();
1015 }
1016 
1017 PresenterTheme::SharedFontDescriptor ViewStyle::GetFont() const
1018 {
1019  if (mpFont.get() != nullptr)
1020  return mpFont;
1021  else if (mpParentStyle != nullptr)
1022  return mpParentStyle->GetFont();
1023  else
1025 }
1026 
1027 //===== StyleAssociationContainer =============================================
1028 
1029 void StyleAssociationContainer::Read (
1030  const Reference<container::XHierarchicalNameAccess>& rxThemeRoot)
1031 {
1032  Reference<container::XNameAccess> xStyleAssociationList (
1034  rxThemeRoot,
1035  "StyleAssociations"),
1036  UNO_QUERY);
1037  if (!xStyleAssociationList.is())
1038  return;
1039 
1040  ::std::vector<OUString> aProperties (2);
1041  aProperties[0] = "ResourceURL";
1042  aProperties[1] = "StyleName";
1044  xStyleAssociationList,
1045  aProperties,
1046  [this] (std::vector<uno::Any> const& rValues)
1047  {
1048  return this->ProcessStyleAssociation(rValues);
1049  });
1050 }
1051 
1052 OUString StyleAssociationContainer::GetStyleName (const OUString& rsResourceName) const
1053 {
1054  StyleAssociations::const_iterator iAssociation (maStyleAssociations.find(rsResourceName));
1055  if (iAssociation != maStyleAssociations.end())
1056  return iAssociation->second;
1057  else
1058  return OUString();
1059 }
1060 
1061 void StyleAssociationContainer::ProcessStyleAssociation(
1062  const ::std::vector<Any>& rValues)
1063 {
1064  if (rValues.size() != 2)
1065  return;
1066 
1067  OUString sResourceURL;
1068  OUString sStyleName;
1069  if ((rValues[0] >>= sResourceURL)
1070  && (rValues[1] >>= sStyleName))
1071  {
1072  maStyleAssociations[sResourceURL] = sStyleName;
1073  }
1074 }
1075 
1076 } // end of anonymous namespace
1077 
1078 } } // end of namespace ::sdext::presenter
1079 
1080 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static void ForAll(const css::uno::Reference< css::container::XNameAccess > &rxContainer, const ::std::vector< OUString > &rArguments, const ItemProcessor &rProcessor)
Execute a functor for all elements of the given container.
::std::vector< sal_Int32 > GetBorderSize(const OUString &rsStyleName, const bool bOuter) const
Reference< rendering::XCanvas > mxCanvas
BorderSize maOuterBorderSize
std::shared_ptr< FontDescriptor > SharedFontDescriptor
static css::uno::Any GetProperty(const css::uno::Reference< css::beans::XPropertySet > &rxProperties, const OUString &rsKey)
This method wraps a call to getPropertyValue() and returns an empty Any instead of throwing an except...
map< OUString, SharedFontDescriptor > FontContainer
SharedBitmapDescriptor mpBackground
std::shared_ptr< PresenterBitmapContainer > mpIconContainer
sal_Int32 mnLeft
PresenterTheme(const css::uno::Reference< css::uno::XComponentContext > &rxContext, const css::uno::Reference< css::rendering::XCanvas > &rxCanvas)
Theme(const Reference< container::XHierarchicalNameAccess > &rThemeRoot, const OUString &rsNodeName)
::std::vector< SharedPaneStyle > mStyles
FontDescriptor(const std::shared_ptr< FontDescriptor > &rpDescriptor)
std::shared_ptr< PresenterConfigurationAccess > GetNodeForViewStyle(const OUString &rsStyleName) const
std::shared_ptr< Theme > mpTheme
uno::Reference< rendering::XCanvasFont > mxFont
Reference< XComponentContext > mxComponentContext
bool PrepareFont(const css::uno::Reference< css::rendering::XCanvas > &rxCanvas)
std::shared_ptr< PresenterBitmapContainer::BitmapDescriptor > SharedBitmapDescriptor
sal_Int32 mnBottom
SharedBitmapDescriptor GetBitmap(const OUString &rsStyleName, const OUString &rsBitmapName) const
Reference< drawing::XPresenterHelper > mxPresenterHelper
PropertiesInfo aProperties
This class gives access to the configuration.
std::shared_ptr< PresenterBitmapContainer > mpBitmaps
if(nullptr==pCandidateA||nullptr==pCandidateB)
double GetCellSizeForDesignSize(const css::uno::Reference< css::rendering::XCanvas > &rxCanvas, const double nDesignSize) const
SharedPaneStyle GetPaneStyle(const OUString &rsStyleName) const
OUString msStyleName
sal_Int32 mnRight
SharedViewStyle GetViewStyle(const OUString &rsStyleName) const
void Read(PresenterConfigurationAccess &rConfiguration, ReadContext &rReadContext)
static const sal_Int32 mnInvalidValue
static bool ConvertToColor(const css::uno::Any &rColorSequence, sal_uInt32 &rColor)
static SharedFontDescriptor ReadFont(const css::uno::Reference< css::container::XHierarchicalNameAccess > &rxNode, const SharedFontDescriptor &rDefaultFount)
BorderSize maInnerBorderSize
void CreateFont(SvxFont &rFont, const SfxItemSet &rSet, bool bSearchInParent, SvtScriptType nScriptType)
StyleAssociationContainer maStyleAssociations
css::uno::Any GetConfigurationNode(const OUString &rsPathToNode)
Return a configuration node below the root of the called object.
css::uno::Reference< css::rendering::XCanvasFont > CreateFont(const css::uno::Reference< css::rendering::XCanvas > &rxCanvas, const double nCellSize) const
css::uno::Reference< css::rendering::XCanvas > mxCanvas
std::shared_ptr< Theme > ReadTheme()
void ProvideCanvas(const css::uno::Reference< css::rendering::XCanvas > &rxCanvas)
sal_uInt32 const mnSize
PresenterTheme::SharedFontDescriptor mpFont
SharedFontDescriptor GetFont(const OUString &rsStyleName) const
OUString GetStyleName(const OUString &rsResourceURL) const
static std::shared_ptr< BitmapDescriptor > LoadBitmap(const css::uno::Reference< css::container::XHierarchicalNameAccess > &rxNode, const OUString &rsPathToBitmapNode, const css::uno::Reference< css::drawing::XPresenterHelper > &rxPresenterHelper, const css::uno::Reference< css::rendering::XCanvas > &rxCanvas, const std::shared_ptr< BitmapDescriptor > &rpDefaultBitmap)
unsigned char sal_uInt8
SvStream & ReadFont(SvStream &rIStm, vcl::Font &rFont)
std::shared_ptr< PaneStyle > mpParentStyle
sal_Int32 mnTop
void ProcessFont(const OUString &rsKey, const Reference< beans::XPropertySet > &rxProperties)
StyleAssociations maStyleAssociations
static bool IsStringPropertyEqual(const OUString &rsValue, const OUString &rsPropertyName, const css::uno::Reference< css::beans::XPropertySet > &rxNode)
css::uno::Reference< css::uno::XComponentContext > mxContext
Reference< container::XHierarchicalNameAccess > mxThemeRoot
static css::geometry::RealRectangle2D GetTextBoundingBox(const css::uno::Reference< css::rendering::XCanvasFont > &rxFont, const OUString &rsText, const sal_Int8=css::rendering::TextDirection::WEAK_LEFT_TO_RIGHT)
Reference< XSingleServiceFactory > xFactory
std::shared_ptr< PresenterBitmapContainer > GetBitmapContainer() const
Color mnColor
Reference< XComponentContext > mxContext
Manage a set of bitmap groups as they are used for buttons: three bitmaps, one for the normal state...