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