Bump version to 5.0-14
[LibreOffice.git] / sdext / source / presenter / PresenterSlideShowView.cxx
blobb3308e2b221ce76c07d401935c0b3670c1b129d1
2 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 /*
4 * This file is part of the LibreOffice project.
6 * This Source Code Form is subject to the terms of the Mozilla Public
7 * License, v. 2.0. If a copy of the MPL was not distributed with this
8 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 * This file incorporates work covered by the following license notice:
12 * Licensed to the Apache Software Foundation (ASF) under one or more
13 * contributor license agreements. See the NOTICE file distributed
14 * with this work for additional information regarding copyright
15 * ownership. The ASF licenses this file to you under the Apache
16 * License, Version 2.0 (the "License"); you may not use this file
17 * except in compliance with the License. You may obtain a copy of
18 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "PresenterSlideShowView.hxx"
22 #include "vcl/svapp.hxx"
23 #include "PresenterCanvasHelper.hxx"
24 #include "PresenterGeometryHelper.hxx"
25 #include "PresenterHelper.hxx"
26 #include "PresenterPaneContainer.hxx"
27 #include <com/sun/star/awt/InvalidateStyle.hpp>
28 #include <com/sun/star/awt/PosSize.hpp>
29 #include <com/sun/star/awt/Pointer.hpp>
30 #include <com/sun/star/awt/Toolkit.hpp>
31 #include <com/sun/star/awt/WindowAttribute.hpp>
32 #include <com/sun/star/awt/XWindow.hpp>
33 #include <com/sun/star/awt/XWindow2.hpp>
34 #include <com/sun/star/awt/XWindowPeer.hpp>
35 #include <com/sun/star/beans/XPropertySet.hpp>
36 #include <com/sun/star/drawing/CanvasFeature.hpp>
37 #include <com/sun/star/drawing/XPresenterHelper.hpp>
38 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
39 #include <com/sun/star/drawing/framework/XConfigurationController.hpp>
40 #include <com/sun/star/rendering/CompositeOperation.hpp>
41 #include <com/sun/star/rendering/TextDirection.hpp>
42 #include <com/sun/star/rendering/TexturingMode.hpp>
43 #include <osl/mutex.hxx>
45 using namespace ::com::sun::star;
46 using namespace ::com::sun::star::uno;
47 using namespace ::com::sun::star::drawing::framework;
49 namespace sdext { namespace presenter {
51 //===== PresenterSlideShowView ================================================
53 PresenterSlideShowView::PresenterSlideShowView (
54 const css::uno::Reference<css::uno::XComponentContext>& rxContext,
55 const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId,
56 const css::uno::Reference<css::frame::XController>& rxController,
57 const ::rtl::Reference<PresenterController>& rpPresenterController)
58 : PresenterSlideShowViewInterfaceBase(m_aMutex),
59 mxComponentContext(rxContext),
60 mpPresenterController(rpPresenterController),
61 mxViewId(rxViewId),
62 mxController(rxController),
63 mxSlideShowController(PresenterHelper::GetSlideShowController(rxController)),
64 mxSlideShow(),
65 mxCanvas(),
66 mxViewCanvas(),
67 mxPointer(),
68 mxWindow(),
69 mxViewWindow(),
70 mxTopPane(),
71 mxPresenterHelper(),
72 mxBackgroundPolygon1(),
73 mxBackgroundPolygon2(),
74 mbIsViewAdded(false),
75 mnPageAspectRatio(28.0/21.0),
76 maBroadcaster(m_aMutex),
77 mpBackground(),
78 mbIsInModifyNotification(false),
79 mbIsForcedPaintPending(false),
80 mbIsPaintPending(true),
81 msClickToExitPresentationText(),
82 msClickToExitPresentationTitle(),
83 msTitleTemplate(),
84 mbIsEndSlideVisible(false),
85 mxCurrentSlide()
87 if (mpPresenterController.get() != NULL)
89 mnPageAspectRatio = mpPresenterController->GetSlideAspectRatio();
90 mpBackground = mpPresenterController->GetViewBackground(mxViewId->getResourceURL());
94 void PresenterSlideShowView::LateInit()
96 mxSlideShow = Reference<presentation::XSlideShow> (
97 mxSlideShowController->getSlideShow(), UNO_QUERY_THROW);
98 Reference<lang::XComponent> xSlideShowComponent (mxSlideShow, UNO_QUERY);
99 if (xSlideShowComponent.is())
100 xSlideShowComponent->addEventListener(static_cast<awt::XWindowListener*>(this));
102 Reference<lang::XMultiComponentFactory> xFactory (
103 mxComponentContext->getServiceManager(), UNO_QUERY_THROW);
104 mxPresenterHelper.set (xFactory->createInstanceWithContext(
105 OUString("com.sun.star.comp.Draw.PresenterHelper"),
106 mxComponentContext),
107 UNO_QUERY_THROW);
109 // Use view id and controller to retrieve window and canvas from
110 // configuration controller.
111 Reference<XControllerManager> xCM (mxController, UNO_QUERY_THROW);
112 Reference<XConfigurationController> xCC (xCM->getConfigurationController());
114 if (xCC.is())
116 mxTopPane.set(xCC->getResource(mxViewId->getAnchor()->getAnchor()), UNO_QUERY);
118 Reference<XPane> xPane (xCC->getResource(mxViewId->getAnchor()), UNO_QUERY_THROW);
120 mxWindow = xPane->getWindow();
121 mxCanvas = xPane->getCanvas();
123 if (mxWindow.is())
125 mxWindow->addPaintListener(this);
126 mxWindow->addWindowListener(this);
129 // The window does not have to paint a background. We do
130 // that ourself.
131 Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
132 if (xPeer.is())
133 xPeer->setBackground(util::Color(0xff000000));
136 // Create a window for the actual slide show view. It is places
137 // centered and with maximal size inside the pane.
138 mxViewWindow = CreateViewWindow(mxWindow);
140 mxViewCanvas = CreateViewCanvas(mxViewWindow);
142 if (mxViewWindow.is())
144 // Register listeners at window.
145 mxViewWindow->addPaintListener(this);
146 mxViewWindow->addMouseListener(this);
147 mxViewWindow->addMouseMotionListener(this);
150 if (mxViewWindow.is())
151 Resize();
153 if (mxWindow.is())
154 mxWindow->setVisible(sal_True);
156 // Add the new slide show view to the slide show.
157 if (mxSlideShow.is() && ! mbIsViewAdded)
159 impl_addAndConfigureView();
160 mbIsViewAdded = true;
163 // Read text for one past last slide.
164 PresenterConfigurationAccess aConfiguration (
165 mxComponentContext,
166 PresenterConfigurationAccess::msPresenterScreenRootName,
167 PresenterConfigurationAccess::READ_ONLY);
168 aConfiguration.GetConfigurationNode(
169 "Presenter/Views/CurrentSlidePreview/"
170 "Strings/ClickToExitPresentationText/String")
171 >>= msClickToExitPresentationText;
172 aConfiguration.GetConfigurationNode(
173 "Presenter/Views/CurrentSlidePreview/"
174 "Strings/ClickToExitPresentationTitle/String")
175 >>= msClickToExitPresentationTitle;
178 PresenterSlideShowView::~PresenterSlideShowView()
182 void PresenterSlideShowView::disposing()
184 // Tell all listeners that we are disposed.
185 lang::EventObject aEvent;
186 aEvent.Source = static_cast<XWeak*>(this);
188 ::cppu::OInterfaceContainerHelper* pIterator
189 = maBroadcaster.getContainer(cppu::UnoType<lang::XEventListener>::get());
190 if (pIterator != NULL)
191 pIterator->disposeAndClear(aEvent);
193 // Do this for
194 // XPaintListener, XModifyListener,XMouseListener,XMouseMotionListener,XWindowListener?
196 if (mxWindow.is())
198 mxWindow->removePaintListener(this);
199 mxWindow->removeMouseListener(this);
200 mxWindow->removeMouseMotionListener(this);
201 mxWindow->removeWindowListener(this);
202 mxWindow = NULL;
204 mxSlideShowController = NULL;
205 mxSlideShow = NULL;
206 if (mxViewCanvas.is())
208 Reference<XComponent> xComponent (mxViewCanvas, UNO_QUERY);
209 mxViewCanvas = NULL;
210 if (xComponent.is())
211 xComponent->dispose();
213 if (mxViewWindow.is())
215 Reference<XComponent> xComponent (mxViewWindow, UNO_QUERY);
216 mxViewWindow = NULL;
217 if (xComponent.is())
218 xComponent->dispose();
220 if (mxPointer.is())
222 Reference<XComponent> xComponent (mxPointer, UNO_QUERY);
223 mxPointer = NULL;
224 if (xComponent.is())
225 xComponent->dispose();
227 if (mxBackgroundPolygon1.is())
229 Reference<XComponent> xComponent (mxBackgroundPolygon1, UNO_QUERY);
230 mxBackgroundPolygon1 = NULL;
231 if (xComponent.is())
232 xComponent->dispose();
234 if (mxBackgroundPolygon2.is())
236 Reference<XComponent> xComponent (mxBackgroundPolygon2, UNO_QUERY);
237 mxBackgroundPolygon2 = NULL;
238 if (xComponent.is())
239 xComponent->dispose();
242 mxComponentContext = NULL;
243 mpPresenterController = NULL;
244 mxViewId = NULL;
245 mxController = NULL;
246 mxCanvas = NULL;
247 mpBackground.reset();
248 msClickToExitPresentationText.clear();
249 msClickToExitPresentationTitle.clear();
250 msTitleTemplate.clear();
251 mxCurrentSlide = NULL;
254 //----- XDrawView -------------------------------------------------------------
256 void SAL_CALL PresenterSlideShowView::setCurrentPage (
257 const css::uno::Reference<css::drawing::XDrawPage>& rxSlide)
258 throw (css::uno::RuntimeException, std::exception)
260 mxCurrentSlide = rxSlide;
261 if (mpPresenterController.get() != NULL
262 && mxSlideShowController.is()
263 && ! mpPresenterController->GetCurrentSlide().is()
264 && ! mxSlideShowController->isPaused())
266 mbIsEndSlideVisible = true;
267 Reference<awt::XWindowPeer> xPeer (mxViewWindow, UNO_QUERY);
268 if (xPeer.is())
269 xPeer->invalidate(awt::InvalidateStyle::NOTRANSPARENT);
271 // For the end slide we use a special title, without the (n of m)
272 // part. Save the title template for the case that the user goes
273 // backwards.
274 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
275 mpPresenterController->GetPaneContainer()->FindViewURL(mxViewId->getResourceURL()));
276 if (pDescriptor.get() != NULL)
278 msTitleTemplate = pDescriptor->msTitleTemplate;
279 pDescriptor->msTitleTemplate = msClickToExitPresentationTitle;
280 mpPresenterController->UpdatePaneTitles();
283 else if (mbIsEndSlideVisible)
285 mbIsEndSlideVisible = false;
287 // Restore the title template.
288 PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
289 mpPresenterController->GetPaneContainer()->FindViewURL(mxViewId->getResourceURL()));
290 if (pDescriptor.get() != NULL)
292 pDescriptor->msTitleTemplate = msTitleTemplate;
293 (pDescriptor->msTitle).clear();
294 mpPresenterController->UpdatePaneTitles();
299 css::uno::Reference<css::drawing::XDrawPage> SAL_CALL PresenterSlideShowView::getCurrentPage()
300 throw (css::uno::RuntimeException, std::exception)
302 return mxCurrentSlide;
305 //----- CachablePresenterView -------------------------------------------------
307 void PresenterSlideShowView::ReleaseView()
309 if (mxSlideShow.is() && mbIsViewAdded)
311 mxSlideShow->removeView(this);
312 mbIsViewAdded = false;
316 //----- XSlideShowView --------------------------------------------------------
318 Reference<rendering::XSpriteCanvas> SAL_CALL PresenterSlideShowView::getCanvas()
319 throw (RuntimeException, std::exception)
321 ThrowIfDisposed();
323 return Reference<rendering::XSpriteCanvas>(mxViewCanvas, UNO_QUERY);
326 void SAL_CALL PresenterSlideShowView::clear()
327 throw (RuntimeException, std::exception)
329 ThrowIfDisposed();
330 mbIsForcedPaintPending = false;
331 mbIsPaintPending = false;
333 if (mxViewCanvas.is() && mxViewWindow.is())
335 // Create a polygon for the window outline.
336 awt::Rectangle aViewWindowBox (mxViewWindow->getPosSize());
337 Reference<rendering::XPolyPolygon2D> xPolygon (PresenterGeometryHelper::CreatePolygon(
338 awt::Rectangle(0,0, aViewWindowBox.Width,aViewWindowBox.Height),
339 mxViewCanvas->getDevice()));
341 rendering::ViewState aViewState (
342 geometry::AffineMatrix2D(1,0,0, 0,1,0),
343 NULL);
344 double aColor[4] = {0,0,0,0};
345 rendering::RenderState aRenderState(
346 geometry::AffineMatrix2D(1,0,0, 0,1,0),
347 NULL,
348 Sequence<double>(aColor,4),
349 rendering::CompositeOperation::SOURCE);
350 mxViewCanvas->fillPolyPolygon(xPolygon, aViewState, aRenderState);
354 geometry::AffineMatrix2D SAL_CALL PresenterSlideShowView::getTransformation()
355 throw (RuntimeException, std::exception)
357 ThrowIfDisposed();
359 if (mxViewWindow.is())
361 // When the mbIsInModifyNotification is set then a slightly modified
362 // version of the transformation is returned in order to get past
363 // optimizations the avoid updates when the transformation is
364 // unchanged (when the window size changes then due to the constant
365 // aspect ratio the size of the preview may remain the same while
366 // the position changes. The position, however, is repesented by
367 // the position of the view window. This transformation is given
368 // relative to the view window and therefore does not contain the
369 // position.)
370 const awt::Rectangle aWindowBox = mxViewWindow->getPosSize();
371 return geometry::AffineMatrix2D(
372 aWindowBox.Width-1, 0, (mbIsInModifyNotification ? 1 : 0),
373 0, aWindowBox.Height-1, 0);
375 else
377 return geometry::AffineMatrix2D(1,0,0, 0,1,0);
381 geometry::IntegerSize2D SAL_CALL PresenterSlideShowView::getTranslationOffset()
382 throw (RuntimeException, std::exception)
384 ThrowIfDisposed();
385 return geometry::IntegerSize2D(0,0);
388 void SAL_CALL PresenterSlideShowView::addTransformationChangedListener(
389 const Reference<util::XModifyListener>& rxListener)
390 throw (RuntimeException, std::exception)
392 ThrowIfDisposed();
393 maBroadcaster.addListener(
394 cppu::UnoType<util::XModifyListener>::get(),
395 rxListener);
398 void SAL_CALL PresenterSlideShowView::removeTransformationChangedListener(
399 const Reference<util::XModifyListener>& rxListener)
400 throw (RuntimeException, std::exception)
402 ThrowIfDisposed();
403 maBroadcaster.removeListener(
404 cppu::UnoType<util::XModifyListener>::get(),
405 rxListener);
408 void SAL_CALL PresenterSlideShowView::addPaintListener(
409 const Reference<awt::XPaintListener>& rxListener)
410 throw (RuntimeException, std::exception)
412 ThrowIfDisposed();
413 maBroadcaster.addListener(
414 cppu::UnoType<awt::XPaintListener>::get(),
415 rxListener);
418 void SAL_CALL PresenterSlideShowView::removePaintListener(
419 const Reference<awt::XPaintListener>& rxListener)
420 throw (RuntimeException, std::exception)
422 ThrowIfDisposed();
423 maBroadcaster.removeListener(
424 cppu::UnoType<awt::XPaintListener>::get(),
425 rxListener);
428 void SAL_CALL PresenterSlideShowView::addMouseListener(
429 const Reference<awt::XMouseListener>& rxListener)
430 throw (RuntimeException, std::exception)
432 ThrowIfDisposed();
433 maBroadcaster.addListener(
434 cppu::UnoType<awt::XMouseListener>::get(),
435 rxListener);
438 void SAL_CALL PresenterSlideShowView::removeMouseListener(
439 const Reference<awt::XMouseListener>& rxListener)
440 throw (RuntimeException, std::exception)
442 ThrowIfDisposed();
443 maBroadcaster.removeListener(
444 cppu::UnoType<awt::XMouseListener>::get(),
445 rxListener);
448 void SAL_CALL PresenterSlideShowView::addMouseMotionListener(
449 const Reference<awt::XMouseMotionListener>& rxListener)
450 throw (RuntimeException, std::exception)
452 ThrowIfDisposed();
453 maBroadcaster.addListener(
454 cppu::UnoType<awt::XMouseMotionListener>::get(),
455 rxListener);
458 void SAL_CALL PresenterSlideShowView::removeMouseMotionListener(
459 const Reference<awt::XMouseMotionListener>& rxListener)
460 throw (RuntimeException, std::exception)
462 ThrowIfDisposed();
463 maBroadcaster.removeListener(
464 cppu::UnoType<awt::XMouseMotionListener>::get(),
465 rxListener);
468 void SAL_CALL PresenterSlideShowView::setMouseCursor(::sal_Int16 nPointerShape)
469 throw (RuntimeException, std::exception)
471 ThrowIfDisposed();
473 // Create a pointer when it does not yet exist.
474 if ( ! mxPointer.is())
476 mxPointer = awt::Pointer::create(mxComponentContext);
479 // Set the pointer to the given shape and the window(peer) to the
480 // pointer.
481 Reference<awt::XWindowPeer> xPeer (mxViewWindow, UNO_QUERY);
482 if (mxPointer.is() && xPeer.is())
484 mxPointer->setType(nPointerShape);
485 xPeer->setPointer(mxPointer);
489 awt::Rectangle SAL_CALL PresenterSlideShowView::getCanvasArea( ) throw (RuntimeException, std::exception)
491 if( mxViewWindow.is() && mxTopPane.is() )
492 return mxPresenterHelper->getWindowExtentsRelative( mxViewWindow, mxTopPane->getWindow() );
494 awt::Rectangle aRectangle;
496 aRectangle.X = aRectangle.Y = aRectangle.Width = aRectangle.Height = 0;
498 return aRectangle;
501 //----- lang::XEventListener --------------------------------------------------
503 void SAL_CALL PresenterSlideShowView::disposing (const lang::EventObject& rEvent)
504 throw (RuntimeException, std::exception)
506 if (rEvent.Source == mxViewWindow)
507 mxViewWindow = NULL;
508 else if (rEvent.Source == mxSlideShow)
509 mxSlideShow = NULL;
512 //----- XPaintListener --------------------------------------------------------
514 void SAL_CALL PresenterSlideShowView::windowPaint (const awt::PaintEvent& rEvent)
515 throw (RuntimeException, std::exception)
517 // Deactivated views must not be painted.
518 if ( ! mbIsPresenterViewActive)
519 return;
521 awt::Rectangle aViewWindowBox (mxViewWindow->getPosSize());
522 if (aViewWindowBox.Width <= 0 || aViewWindowBox.Height <= 0)
523 return;
525 if (rEvent.Source == mxWindow)
526 PaintOuterWindow(rEvent.UpdateRect);
527 else if (mbIsEndSlideVisible)
528 PaintEndSlide(rEvent.UpdateRect);
529 else
530 PaintInnerWindow(rEvent);
533 //----- XMouseListener --------------------------------------------------------
535 void SAL_CALL PresenterSlideShowView::mousePressed (const awt::MouseEvent& rEvent)
536 throw (RuntimeException, std::exception)
538 awt::MouseEvent aEvent (rEvent);
539 aEvent.Source = static_cast<XWeak*>(this);
540 ::cppu::OInterfaceContainerHelper* pIterator
541 = maBroadcaster.getContainer(cppu::UnoType<awt::XMouseListener>::get());
542 if (pIterator != NULL)
544 pIterator->notifyEach(&awt::XMouseListener::mousePressed, aEvent);
547 // Only when the end slide is displayed we forward the mouse event to
548 // the PresenterController so that it switches to the next slide and
549 // ends the presentation.
550 if (mbIsEndSlideVisible)
551 if (mpPresenterController.get() != NULL)
552 mpPresenterController->HandleMouseClick(rEvent);
555 void SAL_CALL PresenterSlideShowView::mouseReleased (const awt::MouseEvent& rEvent)
556 throw (RuntimeException, std::exception)
558 awt::MouseEvent aEvent (rEvent);
559 aEvent.Source = static_cast<XWeak*>(this);
560 ::cppu::OInterfaceContainerHelper* pIterator
561 = maBroadcaster.getContainer(cppu::UnoType<awt::XMouseListener>::get());
562 if (pIterator != NULL)
564 pIterator->notifyEach(&awt::XMouseListener::mouseReleased, aEvent);
568 void SAL_CALL PresenterSlideShowView::mouseEntered (const awt::MouseEvent& rEvent)
569 throw (RuntimeException, std::exception)
571 awt::MouseEvent aEvent (rEvent);
572 aEvent.Source = static_cast<XWeak*>(this);
573 ::cppu::OInterfaceContainerHelper* pIterator
574 = maBroadcaster.getContainer(cppu::UnoType<awt::XMouseListener>::get());
575 if (pIterator != NULL)
577 pIterator->notifyEach(&awt::XMouseListener::mouseEntered, aEvent);
581 void SAL_CALL PresenterSlideShowView::mouseExited (const awt::MouseEvent& rEvent)
582 throw (RuntimeException, std::exception)
584 awt::MouseEvent aEvent (rEvent);
585 aEvent.Source = static_cast<XWeak*>(this);
586 ::cppu::OInterfaceContainerHelper* pIterator
587 = maBroadcaster.getContainer(cppu::UnoType<awt::XMouseListener>::get());
588 if (pIterator != NULL)
590 pIterator->notifyEach(&awt::XMouseListener::mouseExited, aEvent);
594 //----- XMouseMotionListener --------------------------------------------------
596 void SAL_CALL PresenterSlideShowView::mouseDragged (const awt::MouseEvent& rEvent)
597 throw (RuntimeException, std::exception)
599 awt::MouseEvent aEvent (rEvent);
600 aEvent.Source = static_cast<XWeak*>(this);
601 ::cppu::OInterfaceContainerHelper* pIterator
602 = maBroadcaster.getContainer(cppu::UnoType<awt::XMouseMotionListener>::get());
603 if (pIterator != NULL)
605 pIterator->notifyEach(&awt::XMouseMotionListener::mouseDragged, aEvent);
609 void SAL_CALL PresenterSlideShowView::mouseMoved (const awt::MouseEvent& rEvent)
610 throw (RuntimeException, std::exception)
612 awt::MouseEvent aEvent (rEvent);
613 aEvent.Source = static_cast<XWeak*>(this);
614 ::cppu::OInterfaceContainerHelper* pIterator
615 = maBroadcaster.getContainer(cppu::UnoType<awt::XMouseMotionListener>::get());
616 if (pIterator != NULL)
618 pIterator->notifyEach(&awt::XMouseMotionListener::mouseMoved, aEvent);
622 //----- XWindowListener -------------------------------------------------------
624 void SAL_CALL PresenterSlideShowView::windowResized (const awt::WindowEvent& rEvent)
625 throw (RuntimeException, std::exception)
627 (void)rEvent;
629 ThrowIfDisposed();
630 ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex());
632 Resize();
635 void SAL_CALL PresenterSlideShowView::windowMoved (const awt::WindowEvent& rEvent)
636 throw (RuntimeException, std::exception)
638 (void)rEvent;
639 if ( ! mbIsPaintPending)
640 mbIsForcedPaintPending = true;
643 void SAL_CALL PresenterSlideShowView::windowShown (const lang::EventObject& rEvent)
644 throw (RuntimeException, std::exception)
646 (void)rEvent;
647 Resize();
650 void SAL_CALL PresenterSlideShowView::windowHidden (const lang::EventObject& rEvent)
651 throw (RuntimeException, std::exception)
653 (void)rEvent;
656 //----- XView -----------------------------------------------------------------
658 Reference<XResourceId> SAL_CALL PresenterSlideShowView::getResourceId()
659 throw(RuntimeException, std::exception)
661 return mxViewId;
664 sal_Bool SAL_CALL PresenterSlideShowView::isAnchorOnly()
665 throw (RuntimeException, std::exception)
667 return false;
670 //----- CachablePresenterView -------------------------------------------------
672 void PresenterSlideShowView::ActivatePresenterView()
674 if (mxSlideShow.is() && ! mbIsViewAdded)
676 impl_addAndConfigureView();
677 mbIsViewAdded = true;
681 void PresenterSlideShowView::DeactivatePresenterView()
683 if (mxSlideShow.is() && mbIsViewAdded)
685 mxSlideShow->removeView(this);
686 mbIsViewAdded = false;
692 void PresenterSlideShowView::PaintOuterWindow (const awt::Rectangle& rRepaintBox)
694 if ( ! mxCanvas.is())
695 return;
697 if (mpBackground.get() == NULL)
698 return;
700 const rendering::ViewState aViewState(
701 geometry::AffineMatrix2D(1,0,0, 0,1,0),
702 PresenterGeometryHelper::CreatePolygon(rRepaintBox, mxCanvas->getDevice()));
704 rendering::RenderState aRenderState (
705 geometry::AffineMatrix2D(1,0,0, 0,1,0),
706 NULL,
707 Sequence<double>(4),
708 rendering::CompositeOperation::SOURCE);
710 Reference<rendering::XBitmap> xBackgroundBitmap (mpBackground->GetNormalBitmap());
711 if (xBackgroundBitmap.is())
713 Sequence<rendering::Texture> aTextures (1);
714 const geometry::IntegerSize2D aBitmapSize(xBackgroundBitmap->getSize());
715 aTextures[0] = rendering::Texture (
716 geometry::AffineMatrix2D(
717 aBitmapSize.Width,0,0,
718 0,aBitmapSize.Height,0),
721 xBackgroundBitmap,
722 NULL,
723 NULL,
724 rendering::StrokeAttributes(),
725 rendering::TexturingMode::REPEAT,
726 rendering::TexturingMode::REPEAT);
728 if (mxBackgroundPolygon1.is())
729 mxCanvas->fillTexturedPolyPolygon(
730 mxBackgroundPolygon1,
731 aViewState,
732 aRenderState,
733 aTextures);
734 if (mxBackgroundPolygon2.is())
735 mxCanvas->fillTexturedPolyPolygon(
736 mxBackgroundPolygon2,
737 aViewState,
738 aRenderState,
739 aTextures);
741 else
743 PresenterCanvasHelper::SetDeviceColor(aRenderState, mpBackground->maReplacementColor);
745 if (mxBackgroundPolygon1.is())
746 mxCanvas->fillPolyPolygon(mxBackgroundPolygon1, aViewState, aRenderState);
747 if (mxBackgroundPolygon2.is())
748 mxCanvas->fillPolyPolygon(mxBackgroundPolygon2, aViewState, aRenderState);
752 void PresenterSlideShowView::PaintEndSlide (const awt::Rectangle& rRepaintBox)
754 if ( ! mxCanvas.is())
755 return;
757 const rendering::ViewState aViewState(
758 geometry::AffineMatrix2D(1,0,0, 0,1,0),
759 PresenterGeometryHelper::CreatePolygon(rRepaintBox, mxCanvas->getDevice()));
761 rendering::RenderState aRenderState (
762 geometry::AffineMatrix2D(1,0,0, 0,1,0),
763 NULL,
764 Sequence<double>(4),
765 rendering::CompositeOperation::SOURCE);
766 PresenterCanvasHelper::SetDeviceColor(aRenderState, util::Color(0x00000000));
767 mxCanvas->fillPolyPolygon(
768 PresenterGeometryHelper::CreatePolygon(mxViewWindow->getPosSize(), mxCanvas->getDevice()),
769 aViewState,
770 aRenderState);
774 if (mpPresenterController.get() == NULL)
775 break;
776 ::boost::shared_ptr<PresenterTheme> pTheme (mpPresenterController->GetTheme());
777 if (pTheme.get() == NULL)
778 break;
780 const OUString sViewStyle (pTheme->GetStyleName(mxViewId->getResourceURL()));
781 PresenterTheme::SharedFontDescriptor pFont (pTheme->GetFont(sViewStyle));
782 if (pFont.get() == NULL)
783 break;
785 /// this is responsible of the " presentation exit " text inside the slide windows
786 PresenterCanvasHelper::SetDeviceColor(aRenderState, util::Color(0x00ffffff));
787 aRenderState.AffineTransform.m02 = 20;
788 aRenderState.AffineTransform.m12 = 40;
789 const rendering::StringContext aContext (
790 msClickToExitPresentationText, 0, msClickToExitPresentationText.getLength());
791 pFont->PrepareFont(mxCanvas);
792 const Reference<rendering::XTextLayout> xLayout (
793 pFont->mxFont->createTextLayout(aContext,rendering::TextDirection::WEAK_LEFT_TO_RIGHT,0));
794 mxCanvas->drawTextLayout(
795 xLayout,
796 aViewState,
797 aRenderState);
799 while (false);
801 // Finally, in double buffered environments, request the changes to be
802 // made visible.
803 Reference<rendering::XSpriteCanvas> mxSpriteCanvas (mxCanvas, UNO_QUERY);
804 if (mxSpriteCanvas.is())
805 mxSpriteCanvas->updateScreen(sal_True);
808 void PresenterSlideShowView::PaintInnerWindow (const awt::PaintEvent& rEvent)
810 // Forward window paint to listeners.
811 awt::PaintEvent aEvent (rEvent);
812 aEvent.Source = static_cast<XWeak*>(this);
813 ::cppu::OInterfaceContainerHelper* pIterator
814 = maBroadcaster.getContainer(cppu::UnoType<awt::XPaintListener>::get());
815 if (pIterator != NULL)
817 pIterator->notifyEach(&awt::XPaintListener::windowPaint, aEvent);
820 if (mbIsForcedPaintPending)
821 ForceRepaint();
823 // Finally, in double buffered environments, request the changes to be
824 // made visible.
825 Reference<rendering::XSpriteCanvas> mxSpriteCanvas (mxCanvas, UNO_QUERY);
826 if (mxSpriteCanvas.is())
827 mxSpriteCanvas->updateScreen(sal_True);
830 Reference<awt::XWindow> PresenterSlideShowView::CreateViewWindow (
831 const Reference<awt::XWindow>& rxParentWindow) const
833 Reference<awt::XWindow> xViewWindow;
836 Reference<lang::XMultiComponentFactory> xFactory (mxComponentContext->getServiceManager());
837 if ( ! xFactory.is())
838 return xViewWindow;
840 Reference<awt::XToolkit2> xToolkit = awt::Toolkit::create(mxComponentContext);
841 awt::WindowDescriptor aWindowDescriptor (
842 awt::WindowClass_CONTAINER,
843 OUString(),
844 Reference<awt::XWindowPeer>(rxParentWindow,UNO_QUERY_THROW),
845 -1, // parent index not available
846 awt::Rectangle(0,0,10,10),
847 awt::WindowAttribute::SIZEABLE
848 | awt::WindowAttribute::MOVEABLE
849 | awt::WindowAttribute::NODECORATION);
850 xViewWindow = Reference<awt::XWindow>(
851 xToolkit->createWindow(aWindowDescriptor),UNO_QUERY_THROW);
853 // Make the background transparent. The slide show paints its own background.
854 Reference<awt::XWindowPeer> xPeer (xViewWindow, UNO_QUERY_THROW);
855 if (xPeer.is())
857 xPeer->setBackground(0xff000000);
860 xViewWindow->setVisible(sal_True);
862 catch (RuntimeException&)
865 return xViewWindow;
868 Reference<rendering::XCanvas> PresenterSlideShowView::CreateViewCanvas (
869 const Reference<awt::XWindow>& rxViewWindow) const
871 // Create a canvas for the view window.
872 return mxPresenterHelper->createSharedCanvas(
873 Reference<rendering::XSpriteCanvas>(mxTopPane->getCanvas(), UNO_QUERY),
874 mxTopPane->getWindow(),
875 mxTopPane->getCanvas(),
876 mxTopPane->getWindow(),
877 rxViewWindow);
880 void PresenterSlideShowView::Resize()
882 if ( ! mxWindow.is() || ! mxViewWindow.is())
883 return;
885 const awt::Rectangle aWindowBox (mxWindow->getPosSize());
886 awt::Rectangle aViewWindowBox;
887 if (aWindowBox.Height > 0)
889 const double nWindowAspectRatio (
890 double(aWindowBox.Width) / double(aWindowBox.Height));
891 if (nWindowAspectRatio > mnPageAspectRatio)
893 // Slides will be painted with the full parent window height.
894 aViewWindowBox.Width = sal_Int32(aWindowBox.Height * mnPageAspectRatio + 0.5);
895 aViewWindowBox.Height = aWindowBox.Height;
896 aViewWindowBox.X = (aWindowBox.Width - aViewWindowBox.Width) / 2;
897 aViewWindowBox.Y = 0;
899 else
901 // Slides will be painted with the full parent window width.
902 aViewWindowBox.Width = aWindowBox.Width;
903 aViewWindowBox.Height = sal_Int32(aWindowBox.Width / mnPageAspectRatio + 0.5);
904 aViewWindowBox.X = 0;
905 aViewWindowBox.Y = (aWindowBox.Height - aViewWindowBox.Height) / 2;
907 mxViewWindow->setPosSize(
908 aViewWindowBox.X,
909 aViewWindowBox.Y,
910 aViewWindowBox.Width,
911 aViewWindowBox.Height,
912 awt::PosSize::POSSIZE);
915 // Clear the background polygon so that on the next paint it is created
916 // for the new size.
917 CreateBackgroundPolygons();
919 // Notify listeners that the transformation that maps the view into the
920 // window has changed.
921 lang::EventObject aEvent (static_cast<XWeak*>(this));
922 ::cppu::OInterfaceContainerHelper* pIterator
923 = maBroadcaster.getContainer(cppu::UnoType<util::XModifyListener>::get());
924 if (pIterator != NULL)
926 pIterator->notifyEach(&util::XModifyListener::modified, aEvent);
929 // Due to constant aspect ratio resizing may lead a preview that changes
930 // its position but not its size. This invalidates the back buffer and
931 // we have to enforce a complete repaint.
932 if ( ! mbIsPaintPending)
933 mbIsForcedPaintPending = true;
936 void PresenterSlideShowView::ForceRepaint()
938 if (mxSlideShow.is() && mbIsViewAdded)
940 mxSlideShow->removeView(this);
941 impl_addAndConfigureView();
945 void PresenterSlideShowView::CreateBackgroundPolygons()
947 const awt::Rectangle aWindowBox (mxWindow->getPosSize());
948 const awt::Rectangle aViewWindowBox (mxViewWindow->getPosSize());
949 if (aWindowBox.Height == aViewWindowBox.Height && aWindowBox.Width == aViewWindowBox.Width)
951 mxBackgroundPolygon1 = NULL;
952 mxBackgroundPolygon2 = NULL;
954 else if (aWindowBox.Height == aViewWindowBox.Height)
956 // Paint two boxes to the left and right of the view window.
957 mxBackgroundPolygon1 = PresenterGeometryHelper::CreatePolygon(
958 awt::Rectangle(
961 aViewWindowBox.X,
962 aWindowBox.Height),
963 mxCanvas->getDevice());
964 mxBackgroundPolygon2 = PresenterGeometryHelper::CreatePolygon(
965 awt::Rectangle(
966 aViewWindowBox.X + aViewWindowBox.Width,
968 aWindowBox.Width - aViewWindowBox.X - aViewWindowBox.Width,
969 aWindowBox.Height),
970 mxCanvas->getDevice());
972 else
974 // Paint two boxes above and below the view window.
975 mxBackgroundPolygon1 = PresenterGeometryHelper::CreatePolygon(
976 awt::Rectangle(
979 aWindowBox.Width,
980 aViewWindowBox.Y),
981 mxCanvas->getDevice());
982 mxBackgroundPolygon2 = PresenterGeometryHelper::CreatePolygon(
983 awt::Rectangle(
985 aViewWindowBox.Y + aViewWindowBox.Height,
986 aWindowBox.Width,
987 aWindowBox.Height - aViewWindowBox.Y - aViewWindowBox.Height),
988 mxCanvas->getDevice());
992 void PresenterSlideShowView::ThrowIfDisposed()
993 throw (::com::sun::star::lang::DisposedException)
995 if (rBHelper.bDisposed || rBHelper.bInDispose)
997 throw lang::DisposedException (
998 OUString("PresenterSlideShowView object has already been disposed"),
999 static_cast<uno::XWeak*>(this));
1003 void PresenterSlideShowView::impl_addAndConfigureView()
1005 Reference<presentation::XSlideShowView> xView (this);
1006 mxSlideShow->addView(xView);
1007 // Prevent embedded sounds being played twice at the same time by
1008 // disabling sound for the new slide show view.
1009 beans::PropertyValue aProperty;
1010 aProperty.Name = "IsSoundEnabled";
1011 Sequence<Any> aValues (2);
1012 aValues[0] <<= xView;
1013 aValues[1] <<= sal_False;
1014 aProperty.Value <<= aValues;
1015 mxSlideShow->setProperty(aProperty);
1018 } } // end of namespace ::sd::presenter
1020 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */