xref: /trunk/main/sd/source/core/EffectMigration.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sd.hxx"
30 #include <com/sun/star/presentation/EffectNodeType.hpp>
31 #include <com/sun/star/presentation/ShapeAnimationSubType.hpp>
32 #include <com/sun/star/presentation/TextAnimationType.hpp>
33 #include <com/sun/star/presentation/ParagraphTarget.hpp>
34 #include <svx/unoshape.hxx>
35 #include <svx/svdotext.hxx>
36 #include <svx/svdopath.hxx>
37 #include "drawdoc.hxx"
38 #include "sdpage.hxx"
39 #include <CustomAnimationPreset.hxx>
40 #include <TransitionPreset.hxx>
41 #include <EffectMigration.hxx>
42 #include <anminfo.hxx>
43 
44 using namespace ::vos;
45 using namespace ::sd;
46 using namespace ::com::sun::star::uno;
47 using namespace ::com::sun::star::animations;
48 using namespace ::com::sun::star::presentation;
49 
50 using ::com::sun::star::drawing::XShape;
51 using ::rtl::OUString;
52 
53 struct deprecated_FadeEffect_conversion_table_entry
54 {
55     FadeEffect  meFadeEffect;
56     const sal_Char* mpPresetId;
57 }
58 deprecated_FadeEffect_conversion_table[] =
59 {
60 // OOo 1.x transitions
61     { FadeEffect_FADE_FROM_LEFT,            "wipe-right" },
62     { FadeEffect_FADE_FROM_TOP,             "wipe-down" },
63     { FadeEffect_FADE_FROM_RIGHT,           "wipe-left" },
64     { FadeEffect_FADE_FROM_BOTTOM,          "wipe-up" },
65 
66     { FadeEffect_CLOCKWISE,                 "wheel-clockwise-1-spoke" },
67 
68     { FadeEffect_UNCOVER_TO_LEFT,           "uncover-left" },
69     { FadeEffect_UNCOVER_TO_UPPERLEFT,      "uncover-left-up" },
70     { FadeEffect_UNCOVER_TO_TOP,            "uncover-up" },
71     { FadeEffect_UNCOVER_TO_UPPERRIGHT,     "uncover-right-up" },
72     { FadeEffect_UNCOVER_TO_RIGHT,          "uncover-right" },
73     { FadeEffect_UNCOVER_TO_LOWERRIGHT,     "uncover-right-down" },
74     { FadeEffect_UNCOVER_TO_BOTTOM,         "uncover-down" },
75     { FadeEffect_UNCOVER_TO_LOWERLEFT,      "uncover-left-down" },
76 
77     { FadeEffect_VERTICAL_LINES,            "random-bars-vertical" },
78     { FadeEffect_HORIZONTAL_LINES,          "random-bars-horizontal" },
79 
80     { FadeEffect_VERTICAL_CHECKERBOARD,     "checkerboard-down" },
81     { FadeEffect_HORIZONTAL_CHECKERBOARD,   "checkerboard-across" },
82 
83     { FadeEffect_FADE_TO_CENTER,            "box-in" },
84     { FadeEffect_FADE_FROM_CENTER,          "box-out" },
85 
86     { FadeEffect_VERTICAL_STRIPES,          "venetian-blinds-vertical" },
87     { FadeEffect_HORIZONTAL_STRIPES,        "venetian-blinds-horizontal" },
88 
89     { FadeEffect_MOVE_FROM_LEFT,            "cover-right" },
90     { FadeEffect_MOVE_FROM_TOP,             "cover-down" },
91     { FadeEffect_MOVE_FROM_RIGHT,           "cover-left" },
92     { FadeEffect_MOVE_FROM_BOTTOM,          "cover-up" },
93     { FadeEffect_MOVE_FROM_UPPERLEFT,       "cover-right-down" },
94     { FadeEffect_MOVE_FROM_UPPERRIGHT,      "cover-left-down" },
95     { FadeEffect_MOVE_FROM_LOWERRIGHT,      "cover-left-up" },
96     { FadeEffect_MOVE_FROM_LOWERLEFT,       "cover-right-up" },
97 
98     { FadeEffect_DISSOLVE,                  "dissolve" },
99 
100     { FadeEffect_RANDOM,                    "random-transition" },
101 
102     { FadeEffect_ROLL_FROM_LEFT,            "push-right" },
103     { FadeEffect_ROLL_FROM_TOP,             "push-down" },
104     { FadeEffect_ROLL_FROM_RIGHT,           "push-left" },
105     { FadeEffect_ROLL_FROM_BOTTOM,          "push-up" },
106 
107     { FadeEffect_CLOSE_VERTICAL,            "split-horizontal-in" },
108     { FadeEffect_CLOSE_HORIZONTAL,          "split-vertical-in" },
109     { FadeEffect_OPEN_VERTICAL,             "split-horizontal-out" },
110     { FadeEffect_OPEN_HORIZONTAL,           "split-vertical-out" },
111 
112     { FadeEffect_FADE_FROM_UPPERLEFT,       "diagonal-squares-right-down" },
113     { FadeEffect_FADE_FROM_UPPERRIGHT,      "diagonal-squares-left-down" },
114     { FadeEffect_FADE_FROM_LOWERLEFT,       "diagonal-squares-right-up" },
115     { FadeEffect_FADE_FROM_LOWERRIGHT,      "diagonal-squares-left-up" },
116 
117 // OOo 1.x transitions not in OOo 2.x
118     { FadeEffect_CLOCKWISE,                 "clock-wipe-twelve" },
119     { FadeEffect_COUNTERCLOCKWISE,          "reverse-clock-wipe-twelve" },
120     { FadeEffect_SPIRALIN_LEFT,             "spiral-wipe-top-left-clockwise" },
121     { FadeEffect_SPIRALIN_RIGHT,            "spiral-wipe-top-right-counter-clockwise" },
122     { FadeEffect_SPIRALOUT_LEFT,            "spiral-wipe-out-to-bottom-right-clockwise" },
123     { FadeEffect_SPIRALOUT_RIGHT,           "spiral-wipe-out-to-bottom-left-counter-clockwise" },
124     { FadeEffect_WAVYLINE_FROM_LEFT,        "snake-wipe-top-left-vertical" },
125     { FadeEffect_WAVYLINE_FROM_TOP,         "snake-wipe-top-left-horizontal" },
126     { FadeEffect_WAVYLINE_FROM_RIGHT,       "snake-wipe-bottom-right-vertical" },
127     { FadeEffect_WAVYLINE_FROM_BOTTOM,      "snake-wipe-bottom-right-horizontal" },
128     { FadeEffect_STRETCH_FROM_LEFT,         "wipe-right" }, // todo
129     { FadeEffect_STRETCH_FROM_TOP,          "wipe-down" },  // todo
130     { FadeEffect_STRETCH_FROM_RIGHT,        "wipe-left" },  // todo
131     { FadeEffect_STRETCH_FROM_BOTTOM,       "wipe-up" },    // todo
132 
133 // OOo 1.x not available transitions
134 
135     { FadeEffect_CLOCKWISE,                 "wheel-clockwise-2-spokes" },
136     { FadeEffect_CLOCKWISE,                 "wheel-clockwise-3-spokes" },
137     { FadeEffect_CLOCKWISE,                 "wheel-clockwise-4-spokes" },
138     { FadeEffect_CLOCKWISE,                 "wheel-clockwise-8-spokes" },
139 
140     { FadeEffect_FADE_FROM_CENTER,          "shape-circle" },
141     { FadeEffect_FADE_FROM_CENTER,          "shape-diamond" },
142     { FadeEffect_FADE_FROM_CENTER,          "shape-plus" },
143 
144     { FadeEffect_CLOCKWISE,                 "wedge" },
145 
146     { FadeEffect_DISSOLVE,                  "fade-through-black" },
147 
148     { FadeEffect_CLOCKWISE,                 "zoom-rotate-in" },
149 
150     { FadeEffect_HORIZONTAL_LINES,          "comb-horizontal" },
151     { FadeEffect_VERTICAL_LINES,            "comb-vertical" },
152 
153     { FadeEffect_DISSOLVE,                  "fade-smoothly" },
154 
155     { FadeEffect_NONE, 0 }
156 };
157 
158 /* todo
159 cut                             cut                                 (same as NONE?)
160 cut-through-black               cut         toBlack
161 wedge                           wedge
162 */
163 
164 void EffectMigration::SetFadeEffect( SdPage* pPage, ::com::sun::star::presentation::FadeEffect eNewEffect)
165 {
166     deprecated_FadeEffect_conversion_table_entry* pEntry = deprecated_FadeEffect_conversion_table;
167     while( (pEntry->meFadeEffect != FadeEffect_NONE) && (pEntry->meFadeEffect != eNewEffect) )
168         pEntry++;
169 
170     if( pEntry->mpPresetId )
171     {
172         const OUString aPresetId( OUString::createFromAscii( pEntry->mpPresetId ) );
173 
174         const TransitionPresetList& rPresetList = TransitionPreset::getTransitionPresetList();
175 
176         TransitionPresetList::const_iterator aIt( rPresetList.begin());
177         const TransitionPresetList::const_iterator aEndIt( rPresetList.end());
178         for( ; aIt != aEndIt; ++aIt )
179         {
180             if( (*aIt)->getPresetId() == aPresetId)
181             {
182                 pPage->setTransitionType( (*aIt)->getTransition() );
183                 pPage->setTransitionSubtype( (*aIt)->getSubtype() );
184                 pPage->setTransitionDirection( (*aIt)->getDirection() );
185                 pPage->setTransitionFadeColor( (*aIt)->getFadeColor() );
186                 break;
187             }
188         }
189     }
190     else
191     {
192         pPage->setTransitionType( 0 );
193         pPage->setTransitionSubtype( 0 );
194         pPage->setTransitionDirection( 0 );
195         pPage->setTransitionFadeColor( 0 );
196     }
197 }
198 
199 FadeEffect EffectMigration::GetFadeEffect( const SdPage* pPage )
200 {
201     const TransitionPresetList & rPresetList = TransitionPreset::getTransitionPresetList();
202     TransitionPresetList::const_iterator aIt( rPresetList.begin());
203     const TransitionPresetList::const_iterator aEndIt( rPresetList.end());
204     for( ; aIt != aEndIt; ++aIt )
205     {
206         if( ( (*aIt)->getTransition() == pPage->getTransitionType() ) &&
207             ( (*aIt)->getSubtype() == pPage->getTransitionSubtype() ) &&
208             ( (*aIt)->getDirection() == pPage->getTransitionDirection() ) &&
209             ( (*aIt)->getFadeColor() == pPage->getTransitionFadeColor() ) )
210         {
211             const OUString& aPresetId = (*aIt)->getPresetId();
212 
213             deprecated_FadeEffect_conversion_table_entry* pEntry = deprecated_FadeEffect_conversion_table;
214             while( (pEntry->meFadeEffect != FadeEffect_NONE) && (!aPresetId.equalsAscii( pEntry->mpPresetId ) ) )
215                 pEntry++;
216 
217             return pEntry->meFadeEffect;
218         }
219     }
220     return FadeEffect_NONE;
221 }
222 
223 struct deprecated_AnimationEffect_conversion_table_entry
224 {
225     AnimationEffect meEffect;
226     const sal_Char* mpPresetId;
227     const sal_Char* mpPresetSubType;
228 }
229 deprecated_AnimationEffect_conversion_table[] =
230 {
231 // OOo 1.x entrance effects
232     { AnimationEffect_APPEAR, "ooo-entrance-appear",0 },
233 
234     { AnimationEffect_FADE_TO_CENTER, "ooo-entrance-box","in" },
235     { AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-box","out" },
236 
237     { AnimationEffect_VERTICAL_CHECKERBOARD, "ooo-entrance-checkerboard","downward" },
238     { AnimationEffect_HORIZONTAL_CHECKERBOARD, "ooo-entrance-checkerboard","across" },
239 
240     { AnimationEffect_FADE_FROM_UPPERLEFT, "ooo-entrance-diagonal-squares","right-to-bottom" },
241     { AnimationEffect_FADE_FROM_UPPERRIGHT, "ooo-entrance-diagonal-squares","left-to-bottom" },
242     { AnimationEffect_FADE_FROM_LOWERLEFT, "ooo-entrance-diagonal-squares","right-to-top" },
243     { AnimationEffect_FADE_FROM_LOWERRIGHT, "ooo-entrance-diagonal-squares","left-to-top" },
244 
245     { AnimationEffect_DISSOLVE, "ooo-entrance-dissolve-in",0 },
246 
247     { AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-fly-in","from-left" },
248     { AnimationEffect_MOVE_FROM_TOP, "ooo-entrance-fly-in","from-top" },
249     { AnimationEffect_MOVE_FROM_RIGHT, "ooo-entrance-fly-in","from-right" },
250     { AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-fly-in","from-bottom" },
251     { AnimationEffect_MOVE_FROM_UPPERLEFT, "ooo-entrance-fly-in","from-top-left" },
252     { AnimationEffect_MOVE_FROM_UPPERRIGHT, "ooo-entrance-fly-in","from-top-right" },
253     { AnimationEffect_MOVE_FROM_LOWERRIGHT, "ooo-entrance-fly-in","from-bottom-right" },
254     { AnimationEffect_MOVE_FROM_LOWERLEFT, "ooo-entrance-fly-in","from-bottom-left" },
255 
256     { AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-fly-in-slow", "from-bottom" },
257     { AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-fly-in-slow", "from-left" },
258     { AnimationEffect_MOVE_FROM_RIGHT, "ooo-entrance-fly-in-slow", "from-right" },
259     { AnimationEffect_MOVE_FROM_TOP, "ooo-entrance-fly-in-slow", "from-top" },
260 
261     { AnimationEffect_MOVE_SHORT_FROM_LEFT, "ooo-entrance-peek-in","from-left" },
262     { AnimationEffect_MOVE_SHORT_FROM_TOP, "ooo-entrance-peek-in","from-top" },
263     { AnimationEffect_MOVE_SHORT_FROM_RIGHT, "ooo-entrance-peek-in","from-right" },
264     { AnimationEffect_MOVE_SHORT_FROM_BOTTOM, "ooo-entrance-peek-in","from-bottom" },
265 
266     { AnimationEffect_VERTICAL_LINES, "ooo-entrance-random-bars","horizontal" },
267     { AnimationEffect_HORIZONTAL_LINES, "ooo-entrance-random-bars","vertical" },
268 
269     { AnimationEffect_RANDOM, "ooo-entrance-random",0 },
270 
271     { AnimationEffect_CLOSE_VERTICAL, "ooo-entrance-split","horizontal-in" },
272     { AnimationEffect_CLOSE_HORIZONTAL, "ooo-entrance-split","vertical-in" },
273     { AnimationEffect_OPEN_VERTICAL, "ooo-entrance-split","horizontal-out" },
274     { AnimationEffect_OPEN_HORIZONTAL, "ooo-entrance-split","vertical-out" },
275 
276     { AnimationEffect_VERTICAL_STRIPES, "ooo-entrance-venetian-blinds","horizontal" },
277     { AnimationEffect_HORIZONTAL_STRIPES, "ooo-entrance-venetian-blinds","vertical" },
278 
279     { AnimationEffect_FADE_FROM_LEFT, "ooo-entrance-wipe","from-left" },
280     { AnimationEffect_FADE_FROM_TOP, "ooo-entrance-wipe","from-bottom" },
281     { AnimationEffect_FADE_FROM_RIGHT, "ooo-entrance-wipe","from-right" },
282     { AnimationEffect_FADE_FROM_BOTTOM, "ooo-entrance-wipe","from-top" },
283 
284     { AnimationEffect_HORIZONTAL_ROTATE, "ooo-entrance-swivel","vertical" },
285     { AnimationEffect_VERTICAL_ROTATE, "ooo-entrance-swivel","horizontal" },
286 
287     { AnimationEffect_STRETCH_FROM_LEFT, "ooo-entrance-stretchy","from-left" },
288     { AnimationEffect_STRETCH_FROM_UPPERLEFT, "ooo-entrance-stretchy","from-top-left" },
289     { AnimationEffect_STRETCH_FROM_TOP, "ooo-entrance-stretchy","from-top" },
290     { AnimationEffect_STRETCH_FROM_UPPERRIGHT, "ooo-entrance-stretchy","from-top-right" },
291     { AnimationEffect_STRETCH_FROM_RIGHT, "ooo-entrance-stretchy","from-right" },
292     { AnimationEffect_STRETCH_FROM_LOWERRIGHT, "ooo-entrance-stretchy","from-bottom-right" },
293     { AnimationEffect_STRETCH_FROM_BOTTOM, "ooo-entrance-stretchy","from-bottom" },
294     { AnimationEffect_STRETCH_FROM_LOWERLEFT, "ooo-entrance-stretchy","from-bottom-left" },
295 
296     { AnimationEffect_HORIZONTAL_STRETCH, "ooo-entrance-expand", 0 },
297 
298     { AnimationEffect_CLOCKWISE, "ooo-entrance-wheel","1" },
299     { AnimationEffect_COUNTERCLOCKWISE, "ooo-entrance-clock-wipe","counter-clockwise" },
300 
301     { AnimationEffect_SPIRALIN_LEFT, "ooo-entrance-spiral-wipe", "from-top-left-clockwise" },
302     { AnimationEffect_SPIRALIN_RIGHT, "ooo-entrance-spiral-wipe", "from-top-right-counter-clockwise" },
303     { AnimationEffect_SPIRALOUT_LEFT, "ooo-entrance-spiral-wipe", "from-center-clockwise" },
304     { AnimationEffect_SPIRALOUT_RIGHT, "ooo-entrance-spiral-wipe", "from-center-counter-clockwise" },
305 
306     { AnimationEffect_WAVYLINE_FROM_LEFT, "ooo-entrance-snake-wipe","from-top-left-vertical" },
307     { AnimationEffect_WAVYLINE_FROM_TOP, "ooo-entrance-snake-wipe","from-top-left-horizontal" },
308     { AnimationEffect_WAVYLINE_FROM_RIGHT, "ooo-entrance-snake-wipe","from-bottom-right-vertical" },
309     { AnimationEffect_WAVYLINE_FROM_BOTTOM, "ooo-entrance-snake-wipe","from-bottom-right-horizontal" },
310 
311 // ooo 1.x exit effects
312     { AnimationEffect_HIDE, "ooo-exit-disappear",0 },
313     { AnimationEffect_MOVE_TO_LEFT, "ooo-exit-fly-out", "from-right" },
314     { AnimationEffect_MOVE_TO_TOP, "ooo-exit-fly-out", "from-bottom" },
315     { AnimationEffect_MOVE_TO_RIGHT, "ooo-exit-fly-out", "from-left" },
316     { AnimationEffect_MOVE_TO_BOTTOM, "ooo-exit-fly-out", "from-top" },
317     { AnimationEffect_MOVE_TO_UPPERLEFT, "ooo-exit-fly-out", "from-top-right" },
318     { AnimationEffect_MOVE_TO_UPPERRIGHT, "ooo-exit-fly-out", "from-top-left" },
319     { AnimationEffect_MOVE_TO_LOWERRIGHT, "ooo-exit-fly-out", "from-bottom-left" },
320     { AnimationEffect_MOVE_TO_LOWERLEFT, "ooo-exit-fly-out", "from-bottom-right" },
321     { AnimationEffect_MOVE_SHORT_TO_LEFT, "ooo-exit-peek-out", "from-right" },
322     { AnimationEffect_MOVE_SHORT_TO_UPPERLEFT, "ooo-exit-peek-out", "from-right" },
323     { AnimationEffect_MOVE_SHORT_TO_TOP, "ooo-exit-peek-out", "from-bottom" },
324     { AnimationEffect_MOVE_SHORT_TO_UPPERRIGHT, "ooo-exit-peek-out", "from-bottom" },
325     { AnimationEffect_MOVE_SHORT_TO_RIGHT, "ooo-exit-peek-out", "from-left" },
326     { AnimationEffect_MOVE_SHORT_TO_LOWERRIGHT, "ooo-exit-peek-out","from-left" },
327     { AnimationEffect_MOVE_SHORT_TO_BOTTOM, "ooo-exit-peek-out", "from-top" },
328     { AnimationEffect_MOVE_SHORT_TO_LOWERLEFT, "ooo-exit-peek-out", "from-top" },
329 
330 // no matching in OOo 2.x
331     { AnimationEffect_MOVE_SHORT_FROM_UPPERLEFT, "ooo-entrance-peek-in","from-left" },
332     { AnimationEffect_MOVE_SHORT_FROM_UPPERRIGHT, "ooo-entrance-peek-in","from-top" },
333     { AnimationEffect_MOVE_SHORT_FROM_LOWERRIGHT, "ooo-entrance-peek-in","from-right" },
334     { AnimationEffect_MOVE_SHORT_FROM_LOWERLEFT, "ooo-entrance-peek-in","from-bottom" },
335     { AnimationEffect_LASER_FROM_LEFT, "ooo-entrance-fly-in","from-left" },
336     { AnimationEffect_LASER_FROM_TOP, "ooo-entrance-fly-in","from-top" },
337     { AnimationEffect_LASER_FROM_RIGHT, "ooo-entrance-fly-in","from-right" },
338     { AnimationEffect_LASER_FROM_BOTTOM, "ooo-entrance-fly-in","from-bottom" },
339     { AnimationEffect_LASER_FROM_UPPERLEFT, "ooo-entrance-fly-in","from-top-left" },
340     { AnimationEffect_LASER_FROM_UPPERRIGHT, "ooo-entrance-fly-in","from-top-right" },
341     { AnimationEffect_LASER_FROM_LOWERLEFT, "ooo-entrance-fly-in","from-bottom-left" },
342     { AnimationEffect_LASER_FROM_LOWERRIGHT, "ooo-entrance-fly-in","from-bottom-right" },
343 
344 // no matching in OOo 1.x
345 
346     { AnimationEffect_FADE_TO_CENTER, "ooo-entrance-circle", "in" },
347     { AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-circle", "out" },
348     { AnimationEffect_FADE_TO_CENTER, "ooo-entrance-diamond", "in" },
349     { AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-diamond", "out" },
350     { AnimationEffect_FADE_TO_CENTER, "ooo-entrance-plus", "in" },
351     { AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-plus", "out" },
352     { AnimationEffect_CLOCKWISE, "ooo-entrance-wedge", 0 },
353     { AnimationEffect_CLOCKWISE, "ooo-entrance-wheel", "2" },
354     { AnimationEffect_CLOCKWISE, "ooo-entrance-wheel", "3" },
355     { AnimationEffect_CLOCKWISE, "ooo-entrance-wheel", "4" },
356     { AnimationEffect_CLOCKWISE, "ooo-entrance-wheel", "8" },
357 
358     { AnimationEffect_MOVE_FROM_RIGHT, "ooo-entrance-boomerang", 0 },
359     { AnimationEffect_MOVE_FROM_UPPERRIGHT, "ooo-entrance-bounce", 0 },
360     { AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-curve-up", 0 },
361     { AnimationEffect_MOVE_FROM_TOP, "ooo-entrance-float", 0 },
362     { AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-glide", 0 },
363     { AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-magnify", 0 },
364     { AnimationEffect_HORIZONTAL_ROTATE, "ooo-entrance-pinwheel", 0 },
365     { AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-breaks", 0 },
366     { AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-sling", 0 },
367     { AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-spiral-in", 0 },
368     { AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-thread", 0 },
369     { AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-ascend", 0 },
370     { AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-center-revolve", 0 },
371     { AnimationEffect_APPEAR, "ooo-entrance-compress", 0 },
372     { AnimationEffect_MOVE_SHORT_FROM_TOP, "ooo-entrance-descend", 0 },
373     { AnimationEffect_MOVE_SHORT_FROM_LEFT, "ooo-entrance-ease-in", 0 },
374     { AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-rise-up", 0 },
375     { AnimationEffect_HORIZONTAL_ROTATE, "ooo-entrance-spin-in", 0 },
376     { AnimationEffect_STRETCH_FROM_LEFT, "ooo-entrance-stretchy", "across" },
377     { AnimationEffect_STRETCH_FROM_TOP, "ooo-entrance-stretchy", "downward" },
378 
379     { AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-zoom","in" },
380     { AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-zoom","in-slightly" },
381     { AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-zoom","in-from-screen-center" },
382     { AnimationEffect_FADE_TO_CENTER, "ooo-entrance-zoom","out" },
383     { AnimationEffect_FADE_TO_CENTER, "ooo-entrance-zoom","out-slightly" },
384     { AnimationEffect_FADE_TO_CENTER, "ooo-entrance-zoom","out-from-screen-center" },
385 
386     { AnimationEffect_DISSOLVE, "ooo-entrance-fade-in", 0 },
387     { AnimationEffect_DISSOLVE, "ooo-entrance-fade-in-and-zoom", 0 },
388     { AnimationEffect_DISSOLVE, "ooo-entrance-fade-in-and-swivel", 0 },
389 
390 // open
391 /*
392     { AnimationEffect_ZOOM_IN_FROM_LEFT, "ooo-entrance-zoom","in" },
393     { AnimationEffect_ZOOM_IN_FROM_UPPERLEFT, "ooo-entrance-zoom","in" },
394     { AnimationEffect_ZOOM_IN_FROM_TOP, "ooo-entrance-zoom","in" },
395     { AnimationEffect_ZOOM_IN_FROM_UPPERRIGHT, "ooo-entrance-zoom","in" },
396     { AnimationEffect_ZOOM_IN_FROM_RIGHT, "ooo-entrance-zoom","in" },
397     { AnimationEffect_ZOOM_IN_FROM_LOWERRIGHT, "ooo-entrance-zoom","in" },
398     { AnimationEffect_ZOOM_IN_FROM_BOTTOM, "ooo-entrance-zoom","in" },
399     { AnimationEffect_ZOOM_IN_FROM_LOWERLEFT, "ooo-entrance-zoom","in" },
400     { AnimationEffect_ZOOM_IN_FROM_CENTER, "ooo-entrance-zoom","in" },
401 
402     { AnimationEffect_ZOOM_OUT_FROM_LEFT, "ooo-entrance-appear",0 },
403     { AnimationEffect_ZOOM_OUT_FROM_UPPERLEFT, "ooo-entrance-appear",0 },
404     { AnimationEffect_ZOOM_OUT_FROM_TOP, "ooo-entrance-appear",0 },
405     { AnimationEffect_ZOOM_OUT_FROM_UPPERRIGHT, "ooo-entrance-appear",0 },
406     { AnimationEffect_ZOOM_OUT_FROM_RIGHT, "ooo-entrance-appear",0 },
407     { AnimationEffect_ZOOM_OUT_FROM_LOWERRIGHT, "ooo-entrance-appear",0 },
408     { AnimationEffect_ZOOM_OUT_FROM_BOTTOM, "ooo-entrance-appear",0 },
409     { AnimationEffect_ZOOM_OUT_FROM_LOWERLEFT, "ooo-entrance-appear",0 },
410     { AnimationEffect_ZOOM_OUT_FROM_CENTER, "ooo-entrance-appear",0 },
411     { AnimationEffect_PATH, "ooo-entrance-spiral-in",0 },
412 */
413     { AnimationEffect_NONE, 0, 0 }
414 };
415 
416 EffectSequence::iterator ImplFindEffect( MainSequencePtr& pMainSequence, const Reference< XShape >& rShape, sal_Int16 nSubItem )
417 {
418     EffectSequence::iterator aIter;
419 
420     for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ )
421     {
422         CustomAnimationEffectPtr pEffect( (*aIter) );
423         if( (pEffect->getTargetShape() == rShape) && (pEffect->getTargetSubItem() == nSubItem) )
424             break;
425     }
426 
427     return aIter;
428 }
429 
430 static bool implIsInsideGroup( SdrObject* pObj )
431 {
432     return pObj && pObj->GetObjList() && pObj->GetObjList()->GetUpList();
433 }
434 
435 void EffectMigration::SetAnimationEffect( SvxShape* pShape, AnimationEffect eEffect )
436 {
437     DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
438                 "sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
439     if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
440         return;
441 
442     SdrObject* pObj = pShape->GetSdrObject();
443     if( implIsInsideGroup( pObj ) )
444         return;
445 
446     OUString aPresetId;
447     OUString aPresetSubType;
448 
449     if( !ConvertAnimationEffect( eEffect, aPresetId, aPresetSubType ) )
450     {
451         DBG_ERROR( "sd::EffectMigration::SetAnimationEffect(), no mapping for given AnimationEffect value" );
452         return;
453     }
454 
455     const CustomAnimationPresets& rPresets = CustomAnimationPresets::getCustomAnimationPresets();
456 
457     CustomAnimationPresetPtr pPreset( rPresets.getEffectDescriptor( aPresetId ) );
458     sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
459 
460     if( pPreset.get() && pMainSequence.get() )
461     {
462         const Reference< XShape > xShape( pShape );
463 
464         EffectSequence::iterator aIterOnlyBackground( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_BACKGROUND ) );
465         EffectSequence::iterator aIterAsWhole( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::AS_WHOLE ) );
466         const EffectSequence::iterator aEnd( pMainSequence->getEnd() );
467 
468         bool bEffectCreated = false;
469 
470         if( (aIterOnlyBackground == aEnd) && (aIterAsWhole == aEnd) )
471         {
472             // check if there is already an text effect for this shape
473             EffectSequence::iterator aIterOnlyText( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_TEXT ) );
474             if( aIterOnlyText != aEnd )
475             {
476                 // check if this is an animation text group
477                 sal_Int32 nGroupId = (*aIterOnlyText)->getGroupId();
478                 if( nGroupId >= 0 )
479                 {
480                     CustomAnimationTextGroupPtr pGroup = pMainSequence->findGroup( nGroupId );
481                     if( pGroup.get() )
482                     {
483                         // add an effect to animate the shape
484                         pMainSequence->setAnimateForm( pGroup, true );
485 
486                         // find this effect
487                         EffectSequence::iterator aIter( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_BACKGROUND ) );
488 
489                         if( aIter != aEnd )
490                         {
491                             if( ((*aIter)->getPresetId() != aPresetId) ||
492                                 ((*aIter)->getPresetSubType() != aPresetSubType) )
493                             {
494                                 (*aIter)->replaceNode( pPreset->create( aPresetSubType ) );
495                                 pMainSequence->rebuild();
496                                 bEffectCreated = true;
497                             }
498                         }
499                     }
500                 }
501             }
502 
503             if( !bEffectCreated )
504             {
505                 // if there is not yet an effect that target this shape, we generate one
506                 // we insert the shape effect before it
507                 Reference< XAnimationNode > xNode( pPreset->create( aPresetSubType ) );
508                 DBG_ASSERT( xNode.is(), "EffectMigration::SetAnimationEffect(), could not create preset!" );
509                 if( xNode.is() )
510                 {
511                     CustomAnimationEffectPtr pEffect( new CustomAnimationEffect( xNode ) );
512                     pEffect->setTarget( makeAny( xShape ) );
513                     SdPage* pPage = dynamic_cast< SdPage* >( pObj->GetPage() );
514                     const bool bManual = (pPage == 0) || (pPage->GetPresChange() == PRESCHANGE_MANUAL);
515                     if( !bManual )
516                         pEffect->setNodeType( EffectNodeType::AFTER_PREVIOUS );
517 
518                     pMainSequence->append( pEffect );
519 
520                     if( ( pObj->GetObjInventor() == SdrInventor ) && ( pObj->GetObjIdentifier() == OBJ_OUTLINETEXT ) )
521                     {
522                         // special case for outline text, effects are always mapped to text group effect
523                         pMainSequence->
524                             createTextGroup( pEffect, 10, bManual ? -1 : 0.0, sal_False, sal_False );
525                     }
526                 }
527             }
528         }
529         else
530         {
531             // if there is already an effect targeting this shape
532             // just replace it
533             CustomAnimationEffectPtr pEffect;
534             if( aIterAsWhole != aEnd )
535             {
536                 pEffect = (*aIterAsWhole);
537             }
538             else
539             {
540                 pEffect = (*aIterOnlyBackground);
541             }
542 
543             if( pEffect.get() )
544             {
545                 if( (pEffect->getPresetId() != aPresetId) ||
546                     (pEffect->getPresetSubType() != aPresetSubType) )
547                 {
548                     pMainSequence->replace( pEffect, pPreset, aPresetSubType );
549                 }
550             }
551         }
552     }
553 }
554 
555 // --------------------------------------------------------------------
556 
557 AnimationEffect EffectMigration::GetAnimationEffect( SvxShape* pShape )
558 {
559     OUString aPresetId;
560     OUString aPresetSubType;
561 
562     SdrObject* pObj = pShape->GetSdrObject();
563     sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
564 
565     if( pMainSequence.get() )
566     {
567         const Reference< XShape > xShape( pShape );
568 
569         EffectSequence::iterator aIter;
570 
571         for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ )
572         {
573             CustomAnimationEffectPtr pEffect( (*aIter) );
574             if( pEffect->getTargetShape() == xShape )
575             {
576                 if( (pEffect->getTargetSubItem() == ShapeAnimationSubType::ONLY_BACKGROUND) ||
577                     (pEffect->getTargetSubItem() == ShapeAnimationSubType::AS_WHOLE))
578                 {
579                     if( pEffect->getDuration() != 0.1 ) // ignore appear effects created from old text effect import
580                     {
581                         aPresetId = (*aIter)->getPresetId();
582                         aPresetSubType = (*aIter)->getPresetSubType();
583                         break;
584                     }
585                 }
586             }
587         }
588     }
589 
590     // now find old effect
591     AnimationEffect eEffect = AnimationEffect_NONE;
592 
593     if( !ConvertPreset( aPresetId, &aPresetSubType, eEffect ) )
594         ConvertPreset( aPresetId, 0, eEffect );
595 
596     return eEffect;
597 }
598 
599 
600 // --------------------------------------------------------------------
601 
602 void EffectMigration::SetTextAnimationEffect( SvxShape* pShape, AnimationEffect eEffect )
603 {
604     DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
605                 "sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
606     if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
607         return;
608 
609     SdrObject* pObj = pShape->GetSdrObject();
610     if( implIsInsideGroup( pObj ) )
611         return;
612 
613     // first map the deprecated AnimationEffect to a preset and subtype
614     OUString aPresetId;
615     OUString aPresetSubType;
616 
617     if( !ConvertAnimationEffect( eEffect, aPresetId, aPresetSubType ) )
618     {
619         DBG_ERROR( "sd::EffectMigration::SetAnimationEffect(), no mapping for given AnimationEffect value" );
620         return;
621     }
622 
623     SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( pObj );
624 
625     // ignore old text effects on shape without text
626     if( (pTextObj == 0) || (!pTextObj->HasText()) )
627         return;
628 
629     const CustomAnimationPresets& rPresets = CustomAnimationPresets::getCustomAnimationPresets();
630 
631     // create an effect from this preset
632     CustomAnimationPresetPtr pPreset( rPresets.getEffectDescriptor( aPresetId ) );
633 
634     sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
635 
636     if( pPreset.get() && pMainSequence.get() )
637     {
638         const Reference< XShape > xShape( pShape );
639 
640         EffectSequence::iterator aIterOnlyText( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_TEXT ) );
641         const EffectSequence::iterator aEnd( pMainSequence->getEnd() );
642 
643         CustomAnimationTextGroupPtr pGroup;
644 
645         // is there already an animation text group for this shape?
646         if( aIterOnlyText != aEnd )
647         {
648             const sal_Int32 nGroupId = (*aIterOnlyText)->getGroupId();
649             if( nGroupId >= 0 )
650                 pGroup = pMainSequence->findGroup( nGroupId );
651         }
652 
653         // if there is not yet a group, create it
654         if( pGroup.get() == 0 )
655         {
656             CustomAnimationEffectPtr pShapeEffect;
657 
658             EffectSequence::iterator aIterOnlyBackground( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_BACKGROUND ) );
659             if( aIterOnlyBackground != aEnd )
660             {
661                 pShapeEffect = (*aIterOnlyBackground);
662             }
663             else
664             {
665                 EffectSequence::iterator aIterAsWhole( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::AS_WHOLE ) );
666                 if( aIterAsWhole != aEnd )
667                 {
668                     pShapeEffect = (*aIterAsWhole);
669                 }
670                 else
671                 {
672                     OUString aEmpty;
673                     CustomAnimationPresetPtr pShapePreset( rPresets.getEffectDescriptor( OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo-entrance-appear" ) ) ) );
674 
675                     Reference< XAnimationNode > xNode( pPreset->create( aEmpty ) );
676                     DBG_ASSERT( xNode.is(), "EffectMigration::SetTextAnimationEffect(), could not create preset!" );
677                     if( xNode.is() )
678                     {
679                         pShapeEffect.reset( new CustomAnimationEffect( xNode ) );
680                         pShapeEffect->setTarget( makeAny( xShape ) );
681                         pShapeEffect->setDuration( 0.1 );
682                         pMainSequence->append( pShapeEffect );
683 
684                         SdPage* pPage = dynamic_cast< SdPage* >( pObj->GetPage() );
685                         if( pPage && pPage->GetPresChange() != PRESCHANGE_MANUAL )
686                             pShapeEffect->setNodeType( EffectNodeType::AFTER_PREVIOUS );
687                     }
688                 }
689             }
690 
691             if( pShapeEffect.get() )
692             {
693                 SdPage* pPage = dynamic_cast< SdPage* >( pObj->GetPage() );
694                 const bool bManual = (pPage == 0) || (pPage->GetPresChange() == PRESCHANGE_MANUAL);
695 
696                 // now create effects for each paragraph
697                 pGroup =
698                     pMainSequence->
699                         createTextGroup( pShapeEffect, 10, bManual ? -1 : 0.0, sal_True, sal_False );
700             }
701         }
702 
703         if( pGroup.get() != 0 )
704         {
705             const bool bLaserEffect = (eEffect >= AnimationEffect_LASER_FROM_LEFT) && (eEffect <= AnimationEffect_LASER_FROM_LOWERRIGHT);
706 
707             // now we have a group, so check if all effects are same as we like to have them
708             const EffectSequence& rEffects = pGroup->getEffects();
709 
710             EffectSequence::const_iterator aIter;
711             for( aIter = rEffects.begin(); aIter != rEffects.end(); aIter++ )
712             {
713                 // only work on paragraph targets
714                 if( (*aIter)->getTarget().getValueType() == ::getCppuType((const ParagraphTarget*)0) )
715                 {
716                     if( ((*aIter)->getPresetId() != aPresetId) ||
717                         ((*aIter)->getPresetSubType() != aPresetSubType) )
718                     {
719                         (*aIter)->replaceNode( pPreset->create( aPresetSubType ) );
720                     }
721 
722                     if( bLaserEffect )
723                     {
724                         (*aIter)->setIterateType( TextAnimationType::BY_LETTER );
725                         (*aIter)->setIterateInterval( 0.5 );// TODO:
726                                                              // Determine
727                                                              // interval
728                                                              // according
729                                                              // to
730                                                              // total
731                                                              // effect
732                                                              // duration
733                     }
734                 }
735             }
736         }
737         pMainSequence->rebuild();
738     }
739 }
740 
741 // --------------------------------------------------------------------
742 
743 AnimationEffect EffectMigration::GetTextAnimationEffect( SvxShape* pShape )
744 {
745     OUString aPresetId;
746     OUString aPresetSubType;
747 
748     SdrObject* pObj = pShape->GetSdrObject();
749     if( pObj )
750     {
751         sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
752 
753         if( pMainSequence.get() )
754         {
755             const Reference< XShape > xShape( pShape );
756             EffectSequence::iterator aIter( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_TEXT ) );
757             if( aIter != pMainSequence->getEnd() )
758             {
759                 aPresetId = (*aIter)->getPresetId();
760                 aPresetSubType = (*aIter)->getPresetSubType();
761             }
762         }
763     }
764 
765     // now find old effect
766     AnimationEffect eEffect = AnimationEffect_NONE;
767 
768     if( !ConvertPreset( aPresetId, &aPresetSubType, eEffect ) )
769         ConvertPreset( aPresetId, 0, eEffect );
770 
771     return eEffect;
772 }
773 
774 // --------------------------------------------------------------------
775 
776 bool EffectMigration::ConvertPreset( const OUString& rPresetId, const OUString* pPresetSubType, AnimationEffect& rEffect )
777 {
778     rEffect = AnimationEffect_NONE;
779     if( rPresetId.getLength() )
780     {
781         // first try a match for preset id and subtype
782         deprecated_AnimationEffect_conversion_table_entry* p = deprecated_AnimationEffect_conversion_table;
783         while( p->mpPresetId )
784         {
785             if( rPresetId.equalsAscii( p->mpPresetId ) &&
786                 (( p->mpPresetSubType == 0 ) ||
787                  ( pPresetSubType == 0) ||
788                  ( pPresetSubType->equalsAscii( p->mpPresetSubType )) ) )
789             {
790                 rEffect = p->meEffect;
791                 return true;
792             }
793             p++;
794         }
795         return false;
796     }
797     else
798     {
799         // empty preset id means AnimationEffect_NONE
800         return true;
801     }
802 }
803 
804 // --------------------------------------------------------------------
805 
806 bool EffectMigration::ConvertAnimationEffect( const AnimationEffect& rEffect, OUString& rPresetId, OUString& rPresetSubType )
807 {
808     deprecated_AnimationEffect_conversion_table_entry* p = deprecated_AnimationEffect_conversion_table;
809     while( p->mpPresetId )
810     {
811         if( p->meEffect == rEffect )
812         {
813             rPresetId = OUString::createFromAscii( p->mpPresetId );
814             rPresetSubType = OUString::createFromAscii( p->mpPresetSubType );
815             return true;
816         }
817         p++;
818     }
819 
820     return false;
821 }
822 
823 // --------------------------------------------------------------------
824 
825 double EffectMigration::ConvertAnimationSpeed( AnimationSpeed eSpeed )
826 {
827     double fDuration;
828     switch( eSpeed )
829     {
830     case AnimationSpeed_SLOW: fDuration = 2.0; break;
831     case AnimationSpeed_FAST: fDuration = 0.5; break;
832     //case AnimationSpeed_MEDIUM:
833     default:
834         fDuration = 1.0; break;
835     }
836     return fDuration;
837 }
838 // --------------------------------------------------------------------
839 
840 void EffectMigration::SetAnimationSpeed( SvxShape* pShape, AnimationSpeed eSpeed )
841 {
842     DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
843                 "sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
844     if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
845         return;
846 
847     SdrObject* pObj = pShape->GetSdrObject();
848     if( implIsInsideGroup( pObj ) )
849         return;
850 
851     double fDuration = ConvertAnimationSpeed( eSpeed );
852 
853     sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
854 
855     const Reference< XShape > xShape( pShape );
856 
857     EffectSequence::iterator aIter;
858     bool bNeedRebuild = false;
859 
860     for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ )
861     {
862         CustomAnimationEffectPtr pEffect( (*aIter) );
863         if( pEffect->getTargetShape() == xShape )
864         {
865             if( pEffect->getDuration() != 0.1 )
866                 pEffect->setDuration( fDuration );
867             bNeedRebuild = true;
868         }
869     }
870 
871     if( bNeedRebuild )
872         pMainSequence->rebuild();
873 }
874 
875 // --------------------------------------------------------------------
876 
877 AnimationSpeed EffectMigration::GetAnimationSpeed( SvxShape* pShape )
878 {
879     SdrObject* pObj = pShape->GetSdrObject();
880     sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
881 
882     const Reference< XShape > xShape( pShape );
883 
884     EffectSequence::iterator aIter;
885 
886     double fDuration = 1.0;
887 
888     for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ )
889     {
890         CustomAnimationEffectPtr pEffect( (*aIter) );
891         if( pEffect->getTargetShape() == xShape )
892         {
893             if( pEffect->getDuration() != 0.1 )
894             {
895                 fDuration = pEffect->getDuration();
896                 break;
897             }
898         }
899     }
900 
901     return ConvertDuration( fDuration );
902 }
903 
904 // --------------------------------------------------------------------
905 
906 AnimationSpeed EffectMigration::ConvertDuration( double fDuration )
907 {
908     AnimationSpeed eSpeed;
909 
910     if( fDuration < 1.0 )
911         eSpeed = AnimationSpeed_FAST;
912     else if( fDuration > 1.5 )
913         eSpeed = AnimationSpeed_SLOW;
914     else
915         eSpeed = AnimationSpeed_MEDIUM;
916 
917     return eSpeed;
918 }
919 
920 // --------------------------------------------------------------------
921 
922 void EffectMigration::SetDimColor( SvxShape* pShape, sal_Int32 nColor )
923 {
924     DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
925                 "sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
926     if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
927         return;
928 
929     SdrObject* pObj = pShape->GetSdrObject();
930     if( implIsInsideGroup( pObj ) )
931         return;
932 
933     sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
934 
935     const Reference< XShape > xShape( pShape );
936 
937     EffectSequence::iterator aIter;
938     bool bNeedRebuild = false;
939 
940     for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ )
941     {
942         CustomAnimationEffectPtr pEffect( (*aIter) );
943         if( pEffect->getTargetShape() == xShape )
944         {
945             pEffect->setHasAfterEffect( true );
946             pEffect->setDimColor( makeAny( nColor ) );
947             pEffect->setAfterEffectOnNext( true );
948             bNeedRebuild = true;
949         }
950     }
951 
952     if( bNeedRebuild )
953         pMainSequence->rebuild();
954 }
955 
956 // --------------------------------------------------------------------
957 
958 sal_Int32 EffectMigration::GetDimColor( SvxShape* pShape )
959 {
960     sal_Int32 nColor = 0;
961     if( pShape )
962     {
963         SdrObject* pObj = pShape->GetSdrObject();
964         if( pObj && pObj->GetPage() )
965         {
966             sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
967 
968             const Reference< XShape > xShape( pShape );
969             EffectSequence::iterator aIter;
970 
971             for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ )
972             {
973                 CustomAnimationEffectPtr pEffect( (*aIter) );
974                 if( (pEffect->getTargetShape() == xShape) &&
975                     pEffect->getDimColor().hasValue() &&
976                     pEffect->hasAfterEffect())
977                 {
978                     pEffect->getDimColor() >>= nColor;
979                     break;
980                 }
981             }
982         }
983     }
984 
985     return nColor;
986 }
987 
988 // --------------------------------------------------------------------
989 
990 
991 void EffectMigration::SetDimHide( SvxShape* pShape, sal_Bool bDimHide )
992 {
993     DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
994                 "sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
995     if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
996         return;
997 
998     SdrObject* pObj = pShape->GetSdrObject();
999     if( implIsInsideGroup( pObj ) )
1000         return;
1001 
1002     Any aEmpty;
1003 
1004     sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1005 
1006     const Reference< XShape > xShape( pShape );
1007 
1008     EffectSequence::iterator aIter;
1009     bool bNeedRebuild = false;
1010 
1011     for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ )
1012     {
1013         CustomAnimationEffectPtr pEffect( (*aIter) );
1014         if( pEffect->getTargetShape() == xShape )
1015         {
1016             pEffect->setHasAfterEffect( bDimHide ? true : false );
1017             if( bDimHide )
1018                 pEffect->setDimColor( aEmpty );
1019             pEffect->setAfterEffectOnNext( false );
1020             bNeedRebuild = true;
1021         }
1022     }
1023 
1024     if( bNeedRebuild )
1025         pMainSequence->rebuild();
1026 }
1027 
1028 // --------------------------------------------------------------------
1029 
1030 sal_Bool EffectMigration::GetDimHide( SvxShape* pShape )
1031 {
1032     sal_Bool bRet = sal_False;
1033     if( pShape )
1034     {
1035         SdrObject* pObj = pShape->GetSdrObject();
1036         if( pObj && pObj->GetPage() )
1037         {
1038             sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1039 
1040             const Reference< XShape > xShape( pShape );
1041 
1042             EffectSequence::iterator aIter;
1043             for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ )
1044             {
1045                 CustomAnimationEffectPtr pEffect( (*aIter) );
1046                 if( pEffect->getTargetShape() == xShape )
1047                 {
1048                     bRet = pEffect->hasAfterEffect() &&
1049                             !pEffect->getDimColor().hasValue() &&
1050                             (!pEffect->IsAfterEffectOnNext());
1051                     break;
1052                 }
1053             }
1054         }
1055     }
1056 
1057     return bRet;
1058 }
1059 
1060 // --------------------------------------------------------------------
1061 
1062 void EffectMigration::SetDimPrevious( SvxShape* pShape, sal_Bool bDimPrevious )
1063 {
1064     DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
1065                 "sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
1066     if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
1067         return;
1068 
1069     SdrObject* pObj = pShape->GetSdrObject();
1070     if( implIsInsideGroup( pObj ) )
1071         return;
1072 
1073     Any aColor;
1074 
1075     if( bDimPrevious )
1076         aColor <<= (sal_Int32)COL_LIGHTGRAY;
1077 
1078     sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1079 
1080     const Reference< XShape > xShape( pShape );
1081 
1082     EffectSequence::iterator aIter;
1083     bool bNeedRebuild = false;
1084 
1085     for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ )
1086     {
1087         CustomAnimationEffectPtr pEffect( (*aIter) );
1088         if( pEffect->getTargetShape() == xShape )
1089         {
1090             pEffect->setHasAfterEffect( bDimPrevious );
1091             if( !bDimPrevious || !pEffect->getDimColor().hasValue() )
1092                 pEffect->setDimColor( aColor );
1093             pEffect->setAfterEffectOnNext( true );
1094             bNeedRebuild = true;
1095         }
1096     }
1097 
1098     if( bNeedRebuild )
1099         pMainSequence->rebuild();
1100 }
1101 
1102 // --------------------------------------------------------------------
1103 
1104 sal_Bool EffectMigration::GetDimPrevious( SvxShape* pShape )
1105 {
1106     sal_Bool bRet = sal_False;
1107     if( pShape )
1108     {
1109         SdrObject* pObj = pShape->GetSdrObject();
1110         if( pObj && pObj->GetPage() )
1111         {
1112             sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1113 
1114             const Reference< XShape > xShape( pShape );
1115 
1116             EffectSequence::iterator aIter;
1117             for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ )
1118             {
1119                 CustomAnimationEffectPtr pEffect( (*aIter) );
1120                 if( pEffect->getTargetShape() == xShape )
1121                 {
1122                     bRet = pEffect->hasAfterEffect() &&
1123                             pEffect->getDimColor().hasValue() &&
1124                             pEffect->IsAfterEffectOnNext();
1125                     break;
1126                 }
1127             }
1128         }
1129     }
1130 
1131     return bRet;
1132 }
1133 
1134 // --------------------------------------------------------------------
1135 
1136 void EffectMigration::SetPresentationOrder( SvxShape* pShape, sal_Int32 nNewPos )
1137 {
1138     if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
1139         return;
1140 
1141     SdrObject* pObj = pShape->GetSdrObject();
1142     sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1143 
1144     EffectSequence& rSequence = pMainSequence->getSequence();
1145     sal_Int32 nPos;
1146     sal_Int32 nCurrentPos = -1;
1147     std::vector< std::vector< EffectSequence::iterator > > aEffectVector(1);
1148 
1149     if( !rSequence.empty() )
1150     {
1151         Reference< XShape > xThis( pShape );
1152         Reference< XShape > xCurrent;
1153 
1154         EffectSequence::iterator aIter( rSequence.begin() );
1155         EffectSequence::iterator aEnd( rSequence.end() );
1156         for( nPos = 0; aIter != aEnd; aIter++ )
1157         {
1158             CustomAnimationEffectPtr pEffect = (*aIter);
1159 
1160             if( !xCurrent.is() )
1161             {
1162                 xCurrent = pEffect->getTargetShape();
1163             }
1164             else if( pEffect->getTargetShape() != xCurrent )
1165             {
1166                 nPos++;
1167                 xCurrent = pEffect->getTargetShape();
1168                 aEffectVector.resize( nPos+1 );
1169             }
1170 
1171             // is this the first effect for xThis shape?
1172             if(( nCurrentPos == -1 ) && ( xCurrent == xThis ) )
1173             {
1174                 nCurrentPos = nPos;
1175             }
1176 
1177             aEffectVector[nPos].push_back( aIter );
1178         }
1179     }
1180 
1181     // check if there is at least one effect for xThis
1182     if( nCurrentPos == -1 )
1183     {
1184         DBG_ERROR("sd::EffectMigration::SetPresentationOrder() failed cause this shape has no effect" );
1185         return;
1186     }
1187 
1188     // check trivial case
1189     if( nCurrentPos != nNewPos )
1190     {
1191         std::vector< CustomAnimationEffectPtr > aEffects;
1192 
1193         std::vector< EffectSequence::iterator >::iterator aIter( aEffectVector[nCurrentPos].begin() );
1194         std::vector< EffectSequence::iterator >::iterator aEnd( aEffectVector[nCurrentPos].end() );
1195         while( aIter != aEnd )
1196         {
1197             aEffects.push_back( (*(*aIter)) );
1198             rSequence.erase( (*aIter++) );
1199         }
1200 
1201         if( nNewPos > nCurrentPos )
1202             nNewPos++;
1203 
1204         std::vector< CustomAnimationEffectPtr >::iterator aTempIter( aEffects.begin() );
1205         std::vector< CustomAnimationEffectPtr >::iterator aTempEnd( aEffects.end() );
1206 
1207         if( nNewPos == (sal_Int32)aEffectVector.size() )
1208         {
1209             while( aTempIter != aTempEnd )
1210             {
1211                 rSequence.push_back( (*aTempIter++) );
1212             }
1213         }
1214         else
1215         {
1216             EffectSequence::iterator aPos( aEffectVector[nNewPos][0] );
1217             while( aTempIter != aTempEnd )
1218             {
1219                 rSequence.insert( aPos, (*aTempIter++) );
1220             }
1221         }
1222     }
1223 }
1224 
1225 // --------------------------------------------------------------------
1226 
1227 /** Returns the position of the given SdrObject in the Presentation order.
1228  *  This function returns -1 if the SdrObject is not in the Presentation order
1229  *  or if its the path-object.
1230  */
1231 sal_Int32 EffectMigration::GetPresentationOrder( SvxShape* pShape )
1232 {
1233     sal_Int32 nPos = -1, nFound = -1;
1234 
1235     SdrObject* pObj = pShape->GetSdrObject();
1236     sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1237 
1238     EffectSequence& rSequence = pMainSequence->getSequence();
1239 
1240     Reference< XShape > xThis( pShape );
1241     Reference< XShape > xCurrent;
1242 
1243     EffectSequence::iterator aIter( rSequence.begin() );
1244     EffectSequence::iterator aEnd( rSequence.end() );
1245     for( ; aIter != aEnd; aIter++ )
1246     {
1247         CustomAnimationEffectPtr pEffect = (*aIter);
1248 
1249         if( !xCurrent.is() || pEffect->getTargetShape() != xCurrent )
1250         {
1251             nPos++;
1252             xCurrent = pEffect->getTargetShape();
1253 
1254             // is this the first effect for xThis shape?
1255             if( xCurrent == xThis )
1256             {
1257                 nFound = nPos;
1258                 break;
1259             }
1260         }
1261     }
1262 
1263     return nFound;
1264 }
1265 
1266 // --------------------------------------------------------------------
1267 
1268 void EffectMigration::UpdateSoundEffect( SvxShape* pShape, SdAnimationInfo* pInfo )
1269 {
1270     if( pInfo )
1271     {
1272         SdrObject* pObj = pShape->GetSdrObject();
1273         sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1274 
1275         const Reference< XShape > xShape( pShape );
1276 
1277         EffectSequence::iterator aIter;
1278         bool bNeedRebuild = false;
1279 
1280         OUString aSoundFile;
1281         if( pInfo->mbSoundOn )
1282             aSoundFile = pInfo->maSoundFile;
1283 
1284         for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); aIter++ )
1285         {
1286             CustomAnimationEffectPtr pEffect( (*aIter) );
1287             if( pEffect->getTargetShape() == xShape )
1288             {
1289                 if( aSoundFile.getLength() )
1290                 {
1291                     pEffect->createAudio( makeAny( aSoundFile ) );
1292                 }
1293                 else
1294                 {
1295                     pEffect->removeAudio();
1296                 }
1297                 bNeedRebuild = true;
1298             }
1299         }
1300 
1301         if( bNeedRebuild )
1302             pMainSequence->rebuild();
1303     }
1304 }
1305 
1306 // --------------------------------------------------------------------
1307 
1308 OUString EffectMigration::GetSoundFile( SvxShape* pShape )
1309 {
1310     OUString aSoundFile;
1311 
1312     if( pShape )
1313     {
1314         SdrObject* pObj = pShape->GetSdrObject();
1315         if( pObj && pObj->GetPage() )
1316         {
1317             sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1318 
1319             const Reference< XShape > xShape( pShape );
1320 
1321             EffectSequence::iterator aIter;
1322 
1323             for(    aIter = pMainSequence->getBegin();
1324                     (aSoundFile.getLength() == 0) && (aIter != pMainSequence->getEnd());
1325                     aIter++ )
1326             {
1327                 CustomAnimationEffectPtr pEffect( (*aIter) );
1328                 if( pEffect->getTargetShape() == xShape )
1329                 {
1330                     if( pEffect->getAudio().is() )
1331                         pEffect->getAudio()->getSource() >>= aSoundFile;
1332                 }
1333             }
1334         }
1335     }
1336     return aSoundFile;
1337 }
1338 
1339 // --------------------------------------------------------------------
1340 
1341 sal_Bool EffectMigration::GetSoundOn( SvxShape* pShape )
1342 {
1343     return GetSoundFile( pShape ).getLength() != 0;
1344 }
1345 
1346 // --------------------------------------------------------------------
1347 
1348 void EffectMigration::SetAnimationPath( SvxShape* pShape, SdrPathObj* pPathObj )
1349 {
1350     if( pShape && pPathObj )
1351     {
1352         SdrObject* pObj = pShape->GetSdrObject();
1353 
1354         if( pObj )
1355         {
1356             //sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1357 
1358             const Reference< XShape > xShape( pShape );
1359             SdPage* pPage = dynamic_cast< SdPage* >( pPathObj ? pPathObj->GetPage() : 0 );
1360             if( pPage )
1361             {
1362                 boost::shared_ptr< sd::MainSequence > pMainSequence( pPage->getMainSequence() );
1363                 if( pMainSequence.get() )
1364                     CustomAnimationEffectPtr pCreated( pMainSequence->append( *pPathObj, makeAny( xShape ), -1.0 ) );
1365             }
1366         }
1367     }
1368 }
1369 
1370 
1371