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