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