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