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