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