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