1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef INCLUDED_SLIDESHOW_EFFECT_REWINDER_HXX
29 #define INCLUDED_SLIDESHOW_EFFECT_REWINDER_HXX
30 
31 #include "animationnode.hxx"
32 #include "eventhandler.hxx"
33 #include "animationeventhandler.hxx"
34 #include "event.hxx"
35 #include "screenupdater.hxx"
36 
37 #include <com/sun/star/presentation/XSlideShow.hpp>
38 #include <boost/scoped_ptr.hpp>
39 #include <boost/function.hpp>
40 #include <vector>
41 
42 namespace css = ::com::sun::star;
43 
44 namespace slideshow { namespace internal {
45 
46 class EventMultiplexer;
47 class EventQueue;
48 class UserEventQueue;
49 
50 /** Rewind single effects of the main effect sequence.  A rewind is
51     initiated by calling the Rewind() method.  Part of the processing is
52     done asynchronously.  Multiple EventQueue::update() calls may be
53     necessary to finish a rewind.
54 
55     Remember to call SetRootAnimationNode() when switching to a different
56     slide so that the EffectRewinder can determine the number of main
57     sequence effects.
58 */
59 class EffectRewinder
60 {
61 public:
62     EffectRewinder (
63         EventMultiplexer& rEventMultiplexer,
64         EventQueue& rEventQueue,
65         UserEventQueue& rUserEventQueue);
66     ~EffectRewinder (void);
67 
68     /** Call Dispose() before the ownder of an EffectRewinder object dies so
69         that the EffectRewinder can release all references to the owner.
70 
71     */
72     void dispose (void);
73 
74     /** Store the root node of the animation tree.  It is used in
75         CountMainSequenceEffects() to count the number of main sequence
76         effects (or effect groups.)
77     */
78     void setRootAnimationNode (
79         const css::uno::Reference<css::animations::XAnimationNode>& xRootNode);
80 
81     /** Rewind one effect of the main effect sequence.  When the current
82         slide has not effects or no main sequence effect has yet been played
83         then switch to the previous slide and replay all of its main
84         sequence effects.
85         The caller has to pass two functors that redisplay the current slide
86         or switch to the previous slide so that it does not have to expose
87         its internals to us.  Only one of the two functors is called.
88         @param rpPaintLock
89             This paint lock is released after the whole asynchronous
90             procoess  of rewinding the current effect is completed.  It
91             prevents intermediate repaints  that would show partial replay
92             of effects.
93         @param rSlideRewindFunctor
94             This functor is called when the current slide is to be
95             redisplayed.  When it is called then the other functor is not
96             called.
97         @param rPreviousSlideFunctor
98             This functor is called to switch to the previous slide.  When it
99             is called then the other functor is not called.
100     */
101     bool rewind (
102         const ::boost::shared_ptr<ScreenUpdater::UpdateLock>& rpPaintLock,
103         const ::boost::function<void(void)>& rSlideRewindFunctor,
104         const ::boost::function<void(void)>& rPreviousSlideFunctor);
105 
106     /** Call this method after gotoPreviousEffect() triggered a slide change
107         to the previous slide.
108     */
109     void skipAllMainSequenceEffects (void);
110 
111 private:
112     EventMultiplexer& mrEventMultiplexer;
113     EventQueue& mrEventQueue;
114     UserEventQueue& mrUserEventQueue;
115 
116     EventHandlerSharedPtr mpSlideStartHandler;
117     EventHandlerSharedPtr mpSlideEndHandler;
118     AnimationEventHandlerSharedPtr mpAnimationStartHandler;
119 
120     /** The number off main sequence effects so far.
121     */
122     sal_Int32 mnMainSequenceEffectCount;
123 
124     /** This is the currently scheduled event that executes the asynchronous
125         part of the effect rewinding.  It is also used as flag that prevents
126         nested rewinds.
127     */
128     EventSharedPtr mpAsynchronousRewindEvent;
129 
130     css::uno::Reference<css::animations::XAnimationNode> mxCurrentAnimationRootNode;
131     ::boost::shared_ptr<ScreenUpdater::UpdateLock> mpPaintLock;
132 
133     bool mbNonUserTriggeredMainSequenceEffectSeen;
134 
135     void initialize (void);
136 
137     bool resetEffectCount (void);
138     /** Called by listeners when an animation (not necessarily of a main
139         sequence effect) starts.
140     */
141     bool notifyAnimationStart (const AnimationNodeSharedPtr& rpNode);
142 
143     /** Count the number of effects (or effect groups) in the main effect
144         sequence.
145     */
146     sal_Int32 countMainSequenceEffects (void);
147 
148     /** Skip the next main sequence effect.
149     */
150     void skipSingleMainSequenceEffects (void);
151 
152     /** Skip the specified number of main sequence effects.
153     */
154     void skipSomeMainSequenceEffects (const sal_Int32 nSkipCount);
155 
156     /** Rewind the last effect of the main effect sequence by replaying all
157         previous effects.
158         @param nEffectCount
159             The number of main sequence effects to replay.
160         @param bRedisplayCurrentSlide
161             When <TRUE/> then the current slide is redisplayed before the
162             effects are replayed.
163         @param rSlideRewindFunctor
164             This functor is used to redisplay the current slide.
165     */
166     void asynchronousRewind (
167         sal_Int32 nEffectCount,
168         const bool bRedisplayCurrentSlide,
169         const boost::function<void(void)>& rSlideRewindFunctor);
170 
171     /** Go to the previous slide and replay all of its main sequence effects
172         (or effect groups).
173         @param rPreviousSlideFunctor
174             This functor is used to go to the previous slide.
175     */
176     void asynchronousRewindToPreviousSlide (
177         const ::boost::function<void(void)>& rPreviousSlideFunctor);
178 };
179 
180 } } // end of namespace ::slideshow::internal
181 
182 #endif
183