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