Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <com/sun/star/presentation/EffectNodeType.hpp>
21 : #include <com/sun/star/presentation/ShapeAnimationSubType.hpp>
22 : #include <com/sun/star/presentation/TextAnimationType.hpp>
23 : #include <com/sun/star/presentation/ParagraphTarget.hpp>
24 : #include <com/sun/star/animations/Event.hpp>
25 : #include <com/sun/star/animations/EventTrigger.hpp>
26 : #include <com/sun/star/animations/Timing.hpp>
27 : #include <comphelper/processfactory.hxx>
28 : #include <com/sun/star/animations/AnimationFill.hpp>
29 : #include <com/sun/star/animations/XAnimate.hpp>
30 : #include <com/sun/star/beans/NamedValue.hpp>
31 : #include <svx/unoshape.hxx>
32 : #include <svx/svdotext.hxx>
33 : #include <svx/svdopath.hxx>
34 : #include <svx/svdogrp.hxx>
35 : #include <svx/svditer.hxx>
36 : #include "drawdoc.hxx"
37 : #include "sdpage.hxx"
38 : #include <CustomAnimationPreset.hxx>
39 : #include <TransitionPreset.hxx>
40 : #include <EffectMigration.hxx>
41 : #include <anminfo.hxx>
42 :
43 : using namespace ::sd;
44 : using namespace ::com::sun::star::uno;
45 : using namespace ::com::sun::star::animations;
46 : using namespace ::com::sun::star::presentation;
47 : using ::com::sun::star::drawing::XShape;
48 : using ::com::sun::star::lang::XMultiServiceFactory;
49 : using ::com::sun::star::drawing::XShape;
50 : using ::com::sun::star::beans::NamedValue;
51 :
52 : struct deprecated_FadeEffect_conversion_table_entry
53 : {
54 : FadeEffect meFadeEffect;
55 : const sal_Char* mpPresetId;
56 : }
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 0 : void EffectMigration::SetFadeEffect( SdPage* pPage, ::com::sun::star::presentation::FadeEffect eNewEffect)
165 : {
166 0 : deprecated_FadeEffect_conversion_table_entry* pEntry = deprecated_FadeEffect_conversion_table;
167 0 : while( (pEntry->meFadeEffect != FadeEffect_NONE) && (pEntry->meFadeEffect != eNewEffect) )
168 0 : pEntry++;
169 :
170 0 : if( pEntry->mpPresetId )
171 : {
172 0 : const OUString aPresetId( OUString::createFromAscii( pEntry->mpPresetId ) );
173 :
174 0 : const TransitionPresetList& rPresetList = TransitionPreset::getTransitionPresetList();
175 :
176 0 : TransitionPresetList::const_iterator aIt( rPresetList.begin());
177 0 : const TransitionPresetList::const_iterator aEndIt( rPresetList.end());
178 0 : for( ; aIt != aEndIt; ++aIt )
179 : {
180 0 : if( (*aIt)->getPresetId() == aPresetId)
181 : {
182 0 : pPage->setTransitionType( (*aIt)->getTransition() );
183 0 : pPage->setTransitionSubtype( (*aIt)->getSubtype() );
184 0 : pPage->setTransitionDirection( (*aIt)->getDirection() );
185 0 : pPage->setTransitionFadeColor( (*aIt)->getFadeColor() );
186 0 : break;
187 : }
188 0 : }
189 : }
190 : else
191 : {
192 0 : pPage->setTransitionType( 0 );
193 0 : pPage->setTransitionSubtype( 0 );
194 0 : pPage->setTransitionDirection( false );
195 0 : pPage->setTransitionFadeColor( 0 );
196 : }
197 0 : }
198 :
199 42 : FadeEffect EffectMigration::GetFadeEffect( const SdPage* pPage )
200 : {
201 42 : const TransitionPresetList & rPresetList = TransitionPreset::getTransitionPresetList();
202 42 : TransitionPresetList::const_iterator aIt( rPresetList.begin());
203 42 : const TransitionPresetList::const_iterator aEndIt( rPresetList.end());
204 3444 : for( ; aIt != aEndIt; ++aIt )
205 : {
206 6804 : if( ( (*aIt)->getTransition() == pPage->getTransitionType() ) &&
207 0 : ( (*aIt)->getSubtype() == pPage->getTransitionSubtype() ) &&
208 3402 : ( (*aIt)->getDirection() == pPage->getTransitionDirection() ) &&
209 0 : ( (*aIt)->getFadeColor() == pPage->getTransitionFadeColor() ) )
210 : {
211 0 : const OUString& aPresetId = (*aIt)->getPresetId();
212 :
213 0 : deprecated_FadeEffect_conversion_table_entry* pEntry = deprecated_FadeEffect_conversion_table;
214 0 : while( (pEntry->meFadeEffect != FadeEffect_NONE) && (!aPresetId.equalsAscii( pEntry->mpPresetId ) ) )
215 0 : pEntry++;
216 :
217 0 : return pEntry->meFadeEffect;
218 : }
219 : }
220 42 : 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 : // still open (no matching effect: AnimationEffect_ZOOM_IN_FROM_*,
391 : // AnimationEffect_ZOOM_OUT_FROM_*, AnimationEffect_PATH
392 :
393 : { AnimationEffect_NONE, 0, 0 }
394 : };
395 :
396 56 : EffectSequence::iterator ImplFindEffect( MainSequencePtr& pMainSequence, const Reference< XShape >& rShape, sal_Int16 nSubItem )
397 : {
398 56 : EffectSequence::iterator aIter;
399 :
400 56 : for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
401 : {
402 0 : CustomAnimationEffectPtr pEffect( (*aIter) );
403 0 : if( (pEffect->getTargetShape() == rShape) && (pEffect->getTargetSubItem() == nSubItem) )
404 0 : break;
405 0 : }
406 :
407 56 : return aIter;
408 : }
409 :
410 0 : static bool implIsInsideGroup( SdrObject* pObj )
411 : {
412 0 : return pObj && pObj->GetObjList() && pObj->GetObjList()->GetUpList();
413 : }
414 :
415 0 : void EffectMigration::SetAnimationEffect( SvxShape* pShape, AnimationEffect eEffect )
416 : {
417 : DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
418 : "sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
419 0 : if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
420 0 : return;
421 :
422 0 : SdrObject* pObj = pShape->GetSdrObject();
423 0 : if( implIsInsideGroup( pObj ) )
424 0 : return;
425 :
426 0 : OUString aPresetId;
427 0 : OUString aPresetSubType;
428 :
429 0 : if( !ConvertAnimationEffect( eEffect, aPresetId, aPresetSubType ) )
430 : {
431 : OSL_FAIL( "sd::EffectMigration::SetAnimationEffect(), no mapping for given AnimationEffect value" );
432 0 : return;
433 : }
434 :
435 0 : const CustomAnimationPresets& rPresets = CustomAnimationPresets::getCustomAnimationPresets();
436 :
437 0 : CustomAnimationPresetPtr pPreset( rPresets.getEffectDescriptor( aPresetId ) );
438 0 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
439 :
440 0 : if( pPreset.get() && pMainSequence.get() )
441 : {
442 0 : const Reference< XShape > xShape( pShape );
443 :
444 0 : EffectSequence::iterator aIterOnlyBackground( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_BACKGROUND ) );
445 0 : EffectSequence::iterator aIterAsWhole( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::AS_WHOLE ) );
446 0 : const EffectSequence::iterator aEnd( pMainSequence->getEnd() );
447 :
448 0 : if( (aIterOnlyBackground == aEnd) && (aIterAsWhole == aEnd) )
449 : {
450 0 : bool bEffectCreated = false;
451 :
452 : // check if there is already an text effect for this shape
453 0 : EffectSequence::iterator aIterOnlyText( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_TEXT ) );
454 0 : if( aIterOnlyText != aEnd )
455 : {
456 : // check if this is an animation text group
457 0 : sal_Int32 nGroupId = (*aIterOnlyText)->getGroupId();
458 0 : if( nGroupId >= 0 )
459 : {
460 0 : CustomAnimationTextGroupPtr pGroup = pMainSequence->findGroup( nGroupId );
461 0 : if( pGroup.get() )
462 : {
463 : // add an effect to animate the shape
464 0 : pMainSequence->setAnimateForm( pGroup, true );
465 :
466 : // find this effect
467 0 : EffectSequence::iterator aIter( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_BACKGROUND ) );
468 :
469 0 : if( aIter != aEnd )
470 : {
471 0 : if( ((*aIter)->getPresetId() != aPresetId) ||
472 0 : ((*aIter)->getPresetSubType() != aPresetSubType) )
473 : {
474 0 : (*aIter)->replaceNode( pPreset->create( aPresetSubType ) );
475 0 : pMainSequence->rebuild();
476 0 : bEffectCreated = true;
477 : }
478 : }
479 0 : }
480 : }
481 : }
482 :
483 0 : if( !bEffectCreated )
484 : {
485 : // if there is not yet an effect that target this shape, we generate one
486 : // we insert the shape effect before it
487 0 : Reference< XAnimationNode > xNode( pPreset->create( aPresetSubType ) );
488 : DBG_ASSERT( xNode.is(), "EffectMigration::SetAnimationEffect(), could not create preset!" );
489 0 : if( xNode.is() )
490 : {
491 0 : CustomAnimationEffectPtr pEffect( new CustomAnimationEffect( xNode ) );
492 0 : pEffect->setTarget( makeAny( xShape ) );
493 0 : SdPage* pPage = dynamic_cast< SdPage* >( pObj->GetPage() );
494 0 : const bool bManual = (pPage == 0) || (pPage->GetPresChange() == PRESCHANGE_MANUAL);
495 0 : if( !bManual )
496 0 : pEffect->setNodeType( EffectNodeType::AFTER_PREVIOUS );
497 :
498 0 : pMainSequence->append( pEffect );
499 :
500 0 : if( ( pObj->GetObjInventor() == SdrInventor ) && ( pObj->GetObjIdentifier() == OBJ_OUTLINETEXT ) )
501 : {
502 : // special case for outline text, effects are always mapped to text group effect
503 0 : pMainSequence->
504 0 : createTextGroup( pEffect, 10, bManual ? -1 : 0.0, false, false );
505 0 : }
506 0 : }
507 : }
508 : }
509 : else
510 : {
511 : // if there is already an effect targeting this shape
512 : // just replace it
513 0 : CustomAnimationEffectPtr pEffect;
514 0 : if( aIterAsWhole != aEnd )
515 : {
516 0 : pEffect = (*aIterAsWhole);
517 : }
518 : else
519 : {
520 0 : pEffect = (*aIterOnlyBackground);
521 : }
522 :
523 0 : if( pEffect.get() )
524 : {
525 0 : if( (pEffect->getPresetId() != aPresetId) ||
526 0 : (pEffect->getPresetSubType() != aPresetSubType) )
527 : {
528 0 : pMainSequence->replace( pEffect, pPreset, aPresetSubType );
529 : }
530 0 : }
531 0 : }
532 0 : }
533 : }
534 :
535 56 : AnimationEffect EffectMigration::GetAnimationEffect( SvxShape* pShape )
536 : {
537 56 : OUString aPresetId;
538 112 : OUString aPresetSubType;
539 :
540 56 : SdrObject* pObj = pShape->GetSdrObject();
541 112 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
542 :
543 56 : if( pMainSequence.get() )
544 : {
545 56 : const Reference< XShape > xShape( pShape );
546 :
547 56 : EffectSequence::iterator aIter;
548 :
549 56 : for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
550 : {
551 0 : CustomAnimationEffectPtr pEffect( (*aIter) );
552 0 : if( pEffect->getTargetShape() == xShape )
553 : {
554 0 : if( (pEffect->getTargetSubItem() == ShapeAnimationSubType::ONLY_BACKGROUND) ||
555 0 : (pEffect->getTargetSubItem() == ShapeAnimationSubType::AS_WHOLE))
556 : {
557 0 : if( pEffect->getDuration() != 0.1 ) // ignore appear effects created from old text effect import
558 : {
559 0 : aPresetId = (*aIter)->getPresetId();
560 0 : aPresetSubType = (*aIter)->getPresetSubType();
561 0 : break;
562 : }
563 : }
564 : }
565 56 : }
566 : }
567 :
568 : // now find old effect
569 56 : AnimationEffect eEffect = AnimationEffect_NONE;
570 :
571 56 : if( !ConvertPreset( aPresetId, &aPresetSubType, eEffect ) )
572 0 : ConvertPreset( aPresetId, 0, eEffect );
573 :
574 112 : return eEffect;
575 : }
576 :
577 0 : void EffectMigration::SetTextAnimationEffect( SvxShape* pShape, AnimationEffect eEffect )
578 : {
579 : DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
580 : "sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
581 0 : if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
582 0 : return;
583 :
584 0 : SdrObject* pObj = pShape->GetSdrObject();
585 0 : if( implIsInsideGroup( pObj ) )
586 0 : return;
587 :
588 : // first map the deprecated AnimationEffect to a preset and subtype
589 0 : OUString aPresetId;
590 0 : OUString aPresetSubType;
591 :
592 0 : if( !ConvertAnimationEffect( eEffect, aPresetId, aPresetSubType ) )
593 : {
594 : OSL_FAIL( "sd::EffectMigration::SetAnimationEffect(), no mapping for given AnimationEffect value" );
595 0 : return;
596 : }
597 :
598 0 : SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( pObj );
599 :
600 : // ignore old text effects on shape without text
601 0 : if( (pTextObj == 0) || (!pTextObj->HasText()) )
602 0 : return;
603 :
604 0 : const CustomAnimationPresets& rPresets = CustomAnimationPresets::getCustomAnimationPresets();
605 :
606 : // create an effect from this preset
607 0 : CustomAnimationPresetPtr pPreset( rPresets.getEffectDescriptor( aPresetId ) );
608 :
609 0 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
610 :
611 0 : if( pPreset.get() && pMainSequence.get() )
612 : {
613 0 : const Reference< XShape > xShape( pShape );
614 :
615 0 : EffectSequence::iterator aIterOnlyText( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_TEXT ) );
616 0 : const EffectSequence::iterator aEnd( pMainSequence->getEnd() );
617 :
618 0 : CustomAnimationTextGroupPtr pGroup;
619 :
620 : // is there already an animation text group for this shape?
621 0 : if( aIterOnlyText != aEnd )
622 : {
623 0 : const sal_Int32 nGroupId = (*aIterOnlyText)->getGroupId();
624 0 : if( nGroupId >= 0 )
625 0 : pGroup = pMainSequence->findGroup( nGroupId );
626 : }
627 :
628 : // if there is not yet a group, create it
629 0 : if( pGroup.get() == 0 )
630 : {
631 0 : CustomAnimationEffectPtr pShapeEffect;
632 :
633 0 : EffectSequence::iterator aIterOnlyBackground( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_BACKGROUND ) );
634 0 : if( aIterOnlyBackground != aEnd )
635 : {
636 0 : pShapeEffect = (*aIterOnlyBackground);
637 : }
638 : else
639 : {
640 0 : EffectSequence::iterator aIterAsWhole( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::AS_WHOLE ) );
641 0 : if( aIterAsWhole != aEnd )
642 : {
643 0 : pShapeEffect = (*aIterAsWhole);
644 : }
645 : else
646 : {
647 0 : OUString aEmpty;
648 0 : CustomAnimationPresetPtr pShapePreset( rPresets.getEffectDescriptor( "ooo-entrance-appear" ) );
649 :
650 0 : Reference< XAnimationNode > xNode( pPreset->create( aEmpty ) );
651 : DBG_ASSERT( xNode.is(), "EffectMigration::SetTextAnimationEffect(), could not create preset!" );
652 0 : if( xNode.is() )
653 : {
654 0 : pShapeEffect.reset( new CustomAnimationEffect( xNode ) );
655 0 : pShapeEffect->setTarget( makeAny( xShape ) );
656 0 : pShapeEffect->setDuration( 0.1 );
657 0 : pMainSequence->append( pShapeEffect );
658 :
659 0 : SdPage* pPage = dynamic_cast< SdPage* >( pObj->GetPage() );
660 0 : if( pPage && pPage->GetPresChange() != PRESCHANGE_MANUAL )
661 0 : pShapeEffect->setNodeType( EffectNodeType::AFTER_PREVIOUS );
662 0 : }
663 : }
664 : }
665 :
666 0 : if( pShapeEffect.get() )
667 : {
668 0 : SdPage* pPage = dynamic_cast< SdPage* >( pObj->GetPage() );
669 0 : const bool bManual = (pPage == 0) || (pPage->GetPresChange() == PRESCHANGE_MANUAL);
670 :
671 : // now create effects for each paragraph
672 0 : pGroup =
673 0 : pMainSequence->
674 0 : createTextGroup( pShapeEffect, 10, bManual ? -1 : 0.0, true, false );
675 0 : }
676 : }
677 :
678 0 : if( pGroup.get() != 0 )
679 : {
680 0 : const bool bLaserEffect = (eEffect >= AnimationEffect_LASER_FROM_LEFT) && (eEffect <= AnimationEffect_LASER_FROM_LOWERRIGHT);
681 :
682 : // now we have a group, so check if all effects are same as we like to have them
683 0 : const EffectSequence& rEffects = pGroup->getEffects();
684 :
685 0 : EffectSequence::const_iterator aIter;
686 0 : for( aIter = rEffects.begin(); aIter != rEffects.end(); ++aIter )
687 : {
688 : // only work on paragraph targets
689 0 : if( (*aIter)->getTarget().getValueType() == ::cppu::UnoType<ParagraphTarget>::get() )
690 : {
691 0 : if( ((*aIter)->getPresetId() != aPresetId) ||
692 0 : ((*aIter)->getPresetSubType() != aPresetSubType) )
693 : {
694 0 : (*aIter)->replaceNode( pPreset->create( aPresetSubType ) );
695 : }
696 :
697 0 : if( bLaserEffect )
698 : {
699 0 : (*aIter)->setIterateType( TextAnimationType::BY_LETTER );
700 0 : (*aIter)->setIterateInterval( 0.5 );// TODO:
701 : // Determine
702 : // interval
703 : // according
704 : // to
705 : // total
706 : // effect
707 : // duration
708 : }
709 : }
710 : }
711 : }
712 0 : pMainSequence->rebuild();
713 0 : }
714 : }
715 :
716 56 : AnimationEffect EffectMigration::GetTextAnimationEffect( SvxShape* pShape )
717 : {
718 56 : OUString aPresetId;
719 112 : OUString aPresetSubType;
720 :
721 56 : SdrObject* pObj = pShape->GetSdrObject();
722 56 : if( pObj )
723 : {
724 56 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
725 :
726 56 : if( pMainSequence.get() )
727 : {
728 56 : const Reference< XShape > xShape( pShape );
729 56 : EffectSequence::iterator aIter( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_TEXT ) );
730 56 : if( aIter != pMainSequence->getEnd() )
731 : {
732 0 : aPresetId = (*aIter)->getPresetId();
733 0 : aPresetSubType = (*aIter)->getPresetSubType();
734 56 : }
735 56 : }
736 : }
737 :
738 : // now find old effect
739 56 : AnimationEffect eEffect = AnimationEffect_NONE;
740 :
741 56 : if( !ConvertPreset( aPresetId, &aPresetSubType, eEffect ) )
742 0 : ConvertPreset( aPresetId, 0, eEffect );
743 :
744 112 : return eEffect;
745 : }
746 :
747 112 : bool EffectMigration::ConvertPreset( const OUString& rPresetId, const OUString* pPresetSubType, AnimationEffect& rEffect )
748 : {
749 112 : rEffect = AnimationEffect_NONE;
750 112 : if( !rPresetId.isEmpty() )
751 : {
752 : // first try a match for preset id and subtype
753 0 : deprecated_AnimationEffect_conversion_table_entry* p = deprecated_AnimationEffect_conversion_table;
754 0 : while( p->mpPresetId )
755 : {
756 0 : if( rPresetId.equalsAscii( p->mpPresetId ) &&
757 0 : (( p->mpPresetSubType == 0 ) ||
758 0 : ( pPresetSubType == 0) ||
759 0 : ( pPresetSubType->equalsAscii( p->mpPresetSubType )) ) )
760 : {
761 0 : rEffect = p->meEffect;
762 0 : return true;
763 : }
764 0 : p++;
765 : }
766 0 : return false;
767 : }
768 : else
769 : {
770 : // empty preset id means AnimationEffect_NONE
771 112 : return true;
772 : }
773 : }
774 :
775 0 : bool EffectMigration::ConvertAnimationEffect( const AnimationEffect& rEffect, OUString& rPresetId, OUString& rPresetSubType )
776 : {
777 0 : deprecated_AnimationEffect_conversion_table_entry* p = deprecated_AnimationEffect_conversion_table;
778 0 : while( p->mpPresetId )
779 : {
780 0 : if( p->meEffect == rEffect )
781 : {
782 0 : rPresetId = OUString::createFromAscii( p->mpPresetId );
783 0 : rPresetSubType = OUString::createFromAscii( p->mpPresetSubType );
784 0 : return true;
785 : }
786 0 : p++;
787 : }
788 :
789 0 : return false;
790 : }
791 :
792 0 : double EffectMigration::ConvertAnimationSpeed( AnimationSpeed eSpeed )
793 : {
794 : double fDuration;
795 0 : switch( eSpeed )
796 : {
797 0 : case AnimationSpeed_SLOW: fDuration = 2.0; break;
798 0 : case AnimationSpeed_FAST: fDuration = 0.5; break;
799 : default:
800 0 : fDuration = 1.0; break;
801 : }
802 0 : return fDuration;
803 : }
804 :
805 0 : void EffectMigration::SetAnimationSpeed( SvxShape* pShape, AnimationSpeed eSpeed )
806 : {
807 : DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
808 : "sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
809 0 : if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
810 0 : return;
811 :
812 0 : SdrObject* pObj = pShape->GetSdrObject();
813 0 : if( implIsInsideGroup( pObj ) )
814 0 : return;
815 :
816 0 : double fDuration = ConvertAnimationSpeed( eSpeed );
817 :
818 0 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
819 :
820 0 : const Reference< XShape > xShape( pShape );
821 :
822 0 : EffectSequence::iterator aIter;
823 0 : bool bNeedRebuild = false;
824 :
825 0 : for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
826 : {
827 0 : CustomAnimationEffectPtr pEffect( (*aIter) );
828 0 : if( pEffect->getTargetShape() == xShape )
829 : {
830 0 : if( pEffect->getDuration() != 0.1 )
831 0 : pEffect->setDuration( fDuration );
832 0 : bNeedRebuild = true;
833 : }
834 0 : }
835 :
836 0 : if( bNeedRebuild )
837 0 : pMainSequence->rebuild();
838 : }
839 :
840 0 : AnimationSpeed EffectMigration::GetAnimationSpeed( SvxShape* pShape )
841 : {
842 0 : SdrObject* pObj = pShape->GetSdrObject();
843 0 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
844 :
845 0 : const Reference< XShape > xShape( pShape );
846 :
847 0 : EffectSequence::iterator aIter;
848 :
849 0 : double fDuration = 1.0;
850 :
851 0 : for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
852 : {
853 0 : CustomAnimationEffectPtr pEffect( (*aIter) );
854 0 : if( pEffect->getTargetShape() == xShape )
855 : {
856 0 : if( pEffect->getDuration() != 0.1 )
857 : {
858 0 : fDuration = pEffect->getDuration();
859 0 : break;
860 : }
861 : }
862 0 : }
863 :
864 0 : return ConvertDuration( fDuration );
865 : }
866 :
867 0 : AnimationSpeed EffectMigration::ConvertDuration( double fDuration )
868 : {
869 : AnimationSpeed eSpeed;
870 :
871 0 : if( fDuration < 1.0 )
872 0 : eSpeed = AnimationSpeed_FAST;
873 0 : else if( fDuration > 1.5 )
874 0 : eSpeed = AnimationSpeed_SLOW;
875 : else
876 0 : eSpeed = AnimationSpeed_MEDIUM;
877 :
878 0 : return eSpeed;
879 : }
880 :
881 0 : void EffectMigration::SetDimColor( SvxShape* pShape, sal_Int32 nColor )
882 : {
883 : DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
884 : "sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
885 0 : if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
886 0 : return;
887 :
888 0 : SdrObject* pObj = pShape->GetSdrObject();
889 0 : if( implIsInsideGroup( pObj ) )
890 0 : return;
891 :
892 0 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
893 :
894 0 : const Reference< XShape > xShape( pShape );
895 :
896 0 : EffectSequence::iterator aIter;
897 0 : bool bNeedRebuild = false;
898 :
899 0 : for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
900 : {
901 0 : CustomAnimationEffectPtr pEffect( (*aIter) );
902 0 : if( pEffect->getTargetShape() == xShape )
903 : {
904 0 : pEffect->setHasAfterEffect( true );
905 0 : pEffect->setDimColor( makeAny( nColor ) );
906 0 : pEffect->setAfterEffectOnNext( true );
907 0 : bNeedRebuild = true;
908 : }
909 0 : }
910 :
911 0 : if( bNeedRebuild )
912 0 : pMainSequence->rebuild();
913 : }
914 :
915 0 : sal_Int32 EffectMigration::GetDimColor( SvxShape* pShape )
916 : {
917 0 : sal_Int32 nColor = 0;
918 0 : if( pShape )
919 : {
920 0 : SdrObject* pObj = pShape->GetSdrObject();
921 0 : if( pObj && pObj->GetPage() )
922 : {
923 0 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
924 :
925 0 : const Reference< XShape > xShape( pShape );
926 0 : EffectSequence::iterator aIter;
927 :
928 0 : for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
929 : {
930 0 : CustomAnimationEffectPtr pEffect( (*aIter) );
931 0 : if( (pEffect->getTargetShape() == xShape) &&
932 0 : pEffect->getDimColor().hasValue() &&
933 0 : pEffect->hasAfterEffect())
934 : {
935 0 : pEffect->getDimColor() >>= nColor;
936 0 : break;
937 : }
938 0 : }
939 : }
940 : }
941 :
942 0 : return nColor;
943 : }
944 :
945 0 : void EffectMigration::SetDimHide( SvxShape* pShape, bool bDimHide )
946 : {
947 : DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
948 : "sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
949 0 : if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
950 0 : return;
951 :
952 0 : SdrObject* pObj = pShape->GetSdrObject();
953 0 : if( implIsInsideGroup( pObj ) )
954 0 : return;
955 :
956 0 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
957 :
958 0 : const Reference< XShape > xShape( pShape );
959 :
960 0 : EffectSequence::iterator aIter;
961 0 : bool bNeedRebuild = false;
962 :
963 0 : for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
964 : {
965 0 : CustomAnimationEffectPtr pEffect( (*aIter) );
966 0 : if( pEffect->getTargetShape() == xShape )
967 : {
968 0 : pEffect->setHasAfterEffect( bDimHide );
969 0 : if( bDimHide ) {
970 0 : Any aEmpty;
971 0 : pEffect->setDimColor( aEmpty );
972 : }
973 0 : pEffect->setAfterEffectOnNext( false );
974 0 : bNeedRebuild = true;
975 : }
976 0 : }
977 :
978 0 : if( bNeedRebuild )
979 0 : pMainSequence->rebuild();
980 : }
981 :
982 0 : bool EffectMigration::GetDimHide( SvxShape* pShape )
983 : {
984 0 : bool bRet = false;
985 0 : if( pShape )
986 : {
987 0 : SdrObject* pObj = pShape->GetSdrObject();
988 0 : if( pObj && pObj->GetPage() )
989 : {
990 0 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
991 :
992 0 : const Reference< XShape > xShape( pShape );
993 :
994 0 : EffectSequence::iterator aIter;
995 0 : for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
996 : {
997 0 : CustomAnimationEffectPtr pEffect( (*aIter) );
998 0 : if( pEffect->getTargetShape() == xShape )
999 : {
1000 0 : bRet = pEffect->hasAfterEffect() &&
1001 0 : !pEffect->getDimColor().hasValue() &&
1002 0 : (!pEffect->IsAfterEffectOnNext());
1003 0 : break;
1004 : }
1005 0 : }
1006 : }
1007 : }
1008 :
1009 0 : return bRet;
1010 : }
1011 :
1012 0 : void EffectMigration::SetDimPrevious( SvxShape* pShape, bool bDimPrevious )
1013 : {
1014 : DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
1015 : "sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
1016 0 : if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
1017 0 : return;
1018 :
1019 0 : SdrObject* pObj = pShape->GetSdrObject();
1020 0 : if( implIsInsideGroup( pObj ) )
1021 0 : return;
1022 :
1023 0 : Any aColor;
1024 :
1025 0 : if( bDimPrevious )
1026 0 : aColor <<= (sal_Int32)COL_LIGHTGRAY;
1027 :
1028 0 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1029 :
1030 0 : const Reference< XShape > xShape( pShape );
1031 :
1032 0 : EffectSequence::iterator aIter;
1033 0 : bool bNeedRebuild = false;
1034 :
1035 0 : for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
1036 : {
1037 0 : CustomAnimationEffectPtr pEffect( (*aIter) );
1038 0 : if( pEffect->getTargetShape() == xShape )
1039 : {
1040 0 : pEffect->setHasAfterEffect( bDimPrevious );
1041 0 : if( !bDimPrevious || !pEffect->getDimColor().hasValue() )
1042 0 : pEffect->setDimColor( aColor );
1043 0 : pEffect->setAfterEffectOnNext( true );
1044 0 : bNeedRebuild = true;
1045 : }
1046 0 : }
1047 :
1048 0 : if( bNeedRebuild )
1049 0 : pMainSequence->rebuild();
1050 : }
1051 :
1052 0 : bool EffectMigration::GetDimPrevious( SvxShape* pShape )
1053 : {
1054 0 : bool bRet = false;
1055 0 : if( pShape )
1056 : {
1057 0 : SdrObject* pObj = pShape->GetSdrObject();
1058 0 : if( pObj && pObj->GetPage() )
1059 : {
1060 0 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1061 :
1062 0 : const Reference< XShape > xShape( pShape );
1063 :
1064 0 : EffectSequence::iterator aIter;
1065 0 : for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
1066 : {
1067 0 : CustomAnimationEffectPtr pEffect( (*aIter) );
1068 0 : if( pEffect->getTargetShape() == xShape )
1069 : {
1070 0 : bRet = pEffect->hasAfterEffect() &&
1071 0 : pEffect->getDimColor().hasValue() &&
1072 0 : pEffect->IsAfterEffectOnNext();
1073 0 : break;
1074 : }
1075 0 : }
1076 : }
1077 : }
1078 :
1079 0 : return bRet;
1080 : }
1081 :
1082 0 : void EffectMigration::SetPresentationOrder( SvxShape* pShape, sal_Int32 nNewPos )
1083 : {
1084 0 : if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
1085 0 : return;
1086 :
1087 0 : SdrObject* pObj = pShape->GetSdrObject();
1088 0 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1089 :
1090 0 : EffectSequence& rSequence = pMainSequence->getSequence();
1091 : sal_Int32 nPos;
1092 0 : sal_Int32 nCurrentPos = -1;
1093 0 : std::vector< std::vector< EffectSequence::iterator > > aEffectVector(1);
1094 :
1095 0 : if( !rSequence.empty() )
1096 : {
1097 0 : Reference< XShape > xThis( pShape );
1098 0 : Reference< XShape > xCurrent;
1099 :
1100 0 : EffectSequence::iterator aIter( rSequence.begin() );
1101 0 : EffectSequence::iterator aEnd( rSequence.end() );
1102 0 : for( nPos = 0; aIter != aEnd; ++aIter )
1103 : {
1104 0 : CustomAnimationEffectPtr pEffect = (*aIter);
1105 :
1106 0 : if( !xCurrent.is() )
1107 : {
1108 0 : xCurrent = pEffect->getTargetShape();
1109 : }
1110 0 : else if( pEffect->getTargetShape() != xCurrent )
1111 : {
1112 0 : nPos++;
1113 0 : xCurrent = pEffect->getTargetShape();
1114 0 : aEffectVector.resize( nPos+1 );
1115 : }
1116 :
1117 : // is this the first effect for xThis shape?
1118 0 : if(( nCurrentPos == -1 ) && ( xCurrent == xThis ) )
1119 : {
1120 0 : nCurrentPos = nPos;
1121 : }
1122 :
1123 0 : aEffectVector[nPos].push_back( aIter );
1124 0 : }
1125 : }
1126 :
1127 : // check if there is at least one effect for xThis
1128 0 : if( nCurrentPos == -1 )
1129 : {
1130 : OSL_FAIL("sd::EffectMigration::SetPresentationOrder() failed cause this shape has no effect" );
1131 0 : return;
1132 : }
1133 :
1134 : // check trivial case
1135 0 : if( nCurrentPos != nNewPos )
1136 : {
1137 0 : std::vector< CustomAnimationEffectPtr > aEffects;
1138 :
1139 0 : std::vector< EffectSequence::iterator >::iterator aIter( aEffectVector[nCurrentPos].begin() );
1140 0 : std::vector< EffectSequence::iterator >::iterator aEnd( aEffectVector[nCurrentPos].end() );
1141 0 : while( aIter != aEnd )
1142 : {
1143 0 : aEffects.push_back( (*(*aIter)) );
1144 0 : rSequence.erase( (*aIter++) );
1145 : }
1146 :
1147 0 : if( nNewPos > nCurrentPos )
1148 0 : nNewPos++;
1149 :
1150 0 : std::vector< CustomAnimationEffectPtr >::iterator aTempIter( aEffects.begin() );
1151 0 : std::vector< CustomAnimationEffectPtr >::iterator aTempEnd( aEffects.end() );
1152 :
1153 0 : if( nNewPos == (sal_Int32)aEffectVector.size() )
1154 : {
1155 0 : while( aTempIter != aTempEnd )
1156 : {
1157 0 : rSequence.push_back( (*aTempIter++) );
1158 : }
1159 : }
1160 : else
1161 : {
1162 0 : EffectSequence::iterator aPos( aEffectVector[nNewPos][0] );
1163 0 : while( aTempIter != aTempEnd )
1164 : {
1165 0 : rSequence.insert( aPos, (*aTempIter++) );
1166 : }
1167 0 : }
1168 0 : }
1169 : }
1170 :
1171 : /** Returns the position of the given SdrObject in the Presentation order.
1172 : * This function returns -1 if the SdrObject is not in the Presentation order
1173 : * or if its the path-object.
1174 : */
1175 56 : sal_Int32 EffectMigration::GetPresentationOrder( SvxShape* pShape )
1176 : {
1177 56 : sal_Int32 nPos = -1, nFound = -1;
1178 :
1179 56 : SdrObject* pObj = pShape->GetSdrObject();
1180 56 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1181 :
1182 56 : EffectSequence& rSequence = pMainSequence->getSequence();
1183 :
1184 112 : Reference< XShape > xThis( pShape );
1185 112 : Reference< XShape > xCurrent;
1186 :
1187 56 : EffectSequence::iterator aIter( rSequence.begin() );
1188 56 : EffectSequence::iterator aEnd( rSequence.end() );
1189 0 : for( ; aIter != aEnd; ++aIter )
1190 : {
1191 0 : CustomAnimationEffectPtr pEffect = (*aIter);
1192 :
1193 0 : if( !xCurrent.is() || pEffect->getTargetShape() != xCurrent )
1194 : {
1195 0 : nPos++;
1196 0 : xCurrent = pEffect->getTargetShape();
1197 :
1198 : // is this the first effect for xThis shape?
1199 0 : if( xCurrent == xThis )
1200 : {
1201 0 : nFound = nPos;
1202 0 : break;
1203 : }
1204 : }
1205 0 : }
1206 :
1207 112 : return nFound;
1208 : }
1209 :
1210 0 : void EffectMigration::UpdateSoundEffect( SvxShape* pShape, SdAnimationInfo* pInfo )
1211 : {
1212 0 : if( pInfo )
1213 : {
1214 0 : SdrObject* pObj = pShape->GetSdrObject();
1215 0 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1216 :
1217 0 : const Reference< XShape > xShape( pShape );
1218 :
1219 0 : EffectSequence::iterator aIter;
1220 0 : bool bNeedRebuild = false;
1221 :
1222 0 : OUString aSoundFile;
1223 0 : if( pInfo->mbSoundOn )
1224 0 : aSoundFile = pInfo->maSoundFile;
1225 :
1226 0 : for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
1227 : {
1228 0 : CustomAnimationEffectPtr pEffect( (*aIter) );
1229 0 : if( pEffect->getTargetShape() == xShape )
1230 : {
1231 0 : if( !aSoundFile.isEmpty() )
1232 : {
1233 0 : pEffect->createAudio( makeAny( aSoundFile ) );
1234 : }
1235 : else
1236 : {
1237 0 : pEffect->removeAudio();
1238 : }
1239 0 : bNeedRebuild = true;
1240 : }
1241 0 : }
1242 :
1243 0 : if( bNeedRebuild )
1244 0 : pMainSequence->rebuild();
1245 : }
1246 0 : }
1247 :
1248 56 : OUString EffectMigration::GetSoundFile( SvxShape* pShape )
1249 : {
1250 56 : OUString aSoundFile;
1251 :
1252 56 : if( pShape )
1253 : {
1254 56 : SdrObject* pObj = pShape->GetSdrObject();
1255 56 : if( pObj && pObj->GetPage() )
1256 : {
1257 56 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1258 :
1259 112 : const Reference< XShape > xShape( pShape );
1260 :
1261 56 : EffectSequence::iterator aIter;
1262 :
1263 168 : for( aIter = pMainSequence->getBegin();
1264 168 : (aSoundFile.isEmpty()) && (aIter != pMainSequence->getEnd());
1265 : ++aIter )
1266 : {
1267 0 : CustomAnimationEffectPtr pEffect( (*aIter) );
1268 0 : if( pEffect->getTargetShape() == xShape )
1269 : {
1270 0 : if( pEffect->getAudio().is() )
1271 0 : pEffect->getAudio()->getSource() >>= aSoundFile;
1272 : }
1273 56 : }
1274 : }
1275 : }
1276 56 : return aSoundFile;
1277 : }
1278 :
1279 56 : bool EffectMigration::GetSoundOn( SvxShape* pShape )
1280 : {
1281 56 : return !GetSoundFile( pShape ).isEmpty();
1282 : }
1283 :
1284 0 : void EffectMigration::SetAnimationPath( SvxShape* pShape, SdrPathObj* pPathObj )
1285 : {
1286 0 : if( pShape && pPathObj )
1287 : {
1288 0 : SdrObject* pObj = pShape->GetSdrObject();
1289 :
1290 0 : if( pObj )
1291 : {
1292 0 : const Reference< XShape > xShape( pShape );
1293 0 : SdPage* pPage = dynamic_cast< SdPage* >(pPathObj->GetPage());
1294 0 : if( pPage )
1295 : {
1296 0 : boost::shared_ptr< sd::MainSequence > pMainSequence( pPage->getMainSequence() );
1297 0 : if( pMainSequence.get() )
1298 0 : CustomAnimationEffectPtr pCreated( pMainSequence->append( *pPathObj, makeAny( xShape ), -1.0 ) );
1299 0 : }
1300 : }
1301 : }
1302 0 : }
1303 :
1304 : // #i42894# helper which creates the needed XAnimate for changing visibility and all the (currently) needed embeddings
1305 0 : void createVisibilityOnOffNode(Reference< XTimeContainer >& rxParentContainer, SdrObject& rCandidate, bool bVisible, bool bOnClick, double fDuration)
1306 : {
1307 0 : Reference< XMultiServiceFactory > xMsf(::comphelper::getProcessServiceFactory());
1308 0 : Any aAny;
1309 :
1310 : // create par container node
1311 0 : Reference< XAnimationNode > xOuterSeqTimeContainer(xMsf->createInstance("com.sun.star.animations.ParallelTimeContainer"), UNO_QUERY_THROW);
1312 :
1313 : // set begin
1314 0 : aAny <<= (double)(0.0);
1315 0 : xOuterSeqTimeContainer->setBegin(aAny);
1316 :
1317 : // set fill
1318 0 : xOuterSeqTimeContainer->setFill(AnimationFill::HOLD);
1319 :
1320 : // set named values
1321 0 : Sequence< NamedValue > aUserDataSequence;
1322 0 : aUserDataSequence.realloc(1);
1323 :
1324 0 : aUserDataSequence[0].Name = "node-type";
1325 0 : aUserDataSequence[0].Value <<= bOnClick ? EffectNodeType::ON_CLICK : EffectNodeType::AFTER_PREVIOUS;
1326 :
1327 0 : xOuterSeqTimeContainer->setUserData(aUserDataSequence);
1328 :
1329 : // create animate set to change visibility for rCandidate
1330 0 : Reference< XAnimationNode > xAnimateSetForLast(xMsf->createInstance("com.sun.star.animations.AnimateSet"), UNO_QUERY_THROW);
1331 :
1332 : // set begin
1333 0 : aAny <<= (double)(0.0);
1334 0 : xAnimateSetForLast->setBegin(aAny);
1335 :
1336 : // set duration
1337 0 : aAny <<= fDuration;
1338 0 : xAnimateSetForLast->setDuration(aAny);
1339 :
1340 : // set fill
1341 0 : xAnimateSetForLast->setFill(AnimationFill::HOLD);
1342 :
1343 : // set target
1344 0 : Reference< XAnimate > xAnimate(xAnimateSetForLast, UNO_QUERY);
1345 0 : Reference< XShape > xTargetShape(rCandidate.getUnoShape(), UNO_QUERY);
1346 0 : aAny <<= xTargetShape;
1347 0 : xAnimate->setTarget(aAny);
1348 :
1349 : // set AttributeName
1350 0 : xAnimate->setAttributeName(OUString("Visibility"));
1351 :
1352 : // set attribute value
1353 0 : aAny <<= bVisible ? sal_True : sal_False;
1354 0 : xAnimate->setTo(aAny);
1355 :
1356 : // ad set node to par node
1357 0 : Reference< XTimeContainer > xParentContainer(xOuterSeqTimeContainer, UNO_QUERY_THROW);
1358 0 : xParentContainer->appendChild(xAnimateSetForLast);
1359 :
1360 : // add node
1361 0 : rxParentContainer->appendChild(xOuterSeqTimeContainer);
1362 0 : }
1363 :
1364 : // #i42894# older native formats supported animated group objects, that means all members of the group
1365 : // were shown animated by showing one after the other. This is no longer supported, but the following
1366 : // fallback will create the needed SMIL animation stuff. Unfortunately the members of the group
1367 : // have to be moved directly to the page, else the (explained to be generic, thus I expected this to
1368 : // work) animations will not work in slideshow
1369 0 : void EffectMigration::CreateAnimatedGroup(SdrObjGroup& rGroupObj, SdPage& rPage)
1370 : {
1371 : // aw080 will give a vector immeditately
1372 0 : SdrObjListIter aIter(rGroupObj);
1373 :
1374 0 : if(aIter.Count())
1375 : {
1376 0 : boost::shared_ptr< sd::MainSequence > pMainSequence(rPage.getMainSequence());
1377 :
1378 0 : if(pMainSequence.get())
1379 : {
1380 0 : std::vector< SdrObject* > aObjects;
1381 0 : aObjects.reserve(aIter.Count());
1382 :
1383 0 : while(aIter.IsMore())
1384 : {
1385 : // do move to page rough with old/current stuff, will be different in aw080 anyways
1386 0 : SdrObject* pCandidate = aIter.Next();
1387 0 : rGroupObj.GetSubList()->NbcRemoveObject(pCandidate->GetOrdNum());
1388 0 : rPage.NbcInsertObject(pCandidate);
1389 0 : aObjects.push_back(pCandidate);
1390 : }
1391 :
1392 : // create main node
1393 0 : Reference< XMultiServiceFactory > xMsf(::comphelper::getProcessServiceFactory());
1394 0 : Reference< XAnimationNode > xOuterSeqTimeContainer(xMsf->createInstance("com.sun.star.animations.ParallelTimeContainer"), UNO_QUERY_THROW);
1395 0 : Any aAny;
1396 :
1397 : // set begin
1398 0 : aAny <<= (double)(0.0);
1399 0 : xOuterSeqTimeContainer->setBegin(aAny);
1400 :
1401 : // prepare parent container
1402 0 : Reference< XTimeContainer > xParentContainer(xOuterSeqTimeContainer, UNO_QUERY_THROW);
1403 :
1404 : // prepare loop over objects
1405 0 : SdrObject* pNext = 0;
1406 0 : const double fDurationShow(0.2);
1407 0 : const double fDurationHide(0.001);
1408 :
1409 0 : for(size_t a(0); a < aObjects.size(); a++)
1410 : {
1411 0 : SdrObject* pLast = pNext;
1412 0 : pNext = aObjects[a];
1413 :
1414 : // create node
1415 0 : if(pLast)
1416 : {
1417 0 : createVisibilityOnOffNode(xParentContainer, *pLast, false, false, fDurationHide);
1418 : }
1419 :
1420 0 : if(pNext)
1421 : {
1422 0 : createVisibilityOnOffNode(xParentContainer, *pNext, true, !a, fDurationShow);
1423 : }
1424 : }
1425 :
1426 : // create end node
1427 0 : if(pNext)
1428 : {
1429 0 : createVisibilityOnOffNode(xParentContainer, *pNext, false, false, fDurationHide);
1430 : }
1431 :
1432 : // add to main sequence and rebuild
1433 0 : pMainSequence->createEffects(xOuterSeqTimeContainer);
1434 0 : pMainSequence->rebuild();
1435 0 : }
1436 0 : }
1437 66 : }
1438 :
1439 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|