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 "PresenterToolBar.hxx" 32 33 #include "PresenterBitmapContainer.hxx" 34 #include "PresenterCanvasHelper.hxx" 35 #include "PresenterComponent.hxx" 36 #include "PresenterGeometryHelper.hxx" 37 #include "PresenterPaintManager.hxx" 38 #include "PresenterPaneBase.hxx" 39 #include "PresenterPaneFactory.hxx" 40 #include "PresenterTimer.hxx" 41 #include "PresenterWindowManager.hxx" 42 43 #include <cppuhelper/compbase2.hxx> 44 #include <com/sun/star/awt/FontDescriptor.hpp> 45 #include <com/sun/star/awt/PosSize.hpp> 46 #include <com/sun/star/awt/XWindowPeer.hpp> 47 #include <com/sun/star/deployment/XPackageInformationProvider.hpp> 48 #include <com/sun/star/drawing/framework/XControllerManager.hpp> 49 #include <com/sun/star/drawing/framework/XConfigurationController.hpp> 50 #include <com/sun/star/drawing/framework/XPane.hpp> 51 #include <com/sun/star/geometry/AffineMatrix2D.hpp> 52 #include <com/sun/star/lang/XServiceName.hpp> 53 #include <com/sun/star/rendering/CompositeOperation.hpp> 54 #include <com/sun/star/rendering/RenderState.hpp> 55 #include <com/sun/star/rendering/TextDirection.hpp> 56 #include <com/sun/star/rendering/ViewState.hpp> 57 #include <com/sun/star/rendering/XSpriteCanvas.hpp> 58 #include <com/sun/star/text/XTextRange.hpp> 59 #include <com/sun/star/util/Color.hpp> 60 #include <com/sun/star/util/XURLTransformer.hpp> 61 #include <rtl/ustrbuf.hxx> 62 #include <boost/bind.hpp> 63 #include <boost/function.hpp> 64 #include <boost/enable_shared_from_this.hpp> 65 #include <map> 66 67 using namespace ::com::sun::star; 68 using namespace ::com::sun::star::uno; 69 using namespace ::com::sun::star::drawing::framework; 70 using ::rtl::OUString; 71 72 #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString))) 73 74 namespace sdext { namespace presenter { 75 76 static const sal_Int32 gnGapSize (20); 77 static const sal_Int32 gnMinimalSeparatorSize (20); 78 static const sal_Int32 gnSeparatorInset (0); 79 80 namespace { 81 82 class Text 83 { 84 public: 85 Text (void); 86 Text (const Text& rText); 87 Text ( 88 const OUString& rsText, 89 const PresenterTheme::SharedFontDescriptor& rpFont); 90 91 void SetText (const OUString& rsText); 92 OUString GetText (void) const; 93 PresenterTheme::SharedFontDescriptor GetFont (void) const; 94 95 void Paint ( 96 const Reference<rendering::XCanvas>& rxCanvas, 97 const rendering::ViewState& rViewState, 98 const awt::Rectangle& rBoundingBox, 99 const awt::Point& rOffset); 100 101 geometry::RealRectangle2D GetBoundingBox ( 102 const Reference<rendering::XCanvas>& rxCanvas); 103 104 private: 105 OUString msText; 106 PresenterTheme::SharedFontDescriptor mpFont; 107 }; 108 109 class ElementMode 110 : private ::boost::noncopyable 111 { 112 public: 113 ElementMode (void); 114 115 SharedBitmapDescriptor mpIcon; 116 OUString msAction; 117 Text maText; 118 119 void ReadElementMode ( 120 const Reference<beans::XPropertySet>& rxProperties, 121 const ::rtl::OUString& rsModeName, 122 ::boost::shared_ptr<ElementMode>& rpDefaultMode, 123 ::sdext::presenter::PresenterToolBar::Context& rContext); 124 }; 125 typedef ::boost::shared_ptr<ElementMode> SharedElementMode; 126 127 } // end of anonymous namespace 128 129 130 class PresenterToolBar::Context 131 : private ::boost::noncopyable 132 { 133 public: 134 ::rtl::OUString msBasePath; 135 Reference<drawing::XPresenterHelper> mxPresenterHelper; 136 css::uno::Reference<css::rendering::XCanvas> mxCanvas; 137 }; 138 139 140 141 142 //===== PresenterToolBar::Element ============================================= 143 144 namespace { 145 typedef cppu::WeakComponentImplHelper2< 146 css::document::XEventListener, 147 css::frame::XStatusListener 148 > ElementInterfaceBase; 149 150 class Element 151 : private ::cppu::BaseMutex, 152 private ::boost::noncopyable, 153 public ElementInterfaceBase 154 { 155 public: 156 Element (const ::rtl::Reference<PresenterToolBar>& rpToolBar); 157 virtual ~Element (void); 158 159 virtual void SAL_CALL disposing (void); 160 161 virtual void SetModes ( 162 const SharedElementMode& rpNormalMode, 163 const SharedElementMode& rpMouseOverMode, 164 const SharedElementMode& rpSelectedMode, 165 const SharedElementMode& rpDisabledMode); 166 virtual void CurrentSlideHasChanged (void); 167 virtual void SetLocation (const awt::Point& rLocation); 168 virtual void SetSize (const geometry::RealSize2D& rSize); 169 virtual void Paint ( 170 const Reference<rendering::XCanvas>& rxCanvas, 171 const rendering::ViewState& rViewState) = 0; 172 awt::Size GetBoundingSize ( 173 const Reference<rendering::XCanvas>& rxCanvas); 174 awt::Rectangle GetBoundingBox (void) const; 175 virtual bool SetState (const bool bIsOver, const bool bIsPressed); 176 virtual void Invalidate (const bool bSynchronous = true); 177 virtual bool IsOutside (const awt::Rectangle& rBox); 178 virtual bool IsFilling (void) const; 179 void UpdateState (void); 180 181 OUString GetAction (void) const; 182 183 // lang::XEventListener 184 185 virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent) 186 throw(css::uno::RuntimeException); 187 188 // document::XEventListener 189 190 virtual void SAL_CALL notifyEvent (const css::document::EventObject& rEvent) 191 throw(css::uno::RuntimeException); 192 193 // frame::XStatusListener 194 195 virtual void SAL_CALL statusChanged (const css::frame::FeatureStateEvent& rEvent) 196 throw(css::uno::RuntimeException); 197 198 protected: 199 ::rtl::Reference<PresenterToolBar> mpToolBar; 200 awt::Point maLocation; 201 awt::Size maSize; 202 SharedElementMode mpNormal; 203 SharedElementMode mpMouseOver; 204 SharedElementMode mpSelected; 205 SharedElementMode mpDisabled; 206 SharedElementMode mpMode; 207 bool mbIsOver; 208 bool mbIsPressed; 209 bool mbIsSelected; 210 211 virtual awt::Size CreateBoundingSize ( 212 const Reference<rendering::XCanvas>& rxCanvas) = 0; 213 214 bool IsEnabled (void) const; 215 void SetEnabledState (const bool bIsEnabled); 216 217 private: 218 bool mbIsEnabled; 219 }; 220 221 } // end of anonymous namespace 222 223 224 class PresenterToolBar::ElementContainerPart 225 : public ::std::vector<rtl::Reference<Element> > 226 { 227 }; 228 229 230 231 232 //===== Button ================================================================ 233 234 namespace { 235 236 class Button : public Element 237 { 238 public: 239 static ::rtl::Reference<Element> Create ( 240 const ::rtl::Reference<PresenterToolBar>& rpToolBar); 241 242 virtual ~Button (void); 243 virtual void SAL_CALL disposing (void); 244 245 virtual void Paint ( 246 const Reference<rendering::XCanvas>& rxCanvas, 247 const rendering::ViewState& rViewState); 248 249 // lang::XEventListener 250 251 virtual void SAL_CALL disposing (const css::lang::EventObject& rEvent) 252 throw(css::uno::RuntimeException); 253 254 protected: 255 virtual awt::Size CreateBoundingSize ( 256 const Reference<rendering::XCanvas>& rxCanvas); 257 258 private: 259 bool mbIsListenerRegistered; 260 261 Button (const ::rtl::Reference<PresenterToolBar>& rpToolBar); 262 void Initialize (void); 263 void PaintIcon ( 264 const Reference<rendering::XCanvas>& rxCanvas, 265 const sal_Int32 nTextHeight, 266 const rendering::ViewState& rViewState); 267 PresenterBitmapDescriptor::Mode GetMode (void) const; 268 }; 269 270 271 272 273 //===== Label ================================================================= 274 275 class Label : public Element 276 { 277 public: 278 Label (const ::rtl::Reference<PresenterToolBar>& rpToolBar); 279 280 void SetText (const OUString& rsText); 281 virtual void Paint ( 282 const Reference<rendering::XCanvas>& rxCanvas, 283 const rendering::ViewState& rViewState); 284 virtual bool SetState (const bool bIsOver, const bool bIsPressed); 285 286 protected: 287 virtual awt::Size CreateBoundingSize ( 288 const Reference<rendering::XCanvas>& rxCanvas); 289 }; 290 291 292 // Some specialized controls. 293 294 295 class ProgressLabel : public Label 296 { 297 public: 298 ProgressLabel (const ::rtl::Reference<PresenterToolBar>& rpToolBar); 299 virtual void CurrentSlideHasChanged (void); 300 }; 301 302 class TimeFormatter 303 { 304 public: 305 TimeFormatter (void); 306 OUString FormatTime (const oslDateTime& rTime); 307 private: 308 bool mbIs24HourFormat; 309 bool mbIsAmPmFormat; 310 bool mbIsShowSeconds; 311 }; 312 313 class TimeLabel : public Label 314 { 315 public: 316 void ConnectToTimer (void); 317 virtual void TimeHasChanged (const oslDateTime& rCurrentTime) = 0; 318 protected: 319 TimeLabel(const ::rtl::Reference<PresenterToolBar>& rpToolBar); 320 using Element::disposing; 321 virtual void SAL_CALL disposing (void); 322 private: 323 class Listener : public PresenterClockTimer::Listener 324 { 325 public: 326 Listener (const ::rtl::Reference<TimeLabel>& rxLabel) 327 : mxLabel(rxLabel) {} 328 virtual ~Listener (void) {} 329 virtual void TimeHasChanged (const oslDateTime& rCurrentTime) 330 { if (mxLabel.is()) mxLabel->TimeHasChanged(rCurrentTime); } 331 private: 332 ::rtl::Reference<TimeLabel> mxLabel; 333 }; 334 ::boost::shared_ptr<PresenterClockTimer::Listener> mpListener; 335 }; 336 337 class CurrentTimeLabel : public TimeLabel 338 { 339 public: 340 static ::rtl::Reference<Element> Create ( 341 const ::rtl::Reference<PresenterToolBar>& rpToolBar); 342 virtual void SetModes ( 343 const SharedElementMode& rpNormalMode, 344 const SharedElementMode& rpMouseOverMode, 345 const SharedElementMode& rpSelectedMode, 346 const SharedElementMode& rpDisabledMode); 347 private: 348 TimeFormatter maTimeFormatter; 349 CurrentTimeLabel (const ::rtl::Reference<PresenterToolBar>& rpToolBar); 350 virtual ~CurrentTimeLabel (void); 351 virtual void TimeHasChanged (const oslDateTime& rCurrentTime); 352 }; 353 354 class PresentationTimeLabel : public TimeLabel 355 { 356 public: 357 static ::rtl::Reference<Element> Create ( 358 const ::rtl::Reference<PresenterToolBar>& rpToolBar); 359 virtual void SetModes ( 360 const SharedElementMode& rpNormalMode, 361 const SharedElementMode& rpMouseOverMode, 362 const SharedElementMode& rpSelectedMode, 363 const SharedElementMode& rpDisabledMode); 364 private: 365 TimeFormatter maTimeFormatter; 366 TimeValue maStartTimeValue; 367 PresentationTimeLabel (const ::rtl::Reference<PresenterToolBar>& rpToolBar); 368 virtual ~PresentationTimeLabel (void); 369 virtual void TimeHasChanged (const oslDateTime& rCurrentTime); 370 }; 371 372 class VerticalSeparator : public Element 373 { 374 public: 375 explicit VerticalSeparator (const ::rtl::Reference<PresenterToolBar>& rpToolBar); 376 virtual void Paint ( 377 const Reference<rendering::XCanvas>& rxCanvas, 378 const rendering::ViewState& rViewState); 379 virtual bool IsFilling (void) const; 380 381 protected: 382 virtual awt::Size CreateBoundingSize ( 383 const Reference<rendering::XCanvas>& rxCanvas); 384 }; 385 386 class HorizontalSeparator : public Element 387 { 388 public: 389 explicit HorizontalSeparator (const ::rtl::Reference<PresenterToolBar>& rpToolBar); 390 virtual void Paint ( 391 const Reference<rendering::XCanvas>& rxCanvas, 392 const rendering::ViewState& rViewState); 393 virtual bool IsFilling (void) const; 394 395 protected: 396 virtual awt::Size CreateBoundingSize ( 397 const Reference<rendering::XCanvas>& rxCanvas); 398 }; 399 } // end of anonymous namespace 400 401 402 403 //===== PresenterToolBar ====================================================== 404 405 PresenterToolBar::PresenterToolBar ( 406 const Reference<XComponentContext>& rxContext, 407 const css::uno::Reference<css::awt::XWindow>& rxWindow, 408 const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, 409 const ::rtl::Reference<PresenterController>& rpPresenterController, 410 const Anchor eAnchor) 411 : PresenterToolBarInterfaceBase(m_aMutex), 412 mxComponentContext(rxContext), 413 maElementContainer(), 414 mpCurrentContainerPart(), 415 mxWindow(rxWindow), 416 mxCanvas(rxCanvas), 417 mxSlideShowController(), 418 mxCurrentSlide(), 419 mpPresenterController(rpPresenterController), 420 mbIsLayoutPending(false), 421 meAnchor(eAnchor), 422 maBoundingBox(), 423 maMinimalSize() 424 { 425 } 426 427 428 429 430 void PresenterToolBar::Initialize ( 431 const ::rtl::OUString& rsConfigurationPath) 432 { 433 try 434 { 435 CreateControls(rsConfigurationPath); 436 437 if (mxWindow.is()) 438 { 439 mxWindow->addWindowListener(this); 440 mxWindow->addPaintListener(this); 441 mxWindow->addMouseListener(this); 442 mxWindow->addMouseMotionListener(this); 443 444 Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY); 445 if (xPeer.is()) 446 xPeer->setBackground(util::Color(0xff000000)); 447 448 mxWindow->setVisible(sal_True); 449 } 450 451 mxSlideShowController = mpPresenterController->GetSlideShowController(); 452 UpdateSlideNumber(); 453 mbIsLayoutPending = true; 454 } 455 catch (RuntimeException&) 456 { 457 mpCurrentContainerPart.reset(); 458 maElementContainer.clear(); 459 throw; 460 } 461 } 462 463 464 465 466 PresenterToolBar::~PresenterToolBar (void) 467 { 468 } 469 470 471 472 473 void SAL_CALL PresenterToolBar::disposing (void) 474 { 475 if (mxWindow.is()) 476 { 477 mxWindow->removeWindowListener(this); 478 mxWindow->removePaintListener(this); 479 mxWindow->removeMouseListener(this); 480 mxWindow->removeMouseMotionListener(this); 481 mxWindow = NULL; 482 } 483 484 // Dispose tool bar elements. 485 ElementContainer::iterator iPart (maElementContainer.begin()); 486 ElementContainer::const_iterator iEnd (maElementContainer.end()); 487 for ( ; iPart!=iEnd; ++iPart) 488 { 489 OSL_ASSERT(iPart->get()!=NULL); 490 ElementContainerPart::iterator iElement ((*iPart)->begin()); 491 ElementContainerPart::const_iterator iPartEnd ((*iPart)->end()); 492 for ( ; iElement!=iPartEnd; ++iElement) 493 { 494 if (iElement->get() != NULL) 495 { 496 ::rtl::Reference<Element> pElement (*iElement); 497 Reference<lang::XComponent> xComponent ( 498 static_cast<XWeak*>(pElement.get()), UNO_QUERY); 499 if (xComponent.is()) 500 xComponent->dispose(); 501 } 502 } 503 } 504 505 mpCurrentContainerPart.reset(); 506 maElementContainer.clear(); 507 } 508 509 510 511 512 void PresenterToolBar::InvalidateArea ( 513 const awt::Rectangle& rRepaintBox, 514 const bool bSynchronous) 515 { 516 mpPresenterController->GetPaintManager()->Invalidate( 517 mxWindow, 518 rRepaintBox, 519 bSynchronous); 520 } 521 522 523 524 525 sal_Int32 PresenterToolBar::GetCurrentSlideIndex (void) 526 { 527 if (mxSlideShowController.is()) 528 return mxSlideShowController->getCurrentSlideIndex(); 529 else 530 return -1; 531 } 532 533 534 535 536 sal_Int32 PresenterToolBar::GetSlideCount (void) 537 { 538 if (mxSlideShowController.is()) 539 return mxSlideShowController->getSlideCount(); 540 else 541 return 0; 542 } 543 544 545 546 547 void PresenterToolBar::RequestLayout (void) 548 { 549 mbIsLayoutPending = true; 550 551 mpPresenterController->GetPaintManager()->Invalidate(mxWindow); 552 } 553 554 555 556 557 geometry::RealSize2D PresenterToolBar::GetSize (void) 558 { 559 if (mbIsLayoutPending) 560 Layout(mxCanvas); 561 return geometry::RealSize2D( 562 maBoundingBox.X2 - maBoundingBox.X1, 563 maBoundingBox.Y2 - maBoundingBox.Y1); 564 } 565 566 567 568 569 geometry::RealSize2D PresenterToolBar::GetMinimalSize (void) 570 { 571 if (mbIsLayoutPending) 572 Layout(mxCanvas); 573 return maMinimalSize; 574 } 575 576 577 578 579 ::rtl::Reference<PresenterController> PresenterToolBar::GetPresenterController (void) const 580 { 581 return mpPresenterController; 582 } 583 584 585 586 587 Reference<awt::XWindow> PresenterToolBar::GetWindow (void) const 588 { 589 return mxWindow; 590 } 591 592 593 594 595 Reference<XComponentContext> PresenterToolBar::GetComponentContext (void) const 596 { 597 return mxComponentContext; 598 } 599 600 601 602 603 //----- lang::XEventListener ------------------------------------------------- 604 605 void SAL_CALL PresenterToolBar::disposing (const lang::EventObject& rEventObject) 606 throw (RuntimeException) 607 { 608 if (rEventObject.Source == mxWindow) 609 mxWindow = NULL; 610 } 611 612 613 614 615 //----- XWindowListener ------------------------------------------------------- 616 617 void SAL_CALL PresenterToolBar::windowResized (const awt::WindowEvent& rEvent) 618 throw (RuntimeException) 619 { 620 (void)rEvent; 621 mbIsLayoutPending = true; 622 } 623 624 625 626 627 void SAL_CALL PresenterToolBar::windowMoved (const awt::WindowEvent& rEvent) 628 throw (RuntimeException) 629 { 630 (void)rEvent; 631 } 632 633 634 635 636 void SAL_CALL PresenterToolBar::windowShown (const lang::EventObject& rEvent) 637 throw (RuntimeException) 638 { 639 (void)rEvent; 640 mbIsLayoutPending = true; 641 } 642 643 644 645 646 void SAL_CALL PresenterToolBar::windowHidden (const lang::EventObject& rEvent) 647 throw (RuntimeException) 648 { 649 (void)rEvent; 650 } 651 652 653 654 655 //----- XPaintListener -------------------------------------------------------- 656 657 void SAL_CALL PresenterToolBar::windowPaint (const css::awt::PaintEvent& rEvent) 658 throw (RuntimeException) 659 { 660 if ( ! mxCanvas.is()) 661 return; 662 663 if ( ! mbIsPresenterViewActive) 664 return; 665 666 const rendering::ViewState aViewState ( 667 geometry::AffineMatrix2D(1,0,0, 0,1,0), 668 PresenterGeometryHelper::CreatePolygon(rEvent.UpdateRect, mxCanvas->getDevice())); 669 670 if (mbIsLayoutPending) 671 Layout(mxCanvas); 672 673 Paint(rEvent.UpdateRect, aViewState); 674 675 // Make the back buffer visible. 676 Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY); 677 if (xSpriteCanvas.is()) 678 xSpriteCanvas->updateScreen(sal_False); 679 } 680 681 682 683 684 //----- XMouseListener -------------------------------------------------------- 685 686 void SAL_CALL PresenterToolBar::mousePressed (const css::awt::MouseEvent& rEvent) 687 throw(css::uno::RuntimeException) 688 { 689 CheckMouseOver(rEvent, true, true); 690 } 691 692 693 694 695 void SAL_CALL PresenterToolBar::mouseReleased (const css::awt::MouseEvent& rEvent) 696 throw(css::uno::RuntimeException) 697 { 698 CheckMouseOver(rEvent, true); 699 } 700 701 702 703 704 void SAL_CALL PresenterToolBar::mouseEntered (const css::awt::MouseEvent& rEvent) 705 throw(css::uno::RuntimeException) 706 { 707 CheckMouseOver(rEvent, true); 708 } 709 710 711 712 713 void SAL_CALL PresenterToolBar::mouseExited (const css::awt::MouseEvent& rEvent) 714 throw(css::uno::RuntimeException) 715 { 716 CheckMouseOver(rEvent, false); 717 } 718 719 720 721 722 //----- XMouseMotionListener -------------------------------------------------- 723 724 void SAL_CALL PresenterToolBar::mouseMoved (const css::awt::MouseEvent& rEvent) 725 throw (css::uno::RuntimeException) 726 { 727 ThrowIfDisposed(); 728 729 CheckMouseOver(rEvent, true); 730 } 731 732 733 734 735 void SAL_CALL PresenterToolBar::mouseDragged (const css::awt::MouseEvent& rEvent) 736 throw (css::uno::RuntimeException) 737 { 738 ThrowIfDisposed(); 739 (void)rEvent; 740 } 741 742 743 744 745 //----- XDrawView ------------------------------------------------------------- 746 747 void SAL_CALL PresenterToolBar::setCurrentPage (const Reference<drawing::XDrawPage>& rxSlide) 748 throw (RuntimeException) 749 { 750 if (rxSlide != mxCurrentSlide) 751 { 752 mxCurrentSlide = rxSlide; 753 UpdateSlideNumber(); 754 } 755 } 756 757 758 759 760 Reference<drawing::XDrawPage> SAL_CALL PresenterToolBar::getCurrentPage (void) 761 throw (RuntimeException) 762 { 763 return mxCurrentSlide; 764 } 765 766 767 768 769 //----------------------------------------------------------------------------- 770 771 void PresenterToolBar::CreateControls ( 772 const ::rtl::OUString& rsConfigurationPath) 773 { 774 if ( ! mxWindow.is()) 775 return; 776 777 // Expand the macro in the bitmap file names. 778 PresenterConfigurationAccess aConfiguration ( 779 mxComponentContext, 780 OUString::createFromAscii("/org.openoffice.Office.extension.PresenterScreen/"), 781 PresenterConfigurationAccess::READ_ONLY); 782 783 const OUString sBasePath (PresenterComponent::GetBasePath(mxComponentContext)); 784 785 mpCurrentContainerPart.reset(new ElementContainerPart()); 786 maElementContainer.clear(); 787 maElementContainer.push_back(mpCurrentContainerPart); 788 789 Reference<container::XHierarchicalNameAccess> xToolBarNode ( 790 aConfiguration.GetConfigurationNode(rsConfigurationPath), 791 UNO_QUERY); 792 if (xToolBarNode.is()) 793 { 794 Reference<container::XNameAccess> xEntries ( 795 PresenterConfigurationAccess::GetConfigurationNode(xToolBarNode, A2S("Entries")), 796 UNO_QUERY); 797 Context aContext; 798 aContext.msBasePath = sBasePath; 799 aContext.mxPresenterHelper = mpPresenterController->GetPresenterHelper(); 800 aContext.mxCanvas = mxCanvas; 801 if (xEntries.is() 802 && aContext.mxPresenterHelper.is() 803 && aContext.mxCanvas.is()) 804 { 805 PresenterConfigurationAccess::ForAll( 806 xEntries, 807 ::boost::bind(&PresenterToolBar::ProcessEntry, this, _2, ::boost::ref(aContext))); 808 } 809 } 810 } 811 812 813 814 815 void PresenterToolBar::ProcessEntry ( 816 const Reference<beans::XPropertySet>& rxProperties, 817 Context& rContext) 818 { 819 if ( ! rxProperties.is()) 820 return; 821 822 // Type has to be present. 823 OUString sType; 824 if ( ! (PresenterConfigurationAccess::GetProperty(rxProperties, A2S("Type")) >>= sType)) 825 return; 826 827 OUString sName; 828 PresenterConfigurationAccess::GetProperty(rxProperties, A2S("Name")) >>= sName; 829 830 // Read mode specific values. 831 SharedElementMode pNormalMode (new ElementMode()); 832 SharedElementMode pMouseOverMode (new ElementMode()); 833 SharedElementMode pSelectedMode (new ElementMode()); 834 SharedElementMode pDisabledMode (new ElementMode()); 835 pNormalMode->ReadElementMode(rxProperties, A2S("Normal"), pNormalMode, rContext); 836 pMouseOverMode->ReadElementMode(rxProperties, A2S("MouseOver"), pNormalMode, rContext); 837 pSelectedMode->ReadElementMode(rxProperties, A2S("Selected"), pNormalMode, rContext); 838 pDisabledMode->ReadElementMode(rxProperties, A2S("Disabled"), pNormalMode, rContext); 839 840 // Create new element. 841 ::rtl::Reference<Element> pElement; 842 if (sType.equalsAscii("Button")) 843 pElement = Button::Create(this); 844 else if (sType.equalsAscii("CurrentTimeLabel")) 845 pElement = CurrentTimeLabel::Create(this); 846 else if (sType.equalsAscii("PresentationTimeLabel")) 847 pElement = PresentationTimeLabel::Create(this); 848 else if (sType.equalsAscii("VerticalSeparator")) 849 pElement = ::rtl::Reference<Element>(new VerticalSeparator(this)); 850 else if (sType.equalsAscii("HorizontalSeparator")) 851 pElement = ::rtl::Reference<Element>(new HorizontalSeparator(this)); 852 else if (sType.equalsAscii("Label")) 853 pElement = ::rtl::Reference<Element>(new Label(this)); 854 else if (sType.equalsAscii("ChangeOrientation")) 855 { 856 mpCurrentContainerPart.reset(new ElementContainerPart()); 857 maElementContainer.push_back(mpCurrentContainerPart); 858 return; 859 } 860 if (pElement.is()) 861 { 862 pElement->SetModes( pNormalMode, pMouseOverMode, pSelectedMode, pDisabledMode); 863 pElement->UpdateState(); 864 if (mpCurrentContainerPart.get() != NULL) 865 mpCurrentContainerPart->push_back(pElement); 866 } 867 } 868 869 870 871 872 void PresenterToolBar::Layout ( 873 const Reference<rendering::XCanvas>& rxCanvas) 874 { 875 if (maElementContainer.size() == 0) 876 return; 877 878 mbIsLayoutPending = false; 879 880 const awt::Rectangle aWindowBox (mxWindow->getPosSize()); 881 ElementContainer::iterator iPart; 882 ElementContainer::iterator iEnd (maElementContainer.end()); 883 ::std::vector<geometry::RealSize2D> aPartSizes (maElementContainer.size()); 884 geometry::RealSize2D aTotalSize (0,0); 885 bool bIsHorizontal (true); 886 sal_Int32 nIndex; 887 double nTotalHorizontalGap (0); 888 sal_Int32 nGapCount (0); 889 for (iPart=maElementContainer.begin(),nIndex=0; iPart!=iEnd; ++iPart,++nIndex) 890 { 891 geometry::RealSize2D aSize (CalculatePartSize(rxCanvas, *iPart, bIsHorizontal)); 892 893 // Remember the size of each part for later. 894 aPartSizes[nIndex] = aSize; 895 896 // Add gaps between elements. 897 if ((*iPart)->size()>1 && bIsHorizontal) 898 { 899 nTotalHorizontalGap += ((*iPart)->size() - 1) * gnGapSize; 900 nGapCount += (*iPart)->size()-1; 901 } 902 903 // Orientation changes for each part. 904 bIsHorizontal = !bIsHorizontal; 905 // Width is accumulated. 906 aTotalSize.Width += aSize.Width; 907 // Height is the maximum height of all parts. 908 aTotalSize.Height = ::std::max(aTotalSize.Height, aSize.Height); 909 } 910 // Add gaps between parts. 911 if (maElementContainer.size() > 1) 912 { 913 nTotalHorizontalGap += (maElementContainer.size() - 1) * gnGapSize; 914 nGapCount += maElementContainer.size()-1; 915 } 916 917 // Calculate the minimal size so that the window size of the tool bar 918 // can be adapted accordingly. 919 maMinimalSize = aTotalSize; 920 maMinimalSize.Width += nTotalHorizontalGap; 921 922 // Calculate the gaps between elements. 923 double nGapWidth (0); 924 if (nGapCount > 0) 925 { 926 if (aTotalSize.Width + nTotalHorizontalGap > aWindowBox.Width) 927 nTotalHorizontalGap = aWindowBox.Width - aTotalSize.Width; 928 nGapWidth = nTotalHorizontalGap / nGapCount; 929 } 930 931 // Determine the location of the left edge. 932 double nX (0); 933 switch (meAnchor) 934 { 935 case Left : nX = 0; break; 936 case Center: nX = (aWindowBox.Width - aTotalSize.Width - nTotalHorizontalGap) / 2; break; 937 case Right: nX = aWindowBox.Width - aTotalSize.Width - nTotalHorizontalGap; break; 938 } 939 940 // Place the parts. 941 double nY ((aWindowBox.Height - aTotalSize.Height) / 2); 942 bIsHorizontal = true; 943 944 maBoundingBox.X1 = nX; 945 maBoundingBox.Y1 = nY; 946 maBoundingBox.X2 = nX + aTotalSize.Width + nTotalHorizontalGap; 947 maBoundingBox.Y2 = nY + aTotalSize.Height; 948 949 for (iPart=maElementContainer.begin(), nIndex=0; iPart!=iEnd; ++iPart,++nIndex) 950 { 951 geometry::RealRectangle2D aBoundingBox( 952 nX, nY, 953 nX+aPartSizes[nIndex].Width, nY+aTotalSize.Height); 954 955 // Add space for gaps between elements. 956 if ((*iPart)->size() > 1) 957 if (bIsHorizontal) 958 aBoundingBox.X2 += ((*iPart)->size()-1) * nGapWidth; 959 960 LayoutPart(rxCanvas, *iPart, aBoundingBox, aPartSizes[nIndex], bIsHorizontal); 961 bIsHorizontal = !bIsHorizontal; 962 nX += aBoundingBox.X2 - aBoundingBox.X1 + nGapWidth; 963 } 964 965 // The whole window has to be repainted. 966 mpPresenterController->GetPaintManager()->Invalidate(mxWindow); 967 } 968 969 970 971 972 geometry::RealSize2D PresenterToolBar::CalculatePartSize ( 973 const Reference<rendering::XCanvas>& rxCanvas, 974 const SharedElementContainerPart& rpPart, 975 const bool bIsHorizontal) 976 { 977 geometry::RealSize2D aTotalSize (0,0); 978 979 if (mxWindow.is()) 980 { 981 const awt::Rectangle aWindowBox (mxWindow->getPosSize()); 982 983 // Calculate the summed width of all elements. 984 ElementContainerPart::const_iterator iElement; 985 for (iElement=rpPart->begin(); iElement!=rpPart->end(); ++iElement) 986 { 987 if (iElement->get() == NULL) 988 continue; 989 990 const awt::Size aBSize ((*iElement)->GetBoundingSize(rxCanvas)); 991 if (bIsHorizontal) 992 { 993 aTotalSize.Width += aBSize.Width; 994 if (aBSize.Height > aTotalSize.Height) 995 aTotalSize.Height = aBSize.Height; 996 } 997 else 998 { 999 aTotalSize.Height += aBSize.Height; 1000 if (aBSize.Width > aTotalSize.Width) 1001 aTotalSize.Width = aBSize.Width; 1002 } 1003 } 1004 } 1005 return aTotalSize; 1006 } 1007 1008 1009 1010 1011 void PresenterToolBar::LayoutPart ( 1012 const Reference<rendering::XCanvas>& rxCanvas, 1013 const SharedElementContainerPart& rpPart, 1014 const geometry::RealRectangle2D& rBoundingBox, 1015 const geometry::RealSize2D& rPartSize, 1016 const bool bIsHorizontal) 1017 { 1018 double nGap (0); 1019 if (rpPart->size() > 1) 1020 { 1021 if (bIsHorizontal) 1022 nGap = (rBoundingBox.X2 - rBoundingBox.X1 - rPartSize.Width) / (rpPart->size()-1); 1023 else 1024 nGap = (rBoundingBox.Y2 - rBoundingBox.Y1 - rPartSize.Height) / (rpPart->size()-1); 1025 } 1026 1027 // Place the elements. 1028 double nX (rBoundingBox.X1); 1029 double nY (rBoundingBox.Y1); 1030 1031 ElementContainerPart::const_iterator iElement; 1032 ElementContainerPart::const_iterator iEnd (rpPart->end()); 1033 for (iElement=rpPart->begin(); iElement!=iEnd; ++iElement) 1034 { 1035 if (iElement->get() == NULL) 1036 continue; 1037 1038 const awt::Size aElementSize ((*iElement)->GetBoundingSize(rxCanvas)); 1039 if (bIsHorizontal) 1040 { 1041 if ((*iElement)->IsFilling()) 1042 { 1043 nY = rBoundingBox.Y1; 1044 (*iElement)->SetSize(geometry::RealSize2D(aElementSize.Width, rBoundingBox.Y2 - rBoundingBox.Y1)); 1045 } 1046 else 1047 nY = rBoundingBox.Y1 + (rBoundingBox.Y2-rBoundingBox.Y1 - aElementSize.Height) / 2; 1048 (*iElement)->SetLocation(awt::Point(sal_Int32(0.5 + nX), sal_Int32(0.5 + nY))); 1049 nX += aElementSize.Width + nGap; 1050 } 1051 else 1052 { 1053 if ((*iElement)->IsFilling()) 1054 { 1055 nX = rBoundingBox.X1; 1056 (*iElement)->SetSize(geometry::RealSize2D(rBoundingBox.X2 - rBoundingBox.X1, aElementSize.Height)); 1057 } 1058 else 1059 nX = rBoundingBox.X1 + (rBoundingBox.X2-rBoundingBox.X1 - aElementSize.Width) / 2; 1060 (*iElement)->SetLocation(awt::Point(sal_Int32(0.5 + nX), sal_Int32(0.5 + nY))); 1061 nY += aElementSize.Height + nGap; 1062 } 1063 } 1064 } 1065 1066 1067 1068 1069 void PresenterToolBar::Paint ( 1070 const awt::Rectangle& rUpdateBox, 1071 const rendering::ViewState& rViewState) 1072 { 1073 OSL_ASSERT(mxCanvas.is()); 1074 1075 ElementContainer::iterator iPart; 1076 ElementContainer::const_iterator iEnd (maElementContainer.end()); 1077 for (iPart=maElementContainer.begin(); iPart!=iEnd; ++iPart) 1078 { 1079 ElementContainerPart::iterator iElement; 1080 ElementContainerPart::const_iterator iPartEnd ((*iPart)->end()); 1081 for (iElement=(*iPart)->begin(); iElement!=iPartEnd; ++iElement) 1082 { 1083 if (iElement->get() != NULL) 1084 { 1085 if ( ! (*iElement)->IsOutside(rUpdateBox)) 1086 (*iElement)->Paint(mxCanvas, rViewState); 1087 } 1088 } 1089 } 1090 } 1091 1092 1093 1094 1095 void PresenterToolBar::UpdateSlideNumber (void) 1096 { 1097 if( mxSlideShowController.is() ) 1098 { 1099 ElementContainer::iterator iPart; 1100 ElementContainer::const_iterator iEnd (maElementContainer.end()); 1101 for (iPart=maElementContainer.begin(); iPart!=iEnd; ++iPart) 1102 { 1103 ElementContainerPart::iterator iElement; 1104 ElementContainerPart::const_iterator iPartEnd ((*iPart)->end()); 1105 for (iElement=(*iPart)->begin(); iElement!=iPartEnd; ++iElement) 1106 { 1107 if (iElement->get() != NULL) 1108 (*iElement)->CurrentSlideHasChanged(); 1109 } 1110 } 1111 } 1112 } 1113 1114 1115 1116 1117 void PresenterToolBar::CheckMouseOver ( 1118 const css::awt::MouseEvent& rEvent, 1119 const bool bOverWindow, 1120 const bool bMouseDown) 1121 { 1122 ElementContainer::iterator iPart; 1123 ElementContainer::const_iterator iEnd (maElementContainer.end()); 1124 for (iPart=maElementContainer.begin(); iPart!=iEnd; ++iPart) 1125 { 1126 ElementContainerPart::iterator iElement; 1127 ElementContainerPart::const_iterator iPartEnd ((*iPart)->end()); 1128 for (iElement=(*iPart)->begin(); iElement!=iPartEnd; ++iElement) 1129 { 1130 if (iElement->get() == NULL) 1131 continue; 1132 1133 awt::Rectangle aBox ((*iElement)->GetBoundingBox()); 1134 const bool bIsOver = bOverWindow 1135 && aBox.X <= rEvent.X 1136 && aBox.Width+aBox.X-1 >= rEvent.X 1137 && aBox.Y <= rEvent.Y 1138 && aBox.Height+aBox.Y-1 >= rEvent.Y; 1139 (*iElement)->SetState( 1140 bIsOver, 1141 bIsOver && rEvent.Buttons!=0 && bMouseDown && rEvent.ClickCount>0); 1142 } 1143 } 1144 } 1145 1146 1147 1148 1149 void PresenterToolBar::ThrowIfDisposed (void) const 1150 throw (::com::sun::star::lang::DisposedException) 1151 { 1152 if (rBHelper.bDisposed || rBHelper.bInDispose) 1153 { 1154 throw lang::DisposedException ( 1155 OUString(RTL_CONSTASCII_USTRINGPARAM( 1156 "PresenterToolBar has already been disposed")), 1157 const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this))); 1158 } 1159 } 1160 1161 1162 1163 1164 //===== PresenterToolBarView ================================================== 1165 1166 PresenterToolBarView::PresenterToolBarView ( 1167 const Reference<XComponentContext>& rxContext, 1168 const Reference<XResourceId>& rxViewId, 1169 const Reference<frame::XController>& rxController, 1170 const ::rtl::Reference<PresenterController>& rpPresenterController) 1171 : PresenterToolBarViewInterfaceBase(m_aMutex), 1172 mxPane(), 1173 mxViewId(rxViewId), 1174 mxWindow(), 1175 mxCanvas(), 1176 mpPresenterController(rpPresenterController), 1177 mxSlideShowController(rpPresenterController->GetSlideShowController()), 1178 mpToolBar() 1179 { 1180 try 1181 { 1182 Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW); 1183 Reference<XConfigurationController> xCC(xCM->getConfigurationController(),UNO_QUERY_THROW); 1184 mxPane = Reference<XPane>(xCC->getResource(rxViewId->getAnchor()), UNO_QUERY_THROW); 1185 1186 mxWindow = mxPane->getWindow(); 1187 mxCanvas = mxPane->getCanvas(); 1188 1189 mpToolBar = new PresenterToolBar( 1190 rxContext, 1191 mxWindow, 1192 mxCanvas, 1193 rpPresenterController, 1194 PresenterToolBar::Center); 1195 mpToolBar->Initialize(A2S("PresenterScreenSettings/ToolBars/ToolBar")); 1196 1197 if (mxWindow.is()) 1198 { 1199 mxWindow->addPaintListener(this); 1200 1201 Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY); 1202 if (xPeer.is()) 1203 xPeer->setBackground(util::Color(0xff000000)); 1204 1205 mxWindow->setVisible(sal_True); 1206 } 1207 } 1208 catch (RuntimeException&) 1209 { 1210 mxViewId = NULL; 1211 throw; 1212 } 1213 } 1214 1215 1216 1217 1218 PresenterToolBarView::~PresenterToolBarView (void) 1219 { 1220 } 1221 1222 1223 1224 1225 void SAL_CALL PresenterToolBarView::disposing (void) 1226 { 1227 Reference<lang::XComponent> xComponent (static_cast<XWeak*>(mpToolBar.get()), UNO_QUERY); 1228 mpToolBar = NULL; 1229 if (xComponent.is()) 1230 xComponent->dispose(); 1231 1232 if (mxWindow.is()) 1233 { 1234 mxWindow->removePaintListener(this); 1235 mxWindow = NULL; 1236 } 1237 mxCanvas = NULL; 1238 mxViewId = NULL; 1239 mxPane = NULL; 1240 mpPresenterController = NULL; 1241 mxSlideShowController = NULL; 1242 1243 } 1244 1245 1246 1247 1248 ::rtl::Reference<PresenterToolBar> PresenterToolBarView::GetPresenterToolBar (void) const 1249 { 1250 return mpToolBar; 1251 } 1252 1253 1254 1255 1256 //----- XPaintListener -------------------------------------------------------- 1257 1258 void SAL_CALL PresenterToolBarView::windowPaint (const css::awt::PaintEvent& rEvent) 1259 throw (RuntimeException) 1260 { 1261 awt::Rectangle aWindowBox (mxWindow->getPosSize()); 1262 mpPresenterController->GetCanvasHelper()->Paint( 1263 mpPresenterController->GetViewBackground(mxViewId->getResourceURL()), 1264 mxCanvas, 1265 rEvent.UpdateRect, 1266 awt::Rectangle(0,0,aWindowBox.Width, aWindowBox.Height), 1267 awt::Rectangle()); 1268 } 1269 1270 1271 1272 1273 //----- lang::XEventListener ------------------------------------------------- 1274 1275 void SAL_CALL PresenterToolBarView::disposing (const lang::EventObject& rEventObject) 1276 throw (RuntimeException) 1277 { 1278 if (rEventObject.Source == mxWindow) 1279 mxWindow = NULL; 1280 } 1281 1282 1283 1284 1285 //----- XResourceId ----------------------------------------------------------- 1286 1287 Reference<XResourceId> SAL_CALL PresenterToolBarView::getResourceId (void) 1288 throw (RuntimeException) 1289 { 1290 return mxViewId; 1291 } 1292 1293 1294 1295 1296 sal_Bool SAL_CALL PresenterToolBarView::isAnchorOnly (void) 1297 throw (RuntimeException) 1298 { 1299 return false; 1300 } 1301 1302 1303 1304 1305 //----- XDrawView ------------------------------------------------------------- 1306 1307 void SAL_CALL PresenterToolBarView::setCurrentPage (const Reference<drawing::XDrawPage>& rxSlide) 1308 throw (RuntimeException) 1309 { 1310 Reference<drawing::XDrawView> xToolBar (static_cast<XWeak*>(mpToolBar.get()), UNO_QUERY); 1311 if (xToolBar.is()) 1312 xToolBar->setCurrentPage(rxSlide); 1313 } 1314 1315 1316 1317 1318 Reference<drawing::XDrawPage> SAL_CALL PresenterToolBarView::getCurrentPage (void) 1319 throw (RuntimeException) 1320 { 1321 return NULL; 1322 } 1323 1324 1325 1326 1327 //----------------------------------------------------------------------------- 1328 1329 void PresenterToolBarView::ThrowIfDisposed (void) const 1330 throw (::com::sun::star::lang::DisposedException) 1331 { 1332 if (rBHelper.bDisposed || rBHelper.bInDispose) 1333 { 1334 throw lang::DisposedException ( 1335 OUString(RTL_CONSTASCII_USTRINGPARAM( 1336 "PresenterToolBarView has already been disposed")), 1337 const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this))); 1338 } 1339 } 1340 1341 1342 1343 1344 //===== PresenterToolBar::Element ============================================= 1345 1346 namespace { 1347 1348 Element::Element ( 1349 const ::rtl::Reference<PresenterToolBar>& rpToolBar) 1350 : ElementInterfaceBase(m_aMutex), 1351 mpToolBar(rpToolBar), 1352 maLocation(), 1353 maSize(), 1354 mpNormal(), 1355 mpMouseOver(), 1356 mpSelected(), 1357 mpDisabled(), 1358 mpMode(), 1359 mbIsOver(false), 1360 mbIsPressed(false), 1361 mbIsSelected(false), 1362 mbIsEnabled(true) 1363 { 1364 if (mpToolBar.get() != NULL) 1365 { 1366 OSL_ASSERT(mpToolBar->GetPresenterController().is()); 1367 OSL_ASSERT(mpToolBar->GetPresenterController()->GetWindowManager().is()); 1368 } 1369 } 1370 1371 1372 1373 1374 Element::~Element (void) 1375 { 1376 } 1377 1378 1379 1380 1381 void Element::SetModes ( 1382 const SharedElementMode& rpNormalMode, 1383 const SharedElementMode& rpMouseOverMode, 1384 const SharedElementMode& rpSelectedMode, 1385 const SharedElementMode& rpDisabledMode) 1386 { 1387 mpNormal = rpNormalMode; 1388 mpMouseOver = rpMouseOverMode; 1389 mpSelected = rpSelectedMode; 1390 mpDisabled = rpDisabledMode; 1391 mpMode = rpNormalMode; 1392 } 1393 1394 1395 1396 1397 void Element::disposing (void) 1398 { 1399 } 1400 1401 1402 1403 1404 awt::Size Element::GetBoundingSize ( 1405 const Reference<rendering::XCanvas>& rxCanvas) 1406 { 1407 maSize = CreateBoundingSize(rxCanvas); 1408 return maSize; 1409 } 1410 1411 1412 1413 1414 awt::Rectangle Element::GetBoundingBox (void) const 1415 { 1416 return awt::Rectangle(maLocation.X,maLocation.Y, maSize.Width, maSize.Height); 1417 } 1418 1419 1420 1421 1422 void Element::CurrentSlideHasChanged (void) 1423 { 1424 UpdateState(); 1425 } 1426 1427 1428 1429 1430 void Element::SetLocation (const awt::Point& rLocation) 1431 { 1432 maLocation = rLocation; 1433 } 1434 1435 1436 1437 void Element::SetSize (const geometry::RealSize2D& rSize) 1438 { 1439 maSize = awt::Size(sal_Int32(0.5+rSize.Width), sal_Int32(0.5+rSize.Height)); 1440 } 1441 1442 1443 1444 1445 bool Element::SetState ( 1446 const bool bIsOver, 1447 const bool bIsPressed) 1448 { 1449 bool bModified (mbIsOver != bIsOver || mbIsPressed != bIsPressed); 1450 bool bClicked (mbIsPressed && bIsOver && ! bIsPressed); 1451 1452 mbIsOver = bIsOver; 1453 mbIsPressed = bIsPressed; 1454 1455 // When the element is disabled then ignore mouse over or selection. 1456 // When the element is selected then ignore mouse over. 1457 if ( ! mbIsEnabled) 1458 mpMode = mpDisabled; 1459 else if (mbIsSelected) 1460 mpMode = mpSelected; 1461 else if (mbIsOver) 1462 mpMode = mpMouseOver; 1463 else 1464 mpMode = mpNormal; 1465 1466 if (bClicked && mbIsEnabled) 1467 { 1468 if (mpMode.get() != NULL) 1469 { 1470 do 1471 { 1472 if (mpMode->msAction.getLength() <= 0) 1473 break; 1474 1475 if (mpToolBar.get() == NULL) 1476 break; 1477 1478 if (mpToolBar->GetPresenterController().get() == NULL) 1479 break; 1480 1481 mpToolBar->GetPresenterController()->DispatchUnoCommand(mpMode->msAction); 1482 mpToolBar->RequestLayout(); 1483 } 1484 while (false); 1485 } 1486 1487 } 1488 else if (bModified) 1489 { 1490 Invalidate(); 1491 } 1492 1493 return bModified; 1494 } 1495 1496 1497 1498 1499 void Element::Invalidate (const bool bSynchronous) 1500 { 1501 OSL_ASSERT(mpToolBar.is()); 1502 mpToolBar->InvalidateArea(GetBoundingBox(), bSynchronous); 1503 } 1504 1505 1506 1507 1508 bool Element::IsOutside (const awt::Rectangle& rBox) 1509 { 1510 if (rBox.X >= maLocation.X+maSize.Width) 1511 return true; 1512 else if (rBox.Y >= maLocation.Y+maSize.Height) 1513 return true; 1514 else if (maLocation.X >= rBox.X+rBox.Width) 1515 return true; 1516 else if (maLocation.Y >= rBox.Y+rBox.Height) 1517 return true; 1518 else 1519 return false; 1520 } 1521 1522 1523 1524 bool Element::IsEnabled (void) const 1525 { 1526 return mbIsEnabled; 1527 } 1528 1529 1530 1531 1532 void Element::SetEnabledState (const bool bIsEnabled) 1533 { 1534 mbIsEnabled = bIsEnabled; 1535 } 1536 1537 1538 1539 1540 bool Element::IsFilling (void) const 1541 { 1542 return false; 1543 } 1544 1545 1546 1547 1548 void Element::UpdateState (void) 1549 { 1550 OSL_ASSERT(mpToolBar.get() != NULL); 1551 OSL_ASSERT(mpToolBar->GetPresenterController().get() != NULL); 1552 1553 if (mpMode.get() == NULL) 1554 return; 1555 1556 util::URL aURL (mpToolBar->GetPresenterController()->CreateURLFromString(mpMode->msAction)); 1557 Reference<frame::XDispatch> xDispatch (mpToolBar->GetPresenterController()->GetDispatch(aURL)); 1558 if (xDispatch.is()) 1559 { 1560 xDispatch->addStatusListener(this, aURL); 1561 xDispatch->removeStatusListener(this, aURL); 1562 } 1563 } 1564 1565 1566 1567 1568 //----- lang::XEventListener -------------------------------------------------- 1569 1570 void SAL_CALL Element::disposing (const css::lang::EventObject& rEvent) 1571 throw(css::uno::RuntimeException) 1572 { 1573 (void)rEvent; 1574 } 1575 1576 1577 1578 1579 //----- document::XEventListener ---------------------------------------------- 1580 1581 void SAL_CALL Element::notifyEvent (const css::document::EventObject& rEvent) 1582 throw(css::uno::RuntimeException) 1583 { 1584 (void)rEvent; 1585 UpdateState(); 1586 } 1587 1588 1589 1590 1591 //----- frame::XStatusListener ------------------------------------------------ 1592 1593 void SAL_CALL Element::statusChanged (const css::frame::FeatureStateEvent& rEvent) 1594 throw(css::uno::RuntimeException) 1595 { 1596 bool bIsSelected (mbIsSelected); 1597 bool bIsEnabled (rEvent.IsEnabled); 1598 rEvent.State >>= bIsSelected; 1599 1600 if (bIsSelected != mbIsSelected || bIsEnabled != mbIsEnabled) 1601 { 1602 mbIsEnabled = bIsEnabled; 1603 mbIsSelected = bIsSelected; 1604 SetState(mbIsOver, mbIsPressed); 1605 mpToolBar->RequestLayout(); 1606 } 1607 } 1608 1609 } // end of anonymous namespace 1610 1611 1612 1613 1614 //===== ElementMode =========================================================== 1615 1616 namespace { 1617 1618 ElementMode::ElementMode (void) 1619 : mpIcon(), 1620 msAction(), 1621 maText() 1622 { 1623 } 1624 1625 1626 1627 1628 void ElementMode::ReadElementMode ( 1629 const Reference<beans::XPropertySet>& rxElementProperties, 1630 const OUString& rsModeName, 1631 ::boost::shared_ptr<ElementMode>& rpDefaultMode, 1632 ::sdext::presenter::PresenterToolBar::Context& rContext) 1633 { 1634 try 1635 { 1636 Reference<container::XHierarchicalNameAccess> xNode ( 1637 PresenterConfigurationAccess::GetProperty(rxElementProperties, rsModeName), 1638 UNO_QUERY); 1639 Reference<beans::XPropertySet> xProperties ( 1640 PresenterConfigurationAccess::GetNodeProperties(xNode, OUString())); 1641 if ( ! xProperties.is() && rpDefaultMode.get()!=NULL) 1642 { 1643 // The mode is not specified. Use the given, possibly empty, 1644 // default mode instead. 1645 mpIcon = rpDefaultMode->mpIcon; 1646 msAction = rpDefaultMode->msAction; 1647 maText = rpDefaultMode->maText; 1648 } 1649 1650 // Read action. 1651 if ( ! (PresenterConfigurationAccess::GetProperty(xProperties, A2S("Action")) >>= msAction)) 1652 if (rpDefaultMode.get()!=NULL) 1653 msAction = rpDefaultMode->msAction; 1654 1655 // Read text and font 1656 OUString sText (rpDefaultMode.get()!=NULL ? rpDefaultMode->maText.GetText() : OUString()); 1657 PresenterConfigurationAccess::GetProperty(xProperties, A2S("Text")) >>= sText; 1658 Reference<container::XHierarchicalNameAccess> xFontNode ( 1659 PresenterConfigurationAccess::GetProperty(xProperties, A2S("Font")), UNO_QUERY); 1660 PresenterTheme::SharedFontDescriptor pFont (PresenterTheme::ReadFont( 1661 xFontNode, 1662 A2S(""), 1663 rpDefaultMode.get()!=NULL 1664 ? rpDefaultMode->maText.GetFont() 1665 : PresenterTheme::SharedFontDescriptor())); 1666 maText = Text(sText,pFont); 1667 1668 // Read bitmaps to display as icons. 1669 Reference<container::XHierarchicalNameAccess> xIconNode ( 1670 PresenterConfigurationAccess::GetProperty(xProperties, A2S("Icon")), UNO_QUERY); 1671 mpIcon = PresenterBitmapContainer::LoadBitmap( 1672 xIconNode, 1673 A2S(""), 1674 rContext.mxPresenterHelper, 1675 rContext.msBasePath, 1676 rContext.mxCanvas, 1677 rpDefaultMode.get()!=NULL ? rpDefaultMode->mpIcon : SharedBitmapDescriptor()); 1678 } 1679 catch(Exception&) 1680 { 1681 OSL_ASSERT(false); 1682 } 1683 } 1684 1685 } // end of anonymous namespace 1686 1687 1688 1689 1690 //===== Button ================================================================ 1691 1692 namespace { 1693 1694 ::rtl::Reference<Element> Button::Create ( 1695 const ::rtl::Reference<PresenterToolBar>& rpToolBar) 1696 { 1697 ::rtl::Reference<Button> pElement (new Button(rpToolBar)); 1698 pElement->Initialize(); 1699 return ::rtl::Reference<Element>(pElement.get()); 1700 } 1701 1702 1703 1704 1705 Button::Button ( 1706 const ::rtl::Reference<PresenterToolBar>& rpToolBar) 1707 : Element(rpToolBar), 1708 mbIsListenerRegistered(false) 1709 { 1710 OSL_ASSERT(mpToolBar.get() != NULL); 1711 OSL_ASSERT(mpToolBar->GetPresenterController().is()); 1712 OSL_ASSERT(mpToolBar->GetPresenterController()->GetWindowManager().is()); 1713 } 1714 1715 1716 1717 1718 Button::~Button (void) 1719 { 1720 } 1721 1722 1723 1724 1725 void Button::Initialize (void) 1726 { 1727 mpToolBar->GetPresenterController()->GetWindowManager()->AddLayoutListener(this); 1728 mbIsListenerRegistered = true; 1729 } 1730 1731 1732 1733 1734 void Button::disposing (void) 1735 { 1736 OSL_ASSERT(mpToolBar.get() != NULL); 1737 if (mpToolBar.get() != NULL 1738 && mbIsListenerRegistered) 1739 { 1740 OSL_ASSERT(mpToolBar->GetPresenterController().is()); 1741 OSL_ASSERT(mpToolBar->GetPresenterController()->GetWindowManager().is()); 1742 1743 mbIsListenerRegistered = false; 1744 mpToolBar->GetPresenterController()->GetWindowManager()->RemoveLayoutListener(this); 1745 } 1746 Element::disposing(); 1747 } 1748 1749 1750 1751 1752 void Button::Paint ( 1753 const Reference<rendering::XCanvas>& rxCanvas, 1754 const rendering::ViewState& rViewState) 1755 { 1756 OSL_ASSERT(rxCanvas.is()); 1757 1758 if (mpMode.get() == NULL) 1759 return; 1760 1761 if (mpMode->mpIcon.get() == NULL) 1762 return; 1763 1764 geometry::RealRectangle2D aTextBBox (mpMode->maText.GetBoundingBox(rxCanvas)); 1765 sal_Int32 nTextHeight (sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.Y2 - aTextBBox.Y1)); 1766 1767 PaintIcon(rxCanvas, nTextHeight, rViewState); 1768 awt::Point aOffset(0,0); 1769 if ( ! IsEnabled()) 1770 if (mpMode->mpIcon.get() != NULL) 1771 { 1772 Reference<rendering::XBitmap> xBitmap (mpMode->mpIcon->GetNormalBitmap()); 1773 if (xBitmap.is()) 1774 aOffset.Y = xBitmap->getSize().Height; 1775 } 1776 mpMode->maText.Paint(rxCanvas, rViewState, GetBoundingBox(), aOffset); 1777 } 1778 1779 1780 1781 1782 awt::Size Button::CreateBoundingSize ( 1783 const Reference<rendering::XCanvas>& rxCanvas) 1784 { 1785 if (mpMode.get() == NULL) 1786 return awt::Size(); 1787 1788 geometry::RealRectangle2D aTextBBox (mpMode->maText.GetBoundingBox(rxCanvas)); 1789 const sal_Int32 nGap (5); 1790 sal_Int32 nTextHeight (sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.Y2 - aTextBBox.Y1)); 1791 sal_Int32 nTextWidth (sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.X2 - aTextBBox.X1)); 1792 Reference<rendering::XBitmap> xBitmap; 1793 if (mpMode->mpIcon.get() != NULL) 1794 xBitmap = mpMode->mpIcon->GetNormalBitmap(); 1795 if (xBitmap.is()) 1796 { 1797 geometry::IntegerSize2D aSize (xBitmap->getSize()); 1798 return awt::Size( 1799 ::std::max(aSize.Width, sal_Int32(0.5 + aTextBBox.X2 - aTextBBox.X1)), 1800 aSize.Height+ nGap + nTextHeight); 1801 } 1802 else 1803 return awt::Size(nTextWidth,nTextHeight); 1804 } 1805 1806 1807 1808 1809 void Button::PaintIcon ( 1810 const Reference<rendering::XCanvas>& rxCanvas, 1811 const sal_Int32 nTextHeight, 1812 const rendering::ViewState& rViewState) 1813 { 1814 if (mpMode.get() == NULL) 1815 return; 1816 1817 Reference<rendering::XBitmap> xBitmap (mpMode->mpIcon->GetBitmap(GetMode())); 1818 if (xBitmap.is()) 1819 { 1820 const sal_Int32 nX (maLocation.X 1821 + (maSize.Width-xBitmap->getSize().Width) / 2); 1822 const sal_Int32 nY (maLocation.Y 1823 + (maSize.Height - nTextHeight - xBitmap->getSize().Height) / 2); 1824 const rendering::RenderState aRenderState( 1825 geometry::AffineMatrix2D(1,0,nX, 0,1,nY), 1826 NULL, 1827 Sequence<double>(4), 1828 rendering::CompositeOperation::OVER); 1829 rxCanvas->drawBitmap(xBitmap, rViewState, aRenderState); 1830 } 1831 } 1832 1833 1834 1835 1836 PresenterBitmapDescriptor::Mode Button::GetMode (void) const 1837 { 1838 if ( ! IsEnabled()) 1839 return PresenterBitmapDescriptor::Disabled; 1840 else if (mbIsPressed) 1841 return PresenterBitmapDescriptor::ButtonDown; 1842 else if (mbIsOver) 1843 return PresenterBitmapDescriptor::MouseOver; 1844 else 1845 return PresenterBitmapDescriptor::Normal; 1846 } 1847 1848 1849 1850 1851 //----- lang::XEventListener -------------------------------------------------- 1852 1853 void SAL_CALL Button::disposing (const css::lang::EventObject& rEvent) 1854 throw(css::uno::RuntimeException) 1855 { 1856 (void)rEvent; 1857 mbIsListenerRegistered = false; 1858 Element::disposing(rEvent); 1859 } 1860 1861 } // end of anonymous namespace 1862 1863 1864 1865 1866 //===== PresenterToolBar::Label =============================================== 1867 1868 namespace { 1869 1870 Label::Label (const ::rtl::Reference<PresenterToolBar>& rpToolBar) 1871 : Element(rpToolBar) 1872 { 1873 } 1874 1875 1876 1877 1878 awt::Size Label::CreateBoundingSize ( 1879 const Reference<rendering::XCanvas>& rxCanvas) 1880 { 1881 if (mpMode.get() == NULL) 1882 return awt::Size(0,0); 1883 1884 geometry::RealRectangle2D aTextBBox (mpMode->maText.GetBoundingBox(rxCanvas)); 1885 return awt::Size( 1886 sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.X2 - aTextBBox.X1), 1887 sal::static_int_cast<sal_Int32>(0.5 + aTextBBox.Y2 - aTextBBox.Y1)); 1888 } 1889 1890 1891 1892 1893 1894 void Label::SetText (const OUString& rsText) 1895 { 1896 OSL_ASSERT(mpToolBar.get() != NULL); 1897 if (mpMode.get() == NULL) 1898 return; 1899 1900 const bool bRequestLayout (mpMode->maText.GetText().getLength() != rsText.getLength()); 1901 1902 mpMode->maText.SetText(rsText); 1903 // Just use the character count for determing whether a layout is 1904 // necessary. This is an optimization to avoid layouts every time a new 1905 // time value is set on some labels. 1906 if (bRequestLayout) 1907 mpToolBar->RequestLayout(); 1908 else 1909 Invalidate(false); 1910 } 1911 1912 1913 1914 1915 void Label::Paint ( 1916 const Reference<rendering::XCanvas>& rxCanvas, 1917 const rendering::ViewState& rViewState) 1918 { 1919 OSL_ASSERT(rxCanvas.is()); 1920 if (mpMode.get() == NULL) 1921 return; 1922 1923 mpMode->maText.Paint(rxCanvas, rViewState, GetBoundingBox(), awt::Point(0,0)); 1924 } 1925 1926 1927 1928 1929 bool Label::SetState (const bool bIsOver, const bool bIsPressed) 1930 { 1931 // For labels there is no mouse over effect. 1932 (void)bIsOver; 1933 (void)bIsPressed; 1934 return Element::SetState(false, false); 1935 } 1936 1937 } // end of anonymous namespace 1938 1939 1940 1941 1942 //===== Text ================================================================== 1943 1944 namespace { 1945 1946 Text::Text (void) 1947 : msText(), 1948 mpFont() 1949 { 1950 } 1951 1952 1953 1954 1955 Text::Text (const Text& rText) 1956 : msText(rText.msText), 1957 mpFont(rText.mpFont) 1958 { 1959 } 1960 1961 1962 1963 1964 Text::Text ( 1965 const OUString& rsText, 1966 const PresenterTheme::SharedFontDescriptor& rpFont) 1967 : msText(rsText), 1968 mpFont(rpFont) 1969 { 1970 } 1971 1972 1973 1974 1975 void Text::SetText (const OUString& rsText) 1976 { 1977 msText = rsText; 1978 } 1979 1980 1981 1982 1983 OUString Text::GetText (void) const 1984 { 1985 return msText; 1986 } 1987 1988 1989 1990 1991 PresenterTheme::SharedFontDescriptor Text::GetFont (void) const 1992 { 1993 return mpFont; 1994 } 1995 1996 1997 1998 1999 void Text::Paint ( 2000 const Reference<rendering::XCanvas>& rxCanvas, 2001 const rendering::ViewState& rViewState, 2002 const awt::Rectangle& rBoundingBox, 2003 const awt::Point& rOffset) 2004 { 2005 (void)rOffset; 2006 OSL_ASSERT(rxCanvas.is()); 2007 2008 if (msText.getLength() <= 0) 2009 return; 2010 if (mpFont.get() == NULL) 2011 return; 2012 2013 if ( ! mpFont->mxFont.is()) 2014 mpFont->PrepareFont(rxCanvas); 2015 if ( ! mpFont->mxFont.is()) 2016 return; 2017 2018 rendering::StringContext aContext (msText, 0, msText.getLength()); 2019 2020 Reference<rendering::XTextLayout> xLayout ( 2021 mpFont->mxFont->createTextLayout( 2022 aContext, 2023 rendering::TextDirection::WEAK_LEFT_TO_RIGHT, 2024 0)); 2025 2026 geometry::RealRectangle2D aBox (xLayout->queryTextBounds()); 2027 const double nTextWidth = aBox.X2 - aBox.X1; 2028 const double nY = rBoundingBox.Y + rBoundingBox.Height - aBox.Y2; 2029 const double nX = rBoundingBox.X + (rBoundingBox.Width - nTextWidth)/2; 2030 2031 rendering::RenderState aRenderState( 2032 geometry::AffineMatrix2D(1,0,nX, 0,1,nY), 2033 NULL, 2034 Sequence<double>(4), 2035 rendering::CompositeOperation::SOURCE); 2036 PresenterCanvasHelper::SetDeviceColor(aRenderState, mpFont->mnColor); 2037 2038 rxCanvas->drawText( 2039 aContext, 2040 mpFont->mxFont, 2041 rViewState, 2042 aRenderState, 2043 rendering::TextDirection::WEAK_LEFT_TO_RIGHT); 2044 } 2045 2046 2047 2048 2049 geometry::RealRectangle2D Text::GetBoundingBox (const Reference<rendering::XCanvas>& rxCanvas) 2050 { 2051 if (mpFont.get() != NULL && msText.getLength() > 0) 2052 { 2053 if ( ! mpFont->mxFont.is()) 2054 mpFont->PrepareFont(rxCanvas); 2055 if (mpFont->mxFont.is()) 2056 { 2057 rendering::StringContext aContext (msText, 0, msText.getLength()); 2058 Reference<rendering::XTextLayout> xLayout ( 2059 mpFont->mxFont->createTextLayout( 2060 aContext, 2061 rendering::TextDirection::WEAK_LEFT_TO_RIGHT, 2062 0)); 2063 return xLayout->queryTextBounds(); 2064 } 2065 } 2066 return geometry::RealRectangle2D(0,0,0,0); 2067 } 2068 2069 2070 2071 2072 //===== ProgressLabel ========================================================= 2073 2074 ProgressLabel::ProgressLabel (const ::rtl::Reference<PresenterToolBar>& rpToolBar) 2075 : Label(rpToolBar) 2076 { 2077 SetText(A2S("-/-")); 2078 } 2079 2080 2081 2082 2083 void ProgressLabel::CurrentSlideHasChanged (void) 2084 { 2085 Label::CurrentSlideHasChanged(); 2086 OSL_ASSERT(mpToolBar.is()); 2087 try 2088 { 2089 const sal_Int32 nCurrentSlideIndex (mpToolBar->GetCurrentSlideIndex() + 1); 2090 const sal_Int32 nSlideCount (mpToolBar->GetSlideCount()); 2091 if (nCurrentSlideIndex >= 0 && nSlideCount > 0) 2092 SetText( 2093 OUString::valueOf(nCurrentSlideIndex) 2094 + OUString::createFromAscii(" / ") 2095 + OUString::valueOf(nSlideCount)); 2096 else 2097 SetText(A2S("")); 2098 Invalidate(); 2099 } 2100 catch (RuntimeException&) 2101 { 2102 } 2103 } 2104 2105 2106 2107 2108 //===== TimeFormatter ========================================================= 2109 2110 TimeFormatter::TimeFormatter (void) 2111 : mbIs24HourFormat(true), 2112 mbIsAmPmFormat(false), 2113 mbIsShowSeconds(true) 2114 { 2115 } 2116 2117 2118 2119 2120 OUString TimeFormatter::FormatTime (const oslDateTime& rTime) 2121 { 2122 ::rtl::OUStringBuffer sText; 2123 2124 const sal_Int32 nHours (sal::static_int_cast<sal_Int32>(rTime.Hours)); 2125 const sal_Int32 nMinutes (sal::static_int_cast<sal_Int32>(rTime.Minutes)); 2126 const sal_Int32 nSeconds(sal::static_int_cast<sal_Int32>(rTime.Seconds)); 2127 2128 // Hours 2129 if (mbIs24HourFormat) 2130 sText.append(OUString::valueOf(nHours)); 2131 else 2132 sText.append(OUString::valueOf( 2133 sal::static_int_cast<sal_Int32>(nHours>12 ? nHours-12 : nHours))); 2134 2135 sText.append(A2S(":")); 2136 2137 // Minutes 2138 const OUString sMinutes (OUString::valueOf(nMinutes)); 2139 if (sMinutes.getLength() == 1) 2140 sText.append(A2S("0")); 2141 sText.append(sMinutes); 2142 2143 // Seconds 2144 if (mbIsShowSeconds) 2145 { 2146 sText.append(A2S(":")); 2147 const OUString sSeconds (OUString::valueOf(nSeconds)); 2148 if (sSeconds.getLength() == 1) 2149 sText.append(A2S("0")); 2150 sText.append(sSeconds); 2151 } 2152 2153 if (mbIsAmPmFormat) 2154 { 2155 if (rTime.Hours < 12) 2156 sText.append(A2S("am")); 2157 else 2158 sText.append(A2S("pm")); 2159 } 2160 return sText.makeStringAndClear(); 2161 } 2162 2163 2164 2165 2166 //===== TimeLabel ============================================================= 2167 2168 TimeLabel::TimeLabel (const ::rtl::Reference<PresenterToolBar>& rpToolBar) 2169 : Label(rpToolBar), 2170 mpListener() 2171 { 2172 } 2173 2174 2175 2176 2177 void SAL_CALL TimeLabel::disposing (void) 2178 { 2179 PresenterClockTimer::Instance(mpToolBar->GetComponentContext())->RemoveListener(mpListener); 2180 mpListener.reset(); 2181 } 2182 2183 2184 2185 2186 void TimeLabel::ConnectToTimer (void) 2187 { 2188 mpListener.reset(new Listener(this)); 2189 PresenterClockTimer::Instance(mpToolBar->GetComponentContext())->AddListener(mpListener); 2190 } 2191 2192 2193 2194 2195 //===== CurrentTimeLabel ====================================================== 2196 2197 ::rtl::Reference<Element> CurrentTimeLabel::Create ( 2198 const ::rtl::Reference<PresenterToolBar>& rpToolBar) 2199 { 2200 ::rtl::Reference<TimeLabel> pElement(new CurrentTimeLabel(rpToolBar)); 2201 pElement->ConnectToTimer(); 2202 return ::rtl::Reference<Element>(pElement.get()); 2203 } 2204 2205 2206 2207 2208 CurrentTimeLabel::~CurrentTimeLabel (void) 2209 { 2210 } 2211 2212 2213 2214 2215 CurrentTimeLabel::CurrentTimeLabel ( 2216 const ::rtl::Reference<PresenterToolBar>& rpToolBar) 2217 : TimeLabel(rpToolBar), 2218 maTimeFormatter() 2219 { 2220 } 2221 2222 2223 2224 2225 void CurrentTimeLabel::TimeHasChanged (const oslDateTime& rCurrentTime) 2226 { 2227 SetText(maTimeFormatter.FormatTime(rCurrentTime)); 2228 Invalidate(false); 2229 } 2230 2231 2232 2233 2234 void CurrentTimeLabel::SetModes ( 2235 const SharedElementMode& rpNormalMode, 2236 const SharedElementMode& rpMouseOverMode, 2237 const SharedElementMode& rpSelectedMode, 2238 const SharedElementMode& rpDisabledMode) 2239 { 2240 TimeLabel::SetModes(rpNormalMode, rpMouseOverMode, rpSelectedMode, rpDisabledMode); 2241 SetText(maTimeFormatter.FormatTime(PresenterClockTimer::GetCurrentTime())); 2242 } 2243 2244 2245 2246 2247 //===== PresentationTimeLabel ================================================= 2248 2249 ::rtl::Reference<Element> PresentationTimeLabel::Create ( 2250 const ::rtl::Reference<PresenterToolBar>& rpToolBar) 2251 { 2252 ::rtl::Reference<TimeLabel> pElement(new PresentationTimeLabel(rpToolBar)); 2253 pElement->ConnectToTimer(); 2254 return ::rtl::Reference<Element>(pElement.get()); 2255 } 2256 2257 2258 2259 2260 PresentationTimeLabel::~PresentationTimeLabel (void) 2261 { 2262 } 2263 2264 2265 2266 2267 PresentationTimeLabel::PresentationTimeLabel ( 2268 const ::rtl::Reference<PresenterToolBar>& rpToolBar) 2269 : TimeLabel(rpToolBar), 2270 maTimeFormatter(), 2271 maStartTimeValue() 2272 { 2273 maStartTimeValue.Seconds = 0; 2274 maStartTimeValue.Nanosec = 0; 2275 } 2276 2277 2278 2279 2280 void PresentationTimeLabel::TimeHasChanged (const oslDateTime& rCurrentTime) 2281 { 2282 TimeValue aCurrentTimeValue; 2283 if (osl_getTimeValueFromDateTime(const_cast<oslDateTime*>(&rCurrentTime), &aCurrentTimeValue)) 2284 { 2285 if (maStartTimeValue.Seconds==0 && maStartTimeValue.Nanosec==0) 2286 { 2287 // This method is called for the first time. Initialize the 2288 // start time. The start time is rounded to nearest second to 2289 // keep the time updates synchronized with the current time label. 2290 maStartTimeValue = aCurrentTimeValue; 2291 if (maStartTimeValue.Nanosec >= 500000000) 2292 maStartTimeValue.Seconds += 1; 2293 maStartTimeValue.Nanosec = 0; 2294 } 2295 2296 TimeValue aElapsedTimeValue; 2297 aElapsedTimeValue.Seconds = aCurrentTimeValue.Seconds - maStartTimeValue.Seconds; 2298 aElapsedTimeValue.Nanosec = aCurrentTimeValue.Nanosec - maStartTimeValue.Nanosec; 2299 2300 oslDateTime aElapsedDateTime; 2301 if (osl_getDateTimeFromTimeValue(&aElapsedTimeValue, &aElapsedDateTime)) 2302 { 2303 SetText(maTimeFormatter.FormatTime(aElapsedDateTime)); 2304 Invalidate(false); 2305 } 2306 } 2307 } 2308 2309 2310 2311 void PresentationTimeLabel::SetModes ( 2312 const SharedElementMode& rpNormalMode, 2313 const SharedElementMode& rpMouseOverMode, 2314 const SharedElementMode& rpSelectedMode, 2315 const SharedElementMode& rpDisabledMode) 2316 { 2317 TimeLabel::SetModes(rpNormalMode, rpMouseOverMode, rpSelectedMode, rpDisabledMode); 2318 2319 oslDateTime aStartDateTime; 2320 if (osl_getDateTimeFromTimeValue(&maStartTimeValue, &aStartDateTime)) 2321 { 2322 SetText(maTimeFormatter.FormatTime(aStartDateTime)); 2323 } 2324 } 2325 2326 2327 2328 2329 //===== VerticalSeparator ===================================================== 2330 2331 VerticalSeparator::VerticalSeparator ( 2332 const ::rtl::Reference<PresenterToolBar>& rpToolBar) 2333 : Element(rpToolBar) 2334 { 2335 } 2336 2337 2338 2339 2340 void VerticalSeparator::Paint ( 2341 const Reference<rendering::XCanvas>& rxCanvas, 2342 const rendering::ViewState& rViewState) 2343 { 2344 OSL_ASSERT(rxCanvas.is()); 2345 2346 awt::Rectangle aBBox (GetBoundingBox()); 2347 2348 rendering::RenderState aRenderState( 2349 geometry::AffineMatrix2D(1,0,0, 0,1,0), 2350 NULL, 2351 Sequence<double>(4), 2352 rendering::CompositeOperation::OVER); 2353 if (mpMode.get() != NULL) 2354 { 2355 PresenterTheme::SharedFontDescriptor pFont (mpMode->maText.GetFont()); 2356 if (pFont.get() != NULL) 2357 PresenterCanvasHelper::SetDeviceColor(aRenderState, pFont->mnColor); 2358 } 2359 2360 if (aBBox.Height >= gnMinimalSeparatorSize + 2*gnSeparatorInset) 2361 { 2362 aBBox.Height -= 2*gnSeparatorInset; 2363 aBBox.Y += gnSeparatorInset; 2364 } 2365 rxCanvas->fillPolyPolygon( 2366 PresenterGeometryHelper::CreatePolygon(aBBox, rxCanvas->getDevice()), 2367 rViewState, 2368 aRenderState); 2369 } 2370 2371 2372 2373 2374 awt::Size VerticalSeparator::CreateBoundingSize ( 2375 const Reference<rendering::XCanvas>& rxCanvas) 2376 { 2377 (void)rxCanvas; 2378 return awt::Size(1,20); 2379 } 2380 2381 2382 2383 2384 bool VerticalSeparator::IsFilling (void) const 2385 { 2386 return true; 2387 } 2388 2389 2390 2391 2392 //===== HorizontalSeparator =================================================== 2393 2394 HorizontalSeparator::HorizontalSeparator ( 2395 const ::rtl::Reference<PresenterToolBar>& rpToolBar) 2396 : Element(rpToolBar) 2397 { 2398 } 2399 2400 2401 2402 2403 void HorizontalSeparator::Paint ( 2404 const Reference<rendering::XCanvas>& rxCanvas, 2405 const rendering::ViewState& rViewState) 2406 { 2407 OSL_ASSERT(rxCanvas.is()); 2408 2409 awt::Rectangle aBBox (GetBoundingBox()); 2410 2411 rendering::RenderState aRenderState( 2412 geometry::AffineMatrix2D(1,0,0, 0,1,0), 2413 NULL, 2414 Sequence<double>(4), 2415 rendering::CompositeOperation::OVER); 2416 if (mpMode.get() != NULL) 2417 { 2418 PresenterTheme::SharedFontDescriptor pFont (mpMode->maText.GetFont()); 2419 if (pFont.get() != NULL) 2420 PresenterCanvasHelper::SetDeviceColor(aRenderState, pFont->mnColor); 2421 } 2422 2423 if (aBBox.Width >= gnMinimalSeparatorSize+2*gnSeparatorInset) 2424 { 2425 aBBox.Width -= 2*gnSeparatorInset; 2426 aBBox.X += gnSeparatorInset; 2427 } 2428 rxCanvas->fillPolyPolygon( 2429 PresenterGeometryHelper::CreatePolygon(aBBox, rxCanvas->getDevice()), 2430 rViewState, 2431 aRenderState); 2432 } 2433 2434 2435 2436 2437 awt::Size HorizontalSeparator::CreateBoundingSize ( 2438 const Reference<rendering::XCanvas>& rxCanvas) 2439 { 2440 (void)rxCanvas; 2441 return awt::Size(20,1); 2442 } 2443 2444 2445 2446 2447 bool HorizontalSeparator::IsFilling (void) const 2448 { 2449 return true; 2450 } 2451 2452 2453 2454 2455 } // end of anonymous namespace 2456 2457 2458 } } // end of namespace ::sdext::presenter 2459