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