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