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"
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>
29
30 using namespace ::com::sun::star;
31 using namespace ::com::sun::star::uno;
32 using namespace ::std;
33
34 namespace sdext::presenter {
35
36 namespace {
37
38 class BorderSize
39 {
40 public:
41 const static sal_Int32 mnInvalidValue = -10000;
42
BorderSize()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
ToVector()53 vector<sal_Int32> ToVector()
54 {
55 return
56 {
57 mnLeft == mnInvalidValue ? 0 : mnLeft,
58 mnTop == mnInvalidValue ? 0 : mnTop,
59 mnRight == mnInvalidValue ? 0 : mnRight,
60 mnBottom == mnInvalidValue ? 0 : mnBottom
61 };
62 };
63
Merge(const BorderSize & rBorderSize)64 void Merge (const BorderSize& rBorderSize)
65 {
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;
74 }
75 };
76
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.
80 */
81 class ReadContext
82 {
83 public:
84 Reference<XComponentContext> mxComponentContext;
85 Reference<rendering::XCanvas> mxCanvas;
86 Reference<drawing::XPresenterHelper> mxPresenterHelper;
87
88 ReadContext (
89 const Reference<XComponentContext>& rxContext,
90 const Reference<rendering::XCanvas>& rxCanvas);
91
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.
96 */
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);
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
116 /** A PaneStyle describes how a pane is rendered.
117 */
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;
127 PresenterTheme::SharedFontDescriptor mpFont;
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
155 /** A ViewStyle describes how a view is displayed.
156 */
157 class ViewStyle
158 {
159 public:
160 ViewStyle();
161
162 SharedBitmapDescriptor GetBitmap (std::u16string_view sBitmapName) const;
163
164 PresenterTheme::SharedFontDescriptor GetFont() const;
165
166 OUString msStyleName;
167 std::shared_ptr<ViewStyle> mpParentStyle;
168 PresenterTheme::SharedFontDescriptor mpFont;
169 SharedBitmapDescriptor mpBackground;
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
210 class PresenterTheme::Theme
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 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;
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
PresenterTheme(const css::uno::Reference<css::uno::XComponentContext> & rxContext,const css::uno::Reference<css::rendering::XCanvas> & rxCanvas)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)
249 {
250 mpTheme = ReadTheme();
251 }
252
~PresenterTheme()253 PresenterTheme::~PresenterTheme()
254 {
255 }
256
ReadTheme()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/",
264 PresenterConfigurationAccess::READ_ONLY);
265
266 return aReadContext.ReadTheme(aConfiguration, OUString());
267 }
268
HasCanvas() const269 bool PresenterTheme::HasCanvas() const
270 {
271 return mxCanvas.is();
272 }
273
ProvideCanvas(const Reference<rendering::XCanvas> & rxCanvas)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
GetStyleName(const OUString & rsResourceURL) const283 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
GetBorderSize(const OUString & rsStyleName,const bool bOuter) const295 ::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)
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
ReadFont(const Reference<container::XHierarchicalNameAccess> & rxNode,const PresenterTheme::SharedFontDescriptor & rpDefault)313 PresenterTheme::SharedFontDescriptor PresenterTheme::ReadFont (
314 const Reference<container::XHierarchicalNameAccess>& rxNode,
315 const PresenterTheme::SharedFontDescriptor& rpDefault)
316 {
317 return ReadContext::ReadFont(rxNode, rpDefault);
318 }
319
ConvertToColor(const Any & rColorSequence,sal_uInt32 & rColor)320 bool PresenterTheme::ConvertToColor (
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
GetNodeForViewStyle(const OUString & rsStyleName) const335 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/",
345 PresenterConfigurationAccess::READ_WRITE);
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 {
355 return PresenterConfigurationAccess::IsStringPropertyEqual(
356 rsStyleName, "StyleName", xProps);
357 });
358 }
359 return pConfiguration;
360 }
361
GetBitmap(const OUString & rsStyleName,const OUString & rsBitmapName) const362 SharedBitmapDescriptor PresenterTheme::GetBitmap (
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)
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)
385 {
386 SharedBitmapDescriptor pBitmap (pPaneStyle->GetBitmap(rsBitmapName));
387 if (pBitmap)
388 return pBitmap;
389 }
390
391 SharedViewStyle pViewStyle (mpTheme->GetViewStyle(rsStyleName));
392 if (pViewStyle)
393 {
394 SharedBitmapDescriptor pBitmap (pViewStyle->GetBitmap(rsBitmapName));
395 if (pBitmap)
396 return pBitmap;
397 }
398 }
399 }
400
401 return SharedBitmapDescriptor();
402 }
403
GetBitmap(const OUString & rsBitmapName) const404 SharedBitmapDescriptor PresenterTheme::GetBitmap (
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)
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
GetBitmapContainer() const429 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
GetFont(const OUString & rsStyleName) const437 PresenterTheme::SharedFontDescriptor PresenterTheme::GetFont (
438 const OUString& rsStyleName) const
439 {
440 if (mpTheme != nullptr)
441 {
442 SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName));
443 if (pPaneStyle)
444 return pPaneStyle->GetFont();
445
446 SharedViewStyle pViewStyle (mpTheme->GetViewStyle(rsStyleName));
447 if (pViewStyle)
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
FontDescriptor(const std::shared_ptr<FontDescriptor> & rpDescriptor)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)
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
PrepareFont(const Reference<rendering::XCanvas> & rxCanvas)488 bool PresenterTheme::FontDescriptor::PrepareFont (
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
CreateFont(const Reference<rendering::XCanvas> & rxCanvas,const double nCellSize) const503 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,
521 Sequence<beans::PropertyValue>(),
522 geometry::Matrix2D(1,0,0,1));
523 }
524
GetCellSizeForDesignSize(const Reference<rendering::XCanvas> & rxCanvas,const double nDesignSize) const525 double PresenterTheme::FontDescriptor::GetCellSizeForDesignSize (
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
Theme(const Reference<container::XHierarchicalNameAccess> & rxThemeRoot,const OUString & rsNodeName)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()
567 {
568 }
569
Read(PresenterConfigurationAccess & rConfiguration,ReadContext & rReadContext)570 void PresenterTheme::Theme::Read (
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.
584 mpBackground = PresenterBitmapContainer::LoadBitmap(
585 mxThemeRoot,
586 "Background",
587 rReadContext.mxPresenterHelper,
588 rReadContext.mxCanvas,
589 SharedBitmapDescriptor());
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 = 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);
607
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)
615 {
616 return this->ProcessFont(rKey, xProps);
617 });
618 }
619
GetPaneStyle(const OUString & rsStyleName) const620 SharedPaneStyle PresenterTheme::Theme::GetPaneStyle (const OUString& rsStyleName) const
621 {
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();
629 }
630
GetViewStyle(const OUString & rsStyleName) const631 SharedViewStyle PresenterTheme::Theme::GetViewStyle (const OUString& rsStyleName) const
632 {
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();
640 }
641
ProcessFont(const OUString & rsKey,const Reference<beans::XPropertySet> & rxProperties)642 void PresenterTheme::Theme::ProcessFont(
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
ReadContext(const css::uno::Reference<css::uno::XComponentContext> & rxContext,const Reference<rendering::XCanvas> & rxCanvas)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()
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
ReadFont(const Reference<container::XHierarchicalNameAccess> & rxNode,const PresenterTheme::SharedFontDescriptor & rpDefault)671 PresenterTheme::SharedFontDescriptor ReadContext::ReadFont (
672 const Reference<container::XHierarchicalNameAccess>& rxNode,
673 const PresenterTheme::SharedFontDescriptor& rpDefault)
674 {
675 if ( ! rxNode.is())
676 return PresenterTheme::SharedFontDescriptor();
677
678 try
679 {
680 Reference<container::XHierarchicalNameAccess> xFont (
681 PresenterConfigurationAccess::GetConfigurationNode(
682 rxNode,
683 /*rsFontPath*/""),
684 UNO_QUERY_THROW);
685
686 Reference<beans::XPropertySet> xProperties (xFont, UNO_QUERY_THROW);
687 return ReadFont(xProperties, rpDefault);
688 }
689 catch (Exception&)
690 {
691 OSL_ASSERT(false);
692 }
693
694 return PresenterTheme::SharedFontDescriptor();
695 }
696
ReadFont(const Reference<beans::XPropertySet> & rxProperties,const PresenterTheme::SharedFontDescriptor & rpDefault)697 PresenterTheme::SharedFontDescriptor ReadContext::ReadFont (
698 const Reference<beans::XPropertySet>& rxProperties,
699 const PresenterTheme::SharedFontDescriptor& rpDefault)
700 {
701 auto pDescriptor = std::make_shared<PresenterTheme::FontDescriptor>(rpDefault);
702
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;
712
713 return pDescriptor;
714 }
715
GetByName(const Reference<container::XNameAccess> & rxNode,const OUString & rsName)716 Any ReadContext::GetByName (
717 const Reference<container::XNameAccess>& rxNode,
718 const OUString& rsName)
719 {
720 OSL_ASSERT(rxNode.is());
721 if (rxNode->hasByName(rsName))
722 return rxNode->getByName(rsName);
723 else
724 return Any();
725 }
726
ReadTheme(PresenterConfigurationAccess & rConfiguration,const OUString & rsThemeName)727 std::shared_ptr<PresenterTheme::Theme> ReadContext::ReadTheme (
728 PresenterConfigurationAccess& rConfiguration,
729 const OUString& rsThemeName)
730 {
731 std::shared_ptr<PresenterTheme::Theme> pTheme;
732
733 OUString sCurrentThemeName (rsThemeName);
734 if (sCurrentThemeName.isEmpty())
735 {
736 // No theme name given. Look up the CurrentTheme property.
737 rConfiguration.GetConfigurationNode("Presenter/CurrentTheme") >>= sCurrentThemeName;
738 if (sCurrentThemeName.isEmpty())
739 {
740 // Still no name. Use "DefaultTheme".
741 sCurrentThemeName = "DefaultTheme";
742 }
743 }
744
745 Reference<container::XNameAccess> xThemes (
746 rConfiguration.GetConfigurationNode("Presenter/Themes"),
747 UNO_QUERY);
748 if (xThemes.is())
749 {
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)
753 {
754 Reference<container::XHierarchicalNameAccess> xTheme (
755 xThemes->getByName(rsKey), UNO_QUERY);
756 if (xTheme.is())
757 {
758 OUString sThemeName;
759 PresenterConfigurationAccess::GetConfigurationNode(xTheme, "ThemeName")
760 >>= sThemeName;
761 if (sThemeName == sCurrentThemeName)
762 {
763 pTheme = std::make_shared<PresenterTheme::Theme>(xTheme,rsKey);
764 break;
765 }
766 }
767 }
768 }
769
770 if (pTheme != nullptr)
771 {
772 pTheme->Read(rConfiguration, *this);
773 }
774
775 return pTheme;
776 }
777
ReadBorderSize(const Reference<container::XNameAccess> & rxNode)778 BorderSize ReadContext::ReadBorderSize (const Reference<container::XNameAccess>& rxNode)
779 {
780 BorderSize aBorderSize;
781
782 if (rxNode.is())
783 {
784 GetByName(rxNode, "Left") >>= aBorderSize.mnLeft;
785 GetByName(rxNode, "Top") >>= aBorderSize.mnTop;
786 GetByName(rxNode, "Right") >>= aBorderSize.mnRight;
787 GetByName(rxNode, "Bottom") >>= aBorderSize.mnBottom;
788 }
789
790 return aBorderSize;
791 }
792
793 //===== PaneStyleContainer ====================================================
794
Read(const ReadContext & rReadContext,const Reference<container::XHierarchicalNameAccess> & rxThemeRoot)795 void PaneStyleContainer::Read (
796 const ReadContext& rReadContext,
797 const Reference<container::XHierarchicalNameAccess>& rxThemeRoot)
798 {
799 Reference<container::XNameAccess> xPaneStyleList (
800 PresenterConfigurationAccess::GetConfigurationNode(
801 rxThemeRoot,
802 "PaneStyles"),
803 UNO_QUERY);
804 if (!xPaneStyleList.is())
805 return;
806
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)
819 {
820 return this->ProcessPaneStyle(rReadContext, rValues);
821 });
822 }
823
ProcessPaneStyle(ReadContext const & rReadContext,const::std::vector<Any> & rValues)824 void PaneStyleContainer::ProcessPaneStyle(
825 ReadContext const & rReadContext,
826 const ::std::vector<Any>& rValues)
827 {
828 if (rValues.size() != 6)
829 return;
830
831 auto pStyle = std::make_shared<PaneStyle>();
832
833 rValues[0] >>= pStyle->msStyleName;
834
835 OUString sParentStyleName;
836 if (rValues[1] >>= sParentStyleName)
837 {
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;
843 }
844
845 Reference<container::XHierarchicalNameAccess> xFontNode (rValues[2], UNO_QUERY);
846 pStyle->mpFont = ReadContext::ReadFont(
847 xFontNode, PresenterTheme::SharedFontDescriptor());
848
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);
853
854 if (pStyle->mpParentStyle != nullptr)
855 {
856 pStyle->maInnerBorderSize.Merge(pStyle->mpParentStyle->maInnerBorderSize);
857 pStyle->maOuterBorderSize.Merge(pStyle->mpParentStyle->maOuterBorderSize);
858 }
859
860 if (rReadContext.mxCanvas.is())
861 {
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);
869 }
870
871 mStyles.push_back(pStyle);
872 }
873
GetPaneStyle(const OUString & rsStyleName) const874 SharedPaneStyle PaneStyleContainer::GetPaneStyle (const OUString& rsStyleName) const
875 {
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();
881 }
882
883 //===== PaneStyle =============================================================
884
PaneStyle()885 PaneStyle::PaneStyle()
886 : msStyleName(),
887 mpParentStyle(),
888 mpFont(),
889 maInnerBorderSize(),
890 maOuterBorderSize(),
891 mpBitmaps()
892 {
893 }
894
GetBitmap(const OUString & rsBitmapName) const895 SharedBitmapDescriptor PaneStyle::GetBitmap (const OUString& rsBitmapName) const
896 {
897 if (mpBitmaps != nullptr)
898 {
899 SharedBitmapDescriptor pBitmap = mpBitmaps->GetBitmap(rsBitmapName);
900 if (pBitmap)
901 return pBitmap;
902 }
903
904 if (mpParentStyle != nullptr)
905 return mpParentStyle->GetBitmap(rsBitmapName);
906 else
907 return SharedBitmapDescriptor();
908 }
909
GetFont() const910 PresenterTheme::SharedFontDescriptor PaneStyle::GetFont() const
911 {
912 if (mpFont)
913 return mpFont;
914 else if (mpParentStyle != nullptr)
915 return mpParentStyle->GetFont();
916 else
917 return PresenterTheme::SharedFontDescriptor();
918 }
919
920 //===== ViewStyleContainer ====================================================
921
Read(const ReadContext & rReadContext,const Reference<container::XHierarchicalNameAccess> & rxThemeRoot)922 void ViewStyleContainer::Read (
923 const ReadContext& rReadContext,
924 const Reference<container::XHierarchicalNameAccess>& rxThemeRoot)
925 {
926 Reference<container::XNameAccess> xViewStyleList (
927 PresenterConfigurationAccess::GetConfigurationNode(
928 rxThemeRoot,
929 "ViewStyles"),
930 UNO_QUERY);
931 if (xViewStyleList.is())
932 {
933 PresenterConfigurationAccess::ForAll(
934 xViewStyleList,
935 [this, &rReadContext] (OUString const&, uno::Reference<beans::XPropertySet> const& xProps)
936 {
937 return this->ProcessViewStyle(rReadContext, xProps);
938 });
939 }
940 }
941
ProcessViewStyle(ReadContext const & rReadContext,const Reference<beans::XPropertySet> & rxProperties)942 void ViewStyleContainer::ProcessViewStyle(
943 ReadContext const & rReadContext,
944 const Reference<beans::XPropertySet>& rxProperties)
945 {
946 auto pStyle = std::make_shared<ViewStyle>();
947
948 PresenterConfigurationAccess::GetProperty(rxProperties, "StyleName")
949 >>= pStyle->msStyleName;
950
951 OUString sParentStyleName;
952 if (PresenterConfigurationAccess::GetProperty(rxProperties, "ParentStyle")
953 >>= sParentStyleName)
954 {
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())
959 {
960 pStyle->mpParentStyle = *iStyle;
961 pStyle->mpFont = (*iStyle)->mpFont;
962 pStyle->mpBackground = (*iStyle)->mpBackground;
963 }
964 }
965
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;
972
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;
984
985 mStyles.push_back(pStyle);
986 }
987
GetViewStyle(const OUString & rsStyleName) const988 SharedViewStyle ViewStyleContainer::GetViewStyle (const OUString& rsStyleName) const
989 {
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();
995 }
996
997 //===== ViewStyle =============================================================
998
ViewStyle()999 ViewStyle::ViewStyle()
1000 : msStyleName(),
1001 mpParentStyle(),
1002 mpFont(),
1003 mpBackground()
1004 {
1005 }
1006
GetBitmap(std::u16string_view rsBitmapName) const1007 SharedBitmapDescriptor ViewStyle::GetBitmap (std::u16string_view rsBitmapName) const
1008 {
1009 if (rsBitmapName == u"Background")
1010 return mpBackground;
1011 else
1012 return SharedBitmapDescriptor();
1013 }
1014
GetFont() const1015 PresenterTheme::SharedFontDescriptor ViewStyle::GetFont() const
1016 {
1017 if (mpFont)
1018 return mpFont;
1019 else if (mpParentStyle != nullptr)
1020 return mpParentStyle->GetFont();
1021 else
1022 return PresenterTheme::SharedFontDescriptor();
1023 }
1024
1025 //===== StyleAssociationContainer =============================================
1026
Read(const Reference<container::XHierarchicalNameAccess> & rxThemeRoot)1027 void StyleAssociationContainer::Read (
1028 const Reference<container::XHierarchicalNameAccess>& rxThemeRoot)
1029 {
1030 Reference<container::XNameAccess> xStyleAssociationList (
1031 PresenterConfigurationAccess::GetConfigurationNode(
1032 rxThemeRoot,
1033 "StyleAssociations"),
1034 UNO_QUERY);
1035 if (!xStyleAssociationList.is())
1036 return;
1037
1038 ::std::vector<OUString> aProperties { "ResourceURL", "StyleName" };
1039 PresenterConfigurationAccess::ForAll(
1040 xStyleAssociationList,
1041 aProperties,
1042 [this] (std::vector<uno::Any> const& rValues)
1043 {
1044 return this->ProcessStyleAssociation(rValues);
1045 });
1046 }
1047
GetStyleName(const OUString & rsResourceName) const1048 OUString StyleAssociationContainer::GetStyleName (const OUString& rsResourceName) const
1049 {
1050 StyleAssociations::const_iterator iAssociation (maStyleAssociations.find(rsResourceName));
1051 if (iAssociation != maStyleAssociations.end())
1052 return iAssociation->second;
1053 else
1054 return OUString();
1055 }
1056
ProcessStyleAssociation(const::std::vector<Any> & rValues)1057 void StyleAssociationContainer::ProcessStyleAssociation(
1058 const ::std::vector<Any>& rValues)
1059 {
1060 if (rValues.size() != 2)
1061 return;
1062
1063 OUString sResourceURL;
1064 OUString sStyleName;
1065 if ((rValues[0] >>= sResourceURL)
1066 && (rValues[1] >>= sStyleName))
1067 {
1068 maStyleAssociations[sResourceURL] = sStyleName;
1069 }
1070 }
1071
1072 } // end of anonymous namespace
1073
1074 } // end of namespace ::sdext::presenter
1075
1076 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1077