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