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