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