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