Line data Source code
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 "PresenterHelper.hxx"
25 : #include <com/sun/star/awt/Point.hpp>
26 : #include <com/sun/star/beans/UnknownPropertyException.hpp>
27 : #include <com/sun/star/deployment/XPackageInformationProvider.hpp>
28 : #include <com/sun/star/drawing/XPresenterHelper.hpp>
29 : #include <com/sun/star/lang/IllegalArgumentException.hpp>
30 : #include <com/sun/star/rendering/PanoseWeight.hpp>
31 : #include <com/sun/star/rendering/XBitmap.hpp>
32 : #include <com/sun/star/util/Color.hpp>
33 : #include <boost/bind.hpp>
34 : #include <map>
35 :
36 : using namespace ::com::sun::star;
37 : using namespace ::com::sun::star::uno;
38 : using namespace ::std;
39 :
40 : namespace sdext { namespace presenter {
41 :
42 : namespace {
43 :
44 : class BorderSize
45 : {
46 : public:
47 : const static sal_Int32 mnInvalidValue = -10000;
48 :
49 0 : BorderSize (void) : mnLeft(mnInvalidValue),
50 : mnTop(mnInvalidValue),
51 : mnRight(mnInvalidValue),
52 0 : mnBottom(mnInvalidValue) {}
53 :
54 : sal_Int32 mnLeft;
55 : sal_Int32 mnTop;
56 : sal_Int32 mnRight;
57 : sal_Int32 mnBottom;
58 :
59 0 : vector<sal_Int32> ToVector (void)
60 : {
61 0 : vector<sal_Int32> aSequence (4);
62 0 : aSequence[0] = mnLeft == mnInvalidValue ? 0 : mnLeft;
63 0 : aSequence[1] = mnTop == mnInvalidValue ? 0 : mnTop;
64 0 : aSequence[2] = mnRight == mnInvalidValue ? 0 : mnRight;
65 0 : aSequence[3] = mnBottom == mnInvalidValue ? 0 : mnBottom;
66 0 : return aSequence;
67 : };
68 :
69 0 : void Merge (const BorderSize& rBorderSize)
70 : {
71 0 : if (mnLeft == mnInvalidValue)
72 0 : mnLeft = rBorderSize.mnLeft;
73 0 : if (mnTop == mnInvalidValue)
74 0 : mnTop = rBorderSize.mnTop;
75 0 : if (mnRight == mnInvalidValue)
76 0 : mnRight = rBorderSize.mnRight;
77 0 : if (mnBottom == mnInvalidValue)
78 0 : mnBottom = rBorderSize.mnBottom;
79 0 : }
80 : };
81 :
82 : /** Reading a theme from the configurations is done in various classes. The
83 : ReadContext gives access to frequently used objects and functions to make
84 : the configuration handling easier.
85 : */
86 : class ReadContext
87 : {
88 : public:
89 : Reference<XComponentContext> mxComponentContext;
90 : Reference<rendering::XCanvas> mxCanvas;
91 : Reference<drawing::XPresenterHelper> mxPresenterHelper;
92 :
93 : ReadContext (
94 : const Reference<XComponentContext>& rxContext,
95 : const Reference<rendering::XCanvas>& rxCanvas);
96 : ~ReadContext (void);
97 :
98 : /** Read data describing a font from the node that can be reached from
99 : the given root via the given path.
100 : @param rsFontPath
101 : May be empty.
102 : */
103 : static PresenterTheme::SharedFontDescriptor ReadFont (
104 : const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxTheme,
105 : const OUString& rsFontPath,
106 : const PresenterTheme::SharedFontDescriptor& rpDefault);
107 : static PresenterTheme::SharedFontDescriptor ReadFont (
108 : const Reference<beans::XPropertySet>& rxFontProperties,
109 : const PresenterTheme::SharedFontDescriptor& rpDefault);
110 :
111 : ::boost::shared_ptr<PresenterTheme::Theme> ReadTheme (
112 : PresenterConfigurationAccess& rConfiguration,
113 : const OUString& rsThemeName);
114 :
115 : BorderSize ReadBorderSize (const Reference<container::XNameAccess>& rxNode);
116 :
117 : private:
118 : Any GetByName (
119 : const Reference<container::XNameAccess>& rxNode,
120 : const OUString& rsName) const;
121 : };
122 :
123 : /** A PaneStyle describes how a pane is rendered.
124 : */
125 : class PaneStyle
126 : {
127 : public:
128 : PaneStyle (void);
129 : ~PaneStyle (void);
130 :
131 : const SharedBitmapDescriptor GetBitmap (const OUString& sBitmapName) const;
132 :
133 : OUString msStyleName;
134 : ::boost::shared_ptr<PaneStyle> mpParentStyle;
135 : PresenterTheme::SharedFontDescriptor mpFont;
136 : BorderSize maInnerBorderSize;
137 : BorderSize maOuterBorderSize;
138 : ::boost::shared_ptr<PresenterBitmapContainer> mpBitmaps;
139 :
140 : PresenterTheme::SharedFontDescriptor GetFont (void) const;
141 : };
142 :
143 : typedef ::boost::shared_ptr<PaneStyle> SharedPaneStyle;
144 :
145 0 : class PaneStyleContainer
146 : {
147 : private:
148 : ::std::vector<SharedPaneStyle> mStyles;
149 :
150 : public:
151 : void Read (
152 : ReadContext& rReadContext,
153 : const Reference<container::XHierarchicalNameAccess>& rThemeRoot);
154 :
155 : SharedPaneStyle GetPaneStyle (const OUString& rsStyleName) const;
156 :
157 : private:
158 : void ProcessPaneStyle (
159 : ReadContext& rReadContext,
160 : const OUString& rsKey,
161 : const ::std::vector<css::uno::Any>& rValues);
162 : };
163 :
164 : /** A ViewStyle describes how a view is displayed.
165 : */
166 : class ViewStyle
167 : {
168 : public:
169 : ViewStyle (void);
170 : ~ViewStyle (void);
171 :
172 : const SharedBitmapDescriptor GetBitmap (const OUString& sBitmapName) const;
173 :
174 : PresenterTheme::SharedFontDescriptor GetFont (void) const;
175 :
176 : OUString msStyleName;
177 : ::boost::shared_ptr<ViewStyle> mpParentStyle;
178 : PresenterTheme::SharedFontDescriptor mpFont;
179 : ::boost::shared_ptr<PresenterBitmapContainer> mpBitmaps;
180 : SharedBitmapDescriptor mpBackground;
181 : };
182 :
183 : typedef ::boost::shared_ptr<ViewStyle> SharedViewStyle;
184 :
185 0 : class ViewStyleContainer
186 : {
187 : private:
188 : ::std::vector<SharedViewStyle> mStyles;
189 :
190 : public:
191 : void Read (
192 : ReadContext& rReadContext,
193 : const Reference<container::XHierarchicalNameAccess>& rThemeRoot);
194 :
195 : SharedViewStyle GetViewStyle (const OUString& rsStyleName) const;
196 :
197 : private:
198 : void ProcessViewStyle(
199 : ReadContext& rReadContext,
200 : const Reference<beans::XPropertySet>& rxProperties);
201 : };
202 :
203 : class ViewDescriptor
204 : {
205 : };
206 : typedef ::boost::shared_ptr<ViewDescriptor> SharedViewDescriptor;
207 : typedef ::std::vector<SharedViewDescriptor> ViewDescriptorContainer;
208 :
209 0 : class StyleAssociationContainer
210 : {
211 : public:
212 : void Read (
213 : ReadContext& rReadContext,
214 : const Reference<container::XHierarchicalNameAccess>& rThemeRoot);
215 :
216 : OUString GetStyleName (const OUString& rsResourceName) const;
217 :
218 : private:
219 : typedef map<OUString, OUString> StyleAssociations;
220 : StyleAssociations maStyleAssociations;
221 :
222 : void ProcessStyleAssociation(
223 : ReadContext& rReadContext,
224 : const OUString& rsKey,
225 : const ::std::vector<css::uno::Any>& rValues);
226 : };
227 :
228 : } // end of anonymous namespace
229 :
230 : class PresenterTheme::Theme
231 : {
232 : public:
233 : Theme (
234 : const OUString& rsName,
235 : const Reference<container::XHierarchicalNameAccess>& rThemeRoot,
236 : const OUString& rsNodeName);
237 : ~Theme (void);
238 :
239 : void Read (
240 : PresenterConfigurationAccess& rConfiguration,
241 : ReadContext& rReadContext);
242 :
243 : OUString msThemeName;
244 : OUString msConfigurationNodeName;
245 : ::boost::shared_ptr<Theme> mpParentTheme;
246 : SharedBitmapDescriptor mpBackground;
247 : PaneStyleContainer maPaneStyles;
248 : ViewStyleContainer maViewStyles;
249 : ViewDescriptorContainer maViewDescriptors;
250 : StyleAssociationContainer maStyleAssociations;
251 : Reference<container::XHierarchicalNameAccess> mxThemeRoot;
252 : ::boost::shared_ptr<PresenterBitmapContainer> mpIconContainer;
253 : typedef map<OUString,SharedFontDescriptor> FontContainer;
254 : FontContainer maFontContainer;
255 :
256 : SharedPaneStyle GetPaneStyle (const OUString& rsStyleName) const;
257 : SharedViewStyle GetViewStyle (const OUString& rsStyleName) const;
258 :
259 : private:
260 : void ProcessFont(
261 : ReadContext& rReadContext,
262 : const OUString& rsKey,
263 : const Reference<beans::XPropertySet>& rxProperties);
264 : };
265 :
266 : //===== PresenterTheme ========================================================
267 :
268 0 : PresenterTheme::PresenterTheme (
269 : const css::uno::Reference<css::uno::XComponentContext>& rxContext,
270 : const OUString& rsThemeName,
271 : const css::uno::Reference<css::rendering::XCanvas>& rxCanvas)
272 : : mxContext(rxContext),
273 : msThemeName(rsThemeName),
274 : mpTheme(),
275 : mpBitmapContainer(),
276 0 : mxCanvas(rxCanvas)
277 : {
278 0 : mpTheme = ReadTheme();
279 0 : }
280 :
281 0 : PresenterTheme::~PresenterTheme (void)
282 : {
283 0 : }
284 :
285 0 : ::boost::shared_ptr<PresenterTheme::Theme> PresenterTheme::ReadTheme (void)
286 : {
287 0 : ReadContext aReadContext(mxContext, mxCanvas);
288 :
289 : PresenterConfigurationAccess aConfiguration (
290 : mxContext,
291 : OUString("/org.openoffice.Office.PresenterScreen/"),
292 0 : PresenterConfigurationAccess::READ_ONLY);
293 :
294 0 : return aReadContext.ReadTheme(aConfiguration, msThemeName);
295 : }
296 :
297 0 : bool PresenterTheme::HasCanvas (void) const
298 : {
299 0 : return mxCanvas.is();
300 : }
301 :
302 0 : void PresenterTheme::ProvideCanvas (const Reference<rendering::XCanvas>& rxCanvas)
303 : {
304 0 : if ( ! mxCanvas.is() && rxCanvas.is())
305 : {
306 0 : mxCanvas = rxCanvas;
307 0 : ReadTheme();
308 : }
309 0 : }
310 :
311 0 : OUString PresenterTheme::GetStyleName (const OUString& rsResourceURL) const
312 : {
313 0 : OUString sStyleName;
314 0 : ::boost::shared_ptr<Theme> pTheme (mpTheme);
315 0 : while (sStyleName.isEmpty() && pTheme.get()!=NULL)
316 : {
317 0 : sStyleName = pTheme->maStyleAssociations.GetStyleName(rsResourceURL);
318 0 : pTheme = pTheme->mpParentTheme;
319 : }
320 0 : return sStyleName;
321 : }
322 :
323 0 : ::std::vector<sal_Int32> PresenterTheme::GetBorderSize (
324 : const OUString& rsStyleName,
325 : const bool bOuter) const
326 : {
327 : OSL_ASSERT(mpTheme.get() != NULL);
328 :
329 0 : SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName));
330 0 : if (pPaneStyle.get() != NULL)
331 0 : if (bOuter)
332 0 : return pPaneStyle->maOuterBorderSize.ToVector();
333 : else
334 0 : return pPaneStyle->maInnerBorderSize.ToVector();
335 : else
336 : {
337 0 : return ::std::vector<sal_Int32>(4,0);
338 0 : }
339 : }
340 :
341 0 : PresenterTheme::SharedFontDescriptor PresenterTheme::ReadFont (
342 : const Reference<container::XHierarchicalNameAccess>& rxNode,
343 : const OUString& rsFontPath,
344 : const PresenterTheme::SharedFontDescriptor& rpDefault)
345 : {
346 0 : return ReadContext::ReadFont(rxNode, rsFontPath, rpDefault);
347 : }
348 :
349 0 : bool PresenterTheme::ConvertToColor (
350 : const Any& rColorSequence,
351 : sal_uInt32& rColor)
352 : {
353 0 : Sequence<sal_Int8> aByteSequence;
354 0 : if (rColorSequence >>= aByteSequence)
355 : {
356 0 : const sal_Int32 nByteCount (aByteSequence.getLength());
357 0 : const sal_uInt8* pArray = reinterpret_cast<const sal_uInt8*>(aByteSequence.getConstArray());
358 0 : rColor = 0;
359 0 : for (sal_Int32 nIndex=0; nIndex<nByteCount; ++nIndex)
360 : {
361 0 : rColor = (rColor << 8) | *pArray++;
362 : }
363 0 : return true;
364 : }
365 : else
366 0 : return false;
367 : }
368 :
369 0 : ::boost::shared_ptr<PresenterConfigurationAccess> PresenterTheme::GetNodeForViewStyle (
370 : const OUString& rsStyleName) const
371 : {
372 0 : if (mpTheme.get() == NULL)
373 0 : return ::boost::shared_ptr<PresenterConfigurationAccess>();
374 :
375 : // Open configuration for writing.
376 : ::boost::shared_ptr<PresenterConfigurationAccess> pConfiguration (
377 : new PresenterConfigurationAccess(
378 : mxContext,
379 : OUString("/org.openoffice.Office.PresenterScreen/"),
380 0 : PresenterConfigurationAccess::READ_WRITE));
381 :
382 : // Get configuration node for the view style container of the current
383 : // theme.
384 0 : if (pConfiguration->GoToChild( OUString(
385 0 : "Presenter/Themes/" + mpTheme->msConfigurationNodeName + "/ViewStyles")))
386 : {
387 : pConfiguration->GoToChild(
388 : ::boost::bind(&PresenterConfigurationAccess::IsStringPropertyEqual,
389 : rsStyleName,
390 : OUString("StyleName"),
391 0 : _2));
392 : }
393 0 : return pConfiguration;
394 : }
395 :
396 0 : SharedBitmapDescriptor PresenterTheme::GetBitmap (
397 : const OUString& rsStyleName,
398 : const OUString& rsBitmapName) const
399 : {
400 0 : if (mpTheme.get() != NULL)
401 : {
402 0 : if (rsStyleName.isEmpty())
403 : {
404 0 : if (rsBitmapName == "Background")
405 : {
406 0 : ::boost::shared_ptr<Theme> pTheme (mpTheme);
407 0 : while (pTheme.get()!=NULL && pTheme->mpBackground.get()==NULL)
408 0 : pTheme = pTheme->mpParentTheme;
409 0 : if (pTheme.get() != NULL)
410 0 : return pTheme->mpBackground;
411 : else
412 0 : return SharedBitmapDescriptor();
413 : }
414 : }
415 : else
416 : {
417 0 : SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName));
418 0 : if (pPaneStyle.get() != NULL)
419 : {
420 0 : SharedBitmapDescriptor pBitmap (pPaneStyle->GetBitmap(rsBitmapName));
421 0 : if (pBitmap.get() != NULL)
422 0 : return pBitmap;
423 : }
424 :
425 0 : SharedViewStyle pViewStyle (mpTheme->GetViewStyle(rsStyleName));
426 0 : if (pViewStyle.get() != NULL)
427 : {
428 0 : SharedBitmapDescriptor pBitmap (pViewStyle->GetBitmap(rsBitmapName));
429 0 : if (pBitmap.get() != NULL)
430 0 : return pBitmap;
431 0 : }
432 : }
433 : }
434 :
435 0 : return SharedBitmapDescriptor();
436 : }
437 :
438 0 : SharedBitmapDescriptor PresenterTheme::GetBitmap (
439 : const OUString& rsBitmapName) const
440 : {
441 0 : if (mpTheme.get() != NULL)
442 : {
443 0 : if (rsBitmapName == "Background")
444 : {
445 0 : ::boost::shared_ptr<Theme> pTheme (mpTheme);
446 0 : while (pTheme.get()!=NULL && pTheme->mpBackground.get()==NULL)
447 0 : pTheme = pTheme->mpParentTheme;
448 0 : if (pTheme.get() != NULL)
449 0 : return pTheme->mpBackground;
450 : else
451 0 : return SharedBitmapDescriptor();
452 : }
453 : else
454 : {
455 0 : if (mpTheme->mpIconContainer.get() != NULL)
456 0 : return mpTheme->mpIconContainer->GetBitmap(rsBitmapName);
457 : }
458 : }
459 :
460 0 : return SharedBitmapDescriptor();
461 : }
462 :
463 0 : ::boost::shared_ptr<PresenterBitmapContainer> PresenterTheme::GetBitmapContainer (void) const
464 : {
465 0 : if (mpTheme.get() != NULL)
466 0 : return mpTheme->mpIconContainer;
467 : else
468 0 : return ::boost::shared_ptr<PresenterBitmapContainer>();
469 : }
470 :
471 0 : PresenterTheme::SharedFontDescriptor PresenterTheme::GetFont (
472 : const OUString& rsStyleName) const
473 : {
474 0 : if (mpTheme.get() != NULL)
475 : {
476 0 : SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName));
477 0 : if (pPaneStyle.get() != NULL)
478 0 : return pPaneStyle->GetFont();
479 :
480 0 : SharedViewStyle pViewStyle (mpTheme->GetViewStyle(rsStyleName));
481 0 : if (pViewStyle.get() != NULL)
482 0 : return pViewStyle->GetFont();
483 :
484 0 : ::boost::shared_ptr<Theme> pTheme (mpTheme);
485 0 : while (pTheme.get() != NULL)
486 : {
487 0 : Theme::FontContainer::const_iterator iFont (pTheme->maFontContainer.find(rsStyleName));
488 0 : if (iFont != pTheme->maFontContainer.end())
489 0 : return iFont->second;
490 :
491 0 : pTheme = pTheme->mpParentTheme;
492 0 : }
493 : }
494 :
495 0 : return SharedFontDescriptor();
496 : }
497 :
498 : //===== FontDescriptor ========================================================
499 :
500 0 : PresenterTheme::FontDescriptor::FontDescriptor (
501 : const ::boost::shared_ptr<FontDescriptor>& rpDescriptor)
502 : : msFamilyName(),
503 : msStyleName(),
504 : mnSize(12),
505 : mnColor(0x00000000),
506 : msAnchor(OUString("Left")),
507 : mnXOffset(0),
508 0 : mnYOffset(0)
509 : {
510 0 : if (rpDescriptor.get() != NULL)
511 : {
512 0 : msFamilyName = rpDescriptor->msFamilyName;
513 0 : msStyleName = rpDescriptor->msStyleName;
514 0 : mnSize = rpDescriptor->mnSize;
515 0 : mnColor = rpDescriptor->mnColor;
516 0 : msAnchor = rpDescriptor->msAnchor;
517 0 : mnXOffset = rpDescriptor->mnXOffset;
518 0 : mnYOffset = rpDescriptor->mnYOffset;
519 : }
520 0 : }
521 :
522 0 : bool PresenterTheme::FontDescriptor::PrepareFont (
523 : const Reference<rendering::XCanvas>& rxCanvas)
524 : {
525 0 : if (mxFont.is())
526 0 : return true;
527 :
528 0 : if ( ! rxCanvas.is())
529 0 : return false;
530 :
531 0 : const double nCellSize (GetCellSizeForDesignSize(rxCanvas, mnSize));
532 0 : mxFont = CreateFont(rxCanvas, nCellSize);
533 :
534 0 : return mxFont.is();
535 : }
536 :
537 0 : Reference<rendering::XCanvasFont> PresenterTheme::FontDescriptor::CreateFont (
538 : const Reference<rendering::XCanvas>& rxCanvas,
539 : const double nCellSize) const
540 : {
541 0 : rendering::FontRequest aFontRequest;
542 0 : aFontRequest.FontDescription.FamilyName = msFamilyName;
543 0 : if (msFamilyName.isEmpty())
544 0 : aFontRequest.FontDescription.FamilyName = "Tahoma";
545 0 : aFontRequest.FontDescription.StyleName = msStyleName;
546 0 : aFontRequest.CellSize = nCellSize;
547 :
548 : // Make an attempt at translating the style name(s)into a corresponding
549 : // font description.
550 0 : if (msStyleName == "Bold")
551 0 : aFontRequest.FontDescription.FontDescription.Weight = rendering::PanoseWeight::HEAVY;
552 :
553 0 : return rxCanvas->createFont(
554 : aFontRequest,
555 : Sequence<beans::PropertyValue>(),
556 0 : geometry::Matrix2D(1,0,0,1));
557 : }
558 :
559 0 : double PresenterTheme::FontDescriptor::GetCellSizeForDesignSize (
560 : const Reference<rendering::XCanvas>& rxCanvas,
561 : const double nDesignSize) const
562 : {
563 : // Use the given design size as initial value in calculating the cell
564 : // size.
565 0 : double nCellSize (nDesignSize);
566 :
567 0 : if ( ! rxCanvas.is())
568 : {
569 : // We need the canvas to do the conversion. Return the design size,
570 : // it is the our best guess in this circumstance.
571 0 : return nDesignSize;
572 : }
573 :
574 0 : Reference<rendering::XCanvasFont> xFont (CreateFont(rxCanvas, nCellSize));
575 0 : if ( ! xFont.is())
576 0 : return nDesignSize;
577 :
578 0 : geometry::RealRectangle2D aBox (PresenterCanvasHelper::GetTextBoundingBox (xFont, "X"));
579 :
580 0 : const double nAscent (-aBox.Y1);
581 0 : const double nDescent (aBox.Y2);
582 0 : const double nScale = (nAscent+nDescent) / nAscent;
583 0 : return nDesignSize * nScale;
584 : }
585 :
586 : //===== Theme =================================================================
587 :
588 0 : PresenterTheme::Theme::Theme (
589 : const OUString& rsName,
590 : const Reference<container::XHierarchicalNameAccess>& rxThemeRoot,
591 : const OUString& rsNodeName)
592 : : msThemeName(rsName),
593 : msConfigurationNodeName(rsNodeName),
594 : mpParentTheme(),
595 : maPaneStyles(),
596 : maViewStyles(),
597 : maStyleAssociations(),
598 : mxThemeRoot(rxThemeRoot),
599 0 : mpIconContainer()
600 : {
601 0 : }
602 :
603 0 : PresenterTheme::Theme::~Theme (void)
604 : {
605 0 : }
606 :
607 0 : void PresenterTheme::Theme::Read (
608 : PresenterConfigurationAccess& rConfiguration,
609 : ReadContext& rReadContext)
610 : {
611 : PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, "ThemeName")
612 0 : >>= msThemeName;
613 :
614 : // Parent theme name.
615 0 : OUString sParentThemeName;
616 0 : if ((PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, "ParentTheme")
617 0 : >>= sParentThemeName)
618 0 : && !sParentThemeName.isEmpty())
619 : {
620 0 : mpParentTheme = rReadContext.ReadTheme(rConfiguration, sParentThemeName);
621 : }
622 :
623 : // Background.
624 0 : mpBackground = PresenterBitmapContainer::LoadBitmap(
625 : mxThemeRoot,
626 : "Background",
627 : rReadContext.mxPresenterHelper,
628 : rReadContext.mxCanvas,
629 0 : SharedBitmapDescriptor());
630 :
631 : // Style associations.
632 0 : maStyleAssociations.Read(rReadContext, mxThemeRoot);
633 :
634 : // Pane styles.
635 0 : maPaneStyles.Read(rReadContext, mxThemeRoot);
636 :
637 : // View styles.
638 0 : maViewStyles.Read(rReadContext, mxThemeRoot);
639 :
640 : // Read bitmaps.
641 : mpIconContainer.reset(
642 : new PresenterBitmapContainer(
643 : Reference<container::XNameAccess>(
644 : PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, "Bitmaps"),
645 : UNO_QUERY),
646 0 : mpParentTheme.get()!=NULL
647 0 : ? mpParentTheme->mpIconContainer
648 : : ::boost::shared_ptr<PresenterBitmapContainer>(),
649 : rReadContext.mxComponentContext,
650 0 : rReadContext.mxCanvas));
651 :
652 : // Read fonts.
653 : Reference<container::XNameAccess> xFontNode(
654 : PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, "Fonts"),
655 0 : UNO_QUERY);
656 : PresenterConfigurationAccess::ForAll(
657 : xFontNode,
658 : ::boost::bind(&PresenterTheme::Theme::ProcessFont,
659 0 : this, ::boost::ref(rReadContext), _1, _2));
660 0 : }
661 :
662 0 : SharedPaneStyle PresenterTheme::Theme::GetPaneStyle (const OUString& rsStyleName) const
663 : {
664 0 : SharedPaneStyle pPaneStyle (maPaneStyles.GetPaneStyle(rsStyleName));
665 0 : if (pPaneStyle.get() != NULL)
666 0 : return pPaneStyle;
667 0 : else if (mpParentTheme.get() != NULL)
668 0 : return mpParentTheme->GetPaneStyle(rsStyleName);
669 : else
670 0 : return SharedPaneStyle();
671 : }
672 :
673 0 : SharedViewStyle PresenterTheme::Theme::GetViewStyle (const OUString& rsStyleName) const
674 : {
675 0 : SharedViewStyle pViewStyle (maViewStyles.GetViewStyle(rsStyleName));
676 0 : if (pViewStyle.get() != NULL)
677 0 : return pViewStyle;
678 0 : else if (mpParentTheme.get() != NULL)
679 0 : return mpParentTheme->GetViewStyle(rsStyleName);
680 : else
681 0 : return SharedViewStyle();
682 : }
683 :
684 0 : void PresenterTheme::Theme::ProcessFont(
685 : ReadContext& rReadContext,
686 : const OUString& rsKey,
687 : const Reference<beans::XPropertySet>& rxProperties)
688 : {
689 : (void)rReadContext;
690 0 : maFontContainer[rsKey] = ReadContext::ReadFont(rxProperties, SharedFontDescriptor());
691 0 : }
692 :
693 : namespace {
694 :
695 : //===== ReadContext ===========================================================
696 :
697 0 : ReadContext::ReadContext (
698 : const css::uno::Reference<css::uno::XComponentContext>& rxContext,
699 : const Reference<rendering::XCanvas>& rxCanvas)
700 : : mxComponentContext(rxContext),
701 : mxCanvas(rxCanvas),
702 0 : mxPresenterHelper()
703 : {
704 0 : Reference<lang::XMultiComponentFactory> xFactory (rxContext->getServiceManager());
705 0 : if (xFactory.is())
706 : {
707 0 : mxPresenterHelper = Reference<drawing::XPresenterHelper>(
708 0 : xFactory->createInstanceWithContext(
709 : OUString("com.sun.star.comp.Draw.PresenterHelper"),
710 0 : rxContext),
711 0 : UNO_QUERY_THROW);
712 0 : }
713 0 : }
714 :
715 0 : ReadContext::~ReadContext (void)
716 : {
717 0 : }
718 :
719 0 : PresenterTheme::SharedFontDescriptor ReadContext::ReadFont (
720 : const Reference<container::XHierarchicalNameAccess>& rxNode,
721 : const OUString& rsFontPath,
722 : const PresenterTheme::SharedFontDescriptor& rpDefault)
723 : {
724 0 : if ( ! rxNode.is())
725 0 : return PresenterTheme::SharedFontDescriptor();
726 :
727 : try
728 : {
729 : Reference<container::XHierarchicalNameAccess> xFont (
730 : PresenterConfigurationAccess::GetConfigurationNode(
731 : rxNode,
732 : rsFontPath),
733 0 : UNO_QUERY_THROW);
734 :
735 0 : Reference<beans::XPropertySet> xProperties (xFont, UNO_QUERY_THROW);
736 0 : return ReadFont(xProperties, rpDefault);
737 : }
738 0 : catch (Exception&)
739 : {
740 : OSL_ASSERT(false);
741 : }
742 :
743 0 : return PresenterTheme::SharedFontDescriptor();
744 : }
745 :
746 0 : PresenterTheme::SharedFontDescriptor ReadContext::ReadFont (
747 : const Reference<beans::XPropertySet>& rxProperties,
748 : const PresenterTheme::SharedFontDescriptor& rpDefault)
749 : {
750 : ::boost::shared_ptr<PresenterTheme::FontDescriptor> pDescriptor (
751 0 : new PresenterTheme::FontDescriptor(rpDefault));
752 :
753 0 : PresenterConfigurationAccess::GetProperty(rxProperties, "FamilyName") >>= pDescriptor->msFamilyName;
754 0 : PresenterConfigurationAccess::GetProperty(rxProperties, "Style") >>= pDescriptor->msStyleName;
755 0 : PresenterConfigurationAccess::GetProperty(rxProperties, "Size") >>= pDescriptor->mnSize;
756 : PresenterTheme::ConvertToColor(
757 : PresenterConfigurationAccess::GetProperty(rxProperties, "Color"),
758 0 : pDescriptor->mnColor);
759 0 : PresenterConfigurationAccess::GetProperty(rxProperties, "Anchor") >>= pDescriptor->msAnchor;
760 0 : PresenterConfigurationAccess::GetProperty(rxProperties, "XOffset") >>= pDescriptor->mnXOffset;
761 0 : PresenterConfigurationAccess::GetProperty(rxProperties, "YOffset") >>= pDescriptor->mnYOffset;
762 :
763 0 : return pDescriptor;
764 : }
765 :
766 0 : Any ReadContext::GetByName (
767 : const Reference<container::XNameAccess>& rxNode,
768 : const OUString& rsName) const
769 : {
770 : OSL_ASSERT(rxNode.is());
771 0 : if (rxNode->hasByName(rsName))
772 0 : return rxNode->getByName(rsName);
773 : else
774 0 : return Any();
775 : }
776 :
777 0 : ::boost::shared_ptr<PresenterTheme::Theme> ReadContext::ReadTheme (
778 : PresenterConfigurationAccess& rConfiguration,
779 : const OUString& rsThemeName)
780 : {
781 0 : ::boost::shared_ptr<PresenterTheme::Theme> pTheme;
782 :
783 0 : OUString sCurrentThemeName (rsThemeName);
784 0 : if (sCurrentThemeName.isEmpty())
785 : {
786 : // No theme name given. Look up the CurrentTheme property.
787 0 : rConfiguration.GetConfigurationNode("Presenter/CurrentTheme") >>= sCurrentThemeName;
788 0 : if (sCurrentThemeName.isEmpty())
789 : {
790 : // Still no name. Use "DefaultTheme".
791 0 : sCurrentThemeName = "DefaultTheme";
792 : }
793 : }
794 :
795 : Reference<container::XNameAccess> xThemes (
796 : rConfiguration.GetConfigurationNode("Presenter/Themes"),
797 0 : UNO_QUERY);
798 0 : if (xThemes.is())
799 : {
800 : // Iterate over all themes and search the one with the given name.
801 0 : Sequence<OUString> aKeys (xThemes->getElementNames());
802 0 : for (sal_Int32 nItemIndex=0; nItemIndex < aKeys.getLength(); ++nItemIndex)
803 : {
804 0 : const OUString& rsKey (aKeys[nItemIndex]);
805 : Reference<container::XHierarchicalNameAccess> xTheme (
806 0 : xThemes->getByName(rsKey), UNO_QUERY);
807 0 : if (xTheme.is())
808 : {
809 0 : OUString sThemeName;
810 : PresenterConfigurationAccess::GetConfigurationNode(xTheme, "ThemeName")
811 0 : >>= sThemeName;
812 0 : if (sThemeName == sCurrentThemeName)
813 : {
814 0 : pTheme.reset(new PresenterTheme::Theme(sThemeName,xTheme,rsKey));
815 0 : break;
816 0 : }
817 : }
818 0 : }
819 : }
820 :
821 0 : if (pTheme.get() != NULL)
822 : {
823 0 : pTheme->Read(rConfiguration, *this);
824 : }
825 :
826 0 : return pTheme;
827 : }
828 :
829 0 : BorderSize ReadContext::ReadBorderSize (const Reference<container::XNameAccess>& rxNode)
830 : {
831 0 : BorderSize aBorderSize;
832 :
833 0 : if (rxNode.is())
834 : {
835 0 : GetByName(rxNode, "Left") >>= aBorderSize.mnLeft;
836 0 : GetByName(rxNode, "Top") >>= aBorderSize.mnTop;
837 0 : GetByName(rxNode, "Right") >>= aBorderSize.mnRight;
838 0 : GetByName(rxNode, "Bottom") >>= aBorderSize.mnBottom;
839 : }
840 :
841 0 : return aBorderSize;
842 : }
843 :
844 : //===== PaneStyleContainer ====================================================
845 :
846 0 : void PaneStyleContainer::Read (
847 : ReadContext& rReadContext,
848 : const Reference<container::XHierarchicalNameAccess>& rxThemeRoot)
849 : {
850 : Reference<container::XNameAccess> xPaneStyleList (
851 : PresenterConfigurationAccess::GetConfigurationNode(
852 : rxThemeRoot,
853 : "PaneStyles"),
854 0 : UNO_QUERY);
855 0 : if (xPaneStyleList.is())
856 : {
857 0 : ::std::vector<OUString> aProperties;
858 0 : aProperties.reserve(6);
859 0 : aProperties.push_back("StyleName");
860 0 : aProperties.push_back("ParentStyle");
861 0 : aProperties.push_back("TitleFont");
862 0 : aProperties.push_back("InnerBorderSize");
863 0 : aProperties.push_back("OuterBorderSize");
864 0 : aProperties.push_back("BorderBitmapList");
865 : PresenterConfigurationAccess::ForAll(
866 : xPaneStyleList,
867 : aProperties,
868 : ::boost::bind(&PaneStyleContainer::ProcessPaneStyle,
869 0 : this, ::boost::ref(rReadContext), _1, _2));
870 0 : }
871 0 : }
872 :
873 0 : void PaneStyleContainer::ProcessPaneStyle(
874 : ReadContext& rReadContext,
875 : const OUString& rsKey,
876 : const ::std::vector<Any>& rValues)
877 : {
878 : (void)rsKey;
879 :
880 0 : if (rValues.size() != 6)
881 0 : return;
882 :
883 0 : ::boost::shared_ptr<PaneStyle> pStyle (new PaneStyle());
884 :
885 0 : rValues[0] >>= pStyle->msStyleName;
886 :
887 0 : OUString sParentStyleName;
888 0 : if (rValues[1] >>= sParentStyleName)
889 : {
890 : // Find parent style.
891 0 : ::std::vector<SharedPaneStyle>::const_iterator iStyle;
892 0 : for (iStyle=mStyles.begin(); iStyle!=mStyles.end(); ++iStyle)
893 0 : if ((*iStyle)->msStyleName.equals(sParentStyleName))
894 : {
895 0 : pStyle->mpParentStyle = *iStyle;
896 0 : break;
897 : }
898 : }
899 :
900 0 : Reference<container::XHierarchicalNameAccess> xFontNode (rValues[2], UNO_QUERY);
901 0 : pStyle->mpFont = ReadContext::ReadFont(
902 0 : xFontNode, "", PresenterTheme::SharedFontDescriptor());
903 :
904 0 : Reference<container::XNameAccess> xInnerBorderSizeNode (rValues[3], UNO_QUERY);
905 0 : pStyle->maInnerBorderSize = rReadContext.ReadBorderSize(xInnerBorderSizeNode);
906 0 : Reference<container::XNameAccess> xOuterBorderSizeNode (rValues[4], UNO_QUERY);
907 0 : pStyle->maOuterBorderSize = rReadContext.ReadBorderSize(xOuterBorderSizeNode);
908 :
909 0 : if (pStyle->mpParentStyle.get() != NULL)
910 : {
911 0 : pStyle->maInnerBorderSize.Merge(pStyle->mpParentStyle->maInnerBorderSize);
912 0 : pStyle->maOuterBorderSize.Merge(pStyle->mpParentStyle->maOuterBorderSize);
913 : }
914 :
915 0 : if (rReadContext.mxCanvas.is())
916 : {
917 0 : Reference<container::XNameAccess> xBitmapsNode (rValues[5], UNO_QUERY);
918 0 : pStyle->mpBitmaps.reset(new PresenterBitmapContainer(
919 : xBitmapsNode,
920 0 : pStyle->mpParentStyle.get()!=NULL
921 0 : ? pStyle->mpParentStyle->mpBitmaps
922 : : ::boost::shared_ptr<PresenterBitmapContainer>(),
923 : rReadContext.mxComponentContext,
924 : rReadContext.mxCanvas,
925 0 : rReadContext.mxPresenterHelper));
926 : }
927 :
928 0 : mStyles.push_back(pStyle);
929 : }
930 :
931 0 : SharedPaneStyle PaneStyleContainer::GetPaneStyle (const OUString& rsStyleName) const
932 : {
933 0 : ::std::vector<SharedPaneStyle>::const_iterator iEnd (mStyles.end());
934 0 : for (::std::vector<SharedPaneStyle>::const_iterator iStyle=mStyles.begin(); iStyle!=iEnd; ++iStyle)
935 0 : if ((*iStyle)->msStyleName == rsStyleName)
936 0 : return *iStyle;
937 0 : return SharedPaneStyle();
938 : }
939 :
940 : //===== PaneStyle =============================================================
941 :
942 0 : PaneStyle::PaneStyle (void)
943 : : msStyleName(),
944 : mpParentStyle(),
945 : mpFont(),
946 : maInnerBorderSize(),
947 : maOuterBorderSize(),
948 0 : mpBitmaps()
949 : {
950 0 : }
951 :
952 0 : PaneStyle::~PaneStyle (void)
953 : {
954 0 : }
955 :
956 0 : const SharedBitmapDescriptor PaneStyle::GetBitmap (const OUString& rsBitmapName) const
957 : {
958 0 : if (mpBitmaps.get() != NULL)
959 : {
960 0 : const SharedBitmapDescriptor pBitmap = mpBitmaps->GetBitmap(rsBitmapName);
961 0 : if (pBitmap.get() != NULL)
962 0 : return pBitmap;
963 : }
964 :
965 0 : if (mpParentStyle.get() != NULL)
966 0 : return mpParentStyle->GetBitmap(rsBitmapName);
967 : else
968 0 : return SharedBitmapDescriptor();
969 : }
970 :
971 0 : PresenterTheme::SharedFontDescriptor PaneStyle::GetFont (void) const
972 : {
973 0 : if (mpFont.get() != NULL)
974 0 : return mpFont;
975 0 : else if (mpParentStyle.get() != NULL)
976 0 : return mpParentStyle->GetFont();
977 : else
978 0 : return PresenterTheme::SharedFontDescriptor();
979 : }
980 :
981 : //===== ViewStyleContainer ====================================================
982 :
983 0 : void ViewStyleContainer::Read (
984 : ReadContext& rReadContext,
985 : const Reference<container::XHierarchicalNameAccess>& rxThemeRoot)
986 : {
987 : (void)rReadContext;
988 :
989 : Reference<container::XNameAccess> xViewStyleList (
990 : PresenterConfigurationAccess::GetConfigurationNode(
991 : rxThemeRoot,
992 : "ViewStyles"),
993 0 : UNO_QUERY);
994 0 : if (xViewStyleList.is())
995 : {
996 : PresenterConfigurationAccess::ForAll(
997 : xViewStyleList,
998 : ::boost::bind(&ViewStyleContainer::ProcessViewStyle,
999 0 : this, ::boost::ref(rReadContext), _2));
1000 0 : }
1001 0 : }
1002 :
1003 0 : void ViewStyleContainer::ProcessViewStyle(
1004 : ReadContext& rReadContext,
1005 : const Reference<beans::XPropertySet>& rxProperties)
1006 : {
1007 0 : ::boost::shared_ptr<ViewStyle> pStyle (new ViewStyle());
1008 :
1009 : PresenterConfigurationAccess::GetProperty(rxProperties, "StyleName")
1010 0 : >>= pStyle->msStyleName;
1011 :
1012 0 : OUString sParentStyleName;
1013 0 : if (PresenterConfigurationAccess::GetProperty(rxProperties, "ParentStyle")
1014 0 : >>= sParentStyleName)
1015 : {
1016 : // Find parent style.
1017 0 : ::std::vector<SharedViewStyle>::const_iterator iStyle;
1018 0 : for (iStyle=mStyles.begin(); iStyle!=mStyles.end(); ++iStyle)
1019 0 : if ((*iStyle)->msStyleName.equals(sParentStyleName))
1020 : {
1021 0 : pStyle->mpParentStyle = *iStyle;
1022 0 : pStyle->mpFont = (*iStyle)->mpFont;
1023 0 : pStyle->mpBackground = (*iStyle)->mpBackground;
1024 0 : break;
1025 : }
1026 : }
1027 :
1028 0 : const OUString sPathToFont; // empty string
1029 : Reference<container::XHierarchicalNameAccess> xFontNode (
1030 0 : PresenterConfigurationAccess::GetProperty(rxProperties, "Font"), UNO_QUERY);
1031 : PresenterTheme::SharedFontDescriptor pFont (
1032 0 : ReadContext::ReadFont(xFontNode, sPathToFont, PresenterTheme::SharedFontDescriptor()));
1033 0 : if (pFont.get() != NULL)
1034 0 : pStyle->mpFont = pFont;
1035 :
1036 : Reference<container::XHierarchicalNameAccess> xBackgroundNode (
1037 : PresenterConfigurationAccess::GetProperty(rxProperties, "Background"),
1038 0 : UNO_QUERY);
1039 : SharedBitmapDescriptor pBackground (PresenterBitmapContainer::LoadBitmap(
1040 : xBackgroundNode,
1041 : OUString(),
1042 : rReadContext.mxPresenterHelper,
1043 : rReadContext.mxCanvas,
1044 0 : SharedBitmapDescriptor()));
1045 0 : if (pBackground.get() != NULL && pBackground->GetNormalBitmap().is())
1046 0 : pStyle->mpBackground = pBackground;
1047 :
1048 0 : mStyles.push_back(pStyle);
1049 0 : }
1050 :
1051 0 : SharedViewStyle ViewStyleContainer::GetViewStyle (const OUString& rsStyleName) const
1052 : {
1053 0 : ::std::vector<SharedViewStyle>::const_iterator iEnd (mStyles.end());
1054 0 : for (::std::vector<SharedViewStyle>::const_iterator iStyle=mStyles.begin(); iStyle!=iEnd; ++iStyle)
1055 0 : if ((*iStyle)->msStyleName == rsStyleName)
1056 0 : return *iStyle;
1057 0 : return SharedViewStyle();
1058 : }
1059 :
1060 : //===== ViewStyle =============================================================
1061 :
1062 0 : ViewStyle::ViewStyle (void)
1063 : : msStyleName(),
1064 : mpParentStyle(),
1065 : mpFont(),
1066 0 : mpBackground()
1067 : {
1068 0 : }
1069 :
1070 0 : ViewStyle::~ViewStyle (void)
1071 : {
1072 0 : }
1073 :
1074 0 : const SharedBitmapDescriptor ViewStyle::GetBitmap (const OUString& rsBitmapName) const
1075 : {
1076 0 : if (rsBitmapName == "Background")
1077 0 : return mpBackground;
1078 : else
1079 0 : return SharedBitmapDescriptor();
1080 : }
1081 :
1082 0 : PresenterTheme::SharedFontDescriptor ViewStyle::GetFont (void) const
1083 : {
1084 0 : if (mpFont.get() != NULL)
1085 0 : return mpFont;
1086 0 : else if (mpParentStyle.get() != NULL)
1087 0 : return mpParentStyle->GetFont();
1088 : else
1089 0 : return PresenterTheme::SharedFontDescriptor();
1090 : }
1091 :
1092 : //===== StyleAssociationContainer =============================================
1093 :
1094 0 : void StyleAssociationContainer::Read (
1095 : ReadContext& rReadContext,
1096 : const Reference<container::XHierarchicalNameAccess>& rxThemeRoot)
1097 : {
1098 : Reference<container::XNameAccess> xStyleAssociationList (
1099 : PresenterConfigurationAccess::GetConfigurationNode(
1100 : rxThemeRoot,
1101 : "StyleAssociations"),
1102 0 : UNO_QUERY);
1103 0 : if (xStyleAssociationList.is())
1104 : {
1105 0 : ::std::vector<OUString> aProperties (2);
1106 0 : aProperties[0] = "ResourceURL";
1107 0 : aProperties[1] = "StyleName";
1108 : PresenterConfigurationAccess::ForAll(
1109 : xStyleAssociationList,
1110 : aProperties,
1111 : ::boost::bind(&StyleAssociationContainer::ProcessStyleAssociation,
1112 0 : this, ::boost::ref(rReadContext), _1, _2));
1113 0 : }
1114 0 : }
1115 :
1116 0 : OUString StyleAssociationContainer::GetStyleName (const OUString& rsResourceName) const
1117 : {
1118 0 : StyleAssociations::const_iterator iAssociation (maStyleAssociations.find(rsResourceName));
1119 0 : if (iAssociation != maStyleAssociations.end())
1120 0 : return iAssociation->second;
1121 : else
1122 0 : return OUString();
1123 : }
1124 :
1125 0 : void StyleAssociationContainer::ProcessStyleAssociation(
1126 : ReadContext& rReadContext,
1127 : const OUString& rsKey,
1128 : const ::std::vector<Any>& rValues)
1129 : {
1130 : (void)rReadContext;
1131 : (void)rsKey;
1132 :
1133 0 : if (rValues.size() != 2)
1134 0 : return;
1135 :
1136 0 : OUString sResourceURL;
1137 0 : OUString sStyleName;
1138 0 : if ((rValues[0] >>= sResourceURL)
1139 0 : && (rValues[1] >>= sStyleName))
1140 : {
1141 0 : maStyleAssociations[sResourceURL] = sStyleName;
1142 0 : }
1143 : }
1144 :
1145 : } // end of anonymous namespace
1146 :
1147 24 : } } // end of namespace ::sdext::presenter
1148 :
1149 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|