LibreOffice Module sdext (master)  1
PresenterSlideShowView.cxx
Go to the documentation of this file.
1 
2 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 /*
4  * This file is part of the LibreOffice project.
5  *
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/.
9  *
10  * This file incorporates work covered by the following license notice:
11  *
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 .
19  */
20 
24 #include "PresenterHelper.hxx"
26 #include <com/sun/star/awt/InvalidateStyle.hpp>
27 #include <com/sun/star/awt/PosSize.hpp>
28 #include <com/sun/star/awt/Pointer.hpp>
29 #include <com/sun/star/awt/Toolkit.hpp>
30 #include <com/sun/star/awt/WindowAttribute.hpp>
31 #include <com/sun/star/awt/XWindow.hpp>
32 #include <com/sun/star/awt/XWindowPeer.hpp>
33 #include <com/sun/star/drawing/XPresenterHelper.hpp>
34 #include <com/sun/star/drawing/framework/XControllerManager.hpp>
35 #include <com/sun/star/drawing/framework/XConfigurationController.hpp>
36 #include <com/sun/star/rendering/CompositeOperation.hpp>
37 #include <com/sun/star/rendering/TextDirection.hpp>
38 #include <com/sun/star/rendering/TexturingMode.hpp>
39 #include <osl/mutex.hxx>
40 
41 using namespace ::com::sun::star;
42 using namespace ::com::sun::star::uno;
43 using namespace ::com::sun::star::drawing::framework;
44 
45 namespace sdext::presenter {
46 
47 //===== PresenterSlideShowView ================================================
48 
50  const css::uno::Reference<css::uno::XComponentContext>& rxContext,
51  const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId,
52  const css::uno::Reference<css::frame::XController>& rxController,
53  const ::rtl::Reference<PresenterController>& rpPresenterController)
55  mxComponentContext(rxContext),
56  mpPresenterController(rpPresenterController),
57  mxViewId(rxViewId),
58  mxController(rxController),
59  mxSlideShowController(PresenterHelper::GetSlideShowController(rxController)),
60  mbIsViewAdded(false),
61  mnPageAspectRatio(28.0/21.0),
62  maBroadcaster(m_aMutex),
63  mbIsForcedPaintPending(false),
64  mbIsPaintPending(true),
65  mbIsEndSlideVisible(false)
66 {
68  {
69  mnPageAspectRatio = mpPresenterController->GetSlideAspectRatio();
70  mpBackground = mpPresenterController->GetViewBackground(mxViewId->getResourceURL());
71  }
72 }
73 
75 {
76  mxSlideShow.set( mxSlideShowController->getSlideShow(), UNO_SET_THROW);
77  Reference<lang::XComponent> xSlideShowComponent (mxSlideShow, UNO_QUERY);
78  xSlideShowComponent->addEventListener(static_cast<awt::XWindowListener*>(this));
79 
80  Reference<lang::XMultiComponentFactory> xFactory (
81  mxComponentContext->getServiceManager(), UNO_SET_THROW);
82  mxPresenterHelper.set (xFactory->createInstanceWithContext(
83  "com.sun.star.comp.Draw.PresenterHelper",
85  UNO_QUERY_THROW);
86 
87  // Use view id and controller to retrieve window and canvas from
88  // configuration controller.
89  Reference<XControllerManager> xCM (mxController, UNO_QUERY_THROW);
90  Reference<XConfigurationController> xCC (xCM->getConfigurationController());
91 
92  if (xCC.is())
93  {
94  mxTopPane.set(xCC->getResource(mxViewId->getAnchor()->getAnchor()), UNO_QUERY);
95 
96  Reference<XPane> xPane (xCC->getResource(mxViewId->getAnchor()), UNO_QUERY_THROW);
97 
98  mxWindow = xPane->getWindow();
99  mxCanvas = xPane->getCanvas();
100 
101  if (mxWindow.is())
102  {
103  mxWindow->addPaintListener(this);
104  mxWindow->addWindowListener(this);
105  }
106 
107  // The window does not have to paint a background. We do
108  // that ourself.
109  Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
110  if (xPeer.is())
111  xPeer->setBackground(util::Color(0xff000000));
112  }
113 
114  // Create a window for the actual slide show view. It is places
115  // centered and with maximal size inside the pane.
117 
119 
120  if (mxViewWindow.is())
121  {
122  // Register listeners at window.
123  mxViewWindow->addPaintListener(this);
124  mxViewWindow->addMouseListener(this);
125  mxViewWindow->addMouseMotionListener(this);
126  }
127 
128  if (mxViewWindow.is())
129  Resize();
130 
131  if (mxWindow.is())
132  mxWindow->setVisible(true);
133 
134  // Add the new slide show view to the slide show.
135  if (mxSlideShow.is() && ! mbIsViewAdded)
136  {
138  mbIsViewAdded = true;
139  }
140 
141  // Read text for one past last slide.
142  PresenterConfigurationAccess aConfiguration (
146  aConfiguration.GetConfigurationNode(
147  "Presenter/Views/CurrentSlidePreview/"
148  "Strings/ClickToExitPresentationText/String")
150  aConfiguration.GetConfigurationNode(
151  "Presenter/Views/CurrentSlidePreview/"
152  "Strings/ClickToExitPresentationTitle/String")
154 }
155 
157 {
158 }
159 
161 {
162  // Tell all listeners that we are disposed.
163  lang::EventObject aEvent;
164  aEvent.Source = static_cast<XWeak*>(this);
165 
168  if (pIterator != nullptr)
169  pIterator->disposeAndClear(aEvent);
170 
171  // Do this for
172  // XPaintListener, XModifyListener,XMouseListener,XMouseMotionListener,XWindowListener?
173 
174  if (mxWindow.is())
175  {
176  mxWindow->removePaintListener(this);
177  mxWindow->removeMouseListener(this);
178  mxWindow->removeMouseMotionListener(this);
179  mxWindow->removeWindowListener(this);
180  mxWindow = nullptr;
181  }
182  mxSlideShowController = nullptr;
183  mxSlideShow = nullptr;
184  if (mxViewCanvas.is())
185  {
186  Reference<XComponent> xComponent (mxViewCanvas, UNO_QUERY);
187  mxViewCanvas = nullptr;
188  if (xComponent.is())
189  xComponent->dispose();
190  }
191  if (mxViewWindow.is())
192  {
193  Reference<XComponent> xComponent = mxViewWindow;
194  mxViewWindow = nullptr;
195  if (xComponent.is())
196  xComponent->dispose();
197  }
198  if (mxPointer.is())
199  {
200  Reference<XComponent> xComponent (mxPointer, UNO_QUERY);
201  mxPointer = nullptr;
202  if (xComponent.is())
203  xComponent->dispose();
204  }
205  if (mxBackgroundPolygon1.is())
206  {
207  Reference<XComponent> xComponent (mxBackgroundPolygon1, UNO_QUERY);
208  mxBackgroundPolygon1 = nullptr;
209  if (xComponent.is())
210  xComponent->dispose();
211  }
212  if (mxBackgroundPolygon2.is())
213  {
214  Reference<XComponent> xComponent (mxBackgroundPolygon2, UNO_QUERY);
215  mxBackgroundPolygon2 = nullptr;
216  if (xComponent.is())
217  xComponent->dispose();
218  }
219 
220  mxComponentContext = nullptr;
221  mpPresenterController = nullptr;
222  mxViewId = nullptr;
223  mxController = nullptr;
224  mxCanvas = nullptr;
225  mpBackground.reset();
228  msTitleTemplate.clear();
229  mxCurrentSlide = nullptr;
230 }
231 
232 //----- XDrawView -------------------------------------------------------------
233 
235  const css::uno::Reference<css::drawing::XDrawPage>& rxSlide)
236 {
237  mxCurrentSlide = rxSlide;
239  && mxSlideShowController.is()
240  && ! mpPresenterController->GetCurrentSlide().is()
241  && ! mxSlideShowController->isPaused())
242  {
243  mbIsEndSlideVisible = true;
244  Reference<awt::XWindowPeer> xPeer (mxViewWindow, UNO_QUERY);
245  if (xPeer.is())
246  xPeer->invalidate(awt::InvalidateStyle::NOTRANSPARENT);
247 
248  // For the end slide we use a special title, without the (n of m)
249  // part. Save the title template for the case that the user goes
250  // backwards.
252  mpPresenterController->GetPaneContainer()->FindViewURL(mxViewId->getResourceURL()));
253  if (pDescriptor)
254  {
255  msTitleTemplate = pDescriptor->msTitleTemplate;
256  pDescriptor->msTitleTemplate = msClickToExitPresentationTitle;
257  mpPresenterController->UpdatePaneTitles();
258  }
259  }
260  else if (mbIsEndSlideVisible)
261  {
262  mbIsEndSlideVisible = false;
263 
264  // Restore the title template.
266  mpPresenterController->GetPaneContainer()->FindViewURL(mxViewId->getResourceURL()));
267  if (pDescriptor)
268  {
269  pDescriptor->msTitleTemplate = msTitleTemplate;
270  pDescriptor->msTitle.clear();
271  mpPresenterController->UpdatePaneTitles();
272  }
273  }
274 }
275 
276 css::uno::Reference<css::drawing::XDrawPage> SAL_CALL PresenterSlideShowView::getCurrentPage()
277 {
278  return mxCurrentSlide;
279 }
280 
281 //----- CachablePresenterView -------------------------------------------------
282 
284 {
285  if (mxSlideShow.is() && mbIsViewAdded)
286  {
287  mxSlideShow->removeView(this);
288  mbIsViewAdded = false;
289  }
290 }
291 
292 //----- XSlideShowView --------------------------------------------------------
293 
294 Reference<rendering::XSpriteCanvas> SAL_CALL PresenterSlideShowView::getCanvas()
295 {
296  ThrowIfDisposed();
297 
298  return Reference<rendering::XSpriteCanvas>(mxViewCanvas, UNO_QUERY);
299 }
300 
302 {
303  ThrowIfDisposed();
304  mbIsForcedPaintPending = false;
305  mbIsPaintPending = false;
306 
307  if (!(mxViewCanvas.is() && mxViewWindow.is()))
308  return;
309 
310  // Create a polygon for the window outline.
311  awt::Rectangle aViewWindowBox (mxViewWindow->getPosSize());
312  Reference<rendering::XPolyPolygon2D> xPolygon (PresenterGeometryHelper::CreatePolygon(
313  awt::Rectangle(0,0, aViewWindowBox.Width,aViewWindowBox.Height),
314  mxViewCanvas->getDevice()));
315 
316  rendering::ViewState aViewState (
317  geometry::AffineMatrix2D(1,0,0, 0,1,0),
318  nullptr);
319  double const aColor[4] = {0,0,0,0};
320  rendering::RenderState aRenderState(
321  geometry::AffineMatrix2D(1,0,0, 0,1,0),
322  nullptr,
323  Sequence<double>(aColor,4),
324  rendering::CompositeOperation::SOURCE);
325  mxViewCanvas->fillPolyPolygon(xPolygon, aViewState, aRenderState);
326 }
327 
328 geometry::AffineMatrix2D SAL_CALL PresenterSlideShowView::getTransformation()
329 {
330  ThrowIfDisposed();
331 
332  if (mxViewWindow.is())
333  {
334  // When the mbIsInModifyNotification is set then a slightly modified
335  // version of the transformation is returned in order to get past
336  // optimizations the avoid updates when the transformation is
337  // unchanged (when the window size changes then due to the constant
338  // aspect ratio the size of the preview may remain the same while
339  // the position changes. The position, however, is represented by
340  // the position of the view window. This transformation is given
341  // relative to the view window and therefore does not contain the
342  // position.)
343  const awt::Rectangle aWindowBox = mxViewWindow->getPosSize();
344  return geometry::AffineMatrix2D(
345  aWindowBox.Width-1, 0, 0,
346  0, aWindowBox.Height-1, 0);
347  }
348  else
349  {
350  return geometry::AffineMatrix2D(1,0,0, 0,1,0);
351  }
352 }
353 
354 geometry::IntegerSize2D SAL_CALL PresenterSlideShowView::getTranslationOffset()
355 {
356  ThrowIfDisposed();
357  return geometry::IntegerSize2D(0,0);
358 }
359 
361  const Reference<util::XModifyListener>& rxListener)
362 {
363  ThrowIfDisposed();
366  rxListener);
367 }
368 
370  const Reference<util::XModifyListener>& rxListener)
371 {
372  ThrowIfDisposed();
375  rxListener);
376 }
377 
379  const Reference<awt::XPaintListener>& rxListener)
380 {
381  ThrowIfDisposed();
384  rxListener);
385 }
386 
388  const Reference<awt::XPaintListener>& rxListener)
389 {
390  ThrowIfDisposed();
393  rxListener);
394 }
395 
397  const Reference<awt::XMouseListener>& rxListener)
398 {
399  ThrowIfDisposed();
402  rxListener);
403 }
404 
406  const Reference<awt::XMouseListener>& rxListener)
407 {
408  ThrowIfDisposed();
411  rxListener);
412 }
413 
415  const Reference<awt::XMouseMotionListener>& rxListener)
416 {
417  ThrowIfDisposed();
420  rxListener);
421 }
422 
424  const Reference<awt::XMouseMotionListener>& rxListener)
425 {
426  ThrowIfDisposed();
429  rxListener);
430 }
431 
432 void SAL_CALL PresenterSlideShowView::setMouseCursor(::sal_Int16 nPointerShape)
433 {
434  ThrowIfDisposed();
435 
436  // Create a pointer when it does not yet exist.
437  if ( ! mxPointer.is())
438  {
439  mxPointer = awt::Pointer::create(mxComponentContext);
440  }
441 
442  // Set the pointer to the given shape and the window(peer) to the
443  // pointer.
444  Reference<awt::XWindowPeer> xPeer (mxViewWindow, UNO_QUERY);
445  if (mxPointer.is() && xPeer.is())
446  {
447  mxPointer->setType(nPointerShape);
448  xPeer->setPointer(mxPointer);
449  }
450 }
451 
452 awt::Rectangle SAL_CALL PresenterSlideShowView::getCanvasArea( )
453 {
454  if( mxViewWindow.is() && mxTopPane.is() )
455  return mxPresenterHelper->getWindowExtentsRelative( mxViewWindow, mxTopPane->getWindow() );
456 
457  awt::Rectangle aRectangle;
458 
459  aRectangle.X = aRectangle.Y = aRectangle.Width = aRectangle.Height = 0;
460 
461  return aRectangle;
462 }
463 
464 //----- lang::XEventListener --------------------------------------------------
465 
466 void SAL_CALL PresenterSlideShowView::disposing (const lang::EventObject& rEvent)
467 {
468  if (rEvent.Source == mxViewWindow)
469  mxViewWindow = nullptr;
470  else if (rEvent.Source == mxSlideShow)
471  mxSlideShow = nullptr;
472 }
473 
474 //----- XPaintListener --------------------------------------------------------
475 
476 void SAL_CALL PresenterSlideShowView::windowPaint (const awt::PaintEvent& rEvent)
477 {
478  // Deactivated views must not be painted.
480  return;
481 
482  awt::Rectangle aViewWindowBox (mxViewWindow->getPosSize());
483  if (aViewWindowBox.Width <= 0 || aViewWindowBox.Height <= 0)
484  return;
485 
486  if (rEvent.Source == mxWindow)
487  PaintOuterWindow(rEvent.UpdateRect);
488  else if (mbIsEndSlideVisible)
489  PaintEndSlide(rEvent.UpdateRect);
490  else
491  PaintInnerWindow(rEvent);
492 }
493 
494 //----- XMouseListener --------------------------------------------------------
495 
496 void SAL_CALL PresenterSlideShowView::mousePressed (const awt::MouseEvent& rEvent)
497 {
498  awt::MouseEvent aEvent (rEvent);
499  aEvent.Source = static_cast<XWeak*>(this);
502  if (pIterator != nullptr)
503  {
504  pIterator->notifyEach(&awt::XMouseListener::mousePressed, aEvent);
505  }
506 
507  // Only when the end slide is displayed we forward the mouse event to
508  // the PresenterController so that it switches to the next slide and
509  // ends the presentation.
512  mpPresenterController->HandleMouseClick(rEvent);
513 }
514 
515 void SAL_CALL PresenterSlideShowView::mouseReleased (const awt::MouseEvent& rEvent)
516 {
517  awt::MouseEvent aEvent (rEvent);
518  aEvent.Source = static_cast<XWeak*>(this);
521  if (pIterator != nullptr)
522  {
523  pIterator->notifyEach(&awt::XMouseListener::mouseReleased, aEvent);
524  }
525 }
526 
527 void SAL_CALL PresenterSlideShowView::mouseEntered (const awt::MouseEvent& rEvent)
528 {
529  awt::MouseEvent aEvent (rEvent);
530  aEvent.Source = static_cast<XWeak*>(this);
533  if (pIterator != nullptr)
534  {
535  pIterator->notifyEach(&awt::XMouseListener::mouseEntered, aEvent);
536  }
537 }
538 
539 void SAL_CALL PresenterSlideShowView::mouseExited (const awt::MouseEvent& rEvent)
540 {
541  awt::MouseEvent aEvent (rEvent);
542  aEvent.Source = static_cast<XWeak*>(this);
545  if (pIterator != nullptr)
546  {
547  pIterator->notifyEach(&awt::XMouseListener::mouseExited, aEvent);
548  }
549 }
550 
551 //----- XMouseMotionListener --------------------------------------------------
552 
553 void SAL_CALL PresenterSlideShowView::mouseDragged (const awt::MouseEvent& rEvent)
554 {
555  awt::MouseEvent aEvent (rEvent);
556  aEvent.Source = static_cast<XWeak*>(this);
559  if (pIterator != nullptr)
560  {
561  pIterator->notifyEach(&awt::XMouseMotionListener::mouseDragged, aEvent);
562  }
563 }
564 
565 void SAL_CALL PresenterSlideShowView::mouseMoved (const awt::MouseEvent& rEvent)
566 {
567  awt::MouseEvent aEvent (rEvent);
568  aEvent.Source = static_cast<XWeak*>(this);
571  if (pIterator != nullptr)
572  {
573  pIterator->notifyEach(&awt::XMouseMotionListener::mouseMoved, aEvent);
574  }
575 }
576 
577 //----- XWindowListener -------------------------------------------------------
578 
579 void SAL_CALL PresenterSlideShowView::windowResized (const awt::WindowEvent&)
580 {
581  ThrowIfDisposed();
582  ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex());
583 
584  Resize();
585 }
586 
587 void SAL_CALL PresenterSlideShowView::windowMoved (const awt::WindowEvent&)
588 {
589  if ( ! mbIsPaintPending)
590  mbIsForcedPaintPending = true;
591 }
592 
593 void SAL_CALL PresenterSlideShowView::windowShown (const lang::EventObject&)
594 {
595  Resize();
596 }
597 
598 void SAL_CALL PresenterSlideShowView::windowHidden (const lang::EventObject&) {}
599 
600 //----- XView -----------------------------------------------------------------
601 
602 Reference<XResourceId> SAL_CALL PresenterSlideShowView::getResourceId()
603 {
604  return mxViewId;
605 }
606 
608 {
609  return false;
610 }
611 
612 //----- CachablePresenterView -------------------------------------------------
613 
615 {
616  if (mxSlideShow.is() && ! mbIsViewAdded)
617  {
619  mbIsViewAdded = true;
620  }
621 }
622 
624 {
625  if (mxSlideShow.is() && mbIsViewAdded)
626  {
627  mxSlideShow->removeView(this);
628  mbIsViewAdded = false;
629  }
630 }
631 
632 
633 void PresenterSlideShowView::PaintOuterWindow (const awt::Rectangle& rRepaintBox)
634 {
635  if ( ! mxCanvas.is())
636  return;
637 
638  if (!mpBackground)
639  return;
640 
641  const rendering::ViewState aViewState(
642  geometry::AffineMatrix2D(1,0,0, 0,1,0),
643  PresenterGeometryHelper::CreatePolygon(rRepaintBox, mxCanvas->getDevice()));
644 
645  rendering::RenderState aRenderState (
646  geometry::AffineMatrix2D(1,0,0, 0,1,0),
647  nullptr,
648  Sequence<double>(4),
649  rendering::CompositeOperation::SOURCE);
650 
651  Reference<rendering::XBitmap> xBackgroundBitmap (mpBackground->GetNormalBitmap());
652  if (xBackgroundBitmap.is())
653  {
654  const geometry::IntegerSize2D aBitmapSize(xBackgroundBitmap->getSize());
655  Sequence<rendering::Texture> aTextures
656  {
657  {
658  geometry::AffineMatrix2D( aBitmapSize.Width,0,0, 0,aBitmapSize.Height,0),
659  1,
660  0,
661  xBackgroundBitmap,
662  nullptr,
663  nullptr,
664  rendering::StrokeAttributes(),
665  rendering::TexturingMode::REPEAT,
666  rendering::TexturingMode::REPEAT
667  }
668  };
669 
670  if (mxBackgroundPolygon1.is())
671  mxCanvas->fillTexturedPolyPolygon(
673  aViewState,
674  aRenderState,
675  aTextures);
676  if (mxBackgroundPolygon2.is())
677  mxCanvas->fillTexturedPolyPolygon(
679  aViewState,
680  aRenderState,
681  aTextures);
682  }
683  else
684  {
685  PresenterCanvasHelper::SetDeviceColor(aRenderState, mpBackground->maReplacementColor);
686 
687  if (mxBackgroundPolygon1.is())
688  mxCanvas->fillPolyPolygon(mxBackgroundPolygon1, aViewState, aRenderState);
689  if (mxBackgroundPolygon2.is())
690  mxCanvas->fillPolyPolygon(mxBackgroundPolygon2, aViewState, aRenderState);
691  }
692 }
693 
694 void PresenterSlideShowView::PaintEndSlide (const awt::Rectangle& rRepaintBox)
695 {
696  if ( ! mxCanvas.is())
697  return;
698 
699  const rendering::ViewState aViewState(
700  geometry::AffineMatrix2D(1,0,0, 0,1,0),
701  PresenterGeometryHelper::CreatePolygon(rRepaintBox, mxCanvas->getDevice()));
702 
703  rendering::RenderState aRenderState (
704  geometry::AffineMatrix2D(1,0,0, 0,1,0),
705  nullptr,
706  Sequence<double>(4),
707  rendering::CompositeOperation::SOURCE);
708  PresenterCanvasHelper::SetDeviceColor(aRenderState, util::Color(0x00000000));
709  mxCanvas->fillPolyPolygon(
710  PresenterGeometryHelper::CreatePolygon(mxViewWindow->getPosSize(), mxCanvas->getDevice()),
711  aViewState,
712  aRenderState);
713 
714  do
715  {
717  break;
718  std::shared_ptr<PresenterTheme> pTheme (mpPresenterController->GetTheme());
719  if (pTheme == nullptr)
720  break;
721 
722  const OUString sViewStyle (pTheme->GetStyleName(mxViewId->getResourceURL()));
723  PresenterTheme::SharedFontDescriptor pFont (pTheme->GetFont(sViewStyle));
724  if (!pFont)
725  break;
726 
728  PresenterCanvasHelper::SetDeviceColor(aRenderState, util::Color(0x00ffffff));
729  aRenderState.AffineTransform.m02 = 20;
730  aRenderState.AffineTransform.m12 = 40;
731  const rendering::StringContext aContext (
733  pFont->PrepareFont(mxCanvas);
734  const Reference<rendering::XTextLayout> xLayout (
735  pFont->mxFont->createTextLayout(aContext,rendering::TextDirection::WEAK_LEFT_TO_RIGHT,0));
736  mxCanvas->drawTextLayout(
737  xLayout,
738  aViewState,
739  aRenderState);
740  }
741  while (false);
742 
743  // Finally, in double buffered environments, request the changes to be
744  // made visible.
745  Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
746  if (xSpriteCanvas.is())
747  xSpriteCanvas->updateScreen(true);
748 }
749 
750 void PresenterSlideShowView::PaintInnerWindow (const awt::PaintEvent& rEvent)
751 {
752  // Forward window paint to listeners.
753  awt::PaintEvent aEvent (rEvent);
754  aEvent.Source = static_cast<XWeak*>(this);
757  if (pIterator != nullptr)
758  {
759  pIterator->notifyEach(&awt::XPaintListener::windowPaint, aEvent);
760  }
761 
767  {
768  mxSlideShow->removeView(this);
770  }
771 
772  // Finally, in double buffered environments, request the changes to be
773  // made visible.
774  Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
775  if (xSpriteCanvas.is())
776  xSpriteCanvas->updateScreen(true);
777 }
778 
780  const Reference<awt::XWindow>& rxParentWindow) const
781 {
782  Reference<awt::XWindow> xViewWindow;
783  try
784  {
785  Reference<lang::XMultiComponentFactory> xFactory (mxComponentContext->getServiceManager());
786  if ( ! xFactory.is())
787  return xViewWindow;
788 
789  Reference<awt::XToolkit2> xToolkit = awt::Toolkit::create(mxComponentContext);
790  awt::WindowDescriptor aWindowDescriptor (
791  awt::WindowClass_CONTAINER,
792  OUString(),
793  Reference<awt::XWindowPeer>(rxParentWindow,UNO_QUERY_THROW),
794  -1, // parent index not available
795  awt::Rectangle(0,0,10,10),
796  awt::WindowAttribute::SIZEABLE
797  | awt::WindowAttribute::MOVEABLE
798  | awt::WindowAttribute::NODECORATION);
799  xViewWindow.set( xToolkit->createWindow(aWindowDescriptor),UNO_QUERY_THROW);
800 
801  // Make the background transparent. The slide show paints its own background.
802  Reference<awt::XWindowPeer> xPeer (xViewWindow, UNO_QUERY_THROW);
803  xPeer->setBackground(0xff000000);
804 
805  xViewWindow->setVisible(true);
806  }
807  catch (RuntimeException&)
808  {
809  }
810  return xViewWindow;
811 }
812 
813 Reference<rendering::XCanvas> PresenterSlideShowView::CreateViewCanvas (
814  const Reference<awt::XWindow>& rxViewWindow) const
815 {
816  // Create a canvas for the view window.
817  return mxPresenterHelper->createSharedCanvas(
818  Reference<rendering::XSpriteCanvas>(mxTopPane->getCanvas(), UNO_QUERY),
819  mxTopPane->getWindow(),
820  mxTopPane->getCanvas(),
821  mxTopPane->getWindow(),
822  rxViewWindow);
823 }
824 
826 {
827  if ( ! mxWindow.is() || ! mxViewWindow.is())
828  return;
829 
830  const awt::Rectangle aWindowBox (mxWindow->getPosSize());
831  if (aWindowBox.Height > 0)
832  {
833  awt::Rectangle aViewWindowBox;
834  const double nWindowAspectRatio (
835  double(aWindowBox.Width) / double(aWindowBox.Height));
836  if (nWindowAspectRatio > mnPageAspectRatio)
837  {
838  // Slides will be painted with the full parent window height.
839  aViewWindowBox.Width = sal_Int32(aWindowBox.Height * mnPageAspectRatio + 0.5);
840  aViewWindowBox.Height = aWindowBox.Height;
841  aViewWindowBox.X = (aWindowBox.Width - aViewWindowBox.Width) / 2;
842  aViewWindowBox.Y = 0;
843  }
844  else
845  {
846  // Slides will be painted with the full parent window width.
847  aViewWindowBox.Width = aWindowBox.Width;
848  aViewWindowBox.Height = sal_Int32(aWindowBox.Width / mnPageAspectRatio + 0.5);
849  aViewWindowBox.X = 0;
850  aViewWindowBox.Y = (aWindowBox.Height - aViewWindowBox.Height) / 2;
851  }
852  mxViewWindow->setPosSize(
853  aViewWindowBox.X,
854  aViewWindowBox.Y,
855  aViewWindowBox.Width,
856  aViewWindowBox.Height,
857  awt::PosSize::POSSIZE);
858  }
859 
860  // Clear the background polygon so that on the next paint it is created
861  // for the new size.
863 
864  // Notify listeners that the transformation that maps the view into the
865  // window has changed.
866  lang::EventObject aEvent (static_cast<XWeak*>(this));
869  if (pIterator != nullptr)
870  {
871  pIterator->notifyEach(&util::XModifyListener::modified, aEvent);
872  }
873 
874  // Due to constant aspect ratio resizing may lead a preview that changes
875  // its position but not its size. This invalidates the back buffer and
876  // we have to enforce a complete repaint.
877  if ( ! mbIsPaintPending)
878  mbIsForcedPaintPending = true;
879 }
880 
882 {
883  const awt::Rectangle aWindowBox (mxWindow->getPosSize());
884  const awt::Rectangle aViewWindowBox (mxViewWindow->getPosSize());
885  if (aWindowBox.Height == aViewWindowBox.Height && aWindowBox.Width == aViewWindowBox.Width)
886  {
887  mxBackgroundPolygon1 = nullptr;
888  mxBackgroundPolygon2 = nullptr;
889  }
890  else if (aWindowBox.Height == aViewWindowBox.Height)
891  {
892  // Paint two boxes to the left and right of the view window.
894  awt::Rectangle(
895  0,
896  0,
897  aViewWindowBox.X,
898  aWindowBox.Height),
899  mxCanvas->getDevice());
901  awt::Rectangle(
902  aViewWindowBox.X + aViewWindowBox.Width,
903  0,
904  aWindowBox.Width - aViewWindowBox.X - aViewWindowBox.Width,
905  aWindowBox.Height),
906  mxCanvas->getDevice());
907  }
908  else
909  {
910  // Paint two boxes above and below the view window.
912  awt::Rectangle(
913  0,
914  0,
915  aWindowBox.Width,
916  aViewWindowBox.Y),
917  mxCanvas->getDevice());
919  awt::Rectangle(
920  0,
921  aViewWindowBox.Y + aViewWindowBox.Height,
922  aWindowBox.Width,
923  aWindowBox.Height - aViewWindowBox.Y - aViewWindowBox.Height),
924  mxCanvas->getDevice());
925  }
926 }
927 
929 {
930  if (rBHelper.bDisposed || rBHelper.bInDispose)
931  {
932  throw lang::DisposedException (
933  "PresenterSlideShowView object has already been disposed",
934  static_cast<uno::XWeak*>(this));
935  }
936 }
937 
939 {
940  Reference<presentation::XSlideShowView> xView (this);
941  mxSlideShow->addView(xView);
942  // Prevent embedded sounds being played twice at the same time by
943  // disabling sound for the new slide show view.
944  beans::PropertyValue aProperty;
945  aProperty.Name = "IsSoundEnabled";
946  Sequence<Any> aValues (2);
947  aValues[0] <<= xView;
948  aValues[1] <<= false;
949  aProperty.Value <<= aValues;
950  mxSlideShow->setProperty(aProperty);
951 }
952 
953 } // end of namespace ::sd::presenter
954 
955 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
cppu::WeakComponentImplHelper< css::presentation::XSlideShowView, css::awt::XPaintListener, css::awt::XMouseListener, css::awt::XMouseMotionListener, css::awt::XWindowListener, css::drawing::framework::XView, css::drawing::XDrawView > PresenterSlideShowViewInterfaceBase
css::uno::Reference< css::rendering::XCanvas > mxViewCanvas
virtual css::uno::Reference< css::rendering::XSpriteCanvas > SAL_CALL getCanvas() override
css::uno::Reference< css::awt::XWindow > CreateViewWindow(const css::uno::Reference< css::awt::XWindow > &rxParentWindow) const
Create the window into which the slide show will render its content.
std::shared_ptr< FontDescriptor > SharedFontDescriptor
PresenterSlideShowView(const css::uno::Reference< css::uno::XComponentContext > &rxContext, const css::uno::Reference< css::drawing::framework::XResourceId > &rxViewId, const css::uno::Reference< css::frame::XController > &rxController, const ::rtl::Reference< PresenterController > &rpPresenterController)
virtual void SAL_CALL setMouseCursor(::sal_Int16 nPointerShape) override
css::uno::Reference< css::frame::XController > mxController
virtual void SAL_CALL mouseDragged(const css::awt::MouseEvent &rEvent) override
css::uno::Reference< css::drawing::XPresenterHelper > mxPresenterHelper
css::uno::Reference< css::rendering::XCanvas > mxCanvas
css::uno::Reference< css::rendering::XPolyPolygon2D > mxBackgroundPolygon2
virtual css::geometry::IntegerSize2D SAL_CALL getTranslationOffset() override
virtual void SAL_CALL mouseMoved(const css::awt::MouseEvent &rEvent) override
virtual void SAL_CALL removeTransformationChangedListener(const css::uno::Reference< css::util::XModifyListener > &xListener) override
void SAL_CALL disposeAndClear(const css::lang::EventObject &rEvt)
virtual css::uno::Reference< css::drawing::XDrawPage > SAL_CALL getCurrentPage() override
OInterfaceContainerHelper *SAL_CALL getContainer(const keyType &key) const
This class gives access to the configuration.
virtual void SAL_CALL windowShown(const css::lang::EventObject &rEvent) override
css::uno::Reference< css::drawing::XDrawPage > mxCurrentSlide
virtual css::awt::Rectangle SAL_CALL getCanvasArea() override
virtual void SAL_CALL disposing() override
std::mutex m_aMutex
virtual void SAL_CALL mouseEntered(const css::awt::MouseEvent &rEvent) override
css::uno::Reference< css::drawing::framework::XResourceId > mxViewId
virtual void SAL_CALL addMouseMotionListener(const css::uno::Reference< css::awt::XMouseMotionListener > &xListener) override
css::uno::Reference< css::rendering::XCanvas > CreateViewCanvas(const css::uno::Reference< css::awt::XWindow > &rxWindow) const
void addListener(const keyType &key, const css::uno::Reference< css::uno::XInterface > &r)
virtual void SAL_CALL addMouseListener(const css::uno::Reference< css::awt::XMouseListener > &xListener) override
virtual void SAL_CALL setCurrentPage(const css::uno::Reference< css::drawing::XDrawPage > &rxSlide) override
css::uno::Reference< css::uno::XComponentContext > mxComponentContext
void removeListener(const keyType &key, const css::uno::Reference< css::uno::XInterface > &r)
void PaintEndSlide(const css::awt::Rectangle &rRepaintBox)
virtual void SAL_CALL mousePressed(const css::awt::MouseEvent &rEvent) override
virtual void SAL_CALL windowResized(const css::awt::WindowEvent &rEvent) override
virtual void SAL_CALL removePaintListener(const css::uno::Reference< css::awt::XPaintListener > &xListener) override
virtual void DeactivatePresenterView() override
Called when the view is put into a cache.
void PaintInnerWindow(const css::awt::PaintEvent &rEvent)
css::uno::Reference< css::presentation::XSlideShowController > GetSlideShowController(const css::uno::Reference< css::frame::XController > &rxController)
Return the slide show controller of a running presentation that has the same document as the given fr...
virtual void SAL_CALL removeMouseMotionListener(const css::uno::Reference< css::awt::XMouseMotionListener > &xListener) override
virtual void SAL_CALL addTransformationChangedListener(const css::uno::Reference< css::util::XModifyListener > &xListener) override
css::uno::Any GetConfigurationNode(const OUString &rsPathToNode)
Return a configuration node below the root of the called object.
unsigned char sal_Bool
virtual void SAL_CALL windowHidden(const css::lang::EventObject &rEvent) override
virtual void SAL_CALL windowPaint(const css::awt::PaintEvent &rEvent) override
virtual void SAL_CALL mouseExited(const css::awt::MouseEvent &rEvent) override
::cppu::OBroadcastHelper maBroadcaster
This broadcast helper is used to notify listeners registered to a SlideShowView object.
virtual void SAL_CALL removeMouseListener(const css::uno::Reference< css::awt::XMouseListener > &xListener) override
virtual void SAL_CALL windowMoved(const css::awt::WindowEvent &rEvent) override
static css::uno::Reference< css::rendering::XPolyPolygon2D > CreatePolygon(const css::awt::Rectangle &rBox, const css::uno::Reference< css::rendering::XGraphicDevice > &rxDevice)
virtual void SAL_CALL addPaintListener(const css::uno::Reference< css::awt::XPaintListener > &xListener) override
virtual css::uno::Reference< css::drawing::framework::XResourceId > SAL_CALL getResourceId() override
double mnPageAspectRatio
Aspect ratio of the current slide.
::rtl::Reference< PresenterController > mpPresenterController
css::uno::Reference< css::awt::XPointer > mxPointer
css::uno::Reference< css::presentation::XSlideShowController > mxSlideShowController
virtual sal_Bool SAL_CALL isAnchorOnly() override
rtl::Reference< PresenterController > mpPresenterController
css::uno::Reference< css::drawing::framework::XPane > mxTopPane
virtual void SAL_CALL mouseReleased(const css::awt::MouseEvent &rEvent) override
virtual css::geometry::AffineMatrix2D SAL_CALL getTransformation() override
css::uno::Reference< css::awt::XWindow > mxWindow
static void SetDeviceColor(css::rendering::RenderState &rRenderState, const css::util::Color aColor)
std::shared_ptr< PaneDescriptor > SharedPaneDescriptor
virtual void ReleaseView() override
Called before the view is disposed.
void PaintOuterWindow(const css::awt::Rectangle &rRepaintBox)
Reference< XSingleServiceFactory > xFactory
void notifyEach(void(SAL_CALL ListenerT::*NotificationMethod)(const EventT &), const EventT &Event)
css::uno::Reference< css::uno::XComponentContext > mxComponentContext
AnyEventRef aEvent
css::uno::Reference< css::awt::XWindow > mxViewWindow
css::uno::Reference< css::rendering::XPolyPolygon2D > mxBackgroundPolygon1
css::uno::Reference< css::presentation::XSlideShow > mxSlideShow