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