xref: /AOO41X/main/slideshow/source/engine/slideshowimpl.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_slideshow.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <canvas/debug.hxx>
32*cdf0e10cSrcweir #include <tools/diagnose_ex.h>
33*cdf0e10cSrcweir 
34*cdf0e10cSrcweir #include <cppuhelper/basemutex.hxx>
35*cdf0e10cSrcweir #include <cppuhelper/compbase1.hxx>
36*cdf0e10cSrcweir #include <cppuhelper/factory.hxx>
37*cdf0e10cSrcweir #include <cppuhelper/implementationentry.hxx>
38*cdf0e10cSrcweir #include <cppuhelper/compbase2.hxx>
39*cdf0e10cSrcweir #include <cppuhelper/interfacecontainer.h>
40*cdf0e10cSrcweir #include <cppuhelper/exc_hlp.hxx>
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir #include <comphelper/anytostring.hxx>
43*cdf0e10cSrcweir #include <comphelper/make_shared_from_uno.hxx>
44*cdf0e10cSrcweir #include <comphelper/scopeguard.hxx>
45*cdf0e10cSrcweir #include <comphelper/optional.hxx>
46*cdf0e10cSrcweir #include <comphelper/servicedecl.hxx>
47*cdf0e10cSrcweir #include <comphelper/namecontainer.hxx>
48*cdf0e10cSrcweir 
49*cdf0e10cSrcweir #include <cppcanvas/spritecanvas.hxx>
50*cdf0e10cSrcweir #include <cppcanvas/vclfactory.hxx>
51*cdf0e10cSrcweir #include <cppcanvas/basegfxfactory.hxx>
52*cdf0e10cSrcweir 
53*cdf0e10cSrcweir #include <tools/debug.hxx>
54*cdf0e10cSrcweir 
55*cdf0e10cSrcweir #include <basegfx/point/b2dpoint.hxx>
56*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx>
57*cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx>
58*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygontools.hxx>
59*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygontools.hxx>
60*cdf0e10cSrcweir #include <basegfx/tools/canvastools.hxx>
61*cdf0e10cSrcweir 
62*cdf0e10cSrcweir #include <vcl/font.hxx>
63*cdf0e10cSrcweir #include "rtl/ref.hxx"
64*cdf0e10cSrcweir 
65*cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
66*cdf0e10cSrcweir #include <com/sun/star/util/XModifyListener.hpp>
67*cdf0e10cSrcweir #include <com/sun/star/util/XUpdatable.hpp>
68*cdf0e10cSrcweir #include <com/sun/star/awt/XPaintListener.hpp>
69*cdf0e10cSrcweir #include <com/sun/star/awt/SystemPointer.hpp>
70*cdf0e10cSrcweir #include <com/sun/star/animations/TransitionType.hpp>
71*cdf0e10cSrcweir #include <com/sun/star/animations/TransitionSubType.hpp>
72*cdf0e10cSrcweir #include <com/sun/star/presentation/XSlideShow.hpp>
73*cdf0e10cSrcweir #include <com/sun/star/presentation/XSlideShowListener.hpp>
74*cdf0e10cSrcweir #include <com/sun/star/lang/XServiceInfo.hpp>
75*cdf0e10cSrcweir #include <com/sun/star/lang/XServiceName.hpp>
76*cdf0e10cSrcweir #include <com/sun/star/lang/XComponent.hpp>
77*cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp>
78*cdf0e10cSrcweir #include <com/sun/star/drawing/PointSequenceSequence.hpp>
79*cdf0e10cSrcweir #include <com/sun/star/drawing/PointSequence.hpp>
80*cdf0e10cSrcweir #include <com/sun/star/drawing/XLayer.hpp>
81*cdf0e10cSrcweir #include <com/sun/star/drawing/XLayerSupplier.hpp>
82*cdf0e10cSrcweir #include <com/sun/star/drawing/XLayerManager.hpp>
83*cdf0e10cSrcweir #include <com/sun/star/container/XNameAccess.hpp>
84*cdf0e10cSrcweir 
85*cdf0e10cSrcweir #include "com/sun/star/uno/Reference.hxx"
86*cdf0e10cSrcweir #include <com/sun/star/loader/CannotActivateFactoryException.hpp>
87*cdf0e10cSrcweir 
88*cdf0e10cSrcweir #include "unoviewcontainer.hxx"
89*cdf0e10cSrcweir #include "transitionfactory.hxx"
90*cdf0e10cSrcweir #include "eventmultiplexer.hxx"
91*cdf0e10cSrcweir #include "usereventqueue.hxx"
92*cdf0e10cSrcweir #include "eventqueue.hxx"
93*cdf0e10cSrcweir #include "cursormanager.hxx"
94*cdf0e10cSrcweir #include "slideshowcontext.hxx"
95*cdf0e10cSrcweir #include "activitiesqueue.hxx"
96*cdf0e10cSrcweir #include "activitiesfactory.hxx"
97*cdf0e10cSrcweir #include "interruptabledelayevent.hxx"
98*cdf0e10cSrcweir #include "slide.hxx"
99*cdf0e10cSrcweir #include "shapemaps.hxx"
100*cdf0e10cSrcweir #include "slideview.hxx"
101*cdf0e10cSrcweir #include "tools.hxx"
102*cdf0e10cSrcweir #include "unoview.hxx"
103*cdf0e10cSrcweir #include "slidebitmap.hxx"
104*cdf0e10cSrcweir #include "rehearsetimingsactivity.hxx"
105*cdf0e10cSrcweir #include "waitsymbol.hxx"
106*cdf0e10cSrcweir #include "effectrewinder.hxx"
107*cdf0e10cSrcweir #include "framerate.hxx"
108*cdf0e10cSrcweir 
109*cdf0e10cSrcweir #include <boost/noncopyable.hpp>
110*cdf0e10cSrcweir #include <boost/bind.hpp>
111*cdf0e10cSrcweir 
112*cdf0e10cSrcweir #include <map>
113*cdf0e10cSrcweir #include <vector>
114*cdf0e10cSrcweir #include <iterator>
115*cdf0e10cSrcweir #include <string>
116*cdf0e10cSrcweir #include <algorithm>
117*cdf0e10cSrcweir #include <stdio.h>
118*cdf0e10cSrcweir #include <iostream>
119*cdf0e10cSrcweir 
120*cdf0e10cSrcweir using namespace com::sun::star;
121*cdf0e10cSrcweir using namespace ::slideshow::internal;
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir namespace {
124*cdf0e10cSrcweir 
125*cdf0e10cSrcweir /** During animations the update() method tells its caller to call it as
126*cdf0e10cSrcweir     soon as possible.  This gives us more time to render the next frame and
127*cdf0e10cSrcweir     still maintain a steady frame rate.  This class is responsible for
128*cdf0e10cSrcweir     synchronizing the display of new frames and thus keeping the frame rate
129*cdf0e10cSrcweir     steady.
130*cdf0e10cSrcweir */
131*cdf0e10cSrcweir class FrameSynchronization
132*cdf0e10cSrcweir {
133*cdf0e10cSrcweir public:
134*cdf0e10cSrcweir     /** Create new object with a predefined duration between two frames.
135*cdf0e10cSrcweir         @param nFrameDuration
136*cdf0e10cSrcweir             The preferred duration between the display of two frames in
137*cdf0e10cSrcweir             seconds.
138*cdf0e10cSrcweir     */
139*cdf0e10cSrcweir     FrameSynchronization (const double nFrameDuration);
140*cdf0e10cSrcweir 
141*cdf0e10cSrcweir     /** Set the current time as the time at which the current frame is
142*cdf0e10cSrcweir         displayed.  From this the target time of the next frame is derived.
143*cdf0e10cSrcweir     */
144*cdf0e10cSrcweir     void MarkCurrentFrame (void);
145*cdf0e10cSrcweir 
146*cdf0e10cSrcweir     /** When there is time left until the next frame is due then wait.
147*cdf0e10cSrcweir         Otherwise return without delay.
148*cdf0e10cSrcweir     */
149*cdf0e10cSrcweir     void Synchronize (void);
150*cdf0e10cSrcweir 
151*cdf0e10cSrcweir     /** Activate frame synchronization when an animation is active and
152*cdf0e10cSrcweir         frames are to be displayed in a steady rate.  While active
153*cdf0e10cSrcweir         Synchronize() will wait until the frame duration time has passed.
154*cdf0e10cSrcweir     */
155*cdf0e10cSrcweir     void Activate (void);
156*cdf0e10cSrcweir 
157*cdf0e10cSrcweir     /** Deactivate frame sychronization when no animation is active and the
158*cdf0e10cSrcweir         time between frames depends on user actions and other external
159*cdf0e10cSrcweir         sources.  While deactivated Synchronize() will return without delay.
160*cdf0e10cSrcweir     */
161*cdf0e10cSrcweir     void Deactivate (void);
162*cdf0e10cSrcweir 
163*cdf0e10cSrcweir     /** Return the current time of the timer.  It is not synchronized with
164*cdf0e10cSrcweir         any other timer so its absolute values are of no concern.  Typically
165*cdf0e10cSrcweir         used during debugging to measure durations.
166*cdf0e10cSrcweir     */
167*cdf0e10cSrcweir     double GetCurrentTime (void) const;
168*cdf0e10cSrcweir 
169*cdf0e10cSrcweir private:
170*cdf0e10cSrcweir     /** The timer that is used for synchronization is independent from the
171*cdf0e10cSrcweir         one used by SlideShowImpl: it is not paused or modified by
172*cdf0e10cSrcweir         animations.
173*cdf0e10cSrcweir     */
174*cdf0e10cSrcweir     canvas::tools::ElapsedTime maTimer;
175*cdf0e10cSrcweir     /** Time between the display of frames.  Enforced only when mbIsActive
176*cdf0e10cSrcweir         is <TRUE/>.
177*cdf0e10cSrcweir     */
178*cdf0e10cSrcweir     const double mnFrameDuration;
179*cdf0e10cSrcweir     /** Time (of maTimer) when the next frame shall be displayed.
180*cdf0e10cSrcweir         Synchronize() will wait until this time.
181*cdf0e10cSrcweir     */
182*cdf0e10cSrcweir     double mnNextFrameTargetTime;
183*cdf0e10cSrcweir     /** Synchronize() will wait only when this flag is <TRUE/>.  Otherwise
184*cdf0e10cSrcweir         it returns immediately.
185*cdf0e10cSrcweir     */
186*cdf0e10cSrcweir     bool mbIsActive;
187*cdf0e10cSrcweir };
188*cdf0e10cSrcweir 
189*cdf0e10cSrcweir 
190*cdf0e10cSrcweir 
191*cdf0e10cSrcweir 
192*cdf0e10cSrcweir /******************************************************************************
193*cdf0e10cSrcweir 
194*cdf0e10cSrcweir    SlideShowImpl
195*cdf0e10cSrcweir 
196*cdf0e10cSrcweir    This class encapsulates the slideshow presentation viewer.
197*cdf0e10cSrcweir 
198*cdf0e10cSrcweir    With an instance of this class, it is possible to statically
199*cdf0e10cSrcweir    and dynamically show a presentation, as defined by the
200*cdf0e10cSrcweir    constructor-provided draw model (represented by a sequence
201*cdf0e10cSrcweir    of ::com::sun::star::drawing::XDrawPage objects).
202*cdf0e10cSrcweir 
203*cdf0e10cSrcweir    It is possible to show the presentation on multiple views
204*cdf0e10cSrcweir    simultaneously (e.g. for a multi-monitor setup). Since this
205*cdf0e10cSrcweir    class also relies on user interaction, the corresponding
206*cdf0e10cSrcweir    XSlideShowView interface provides means to register some UI
207*cdf0e10cSrcweir    event listeners (mostly borrowed from awt::XWindow interface).
208*cdf0e10cSrcweir 
209*cdf0e10cSrcweir    Since currently (mid 2004), OOo isn't very well suited to
210*cdf0e10cSrcweir    multi-threaded rendering, this class relies on <em>very
211*cdf0e10cSrcweir    frequent</em> external update() calls, which will render the
212*cdf0e10cSrcweir    next frame of animations. This works as follows: after the
213*cdf0e10cSrcweir    displaySlide() has been successfully called (which setup and
214*cdf0e10cSrcweir    starts an actual slide show), the update() method must be
215*cdf0e10cSrcweir    called until it returns false.
216*cdf0e10cSrcweir    Effectively, this puts the burden of providing
217*cdf0e10cSrcweir    concurrency to the clients of this class, which, as noted
218*cdf0e10cSrcweir    above, is currently unavoidable with the current state of
219*cdf0e10cSrcweir    affairs (I've actually tried threading here, but failed
220*cdf0e10cSrcweir    miserably when using the VCL canvas as the render backend -
221*cdf0e10cSrcweir    deadlocked).
222*cdf0e10cSrcweir 
223*cdf0e10cSrcweir  ******************************************************************************/
224*cdf0e10cSrcweir 
225*cdf0e10cSrcweir typedef cppu::WeakComponentImplHelper1<presentation::XSlideShow> SlideShowImplBase;
226*cdf0e10cSrcweir 
227*cdf0e10cSrcweir typedef ::std::vector< ::cppcanvas::PolyPolygonSharedPtr> PolyPolygonVector;
228*cdf0e10cSrcweir 
229*cdf0e10cSrcweir /// Maps XDrawPage for annotations persistence
230*cdf0e10cSrcweir typedef ::std::map< ::com::sun::star::uno::Reference<
231*cdf0e10cSrcweir                                     ::com::sun::star::drawing::XDrawPage>,
232*cdf0e10cSrcweir                                     PolyPolygonVector>  PolygonMap;
233*cdf0e10cSrcweir 
234*cdf0e10cSrcweir class SlideShowImpl : private cppu::BaseMutex,
235*cdf0e10cSrcweir                       public CursorManager,
236*cdf0e10cSrcweir                       public SlideShowImplBase
237*cdf0e10cSrcweir {
238*cdf0e10cSrcweir public:
239*cdf0e10cSrcweir     explicit SlideShowImpl(
240*cdf0e10cSrcweir         uno::Reference<uno::XComponentContext> const& xContext );
241*cdf0e10cSrcweir 
242*cdf0e10cSrcweir     /** Notify that the transition phase of the current slide
243*cdf0e10cSrcweir         has ended.
244*cdf0e10cSrcweir 
245*cdf0e10cSrcweir         The life of a slide has three phases: the transition
246*cdf0e10cSrcweir         phase, when the previous slide vanishes, and the
247*cdf0e10cSrcweir         current slide becomes visible, the shape animation
248*cdf0e10cSrcweir         phase, when shape effects are running, and the phase
249*cdf0e10cSrcweir         after the last shape animation has ended, but before
250*cdf0e10cSrcweir         the next slide transition starts.
251*cdf0e10cSrcweir 
252*cdf0e10cSrcweir         This method notifies the end of the first phase.
253*cdf0e10cSrcweir 
254*cdf0e10cSrcweir         @param bPaintSlide
255*cdf0e10cSrcweir         When true, Slide::show() is passed a true as well, denoting
256*cdf0e10cSrcweir         explicit paint of slide content. Pass false here, if e.g. a
257*cdf0e10cSrcweir         slide transition has already rendered the initial slide image.
258*cdf0e10cSrcweir     */
259*cdf0e10cSrcweir     void notifySlideTransitionEnded( bool bPaintSlide );
260*cdf0e10cSrcweir 
261*cdf0e10cSrcweir     /** Notify that the shape animation phase of the current slide
262*cdf0e10cSrcweir         has ended.
263*cdf0e10cSrcweir 
264*cdf0e10cSrcweir         The life of a slide has three phases: the transition
265*cdf0e10cSrcweir         phase, when the previous slide vanishes, and the
266*cdf0e10cSrcweir         current slide becomes visible, the shape animation
267*cdf0e10cSrcweir         phase, when shape effects are running, and the phase
268*cdf0e10cSrcweir         after the last shape animation has ended, but before
269*cdf0e10cSrcweir         the next slide transition starts.
270*cdf0e10cSrcweir 
271*cdf0e10cSrcweir         This method notifies the end of the second phase.
272*cdf0e10cSrcweir     */
273*cdf0e10cSrcweir     void notifySlideAnimationsEnded();
274*cdf0e10cSrcweir 
275*cdf0e10cSrcweir     /** Notify that the slide has ended.
276*cdf0e10cSrcweir 
277*cdf0e10cSrcweir         The life of a slide has three phases: the transition
278*cdf0e10cSrcweir         phase, when the previous slide vanishes, and the
279*cdf0e10cSrcweir         current slide becomes visible, the shape animation
280*cdf0e10cSrcweir         phase, when shape effects are running, and the phase
281*cdf0e10cSrcweir         after the last shape animation has ended, but before
282*cdf0e10cSrcweir         the next slide transition starts.
283*cdf0e10cSrcweir 
284*cdf0e10cSrcweir         This method notifies the end of the third phase.
285*cdf0e10cSrcweir     */
286*cdf0e10cSrcweir     void notifySlideEnded (const bool bReverse);
287*cdf0e10cSrcweir 
288*cdf0e10cSrcweir     /** Notification from eventmultiplexer that a hyperlink
289*cdf0e10cSrcweir         has been clicked.
290*cdf0e10cSrcweir     */
291*cdf0e10cSrcweir     bool notifyHyperLinkClicked( rtl::OUString const& hyperLink );
292*cdf0e10cSrcweir 
293*cdf0e10cSrcweir     /** Notification from eventmultiplexer that an animation event has occoured.
294*cdf0e10cSrcweir 		This will be forewarded to all registered XSlideShowListener
295*cdf0e10cSrcweir      */
296*cdf0e10cSrcweir 	bool handleAnimationEvent( const AnimationNodeSharedPtr& rNode );
297*cdf0e10cSrcweir 
298*cdf0e10cSrcweir private:
299*cdf0e10cSrcweir     // XSlideShow:
300*cdf0e10cSrcweir     virtual sal_Bool SAL_CALL nextEffect() throw (uno::RuntimeException);
301*cdf0e10cSrcweir     virtual sal_Bool SAL_CALL previousEffect() throw (uno::RuntimeException);
302*cdf0e10cSrcweir     virtual sal_Bool SAL_CALL startShapeActivity(
303*cdf0e10cSrcweir         uno::Reference<drawing::XShape> const& xShape )
304*cdf0e10cSrcweir         throw (uno::RuntimeException);
305*cdf0e10cSrcweir     virtual sal_Bool SAL_CALL stopShapeActivity(
306*cdf0e10cSrcweir         uno::Reference<drawing::XShape> const& xShape )
307*cdf0e10cSrcweir         throw (uno::RuntimeException);
308*cdf0e10cSrcweir     virtual sal_Bool SAL_CALL pause( sal_Bool bPauseShow )
309*cdf0e10cSrcweir         throw (uno::RuntimeException);
310*cdf0e10cSrcweir     virtual uno::Reference<drawing::XDrawPage> SAL_CALL getCurrentSlide()
311*cdf0e10cSrcweir         throw (uno::RuntimeException);
312*cdf0e10cSrcweir     virtual void SAL_CALL displaySlide(
313*cdf0e10cSrcweir         uno::Reference<drawing::XDrawPage> const& xSlide,
314*cdf0e10cSrcweir         uno::Reference<drawing::XDrawPagesSupplier> const& xDrawPages,
315*cdf0e10cSrcweir         uno::Reference<animations::XAnimationNode> const& xRootNode,
316*cdf0e10cSrcweir         uno::Sequence<beans::PropertyValue> const& rProperties )
317*cdf0e10cSrcweir         throw (uno::RuntimeException);
318*cdf0e10cSrcweir     virtual void SAL_CALL registerUserPaintPolygons( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xDocFactory ) throw (::com::sun::star::uno::RuntimeException);
319*cdf0e10cSrcweir     virtual sal_Bool SAL_CALL setProperty(
320*cdf0e10cSrcweir         beans::PropertyValue const& rProperty ) throw (uno::RuntimeException);
321*cdf0e10cSrcweir     virtual sal_Bool SAL_CALL addView(
322*cdf0e10cSrcweir         uno::Reference<presentation::XSlideShowView> const& xView )
323*cdf0e10cSrcweir         throw (uno::RuntimeException);
324*cdf0e10cSrcweir     virtual sal_Bool SAL_CALL removeView(
325*cdf0e10cSrcweir         uno::Reference<presentation::XSlideShowView> const& xView )
326*cdf0e10cSrcweir         throw (uno::RuntimeException);
327*cdf0e10cSrcweir     virtual sal_Bool SAL_CALL update( double & nNextTimeout )
328*cdf0e10cSrcweir         throw (uno::RuntimeException);
329*cdf0e10cSrcweir     virtual void SAL_CALL addSlideShowListener(
330*cdf0e10cSrcweir         uno::Reference<presentation::XSlideShowListener> const& xListener )
331*cdf0e10cSrcweir         throw (uno::RuntimeException);
332*cdf0e10cSrcweir     virtual void SAL_CALL removeSlideShowListener(
333*cdf0e10cSrcweir         uno::Reference<presentation::XSlideShowListener> const& xListener )
334*cdf0e10cSrcweir         throw (uno::RuntimeException);
335*cdf0e10cSrcweir     virtual void SAL_CALL addShapeEventListener(
336*cdf0e10cSrcweir         uno::Reference<presentation::XShapeEventListener> const& xListener,
337*cdf0e10cSrcweir         uno::Reference<drawing::XShape> const& xShape )
338*cdf0e10cSrcweir         throw (uno::RuntimeException);
339*cdf0e10cSrcweir     virtual void SAL_CALL removeShapeEventListener(
340*cdf0e10cSrcweir         uno::Reference<presentation::XShapeEventListener> const& xListener,
341*cdf0e10cSrcweir         uno::Reference<drawing::XShape> const& xShape )
342*cdf0e10cSrcweir         throw (uno::RuntimeException);
343*cdf0e10cSrcweir     virtual void SAL_CALL setShapeCursor(
344*cdf0e10cSrcweir         uno::Reference<drawing::XShape> const& xShape, sal_Int16 nPointerShape )
345*cdf0e10cSrcweir         throw (uno::RuntimeException);
346*cdf0e10cSrcweir 
347*cdf0e10cSrcweir 
348*cdf0e10cSrcweir     // CursorManager
349*cdf0e10cSrcweir     // -----------------------------------------------------------
350*cdf0e10cSrcweir 
351*cdf0e10cSrcweir     virtual bool requestCursor( sal_Int16 nCursorShape );
352*cdf0e10cSrcweir     virtual void resetCursor();
353*cdf0e10cSrcweir 
354*cdf0e10cSrcweir     /** This is somewhat similar to displaySlide when called for the current
355*cdf0e10cSrcweir         slide.  It has been simplified to take advantage of that no slide
356*cdf0e10cSrcweir         change takes place.  Furthermore it does not show the slide
357*cdf0e10cSrcweir         transition.
358*cdf0e10cSrcweir     */
359*cdf0e10cSrcweir     void redisplayCurrentSlide (void);
360*cdf0e10cSrcweir 
361*cdf0e10cSrcweir protected:
362*cdf0e10cSrcweir     // WeakComponentImplHelperBase
363*cdf0e10cSrcweir     virtual void SAL_CALL disposing();
364*cdf0e10cSrcweir 
365*cdf0e10cSrcweir     bool isDisposed() const
366*cdf0e10cSrcweir     {
367*cdf0e10cSrcweir         return (rBHelper.bDisposed || rBHelper.bInDispose);
368*cdf0e10cSrcweir     }
369*cdf0e10cSrcweir 
370*cdf0e10cSrcweir private:
371*cdf0e10cSrcweir     struct SeparateListenerImpl; friend struct SeparateListenerImpl;
372*cdf0e10cSrcweir     struct PrefetchPropertiesFunc; friend struct PrefetchPropertiesFunc;
373*cdf0e10cSrcweir 
374*cdf0e10cSrcweir     /// Stop currently running show.
375*cdf0e10cSrcweir     void stopShow();
376*cdf0e10cSrcweir 
377*cdf0e10cSrcweir     ///Find a polygons vector in maPolygons (map)
378*cdf0e10cSrcweir     PolygonMap::iterator findPolygons( uno::Reference<drawing::XDrawPage> const& xDrawPage);
379*cdf0e10cSrcweir 
380*cdf0e10cSrcweir     /// Creates a new slide.
381*cdf0e10cSrcweir     SlideSharedPtr makeSlide(
382*cdf0e10cSrcweir         uno::Reference<drawing::XDrawPage> const& xDrawPage,
383*cdf0e10cSrcweir         uno::Reference<drawing::XDrawPagesSupplier> const& xDrawPages,
384*cdf0e10cSrcweir         uno::Reference<animations::XAnimationNode> const& xRootNode );
385*cdf0e10cSrcweir 
386*cdf0e10cSrcweir     /// Checks whether the given slide/animation node matches mpPrefetchSlide
387*cdf0e10cSrcweir     static bool matches(
388*cdf0e10cSrcweir         SlideSharedPtr const& pSlide,
389*cdf0e10cSrcweir         uno::Reference<drawing::XDrawPage> const& xSlide,
390*cdf0e10cSrcweir         uno::Reference<animations::XAnimationNode> const& xNode )
391*cdf0e10cSrcweir     {
392*cdf0e10cSrcweir         if (pSlide)
393*cdf0e10cSrcweir             return (pSlide->getXDrawPage() == xSlide &&
394*cdf0e10cSrcweir                     pSlide->getXAnimationNode() == xNode);
395*cdf0e10cSrcweir         else
396*cdf0e10cSrcweir             return (!xSlide.is() && !xNode.is());
397*cdf0e10cSrcweir     }
398*cdf0e10cSrcweir 
399*cdf0e10cSrcweir     /// Resets the current slide transition sound object with a new one:
400*cdf0e10cSrcweir     SoundPlayerSharedPtr resetSlideTransitionSound(
401*cdf0e10cSrcweir 		uno::Any const& url = uno::Any(), bool bLoopSound = false );
402*cdf0e10cSrcweir 
403*cdf0e10cSrcweir 	/// stops the current slide transition sound
404*cdf0e10cSrcweir 	void stopSlideTransitionSound();
405*cdf0e10cSrcweir 
406*cdf0e10cSrcweir     /** Prepare a slide transition
407*cdf0e10cSrcweir 
408*cdf0e10cSrcweir         This method registers all necessary events and
409*cdf0e10cSrcweir         activities for a slide transition.
410*cdf0e10cSrcweir 
411*cdf0e10cSrcweir         @return the slide change activity, or NULL for no transition effect
412*cdf0e10cSrcweir     */
413*cdf0e10cSrcweir     ActivitySharedPtr createSlideTransition(
414*cdf0e10cSrcweir         const uno::Reference< drawing::XDrawPage >&    xDrawPage,
415*cdf0e10cSrcweir         const SlideSharedPtr&                          rLeavingSlide,
416*cdf0e10cSrcweir         const SlideSharedPtr&                          rEnteringSlide,
417*cdf0e10cSrcweir         const EventSharedPtr&                          rTransitionEndEvent );
418*cdf0e10cSrcweir 
419*cdf0e10cSrcweir     /** Request/release the wait symbol.  The wait symbol is displayed when
420*cdf0e10cSrcweir         there are more requests then releases.  Locking the wait symbol
421*cdf0e10cSrcweir         helps to avoid intermediate repaints.
422*cdf0e10cSrcweir 
423*cdf0e10cSrcweir         Do not call this method directly.  Use WaitSymbolLock instead.
424*cdf0e10cSrcweir     */
425*cdf0e10cSrcweir     void requestWaitSymbol (void);
426*cdf0e10cSrcweir     void releaseWaitSymbol (void);
427*cdf0e10cSrcweir 
428*cdf0e10cSrcweir     class WaitSymbolLock {public:
429*cdf0e10cSrcweir         WaitSymbolLock(SlideShowImpl& rSlideShowImpl) : mrSlideShowImpl(rSlideShowImpl)
430*cdf0e10cSrcweir             { mrSlideShowImpl.requestWaitSymbol(); }
431*cdf0e10cSrcweir         ~WaitSymbolLock(void)
432*cdf0e10cSrcweir             { mrSlideShowImpl.releaseWaitSymbol(); }
433*cdf0e10cSrcweir     private: SlideShowImpl& mrSlideShowImpl;
434*cdf0e10cSrcweir     };
435*cdf0e10cSrcweir 
436*cdf0e10cSrcweir 
437*cdf0e10cSrcweir     /// Filter requested cursor shape against hard slideshow cursors (wait, etc.)
438*cdf0e10cSrcweir     sal_Int16 calcActiveCursor( sal_Int16 nCursorShape ) const;
439*cdf0e10cSrcweir 
440*cdf0e10cSrcweir     /** This method is called asynchronously to finish the rewinding of an
441*cdf0e10cSrcweir         effect to the previous slide that was initiated earlier.
442*cdf0e10cSrcweir     */
443*cdf0e10cSrcweir     void rewindEffectToPreviousSlide (void);
444*cdf0e10cSrcweir 
445*cdf0e10cSrcweir     /// all registered views
446*cdf0e10cSrcweir     UnoViewContainer                        maViewContainer;
447*cdf0e10cSrcweir 
448*cdf0e10cSrcweir     /// all registered slide show listeners
449*cdf0e10cSrcweir     cppu::OInterfaceContainerHelper         maListenerContainer;
450*cdf0e10cSrcweir 
451*cdf0e10cSrcweir     /// map of vectors, containing all registered listeners for a shape
452*cdf0e10cSrcweir     ShapeEventListenerMap                   maShapeEventListeners;
453*cdf0e10cSrcweir     /// map of sal_Int16 values, specifying the mouse cursor for every shape
454*cdf0e10cSrcweir     ShapeCursorMap                          maShapeCursors;
455*cdf0e10cSrcweir 
456*cdf0e10cSrcweir     //map of vector of Polygons, containing polygons drawn on each slide.
457*cdf0e10cSrcweir     PolygonMap                              maPolygons;
458*cdf0e10cSrcweir 
459*cdf0e10cSrcweir     boost::optional<RGBColor>               maUserPaintColor;
460*cdf0e10cSrcweir 
461*cdf0e10cSrcweir 	double									maUserPaintStrokeWidth;
462*cdf0e10cSrcweir 
463*cdf0e10cSrcweir     //changed for the eraser project
464*cdf0e10cSrcweir     boost::optional<bool>		    maEraseAllInk;
465*cdf0e10cSrcweir     boost::optional<bool>		    maSwitchPenMode;
466*cdf0e10cSrcweir     boost::optional<bool>		    maSwitchEraserMode;
467*cdf0e10cSrcweir     boost::optional<sal_Int32>		    maEraseInk;
468*cdf0e10cSrcweir     //end changed
469*cdf0e10cSrcweir 
470*cdf0e10cSrcweir     boost::shared_ptr<canvas::tools::ElapsedTime> mpPresTimer;
471*cdf0e10cSrcweir     ScreenUpdater                           maScreenUpdater;
472*cdf0e10cSrcweir     EventQueue                              maEventQueue;
473*cdf0e10cSrcweir     EventMultiplexer                        maEventMultiplexer;
474*cdf0e10cSrcweir     ActivitiesQueue                         maActivitiesQueue;
475*cdf0e10cSrcweir     UserEventQueue                          maUserEventQueue;
476*cdf0e10cSrcweir     SubsettableShapeManagerSharedPtr        mpDummyPtr;
477*cdf0e10cSrcweir 
478*cdf0e10cSrcweir     boost::shared_ptr<SeparateListenerImpl> mpListener;
479*cdf0e10cSrcweir 
480*cdf0e10cSrcweir     boost::shared_ptr<RehearseTimingsActivity> mpRehearseTimingsActivity;
481*cdf0e10cSrcweir     boost::shared_ptr<WaitSymbol>           mpWaitSymbol;
482*cdf0e10cSrcweir 
483*cdf0e10cSrcweir     /// the current slide transition sound object:
484*cdf0e10cSrcweir     SoundPlayerSharedPtr                    mpCurrentSlideTransitionSound;
485*cdf0e10cSrcweir 
486*cdf0e10cSrcweir     uno::Reference<uno::XComponentContext>  mxComponentContext;
487*cdf0e10cSrcweir     uno::Reference<
488*cdf0e10cSrcweir         presentation::XTransitionFactory>   mxOptionalTransitionFactory;
489*cdf0e10cSrcweir 
490*cdf0e10cSrcweir     /// the previously running slide
491*cdf0e10cSrcweir     SlideSharedPtr                          mpPreviousSlide;
492*cdf0e10cSrcweir     /// the currently running slide
493*cdf0e10cSrcweir     SlideSharedPtr                          mpCurrentSlide;
494*cdf0e10cSrcweir     /// the already prefetched slide: best candidate for upcoming slide
495*cdf0e10cSrcweir     SlideSharedPtr                          mpPrefetchSlide;
496*cdf0e10cSrcweir     /// slide to be prefetched: best candidate for upcoming slide
497*cdf0e10cSrcweir     uno::Reference<drawing::XDrawPage>      mxPrefetchSlide;
498*cdf0e10cSrcweir     ///  save the XDrawPagesSupplier to retieve polygons
499*cdf0e10cSrcweir     uno::Reference<drawing::XDrawPagesSupplier>  mxDrawPagesSupplier;
500*cdf0e10cSrcweir     /// slide animation to be prefetched:
501*cdf0e10cSrcweir     uno::Reference<animations::XAnimationNode> mxPrefetchAnimationNode;
502*cdf0e10cSrcweir 
503*cdf0e10cSrcweir     sal_Int16                               mnCurrentCursor;
504*cdf0e10cSrcweir 
505*cdf0e10cSrcweir     sal_Int32                               mnWaitSymbolRequestCount;
506*cdf0e10cSrcweir     bool                                    mbAutomaticAdvancementMode;
507*cdf0e10cSrcweir     bool                                    mbImageAnimationsAllowed;
508*cdf0e10cSrcweir     bool                                    mbNoSlideTransitions;
509*cdf0e10cSrcweir     bool                                    mbMouseVisible;
510*cdf0e10cSrcweir     bool                                    mbForceManualAdvance;
511*cdf0e10cSrcweir     bool                                    mbShowPaused;
512*cdf0e10cSrcweir     bool                                    mbSlideShowIdle;
513*cdf0e10cSrcweir     bool                                    mbDisableAnimationZOrder;
514*cdf0e10cSrcweir 
515*cdf0e10cSrcweir     EffectRewinder                          maEffectRewinder;
516*cdf0e10cSrcweir     FrameSynchronization                    maFrameSynchronization;
517*cdf0e10cSrcweir };
518*cdf0e10cSrcweir 
519*cdf0e10cSrcweir 
520*cdf0e10cSrcweir /** Separate event listener for animation, view and hyperlink events.
521*cdf0e10cSrcweir 
522*cdf0e10cSrcweir     This handler is registered for slide animation end, view and
523*cdf0e10cSrcweir     hyperlink events at the global EventMultiplexer, and forwards
524*cdf0e10cSrcweir     notifications to the SlideShowImpl
525*cdf0e10cSrcweir */
526*cdf0e10cSrcweir struct SlideShowImpl::SeparateListenerImpl : public EventHandler,
527*cdf0e10cSrcweir                                              public ViewRepaintHandler,
528*cdf0e10cSrcweir                                              public HyperlinkHandler,
529*cdf0e10cSrcweir 											 public AnimationEventHandler,
530*cdf0e10cSrcweir                                              private boost::noncopyable
531*cdf0e10cSrcweir {
532*cdf0e10cSrcweir     SlideShowImpl& mrShow;
533*cdf0e10cSrcweir     ScreenUpdater& mrScreenUpdater;
534*cdf0e10cSrcweir     EventQueue&    mrEventQueue;
535*cdf0e10cSrcweir 
536*cdf0e10cSrcweir     SeparateListenerImpl( SlideShowImpl& rShow,
537*cdf0e10cSrcweir                           ScreenUpdater& rScreenUpdater,
538*cdf0e10cSrcweir                           EventQueue&    rEventQueue ) :
539*cdf0e10cSrcweir         mrShow( rShow ),
540*cdf0e10cSrcweir         mrScreenUpdater( rScreenUpdater ),
541*cdf0e10cSrcweir         mrEventQueue( rEventQueue )
542*cdf0e10cSrcweir     {}
543*cdf0e10cSrcweir 
544*cdf0e10cSrcweir     // EventHandler
545*cdf0e10cSrcweir     virtual bool handleEvent()
546*cdf0e10cSrcweir     {
547*cdf0e10cSrcweir         // DON't call notifySlideAnimationsEnded()
548*cdf0e10cSrcweir         // directly, but queue an event. handleEvent()
549*cdf0e10cSrcweir         // might be called from e.g.
550*cdf0e10cSrcweir         // showNext(), and notifySlideAnimationsEnded() must not be called
551*cdf0e10cSrcweir         // in recursion.  Note that the event is scheduled for the next
552*cdf0e10cSrcweir         // frame so that its expensive execution does not come in between
553*cdf0e10cSrcweir         // sprite hiding and shape redraw (at the end of the animation of a
554*cdf0e10cSrcweir         // shape), which would cause a flicker.
555*cdf0e10cSrcweir         mrEventQueue.addEventForNextRound(
556*cdf0e10cSrcweir             makeEvent(
557*cdf0e10cSrcweir                 boost::bind( &SlideShowImpl::notifySlideAnimationsEnded, boost::ref(mrShow) ),
558*cdf0e10cSrcweir                 "SlideShowImpl::notifySlideAnimationsEnded"));
559*cdf0e10cSrcweir         return true;
560*cdf0e10cSrcweir     }
561*cdf0e10cSrcweir 
562*cdf0e10cSrcweir     // ViewRepaintHandler
563*cdf0e10cSrcweir     virtual void viewClobbered( const UnoViewSharedPtr& rView )
564*cdf0e10cSrcweir     {
565*cdf0e10cSrcweir         // given view needs repaint, request update
566*cdf0e10cSrcweir         mrScreenUpdater.notifyUpdate(rView, true);
567*cdf0e10cSrcweir     }
568*cdf0e10cSrcweir 
569*cdf0e10cSrcweir     // HyperlinkHandler
570*cdf0e10cSrcweir     virtual bool handleHyperlink( ::rtl::OUString const& rLink )
571*cdf0e10cSrcweir     {
572*cdf0e10cSrcweir         return mrShow.notifyHyperLinkClicked(rLink);
573*cdf0e10cSrcweir     }
574*cdf0e10cSrcweir 
575*cdf0e10cSrcweir 	// AnimationEventHandler
576*cdf0e10cSrcweir     virtual bool handleAnimationEvent( const AnimationNodeSharedPtr& rNode )
577*cdf0e10cSrcweir 	{
578*cdf0e10cSrcweir 		return mrShow.handleAnimationEvent(rNode);
579*cdf0e10cSrcweir 	}
580*cdf0e10cSrcweir };
581*cdf0e10cSrcweir 
582*cdf0e10cSrcweir 
583*cdf0e10cSrcweir SlideShowImpl::SlideShowImpl(
584*cdf0e10cSrcweir     uno::Reference<uno::XComponentContext> const& xContext )
585*cdf0e10cSrcweir     : SlideShowImplBase(m_aMutex),
586*cdf0e10cSrcweir       maViewContainer(),
587*cdf0e10cSrcweir       maListenerContainer( m_aMutex ),
588*cdf0e10cSrcweir       maShapeEventListeners(),
589*cdf0e10cSrcweir       maShapeCursors(),
590*cdf0e10cSrcweir       maUserPaintColor(),
591*cdf0e10cSrcweir       maUserPaintStrokeWidth(4.0),
592*cdf0e10cSrcweir       mpPresTimer( new canvas::tools::ElapsedTime ),
593*cdf0e10cSrcweir       maScreenUpdater(maViewContainer),
594*cdf0e10cSrcweir       maEventQueue( mpPresTimer ),
595*cdf0e10cSrcweir       maEventMultiplexer( maEventQueue,
596*cdf0e10cSrcweir                           maViewContainer ),
597*cdf0e10cSrcweir       maActivitiesQueue( mpPresTimer ),
598*cdf0e10cSrcweir       maUserEventQueue( maEventMultiplexer,
599*cdf0e10cSrcweir                         maEventQueue,
600*cdf0e10cSrcweir                         *this ),
601*cdf0e10cSrcweir       mpDummyPtr(),
602*cdf0e10cSrcweir       mpListener(),
603*cdf0e10cSrcweir       mpRehearseTimingsActivity(),
604*cdf0e10cSrcweir       mpWaitSymbol(),
605*cdf0e10cSrcweir       mpCurrentSlideTransitionSound(),
606*cdf0e10cSrcweir       mxComponentContext( xContext ),
607*cdf0e10cSrcweir       mxOptionalTransitionFactory(),
608*cdf0e10cSrcweir       mpCurrentSlide(),
609*cdf0e10cSrcweir       mpPrefetchSlide(),
610*cdf0e10cSrcweir       mxPrefetchSlide(),
611*cdf0e10cSrcweir       mxDrawPagesSupplier(),
612*cdf0e10cSrcweir       mxPrefetchAnimationNode(),
613*cdf0e10cSrcweir       mnCurrentCursor(awt::SystemPointer::ARROW),
614*cdf0e10cSrcweir       mnWaitSymbolRequestCount(0),
615*cdf0e10cSrcweir       mbAutomaticAdvancementMode(false),
616*cdf0e10cSrcweir       mbImageAnimationsAllowed( true ),
617*cdf0e10cSrcweir       mbNoSlideTransitions( false ),
618*cdf0e10cSrcweir       mbMouseVisible( true ),
619*cdf0e10cSrcweir       mbForceManualAdvance( false ),
620*cdf0e10cSrcweir       mbShowPaused( false ),
621*cdf0e10cSrcweir       mbSlideShowIdle( true ),
622*cdf0e10cSrcweir       mbDisableAnimationZOrder( false ),
623*cdf0e10cSrcweir       maEffectRewinder(maEventMultiplexer, maEventQueue, maUserEventQueue),
624*cdf0e10cSrcweir       maFrameSynchronization(1.0 / FrameRate::PreferredFramesPerSecond)
625*cdf0e10cSrcweir 
626*cdf0e10cSrcweir {
627*cdf0e10cSrcweir     // keep care not constructing any UNO references to this inside ctor,
628*cdf0e10cSrcweir     // shift that code to create()!
629*cdf0e10cSrcweir 
630*cdf0e10cSrcweir     uno::Reference<lang::XMultiComponentFactory> xFactory(
631*cdf0e10cSrcweir         mxComponentContext->getServiceManager() );
632*cdf0e10cSrcweir 
633*cdf0e10cSrcweir     if( xFactory.is() )
634*cdf0e10cSrcweir     {
635*cdf0e10cSrcweir         try
636*cdf0e10cSrcweir 	{
637*cdf0e10cSrcweir             // #i82460# try to retrieve special transition factory
638*cdf0e10cSrcweir             mxOptionalTransitionFactory.set(
639*cdf0e10cSrcweir                 xFactory->createInstanceWithContext(
640*cdf0e10cSrcweir                     ::rtl::OUString::createFromAscii( "com.sun.star.presentation.TransitionFactory" ),
641*cdf0e10cSrcweir                     mxComponentContext ),
642*cdf0e10cSrcweir                 uno::UNO_QUERY );
643*cdf0e10cSrcweir         }
644*cdf0e10cSrcweir         catch (loader::CannotActivateFactoryException const&)
645*cdf0e10cSrcweir 	{
646*cdf0e10cSrcweir 	}
647*cdf0e10cSrcweir     }
648*cdf0e10cSrcweir 
649*cdf0e10cSrcweir     mpListener.reset( new SeparateListenerImpl(
650*cdf0e10cSrcweir                           *this,
651*cdf0e10cSrcweir                           maScreenUpdater,
652*cdf0e10cSrcweir                           maEventQueue ));
653*cdf0e10cSrcweir     maEventMultiplexer.addSlideAnimationsEndHandler( mpListener );
654*cdf0e10cSrcweir     maEventMultiplexer.addViewRepaintHandler( mpListener );
655*cdf0e10cSrcweir     maEventMultiplexer.addHyperlinkHandler( mpListener, 0.0 );
656*cdf0e10cSrcweir 	maEventMultiplexer.addAnimationStartHandler( mpListener );
657*cdf0e10cSrcweir 	maEventMultiplexer.addAnimationEndHandler( mpListener );
658*cdf0e10cSrcweir }
659*cdf0e10cSrcweir 
660*cdf0e10cSrcweir // we are about to be disposed (someone call dispose() on us)
661*cdf0e10cSrcweir void SlideShowImpl::disposing()
662*cdf0e10cSrcweir {
663*cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
664*cdf0e10cSrcweir 
665*cdf0e10cSrcweir     maEffectRewinder.dispose();
666*cdf0e10cSrcweir 
667*cdf0e10cSrcweir 	// stop slide transition sound, if any:
668*cdf0e10cSrcweir     stopSlideTransitionSound();
669*cdf0e10cSrcweir 
670*cdf0e10cSrcweir     mxComponentContext.clear();
671*cdf0e10cSrcweir 
672*cdf0e10cSrcweir     if( mpCurrentSlideTransitionSound )
673*cdf0e10cSrcweir     {
674*cdf0e10cSrcweir         mpCurrentSlideTransitionSound->dispose();
675*cdf0e10cSrcweir         mpCurrentSlideTransitionSound.reset();
676*cdf0e10cSrcweir     }
677*cdf0e10cSrcweir 
678*cdf0e10cSrcweir     mpWaitSymbol.reset();
679*cdf0e10cSrcweir 
680*cdf0e10cSrcweir     if( mpRehearseTimingsActivity )
681*cdf0e10cSrcweir     {
682*cdf0e10cSrcweir         mpRehearseTimingsActivity->dispose();
683*cdf0e10cSrcweir         mpRehearseTimingsActivity.reset();
684*cdf0e10cSrcweir     }
685*cdf0e10cSrcweir 
686*cdf0e10cSrcweir     if( mpListener )
687*cdf0e10cSrcweir     {
688*cdf0e10cSrcweir         maEventMultiplexer.removeSlideAnimationsEndHandler(mpListener);
689*cdf0e10cSrcweir         maEventMultiplexer.removeViewRepaintHandler(mpListener);
690*cdf0e10cSrcweir         maEventMultiplexer.removeHyperlinkHandler(mpListener);
691*cdf0e10cSrcweir 		maEventMultiplexer.removeAnimationStartHandler( mpListener );
692*cdf0e10cSrcweir 		maEventMultiplexer.removeAnimationEndHandler( mpListener );
693*cdf0e10cSrcweir 
694*cdf0e10cSrcweir         mpListener.reset();
695*cdf0e10cSrcweir     }
696*cdf0e10cSrcweir 
697*cdf0e10cSrcweir     maUserEventQueue.clear();
698*cdf0e10cSrcweir     maActivitiesQueue.clear();
699*cdf0e10cSrcweir     maEventMultiplexer.clear();
700*cdf0e10cSrcweir     maEventQueue.clear();
701*cdf0e10cSrcweir     mpPresTimer.reset();
702*cdf0e10cSrcweir     maShapeCursors.clear();
703*cdf0e10cSrcweir     maShapeEventListeners.clear();
704*cdf0e10cSrcweir 
705*cdf0e10cSrcweir     // send all listeners a disposing() that we are going down:
706*cdf0e10cSrcweir     maListenerContainer.disposeAndClear(
707*cdf0e10cSrcweir         lang::EventObject( static_cast<cppu::OWeakObject *>(this) ) );
708*cdf0e10cSrcweir 
709*cdf0e10cSrcweir     maViewContainer.dispose();
710*cdf0e10cSrcweir 
711*cdf0e10cSrcweir     // release slides:
712*cdf0e10cSrcweir     mxPrefetchAnimationNode.clear();
713*cdf0e10cSrcweir     mxPrefetchSlide.clear();
714*cdf0e10cSrcweir     mpPrefetchSlide.reset();
715*cdf0e10cSrcweir     mpCurrentSlide.reset();
716*cdf0e10cSrcweir     mpPreviousSlide.reset();
717*cdf0e10cSrcweir }
718*cdf0e10cSrcweir 
719*cdf0e10cSrcweir /// stops the current slide transition sound
720*cdf0e10cSrcweir void SlideShowImpl::stopSlideTransitionSound()
721*cdf0e10cSrcweir {
722*cdf0e10cSrcweir     if (mpCurrentSlideTransitionSound)
723*cdf0e10cSrcweir     {
724*cdf0e10cSrcweir         mpCurrentSlideTransitionSound->stopPlayback();
725*cdf0e10cSrcweir         mpCurrentSlideTransitionSound->dispose();
726*cdf0e10cSrcweir         mpCurrentSlideTransitionSound.reset();
727*cdf0e10cSrcweir     }
728*cdf0e10cSrcweir  }
729*cdf0e10cSrcweir 
730*cdf0e10cSrcweir SoundPlayerSharedPtr SlideShowImpl::resetSlideTransitionSound( const uno::Any& rSound, bool bLoopSound )
731*cdf0e10cSrcweir {
732*cdf0e10cSrcweir 	sal_Bool bStopSound = sal_False;
733*cdf0e10cSrcweir 	rtl::OUString url;
734*cdf0e10cSrcweir 
735*cdf0e10cSrcweir 	if( !(rSound >>= bStopSound) )
736*cdf0e10cSrcweir 		bStopSound = sal_False;
737*cdf0e10cSrcweir 	rSound >>= url;
738*cdf0e10cSrcweir 
739*cdf0e10cSrcweir 	if( !bStopSound && (url.getLength() == 0) )
740*cdf0e10cSrcweir 		return SoundPlayerSharedPtr();
741*cdf0e10cSrcweir 
742*cdf0e10cSrcweir 	stopSlideTransitionSound();
743*cdf0e10cSrcweir 
744*cdf0e10cSrcweir     if (url.getLength() > 0)
745*cdf0e10cSrcweir     {
746*cdf0e10cSrcweir         try
747*cdf0e10cSrcweir         {
748*cdf0e10cSrcweir             mpCurrentSlideTransitionSound = SoundPlayer::create(
749*cdf0e10cSrcweir                 maEventMultiplexer, url, mxComponentContext );
750*cdf0e10cSrcweir 			mpCurrentSlideTransitionSound->setPlaybackLoop( bLoopSound );
751*cdf0e10cSrcweir         }
752*cdf0e10cSrcweir         catch (lang::NoSupportException const&)
753*cdf0e10cSrcweir         {
754*cdf0e10cSrcweir             // catch possible exceptions from SoundPlayer, since
755*cdf0e10cSrcweir             // being not able to playback the sound is not a hard
756*cdf0e10cSrcweir             // error here (still, the slide transition should be
757*cdf0e10cSrcweir             // shown).
758*cdf0e10cSrcweir         }
759*cdf0e10cSrcweir     }
760*cdf0e10cSrcweir     return mpCurrentSlideTransitionSound;
761*cdf0e10cSrcweir }
762*cdf0e10cSrcweir 
763*cdf0e10cSrcweir ActivitySharedPtr SlideShowImpl::createSlideTransition(
764*cdf0e10cSrcweir     const uno::Reference< drawing::XDrawPage >& xDrawPage,
765*cdf0e10cSrcweir     const SlideSharedPtr&                       rLeavingSlide,
766*cdf0e10cSrcweir     const SlideSharedPtr&                       rEnteringSlide,
767*cdf0e10cSrcweir     const EventSharedPtr&                       rTransitionEndEvent)
768*cdf0e10cSrcweir {
769*cdf0e10cSrcweir     ENSURE_OR_THROW( !maViewContainer.empty(),
770*cdf0e10cSrcweir                       "createSlideTransition(): No views" );
771*cdf0e10cSrcweir     ENSURE_OR_THROW( rEnteringSlide,
772*cdf0e10cSrcweir                       "createSlideTransition(): No entering slide" );
773*cdf0e10cSrcweir 
774*cdf0e10cSrcweir     // return empty transition, if slide transitions
775*cdf0e10cSrcweir     // are disabled.
776*cdf0e10cSrcweir     if (mbNoSlideTransitions)
777*cdf0e10cSrcweir         return ActivitySharedPtr();
778*cdf0e10cSrcweir 
779*cdf0e10cSrcweir     // retrieve slide change parameters from XDrawPage
780*cdf0e10cSrcweir     uno::Reference< beans::XPropertySet > xPropSet( xDrawPage,
781*cdf0e10cSrcweir                                                     uno::UNO_QUERY );
782*cdf0e10cSrcweir 
783*cdf0e10cSrcweir     if( !xPropSet.is() )
784*cdf0e10cSrcweir     {
785*cdf0e10cSrcweir         OSL_TRACE( "createSlideTransition(): "
786*cdf0e10cSrcweir                    "Slide has no PropertySet - assuming no transition\n" );
787*cdf0e10cSrcweir         return ActivitySharedPtr();
788*cdf0e10cSrcweir     }
789*cdf0e10cSrcweir 
790*cdf0e10cSrcweir     sal_Int16 nTransitionType(0);
791*cdf0e10cSrcweir     if( !getPropertyValue( nTransitionType,
792*cdf0e10cSrcweir                            xPropSet,
793*cdf0e10cSrcweir                            OUSTR("TransitionType" )) )
794*cdf0e10cSrcweir     {
795*cdf0e10cSrcweir         OSL_TRACE( "createSlideTransition(): "
796*cdf0e10cSrcweir                    "Could not extract slide transition type from XDrawPage - assuming no transition\n" );
797*cdf0e10cSrcweir         return ActivitySharedPtr();
798*cdf0e10cSrcweir     }
799*cdf0e10cSrcweir 
800*cdf0e10cSrcweir     sal_Int16 nTransitionSubType(0);
801*cdf0e10cSrcweir     if( !getPropertyValue( nTransitionSubType,
802*cdf0e10cSrcweir                            xPropSet,
803*cdf0e10cSrcweir                            OUSTR("TransitionSubtype" )) )
804*cdf0e10cSrcweir     {
805*cdf0e10cSrcweir         OSL_TRACE( "createSlideTransition(): "
806*cdf0e10cSrcweir                    "Could not extract slide transition subtype from XDrawPage - assuming no transition\n" );
807*cdf0e10cSrcweir         return ActivitySharedPtr();
808*cdf0e10cSrcweir     }
809*cdf0e10cSrcweir 
810*cdf0e10cSrcweir     bool bTransitionDirection(false);
811*cdf0e10cSrcweir     if( !getPropertyValue( bTransitionDirection,
812*cdf0e10cSrcweir                            xPropSet,
813*cdf0e10cSrcweir                            OUSTR("TransitionDirection")) )
814*cdf0e10cSrcweir     {
815*cdf0e10cSrcweir         OSL_TRACE( "createSlideTransition(): "
816*cdf0e10cSrcweir                    "Could not extract slide transition direction from XDrawPage - assuming default direction\n" );
817*cdf0e10cSrcweir     }
818*cdf0e10cSrcweir 
819*cdf0e10cSrcweir     sal_Int32 aUnoColor(0);
820*cdf0e10cSrcweir     if( !getPropertyValue( aUnoColor,
821*cdf0e10cSrcweir                            xPropSet,
822*cdf0e10cSrcweir                            OUSTR("TransitionFadeColor")) )
823*cdf0e10cSrcweir     {
824*cdf0e10cSrcweir         OSL_TRACE( "createSlideTransition(): "
825*cdf0e10cSrcweir                    "Could not extract slide transition fade color from XDrawPage - assuming black\n" );
826*cdf0e10cSrcweir     }
827*cdf0e10cSrcweir 
828*cdf0e10cSrcweir     const RGBColor aTransitionFadeColor( unoColor2RGBColor( aUnoColor ));
829*cdf0e10cSrcweir 
830*cdf0e10cSrcweir 	uno::Any aSound;
831*cdf0e10cSrcweir 	sal_Bool bLoopSound = sal_False;
832*cdf0e10cSrcweir 
833*cdf0e10cSrcweir 	if( !getPropertyValue( aSound, xPropSet, OUSTR("Sound")) )
834*cdf0e10cSrcweir 		OSL_TRACE( "createSlideTransition(): Could not determine transition sound effect URL from XDrawPage - using no sound\n" );
835*cdf0e10cSrcweir 
836*cdf0e10cSrcweir 	if( !getPropertyValue( bLoopSound, xPropSet, OUSTR("LoopSound") ) )
837*cdf0e10cSrcweir 		OSL_TRACE( "createSlideTransition(): Could not get slide property 'LoopSound' - using no sound\n" );
838*cdf0e10cSrcweir 
839*cdf0e10cSrcweir     NumberAnimationSharedPtr pTransition(
840*cdf0e10cSrcweir         TransitionFactory::createSlideTransition(
841*cdf0e10cSrcweir             rLeavingSlide,
842*cdf0e10cSrcweir             rEnteringSlide,
843*cdf0e10cSrcweir             maViewContainer,
844*cdf0e10cSrcweir             maScreenUpdater,
845*cdf0e10cSrcweir             maEventMultiplexer,
846*cdf0e10cSrcweir             mxOptionalTransitionFactory,
847*cdf0e10cSrcweir             nTransitionType,
848*cdf0e10cSrcweir             nTransitionSubType,
849*cdf0e10cSrcweir             bTransitionDirection,
850*cdf0e10cSrcweir             aTransitionFadeColor,
851*cdf0e10cSrcweir             resetSlideTransitionSound( aSound, bLoopSound ) ));
852*cdf0e10cSrcweir 
853*cdf0e10cSrcweir     if( !pTransition )
854*cdf0e10cSrcweir         return ActivitySharedPtr(); // no transition effect has been
855*cdf0e10cSrcweir                                     // generated. Normally, that means
856*cdf0e10cSrcweir                                     // that simply no transition is
857*cdf0e10cSrcweir                                     // set on this slide.
858*cdf0e10cSrcweir 
859*cdf0e10cSrcweir     double nTransitionDuration(0.0);
860*cdf0e10cSrcweir     if( !getPropertyValue( nTransitionDuration,
861*cdf0e10cSrcweir                            xPropSet,
862*cdf0e10cSrcweir                            OUSTR("TransitionDuration")) )
863*cdf0e10cSrcweir     {
864*cdf0e10cSrcweir         OSL_TRACE( "createSlideTransition(): "
865*cdf0e10cSrcweir                    "Could not extract slide transition duration from XDrawPage - assuming no transition\n" );
866*cdf0e10cSrcweir         return ActivitySharedPtr();
867*cdf0e10cSrcweir     }
868*cdf0e10cSrcweir 
869*cdf0e10cSrcweir     sal_Int32 nMinFrames(5);
870*cdf0e10cSrcweir     if( !getPropertyValue( nMinFrames,
871*cdf0e10cSrcweir                            xPropSet,
872*cdf0e10cSrcweir                            OUSTR("MinimalFrameNumber")) )
873*cdf0e10cSrcweir     {
874*cdf0e10cSrcweir         OSL_TRACE( "createSlideTransition(): "
875*cdf0e10cSrcweir                    "No minimal number of frames given - assuming 5\n" );
876*cdf0e10cSrcweir     }
877*cdf0e10cSrcweir 
878*cdf0e10cSrcweir     // prefetch slide transition bitmaps, but postpone it after
879*cdf0e10cSrcweir     // displaySlide() has finished - sometimes, view size has not yet
880*cdf0e10cSrcweir     // reached final size
881*cdf0e10cSrcweir     maEventQueue.addEvent(
882*cdf0e10cSrcweir         makeEvent(
883*cdf0e10cSrcweir             boost::bind(
884*cdf0e10cSrcweir                 &::slideshow::internal::Animation::prefetch,
885*cdf0e10cSrcweir                 pTransition,
886*cdf0e10cSrcweir                 AnimatableShapeSharedPtr(),
887*cdf0e10cSrcweir                 ShapeAttributeLayerSharedPtr()),
888*cdf0e10cSrcweir             "Animation::prefetch"));
889*cdf0e10cSrcweir 
890*cdf0e10cSrcweir     return ActivitySharedPtr(
891*cdf0e10cSrcweir         ActivitiesFactory::createSimpleActivity(
892*cdf0e10cSrcweir             ActivitiesFactory::CommonParameters(
893*cdf0e10cSrcweir                 rTransitionEndEvent,
894*cdf0e10cSrcweir                 maEventQueue,
895*cdf0e10cSrcweir                 maActivitiesQueue,
896*cdf0e10cSrcweir                 nTransitionDuration,
897*cdf0e10cSrcweir                 nMinFrames,
898*cdf0e10cSrcweir                 false,
899*cdf0e10cSrcweir                 boost::optional<double>(1.0),
900*cdf0e10cSrcweir                 0.0,
901*cdf0e10cSrcweir                 0.0,
902*cdf0e10cSrcweir                 ShapeSharedPtr(),
903*cdf0e10cSrcweir                 rEnteringSlide->getSlideSize() ),
904*cdf0e10cSrcweir             pTransition,
905*cdf0e10cSrcweir             true ));
906*cdf0e10cSrcweir }
907*cdf0e10cSrcweir 
908*cdf0e10cSrcweir PolygonMap::iterator SlideShowImpl::findPolygons( uno::Reference<drawing::XDrawPage> const& xDrawPage)
909*cdf0e10cSrcweir {
910*cdf0e10cSrcweir     // TODO(P2) : Optimze research in the map.
911*cdf0e10cSrcweir     bool bFound = false;
912*cdf0e10cSrcweir     PolygonMap::iterator aIter=maPolygons.begin();
913*cdf0e10cSrcweir 
914*cdf0e10cSrcweir 
915*cdf0e10cSrcweir     while(aIter!=maPolygons.end() && !bFound)
916*cdf0e10cSrcweir     {
917*cdf0e10cSrcweir         if(aIter->first == xDrawPage)
918*cdf0e10cSrcweir             bFound = true;
919*cdf0e10cSrcweir         else
920*cdf0e10cSrcweir             aIter++;
921*cdf0e10cSrcweir     }
922*cdf0e10cSrcweir 
923*cdf0e10cSrcweir     return aIter;
924*cdf0e10cSrcweir }
925*cdf0e10cSrcweir 
926*cdf0e10cSrcweir SlideSharedPtr SlideShowImpl::makeSlide(
927*cdf0e10cSrcweir     uno::Reference<drawing::XDrawPage> const&          xDrawPage,
928*cdf0e10cSrcweir     uno::Reference<drawing::XDrawPagesSupplier> const& xDrawPages,
929*cdf0e10cSrcweir     uno::Reference<animations::XAnimationNode> const&  xRootNode )
930*cdf0e10cSrcweir {
931*cdf0e10cSrcweir     if( !xDrawPage.is() )
932*cdf0e10cSrcweir         return SlideSharedPtr();
933*cdf0e10cSrcweir 
934*cdf0e10cSrcweir     //Retrieve polygons for the current slide
935*cdf0e10cSrcweir     PolygonMap::iterator aIter;
936*cdf0e10cSrcweir     aIter = findPolygons(xDrawPage);
937*cdf0e10cSrcweir 
938*cdf0e10cSrcweir     const SlideSharedPtr pSlide( createSlide(xDrawPage,
939*cdf0e10cSrcweir                                              xDrawPages,
940*cdf0e10cSrcweir                                              xRootNode,
941*cdf0e10cSrcweir                                              maEventQueue,
942*cdf0e10cSrcweir                                              maEventMultiplexer,
943*cdf0e10cSrcweir                                              maScreenUpdater,
944*cdf0e10cSrcweir                                              maActivitiesQueue,
945*cdf0e10cSrcweir                                              maUserEventQueue,
946*cdf0e10cSrcweir                                              *this,
947*cdf0e10cSrcweir                                              maViewContainer,
948*cdf0e10cSrcweir                                              mxComponentContext,
949*cdf0e10cSrcweir                                              maShapeEventListeners,
950*cdf0e10cSrcweir                                              maShapeCursors,
951*cdf0e10cSrcweir                                              (aIter != maPolygons.end()) ? aIter->second :  PolyPolygonVector(),
952*cdf0e10cSrcweir                                              maUserPaintColor ? *maUserPaintColor : RGBColor(),
953*cdf0e10cSrcweir 											 maUserPaintStrokeWidth,
954*cdf0e10cSrcweir                                              !!maUserPaintColor,
955*cdf0e10cSrcweir                                              mbImageAnimationsAllowed,
956*cdf0e10cSrcweir                                              mbDisableAnimationZOrder) );
957*cdf0e10cSrcweir 
958*cdf0e10cSrcweir     // prefetch show content (reducing latency for slide
959*cdf0e10cSrcweir     // bitmap and effect start later on)
960*cdf0e10cSrcweir     pSlide->prefetch();
961*cdf0e10cSrcweir 
962*cdf0e10cSrcweir     return pSlide;
963*cdf0e10cSrcweir }
964*cdf0e10cSrcweir 
965*cdf0e10cSrcweir void SlideShowImpl::requestWaitSymbol (void)
966*cdf0e10cSrcweir {
967*cdf0e10cSrcweir     ++mnWaitSymbolRequestCount;
968*cdf0e10cSrcweir     OSL_ASSERT(mnWaitSymbolRequestCount>0);
969*cdf0e10cSrcweir 
970*cdf0e10cSrcweir     if (mnWaitSymbolRequestCount == 1)
971*cdf0e10cSrcweir     {
972*cdf0e10cSrcweir         if( !mpWaitSymbol )
973*cdf0e10cSrcweir         {
974*cdf0e10cSrcweir             // fall back to cursor
975*cdf0e10cSrcweir             requestCursor(calcActiveCursor(mnCurrentCursor));
976*cdf0e10cSrcweir         }
977*cdf0e10cSrcweir         else
978*cdf0e10cSrcweir             mpWaitSymbol->show();
979*cdf0e10cSrcweir     }
980*cdf0e10cSrcweir }
981*cdf0e10cSrcweir 
982*cdf0e10cSrcweir void SlideShowImpl::releaseWaitSymbol (void)
983*cdf0e10cSrcweir {
984*cdf0e10cSrcweir     --mnWaitSymbolRequestCount;
985*cdf0e10cSrcweir     OSL_ASSERT(mnWaitSymbolRequestCount>=0);
986*cdf0e10cSrcweir 
987*cdf0e10cSrcweir     if (mnWaitSymbolRequestCount == 0)
988*cdf0e10cSrcweir     {
989*cdf0e10cSrcweir         if( !mpWaitSymbol )
990*cdf0e10cSrcweir         {
991*cdf0e10cSrcweir             // fall back to cursor
992*cdf0e10cSrcweir             requestCursor(calcActiveCursor(mnCurrentCursor));
993*cdf0e10cSrcweir         }
994*cdf0e10cSrcweir         else
995*cdf0e10cSrcweir             mpWaitSymbol->hide();
996*cdf0e10cSrcweir     }
997*cdf0e10cSrcweir }
998*cdf0e10cSrcweir 
999*cdf0e10cSrcweir sal_Int16 SlideShowImpl::calcActiveCursor( sal_Int16 nCursorShape ) const
1000*cdf0e10cSrcweir {
1001*cdf0e10cSrcweir     if( mnWaitSymbolRequestCount>0 && !mpWaitSymbol ) // enforce wait cursor
1002*cdf0e10cSrcweir         nCursorShape = awt::SystemPointer::WAIT;
1003*cdf0e10cSrcweir     else if( !mbMouseVisible ) // enforce INVISIBLE
1004*cdf0e10cSrcweir         nCursorShape = awt::SystemPointer::INVISIBLE;
1005*cdf0e10cSrcweir     else if( maUserPaintColor &&
1006*cdf0e10cSrcweir              nCursorShape == awt::SystemPointer::ARROW )
1007*cdf0e10cSrcweir         nCursorShape = awt::SystemPointer::PEN;
1008*cdf0e10cSrcweir 
1009*cdf0e10cSrcweir     return nCursorShape;
1010*cdf0e10cSrcweir }
1011*cdf0e10cSrcweir 
1012*cdf0e10cSrcweir 
1013*cdf0e10cSrcweir void SlideShowImpl::stopShow()
1014*cdf0e10cSrcweir {
1015*cdf0e10cSrcweir     // Force-end running animation
1016*cdf0e10cSrcweir     // ===========================
1017*cdf0e10cSrcweir     if (mpCurrentSlide)
1018*cdf0e10cSrcweir     {
1019*cdf0e10cSrcweir         mpCurrentSlide->hide();
1020*cdf0e10cSrcweir         //Register polygons in the map
1021*cdf0e10cSrcweir         if(findPolygons(mpCurrentSlide->getXDrawPage()) != maPolygons.end())
1022*cdf0e10cSrcweir             maPolygons.erase(mpCurrentSlide->getXDrawPage());
1023*cdf0e10cSrcweir 
1024*cdf0e10cSrcweir         maPolygons.insert(make_pair(mpCurrentSlide->getXDrawPage(),mpCurrentSlide->getPolygons()));
1025*cdf0e10cSrcweir     }
1026*cdf0e10cSrcweir 
1027*cdf0e10cSrcweir     // clear all queues
1028*cdf0e10cSrcweir     maEventQueue.clear();
1029*cdf0e10cSrcweir     maActivitiesQueue.clear();
1030*cdf0e10cSrcweir 
1031*cdf0e10cSrcweir     // Attention: we MUST clear the user event queue here,
1032*cdf0e10cSrcweir     // this is because the current slide might have registered
1033*cdf0e10cSrcweir     // shape events (click or enter/leave), which might
1034*cdf0e10cSrcweir     // otherwise dangle forever in the queue (because of the
1035*cdf0e10cSrcweir     // shared ptr nature). If someone needs to change this:
1036*cdf0e10cSrcweir     // somehow unregister those shapes at the user event queue
1037*cdf0e10cSrcweir     // on notifySlideEnded().
1038*cdf0e10cSrcweir     maUserEventQueue.clear();
1039*cdf0e10cSrcweir 
1040*cdf0e10cSrcweir     // re-enable automatic effect advancement
1041*cdf0e10cSrcweir     // (maEventQueue.clear() above might have killed
1042*cdf0e10cSrcweir     // maEventMultiplexer's tick events)
1043*cdf0e10cSrcweir     if (mbAutomaticAdvancementMode)
1044*cdf0e10cSrcweir     {
1045*cdf0e10cSrcweir         // toggle automatic mode (enabling just again is
1046*cdf0e10cSrcweir         // ignored by EventMultiplexer)
1047*cdf0e10cSrcweir         maEventMultiplexer.setAutomaticMode( false );
1048*cdf0e10cSrcweir         maEventMultiplexer.setAutomaticMode( true );
1049*cdf0e10cSrcweir     }
1050*cdf0e10cSrcweir }
1051*cdf0e10cSrcweir 
1052*cdf0e10cSrcweir 
1053*cdf0e10cSrcweir 
1054*cdf0e10cSrcweir class SlideShowImpl::PrefetchPropertiesFunc
1055*cdf0e10cSrcweir {
1056*cdf0e10cSrcweir public:
1057*cdf0e10cSrcweir     PrefetchPropertiesFunc( SlideShowImpl * that_,
1058*cdf0e10cSrcweir         bool& rbSkipAllMainSequenceEffects,
1059*cdf0e10cSrcweir         bool& rbSkipSlideTransition)
1060*cdf0e10cSrcweir         : mpSlideShowImpl(that_),
1061*cdf0e10cSrcweir           mrbSkipAllMainSequenceEffects(rbSkipAllMainSequenceEffects),
1062*cdf0e10cSrcweir           mrbSkipSlideTransition(rbSkipSlideTransition)
1063*cdf0e10cSrcweir     {}
1064*cdf0e10cSrcweir 
1065*cdf0e10cSrcweir     void operator()( beans::PropertyValue const& rProperty ) const {
1066*cdf0e10cSrcweir         if (rProperty.Name.equalsAsciiL(
1067*cdf0e10cSrcweir                 RTL_CONSTASCII_STRINGPARAM("Prefetch") ))
1068*cdf0e10cSrcweir         {
1069*cdf0e10cSrcweir             uno::Sequence<uno::Any> seq;
1070*cdf0e10cSrcweir             if ((rProperty.Value >>= seq) && seq.getLength() == 2)
1071*cdf0e10cSrcweir             {
1072*cdf0e10cSrcweir                 seq[0] >>= mpSlideShowImpl->mxPrefetchSlide;
1073*cdf0e10cSrcweir                 seq[1] >>= mpSlideShowImpl->mxPrefetchAnimationNode;
1074*cdf0e10cSrcweir             }
1075*cdf0e10cSrcweir         }
1076*cdf0e10cSrcweir         else if (rProperty.Name.equalsAsciiL(
1077*cdf0e10cSrcweir                 RTL_CONSTASCII_STRINGPARAM("SkipAllMainSequenceEffects") ))
1078*cdf0e10cSrcweir         {
1079*cdf0e10cSrcweir             rProperty.Value >>= mrbSkipAllMainSequenceEffects;
1080*cdf0e10cSrcweir         }
1081*cdf0e10cSrcweir         else if (rProperty.Name.equalsAsciiL(
1082*cdf0e10cSrcweir                 RTL_CONSTASCII_STRINGPARAM("SkipSlideTransition") ))
1083*cdf0e10cSrcweir         {
1084*cdf0e10cSrcweir             rProperty.Value >>= mrbSkipSlideTransition;
1085*cdf0e10cSrcweir         }
1086*cdf0e10cSrcweir         else
1087*cdf0e10cSrcweir         {
1088*cdf0e10cSrcweir             OSL_ENSURE( false, rtl::OUStringToOString(
1089*cdf0e10cSrcweir                             rProperty.Name, RTL_TEXTENCODING_UTF8 ).getStr() );
1090*cdf0e10cSrcweir         }
1091*cdf0e10cSrcweir     }
1092*cdf0e10cSrcweir private:
1093*cdf0e10cSrcweir     SlideShowImpl *const mpSlideShowImpl;
1094*cdf0e10cSrcweir     bool& mrbSkipAllMainSequenceEffects;
1095*cdf0e10cSrcweir     bool& mrbSkipSlideTransition;
1096*cdf0e10cSrcweir };
1097*cdf0e10cSrcweir 
1098*cdf0e10cSrcweir void SlideShowImpl::displaySlide(
1099*cdf0e10cSrcweir     uno::Reference<drawing::XDrawPage> const& xSlide,
1100*cdf0e10cSrcweir     uno::Reference<drawing::XDrawPagesSupplier> const& xDrawPages,
1101*cdf0e10cSrcweir     uno::Reference<animations::XAnimationNode> const& xRootNode,
1102*cdf0e10cSrcweir     uno::Sequence<beans::PropertyValue> const& rProperties )
1103*cdf0e10cSrcweir     throw (uno::RuntimeException)
1104*cdf0e10cSrcweir {
1105*cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
1106*cdf0e10cSrcweir 
1107*cdf0e10cSrcweir     if (isDisposed())
1108*cdf0e10cSrcweir         return;
1109*cdf0e10cSrcweir 
1110*cdf0e10cSrcweir     maEffectRewinder.setRootAnimationNode(xRootNode);
1111*cdf0e10cSrcweir 
1112*cdf0e10cSrcweir     // precondition: must only be called from the main thread!
1113*cdf0e10cSrcweir     DBG_TESTSOLARMUTEX();
1114*cdf0e10cSrcweir 
1115*cdf0e10cSrcweir     mxDrawPagesSupplier = xDrawPages;
1116*cdf0e10cSrcweir 
1117*cdf0e10cSrcweir     stopShow();  // MUST call that: results in
1118*cdf0e10cSrcweir     // maUserEventQueue.clear(). What's more,
1119*cdf0e10cSrcweir     // stopShow()'s currSlide->hide() call is
1120*cdf0e10cSrcweir     // now also required, notifySlideEnded()
1121*cdf0e10cSrcweir     // relies on that
1122*cdf0e10cSrcweir     // unconditionally. Otherwise, genuine
1123*cdf0e10cSrcweir     // shape animations (drawing layer and
1124*cdf0e10cSrcweir     // GIF) will not be stopped.
1125*cdf0e10cSrcweir 
1126*cdf0e10cSrcweir     bool bSkipAllMainSequenceEffects (false);
1127*cdf0e10cSrcweir     bool bSkipSlideTransition (false);
1128*cdf0e10cSrcweir     std::for_each( rProperties.getConstArray(),
1129*cdf0e10cSrcweir                    rProperties.getConstArray() + rProperties.getLength(),
1130*cdf0e10cSrcweir         PrefetchPropertiesFunc(this, bSkipAllMainSequenceEffects, bSkipSlideTransition) );
1131*cdf0e10cSrcweir 
1132*cdf0e10cSrcweir     OSL_ENSURE( !maViewContainer.empty(), "### no views!" );
1133*cdf0e10cSrcweir     if (maViewContainer.empty())
1134*cdf0e10cSrcweir         return;
1135*cdf0e10cSrcweir 
1136*cdf0e10cSrcweir     // this here might take some time
1137*cdf0e10cSrcweir     {
1138*cdf0e10cSrcweir         WaitSymbolLock aLock (*this);
1139*cdf0e10cSrcweir 
1140*cdf0e10cSrcweir         mpPreviousSlide = mpCurrentSlide;
1141*cdf0e10cSrcweir         mpCurrentSlide.reset();
1142*cdf0e10cSrcweir 
1143*cdf0e10cSrcweir         if (matches( mpPrefetchSlide, xSlide, xRootNode ))
1144*cdf0e10cSrcweir         {
1145*cdf0e10cSrcweir             // prefetched slide matches:
1146*cdf0e10cSrcweir             mpCurrentSlide = mpPrefetchSlide;
1147*cdf0e10cSrcweir         }
1148*cdf0e10cSrcweir         else
1149*cdf0e10cSrcweir             mpCurrentSlide = makeSlide( xSlide, xDrawPages, xRootNode );
1150*cdf0e10cSrcweir 
1151*cdf0e10cSrcweir         OSL_ASSERT( mpCurrentSlide );
1152*cdf0e10cSrcweir         if (mpCurrentSlide)
1153*cdf0e10cSrcweir         {
1154*cdf0e10cSrcweir             basegfx::B2DSize oldSlideSize;
1155*cdf0e10cSrcweir             if( mpPreviousSlide )
1156*cdf0e10cSrcweir                 oldSlideSize = mpPreviousSlide->getSlideSize();
1157*cdf0e10cSrcweir 
1158*cdf0e10cSrcweir             basegfx::B2DSize const slideSize( mpCurrentSlide->getSlideSize() );
1159*cdf0e10cSrcweir 
1160*cdf0e10cSrcweir             // push new transformation to all views, if size changed
1161*cdf0e10cSrcweir             if( !mpPreviousSlide || oldSlideSize != slideSize )
1162*cdf0e10cSrcweir             {
1163*cdf0e10cSrcweir                 std::for_each( maViewContainer.begin(),
1164*cdf0e10cSrcweir                                maViewContainer.end(),
1165*cdf0e10cSrcweir                                boost::bind( &View::setViewSize, _1,
1166*cdf0e10cSrcweir                                             boost::cref(slideSize) ));
1167*cdf0e10cSrcweir 
1168*cdf0e10cSrcweir                 // explicitly notify view change here,
1169*cdf0e10cSrcweir                 // because transformation might have changed:
1170*cdf0e10cSrcweir                 // optimization, this->notifyViewChange() would
1171*cdf0e10cSrcweir                 // repaint slide which is not necessary.
1172*cdf0e10cSrcweir                 maEventMultiplexer.notifyViewsChanged();
1173*cdf0e10cSrcweir             }
1174*cdf0e10cSrcweir 
1175*cdf0e10cSrcweir             // create slide transition, and add proper end event
1176*cdf0e10cSrcweir             // (which then starts the slide effects
1177*cdf0e10cSrcweir             // via CURRENT_SLIDE.show())
1178*cdf0e10cSrcweir             ActivitySharedPtr pSlideChangeActivity (
1179*cdf0e10cSrcweir                 createSlideTransition(
1180*cdf0e10cSrcweir                     mpCurrentSlide->getXDrawPage(),
1181*cdf0e10cSrcweir                     mpPreviousSlide,
1182*cdf0e10cSrcweir                     mpCurrentSlide,
1183*cdf0e10cSrcweir                     makeEvent(
1184*cdf0e10cSrcweir                         boost::bind(
1185*cdf0e10cSrcweir                             &SlideShowImpl::notifySlideTransitionEnded,
1186*cdf0e10cSrcweir                             this,
1187*cdf0e10cSrcweir                             false ),
1188*cdf0e10cSrcweir                         "SlideShowImpl::notifySlideTransitionEnded")));
1189*cdf0e10cSrcweir 
1190*cdf0e10cSrcweir             if (bSkipSlideTransition)
1191*cdf0e10cSrcweir             {
1192*cdf0e10cSrcweir                 // The transition activity was created for the side effects
1193*cdf0e10cSrcweir                 // (like sound transitions).  Because we want to skip the
1194*cdf0e10cSrcweir                 // acutual transition animation we do not need the activity
1195*cdf0e10cSrcweir                 // anymore.
1196*cdf0e10cSrcweir                 pSlideChangeActivity.reset();
1197*cdf0e10cSrcweir             }
1198*cdf0e10cSrcweir 
1199*cdf0e10cSrcweir             if (pSlideChangeActivity)
1200*cdf0e10cSrcweir             {
1201*cdf0e10cSrcweir                 // factory generated a slide transition - activate it!
1202*cdf0e10cSrcweir                 maActivitiesQueue.addActivity( pSlideChangeActivity );
1203*cdf0e10cSrcweir             }
1204*cdf0e10cSrcweir             else
1205*cdf0e10cSrcweir             {
1206*cdf0e10cSrcweir                 // no transition effect on this slide - schedule slide
1207*cdf0e10cSrcweir                 // effect start event right away.
1208*cdf0e10cSrcweir                 maEventQueue.addEvent(
1209*cdf0e10cSrcweir                     makeEvent(
1210*cdf0e10cSrcweir                         boost::bind(
1211*cdf0e10cSrcweir                             &SlideShowImpl::notifySlideTransitionEnded,
1212*cdf0e10cSrcweir                             this,
1213*cdf0e10cSrcweir                             true ),
1214*cdf0e10cSrcweir                         "SlideShowImpl::notifySlideTransitionEnded"));
1215*cdf0e10cSrcweir             }
1216*cdf0e10cSrcweir         }
1217*cdf0e10cSrcweir     } // finally
1218*cdf0e10cSrcweir 
1219*cdf0e10cSrcweir     maEventMultiplexer.notifySlideTransitionStarted();
1220*cdf0e10cSrcweir     maListenerContainer.forEach<presentation::XSlideShowListener>(
1221*cdf0e10cSrcweir         boost::mem_fn( &presentation::XSlideShowListener::slideTransitionStarted ) );
1222*cdf0e10cSrcweir 
1223*cdf0e10cSrcweir     // We are currently rewinding an effect.  This lead us from the next
1224*cdf0e10cSrcweir     // slide to this one.  To complete this we have to play back all main
1225*cdf0e10cSrcweir     // sequence effects on this slide.
1226*cdf0e10cSrcweir     if (bSkipAllMainSequenceEffects)
1227*cdf0e10cSrcweir         maEffectRewinder.skipAllMainSequenceEffects();
1228*cdf0e10cSrcweir }
1229*cdf0e10cSrcweir 
1230*cdf0e10cSrcweir void SlideShowImpl::redisplayCurrentSlide (void)
1231*cdf0e10cSrcweir {
1232*cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
1233*cdf0e10cSrcweir 
1234*cdf0e10cSrcweir     if (isDisposed())
1235*cdf0e10cSrcweir         return;
1236*cdf0e10cSrcweir 
1237*cdf0e10cSrcweir     // precondition: must only be called from the main thread!
1238*cdf0e10cSrcweir     DBG_TESTSOLARMUTEX();
1239*cdf0e10cSrcweir     stopShow();
1240*cdf0e10cSrcweir 
1241*cdf0e10cSrcweir     OSL_ENSURE( !maViewContainer.empty(), "### no views!" );
1242*cdf0e10cSrcweir     if (maViewContainer.empty())
1243*cdf0e10cSrcweir         return;
1244*cdf0e10cSrcweir 
1245*cdf0e10cSrcweir     // No transition effect on this slide - schedule slide
1246*cdf0e10cSrcweir     // effect start event right away.
1247*cdf0e10cSrcweir     maEventQueue.addEvent(
1248*cdf0e10cSrcweir         makeEvent(
1249*cdf0e10cSrcweir             boost::bind(
1250*cdf0e10cSrcweir                 &SlideShowImpl::notifySlideTransitionEnded,
1251*cdf0e10cSrcweir                 this,
1252*cdf0e10cSrcweir                 true ),
1253*cdf0e10cSrcweir             "SlideShowImpl::notifySlideTransitionEnded"));
1254*cdf0e10cSrcweir 
1255*cdf0e10cSrcweir     maEventMultiplexer.notifySlideTransitionStarted();
1256*cdf0e10cSrcweir     maListenerContainer.forEach<presentation::XSlideShowListener>(
1257*cdf0e10cSrcweir         boost::mem_fn( &presentation::XSlideShowListener::slideTransitionStarted ) );
1258*cdf0e10cSrcweir }
1259*cdf0e10cSrcweir 
1260*cdf0e10cSrcweir sal_Bool SlideShowImpl::nextEffect() throw (uno::RuntimeException)
1261*cdf0e10cSrcweir {
1262*cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
1263*cdf0e10cSrcweir 
1264*cdf0e10cSrcweir     if (isDisposed())
1265*cdf0e10cSrcweir         return false;
1266*cdf0e10cSrcweir 
1267*cdf0e10cSrcweir     // precondition: must only be called from the main thread!
1268*cdf0e10cSrcweir     DBG_TESTSOLARMUTEX();
1269*cdf0e10cSrcweir 
1270*cdf0e10cSrcweir     if (mbShowPaused)
1271*cdf0e10cSrcweir         return true;
1272*cdf0e10cSrcweir     else
1273*cdf0e10cSrcweir         return maEventMultiplexer.notifyNextEffect();
1274*cdf0e10cSrcweir }
1275*cdf0e10cSrcweir 
1276*cdf0e10cSrcweir 
1277*cdf0e10cSrcweir sal_Bool SlideShowImpl::previousEffect() throw (uno::RuntimeException)
1278*cdf0e10cSrcweir {
1279*cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
1280*cdf0e10cSrcweir 
1281*cdf0e10cSrcweir     if (isDisposed())
1282*cdf0e10cSrcweir         return false;
1283*cdf0e10cSrcweir 
1284*cdf0e10cSrcweir     // precondition: must only be called from the main thread!
1285*cdf0e10cSrcweir     DBG_TESTSOLARMUTEX();
1286*cdf0e10cSrcweir 
1287*cdf0e10cSrcweir     if (mbShowPaused)
1288*cdf0e10cSrcweir         return true;
1289*cdf0e10cSrcweir     else
1290*cdf0e10cSrcweir     {
1291*cdf0e10cSrcweir         return maEffectRewinder.rewind(
1292*cdf0e10cSrcweir             maScreenUpdater.createLock(false),
1293*cdf0e10cSrcweir             ::boost::bind<void>(::boost::mem_fn(&SlideShowImpl::redisplayCurrentSlide), this),
1294*cdf0e10cSrcweir             ::boost::bind<void>(::boost::mem_fn(&SlideShowImpl::rewindEffectToPreviousSlide), this));
1295*cdf0e10cSrcweir     }
1296*cdf0e10cSrcweir }
1297*cdf0e10cSrcweir 
1298*cdf0e10cSrcweir void SlideShowImpl::rewindEffectToPreviousSlide (void)
1299*cdf0e10cSrcweir {
1300*cdf0e10cSrcweir     // Show the wait symbol now and prevent it from showing temporary slide
1301*cdf0e10cSrcweir     // content while effects are played back.
1302*cdf0e10cSrcweir     WaitSymbolLock aLock (*this);
1303*cdf0e10cSrcweir 
1304*cdf0e10cSrcweir     // A previous call to EffectRewinder::Rewind could not rewind the current
1305*cdf0e10cSrcweir     // effect because there are no effects on the current slide or none has
1306*cdf0e10cSrcweir     // yet been displayed.  Go to the previous slide.
1307*cdf0e10cSrcweir     notifySlideEnded(true);
1308*cdf0e10cSrcweir 
1309*cdf0e10cSrcweir     // Process pending events once more in order to have the following
1310*cdf0e10cSrcweir     // screen update show the last effect.  Not sure whether this should be
1311*cdf0e10cSrcweir     // necessary.
1312*cdf0e10cSrcweir     maEventQueue.forceEmpty();
1313*cdf0e10cSrcweir 
1314*cdf0e10cSrcweir     // We have to call the screen updater before the wait symbol is turned
1315*cdf0e10cSrcweir     // off.  Otherwise the wait symbol would force the display of an
1316*cdf0e10cSrcweir     // intermediate state of the slide (before the effects are replayed.)
1317*cdf0e10cSrcweir     maScreenUpdater.commitUpdates();
1318*cdf0e10cSrcweir }
1319*cdf0e10cSrcweir 
1320*cdf0e10cSrcweir sal_Bool SlideShowImpl::startShapeActivity(
1321*cdf0e10cSrcweir     uno::Reference<drawing::XShape> const& /*xShape*/ )
1322*cdf0e10cSrcweir     throw (uno::RuntimeException)
1323*cdf0e10cSrcweir {
1324*cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
1325*cdf0e10cSrcweir 
1326*cdf0e10cSrcweir     // precondition: must only be called from the main thread!
1327*cdf0e10cSrcweir     DBG_TESTSOLARMUTEX();
1328*cdf0e10cSrcweir 
1329*cdf0e10cSrcweir     // TODO(F3): NYI
1330*cdf0e10cSrcweir     OSL_ENSURE( false, "not yet implemented!" );
1331*cdf0e10cSrcweir     return false;
1332*cdf0e10cSrcweir }
1333*cdf0e10cSrcweir 
1334*cdf0e10cSrcweir sal_Bool SlideShowImpl::stopShapeActivity(
1335*cdf0e10cSrcweir     uno::Reference<drawing::XShape> const& /*xShape*/ )
1336*cdf0e10cSrcweir     throw (uno::RuntimeException)
1337*cdf0e10cSrcweir {
1338*cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
1339*cdf0e10cSrcweir 
1340*cdf0e10cSrcweir     // precondition: must only be called from the main thread!
1341*cdf0e10cSrcweir     DBG_TESTSOLARMUTEX();
1342*cdf0e10cSrcweir 
1343*cdf0e10cSrcweir     // TODO(F3): NYI
1344*cdf0e10cSrcweir     OSL_ENSURE( false, "not yet implemented!" );
1345*cdf0e10cSrcweir     return false;
1346*cdf0e10cSrcweir }
1347*cdf0e10cSrcweir 
1348*cdf0e10cSrcweir sal_Bool SlideShowImpl::pause( sal_Bool bPauseShow )
1349*cdf0e10cSrcweir     throw (uno::RuntimeException)
1350*cdf0e10cSrcweir {
1351*cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
1352*cdf0e10cSrcweir 
1353*cdf0e10cSrcweir     if (isDisposed())
1354*cdf0e10cSrcweir         return false;
1355*cdf0e10cSrcweir 
1356*cdf0e10cSrcweir     // precondition: must only be called from the main thread!
1357*cdf0e10cSrcweir     DBG_TESTSOLARMUTEX();
1358*cdf0e10cSrcweir 
1359*cdf0e10cSrcweir 
1360*cdf0e10cSrcweir     if (bPauseShow)
1361*cdf0e10cSrcweir         mpPresTimer->pauseTimer();
1362*cdf0e10cSrcweir     else
1363*cdf0e10cSrcweir         mpPresTimer->continueTimer();
1364*cdf0e10cSrcweir 
1365*cdf0e10cSrcweir     maEventMultiplexer.notifyPauseMode(bPauseShow);
1366*cdf0e10cSrcweir 
1367*cdf0e10cSrcweir     mbShowPaused = bPauseShow;
1368*cdf0e10cSrcweir     return true;
1369*cdf0e10cSrcweir }
1370*cdf0e10cSrcweir 
1371*cdf0e10cSrcweir uno::Reference<drawing::XDrawPage> SlideShowImpl::getCurrentSlide()
1372*cdf0e10cSrcweir     throw (uno::RuntimeException)
1373*cdf0e10cSrcweir {
1374*cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
1375*cdf0e10cSrcweir 
1376*cdf0e10cSrcweir     if (isDisposed())
1377*cdf0e10cSrcweir         return uno::Reference<drawing::XDrawPage>();
1378*cdf0e10cSrcweir 
1379*cdf0e10cSrcweir     // precondition: must only be called from the main thread!
1380*cdf0e10cSrcweir     DBG_TESTSOLARMUTEX();
1381*cdf0e10cSrcweir 
1382*cdf0e10cSrcweir     if (mpCurrentSlide)
1383*cdf0e10cSrcweir         return mpCurrentSlide->getXDrawPage();
1384*cdf0e10cSrcweir     else
1385*cdf0e10cSrcweir         return uno::Reference<drawing::XDrawPage>();
1386*cdf0e10cSrcweir }
1387*cdf0e10cSrcweir 
1388*cdf0e10cSrcweir sal_Bool SlideShowImpl::addView(
1389*cdf0e10cSrcweir     uno::Reference<presentation::XSlideShowView> const& xView )
1390*cdf0e10cSrcweir     throw (uno::RuntimeException)
1391*cdf0e10cSrcweir {
1392*cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
1393*cdf0e10cSrcweir 
1394*cdf0e10cSrcweir     if (isDisposed())
1395*cdf0e10cSrcweir         return false;
1396*cdf0e10cSrcweir 
1397*cdf0e10cSrcweir     // precondition: must only be called from the main thread!
1398*cdf0e10cSrcweir     DBG_TESTSOLARMUTEX();
1399*cdf0e10cSrcweir 
1400*cdf0e10cSrcweir     // first of all, check if view has a valid canvas
1401*cdf0e10cSrcweir     ENSURE_OR_RETURN_FALSE( xView.is(), "addView(): Invalid view" );
1402*cdf0e10cSrcweir     ENSURE_OR_RETURN_FALSE( xView->getCanvas().is(),
1403*cdf0e10cSrcweir                        "addView(): View does not provide a valid canvas" );
1404*cdf0e10cSrcweir 
1405*cdf0e10cSrcweir     UnoViewSharedPtr const pView( createSlideView(
1406*cdf0e10cSrcweir                                       xView,
1407*cdf0e10cSrcweir                                       maEventQueue,
1408*cdf0e10cSrcweir                                       maEventMultiplexer ));
1409*cdf0e10cSrcweir     if (!maViewContainer.addView( pView ))
1410*cdf0e10cSrcweir         return false; // view already added
1411*cdf0e10cSrcweir 
1412*cdf0e10cSrcweir     // initialize view content
1413*cdf0e10cSrcweir     // =======================
1414*cdf0e10cSrcweir 
1415*cdf0e10cSrcweir     if (mpCurrentSlide)
1416*cdf0e10cSrcweir     {
1417*cdf0e10cSrcweir         // set view transformation
1418*cdf0e10cSrcweir         const basegfx::B2ISize slideSize = mpCurrentSlide->getSlideSize();
1419*cdf0e10cSrcweir         pView->setViewSize( basegfx::B2DSize( slideSize.getX(),
1420*cdf0e10cSrcweir                                               slideSize.getY() ) );
1421*cdf0e10cSrcweir     }
1422*cdf0e10cSrcweir 
1423*cdf0e10cSrcweir     // clear view area (since its newly added,
1424*cdf0e10cSrcweir     // we need a clean slate)
1425*cdf0e10cSrcweir     pView->clearAll();
1426*cdf0e10cSrcweir 
1427*cdf0e10cSrcweir     // broadcast newly added view
1428*cdf0e10cSrcweir     maEventMultiplexer.notifyViewAdded( pView );
1429*cdf0e10cSrcweir 
1430*cdf0e10cSrcweir     // set current mouse ptr
1431*cdf0e10cSrcweir     pView->setCursorShape( calcActiveCursor(mnCurrentCursor) );
1432*cdf0e10cSrcweir 
1433*cdf0e10cSrcweir     return true;
1434*cdf0e10cSrcweir }
1435*cdf0e10cSrcweir 
1436*cdf0e10cSrcweir sal_Bool SlideShowImpl::removeView(
1437*cdf0e10cSrcweir     uno::Reference<presentation::XSlideShowView> const& xView )
1438*cdf0e10cSrcweir     throw (uno::RuntimeException)
1439*cdf0e10cSrcweir {
1440*cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
1441*cdf0e10cSrcweir 
1442*cdf0e10cSrcweir     // precondition: must only be called from the main thread!
1443*cdf0e10cSrcweir     DBG_TESTSOLARMUTEX();
1444*cdf0e10cSrcweir 
1445*cdf0e10cSrcweir     ENSURE_OR_RETURN_FALSE( xView.is(), "removeView(): Invalid view" );
1446*cdf0e10cSrcweir 
1447*cdf0e10cSrcweir     UnoViewSharedPtr const pView( maViewContainer.removeView( xView ) );
1448*cdf0e10cSrcweir     if( !pView )
1449*cdf0e10cSrcweir         return false; // view was not added in the first place
1450*cdf0e10cSrcweir 
1451*cdf0e10cSrcweir     // remove view from EventMultiplexer (mouse events etc.)
1452*cdf0e10cSrcweir     maEventMultiplexer.notifyViewRemoved( pView );
1453*cdf0e10cSrcweir 
1454*cdf0e10cSrcweir     pView->_dispose();
1455*cdf0e10cSrcweir 
1456*cdf0e10cSrcweir     return true;
1457*cdf0e10cSrcweir }
1458*cdf0e10cSrcweir 
1459*cdf0e10cSrcweir void SlideShowImpl::registerUserPaintPolygons( const uno::Reference< lang::XMultiServiceFactory >& xDocFactory ) throw (uno::RuntimeException)
1460*cdf0e10cSrcweir {
1461*cdf0e10cSrcweir     //Retrieve Polygons if user ends presentation by context menu
1462*cdf0e10cSrcweir     if (mpCurrentSlide)
1463*cdf0e10cSrcweir     {
1464*cdf0e10cSrcweir         if(findPolygons(mpCurrentSlide->getXDrawPage()) != maPolygons.end())
1465*cdf0e10cSrcweir             maPolygons.erase(mpCurrentSlide->getXDrawPage());
1466*cdf0e10cSrcweir 
1467*cdf0e10cSrcweir         maPolygons.insert(make_pair(mpCurrentSlide->getXDrawPage(),mpCurrentSlide->getPolygons()));
1468*cdf0e10cSrcweir     }
1469*cdf0e10cSrcweir 
1470*cdf0e10cSrcweir     //Creating the layer for shapes
1471*cdf0e10cSrcweir     // query for the XLayerManager
1472*cdf0e10cSrcweir     uno::Reference< drawing::XLayerSupplier > xLayerSupplier(xDocFactory, uno::UNO_QUERY);
1473*cdf0e10cSrcweir     uno::Reference< container::XNameAccess > xNameAccess = xLayerSupplier->getLayerManager();
1474*cdf0e10cSrcweir 
1475*cdf0e10cSrcweir     uno::Reference< drawing::XLayerManager > xLayerManager(xNameAccess, uno::UNO_QUERY);
1476*cdf0e10cSrcweir     // create a layer and set its properties
1477*cdf0e10cSrcweir     uno::Reference< drawing::XLayer > xDrawnInSlideshow = xLayerManager->insertNewByIndex(xLayerManager->getCount());
1478*cdf0e10cSrcweir     uno::Reference< beans::XPropertySet > xLayerPropSet(xDrawnInSlideshow, uno::UNO_QUERY);
1479*cdf0e10cSrcweir 
1480*cdf0e10cSrcweir     //Layer Name which enables to catch annotations
1481*cdf0e10cSrcweir     rtl::OUString layerName = rtl::OUString::createFromAscii("DrawnInSlideshow");
1482*cdf0e10cSrcweir     uno::Any aPropLayer;
1483*cdf0e10cSrcweir 
1484*cdf0e10cSrcweir     aPropLayer <<= layerName;
1485*cdf0e10cSrcweir     xLayerPropSet->setPropertyValue(rtl::OUString::createFromAscii("Name"), aPropLayer);
1486*cdf0e10cSrcweir 
1487*cdf0e10cSrcweir     aPropLayer <<= true;
1488*cdf0e10cSrcweir     xLayerPropSet->setPropertyValue(rtl::OUString::createFromAscii("IsVisible"), aPropLayer);
1489*cdf0e10cSrcweir 
1490*cdf0e10cSrcweir     aPropLayer <<= false;
1491*cdf0e10cSrcweir     xLayerPropSet->setPropertyValue(rtl::OUString::createFromAscii("IsLocked"), aPropLayer);
1492*cdf0e10cSrcweir 
1493*cdf0e10cSrcweir     PolygonMap::iterator aIter=maPolygons.begin();
1494*cdf0e10cSrcweir 
1495*cdf0e10cSrcweir     PolyPolygonVector aPolygons;
1496*cdf0e10cSrcweir     ::cppcanvas::PolyPolygonSharedPtr pPolyPoly;
1497*cdf0e10cSrcweir     ::basegfx::B2DPolyPolygon b2DPolyPoly;
1498*cdf0e10cSrcweir 
1499*cdf0e10cSrcweir     //Register polygons for each slide
1500*cdf0e10cSrcweir     while(aIter!=maPolygons.end())
1501*cdf0e10cSrcweir     {
1502*cdf0e10cSrcweir         aPolygons = aIter->second;
1503*cdf0e10cSrcweir         //Get shapes for the slide
1504*cdf0e10cSrcweir         ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes > Shapes(aIter->first, ::com::sun::star::uno::UNO_QUERY);
1505*cdf0e10cSrcweir         //Retrieve polygons for one slide
1506*cdf0e10cSrcweir         for( PolyPolygonVector::iterator aIterPoly=aPolygons.begin(),
1507*cdf0e10cSrcweir                  aEnd=aPolygons.end();
1508*cdf0e10cSrcweir              aIterPoly!=aEnd; ++aIterPoly )
1509*cdf0e10cSrcweir         {
1510*cdf0e10cSrcweir             pPolyPoly = (*aIterPoly);
1511*cdf0e10cSrcweir             b2DPolyPoly = ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(pPolyPoly->getUNOPolyPolygon());
1512*cdf0e10cSrcweir 
1513*cdf0e10cSrcweir             //Normally there is only one polygon
1514*cdf0e10cSrcweir             for(sal_uInt32 i=0; i< b2DPolyPoly.count();i++)
1515*cdf0e10cSrcweir             {
1516*cdf0e10cSrcweir                 const ::basegfx::B2DPolygon& aPoly =  b2DPolyPoly.getB2DPolygon(i);
1517*cdf0e10cSrcweir                 sal_uInt32 nPoints = aPoly.count();
1518*cdf0e10cSrcweir 
1519*cdf0e10cSrcweir                 if( nPoints > 1)
1520*cdf0e10cSrcweir                 {
1521*cdf0e10cSrcweir                     //create the PolyLineShape
1522*cdf0e10cSrcweir                     uno::Reference< uno::XInterface > polyshape(xDocFactory->createInstance(
1523*cdf0e10cSrcweir                                                                     rtl::OUString::createFromAscii("com.sun.star.drawing.PolyLineShape") ) );
1524*cdf0e10cSrcweir                     uno::Reference< drawing::XShape > rPolyShape(polyshape, uno::UNO_QUERY);
1525*cdf0e10cSrcweir 
1526*cdf0e10cSrcweir                     //Add the shape to the slide
1527*cdf0e10cSrcweir                     Shapes->add(rPolyShape);
1528*cdf0e10cSrcweir 
1529*cdf0e10cSrcweir                     //Retrieve shape properties
1530*cdf0e10cSrcweir                     uno::Reference< beans::XPropertySet > aXPropSet = uno::Reference< beans::XPropertySet >( rPolyShape, uno::UNO_QUERY );
1531*cdf0e10cSrcweir                     //Construct a sequence of points sequence
1532*cdf0e10cSrcweir                     drawing::PointSequenceSequence aRetval;
1533*cdf0e10cSrcweir                     //Create only one sequence for one polygon
1534*cdf0e10cSrcweir                     aRetval.realloc( 1 );
1535*cdf0e10cSrcweir                     // Retrieve the sequence of points from aRetval
1536*cdf0e10cSrcweir                     drawing::PointSequence* pOuterSequence = aRetval.getArray();
1537*cdf0e10cSrcweir                     // Create 2 points in this sequence
1538*cdf0e10cSrcweir                     pOuterSequence->realloc(nPoints);
1539*cdf0e10cSrcweir                     // Get these points which are in an array
1540*cdf0e10cSrcweir                     awt::Point* pInnerSequence = pOuterSequence->getArray();
1541*cdf0e10cSrcweir                     for( sal_uInt32 n = 0; n < nPoints; n++ )
1542*cdf0e10cSrcweir                     {
1543*cdf0e10cSrcweir                         //Create a point from the polygon
1544*cdf0e10cSrcweir                         *pInnerSequence++ = awt::Point(
1545*cdf0e10cSrcweir                             basegfx::fround(aPoly.getB2DPoint(n).getX()),
1546*cdf0e10cSrcweir                             basegfx::fround(aPoly.getB2DPoint(n).getY()));
1547*cdf0e10cSrcweir                     }
1548*cdf0e10cSrcweir 
1549*cdf0e10cSrcweir                     //Fill the properties
1550*cdf0e10cSrcweir                     //Give the built PointSequenceSequence.
1551*cdf0e10cSrcweir                     uno::Any aParam;
1552*cdf0e10cSrcweir                     aParam <<= aRetval;
1553*cdf0e10cSrcweir                     aXPropSet->setPropertyValue( rtl::OUString::createFromAscii("PolyPolygon"), aParam );
1554*cdf0e10cSrcweir 
1555*cdf0e10cSrcweir                     //LineStyle : SOLID by default
1556*cdf0e10cSrcweir                     uno::Any			aAny;
1557*cdf0e10cSrcweir                     drawing::LineStyle	eLS;
1558*cdf0e10cSrcweir                     eLS = drawing::LineStyle_SOLID;
1559*cdf0e10cSrcweir                     aAny <<= eLS;
1560*cdf0e10cSrcweir                     aXPropSet->setPropertyValue( rtl::OUString::createFromAscii("LineStyle"), aAny );
1561*cdf0e10cSrcweir 
1562*cdf0e10cSrcweir                     //LineColor
1563*cdf0e10cSrcweir                     sal_uInt32			nLineColor;
1564*cdf0e10cSrcweir                     nLineColor = pPolyPoly->getRGBALineColor();
1565*cdf0e10cSrcweir                     //Transform polygon color from RRGGBBAA to AARRGGBB
1566*cdf0e10cSrcweir                     aAny <<= RGBAColor2UnoColor(nLineColor);
1567*cdf0e10cSrcweir                     aXPropSet->setPropertyValue( rtl::OUString::createFromAscii("LineColor"), aAny );
1568*cdf0e10cSrcweir 
1569*cdf0e10cSrcweir                     //LineWidth
1570*cdf0e10cSrcweir                     double				fLineWidth;
1571*cdf0e10cSrcweir                     fLineWidth = pPolyPoly->getStrokeWidth();
1572*cdf0e10cSrcweir                     aAny <<= (sal_Int32)fLineWidth;
1573*cdf0e10cSrcweir                     aXPropSet->setPropertyValue( rtl::OUString::createFromAscii("LineWidth"), aAny );
1574*cdf0e10cSrcweir 
1575*cdf0e10cSrcweir                     // make polygons special
1576*cdf0e10cSrcweir                     xLayerManager->attachShapeToLayer(rPolyShape, xDrawnInSlideshow);
1577*cdf0e10cSrcweir                 }
1578*cdf0e10cSrcweir             }
1579*cdf0e10cSrcweir         }
1580*cdf0e10cSrcweir         ++aIter;
1581*cdf0e10cSrcweir     }
1582*cdf0e10cSrcweir }
1583*cdf0e10cSrcweir 
1584*cdf0e10cSrcweir sal_Bool SlideShowImpl::setProperty( beans::PropertyValue const& rProperty )
1585*cdf0e10cSrcweir     throw (uno::RuntimeException)
1586*cdf0e10cSrcweir {
1587*cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
1588*cdf0e10cSrcweir 
1589*cdf0e10cSrcweir     if (isDisposed())
1590*cdf0e10cSrcweir         return false;
1591*cdf0e10cSrcweir 
1592*cdf0e10cSrcweir     // precondition: must only be called from the main thread!
1593*cdf0e10cSrcweir     DBG_TESTSOLARMUTEX();
1594*cdf0e10cSrcweir 
1595*cdf0e10cSrcweir     if (rProperty.Name.equalsAsciiL(
1596*cdf0e10cSrcweir             RTL_CONSTASCII_STRINGPARAM("AutomaticAdvancement") ))
1597*cdf0e10cSrcweir     {
1598*cdf0e10cSrcweir         double nTimeout(0.0);
1599*cdf0e10cSrcweir         mbAutomaticAdvancementMode = (rProperty.Value >>= nTimeout);
1600*cdf0e10cSrcweir         if (mbAutomaticAdvancementMode)
1601*cdf0e10cSrcweir         {
1602*cdf0e10cSrcweir             maEventMultiplexer.setAutomaticTimeout( nTimeout );
1603*cdf0e10cSrcweir         }
1604*cdf0e10cSrcweir         maEventMultiplexer.setAutomaticMode( mbAutomaticAdvancementMode );
1605*cdf0e10cSrcweir         return true;
1606*cdf0e10cSrcweir     }
1607*cdf0e10cSrcweir 
1608*cdf0e10cSrcweir     if (rProperty.Name.equalsAsciiL(
1609*cdf0e10cSrcweir             RTL_CONSTASCII_STRINGPARAM("UserPaintColor") ))
1610*cdf0e10cSrcweir     {
1611*cdf0e10cSrcweir         sal_Int32 nColor(0);
1612*cdf0e10cSrcweir         if (rProperty.Value >>= nColor)
1613*cdf0e10cSrcweir         {
1614*cdf0e10cSrcweir             OSL_ENSURE( mbMouseVisible,
1615*cdf0e10cSrcweir                         "setProperty(): User paint overrides invisible mouse" );
1616*cdf0e10cSrcweir 
1617*cdf0e10cSrcweir             // enable user paint
1618*cdf0e10cSrcweir             maUserPaintColor.reset( unoColor2RGBColor( nColor ) );
1619*cdf0e10cSrcweir 			if( mpCurrentSlide && !mpCurrentSlide->isPaintOverlayActive() )
1620*cdf0e10cSrcweir 				mpCurrentSlide->enablePaintOverlay();
1621*cdf0e10cSrcweir 
1622*cdf0e10cSrcweir 			maEventMultiplexer.notifyUserPaintColor( *maUserPaintColor );
1623*cdf0e10cSrcweir         }
1624*cdf0e10cSrcweir         else
1625*cdf0e10cSrcweir         {
1626*cdf0e10cSrcweir             // disable user paint
1627*cdf0e10cSrcweir             maUserPaintColor.reset();
1628*cdf0e10cSrcweir             maEventMultiplexer.notifyUserPaintDisabled();
1629*cdf0e10cSrcweir 			if( mpCurrentSlide )
1630*cdf0e10cSrcweir 				mpCurrentSlide->disablePaintOverlay();
1631*cdf0e10cSrcweir         }
1632*cdf0e10cSrcweir 
1633*cdf0e10cSrcweir         resetCursor();
1634*cdf0e10cSrcweir 
1635*cdf0e10cSrcweir         return true;
1636*cdf0e10cSrcweir     }
1637*cdf0e10cSrcweir 
1638*cdf0e10cSrcweir 	//adding support for erasing features in UserPaintOverlay
1639*cdf0e10cSrcweir 	if (rProperty.Name.equalsAsciiL(
1640*cdf0e10cSrcweir             RTL_CONSTASCII_STRINGPARAM("EraseAllInk") ))
1641*cdf0e10cSrcweir 	{
1642*cdf0e10cSrcweir 		bool nEraseAllInk(false);
1643*cdf0e10cSrcweir 		if (rProperty.Value >>= nEraseAllInk)
1644*cdf0e10cSrcweir 		{
1645*cdf0e10cSrcweir 		    OSL_ENSURE( mbMouseVisible,
1646*cdf0e10cSrcweir                         "setProperty(): User paint overrides invisible mouse" );
1647*cdf0e10cSrcweir 
1648*cdf0e10cSrcweir 		    // enable user paint
1649*cdf0e10cSrcweir 		    maEraseAllInk.reset( nEraseAllInk );
1650*cdf0e10cSrcweir 		    maEventMultiplexer.notifyEraseAllInk( *maEraseAllInk );
1651*cdf0e10cSrcweir 	    }
1652*cdf0e10cSrcweir 
1653*cdf0e10cSrcweir 	    return true;
1654*cdf0e10cSrcweir 	}
1655*cdf0e10cSrcweir 
1656*cdf0e10cSrcweir 	if (rProperty.Name.equalsAsciiL(
1657*cdf0e10cSrcweir             RTL_CONSTASCII_STRINGPARAM("SwitchPenMode") ))
1658*cdf0e10cSrcweir 	{
1659*cdf0e10cSrcweir 		bool nSwitchPenMode(false);
1660*cdf0e10cSrcweir 		if (rProperty.Value >>= nSwitchPenMode)
1661*cdf0e10cSrcweir 		{
1662*cdf0e10cSrcweir 		    OSL_ENSURE( mbMouseVisible,
1663*cdf0e10cSrcweir                         "setProperty(): User paint overrides invisible mouse" );
1664*cdf0e10cSrcweir 
1665*cdf0e10cSrcweir 		    if(nSwitchPenMode == true){
1666*cdf0e10cSrcweir 			// Switch to Pen Mode
1667*cdf0e10cSrcweir 			maSwitchPenMode.reset( nSwitchPenMode );
1668*cdf0e10cSrcweir 			maEventMultiplexer.notifySwitchPenMode();
1669*cdf0e10cSrcweir 		    }
1670*cdf0e10cSrcweir 		}
1671*cdf0e10cSrcweir 		return true;
1672*cdf0e10cSrcweir 	}
1673*cdf0e10cSrcweir 
1674*cdf0e10cSrcweir 
1675*cdf0e10cSrcweir 	if (rProperty.Name.equalsAsciiL(
1676*cdf0e10cSrcweir             RTL_CONSTASCII_STRINGPARAM("SwitchEraserMode") ))
1677*cdf0e10cSrcweir 	{
1678*cdf0e10cSrcweir 		bool nSwitchEraserMode(false);
1679*cdf0e10cSrcweir 		if (rProperty.Value >>= nSwitchEraserMode)
1680*cdf0e10cSrcweir 		{
1681*cdf0e10cSrcweir 		    OSL_ENSURE( mbMouseVisible,
1682*cdf0e10cSrcweir                         "setProperty(): User paint overrides invisible mouse" );
1683*cdf0e10cSrcweir 		    if(nSwitchEraserMode == true){
1684*cdf0e10cSrcweir 			// switch to Eraser mode
1685*cdf0e10cSrcweir 			maSwitchEraserMode.reset( nSwitchEraserMode );
1686*cdf0e10cSrcweir 			maEventMultiplexer.notifySwitchEraserMode();
1687*cdf0e10cSrcweir 		    }
1688*cdf0e10cSrcweir 		}
1689*cdf0e10cSrcweir 
1690*cdf0e10cSrcweir 		return true;
1691*cdf0e10cSrcweir 	}
1692*cdf0e10cSrcweir 
1693*cdf0e10cSrcweir 
1694*cdf0e10cSrcweir 
1695*cdf0e10cSrcweir 	if (rProperty.Name.equalsAsciiL(
1696*cdf0e10cSrcweir             RTL_CONSTASCII_STRINGPARAM("EraseInk") ))
1697*cdf0e10cSrcweir 	{
1698*cdf0e10cSrcweir 		sal_Int32 nEraseInk(100);
1699*cdf0e10cSrcweir 		if (rProperty.Value >>= nEraseInk)
1700*cdf0e10cSrcweir 		{
1701*cdf0e10cSrcweir 		    OSL_ENSURE( mbMouseVisible,
1702*cdf0e10cSrcweir                         "setProperty(): User paint overrides invisible mouse" );
1703*cdf0e10cSrcweir 
1704*cdf0e10cSrcweir 		    // enable user paint
1705*cdf0e10cSrcweir 		    maEraseInk.reset( nEraseInk );
1706*cdf0e10cSrcweir 		    maEventMultiplexer.notifyEraseInkWidth( *maEraseInk );
1707*cdf0e10cSrcweir 		}
1708*cdf0e10cSrcweir 
1709*cdf0e10cSrcweir 		return true;
1710*cdf0e10cSrcweir 	}
1711*cdf0e10cSrcweir 
1712*cdf0e10cSrcweir 	// new Property for pen's width
1713*cdf0e10cSrcweir     if (rProperty.Name.equalsAsciiL(
1714*cdf0e10cSrcweir             RTL_CONSTASCII_STRINGPARAM("UserPaintStrokeWidth") ))
1715*cdf0e10cSrcweir     {
1716*cdf0e10cSrcweir         double nWidth(4.0);
1717*cdf0e10cSrcweir         if (rProperty.Value >>= nWidth)
1718*cdf0e10cSrcweir         {
1719*cdf0e10cSrcweir             OSL_ENSURE( mbMouseVisible,"setProperty(): User paint overrides invisible mouse" );
1720*cdf0e10cSrcweir             // enable user paint stroke width
1721*cdf0e10cSrcweir             maUserPaintStrokeWidth = nWidth;
1722*cdf0e10cSrcweir             maEventMultiplexer.notifyUserPaintStrokeWidth( maUserPaintStrokeWidth );
1723*cdf0e10cSrcweir         }
1724*cdf0e10cSrcweir 
1725*cdf0e10cSrcweir         return true;
1726*cdf0e10cSrcweir     }
1727*cdf0e10cSrcweir 
1728*cdf0e10cSrcweir     if (rProperty.Name.equalsAsciiL(
1729*cdf0e10cSrcweir             RTL_CONSTASCII_STRINGPARAM("AdvanceOnClick") ))
1730*cdf0e10cSrcweir     {
1731*cdf0e10cSrcweir         sal_Bool bAdvanceOnClick = sal_False;
1732*cdf0e10cSrcweir         if (! (rProperty.Value >>= bAdvanceOnClick))
1733*cdf0e10cSrcweir             return false;
1734*cdf0e10cSrcweir         maUserEventQueue.setAdvanceOnClick( bAdvanceOnClick );
1735*cdf0e10cSrcweir         return true;
1736*cdf0e10cSrcweir     }
1737*cdf0e10cSrcweir 
1738*cdf0e10cSrcweir     if (rProperty.Name.equalsAsciiL(
1739*cdf0e10cSrcweir             RTL_CONSTASCII_STRINGPARAM("DisableAnimationZOrder") ))
1740*cdf0e10cSrcweir     {
1741*cdf0e10cSrcweir         sal_Bool bDisableAnimationZOrder = sal_False;
1742*cdf0e10cSrcweir         if (! (rProperty.Value >>= bDisableAnimationZOrder))
1743*cdf0e10cSrcweir             return false;
1744*cdf0e10cSrcweir         mbDisableAnimationZOrder = bDisableAnimationZOrder == sal_True;
1745*cdf0e10cSrcweir         return true;
1746*cdf0e10cSrcweir     }
1747*cdf0e10cSrcweir 
1748*cdf0e10cSrcweir     if (rProperty.Name.equalsAsciiL(
1749*cdf0e10cSrcweir             RTL_CONSTASCII_STRINGPARAM("ImageAnimationsAllowed") ) )
1750*cdf0e10cSrcweir     {
1751*cdf0e10cSrcweir         if (! (rProperty.Value >>= mbImageAnimationsAllowed))
1752*cdf0e10cSrcweir             return false;
1753*cdf0e10cSrcweir 
1754*cdf0e10cSrcweir         // TODO(F3): Forward to slides!
1755*cdf0e10cSrcweir //         if( bOldValue != mbImageAnimationsAllowed )
1756*cdf0e10cSrcweir //         {
1757*cdf0e10cSrcweir //             if( mbImageAnimationsAllowed )
1758*cdf0e10cSrcweir //                 maEventMultiplexer.notifyIntrinsicAnimationsEnabled();
1759*cdf0e10cSrcweir //             else
1760*cdf0e10cSrcweir //                 maEventMultiplexer.notifyIntrinsicAnimationsDisabled();
1761*cdf0e10cSrcweir //         }
1762*cdf0e10cSrcweir 
1763*cdf0e10cSrcweir         return true;
1764*cdf0e10cSrcweir     }
1765*cdf0e10cSrcweir 
1766*cdf0e10cSrcweir     if (rProperty.Name.equalsAsciiL(
1767*cdf0e10cSrcweir             RTL_CONSTASCII_STRINGPARAM("MouseVisible") ))
1768*cdf0e10cSrcweir     {
1769*cdf0e10cSrcweir         if (! (rProperty.Value >>= mbMouseVisible))
1770*cdf0e10cSrcweir             return false;
1771*cdf0e10cSrcweir 
1772*cdf0e10cSrcweir         requestCursor(mnCurrentCursor);
1773*cdf0e10cSrcweir 
1774*cdf0e10cSrcweir         return true;
1775*cdf0e10cSrcweir     }
1776*cdf0e10cSrcweir 
1777*cdf0e10cSrcweir     if (rProperty.Name.equalsAsciiL(
1778*cdf0e10cSrcweir             RTL_CONSTASCII_STRINGPARAM("ForceManualAdvance") ))
1779*cdf0e10cSrcweir     {
1780*cdf0e10cSrcweir         return (rProperty.Value >>= mbForceManualAdvance);
1781*cdf0e10cSrcweir     }
1782*cdf0e10cSrcweir 
1783*cdf0e10cSrcweir     if (rProperty.Name.equalsAsciiL(
1784*cdf0e10cSrcweir             RTL_CONSTASCII_STRINGPARAM("RehearseTimings") ))
1785*cdf0e10cSrcweir     {
1786*cdf0e10cSrcweir         bool bRehearseTimings = false;
1787*cdf0e10cSrcweir         if (! (rProperty.Value >>= bRehearseTimings))
1788*cdf0e10cSrcweir             return false;
1789*cdf0e10cSrcweir 
1790*cdf0e10cSrcweir         if (bRehearseTimings)
1791*cdf0e10cSrcweir         {
1792*cdf0e10cSrcweir             // TODO(Q3): Move to slide
1793*cdf0e10cSrcweir             mpRehearseTimingsActivity = RehearseTimingsActivity::create(
1794*cdf0e10cSrcweir                 SlideShowContext(
1795*cdf0e10cSrcweir                     mpDummyPtr,
1796*cdf0e10cSrcweir                     maEventQueue,
1797*cdf0e10cSrcweir                     maEventMultiplexer,
1798*cdf0e10cSrcweir                     maScreenUpdater,
1799*cdf0e10cSrcweir                     maActivitiesQueue,
1800*cdf0e10cSrcweir                     maUserEventQueue,
1801*cdf0e10cSrcweir                     *this,
1802*cdf0e10cSrcweir                     maViewContainer,
1803*cdf0e10cSrcweir                     mxComponentContext) );
1804*cdf0e10cSrcweir         }
1805*cdf0e10cSrcweir         else if (mpRehearseTimingsActivity)
1806*cdf0e10cSrcweir         {
1807*cdf0e10cSrcweir             // removes timer from all views:
1808*cdf0e10cSrcweir             mpRehearseTimingsActivity->dispose();
1809*cdf0e10cSrcweir             mpRehearseTimingsActivity.reset();
1810*cdf0e10cSrcweir         }
1811*cdf0e10cSrcweir         return true;
1812*cdf0e10cSrcweir     }
1813*cdf0e10cSrcweir 
1814*cdf0e10cSrcweir     if (rProperty.Name.equalsAsciiL(
1815*cdf0e10cSrcweir             RTL_CONSTASCII_STRINGPARAM("WaitSymbolBitmap") ))
1816*cdf0e10cSrcweir     {
1817*cdf0e10cSrcweir         uno::Reference<rendering::XBitmap> xBitmap;
1818*cdf0e10cSrcweir         if (! (rProperty.Value >>= xBitmap))
1819*cdf0e10cSrcweir             return false;
1820*cdf0e10cSrcweir 
1821*cdf0e10cSrcweir         mpWaitSymbol = WaitSymbol::create( xBitmap,
1822*cdf0e10cSrcweir                                            maScreenUpdater,
1823*cdf0e10cSrcweir                                            maEventMultiplexer,
1824*cdf0e10cSrcweir                                            maViewContainer );
1825*cdf0e10cSrcweir 
1826*cdf0e10cSrcweir         return true;
1827*cdf0e10cSrcweir     }
1828*cdf0e10cSrcweir 
1829*cdf0e10cSrcweir     if (rProperty.Name.equalsAsciiL(
1830*cdf0e10cSrcweir             RTL_CONSTASCII_STRINGPARAM("NoSlideTransitions") ))
1831*cdf0e10cSrcweir     {
1832*cdf0e10cSrcweir         return (rProperty.Value >>= mbNoSlideTransitions);
1833*cdf0e10cSrcweir     }
1834*cdf0e10cSrcweir 
1835*cdf0e10cSrcweir     if (rProperty.Name.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("IsSoundEnabled")))
1836*cdf0e10cSrcweir     {
1837*cdf0e10cSrcweir         uno::Sequence<uno::Any> aValues;
1838*cdf0e10cSrcweir         uno::Reference<presentation::XSlideShowView> xView;
1839*cdf0e10cSrcweir         sal_Bool bValue (false);
1840*cdf0e10cSrcweir         if ((rProperty.Value >>= aValues)
1841*cdf0e10cSrcweir             && aValues.getLength()==2
1842*cdf0e10cSrcweir             && (aValues[0] >>= xView)
1843*cdf0e10cSrcweir             && (aValues[1] >>= bValue))
1844*cdf0e10cSrcweir         {
1845*cdf0e10cSrcweir             // Look up the view.
1846*cdf0e10cSrcweir             for (UnoViewVector::const_iterator
1847*cdf0e10cSrcweir                      iView (maViewContainer.begin()),
1848*cdf0e10cSrcweir                      iEnd (maViewContainer.end());
1849*cdf0e10cSrcweir                  iView!=iEnd;
1850*cdf0e10cSrcweir                  ++iView)
1851*cdf0e10cSrcweir             {
1852*cdf0e10cSrcweir                 if (*iView && (*iView)->getUnoView()==xView)
1853*cdf0e10cSrcweir                 {
1854*cdf0e10cSrcweir                     // Store the flag at the view so that media shapes have
1855*cdf0e10cSrcweir                     // access to it.
1856*cdf0e10cSrcweir                     (*iView)->setIsSoundEnabled(bValue);
1857*cdf0e10cSrcweir                     return true;
1858*cdf0e10cSrcweir                 }
1859*cdf0e10cSrcweir             }
1860*cdf0e10cSrcweir         }
1861*cdf0e10cSrcweir     }
1862*cdf0e10cSrcweir 
1863*cdf0e10cSrcweir     return false;
1864*cdf0e10cSrcweir }
1865*cdf0e10cSrcweir 
1866*cdf0e10cSrcweir void SlideShowImpl::addSlideShowListener(
1867*cdf0e10cSrcweir     uno::Reference<presentation::XSlideShowListener> const& xListener )
1868*cdf0e10cSrcweir     throw (uno::RuntimeException)
1869*cdf0e10cSrcweir {
1870*cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
1871*cdf0e10cSrcweir 
1872*cdf0e10cSrcweir     if (isDisposed())
1873*cdf0e10cSrcweir         return;
1874*cdf0e10cSrcweir 
1875*cdf0e10cSrcweir     // container syncs with passed mutex ref
1876*cdf0e10cSrcweir     maListenerContainer.addInterface(xListener);
1877*cdf0e10cSrcweir }
1878*cdf0e10cSrcweir 
1879*cdf0e10cSrcweir void SlideShowImpl::removeSlideShowListener(
1880*cdf0e10cSrcweir     uno::Reference<presentation::XSlideShowListener> const& xListener )
1881*cdf0e10cSrcweir     throw (uno::RuntimeException)
1882*cdf0e10cSrcweir {
1883*cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
1884*cdf0e10cSrcweir 
1885*cdf0e10cSrcweir     // container syncs with passed mutex ref
1886*cdf0e10cSrcweir     maListenerContainer.removeInterface(xListener);
1887*cdf0e10cSrcweir }
1888*cdf0e10cSrcweir 
1889*cdf0e10cSrcweir void SlideShowImpl::addShapeEventListener(
1890*cdf0e10cSrcweir     uno::Reference<presentation::XShapeEventListener> const& xListener,
1891*cdf0e10cSrcweir     uno::Reference<drawing::XShape> const& xShape )
1892*cdf0e10cSrcweir     throw (uno::RuntimeException)
1893*cdf0e10cSrcweir {
1894*cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
1895*cdf0e10cSrcweir 
1896*cdf0e10cSrcweir     if (isDisposed())
1897*cdf0e10cSrcweir         return;
1898*cdf0e10cSrcweir 
1899*cdf0e10cSrcweir     // precondition: must only be called from the main thread!
1900*cdf0e10cSrcweir     DBG_TESTSOLARMUTEX();
1901*cdf0e10cSrcweir 
1902*cdf0e10cSrcweir     ShapeEventListenerMap::iterator aIter;
1903*cdf0e10cSrcweir     if( (aIter=maShapeEventListeners.find( xShape )) ==
1904*cdf0e10cSrcweir         maShapeEventListeners.end() )
1905*cdf0e10cSrcweir     {
1906*cdf0e10cSrcweir         // no entry for this shape -> create one
1907*cdf0e10cSrcweir         aIter = maShapeEventListeners.insert(
1908*cdf0e10cSrcweir             ShapeEventListenerMap::value_type(
1909*cdf0e10cSrcweir                 xShape,
1910*cdf0e10cSrcweir                 boost::shared_ptr<cppu::OInterfaceContainerHelper>(
1911*cdf0e10cSrcweir                     new cppu::OInterfaceContainerHelper(m_aMutex)))).first;
1912*cdf0e10cSrcweir     }
1913*cdf0e10cSrcweir 
1914*cdf0e10cSrcweir     // add new listener to broadcaster
1915*cdf0e10cSrcweir     if( aIter->second.get() )
1916*cdf0e10cSrcweir         aIter->second->addInterface( xListener );
1917*cdf0e10cSrcweir 
1918*cdf0e10cSrcweir     maEventMultiplexer.notifyShapeListenerAdded(xListener,
1919*cdf0e10cSrcweir                                                 xShape);
1920*cdf0e10cSrcweir }
1921*cdf0e10cSrcweir 
1922*cdf0e10cSrcweir void SlideShowImpl::removeShapeEventListener(
1923*cdf0e10cSrcweir     uno::Reference<presentation::XShapeEventListener> const& xListener,
1924*cdf0e10cSrcweir     uno::Reference<drawing::XShape> const& xShape )
1925*cdf0e10cSrcweir     throw (uno::RuntimeException)
1926*cdf0e10cSrcweir {
1927*cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
1928*cdf0e10cSrcweir 
1929*cdf0e10cSrcweir     // precondition: must only be called from the main thread!
1930*cdf0e10cSrcweir     DBG_TESTSOLARMUTEX();
1931*cdf0e10cSrcweir 
1932*cdf0e10cSrcweir     ShapeEventListenerMap::iterator aIter;
1933*cdf0e10cSrcweir     if( (aIter = maShapeEventListeners.find( xShape )) !=
1934*cdf0e10cSrcweir         maShapeEventListeners.end() )
1935*cdf0e10cSrcweir     {
1936*cdf0e10cSrcweir         // entry for this shape found -> remove listener from
1937*cdf0e10cSrcweir         // helper object
1938*cdf0e10cSrcweir         ENSURE_OR_THROW(
1939*cdf0e10cSrcweir             aIter->second.get(),
1940*cdf0e10cSrcweir             "SlideShowImpl::removeShapeEventListener(): "
1941*cdf0e10cSrcweir             "listener map contains NULL broadcast helper" );
1942*cdf0e10cSrcweir 
1943*cdf0e10cSrcweir         aIter->second->removeInterface( xListener );
1944*cdf0e10cSrcweir     }
1945*cdf0e10cSrcweir 
1946*cdf0e10cSrcweir     maEventMultiplexer.notifyShapeListenerRemoved(xListener,
1947*cdf0e10cSrcweir                                                   xShape);
1948*cdf0e10cSrcweir }
1949*cdf0e10cSrcweir 
1950*cdf0e10cSrcweir void SlideShowImpl::setShapeCursor(
1951*cdf0e10cSrcweir     uno::Reference<drawing::XShape> const& xShape, sal_Int16 nPointerShape )
1952*cdf0e10cSrcweir     throw (uno::RuntimeException)
1953*cdf0e10cSrcweir {
1954*cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
1955*cdf0e10cSrcweir 
1956*cdf0e10cSrcweir     if (isDisposed())
1957*cdf0e10cSrcweir         return;
1958*cdf0e10cSrcweir 
1959*cdf0e10cSrcweir     // precondition: must only be called from the main thread!
1960*cdf0e10cSrcweir     DBG_TESTSOLARMUTEX();
1961*cdf0e10cSrcweir 
1962*cdf0e10cSrcweir     ShapeCursorMap::iterator aIter;
1963*cdf0e10cSrcweir     if( (aIter=maShapeCursors.find( xShape )) == maShapeCursors.end() )
1964*cdf0e10cSrcweir     {
1965*cdf0e10cSrcweir         // no entry for this shape -> create one
1966*cdf0e10cSrcweir         if( nPointerShape != awt::SystemPointer::ARROW )
1967*cdf0e10cSrcweir         {
1968*cdf0e10cSrcweir             // add new entry, unless shape shall display
1969*cdf0e10cSrcweir             // normal pointer arrow -> no need to handle that
1970*cdf0e10cSrcweir             // case
1971*cdf0e10cSrcweir             maShapeCursors.insert(
1972*cdf0e10cSrcweir                 ShapeCursorMap::value_type(xShape,
1973*cdf0e10cSrcweir                                            nPointerShape) );
1974*cdf0e10cSrcweir         }
1975*cdf0e10cSrcweir     }
1976*cdf0e10cSrcweir     else if( nPointerShape == awt::SystemPointer::ARROW )
1977*cdf0e10cSrcweir     {
1978*cdf0e10cSrcweir         // shape shall display normal cursor -> can disable
1979*cdf0e10cSrcweir         // the cursor and clear the entry
1980*cdf0e10cSrcweir         maShapeCursors.erase( xShape );
1981*cdf0e10cSrcweir     }
1982*cdf0e10cSrcweir     else
1983*cdf0e10cSrcweir     {
1984*cdf0e10cSrcweir         // existing entry found, update with new cursor ID
1985*cdf0e10cSrcweir         aIter->second = nPointerShape;
1986*cdf0e10cSrcweir     }
1987*cdf0e10cSrcweir 
1988*cdf0e10cSrcweir     maEventMultiplexer.notifyShapeCursorChange(xShape,
1989*cdf0e10cSrcweir                                                nPointerShape);
1990*cdf0e10cSrcweir }
1991*cdf0e10cSrcweir 
1992*cdf0e10cSrcweir bool SlideShowImpl::requestCursor( sal_Int16 nCursorShape )
1993*cdf0e10cSrcweir {
1994*cdf0e10cSrcweir     mnCurrentCursor = nCursorShape;
1995*cdf0e10cSrcweir 
1996*cdf0e10cSrcweir     const sal_Int16 nActualCursor = calcActiveCursor(mnCurrentCursor);
1997*cdf0e10cSrcweir 
1998*cdf0e10cSrcweir     // change all views to the requested cursor ID
1999*cdf0e10cSrcweir     std::for_each( maViewContainer.begin(),
2000*cdf0e10cSrcweir                    maViewContainer.end(),
2001*cdf0e10cSrcweir                    boost::bind( &View::setCursorShape,
2002*cdf0e10cSrcweir                                 _1,
2003*cdf0e10cSrcweir                                 nActualCursor ));
2004*cdf0e10cSrcweir 
2005*cdf0e10cSrcweir     return nActualCursor==nCursorShape;
2006*cdf0e10cSrcweir }
2007*cdf0e10cSrcweir 
2008*cdf0e10cSrcweir void SlideShowImpl::resetCursor()
2009*cdf0e10cSrcweir {
2010*cdf0e10cSrcweir     mnCurrentCursor = awt::SystemPointer::ARROW;
2011*cdf0e10cSrcweir 
2012*cdf0e10cSrcweir     // change all views to the default cursor ID
2013*cdf0e10cSrcweir     std::for_each( maViewContainer.begin(),
2014*cdf0e10cSrcweir                    maViewContainer.end(),
2015*cdf0e10cSrcweir                    boost::bind( &View::setCursorShape,
2016*cdf0e10cSrcweir                                 _1,
2017*cdf0e10cSrcweir                                 calcActiveCursor(mnCurrentCursor) ));
2018*cdf0e10cSrcweir }
2019*cdf0e10cSrcweir 
2020*cdf0e10cSrcweir sal_Bool SlideShowImpl::update( double & nNextTimeout )
2021*cdf0e10cSrcweir     throw (uno::RuntimeException)
2022*cdf0e10cSrcweir {
2023*cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
2024*cdf0e10cSrcweir 
2025*cdf0e10cSrcweir     if (isDisposed())
2026*cdf0e10cSrcweir         return false;
2027*cdf0e10cSrcweir 
2028*cdf0e10cSrcweir     // precondition: update() must only be called from the
2029*cdf0e10cSrcweir     // main thread!
2030*cdf0e10cSrcweir     DBG_TESTSOLARMUTEX();
2031*cdf0e10cSrcweir 
2032*cdf0e10cSrcweir     if( mbShowPaused )
2033*cdf0e10cSrcweir     {
2034*cdf0e10cSrcweir         // commit frame (might be repaints pending)
2035*cdf0e10cSrcweir         maScreenUpdater.commitUpdates();
2036*cdf0e10cSrcweir 
2037*cdf0e10cSrcweir         return false;
2038*cdf0e10cSrcweir     }
2039*cdf0e10cSrcweir     else
2040*cdf0e10cSrcweir     {
2041*cdf0e10cSrcweir         // TODO(F2): re-evaluate whether that timer lagging makes
2042*cdf0e10cSrcweir         // sense.
2043*cdf0e10cSrcweir 
2044*cdf0e10cSrcweir         // hold timer, while processing the queues:
2045*cdf0e10cSrcweir         // 1. when there is more than one active activity this ensures the
2046*cdf0e10cSrcweir         //    same time for all activities and events
2047*cdf0e10cSrcweir         // 2. processing of events may lead to creation of further events
2048*cdf0e10cSrcweir         //    that have zero delay.  While the timer is stopped these events
2049*cdf0e10cSrcweir         //    are processed in the same run.
2050*cdf0e10cSrcweir         {
2051*cdf0e10cSrcweir             comphelper::ScopeGuard scopeGuard(
2052*cdf0e10cSrcweir                 boost::bind( &canvas::tools::ElapsedTime::releaseTimer,
2053*cdf0e10cSrcweir                              boost::cref(mpPresTimer) ) );
2054*cdf0e10cSrcweir             mpPresTimer->holdTimer();
2055*cdf0e10cSrcweir 
2056*cdf0e10cSrcweir             // process queues
2057*cdf0e10cSrcweir             maEventQueue.process();
2058*cdf0e10cSrcweir             maActivitiesQueue.process();
2059*cdf0e10cSrcweir 
2060*cdf0e10cSrcweir             // commit frame to screen
2061*cdf0e10cSrcweir             maFrameSynchronization.Synchronize();
2062*cdf0e10cSrcweir             maScreenUpdater.commitUpdates();
2063*cdf0e10cSrcweir 
2064*cdf0e10cSrcweir             // TODO(Q3): remove need to call dequeued() from
2065*cdf0e10cSrcweir             // activities. feels like a wart.
2066*cdf0e10cSrcweir             //
2067*cdf0e10cSrcweir             // Rationale for ActivitiesQueue::processDequeued(): when
2068*cdf0e10cSrcweir             // an activity ends, it usually pushed the end state to
2069*cdf0e10cSrcweir             // the animated shape in question, and ends the animation
2070*cdf0e10cSrcweir             // (which, in turn, will usually disable shape sprite
2071*cdf0e10cSrcweir             // mode). Disabling shape sprite mode causes shape
2072*cdf0e10cSrcweir             // repaint, which, depending on slide content, takes
2073*cdf0e10cSrcweir             // considerably more time than sprite updates. Thus, the
2074*cdf0e10cSrcweir             // last animation step tends to look delayed. To
2075*cdf0e10cSrcweir             // camouflage this, reaching end position and disabling
2076*cdf0e10cSrcweir             // sprite mode is split into two (normal Activity::end(),
2077*cdf0e10cSrcweir             // and Activity::dequeued()). Now, the reason to call
2078*cdf0e10cSrcweir             // commitUpdates() twice here is caused by the unrelated
2079*cdf0e10cSrcweir             // fact that during wait cursor display/hide, the screen
2080*cdf0e10cSrcweir             // is updated, and shows hidden sprites, but, in case of
2081*cdf0e10cSrcweir             // leaving the second commitUpdates() call out and punting
2082*cdf0e10cSrcweir             // that to the next round, no updated static slide
2083*cdf0e10cSrcweir             // content. In short, the last shape animation of a slide
2084*cdf0e10cSrcweir             // tends to blink at its end.
2085*cdf0e10cSrcweir 
2086*cdf0e10cSrcweir             // process dequeued activities _after_ commit to screen
2087*cdf0e10cSrcweir             maActivitiesQueue.processDequeued();
2088*cdf0e10cSrcweir 
2089*cdf0e10cSrcweir             // commit frame to screen
2090*cdf0e10cSrcweir             maScreenUpdater.commitUpdates();
2091*cdf0e10cSrcweir         }
2092*cdf0e10cSrcweir         // Time held until here
2093*cdf0e10cSrcweir 
2094*cdf0e10cSrcweir         const bool bActivitiesLeft = (! maActivitiesQueue.isEmpty());
2095*cdf0e10cSrcweir         const bool bTimerEventsLeft = (! maEventQueue.isEmpty());
2096*cdf0e10cSrcweir         const bool bRet = (bActivitiesLeft || bTimerEventsLeft);
2097*cdf0e10cSrcweir 
2098*cdf0e10cSrcweir         if (bRet)
2099*cdf0e10cSrcweir         {
2100*cdf0e10cSrcweir             // calc nNextTimeout value:
2101*cdf0e10cSrcweir             if (bActivitiesLeft)
2102*cdf0e10cSrcweir             {
2103*cdf0e10cSrcweir                 // Activity queue is not empty.  Tell caller that we would
2104*cdf0e10cSrcweir                 // like to render another frame.
2105*cdf0e10cSrcweir 
2106*cdf0e10cSrcweir                 // Return a zero time-out to signal our caller to call us
2107*cdf0e10cSrcweir                 // back as soon as possible.  The actual timing, waiting the
2108*cdf0e10cSrcweir                 // appropriate amount of time between frames, is then done
2109*cdf0e10cSrcweir                 // by the maFrameSynchronization object.
2110*cdf0e10cSrcweir                 nNextTimeout = 0;
2111*cdf0e10cSrcweir                 maFrameSynchronization.Activate();
2112*cdf0e10cSrcweir             }
2113*cdf0e10cSrcweir             else
2114*cdf0e10cSrcweir             {
2115*cdf0e10cSrcweir                 // timer events left:
2116*cdf0e10cSrcweir                 // difference from current time (nota bene:
2117*cdf0e10cSrcweir                 // time no longer held here!) to the next event in
2118*cdf0e10cSrcweir                 // the event queue.
2119*cdf0e10cSrcweir 
2120*cdf0e10cSrcweir                 // #i61190# Retrieve next timeout only _after_
2121*cdf0e10cSrcweir                 // processing activity queue
2122*cdf0e10cSrcweir 
2123*cdf0e10cSrcweir                 // ensure positive value:
2124*cdf0e10cSrcweir                 nNextTimeout = std::max( 0.0, maEventQueue.nextTimeout() );
2125*cdf0e10cSrcweir 
2126*cdf0e10cSrcweir                 // There is no active animation so the frame rate does not
2127*cdf0e10cSrcweir                 // need to be synchronized.
2128*cdf0e10cSrcweir                 maFrameSynchronization.Deactivate();
2129*cdf0e10cSrcweir             }
2130*cdf0e10cSrcweir 
2131*cdf0e10cSrcweir             mbSlideShowIdle = false;
2132*cdf0e10cSrcweir         }
2133*cdf0e10cSrcweir 
2134*cdf0e10cSrcweir #if defined(VERBOSE) && defined(DBG_UTIL)
2135*cdf0e10cSrcweir         // when slideshow is idle, issue an XUpdatable::update() call
2136*cdf0e10cSrcweir         // exactly once after a previous animation sequence finished -
2137*cdf0e10cSrcweir         // this might trigger screen dumps on some canvas
2138*cdf0e10cSrcweir         // implementations
2139*cdf0e10cSrcweir         if( !mbSlideShowIdle &&
2140*cdf0e10cSrcweir             (!bRet ||
2141*cdf0e10cSrcweir              nNextTimeout > 1.0) )
2142*cdf0e10cSrcweir         {
2143*cdf0e10cSrcweir             UnoViewVector::const_iterator       aCurr(maViewContainer.begin());
2144*cdf0e10cSrcweir             const UnoViewVector::const_iterator aEnd(maViewContainer.end());
2145*cdf0e10cSrcweir             while( aCurr != aEnd )
2146*cdf0e10cSrcweir             {
2147*cdf0e10cSrcweir                 try
2148*cdf0e10cSrcweir                 {
2149*cdf0e10cSrcweir                     uno::Reference< presentation::XSlideShowView > xView( (*aCurr)->getUnoView(),
2150*cdf0e10cSrcweir                                                                           uno::UNO_QUERY_THROW );
2151*cdf0e10cSrcweir                     uno::Reference< util::XUpdatable >             xUpdatable( xView->getCanvas(),
2152*cdf0e10cSrcweir                                                                                uno::UNO_QUERY_THROW );
2153*cdf0e10cSrcweir                     xUpdatable->update();
2154*cdf0e10cSrcweir                 }
2155*cdf0e10cSrcweir                 catch( uno::RuntimeException& )
2156*cdf0e10cSrcweir                 {
2157*cdf0e10cSrcweir                     throw;
2158*cdf0e10cSrcweir                 }
2159*cdf0e10cSrcweir                 catch( uno::Exception& )
2160*cdf0e10cSrcweir                 {
2161*cdf0e10cSrcweir                     OSL_ENSURE( false,
2162*cdf0e10cSrcweir                                 rtl::OUStringToOString(
2163*cdf0e10cSrcweir                                     comphelper::anyToString( cppu::getCaughtException() ),
2164*cdf0e10cSrcweir                                     RTL_TEXTENCODING_UTF8 ).getStr() );
2165*cdf0e10cSrcweir                 }
2166*cdf0e10cSrcweir 
2167*cdf0e10cSrcweir                 ++aCurr;
2168*cdf0e10cSrcweir             }
2169*cdf0e10cSrcweir 
2170*cdf0e10cSrcweir             mbSlideShowIdle = true;
2171*cdf0e10cSrcweir         }
2172*cdf0e10cSrcweir #endif
2173*cdf0e10cSrcweir 
2174*cdf0e10cSrcweir         return bRet;
2175*cdf0e10cSrcweir     }
2176*cdf0e10cSrcweir }
2177*cdf0e10cSrcweir 
2178*cdf0e10cSrcweir void SlideShowImpl::notifySlideTransitionEnded( bool bPaintSlide )
2179*cdf0e10cSrcweir {
2180*cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
2181*cdf0e10cSrcweir 
2182*cdf0e10cSrcweir     OSL_ENSURE( !isDisposed(), "### already disposed!" );
2183*cdf0e10cSrcweir     OSL_ENSURE( mpCurrentSlide,
2184*cdf0e10cSrcweir                 "notifySlideTransitionEnded(): Invalid current slide" );
2185*cdf0e10cSrcweir     if (mpCurrentSlide)
2186*cdf0e10cSrcweir     {
2187*cdf0e10cSrcweir 		mpCurrentSlide->update_settings( !!maUserPaintColor, maUserPaintColor ? *maUserPaintColor : RGBColor(), maUserPaintStrokeWidth );
2188*cdf0e10cSrcweir 
2189*cdf0e10cSrcweir 		// first init show, to give the animations
2190*cdf0e10cSrcweir         // the chance to register SlideStartEvents
2191*cdf0e10cSrcweir         const bool bBackgroundLayerRendered( !bPaintSlide );
2192*cdf0e10cSrcweir         mpCurrentSlide->show( bBackgroundLayerRendered );
2193*cdf0e10cSrcweir         maEventMultiplexer.notifySlideStartEvent();
2194*cdf0e10cSrcweir     }
2195*cdf0e10cSrcweir }
2196*cdf0e10cSrcweir 
2197*cdf0e10cSrcweir void queryAutomaticSlideTransition( uno::Reference<drawing::XDrawPage> const& xDrawPage,
2198*cdf0e10cSrcweir                                     double&                                   nAutomaticNextSlideTimeout,
2199*cdf0e10cSrcweir                                     bool&                                     bHasAutomaticNextSlide )
2200*cdf0e10cSrcweir {
2201*cdf0e10cSrcweir     // retrieve slide change parameters from XDrawPage
2202*cdf0e10cSrcweir     // ===============================================
2203*cdf0e10cSrcweir 
2204*cdf0e10cSrcweir     uno::Reference< beans::XPropertySet > xPropSet( xDrawPage,
2205*cdf0e10cSrcweir                                                     uno::UNO_QUERY );
2206*cdf0e10cSrcweir 
2207*cdf0e10cSrcweir     sal_Int32 nChange(0);
2208*cdf0e10cSrcweir     if( !xPropSet.is() ||
2209*cdf0e10cSrcweir         !getPropertyValue( nChange,
2210*cdf0e10cSrcweir                            xPropSet,
2211*cdf0e10cSrcweir                            ::rtl::OUString(
2212*cdf0e10cSrcweir                                RTL_CONSTASCII_USTRINGPARAM("Change"))) )
2213*cdf0e10cSrcweir     {
2214*cdf0e10cSrcweir         OSL_TRACE(
2215*cdf0e10cSrcweir             "queryAutomaticSlideTransition(): "
2216*cdf0e10cSrcweir             "Could not extract slide change mode from XDrawPage - assuming <none>\n" );
2217*cdf0e10cSrcweir     }
2218*cdf0e10cSrcweir 
2219*cdf0e10cSrcweir     bHasAutomaticNextSlide = nChange == 1;
2220*cdf0e10cSrcweir 
2221*cdf0e10cSrcweir     if( !xPropSet.is() ||
2222*cdf0e10cSrcweir         !getPropertyValue( nAutomaticNextSlideTimeout,
2223*cdf0e10cSrcweir                            xPropSet,
2224*cdf0e10cSrcweir                            ::rtl::OUString(
2225*cdf0e10cSrcweir                                RTL_CONSTASCII_USTRINGPARAM("Duration"))) )
2226*cdf0e10cSrcweir     {
2227*cdf0e10cSrcweir         OSL_TRACE(
2228*cdf0e10cSrcweir             "queryAutomaticSlideTransition(): "
2229*cdf0e10cSrcweir             "Could not extract slide transition timeout from "
2230*cdf0e10cSrcweir             "XDrawPage - assuming 1 sec\n" );
2231*cdf0e10cSrcweir     }
2232*cdf0e10cSrcweir }
2233*cdf0e10cSrcweir 
2234*cdf0e10cSrcweir void SlideShowImpl::notifySlideAnimationsEnded()
2235*cdf0e10cSrcweir {
2236*cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
2237*cdf0e10cSrcweir 
2238*cdf0e10cSrcweir     //Draw polygons above animations
2239*cdf0e10cSrcweir     mpCurrentSlide->drawPolygons();
2240*cdf0e10cSrcweir 
2241*cdf0e10cSrcweir     OSL_ENSURE( !isDisposed(), "### already disposed!" );
2242*cdf0e10cSrcweir 
2243*cdf0e10cSrcweir     // This struct will receive the (interruptable) event,
2244*cdf0e10cSrcweir     // that triggers the notifySlideEnded() method.
2245*cdf0e10cSrcweir     InterruptableEventPair aNotificationEvents;
2246*cdf0e10cSrcweir 
2247*cdf0e10cSrcweir     if( maEventMultiplexer.getAutomaticMode() )
2248*cdf0e10cSrcweir     {
2249*cdf0e10cSrcweir         OSL_ENSURE( ! mpRehearseTimingsActivity,
2250*cdf0e10cSrcweir                     "unexpected: RehearseTimings mode!" );
2251*cdf0e10cSrcweir 
2252*cdf0e10cSrcweir         // schedule a slide end event, with automatic mode's
2253*cdf0e10cSrcweir         // delay
2254*cdf0e10cSrcweir         aNotificationEvents = makeInterruptableDelay(
2255*cdf0e10cSrcweir             boost::bind<void>( boost::mem_fn(&SlideShowImpl::notifySlideEnded), this, false ),
2256*cdf0e10cSrcweir             maEventMultiplexer.getAutomaticTimeout() );
2257*cdf0e10cSrcweir     }
2258*cdf0e10cSrcweir     else
2259*cdf0e10cSrcweir     {
2260*cdf0e10cSrcweir         OSL_ENSURE( mpCurrentSlide,
2261*cdf0e10cSrcweir                     "notifySlideAnimationsEnded(): Invalid current slide!" );
2262*cdf0e10cSrcweir 
2263*cdf0e10cSrcweir         bool   bHasAutomaticNextSlide=false;
2264*cdf0e10cSrcweir         double nAutomaticNextSlideTimeout=0.0;
2265*cdf0e10cSrcweir         queryAutomaticSlideTransition(mpCurrentSlide->getXDrawPage(),
2266*cdf0e10cSrcweir                                       nAutomaticNextSlideTimeout,
2267*cdf0e10cSrcweir                                       bHasAutomaticNextSlide);
2268*cdf0e10cSrcweir 
2269*cdf0e10cSrcweir         // check whether slide transition should happen
2270*cdf0e10cSrcweir         // 'automatically'. If yes, simply schedule the
2271*cdf0e10cSrcweir         // specified timeout.
2272*cdf0e10cSrcweir         // NOTE: mbForceManualAdvance and mpRehearseTimingsActivity
2273*cdf0e10cSrcweir         // override any individual slide setting, to always
2274*cdf0e10cSrcweir         // step slides manually.
2275*cdf0e10cSrcweir         if( !mbForceManualAdvance &&
2276*cdf0e10cSrcweir             !mpRehearseTimingsActivity &&
2277*cdf0e10cSrcweir             bHasAutomaticNextSlide )
2278*cdf0e10cSrcweir         {
2279*cdf0e10cSrcweir             aNotificationEvents = makeInterruptableDelay(
2280*cdf0e10cSrcweir                 boost::bind<void>( boost::mem_fn(&SlideShowImpl::notifySlideEnded), this, false ),
2281*cdf0e10cSrcweir                 nAutomaticNextSlideTimeout);
2282*cdf0e10cSrcweir 
2283*cdf0e10cSrcweir             // TODO(F2): Provide a mechanism to let the user override
2284*cdf0e10cSrcweir             // this automatic timeout via next()
2285*cdf0e10cSrcweir         }
2286*cdf0e10cSrcweir         else
2287*cdf0e10cSrcweir         {
2288*cdf0e10cSrcweir             if (mpRehearseTimingsActivity)
2289*cdf0e10cSrcweir                 mpRehearseTimingsActivity->start();
2290*cdf0e10cSrcweir 
2291*cdf0e10cSrcweir             // generate click event. Thus, the user must
2292*cdf0e10cSrcweir             // trigger the actual end of a slide. No need to
2293*cdf0e10cSrcweir             // generate interruptable event here, there's no
2294*cdf0e10cSrcweir             // timeout involved.
2295*cdf0e10cSrcweir             aNotificationEvents.mpImmediateEvent =
2296*cdf0e10cSrcweir                 makeEvent( boost::bind<void>(
2297*cdf0e10cSrcweir                     boost::mem_fn(&SlideShowImpl::notifySlideEnded), this, false ),
2298*cdf0e10cSrcweir                     "SlideShowImpl::notifySlideEnded");
2299*cdf0e10cSrcweir         }
2300*cdf0e10cSrcweir     }
2301*cdf0e10cSrcweir 
2302*cdf0e10cSrcweir     // register events on the queues. To make automatic slide
2303*cdf0e10cSrcweir     // changes interruptable, register the interruption event
2304*cdf0e10cSrcweir     // as a nextEffectEvent target. Note that the timeout
2305*cdf0e10cSrcweir     // event is optional (e.g. manual slide changes don't
2306*cdf0e10cSrcweir     // generate a timeout)
2307*cdf0e10cSrcweir     maUserEventQueue.registerNextEffectEvent(
2308*cdf0e10cSrcweir         aNotificationEvents.mpImmediateEvent );
2309*cdf0e10cSrcweir 
2310*cdf0e10cSrcweir     if( aNotificationEvents.mpTimeoutEvent )
2311*cdf0e10cSrcweir         maEventQueue.addEvent( aNotificationEvents.mpTimeoutEvent );
2312*cdf0e10cSrcweir 
2313*cdf0e10cSrcweir     // current slide's main sequence is over. Now should be
2314*cdf0e10cSrcweir     // the time to prefetch the next slide (if any), and
2315*cdf0e10cSrcweir     // prepare the initial slide bitmap (speeds up slide
2316*cdf0e10cSrcweir     // change setup time a lot). Show the wait cursor, this
2317*cdf0e10cSrcweir     // indeed might take some seconds.
2318*cdf0e10cSrcweir     {
2319*cdf0e10cSrcweir         WaitSymbolLock aLock (*this);
2320*cdf0e10cSrcweir 
2321*cdf0e10cSrcweir         if (! matches( mpPrefetchSlide,
2322*cdf0e10cSrcweir                        mxPrefetchSlide, mxPrefetchAnimationNode ))
2323*cdf0e10cSrcweir         {
2324*cdf0e10cSrcweir             mpPrefetchSlide = makeSlide( mxPrefetchSlide, mxDrawPagesSupplier,
2325*cdf0e10cSrcweir                                          mxPrefetchAnimationNode );
2326*cdf0e10cSrcweir         }
2327*cdf0e10cSrcweir         if (mpPrefetchSlide)
2328*cdf0e10cSrcweir         {
2329*cdf0e10cSrcweir             // ignore return value, this is just to populate
2330*cdf0e10cSrcweir             // Slide's internal bitmap buffer, such that the time
2331*cdf0e10cSrcweir             // needed to generate the slide bitmap is not spent
2332*cdf0e10cSrcweir             // when the slide change is requested.
2333*cdf0e10cSrcweir             mpPrefetchSlide->getCurrentSlideBitmap( *maViewContainer.begin() );
2334*cdf0e10cSrcweir         }
2335*cdf0e10cSrcweir     } // finally
2336*cdf0e10cSrcweir 
2337*cdf0e10cSrcweir     maListenerContainer.forEach<presentation::XSlideShowListener>(
2338*cdf0e10cSrcweir         boost::mem_fn( &presentation::XSlideShowListener::slideAnimationsEnded ) );
2339*cdf0e10cSrcweir }
2340*cdf0e10cSrcweir 
2341*cdf0e10cSrcweir void SlideShowImpl::notifySlideEnded (const bool bReverse)
2342*cdf0e10cSrcweir {
2343*cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
2344*cdf0e10cSrcweir 
2345*cdf0e10cSrcweir     OSL_ENSURE( !isDisposed(), "### already disposed!" );
2346*cdf0e10cSrcweir 
2347*cdf0e10cSrcweir     if (mpRehearseTimingsActivity && !bReverse)
2348*cdf0e10cSrcweir     {
2349*cdf0e10cSrcweir         const double time = mpRehearseTimingsActivity->stop();
2350*cdf0e10cSrcweir         if (mpRehearseTimingsActivity->hasBeenClicked())
2351*cdf0e10cSrcweir         {
2352*cdf0e10cSrcweir             // save time at current drawpage:
2353*cdf0e10cSrcweir             uno::Reference<beans::XPropertySet> xPropSet(
2354*cdf0e10cSrcweir                 mpCurrentSlide->getXDrawPage(), uno::UNO_QUERY );
2355*cdf0e10cSrcweir             OSL_ASSERT( xPropSet.is() );
2356*cdf0e10cSrcweir             if (xPropSet.is())
2357*cdf0e10cSrcweir             {
2358*cdf0e10cSrcweir                 xPropSet->setPropertyValue(
2359*cdf0e10cSrcweir                     OUSTR("Change"),
2360*cdf0e10cSrcweir                     uno::Any( static_cast<sal_Int32>(1) ) );
2361*cdf0e10cSrcweir                 xPropSet->setPropertyValue(
2362*cdf0e10cSrcweir                     OUSTR("Duration"),
2363*cdf0e10cSrcweir                     uno::Any( static_cast<sal_Int32>(time) ) );
2364*cdf0e10cSrcweir             }
2365*cdf0e10cSrcweir         }
2366*cdf0e10cSrcweir     }
2367*cdf0e10cSrcweir 
2368*cdf0e10cSrcweir     if (bReverse)
2369*cdf0e10cSrcweir         maEventMultiplexer.notifySlideEndEvent();
2370*cdf0e10cSrcweir 
2371*cdf0e10cSrcweir     stopShow();  // MUST call that: results in
2372*cdf0e10cSrcweir                  // maUserEventQueue.clear(). What's more,
2373*cdf0e10cSrcweir                  // stopShow()'s currSlide->hide() call is
2374*cdf0e10cSrcweir                  // now also required, notifySlideEnded()
2375*cdf0e10cSrcweir                  // relies on that
2376*cdf0e10cSrcweir                  // unconditionally. Otherwise, genuine
2377*cdf0e10cSrcweir                  // shape animations (drawing layer and
2378*cdf0e10cSrcweir                  // GIF) will not be stopped.
2379*cdf0e10cSrcweir 
2380*cdf0e10cSrcweir     maListenerContainer.forEach<presentation::XSlideShowListener>(
2381*cdf0e10cSrcweir         boost::bind<void>(
2382*cdf0e10cSrcweir             ::boost::mem_fn(&presentation::XSlideShowListener::slideEnded),
2383*cdf0e10cSrcweir             _1,
2384*cdf0e10cSrcweir             sal_Bool(bReverse)));
2385*cdf0e10cSrcweir }
2386*cdf0e10cSrcweir 
2387*cdf0e10cSrcweir bool SlideShowImpl::notifyHyperLinkClicked( rtl::OUString const& hyperLink )
2388*cdf0e10cSrcweir {
2389*cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
2390*cdf0e10cSrcweir 
2391*cdf0e10cSrcweir     maListenerContainer.forEach<presentation::XSlideShowListener>(
2392*cdf0e10cSrcweir         boost::bind( &presentation::XSlideShowListener::hyperLinkClicked,
2393*cdf0e10cSrcweir                      _1,
2394*cdf0e10cSrcweir                      boost::cref(hyperLink) ));
2395*cdf0e10cSrcweir     return true;
2396*cdf0e10cSrcweir }
2397*cdf0e10cSrcweir 
2398*cdf0e10cSrcweir /** Notification from eventmultiplexer that an animation event has occoured.
2399*cdf0e10cSrcweir 	This will be forewarded to all registered XSlideShoeListener
2400*cdf0e10cSrcweir  */
2401*cdf0e10cSrcweir bool SlideShowImpl::handleAnimationEvent( const AnimationNodeSharedPtr& rNode )
2402*cdf0e10cSrcweir {
2403*cdf0e10cSrcweir     osl::MutexGuard const guard( m_aMutex );
2404*cdf0e10cSrcweir 
2405*cdf0e10cSrcweir 	uno::Reference<animations::XAnimationNode> xNode( rNode->getXAnimationNode() );
2406*cdf0e10cSrcweir 
2407*cdf0e10cSrcweir 	switch( rNode->getState() )
2408*cdf0e10cSrcweir 	{
2409*cdf0e10cSrcweir 	case AnimationNode::ACTIVE:
2410*cdf0e10cSrcweir 	    maListenerContainer.forEach<presentation::XSlideShowListener>(
2411*cdf0e10cSrcweir 		    boost::bind( &animations::XAnimationListener::beginEvent,
2412*cdf0e10cSrcweir 			             _1,
2413*cdf0e10cSrcweir 				         boost::cref(xNode) ));
2414*cdf0e10cSrcweir 		break;
2415*cdf0e10cSrcweir 
2416*cdf0e10cSrcweir 	case AnimationNode::FROZEN:
2417*cdf0e10cSrcweir 	case AnimationNode::ENDED:
2418*cdf0e10cSrcweir 	    maListenerContainer.forEach<presentation::XSlideShowListener>(
2419*cdf0e10cSrcweir 		    boost::bind( &animations::XAnimationListener::endEvent,
2420*cdf0e10cSrcweir 			             _1,
2421*cdf0e10cSrcweir 				         boost::cref(xNode) ));
2422*cdf0e10cSrcweir         if(mpCurrentSlide->isPaintOverlayActive())
2423*cdf0e10cSrcweir            mpCurrentSlide->drawPolygons();
2424*cdf0e10cSrcweir 		break;
2425*cdf0e10cSrcweir 	default:
2426*cdf0e10cSrcweir 		break;
2427*cdf0e10cSrcweir 	}
2428*cdf0e10cSrcweir 
2429*cdf0e10cSrcweir 	return true;
2430*cdf0e10cSrcweir }
2431*cdf0e10cSrcweir 
2432*cdf0e10cSrcweir 
2433*cdf0e10cSrcweir //===== FrameSynchronization ==================================================
2434*cdf0e10cSrcweir 
2435*cdf0e10cSrcweir FrameSynchronization::FrameSynchronization (const double nFrameDuration)
2436*cdf0e10cSrcweir     : maTimer(),
2437*cdf0e10cSrcweir       mnFrameDuration(nFrameDuration),
2438*cdf0e10cSrcweir       mnNextFrameTargetTime(0),
2439*cdf0e10cSrcweir       mbIsActive(false)
2440*cdf0e10cSrcweir {
2441*cdf0e10cSrcweir     MarkCurrentFrame();
2442*cdf0e10cSrcweir }
2443*cdf0e10cSrcweir 
2444*cdf0e10cSrcweir 
2445*cdf0e10cSrcweir 
2446*cdf0e10cSrcweir 
2447*cdf0e10cSrcweir void FrameSynchronization::MarkCurrentFrame (void)
2448*cdf0e10cSrcweir {
2449*cdf0e10cSrcweir     mnNextFrameTargetTime = maTimer.getElapsedTime() + mnFrameDuration;
2450*cdf0e10cSrcweir }
2451*cdf0e10cSrcweir 
2452*cdf0e10cSrcweir 
2453*cdf0e10cSrcweir 
2454*cdf0e10cSrcweir 
2455*cdf0e10cSrcweir void FrameSynchronization::Synchronize (void)
2456*cdf0e10cSrcweir {
2457*cdf0e10cSrcweir     if (mbIsActive)
2458*cdf0e10cSrcweir     {
2459*cdf0e10cSrcweir         // Do busy waiting for now.
2460*cdf0e10cSrcweir         while (maTimer.getElapsedTime() < mnNextFrameTargetTime)
2461*cdf0e10cSrcweir             ;
2462*cdf0e10cSrcweir     }
2463*cdf0e10cSrcweir 
2464*cdf0e10cSrcweir     MarkCurrentFrame();
2465*cdf0e10cSrcweir }
2466*cdf0e10cSrcweir 
2467*cdf0e10cSrcweir 
2468*cdf0e10cSrcweir 
2469*cdf0e10cSrcweir 
2470*cdf0e10cSrcweir void FrameSynchronization::Activate (void)
2471*cdf0e10cSrcweir {
2472*cdf0e10cSrcweir     mbIsActive = true;
2473*cdf0e10cSrcweir }
2474*cdf0e10cSrcweir 
2475*cdf0e10cSrcweir 
2476*cdf0e10cSrcweir 
2477*cdf0e10cSrcweir 
2478*cdf0e10cSrcweir void FrameSynchronization::Deactivate (void)
2479*cdf0e10cSrcweir {
2480*cdf0e10cSrcweir     mbIsActive = false;
2481*cdf0e10cSrcweir }
2482*cdf0e10cSrcweir 
2483*cdf0e10cSrcweir 
2484*cdf0e10cSrcweir 
2485*cdf0e10cSrcweir 
2486*cdf0e10cSrcweir double FrameSynchronization::GetCurrentTime (void) const
2487*cdf0e10cSrcweir {
2488*cdf0e10cSrcweir     return maTimer.getElapsedTime();
2489*cdf0e10cSrcweir }
2490*cdf0e10cSrcweir 
2491*cdf0e10cSrcweir 
2492*cdf0e10cSrcweir } // anon namespace
2493*cdf0e10cSrcweir 
2494*cdf0e10cSrcweir namespace sdecl = comphelper::service_decl;
2495*cdf0e10cSrcweir #if defined (__GNUC__) && (__GNUC__ == 3 && __GNUC_MINOR__ <= 3)
2496*cdf0e10cSrcweir  sdecl::class_<SlideShowImpl> serviceImpl;
2497*cdf0e10cSrcweir  const sdecl::ServiceDecl slideShowDecl(
2498*cdf0e10cSrcweir      serviceImpl,
2499*cdf0e10cSrcweir #else
2500*cdf0e10cSrcweir  const sdecl::ServiceDecl slideShowDecl(
2501*cdf0e10cSrcweir      sdecl::class_<SlideShowImpl>(),
2502*cdf0e10cSrcweir #endif
2503*cdf0e10cSrcweir     "com.sun.star.comp.presentation.SlideShow",
2504*cdf0e10cSrcweir     "com.sun.star.presentation.SlideShow" );
2505*cdf0e10cSrcweir 
2506*cdf0e10cSrcweir // The C shared lib entry points
2507*cdf0e10cSrcweir COMPHELPER_SERVICEDECL_EXPORTS1(slideShowDecl)
2508*cdf0e10cSrcweir 
2509