1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sdext.hxx" 30 31 #include "PresenterTheme.hxx" 32 #include "PresenterBitmapContainer.hxx" 33 #include "PresenterCanvasHelper.hxx" 34 #include "PresenterComponent.hxx" 35 #include "PresenterConfigurationAccess.hxx" 36 #include "PresenterHelper.hxx" 37 #include <com/sun/star/awt/Point.hpp> 38 #include <com/sun/star/beans/UnknownPropertyException.hpp> 39 #include <com/sun/star/deployment/XPackageInformationProvider.hpp> 40 #include <com/sun/star/drawing/XPresenterHelper.hpp> 41 #include <com/sun/star/lang/IllegalArgumentException.hpp> 42 #include <com/sun/star/rendering/PanoseWeight.hpp> 43 #include <com/sun/star/rendering/XBitmap.hpp> 44 #include <com/sun/star/util/Color.hpp> 45 #include <boost/bind.hpp> 46 #include <map> 47 48 using namespace ::com::sun::star; 49 using namespace ::com::sun::star::uno; 50 using namespace ::std; 51 using ::rtl::OUString; 52 53 #define A2S(s) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))) 54 55 namespace sdext { namespace presenter { 56 57 namespace { 58 59 class BorderSize 60 { 61 public: 62 const static sal_Int32 mnInvalidValue = -10000; 63 64 BorderSize (void) : mnLeft(mnInvalidValue), 65 mnTop(mnInvalidValue), 66 mnRight(mnInvalidValue), 67 mnBottom(mnInvalidValue) {} 68 69 sal_Int32 mnLeft; 70 sal_Int32 mnTop; 71 sal_Int32 mnRight; 72 sal_Int32 mnBottom; 73 74 vector<sal_Int32> ToVector (void) 75 { 76 vector<sal_Int32> aSequence (4); 77 aSequence[0] = mnLeft == mnInvalidValue ? 0 : mnLeft; 78 aSequence[1] = mnTop == mnInvalidValue ? 0 : mnTop; 79 aSequence[2] = mnRight == mnInvalidValue ? 0 : mnRight; 80 aSequence[3] = mnBottom == mnInvalidValue ? 0 : mnBottom; 81 return aSequence; 82 }; 83 84 85 void Merge (const BorderSize& rBorderSize) 86 { 87 if (mnLeft == mnInvalidValue) 88 mnLeft = rBorderSize.mnLeft; 89 if (mnTop == mnInvalidValue) 90 mnTop = rBorderSize.mnTop; 91 if (mnRight == mnInvalidValue) 92 mnRight = rBorderSize.mnRight; 93 if (mnBottom == mnInvalidValue) 94 mnBottom = rBorderSize.mnBottom; 95 } 96 }; 97 98 99 /** Reading a theme from the configurations is done in various classes. The 100 ReadContext gives access to frequently used objects and functions to make 101 the configuration handling easier. 102 */ 103 class ReadContext 104 { 105 public: 106 Reference<XComponentContext> mxComponentContext; 107 Reference<rendering::XCanvas> mxCanvas; 108 Reference<drawing::XPresenterHelper> mxPresenterHelper; 109 OUString msBasePath; 110 111 ReadContext ( 112 const Reference<XComponentContext>& rxContext, 113 const Reference<rendering::XCanvas>& rxCanvas); 114 ~ReadContext (void); 115 116 /** Read data describing a font from the node that can be reached from 117 the given root via the given path. 118 @param rsFontPath 119 May be empty. 120 */ 121 static PresenterTheme::SharedFontDescriptor ReadFont ( 122 const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxTheme, 123 const ::rtl::OUString& rsFontPath, 124 const PresenterTheme::SharedFontDescriptor& rpDefault); 125 static PresenterTheme::SharedFontDescriptor ReadFont ( 126 const Reference<beans::XPropertySet>& rxFontProperties, 127 const PresenterTheme::SharedFontDescriptor& rpDefault); 128 129 ::boost::shared_ptr<PresenterTheme::Theme> ReadTheme ( 130 PresenterConfigurationAccess& rConfiguration, 131 const OUString& rsThemeName); 132 133 BorderSize ReadBorderSize (const Reference<container::XNameAccess>& rxNode); 134 135 void SetBitmapSourceExtension (const OUString& rsExtensionName); 136 137 private: 138 Any GetByName ( 139 const Reference<container::XNameAccess>& rxNode, 140 const OUString& rsName) const; 141 }; 142 143 144 145 146 /** A PaneStyle describes how a pane is rendered. 147 */ 148 class PaneStyle 149 { 150 public: 151 PaneStyle (void); 152 ~PaneStyle (void); 153 154 const SharedBitmapDescriptor GetBitmap (const OUString& sBitmapName) const; 155 156 OUString msStyleName; 157 ::boost::shared_ptr<PaneStyle> mpParentStyle; 158 PresenterTheme::SharedFontDescriptor mpFont; 159 BorderSize maInnerBorderSize; 160 BorderSize maOuterBorderSize; 161 ::boost::shared_ptr<PresenterBitmapContainer> mpBitmaps; 162 163 PresenterTheme::SharedFontDescriptor GetFont (void) const; 164 165 private: 166 167 void UpdateBorderSize (BorderSize& rBorderSize, bool bInner); 168 }; 169 170 typedef ::boost::shared_ptr<PaneStyle> SharedPaneStyle; 171 172 173 174 175 class PaneStyleContainer : vector<SharedPaneStyle> 176 { 177 public: 178 void Read ( 179 ReadContext& rReadContext, 180 const Reference<container::XHierarchicalNameAccess>& rThemeRoot); 181 182 SharedPaneStyle GetPaneStyle (const OUString& rsStyleName) const; 183 184 private: 185 void ProcessPaneStyle ( 186 ReadContext& rReadContext, 187 const ::rtl::OUString& rsKey, 188 const ::std::vector<css::uno::Any>& rValues); 189 }; 190 191 192 193 194 /** A ViewStyle describes how a view is displayed. 195 */ 196 class ViewStyle 197 { 198 public: 199 ViewStyle (void); 200 ~ViewStyle (void); 201 202 const SharedBitmapDescriptor GetBitmap (const OUString& sBitmapName) const; 203 204 PresenterTheme::SharedFontDescriptor GetFont (void) const; 205 206 OUString msStyleName; 207 ::boost::shared_ptr<ViewStyle> mpParentStyle; 208 PresenterTheme::SharedFontDescriptor mpFont; 209 ::boost::shared_ptr<PresenterBitmapContainer> mpBitmaps; 210 SharedBitmapDescriptor mpBackground; 211 }; 212 213 typedef ::boost::shared_ptr<ViewStyle> SharedViewStyle; 214 215 216 217 218 class ViewStyleContainer : vector<SharedViewStyle> 219 { 220 public: 221 void Read ( 222 ReadContext& rReadContext, 223 const Reference<container::XHierarchicalNameAccess>& rThemeRoot); 224 225 SharedViewStyle GetViewStyle (const OUString& rsStyleName) const; 226 227 private: 228 void ProcessViewStyle( 229 ReadContext& rReadContext, 230 const Reference<beans::XPropertySet>& rxProperties); 231 }; 232 233 234 235 236 class ViewDescriptor 237 { 238 }; 239 typedef ::boost::shared_ptr<ViewDescriptor> SharedViewDescriptor; 240 typedef ::std::vector<SharedViewDescriptor> ViewDescriptorContainer; 241 242 243 244 class StyleAssociationContainer 245 { 246 public: 247 void Read ( 248 ReadContext& rReadContext, 249 const Reference<container::XHierarchicalNameAccess>& rThemeRoot); 250 251 OUString GetStyleName (const OUString& rsResourceName) const; 252 253 private: 254 typedef map<OUString, OUString> StyleAssociations; 255 StyleAssociations maStyleAssociations; 256 257 void ProcessStyleAssociation( 258 ReadContext& rReadContext, 259 const ::rtl::OUString& rsKey, 260 const ::std::vector<css::uno::Any>& rValues); 261 }; 262 263 } // end of anonymous namespace 264 265 266 class PresenterTheme::Theme 267 { 268 public: 269 Theme ( 270 const OUString& rsName, 271 const Reference<container::XHierarchicalNameAccess>& rThemeRoot, 272 const OUString& rsNodeName); 273 ~Theme (void); 274 275 void Read ( 276 PresenterConfigurationAccess& rConfiguration, 277 ReadContext& rReadContext); 278 279 OUString msThemeName; 280 OUString msConfigurationNodeName; 281 ::boost::shared_ptr<Theme> mpParentTheme; 282 SharedBitmapDescriptor mpBackground; 283 PaneStyleContainer maPaneStyles; 284 ViewStyleContainer maViewStyles; 285 ViewDescriptorContainer maViewDescriptors; 286 StyleAssociationContainer maStyleAssociations; 287 Reference<container::XHierarchicalNameAccess> mxThemeRoot; 288 ::boost::shared_ptr<PresenterBitmapContainer> mpIconContainer; 289 typedef map<rtl::OUString,SharedFontDescriptor> FontContainer; 290 FontContainer maFontContainer; 291 292 SharedPaneStyle GetPaneStyle (const OUString& rsStyleName) const; 293 SharedViewStyle GetViewStyle (const OUString& rsStyleName) const; 294 295 private: 296 void ProcessFont( 297 ReadContext& rReadContext, 298 const OUString& rsKey, 299 const Reference<beans::XPropertySet>& rxProperties); 300 }; 301 302 303 304 305 //===== PresenterTheme ======================================================== 306 307 PresenterTheme::PresenterTheme ( 308 const css::uno::Reference<css::uno::XComponentContext>& rxContext, 309 const rtl::OUString& rsThemeName, 310 const css::uno::Reference<css::rendering::XCanvas>& rxCanvas) 311 : mxContext(rxContext), 312 msThemeName(rsThemeName), 313 mpTheme(), 314 mpBitmapContainer(), 315 mxCanvas(rxCanvas) 316 { 317 mpTheme = ReadTheme(); 318 } 319 320 321 322 323 PresenterTheme::~PresenterTheme (void) 324 { 325 } 326 327 328 329 330 void SAL_CALL PresenterTheme::disposing (void) 331 { 332 } 333 334 335 336 337 ::boost::shared_ptr<PresenterTheme::Theme> PresenterTheme::ReadTheme (void) 338 { 339 ReadContext aReadContext(mxContext, mxCanvas); 340 341 PresenterConfigurationAccess aConfiguration ( 342 mxContext, 343 OUString::createFromAscii("/org.openoffice.Office.extension.PresenterScreen/"), 344 PresenterConfigurationAccess::READ_ONLY); 345 346 return aReadContext.ReadTheme(aConfiguration, msThemeName); 347 } 348 349 350 351 352 bool PresenterTheme::HasCanvas (void) const 353 { 354 return mxCanvas.is(); 355 } 356 357 358 359 360 void PresenterTheme::ProvideCanvas (const Reference<rendering::XCanvas>& rxCanvas) 361 { 362 if ( ! mxCanvas.is() && rxCanvas.is()) 363 { 364 mxCanvas = rxCanvas; 365 ReadTheme(); 366 } 367 } 368 369 370 371 372 OUString PresenterTheme::GetStyleName (const ::rtl::OUString& rsResourceURL) const 373 { 374 OUString sStyleName; 375 ::boost::shared_ptr<Theme> pTheme (mpTheme); 376 while (sStyleName.getLength()==0 && pTheme.get()!=NULL) 377 { 378 sStyleName = pTheme->maStyleAssociations.GetStyleName(rsResourceURL); 379 pTheme = pTheme->mpParentTheme; 380 } 381 return sStyleName; 382 } 383 384 385 386 387 ::std::vector<sal_Int32> PresenterTheme::GetBorderSize ( 388 const ::rtl::OUString& rsStyleName, 389 const bool bOuter) const 390 { 391 OSL_ASSERT(mpTheme.get() != NULL); 392 393 SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName)); 394 if (pPaneStyle.get() != NULL) 395 if (bOuter) 396 return pPaneStyle->maOuterBorderSize.ToVector(); 397 else 398 return pPaneStyle->maInnerBorderSize.ToVector(); 399 else 400 { 401 return ::std::vector<sal_Int32>(4,0); 402 } 403 } 404 405 406 407 408 PresenterTheme::SharedFontDescriptor PresenterTheme::ReadFont ( 409 const Reference<container::XHierarchicalNameAccess>& rxNode, 410 const OUString& rsFontPath, 411 const PresenterTheme::SharedFontDescriptor& rpDefault) 412 { 413 return ReadContext::ReadFont(rxNode, rsFontPath, rpDefault); 414 } 415 416 417 418 419 bool PresenterTheme::ConvertToColor ( 420 const Any& rColorSequence, 421 sal_uInt32& rColor) 422 { 423 Sequence<sal_Int8> aByteSequence; 424 if (rColorSequence >>= aByteSequence) 425 { 426 const sal_Int32 nByteCount (aByteSequence.getLength()); 427 const sal_uInt8* pArray = reinterpret_cast<const sal_uInt8*>(aByteSequence.getConstArray()); 428 rColor = 0; 429 for (sal_Int32 nIndex=0; nIndex<nByteCount; ++nIndex) 430 { 431 rColor = (rColor << 8) | *pArray++; 432 } 433 return true; 434 } 435 else 436 return false; 437 } 438 439 440 441 442 ::boost::shared_ptr<PresenterConfigurationAccess> PresenterTheme::GetNodeForViewStyle ( 443 const ::rtl::OUString& rsStyleName, 444 const PresenterConfigurationAccess::WriteMode) const 445 { 446 if (mpTheme.get() == NULL) 447 return ::boost::shared_ptr<PresenterConfigurationAccess>(); 448 449 // Open configuration for writing. 450 ::boost::shared_ptr<PresenterConfigurationAccess> pConfiguration ( 451 new PresenterConfigurationAccess( 452 mxContext, 453 OUString::createFromAscii("/org.openoffice.Office.extension.PresenterScreen/"), 454 PresenterConfigurationAccess::READ_WRITE)); 455 456 // Get configuration node for the view style container of the current 457 // theme. 458 if (pConfiguration->GoToChild( 459 A2S("Presenter/Themes/") + mpTheme->msConfigurationNodeName + A2S("/ViewStyles"))) 460 { 461 pConfiguration->GoToChild( 462 ::boost::bind(&PresenterConfigurationAccess::IsStringPropertyEqual, 463 rsStyleName, 464 A2S("StyleName"), 465 _2)); 466 } 467 return pConfiguration; 468 } 469 470 471 472 473 ::rtl::OUString PresenterTheme::GetThemeName (void) const 474 { 475 if (mpTheme.get() != NULL) 476 return mpTheme->msThemeName; 477 else 478 return OUString(); 479 } 480 481 482 483 484 SharedBitmapDescriptor PresenterTheme::GetBitmap ( 485 const OUString& rsStyleName, 486 const OUString& rsBitmapName) const 487 { 488 if (mpTheme.get() != NULL) 489 { 490 if (rsStyleName.getLength() == 0) 491 { 492 if (rsBitmapName == A2S("Background")) 493 { 494 ::boost::shared_ptr<Theme> pTheme (mpTheme); 495 while (pTheme.get()!=NULL && pTheme->mpBackground.get()==NULL) 496 pTheme = pTheme->mpParentTheme; 497 if (pTheme.get() != NULL) 498 return pTheme->mpBackground; 499 else 500 return SharedBitmapDescriptor(); 501 } 502 } 503 else 504 { 505 SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName)); 506 if (pPaneStyle.get() != NULL) 507 { 508 SharedBitmapDescriptor pBitmap (pPaneStyle->GetBitmap(rsBitmapName)); 509 if (pBitmap.get() != NULL) 510 return pBitmap; 511 } 512 513 SharedViewStyle pViewStyle (mpTheme->GetViewStyle(rsStyleName)); 514 if (pViewStyle.get() != NULL) 515 { 516 SharedBitmapDescriptor pBitmap (pViewStyle->GetBitmap(rsBitmapName)); 517 if (pBitmap.get() != NULL) 518 return pBitmap; 519 } 520 } 521 } 522 523 return SharedBitmapDescriptor(); 524 } 525 526 527 528 529 SharedBitmapDescriptor PresenterTheme::GetBitmap ( 530 const OUString& rsBitmapName) const 531 { 532 if (mpTheme.get() != NULL) 533 { 534 if (rsBitmapName == A2S("Background")) 535 { 536 ::boost::shared_ptr<Theme> pTheme (mpTheme); 537 while (pTheme.get()!=NULL && pTheme->mpBackground.get()==NULL) 538 pTheme = pTheme->mpParentTheme; 539 if (pTheme.get() != NULL) 540 return pTheme->mpBackground; 541 else 542 return SharedBitmapDescriptor(); 543 } 544 else 545 { 546 if (mpTheme->mpIconContainer.get() != NULL) 547 return mpTheme->mpIconContainer->GetBitmap(rsBitmapName); 548 } 549 } 550 551 return SharedBitmapDescriptor(); 552 } 553 554 555 556 557 ::boost::shared_ptr<PresenterBitmapContainer> PresenterTheme::GetBitmapContainer (void) const 558 { 559 if (mpTheme.get() != NULL) 560 return mpTheme->mpIconContainer; 561 else 562 return ::boost::shared_ptr<PresenterBitmapContainer>(); 563 } 564 565 566 567 568 PresenterTheme::SharedFontDescriptor PresenterTheme::GetFont ( 569 const OUString& rsStyleName) const 570 { 571 if (mpTheme.get() != NULL) 572 { 573 SharedPaneStyle pPaneStyle (mpTheme->GetPaneStyle(rsStyleName)); 574 if (pPaneStyle.get() != NULL) 575 return pPaneStyle->GetFont(); 576 577 SharedViewStyle pViewStyle (mpTheme->GetViewStyle(rsStyleName)); 578 if (pViewStyle.get() != NULL) 579 return pViewStyle->GetFont(); 580 581 ::boost::shared_ptr<Theme> pTheme (mpTheme); 582 while (pTheme.get() != NULL) 583 { 584 Theme::FontContainer::const_iterator iFont (pTheme->maFontContainer.find(rsStyleName)); 585 if (iFont != pTheme->maFontContainer.end()) 586 return iFont->second; 587 588 pTheme = pTheme->mpParentTheme; 589 } 590 } 591 592 return SharedFontDescriptor(); 593 } 594 595 596 597 598 //===== FontDescriptor ======================================================== 599 600 PresenterTheme::FontDescriptor::FontDescriptor (void) 601 : msFamilyName(), 602 msStyleName(), 603 mnSize(12), 604 mnColor(0x00000000), 605 msAnchor(OUString::createFromAscii("Left")), 606 mnXOffset(0), 607 mnYOffset(0) 608 { 609 } 610 611 612 613 614 PresenterTheme::FontDescriptor::FontDescriptor ( 615 const ::boost::shared_ptr<FontDescriptor>& rpDescriptor) 616 : msFamilyName(), 617 msStyleName(), 618 mnSize(12), 619 mnColor(0x00000000), 620 msAnchor(OUString::createFromAscii("Left")), 621 mnXOffset(0), 622 mnYOffset(0) 623 { 624 if (rpDescriptor.get() != NULL) 625 { 626 msFamilyName = rpDescriptor->msFamilyName; 627 msStyleName = rpDescriptor->msStyleName; 628 mnSize = rpDescriptor->mnSize; 629 mnColor = rpDescriptor->mnColor; 630 msAnchor = rpDescriptor->msAnchor; 631 mnXOffset = rpDescriptor->mnXOffset; 632 mnYOffset = rpDescriptor->mnYOffset; 633 } 634 } 635 636 637 638 639 bool PresenterTheme::FontDescriptor::PrepareFont ( 640 const Reference<rendering::XCanvas>& rxCanvas) 641 { 642 if (mxFont.is()) 643 return true; 644 645 if ( ! rxCanvas.is()) 646 return false; 647 648 649 const double nCellSize (GetCellSizeForDesignSize(rxCanvas, mnSize)); 650 mxFont = CreateFont(rxCanvas, nCellSize); 651 652 return mxFont.is(); 653 } 654 655 656 657 658 Reference<rendering::XCanvasFont> PresenterTheme::FontDescriptor::CreateFont ( 659 const Reference<rendering::XCanvas>& rxCanvas, 660 const double nCellSize) const 661 { 662 rendering::FontRequest aFontRequest; 663 aFontRequest.FontDescription.FamilyName = msFamilyName; 664 if (msFamilyName.getLength() == 0) 665 aFontRequest.FontDescription.FamilyName = A2S("Tahoma"); 666 aFontRequest.FontDescription.StyleName = msStyleName; 667 aFontRequest.CellSize = nCellSize; 668 669 // Make an attempt at translating the style name(s)into a corresponding 670 // font description. 671 if (msStyleName == A2S("Bold")) 672 aFontRequest.FontDescription.FontDescription.Weight = rendering::PanoseWeight::HEAVY; 673 674 return rxCanvas->createFont( 675 aFontRequest, 676 Sequence<beans::PropertyValue>(), 677 geometry::Matrix2D(1,0,0,1)); 678 } 679 680 681 682 683 double PresenterTheme::FontDescriptor::GetCellSizeForDesignSize ( 684 const Reference<rendering::XCanvas>& rxCanvas, 685 const double nDesignSize) const 686 { 687 // Use the given design size as initial value in calculating the cell 688 // size. 689 double nCellSize (nDesignSize); 690 691 if ( ! rxCanvas.is()) 692 { 693 // We need the canvas to do the conversion. Return the design size, 694 // it is the our best guess in this circumstance. 695 return nDesignSize; 696 } 697 698 Reference<rendering::XCanvasFont> xFont (CreateFont(rxCanvas, nCellSize)); 699 if ( ! xFont.is()) 700 return nDesignSize; 701 702 geometry::RealRectangle2D aBox (PresenterCanvasHelper::GetTextBoundingBox (xFont, A2S("X"))); 703 704 const double nAscent (-aBox.Y1); 705 const double nDescent (aBox.Y2); 706 const double nScale = (nAscent+nDescent) / nAscent; 707 return nDesignSize * nScale; 708 } 709 710 711 712 713 //===== Theme ================================================================= 714 715 PresenterTheme::Theme::Theme ( 716 const OUString& rsName, 717 const Reference<container::XHierarchicalNameAccess>& rxThemeRoot, 718 const OUString& rsNodeName) 719 : msThemeName(rsName), 720 msConfigurationNodeName(rsNodeName), 721 mpParentTheme(), 722 maPaneStyles(), 723 maViewStyles(), 724 maStyleAssociations(), 725 mxThemeRoot(rxThemeRoot), 726 mpIconContainer() 727 { 728 } 729 730 731 732 733 PresenterTheme::Theme::~Theme (void) 734 { 735 } 736 737 738 739 740 void PresenterTheme::Theme::Read ( 741 PresenterConfigurationAccess& rConfiguration, 742 ReadContext& rReadContext) 743 { 744 PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, A2S("ThemeName")) 745 >>= msThemeName; 746 747 // Parent theme name. 748 OUString sParentThemeName; 749 if ((PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, A2S("ParentTheme")) 750 >>= sParentThemeName) 751 && sParentThemeName.getLength()>0) 752 { 753 mpParentTheme = rReadContext.ReadTheme(rConfiguration, sParentThemeName); 754 } 755 756 // Read the extension that contains the bitmaps referenced in this 757 // theme. 758 OUString sBitmapSourceExtension; 759 if ((PresenterConfigurationAccess::GetConfigurationNode( 760 mxThemeRoot, A2S("BitmapSourceExtension")) >>= sBitmapSourceExtension) 761 && sBitmapSourceExtension.getLength()>0) 762 { 763 rReadContext.SetBitmapSourceExtension(sBitmapSourceExtension); 764 } 765 else 766 { 767 rReadContext.SetBitmapSourceExtension(PresenterComponent::gsExtensionIdentifier); 768 } 769 770 // Background. 771 mpBackground = PresenterBitmapContainer::LoadBitmap( 772 mxThemeRoot, 773 A2S("Background"), 774 rReadContext.mxPresenterHelper, 775 rReadContext.msBasePath, 776 rReadContext.mxCanvas, 777 SharedBitmapDescriptor()); 778 779 // Style associations. 780 maStyleAssociations.Read(rReadContext, mxThemeRoot); 781 782 // Pane styles. 783 maPaneStyles.Read(rReadContext, mxThemeRoot); 784 785 // View styles. 786 maViewStyles.Read(rReadContext, mxThemeRoot); 787 788 // Read bitmaps. 789 mpIconContainer.reset( 790 new PresenterBitmapContainer( 791 Reference<container::XNameAccess>( 792 PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, A2S("Bitmaps")), 793 UNO_QUERY), 794 mpParentTheme.get()!=NULL 795 ? mpParentTheme->mpIconContainer 796 : ::boost::shared_ptr<PresenterBitmapContainer>(), 797 rReadContext.mxComponentContext, 798 rReadContext.mxCanvas, 799 rReadContext.msBasePath)); 800 801 // Read fonts. 802 Reference<container::XNameAccess> xFontNode( 803 PresenterConfigurationAccess::GetConfigurationNode(mxThemeRoot, A2S("Fonts")), 804 UNO_QUERY); 805 PresenterConfigurationAccess::ForAll( 806 xFontNode, 807 ::boost::bind(&PresenterTheme::Theme::ProcessFont, 808 this, ::boost::ref(rReadContext), _1, _2)); 809 } 810 811 812 813 814 SharedPaneStyle PresenterTheme::Theme::GetPaneStyle (const OUString& rsStyleName) const 815 { 816 SharedPaneStyle pPaneStyle (maPaneStyles.GetPaneStyle(rsStyleName)); 817 if (pPaneStyle.get() != NULL) 818 return pPaneStyle; 819 else if (mpParentTheme.get() != NULL) 820 return mpParentTheme->GetPaneStyle(rsStyleName); 821 else 822 return SharedPaneStyle(); 823 } 824 825 826 827 828 SharedViewStyle PresenterTheme::Theme::GetViewStyle (const OUString& rsStyleName) const 829 { 830 SharedViewStyle pViewStyle (maViewStyles.GetViewStyle(rsStyleName)); 831 if (pViewStyle.get() != NULL) 832 return pViewStyle; 833 else if (mpParentTheme.get() != NULL) 834 return mpParentTheme->GetViewStyle(rsStyleName); 835 else 836 return SharedViewStyle(); 837 } 838 839 840 841 842 void PresenterTheme::Theme::ProcessFont( 843 ReadContext& rReadContext, 844 const OUString& rsKey, 845 const Reference<beans::XPropertySet>& rxProperties) 846 { 847 (void)rReadContext; 848 maFontContainer[rsKey] = ReadContext::ReadFont(rxProperties, SharedFontDescriptor()); 849 } 850 851 852 853 854 namespace { 855 856 //===== ReadContext =========================================================== 857 858 ReadContext::ReadContext ( 859 const css::uno::Reference<css::uno::XComponentContext>& rxContext, 860 const Reference<rendering::XCanvas>& rxCanvas) 861 : mxComponentContext(rxContext), 862 mxCanvas(rxCanvas), 863 mxPresenterHelper(), 864 msBasePath() 865 { 866 Reference<lang::XMultiComponentFactory> xFactory (rxContext->getServiceManager()); 867 if (xFactory.is()) 868 { 869 mxPresenterHelper = Reference<drawing::XPresenterHelper>( 870 xFactory->createInstanceWithContext( 871 OUString::createFromAscii("com.sun.star.comp.Draw.PresenterHelper"), 872 rxContext), 873 UNO_QUERY_THROW); 874 } 875 876 // Get base path to bitmaps. 877 SetBitmapSourceExtension(PresenterComponent::gsExtensionIdentifier); 878 } 879 880 881 882 883 ReadContext::~ReadContext (void) 884 { 885 } 886 887 888 889 890 PresenterTheme::SharedFontDescriptor ReadContext::ReadFont ( 891 const Reference<container::XHierarchicalNameAccess>& rxNode, 892 const OUString& rsFontPath, 893 const PresenterTheme::SharedFontDescriptor& rpDefault) 894 { 895 if ( ! rxNode.is()) 896 return PresenterTheme::SharedFontDescriptor(); 897 898 try 899 { 900 Reference<container::XHierarchicalNameAccess> xFont ( 901 PresenterConfigurationAccess::GetConfigurationNode( 902 rxNode, 903 rsFontPath), 904 UNO_QUERY_THROW); 905 906 Reference<beans::XPropertySet> xProperties (xFont, UNO_QUERY_THROW); 907 return ReadFont(xProperties, rpDefault); 908 } 909 catch (Exception&) 910 { 911 OSL_ASSERT(false); 912 } 913 914 return PresenterTheme::SharedFontDescriptor(); 915 } 916 917 918 919 920 PresenterTheme::SharedFontDescriptor ReadContext::ReadFont ( 921 const Reference<beans::XPropertySet>& rxProperties, 922 const PresenterTheme::SharedFontDescriptor& rpDefault) 923 { 924 ::boost::shared_ptr<PresenterTheme::FontDescriptor> pDescriptor ( 925 new PresenterTheme::FontDescriptor(rpDefault)); 926 927 PresenterConfigurationAccess::GetProperty(rxProperties, A2S("FamilyName")) >>= pDescriptor->msFamilyName; 928 PresenterConfigurationAccess::GetProperty(rxProperties, A2S("Style")) >>= pDescriptor->msStyleName; 929 PresenterConfigurationAccess::GetProperty(rxProperties, A2S("Size")) >>= pDescriptor->mnSize; 930 PresenterTheme::ConvertToColor( 931 PresenterConfigurationAccess::GetProperty(rxProperties, A2S("Color")), 932 pDescriptor->mnColor); 933 PresenterConfigurationAccess::GetProperty(rxProperties, A2S("Anchor")) >>= pDescriptor->msAnchor; 934 PresenterConfigurationAccess::GetProperty(rxProperties, A2S("XOffset")) >>= pDescriptor->mnXOffset; 935 PresenterConfigurationAccess::GetProperty(rxProperties, A2S("YOffset")) >>= pDescriptor->mnYOffset; 936 937 return pDescriptor; 938 } 939 940 941 942 943 Any ReadContext::GetByName ( 944 const Reference<container::XNameAccess>& rxNode, 945 const OUString& rsName) const 946 { 947 OSL_ASSERT(rxNode.is()); 948 if (rxNode->hasByName(rsName)) 949 return rxNode->getByName(rsName); 950 else 951 return Any(); 952 } 953 954 955 956 957 ::boost::shared_ptr<PresenterTheme::Theme> ReadContext::ReadTheme ( 958 PresenterConfigurationAccess& rConfiguration, 959 const OUString& rsThemeName) 960 { 961 ::boost::shared_ptr<PresenterTheme::Theme> pTheme; 962 963 OUString sCurrentThemeName (rsThemeName); 964 if (sCurrentThemeName.getLength() == 0) 965 { 966 // No theme name given. Look up the CurrentTheme property. 967 rConfiguration.GetConfigurationNode(A2S("Presenter/CurrentTheme")) >>= sCurrentThemeName; 968 if (sCurrentThemeName.getLength() == 0) 969 { 970 // Still no name. Use "DefaultTheme". 971 sCurrentThemeName = A2S("DefaultTheme"); 972 } 973 } 974 975 Reference<container::XNameAccess> xThemes ( 976 rConfiguration.GetConfigurationNode(A2S("Presenter/Themes")), 977 UNO_QUERY); 978 if (xThemes.is()) 979 { 980 // Iterate over all themes and search the one with the given name. 981 Sequence<OUString> aKeys (xThemes->getElementNames()); 982 for (sal_Int32 nItemIndex=0; nItemIndex<aKeys.getLength(); ++nItemIndex) 983 { 984 const OUString& rsKey (aKeys[nItemIndex]); 985 Reference<container::XHierarchicalNameAccess> xTheme ( 986 xThemes->getByName(rsKey), UNO_QUERY); 987 if (xTheme.is()) 988 { 989 OUString sThemeName; 990 PresenterConfigurationAccess::GetConfigurationNode(xTheme, A2S("ThemeName")) 991 >>= sThemeName; 992 if (sThemeName == sCurrentThemeName) 993 { 994 pTheme.reset(new PresenterTheme::Theme(sThemeName,xTheme,rsKey)); 995 break; 996 } 997 } 998 } 999 } 1000 1001 if (pTheme.get() != NULL) 1002 { 1003 pTheme->Read(rConfiguration, *this); 1004 } 1005 1006 return pTheme; 1007 } 1008 1009 1010 1011 1012 BorderSize ReadContext::ReadBorderSize (const Reference<container::XNameAccess>& rxNode) 1013 { 1014 BorderSize aBorderSize; 1015 1016 if (rxNode.is()) 1017 { 1018 GetByName(rxNode, A2S("Left")) >>= aBorderSize.mnLeft; 1019 GetByName(rxNode, A2S("Top")) >>= aBorderSize.mnTop; 1020 GetByName(rxNode, A2S("Right")) >>= aBorderSize.mnRight; 1021 GetByName(rxNode, A2S("Bottom")) >>= aBorderSize.mnBottom; 1022 } 1023 1024 return aBorderSize; 1025 } 1026 1027 1028 1029 1030 void ReadContext::SetBitmapSourceExtension (const OUString& rsExtensionIdentifier) 1031 { 1032 // Get base path to bitmaps. 1033 msBasePath = PresenterComponent::GetBasePath(mxComponentContext, rsExtensionIdentifier); 1034 } 1035 1036 1037 1038 1039 //===== PaneStyleContainer ==================================================== 1040 1041 void PaneStyleContainer::Read ( 1042 ReadContext& rReadContext, 1043 const Reference<container::XHierarchicalNameAccess>& rxThemeRoot) 1044 { 1045 Reference<container::XNameAccess> xPaneStyleList ( 1046 PresenterConfigurationAccess::GetConfigurationNode( 1047 rxThemeRoot, 1048 A2S("PaneStyles")), 1049 UNO_QUERY); 1050 if (xPaneStyleList.is()) 1051 { 1052 ::std::vector<rtl::OUString> aProperties; 1053 aProperties.reserve(6); 1054 aProperties.push_back(A2S("StyleName")); 1055 aProperties.push_back(A2S("ParentStyle")); 1056 aProperties.push_back(A2S("TitleFont")); 1057 aProperties.push_back(A2S("InnerBorderSize")); 1058 aProperties.push_back(A2S("OuterBorderSize")); 1059 aProperties.push_back(A2S("BorderBitmapList")); 1060 PresenterConfigurationAccess::ForAll( 1061 xPaneStyleList, 1062 aProperties, 1063 ::boost::bind(&PaneStyleContainer::ProcessPaneStyle, 1064 this, ::boost::ref(rReadContext), _1, _2)); 1065 } 1066 } 1067 1068 1069 1070 1071 void PaneStyleContainer::ProcessPaneStyle( 1072 ReadContext& rReadContext, 1073 const OUString& rsKey, 1074 const ::std::vector<Any>& rValues) 1075 { 1076 (void)rsKey; 1077 1078 if (rValues.size() != 6) 1079 return; 1080 1081 ::boost::shared_ptr<PaneStyle> pStyle (new PaneStyle()); 1082 1083 rValues[0] >>= pStyle->msStyleName; 1084 1085 OUString sParentStyleName; 1086 if (rValues[1] >>= sParentStyleName) 1087 { 1088 // Find parent style. 1089 PaneStyleContainer::const_iterator iStyle; 1090 for (iStyle=begin(); iStyle!=end(); ++iStyle) 1091 if ((*iStyle)->msStyleName.equals(sParentStyleName)) 1092 { 1093 pStyle->mpParentStyle = *iStyle; 1094 break; 1095 } 1096 } 1097 1098 Reference<container::XHierarchicalNameAccess> xFontNode (rValues[2], UNO_QUERY); 1099 pStyle->mpFont = rReadContext.ReadFont( 1100 xFontNode, A2S(""), PresenterTheme::SharedFontDescriptor()); 1101 1102 Reference<container::XNameAccess> xInnerBorderSizeNode (rValues[3], UNO_QUERY); 1103 pStyle->maInnerBorderSize = rReadContext.ReadBorderSize(xInnerBorderSizeNode); 1104 Reference<container::XNameAccess> xOuterBorderSizeNode (rValues[4], UNO_QUERY); 1105 pStyle->maOuterBorderSize = rReadContext.ReadBorderSize(xOuterBorderSizeNode); 1106 1107 if (pStyle->mpParentStyle.get() != NULL) 1108 { 1109 pStyle->maInnerBorderSize.Merge(pStyle->mpParentStyle->maInnerBorderSize); 1110 pStyle->maOuterBorderSize.Merge(pStyle->mpParentStyle->maOuterBorderSize); 1111 } 1112 1113 if (rReadContext.mxCanvas.is()) 1114 { 1115 Reference<container::XNameAccess> xBitmapsNode (rValues[5], UNO_QUERY); 1116 pStyle->mpBitmaps.reset(new PresenterBitmapContainer( 1117 xBitmapsNode, 1118 pStyle->mpParentStyle.get()!=NULL 1119 ? pStyle->mpParentStyle->mpBitmaps 1120 : ::boost::shared_ptr<PresenterBitmapContainer>(), 1121 rReadContext.mxComponentContext, 1122 rReadContext.mxCanvas, 1123 rReadContext.msBasePath, 1124 rReadContext.mxPresenterHelper)); 1125 } 1126 1127 push_back(pStyle); 1128 } 1129 1130 1131 1132 1133 SharedPaneStyle PaneStyleContainer::GetPaneStyle (const OUString& rsStyleName) const 1134 { 1135 const_iterator iEnd (end()); 1136 for (const_iterator iStyle=begin(); iStyle!=iEnd; ++iStyle) 1137 if ((*iStyle)->msStyleName == rsStyleName) 1138 return *iStyle; 1139 return SharedPaneStyle(); 1140 } 1141 1142 1143 1144 1145 //===== PaneStyle ============================================================= 1146 1147 PaneStyle::PaneStyle (void) 1148 : msStyleName(), 1149 mpParentStyle(), 1150 mpFont(), 1151 maInnerBorderSize(), 1152 maOuterBorderSize(), 1153 mpBitmaps() 1154 { 1155 } 1156 1157 1158 1159 1160 PaneStyle::~PaneStyle (void) 1161 { 1162 } 1163 1164 1165 1166 1167 void PaneStyle::UpdateBorderSize (BorderSize& rBorderSize, bool bInner) 1168 { 1169 if (mpParentStyle.get() != NULL) 1170 mpParentStyle->UpdateBorderSize(rBorderSize, bInner); 1171 1172 BorderSize& rThisBorderSize (bInner ? maInnerBorderSize : maOuterBorderSize); 1173 if (rThisBorderSize.mnLeft >= 0) 1174 rBorderSize.mnLeft = rThisBorderSize.mnLeft; 1175 if (rThisBorderSize.mnTop >= 0) 1176 rBorderSize.mnTop = rThisBorderSize.mnTop; 1177 if (rThisBorderSize.mnRight >= 0) 1178 rBorderSize.mnRight = rThisBorderSize.mnRight; 1179 if (rThisBorderSize.mnBottom >= 0) 1180 rBorderSize.mnBottom = rThisBorderSize.mnBottom; 1181 } 1182 1183 1184 1185 1186 const SharedBitmapDescriptor PaneStyle::GetBitmap (const OUString& rsBitmapName) const 1187 { 1188 if (mpBitmaps.get() != NULL) 1189 { 1190 const SharedBitmapDescriptor pBitmap = mpBitmaps->GetBitmap(rsBitmapName); 1191 if (pBitmap.get() != NULL) 1192 return pBitmap; 1193 } 1194 1195 if (mpParentStyle.get() != NULL) 1196 return mpParentStyle->GetBitmap(rsBitmapName); 1197 else 1198 return SharedBitmapDescriptor(); 1199 } 1200 1201 1202 1203 1204 PresenterTheme::SharedFontDescriptor PaneStyle::GetFont (void) const 1205 { 1206 if (mpFont.get() != NULL) 1207 return mpFont; 1208 else if (mpParentStyle.get() != NULL) 1209 return mpParentStyle->GetFont(); 1210 else 1211 return PresenterTheme::SharedFontDescriptor(); 1212 } 1213 1214 1215 1216 1217 //===== ViewStyleContainer ==================================================== 1218 1219 void ViewStyleContainer::Read ( 1220 ReadContext& rReadContext, 1221 const Reference<container::XHierarchicalNameAccess>& rxThemeRoot) 1222 { 1223 (void)rReadContext; 1224 1225 Reference<container::XNameAccess> xViewStyleList ( 1226 PresenterConfigurationAccess::GetConfigurationNode( 1227 rxThemeRoot, 1228 A2S("ViewStyles")), 1229 UNO_QUERY); 1230 if (xViewStyleList.is()) 1231 { 1232 PresenterConfigurationAccess::ForAll( 1233 xViewStyleList, 1234 ::boost::bind(&ViewStyleContainer::ProcessViewStyle, 1235 this, ::boost::ref(rReadContext), _2)); 1236 } 1237 } 1238 1239 1240 1241 1242 void ViewStyleContainer::ProcessViewStyle( 1243 ReadContext& rReadContext, 1244 const Reference<beans::XPropertySet>& rxProperties) 1245 { 1246 ::boost::shared_ptr<ViewStyle> pStyle (new ViewStyle()); 1247 1248 PresenterConfigurationAccess::GetProperty(rxProperties, A2S("StyleName")) 1249 >>= pStyle->msStyleName; 1250 1251 OUString sParentStyleName; 1252 if (PresenterConfigurationAccess::GetProperty(rxProperties, A2S("ParentStyle")) 1253 >>= sParentStyleName) 1254 { 1255 // Find parent style. 1256 ViewStyleContainer::const_iterator iStyle; 1257 for (iStyle=begin(); iStyle!=end(); ++iStyle) 1258 if ((*iStyle)->msStyleName.equals(sParentStyleName)) 1259 { 1260 pStyle->mpParentStyle = *iStyle; 1261 pStyle->mpFont = (*iStyle)->mpFont; 1262 pStyle->mpBackground = (*iStyle)->mpBackground; 1263 break; 1264 } 1265 } 1266 1267 const OUString sPathToFont; // empty string 1268 Reference<container::XHierarchicalNameAccess> xFontNode ( 1269 PresenterConfigurationAccess::GetProperty(rxProperties, A2S("Font")), UNO_QUERY); 1270 PresenterTheme::SharedFontDescriptor pFont ( 1271 rReadContext.ReadFont(xFontNode, sPathToFont, PresenterTheme::SharedFontDescriptor())); 1272 if (pFont.get() != NULL) 1273 pStyle->mpFont = pFont; 1274 1275 Reference<container::XHierarchicalNameAccess> xBackgroundNode ( 1276 PresenterConfigurationAccess::GetProperty(rxProperties, A2S("Background")), 1277 UNO_QUERY); 1278 SharedBitmapDescriptor pBackground (PresenterBitmapContainer::LoadBitmap( 1279 xBackgroundNode, 1280 OUString(), 1281 rReadContext.mxPresenterHelper, 1282 rReadContext.msBasePath, 1283 rReadContext.mxCanvas, 1284 SharedBitmapDescriptor())); 1285 if (pBackground.get() != NULL && pBackground->GetNormalBitmap().is()) 1286 pStyle->mpBackground = pBackground; 1287 1288 push_back(pStyle); 1289 } 1290 1291 1292 1293 1294 SharedViewStyle ViewStyleContainer::GetViewStyle (const OUString& rsStyleName) const 1295 { 1296 const_iterator iEnd (end()); 1297 for (const_iterator iStyle=begin(); iStyle!=iEnd; ++iStyle) 1298 if ((*iStyle)->msStyleName == rsStyleName) 1299 return *iStyle; 1300 return SharedViewStyle(); 1301 } 1302 1303 1304 1305 1306 //===== ViewStyle ============================================================= 1307 1308 ViewStyle::ViewStyle (void) 1309 : msStyleName(), 1310 mpParentStyle(), 1311 mpFont(), 1312 mpBackground() 1313 { 1314 } 1315 1316 1317 1318 1319 ViewStyle::~ViewStyle (void) 1320 { 1321 } 1322 1323 1324 1325 1326 const SharedBitmapDescriptor ViewStyle::GetBitmap (const OUString& rsBitmapName) const 1327 { 1328 if (rsBitmapName == A2S("Background")) 1329 return mpBackground; 1330 else 1331 return SharedBitmapDescriptor(); 1332 } 1333 1334 1335 1336 1337 PresenterTheme::SharedFontDescriptor ViewStyle::GetFont (void) const 1338 { 1339 if (mpFont.get() != NULL) 1340 return mpFont; 1341 else if (mpParentStyle.get() != NULL) 1342 return mpParentStyle->GetFont(); 1343 else 1344 return PresenterTheme::SharedFontDescriptor(); 1345 } 1346 1347 1348 1349 1350 //===== StyleAssociationContainer ============================================= 1351 1352 void StyleAssociationContainer::Read ( 1353 ReadContext& rReadContext, 1354 const Reference<container::XHierarchicalNameAccess>& rxThemeRoot) 1355 { 1356 Reference<container::XNameAccess> xStyleAssociationList ( 1357 PresenterConfigurationAccess::GetConfigurationNode( 1358 rxThemeRoot, 1359 A2S("StyleAssociations")), 1360 UNO_QUERY); 1361 if (xStyleAssociationList.is()) 1362 { 1363 ::std::vector<rtl::OUString> aProperties (2); 1364 aProperties[0] = A2S("ResourceURL"); 1365 aProperties[1] = A2S("StyleName"); 1366 PresenterConfigurationAccess::ForAll( 1367 xStyleAssociationList, 1368 aProperties, 1369 ::boost::bind(&StyleAssociationContainer::ProcessStyleAssociation, 1370 this, ::boost::ref(rReadContext), _1, _2)); 1371 } 1372 } 1373 1374 1375 1376 1377 OUString StyleAssociationContainer::GetStyleName (const OUString& rsResourceName) const 1378 { 1379 StyleAssociations::const_iterator iAssociation (maStyleAssociations.find(rsResourceName)); 1380 if (iAssociation != maStyleAssociations.end()) 1381 return iAssociation->second; 1382 else 1383 return OUString(); 1384 } 1385 1386 1387 1388 1389 void StyleAssociationContainer::ProcessStyleAssociation( 1390 ReadContext& rReadContext, 1391 const OUString& rsKey, 1392 const ::std::vector<Any>& rValues) 1393 { 1394 (void)rReadContext; 1395 (void)rsKey; 1396 1397 if (rValues.size() != 2) 1398 return; 1399 1400 OUString sResourceURL; 1401 OUString sStyleName; 1402 if ((rValues[0] >>= sResourceURL) 1403 && (rValues[1] >>= sStyleName)) 1404 { 1405 maStyleAssociations[sResourceURL] = sStyleName; 1406 } 1407 } 1408 1409 1410 1411 1412 } // end of anonymous namespace 1413 1414 } } // end of namespace ::sdext::presenter 1415