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