Line data Source code
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 :
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>
44 :
45 : using namespace ::com::sun::star;
46 : using namespace ::com::sun::star::uno;
47 : using namespace ::com::sun::star::drawing::framework;
48 :
49 : namespace sdext { namespace presenter {
50 :
51 : //===== PresenterSlideShowView ================================================
52 :
53 0 : 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 0 : mxCurrentSlide()
86 : {
87 0 : if (mpPresenterController.get() != NULL)
88 : {
89 0 : mnPageAspectRatio = mpPresenterController->GetSlideAspectRatio();
90 0 : mpBackground = mpPresenterController->GetViewBackground(mxViewId->getResourceURL());
91 : }
92 0 : }
93 :
94 0 : void PresenterSlideShowView::LateInit (void)
95 : {
96 0 : mxSlideShow = Reference<presentation::XSlideShow> (
97 0 : mxSlideShowController->getSlideShow(), UNO_QUERY_THROW);
98 0 : Reference<lang::XComponent> xSlideShowComponent (mxSlideShow, UNO_QUERY);
99 0 : if (xSlideShowComponent.is())
100 0 : xSlideShowComponent->addEventListener(static_cast<awt::XWindowListener*>(this));
101 :
102 : Reference<lang::XMultiComponentFactory> xFactory (
103 0 : mxComponentContext->getServiceManager(), UNO_QUERY_THROW);
104 0 : mxPresenterHelper.set (xFactory->createInstanceWithContext(
105 : OUString("com.sun.star.comp.Draw.PresenterHelper"),
106 0 : mxComponentContext),
107 0 : UNO_QUERY_THROW);
108 :
109 : // Use view id and controller to retrieve window and canvas from
110 : // configuration controller.
111 0 : Reference<XControllerManager> xCM (mxController, UNO_QUERY_THROW);
112 0 : Reference<XConfigurationController> xCC (xCM->getConfigurationController());
113 :
114 0 : if (xCC.is())
115 : {
116 0 : mxTopPane.set(xCC->getResource(mxViewId->getAnchor()->getAnchor()), UNO_QUERY);
117 :
118 0 : Reference<XPane> xPane (xCC->getResource(mxViewId->getAnchor()), UNO_QUERY_THROW);
119 :
120 0 : mxWindow = xPane->getWindow();
121 0 : mxCanvas = xPane->getCanvas();
122 :
123 0 : if (mxWindow.is())
124 : {
125 0 : mxWindow->addPaintListener(this);
126 0 : mxWindow->addWindowListener(this);
127 : }
128 :
129 : // The window does not have to paint a background. We do
130 : // that ourself.
131 0 : Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY);
132 0 : if (xPeer.is())
133 0 : xPeer->setBackground(util::Color(0xff000000));
134 : }
135 :
136 : // Create a window for the actual slide show view. It is places
137 : // centered and with maximal size inside the pane.
138 0 : mxViewWindow = CreateViewWindow(mxWindow);
139 :
140 0 : mxViewCanvas = CreateViewCanvas(mxViewWindow);
141 :
142 0 : if (mxViewWindow.is())
143 : {
144 : // Register listeners at window.
145 0 : mxViewWindow->addPaintListener(this);
146 0 : mxViewWindow->addMouseListener(this);
147 0 : mxViewWindow->addMouseMotionListener(this);
148 : }
149 :
150 0 : if (mxViewWindow.is())
151 0 : Resize();
152 :
153 0 : if (mxWindow.is())
154 0 : mxWindow->setVisible(sal_True);
155 :
156 : // Add the new slide show view to the slide show.
157 0 : if (mxSlideShow.is() && ! mbIsViewAdded)
158 : {
159 0 : impl_addAndConfigureView();
160 0 : mbIsViewAdded = true;
161 : }
162 :
163 : // Read text for one past last slide.
164 : PresenterConfigurationAccess aConfiguration (
165 : mxComponentContext,
166 : PresenterConfigurationAccess::msPresenterScreenRootName,
167 0 : PresenterConfigurationAccess::READ_ONLY);
168 : aConfiguration.GetConfigurationNode(
169 : "Presenter/Views/CurrentSlidePreview/"
170 : "Strings/ClickToExitPresentationText/String")
171 0 : >>= msClickToExitPresentationText;
172 : aConfiguration.GetConfigurationNode(
173 : "Presenter/Views/CurrentSlidePreview/"
174 : "Strings/ClickToExitPresentationTitle/String")
175 0 : >>= msClickToExitPresentationTitle;
176 0 : }
177 :
178 0 : PresenterSlideShowView::~PresenterSlideShowView (void)
179 : {
180 0 : }
181 :
182 0 : void PresenterSlideShowView::disposing (void)
183 : {
184 : // Tell all listeners that we are disposed.
185 0 : lang::EventObject aEvent;
186 0 : aEvent.Source = static_cast<XWeak*>(this);
187 :
188 : ::cppu::OInterfaceContainerHelper* pIterator
189 0 : = maBroadcaster.getContainer(cppu::UnoType<lang::XEventListener>::get());
190 0 : if (pIterator != NULL)
191 0 : pIterator->disposeAndClear(aEvent);
192 :
193 : // Do this for
194 : // XPaintListener, XModifyListener,XMouseListener,XMouseMotionListener,XWindowListener?
195 :
196 0 : if (mxWindow.is())
197 : {
198 0 : mxWindow->removePaintListener(this);
199 0 : mxWindow->removeMouseListener(this);
200 0 : mxWindow->removeMouseMotionListener(this);
201 0 : mxWindow->removeWindowListener(this);
202 0 : mxWindow = NULL;
203 : }
204 0 : mxSlideShowController = NULL;
205 0 : mxSlideShow = NULL;
206 0 : if (mxViewCanvas.is())
207 : {
208 0 : Reference<XComponent> xComponent (mxViewCanvas, UNO_QUERY);
209 0 : mxViewCanvas = NULL;
210 0 : if (xComponent.is())
211 0 : xComponent->dispose();
212 : }
213 0 : if (mxViewWindow.is())
214 : {
215 0 : Reference<XComponent> xComponent (mxViewWindow, UNO_QUERY);
216 0 : mxViewWindow = NULL;
217 0 : if (xComponent.is())
218 0 : xComponent->dispose();
219 : }
220 0 : if (mxPointer.is())
221 : {
222 0 : Reference<XComponent> xComponent (mxPointer, UNO_QUERY);
223 0 : mxPointer = NULL;
224 0 : if (xComponent.is())
225 0 : xComponent->dispose();
226 : }
227 0 : if (mxBackgroundPolygon1.is())
228 : {
229 0 : Reference<XComponent> xComponent (mxBackgroundPolygon1, UNO_QUERY);
230 0 : mxBackgroundPolygon1 = NULL;
231 0 : if (xComponent.is())
232 0 : xComponent->dispose();
233 : }
234 0 : if (mxBackgroundPolygon2.is())
235 : {
236 0 : Reference<XComponent> xComponent (mxBackgroundPolygon2, UNO_QUERY);
237 0 : mxBackgroundPolygon2 = NULL;
238 0 : if (xComponent.is())
239 0 : xComponent->dispose();
240 : }
241 :
242 0 : mxComponentContext = NULL;
243 0 : mpPresenterController = NULL;
244 0 : mxViewId = NULL;
245 0 : mxController = NULL;
246 0 : mxCanvas = NULL;
247 0 : mpBackground.reset();
248 0 : msClickToExitPresentationText = OUString();
249 0 : msClickToExitPresentationTitle = OUString();
250 0 : msTitleTemplate = OUString();
251 0 : mxCurrentSlide = NULL;
252 0 : }
253 :
254 : //----- XDrawView -------------------------------------------------------------
255 :
256 0 : void SAL_CALL PresenterSlideShowView::setCurrentPage (
257 : const css::uno::Reference<css::drawing::XDrawPage>& rxSlide)
258 : throw (css::uno::RuntimeException, std::exception)
259 : {
260 0 : mxCurrentSlide = rxSlide;
261 0 : if (mpPresenterController.get() != NULL
262 0 : && mxSlideShowController.is()
263 0 : && ! mpPresenterController->GetCurrentSlide().is()
264 0 : && ! mxSlideShowController->isPaused())
265 : {
266 0 : mbIsEndSlideVisible = true;
267 0 : Reference<awt::XWindowPeer> xPeer (mxViewWindow, UNO_QUERY);
268 0 : if (xPeer.is())
269 0 : xPeer->invalidate(awt::InvalidateStyle::NOTRANSPARENT);
270 :
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 0 : mpPresenterController->GetPaneContainer()->FindViewURL(mxViewId->getResourceURL()));
276 0 : if (pDescriptor.get() != NULL)
277 : {
278 0 : msTitleTemplate = pDescriptor->msTitleTemplate;
279 0 : pDescriptor->msTitleTemplate = msClickToExitPresentationTitle;
280 0 : mpPresenterController->UpdatePaneTitles();
281 0 : }
282 : }
283 0 : else if (mbIsEndSlideVisible)
284 : {
285 0 : mbIsEndSlideVisible = false;
286 :
287 : // Restore the title template.
288 : PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
289 0 : mpPresenterController->GetPaneContainer()->FindViewURL(mxViewId->getResourceURL()));
290 0 : if (pDescriptor.get() != NULL)
291 : {
292 0 : pDescriptor->msTitleTemplate = msTitleTemplate;
293 0 : pDescriptor->msTitle = OUString();
294 0 : mpPresenterController->UpdatePaneTitles();
295 0 : }
296 : }
297 0 : }
298 :
299 0 : css::uno::Reference<css::drawing::XDrawPage> SAL_CALL PresenterSlideShowView::getCurrentPage (void)
300 : throw (css::uno::RuntimeException, std::exception)
301 : {
302 0 : return mxCurrentSlide;
303 : }
304 :
305 : //----- CachablePresenterView -------------------------------------------------
306 :
307 0 : void PresenterSlideShowView::ReleaseView (void)
308 : {
309 0 : if (mxSlideShow.is() && mbIsViewAdded)
310 : {
311 0 : mxSlideShow->removeView(this);
312 0 : mbIsViewAdded = false;
313 : }
314 0 : }
315 :
316 : //----- XSlideShowView --------------------------------------------------------
317 :
318 0 : Reference<rendering::XSpriteCanvas> SAL_CALL PresenterSlideShowView::getCanvas (void)
319 : throw (RuntimeException, std::exception)
320 : {
321 0 : ThrowIfDisposed();
322 :
323 0 : return Reference<rendering::XSpriteCanvas>(mxViewCanvas, UNO_QUERY);
324 : }
325 :
326 0 : void SAL_CALL PresenterSlideShowView::clear (void)
327 : throw (RuntimeException, std::exception)
328 : {
329 0 : ThrowIfDisposed();
330 0 : mbIsForcedPaintPending = false;
331 0 : mbIsPaintPending = false;
332 :
333 0 : if (mxViewCanvas.is() && mxViewWindow.is())
334 : {
335 : // Create a polygon for the window outline.
336 0 : awt::Rectangle aViewWindowBox (mxViewWindow->getPosSize());
337 : Reference<rendering::XPolyPolygon2D> xPolygon (PresenterGeometryHelper::CreatePolygon(
338 : awt::Rectangle(0,0, aViewWindowBox.Width,aViewWindowBox.Height),
339 0 : mxViewCanvas->getDevice()));
340 :
341 : rendering::ViewState aViewState (
342 : geometry::AffineMatrix2D(1,0,0, 0,1,0),
343 0 : NULL);
344 0 : 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 0 : rendering::CompositeOperation::SOURCE);
350 0 : mxViewCanvas->fillPolyPolygon(xPolygon, aViewState, aRenderState);
351 : }
352 0 : }
353 :
354 0 : geometry::AffineMatrix2D SAL_CALL PresenterSlideShowView::getTransformation (void)
355 : throw (RuntimeException, std::exception)
356 : {
357 0 : ThrowIfDisposed();
358 :
359 0 : if (mxViewWindow.is())
360 : {
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 0 : const awt::Rectangle aWindowBox = mxViewWindow->getPosSize();
371 : return geometry::AffineMatrix2D(
372 0 : aWindowBox.Width-1, 0, (mbIsInModifyNotification ? 1 : 0),
373 0 : 0, aWindowBox.Height-1, 0);
374 : }
375 : else
376 : {
377 0 : return geometry::AffineMatrix2D(1,0,0, 0,1,0);
378 : }
379 : }
380 :
381 0 : geometry::IntegerSize2D SAL_CALL PresenterSlideShowView::getTranslationOffset(void)
382 : throw (RuntimeException, std::exception)
383 : {
384 0 : ThrowIfDisposed();
385 0 : return geometry::IntegerSize2D(0,0);
386 : }
387 :
388 0 : void SAL_CALL PresenterSlideShowView::addTransformationChangedListener(
389 : const Reference<util::XModifyListener>& rxListener)
390 : throw (RuntimeException, std::exception)
391 : {
392 0 : ThrowIfDisposed();
393 : maBroadcaster.addListener(
394 0 : cppu::UnoType<util::XModifyListener>::get(),
395 0 : rxListener);
396 0 : }
397 :
398 0 : void SAL_CALL PresenterSlideShowView::removeTransformationChangedListener(
399 : const Reference<util::XModifyListener>& rxListener)
400 : throw (RuntimeException, std::exception)
401 : {
402 0 : ThrowIfDisposed();
403 : maBroadcaster.removeListener(
404 0 : cppu::UnoType<util::XModifyListener>::get(),
405 0 : rxListener);
406 0 : }
407 :
408 0 : void SAL_CALL PresenterSlideShowView::addPaintListener(
409 : const Reference<awt::XPaintListener>& rxListener)
410 : throw (RuntimeException, std::exception)
411 : {
412 0 : ThrowIfDisposed();
413 : maBroadcaster.addListener(
414 0 : cppu::UnoType<awt::XPaintListener>::get(),
415 0 : rxListener);
416 0 : }
417 :
418 0 : void SAL_CALL PresenterSlideShowView::removePaintListener(
419 : const Reference<awt::XPaintListener>& rxListener)
420 : throw (RuntimeException, std::exception)
421 : {
422 0 : ThrowIfDisposed();
423 : maBroadcaster.removeListener(
424 0 : cppu::UnoType<awt::XPaintListener>::get(),
425 0 : rxListener);
426 0 : }
427 :
428 0 : void SAL_CALL PresenterSlideShowView::addMouseListener(
429 : const Reference<awt::XMouseListener>& rxListener)
430 : throw (RuntimeException, std::exception)
431 : {
432 0 : ThrowIfDisposed();
433 : maBroadcaster.addListener(
434 0 : cppu::UnoType<awt::XMouseListener>::get(),
435 0 : rxListener);
436 0 : }
437 :
438 0 : void SAL_CALL PresenterSlideShowView::removeMouseListener(
439 : const Reference<awt::XMouseListener>& rxListener)
440 : throw (RuntimeException, std::exception)
441 : {
442 0 : ThrowIfDisposed();
443 : maBroadcaster.removeListener(
444 0 : cppu::UnoType<awt::XMouseListener>::get(),
445 0 : rxListener);
446 0 : }
447 :
448 0 : void SAL_CALL PresenterSlideShowView::addMouseMotionListener(
449 : const Reference<awt::XMouseMotionListener>& rxListener)
450 : throw (RuntimeException, std::exception)
451 : {
452 0 : ThrowIfDisposed();
453 : maBroadcaster.addListener(
454 0 : cppu::UnoType<awt::XMouseMotionListener>::get(),
455 0 : rxListener);
456 0 : }
457 :
458 0 : void SAL_CALL PresenterSlideShowView::removeMouseMotionListener(
459 : const Reference<awt::XMouseMotionListener>& rxListener)
460 : throw (RuntimeException, std::exception)
461 : {
462 0 : ThrowIfDisposed();
463 : maBroadcaster.removeListener(
464 0 : cppu::UnoType<awt::XMouseMotionListener>::get(),
465 0 : rxListener);
466 0 : }
467 :
468 0 : void SAL_CALL PresenterSlideShowView::setMouseCursor(::sal_Int16 nPointerShape)
469 : throw (RuntimeException, std::exception)
470 : {
471 0 : ThrowIfDisposed();
472 :
473 : // Create a pointer when it does not yet exist.
474 0 : if ( ! mxPointer.is())
475 : {
476 0 : mxPointer = awt::Pointer::create(mxComponentContext);
477 : }
478 :
479 : // Set the pointer to the given shape and the window(peer) to the
480 : // pointer.
481 0 : Reference<awt::XWindowPeer> xPeer (mxViewWindow, UNO_QUERY);
482 0 : if (mxPointer.is() && xPeer.is())
483 : {
484 0 : mxPointer->setType(nPointerShape);
485 0 : xPeer->setPointer(mxPointer);
486 0 : }
487 0 : }
488 :
489 0 : awt::Rectangle SAL_CALL PresenterSlideShowView::getCanvasArea( ) throw (RuntimeException, std::exception)
490 : {
491 0 : if( mxViewWindow.is() && mxTopPane.is() )
492 0 : return mxPresenterHelper->getWindowExtentsRelative( mxViewWindow, mxTopPane->getWindow() );
493 :
494 0 : awt::Rectangle aRectangle;
495 :
496 0 : aRectangle.X = aRectangle.Y = aRectangle.Width = aRectangle.Height = 0;
497 :
498 0 : return aRectangle;
499 : }
500 :
501 : //----- lang::XEventListener --------------------------------------------------
502 :
503 0 : void SAL_CALL PresenterSlideShowView::disposing (const lang::EventObject& rEvent)
504 : throw (RuntimeException, std::exception)
505 : {
506 0 : if (rEvent.Source == mxViewWindow)
507 0 : mxViewWindow = NULL;
508 0 : else if (rEvent.Source == mxSlideShow)
509 0 : mxSlideShow = NULL;
510 0 : }
511 :
512 : //----- XPaintListener --------------------------------------------------------
513 :
514 0 : void SAL_CALL PresenterSlideShowView::windowPaint (const awt::PaintEvent& rEvent)
515 : throw (RuntimeException, std::exception)
516 : {
517 : // Deactivated views must not be painted.
518 0 : if ( ! mbIsPresenterViewActive)
519 0 : return;
520 :
521 0 : awt::Rectangle aViewWindowBox (mxViewWindow->getPosSize());
522 0 : if (aViewWindowBox.Width <= 0 || aViewWindowBox.Height <= 0)
523 0 : return;
524 :
525 0 : if (rEvent.Source == mxWindow)
526 0 : PaintOuterWindow(rEvent.UpdateRect);
527 0 : else if (mbIsEndSlideVisible)
528 0 : PaintEndSlide(rEvent.UpdateRect);
529 : else
530 0 : PaintInnerWindow(rEvent);
531 : }
532 :
533 : //----- XMouseListener --------------------------------------------------------
534 :
535 0 : void SAL_CALL PresenterSlideShowView::mousePressed (const awt::MouseEvent& rEvent)
536 : throw (RuntimeException, std::exception)
537 : {
538 0 : awt::MouseEvent aEvent (rEvent);
539 0 : aEvent.Source = static_cast<XWeak*>(this);
540 : ::cppu::OInterfaceContainerHelper* pIterator
541 0 : = maBroadcaster.getContainer(cppu::UnoType<awt::XMouseListener>::get());
542 0 : if (pIterator != NULL)
543 : {
544 0 : pIterator->notifyEach(&awt::XMouseListener::mousePressed, aEvent);
545 : }
546 :
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 0 : if (mbIsEndSlideVisible)
551 0 : if (mpPresenterController.get() != NULL)
552 0 : mpPresenterController->HandleMouseClick(rEvent);
553 0 : }
554 :
555 0 : void SAL_CALL PresenterSlideShowView::mouseReleased (const awt::MouseEvent& rEvent)
556 : throw (RuntimeException, std::exception)
557 : {
558 0 : awt::MouseEvent aEvent (rEvent);
559 0 : aEvent.Source = static_cast<XWeak*>(this);
560 : ::cppu::OInterfaceContainerHelper* pIterator
561 0 : = maBroadcaster.getContainer(cppu::UnoType<awt::XMouseListener>::get());
562 0 : if (pIterator != NULL)
563 : {
564 0 : pIterator->notifyEach(&awt::XMouseListener::mouseReleased, aEvent);
565 0 : }
566 0 : }
567 :
568 0 : void SAL_CALL PresenterSlideShowView::mouseEntered (const awt::MouseEvent& rEvent)
569 : throw (RuntimeException, std::exception)
570 : {
571 0 : awt::MouseEvent aEvent (rEvent);
572 0 : aEvent.Source = static_cast<XWeak*>(this);
573 : ::cppu::OInterfaceContainerHelper* pIterator
574 0 : = maBroadcaster.getContainer(cppu::UnoType<awt::XMouseListener>::get());
575 0 : if (pIterator != NULL)
576 : {
577 0 : pIterator->notifyEach(&awt::XMouseListener::mouseEntered, aEvent);
578 0 : }
579 0 : }
580 :
581 0 : void SAL_CALL PresenterSlideShowView::mouseExited (const awt::MouseEvent& rEvent)
582 : throw (RuntimeException, std::exception)
583 : {
584 0 : awt::MouseEvent aEvent (rEvent);
585 0 : aEvent.Source = static_cast<XWeak*>(this);
586 : ::cppu::OInterfaceContainerHelper* pIterator
587 0 : = maBroadcaster.getContainer(cppu::UnoType<awt::XMouseListener>::get());
588 0 : if (pIterator != NULL)
589 : {
590 0 : pIterator->notifyEach(&awt::XMouseListener::mouseExited, aEvent);
591 0 : }
592 0 : }
593 :
594 : //----- XMouseMotionListener --------------------------------------------------
595 :
596 0 : void SAL_CALL PresenterSlideShowView::mouseDragged (const awt::MouseEvent& rEvent)
597 : throw (RuntimeException, std::exception)
598 : {
599 0 : awt::MouseEvent aEvent (rEvent);
600 0 : aEvent.Source = static_cast<XWeak*>(this);
601 : ::cppu::OInterfaceContainerHelper* pIterator
602 0 : = maBroadcaster.getContainer(cppu::UnoType<awt::XMouseMotionListener>::get());
603 0 : if (pIterator != NULL)
604 : {
605 0 : pIterator->notifyEach(&awt::XMouseMotionListener::mouseDragged, aEvent);
606 0 : }
607 0 : }
608 :
609 0 : void SAL_CALL PresenterSlideShowView::mouseMoved (const awt::MouseEvent& rEvent)
610 : throw (RuntimeException, std::exception)
611 : {
612 0 : awt::MouseEvent aEvent (rEvent);
613 0 : aEvent.Source = static_cast<XWeak*>(this);
614 : ::cppu::OInterfaceContainerHelper* pIterator
615 0 : = maBroadcaster.getContainer(cppu::UnoType<awt::XMouseMotionListener>::get());
616 0 : if (pIterator != NULL)
617 : {
618 0 : pIterator->notifyEach(&awt::XMouseMotionListener::mouseMoved, aEvent);
619 0 : }
620 0 : }
621 :
622 : //----- XWindowListener -------------------------------------------------------
623 :
624 0 : void SAL_CALL PresenterSlideShowView::windowResized (const awt::WindowEvent& rEvent)
625 : throw (RuntimeException, std::exception)
626 : {
627 : (void)rEvent;
628 :
629 0 : ThrowIfDisposed();
630 0 : ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex());
631 :
632 0 : Resize();
633 0 : }
634 :
635 0 : void SAL_CALL PresenterSlideShowView::windowMoved (const awt::WindowEvent& rEvent)
636 : throw (RuntimeException, std::exception)
637 : {
638 : (void)rEvent;
639 0 : if ( ! mbIsPaintPending)
640 0 : mbIsForcedPaintPending = true;
641 0 : }
642 :
643 0 : void SAL_CALL PresenterSlideShowView::windowShown (const lang::EventObject& rEvent)
644 : throw (RuntimeException, std::exception)
645 : {
646 : (void)rEvent;
647 0 : Resize();
648 0 : }
649 :
650 0 : void SAL_CALL PresenterSlideShowView::windowHidden (const lang::EventObject& rEvent)
651 : throw (RuntimeException, std::exception)
652 : {
653 : (void)rEvent;
654 0 : }
655 :
656 : //----- XView -----------------------------------------------------------------
657 :
658 0 : Reference<XResourceId> SAL_CALL PresenterSlideShowView::getResourceId (void)
659 : throw(RuntimeException, std::exception)
660 : {
661 0 : return mxViewId;
662 : }
663 :
664 0 : sal_Bool SAL_CALL PresenterSlideShowView::isAnchorOnly (void)
665 : throw (RuntimeException, std::exception)
666 : {
667 0 : return false;
668 : }
669 :
670 : //----- CachablePresenterView -------------------------------------------------
671 :
672 0 : void PresenterSlideShowView::ActivatePresenterView (void)
673 : {
674 0 : if (mxSlideShow.is() && ! mbIsViewAdded)
675 : {
676 0 : impl_addAndConfigureView();
677 0 : mbIsViewAdded = true;
678 : }
679 0 : }
680 :
681 0 : void PresenterSlideShowView::DeactivatePresenterView (void)
682 : {
683 0 : if (mxSlideShow.is() && mbIsViewAdded)
684 : {
685 0 : mxSlideShow->removeView(this);
686 0 : mbIsViewAdded = false;
687 : }
688 0 : }
689 :
690 :
691 :
692 0 : void PresenterSlideShowView::PaintOuterWindow (const awt::Rectangle& rRepaintBox)
693 : {
694 0 : if ( ! mxCanvas.is())
695 0 : return;
696 :
697 0 : if (mpBackground.get() == NULL)
698 0 : return;
699 :
700 : const rendering::ViewState aViewState(
701 : geometry::AffineMatrix2D(1,0,0, 0,1,0),
702 0 : PresenterGeometryHelper::CreatePolygon(rRepaintBox, mxCanvas->getDevice()));
703 :
704 : rendering::RenderState aRenderState (
705 : geometry::AffineMatrix2D(1,0,0, 0,1,0),
706 : NULL,
707 : Sequence<double>(4),
708 0 : rendering::CompositeOperation::SOURCE);
709 :
710 0 : Reference<rendering::XBitmap> xBackgroundBitmap (mpBackground->GetNormalBitmap());
711 0 : if (xBackgroundBitmap.is())
712 : {
713 0 : Sequence<rendering::Texture> aTextures (1);
714 0 : const geometry::IntegerSize2D aBitmapSize(xBackgroundBitmap->getSize());
715 0 : aTextures[0] = rendering::Texture (
716 : geometry::AffineMatrix2D(
717 : aBitmapSize.Width,0,0,
718 : 0,aBitmapSize.Height,0),
719 : 1,
720 : 0,
721 : xBackgroundBitmap,
722 : NULL,
723 : NULL,
724 : rendering::StrokeAttributes(),
725 : rendering::TexturingMode::REPEAT,
726 0 : rendering::TexturingMode::REPEAT);
727 :
728 0 : if (mxBackgroundPolygon1.is())
729 0 : mxCanvas->fillTexturedPolyPolygon(
730 : mxBackgroundPolygon1,
731 : aViewState,
732 : aRenderState,
733 0 : aTextures);
734 0 : if (mxBackgroundPolygon2.is())
735 0 : mxCanvas->fillTexturedPolyPolygon(
736 : mxBackgroundPolygon2,
737 : aViewState,
738 : aRenderState,
739 0 : aTextures);
740 : }
741 : else
742 : {
743 0 : PresenterCanvasHelper::SetDeviceColor(aRenderState, mpBackground->maReplacementColor);
744 :
745 0 : if (mxBackgroundPolygon1.is())
746 0 : mxCanvas->fillPolyPolygon(mxBackgroundPolygon1, aViewState, aRenderState);
747 0 : if (mxBackgroundPolygon2.is())
748 0 : mxCanvas->fillPolyPolygon(mxBackgroundPolygon2, aViewState, aRenderState);
749 0 : }
750 : }
751 :
752 0 : void PresenterSlideShowView::PaintEndSlide (const awt::Rectangle& rRepaintBox)
753 : {
754 0 : if ( ! mxCanvas.is())
755 0 : return;
756 :
757 : const rendering::ViewState aViewState(
758 : geometry::AffineMatrix2D(1,0,0, 0,1,0),
759 0 : PresenterGeometryHelper::CreatePolygon(rRepaintBox, mxCanvas->getDevice()));
760 :
761 : rendering::RenderState aRenderState (
762 : geometry::AffineMatrix2D(1,0,0, 0,1,0),
763 : NULL,
764 : Sequence<double>(4),
765 0 : rendering::CompositeOperation::SOURCE);
766 0 : PresenterCanvasHelper::SetDeviceColor(aRenderState, util::Color(0x00000000));
767 0 : mxCanvas->fillPolyPolygon(
768 0 : PresenterGeometryHelper::CreatePolygon(mxViewWindow->getPosSize(), mxCanvas->getDevice()),
769 : aViewState,
770 0 : aRenderState);
771 :
772 : do
773 : {
774 0 : if (mpPresenterController.get() == NULL)
775 0 : break;
776 0 : ::boost::shared_ptr<PresenterTheme> pTheme (mpPresenterController->GetTheme());
777 0 : if (pTheme.get() == NULL)
778 0 : break;
779 :
780 0 : const OUString sViewStyle (pTheme->GetStyleName(mxViewId->getResourceURL()));
781 0 : PresenterTheme::SharedFontDescriptor pFont (pTheme->GetFont(sViewStyle));
782 0 : if (pFont.get() == NULL)
783 0 : break;
784 :
785 : /// this is responsible of the " presentation exit " text inside the slide windows
786 0 : PresenterCanvasHelper::SetDeviceColor(aRenderState, util::Color(0x00ffffff));
787 0 : aRenderState.AffineTransform.m02 = 20;
788 0 : aRenderState.AffineTransform.m12 = 40;
789 : const rendering::StringContext aContext (
790 0 : msClickToExitPresentationText, 0, msClickToExitPresentationText.getLength());
791 0 : pFont->PrepareFont(mxCanvas);
792 : const Reference<rendering::XTextLayout> xLayout (
793 0 : pFont->mxFont->createTextLayout(aContext,rendering::TextDirection::WEAK_LEFT_TO_RIGHT,0));
794 0 : mxCanvas->drawTextLayout(
795 : xLayout,
796 : aViewState,
797 0 : aRenderState);
798 : }
799 : while (false);
800 :
801 : // Finally, in double buffered environments, request the changes to be
802 : // made visible.
803 0 : Reference<rendering::XSpriteCanvas> mxSpriteCanvas (mxCanvas, UNO_QUERY);
804 0 : if (mxSpriteCanvas.is())
805 0 : mxSpriteCanvas->updateScreen(sal_True);
806 : }
807 :
808 0 : void PresenterSlideShowView::PaintInnerWindow (const awt::PaintEvent& rEvent)
809 : {
810 : // Forward window paint to listeners.
811 0 : awt::PaintEvent aEvent (rEvent);
812 0 : aEvent.Source = static_cast<XWeak*>(this);
813 : ::cppu::OInterfaceContainerHelper* pIterator
814 0 : = maBroadcaster.getContainer(cppu::UnoType<awt::XPaintListener>::get());
815 0 : if (pIterator != NULL)
816 : {
817 0 : pIterator->notifyEach(&awt::XPaintListener::windowPaint, aEvent);
818 : }
819 :
820 0 : if (mbIsForcedPaintPending)
821 0 : ForceRepaint();
822 :
823 : // Finally, in double buffered environments, request the changes to be
824 : // made visible.
825 0 : Reference<rendering::XSpriteCanvas> mxSpriteCanvas (mxCanvas, UNO_QUERY);
826 0 : if (mxSpriteCanvas.is())
827 0 : mxSpriteCanvas->updateScreen(sal_True);
828 0 : }
829 :
830 0 : Reference<awt::XWindow> PresenterSlideShowView::CreateViewWindow (
831 : const Reference<awt::XWindow>& rxParentWindow) const
832 : {
833 0 : Reference<awt::XWindow> xViewWindow;
834 : try
835 : {
836 0 : Reference<lang::XMultiComponentFactory> xFactory (mxComponentContext->getServiceManager());
837 0 : if ( ! xFactory.is())
838 0 : return xViewWindow;
839 :
840 0 : 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 0 : | awt::WindowAttribute::NODECORATION);
850 0 : xViewWindow = Reference<awt::XWindow>(
851 0 : xToolkit->createWindow(aWindowDescriptor),UNO_QUERY_THROW);
852 :
853 : // Make the background transparent. The slide show paints its own background.
854 0 : Reference<awt::XWindowPeer> xPeer (xViewWindow, UNO_QUERY_THROW);
855 0 : if (xPeer.is())
856 : {
857 0 : xPeer->setBackground(0xff000000);
858 : }
859 :
860 0 : xViewWindow->setVisible(sal_True);
861 : }
862 0 : catch (RuntimeException&)
863 : {
864 : }
865 0 : return xViewWindow;
866 : }
867 :
868 0 : Reference<rendering::XCanvas> PresenterSlideShowView::CreateViewCanvas (
869 : const Reference<awt::XWindow>& rxViewWindow) const
870 : {
871 : // Create a canvas for the view window.
872 0 : return mxPresenterHelper->createSharedCanvas(
873 0 : Reference<rendering::XSpriteCanvas>(mxTopPane->getCanvas(), UNO_QUERY),
874 0 : mxTopPane->getWindow(),
875 0 : mxTopPane->getCanvas(),
876 0 : mxTopPane->getWindow(),
877 0 : rxViewWindow);
878 : }
879 :
880 0 : void PresenterSlideShowView::Resize (void)
881 : {
882 0 : if ( ! mxWindow.is() || ! mxViewWindow.is())
883 0 : return;
884 :
885 0 : const awt::Rectangle aWindowBox (mxWindow->getPosSize());
886 0 : awt::Rectangle aViewWindowBox;
887 0 : if (aWindowBox.Height > 0)
888 : {
889 : const double nWindowAspectRatio (
890 0 : double(aWindowBox.Width) / double(aWindowBox.Height));
891 0 : if (nWindowAspectRatio > mnPageAspectRatio)
892 : {
893 : // Slides will be painted with the full parent window height.
894 0 : aViewWindowBox.Width = sal_Int32(aWindowBox.Height * mnPageAspectRatio + 0.5);
895 0 : aViewWindowBox.Height = aWindowBox.Height;
896 0 : aViewWindowBox.X = (aWindowBox.Width - aViewWindowBox.Width) / 2;
897 0 : aViewWindowBox.Y = 0;
898 : }
899 : else
900 : {
901 : // Slides will be painted with the full parent window width.
902 0 : aViewWindowBox.Width = aWindowBox.Width;
903 0 : aViewWindowBox.Height = sal_Int32(aWindowBox.Width / mnPageAspectRatio + 0.5);
904 0 : aViewWindowBox.X = 0;
905 0 : aViewWindowBox.Y = (aWindowBox.Height - aViewWindowBox.Height) / 2;
906 : }
907 0 : mxViewWindow->setPosSize(
908 : aViewWindowBox.X,
909 : aViewWindowBox.Y,
910 : aViewWindowBox.Width,
911 : aViewWindowBox.Height,
912 0 : awt::PosSize::POSSIZE);
913 : }
914 :
915 : // Clear the background polygon so that on the next paint it is created
916 : // for the new size.
917 0 : CreateBackgroundPolygons();
918 :
919 : // Notify listeners that the transformation that maps the view into the
920 : // window has changed.
921 0 : lang::EventObject aEvent (static_cast<XWeak*>(this));
922 : ::cppu::OInterfaceContainerHelper* pIterator
923 0 : = maBroadcaster.getContainer(cppu::UnoType<util::XModifyListener>::get());
924 0 : if (pIterator != NULL)
925 : {
926 0 : pIterator->notifyEach(&util::XModifyListener::modified, aEvent);
927 : }
928 :
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 0 : if ( ! mbIsPaintPending)
933 0 : mbIsForcedPaintPending = true;
934 : }
935 :
936 0 : void PresenterSlideShowView::ForceRepaint (void)
937 : {
938 0 : if (mxSlideShow.is() && mbIsViewAdded)
939 : {
940 0 : mxSlideShow->removeView(this);
941 0 : impl_addAndConfigureView();
942 : }
943 0 : }
944 :
945 0 : void PresenterSlideShowView::CreateBackgroundPolygons (void)
946 : {
947 0 : const awt::Rectangle aWindowBox (mxWindow->getPosSize());
948 0 : const awt::Rectangle aViewWindowBox (mxViewWindow->getPosSize());
949 0 : if (aWindowBox.Height == aViewWindowBox.Height && aWindowBox.Width == aViewWindowBox.Width)
950 : {
951 0 : mxBackgroundPolygon1 = NULL;
952 0 : mxBackgroundPolygon2 = NULL;
953 : }
954 0 : else if (aWindowBox.Height == aViewWindowBox.Height)
955 : {
956 : // Paint two boxes to the left and right of the view window.
957 0 : mxBackgroundPolygon1 = PresenterGeometryHelper::CreatePolygon(
958 : awt::Rectangle(
959 : 0,
960 : 0,
961 : aViewWindowBox.X,
962 : aWindowBox.Height),
963 0 : mxCanvas->getDevice());
964 0 : mxBackgroundPolygon2 = PresenterGeometryHelper::CreatePolygon(
965 : awt::Rectangle(
966 0 : aViewWindowBox.X + aViewWindowBox.Width,
967 : 0,
968 0 : aWindowBox.Width - aViewWindowBox.X - aViewWindowBox.Width,
969 : aWindowBox.Height),
970 0 : mxCanvas->getDevice());
971 : }
972 : else
973 : {
974 : // Paint two boxes above and below the view window.
975 0 : mxBackgroundPolygon1 = PresenterGeometryHelper::CreatePolygon(
976 : awt::Rectangle(
977 : 0,
978 : 0,
979 : aWindowBox.Width,
980 : aViewWindowBox.Y),
981 0 : mxCanvas->getDevice());
982 0 : mxBackgroundPolygon2 = PresenterGeometryHelper::CreatePolygon(
983 : awt::Rectangle(
984 : 0,
985 0 : aViewWindowBox.Y + aViewWindowBox.Height,
986 : aWindowBox.Width,
987 0 : aWindowBox.Height - aViewWindowBox.Y - aViewWindowBox.Height),
988 0 : mxCanvas->getDevice());
989 : }
990 0 : }
991 :
992 0 : void PresenterSlideShowView::ThrowIfDisposed (void)
993 : throw (::com::sun::star::lang::DisposedException)
994 : {
995 0 : if (rBHelper.bDisposed || rBHelper.bInDispose)
996 : {
997 : throw lang::DisposedException (
998 : OUString("PresenterSlideShowView object has already been disposed"),
999 0 : static_cast<uno::XWeak*>(this));
1000 : }
1001 0 : }
1002 :
1003 0 : void PresenterSlideShowView::impl_addAndConfigureView()
1004 : {
1005 0 : Reference<presentation::XSlideShowView> xView (this);
1006 0 : mxSlideShow->addView(xView);
1007 : // Prevent embeded sounds being played twice at the same time by
1008 : // disabling sound for the new slide show view.
1009 0 : beans::PropertyValue aProperty;
1010 0 : aProperty.Name = "IsSoundEnabled";
1011 0 : Sequence<Any> aValues (2);
1012 0 : aValues[0] <<= xView;
1013 0 : aValues[1] <<= sal_False;
1014 0 : aProperty.Value <<= aValues;
1015 0 : mxSlideShow->setProperty(aProperty);
1016 0 : }
1017 :
1018 24 : } } // end of namespace ::sd::presenter
1019 :
1020 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|