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( 0 );
195 0 : pPage->setTransitionFadeColor( 0 );
196 : }
197 0 : }
198 :
199 0 : FadeEffect EffectMigration::GetFadeEffect( const SdPage* pPage )
200 : {
201 0 : const TransitionPresetList & rPresetList = TransitionPreset::getTransitionPresetList();
202 0 : TransitionPresetList::const_iterator aIt( rPresetList.begin());
203 0 : const TransitionPresetList::const_iterator aEndIt( rPresetList.end());
204 0 : for( ; aIt != aEndIt; ++aIt )
205 : {
206 0 : if( ( (*aIt)->getTransition() == pPage->getTransitionType() ) &&
207 0 : ( (*aIt)->getSubtype() == pPage->getTransitionSubtype() ) &&
208 0 : ( (*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 0 : 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 0 : EffectSequence::iterator ImplFindEffect( MainSequencePtr& pMainSequence, const Reference< XShape >& rShape, sal_Int16 nSubItem )
397 : {
398 0 : EffectSequence::iterator aIter;
399 :
400 0 : 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 0 : 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 : bool bEffectCreated = false;
449 :
450 0 : if( (aIterOnlyBackground == aEnd) && (aIterAsWhole == aEnd) )
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, sal_False, sal_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 :
536 :
537 0 : AnimationEffect EffectMigration::GetAnimationEffect( SvxShape* pShape )
538 : {
539 0 : OUString aPresetId;
540 0 : OUString aPresetSubType;
541 :
542 0 : SdrObject* pObj = pShape->GetSdrObject();
543 0 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
544 :
545 0 : if( pMainSequence.get() )
546 : {
547 0 : const Reference< XShape > xShape( pShape );
548 :
549 0 : EffectSequence::iterator aIter;
550 :
551 0 : for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
552 : {
553 0 : CustomAnimationEffectPtr pEffect( (*aIter) );
554 0 : if( pEffect->getTargetShape() == xShape )
555 : {
556 0 : if( (pEffect->getTargetSubItem() == ShapeAnimationSubType::ONLY_BACKGROUND) ||
557 0 : (pEffect->getTargetSubItem() == ShapeAnimationSubType::AS_WHOLE))
558 : {
559 0 : if( pEffect->getDuration() != 0.1 ) // ignore appear effects created from old text effect import
560 : {
561 0 : aPresetId = (*aIter)->getPresetId();
562 0 : aPresetSubType = (*aIter)->getPresetSubType();
563 0 : break;
564 : }
565 : }
566 : }
567 0 : }
568 : }
569 :
570 : // now find old effect
571 0 : AnimationEffect eEffect = AnimationEffect_NONE;
572 :
573 0 : if( !ConvertPreset( aPresetId, &aPresetSubType, eEffect ) )
574 0 : ConvertPreset( aPresetId, 0, eEffect );
575 :
576 0 : return eEffect;
577 : }
578 :
579 :
580 :
581 :
582 0 : void EffectMigration::SetTextAnimationEffect( SvxShape* pShape, AnimationEffect eEffect )
583 : {
584 : DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
585 : "sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
586 0 : if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
587 0 : return;
588 :
589 0 : SdrObject* pObj = pShape->GetSdrObject();
590 0 : if( implIsInsideGroup( pObj ) )
591 0 : return;
592 :
593 : // first map the deprecated AnimationEffect to a preset and subtype
594 0 : OUString aPresetId;
595 0 : OUString aPresetSubType;
596 :
597 0 : if( !ConvertAnimationEffect( eEffect, aPresetId, aPresetSubType ) )
598 : {
599 : OSL_FAIL( "sd::EffectMigration::SetAnimationEffect(), no mapping for given AnimationEffect value" );
600 0 : return;
601 : }
602 :
603 0 : SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( pObj );
604 :
605 : // ignore old text effects on shape without text
606 0 : if( (pTextObj == 0) || (!pTextObj->HasText()) )
607 0 : return;
608 :
609 0 : const CustomAnimationPresets& rPresets = CustomAnimationPresets::getCustomAnimationPresets();
610 :
611 : // create an effect from this preset
612 0 : CustomAnimationPresetPtr pPreset( rPresets.getEffectDescriptor( aPresetId ) );
613 :
614 0 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
615 :
616 0 : if( pPreset.get() && pMainSequence.get() )
617 : {
618 0 : const Reference< XShape > xShape( pShape );
619 :
620 0 : EffectSequence::iterator aIterOnlyText( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_TEXT ) );
621 0 : const EffectSequence::iterator aEnd( pMainSequence->getEnd() );
622 :
623 0 : CustomAnimationTextGroupPtr pGroup;
624 :
625 : // is there already an animation text group for this shape?
626 0 : if( aIterOnlyText != aEnd )
627 : {
628 0 : const sal_Int32 nGroupId = (*aIterOnlyText)->getGroupId();
629 0 : if( nGroupId >= 0 )
630 0 : pGroup = pMainSequence->findGroup( nGroupId );
631 : }
632 :
633 : // if there is not yet a group, create it
634 0 : if( pGroup.get() == 0 )
635 : {
636 0 : CustomAnimationEffectPtr pShapeEffect;
637 :
638 0 : EffectSequence::iterator aIterOnlyBackground( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_BACKGROUND ) );
639 0 : if( aIterOnlyBackground != aEnd )
640 : {
641 0 : pShapeEffect = (*aIterOnlyBackground);
642 : }
643 : else
644 : {
645 0 : EffectSequence::iterator aIterAsWhole( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::AS_WHOLE ) );
646 0 : if( aIterAsWhole != aEnd )
647 : {
648 0 : pShapeEffect = (*aIterAsWhole);
649 : }
650 : else
651 : {
652 0 : OUString aEmpty;
653 0 : CustomAnimationPresetPtr pShapePreset( rPresets.getEffectDescriptor( "ooo-entrance-appear" ) );
654 :
655 0 : Reference< XAnimationNode > xNode( pPreset->create( aEmpty ) );
656 : DBG_ASSERT( xNode.is(), "EffectMigration::SetTextAnimationEffect(), could not create preset!" );
657 0 : if( xNode.is() )
658 : {
659 0 : pShapeEffect.reset( new CustomAnimationEffect( xNode ) );
660 0 : pShapeEffect->setTarget( makeAny( xShape ) );
661 0 : pShapeEffect->setDuration( 0.1 );
662 0 : pMainSequence->append( pShapeEffect );
663 :
664 0 : SdPage* pPage = dynamic_cast< SdPage* >( pObj->GetPage() );
665 0 : if( pPage && pPage->GetPresChange() != PRESCHANGE_MANUAL )
666 0 : pShapeEffect->setNodeType( EffectNodeType::AFTER_PREVIOUS );
667 0 : }
668 : }
669 : }
670 :
671 0 : if( pShapeEffect.get() )
672 : {
673 0 : SdPage* pPage = dynamic_cast< SdPage* >( pObj->GetPage() );
674 0 : const bool bManual = (pPage == 0) || (pPage->GetPresChange() == PRESCHANGE_MANUAL);
675 :
676 : // now create effects for each paragraph
677 0 : pGroup =
678 0 : pMainSequence->
679 0 : createTextGroup( pShapeEffect, 10, bManual ? -1 : 0.0, sal_True, sal_False );
680 0 : }
681 : }
682 :
683 0 : if( pGroup.get() != 0 )
684 : {
685 0 : const bool bLaserEffect = (eEffect >= AnimationEffect_LASER_FROM_LEFT) && (eEffect <= AnimationEffect_LASER_FROM_LOWERRIGHT);
686 :
687 : // now we have a group, so check if all effects are same as we like to have them
688 0 : const EffectSequence& rEffects = pGroup->getEffects();
689 :
690 0 : EffectSequence::const_iterator aIter;
691 0 : for( aIter = rEffects.begin(); aIter != rEffects.end(); ++aIter )
692 : {
693 : // only work on paragraph targets
694 0 : if( (*aIter)->getTarget().getValueType() == ::getCppuType((const ParagraphTarget*)0) )
695 : {
696 0 : if( ((*aIter)->getPresetId() != aPresetId) ||
697 0 : ((*aIter)->getPresetSubType() != aPresetSubType) )
698 : {
699 0 : (*aIter)->replaceNode( pPreset->create( aPresetSubType ) );
700 : }
701 :
702 0 : if( bLaserEffect )
703 : {
704 0 : (*aIter)->setIterateType( TextAnimationType::BY_LETTER );
705 0 : (*aIter)->setIterateInterval( 0.5 );// TODO:
706 : // Determine
707 : // interval
708 : // according
709 : // to
710 : // total
711 : // effect
712 : // duration
713 : }
714 : }
715 : }
716 : }
717 0 : pMainSequence->rebuild();
718 0 : }
719 : }
720 :
721 :
722 :
723 0 : AnimationEffect EffectMigration::GetTextAnimationEffect( SvxShape* pShape )
724 : {
725 0 : OUString aPresetId;
726 0 : OUString aPresetSubType;
727 :
728 0 : SdrObject* pObj = pShape->GetSdrObject();
729 0 : if( pObj )
730 : {
731 0 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
732 :
733 0 : if( pMainSequence.get() )
734 : {
735 0 : const Reference< XShape > xShape( pShape );
736 0 : EffectSequence::iterator aIter( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_TEXT ) );
737 0 : if( aIter != pMainSequence->getEnd() )
738 : {
739 0 : aPresetId = (*aIter)->getPresetId();
740 0 : aPresetSubType = (*aIter)->getPresetSubType();
741 0 : }
742 0 : }
743 : }
744 :
745 : // now find old effect
746 0 : AnimationEffect eEffect = AnimationEffect_NONE;
747 :
748 0 : if( !ConvertPreset( aPresetId, &aPresetSubType, eEffect ) )
749 0 : ConvertPreset( aPresetId, 0, eEffect );
750 :
751 0 : return eEffect;
752 : }
753 :
754 :
755 :
756 0 : bool EffectMigration::ConvertPreset( const OUString& rPresetId, const OUString* pPresetSubType, AnimationEffect& rEffect )
757 : {
758 0 : rEffect = AnimationEffect_NONE;
759 0 : if( !rPresetId.isEmpty() )
760 : {
761 : // first try a match for preset id and subtype
762 0 : deprecated_AnimationEffect_conversion_table_entry* p = deprecated_AnimationEffect_conversion_table;
763 0 : while( p->mpPresetId )
764 : {
765 0 : if( rPresetId.equalsAscii( p->mpPresetId ) &&
766 0 : (( p->mpPresetSubType == 0 ) ||
767 0 : ( pPresetSubType == 0) ||
768 0 : ( pPresetSubType->equalsAscii( p->mpPresetSubType )) ) )
769 : {
770 0 : rEffect = p->meEffect;
771 0 : return true;
772 : }
773 0 : p++;
774 : }
775 0 : return false;
776 : }
777 : else
778 : {
779 : // empty preset id means AnimationEffect_NONE
780 0 : return true;
781 : }
782 : }
783 :
784 :
785 :
786 0 : bool EffectMigration::ConvertAnimationEffect( const AnimationEffect& rEffect, OUString& rPresetId, OUString& rPresetSubType )
787 : {
788 0 : deprecated_AnimationEffect_conversion_table_entry* p = deprecated_AnimationEffect_conversion_table;
789 0 : while( p->mpPresetId )
790 : {
791 0 : if( p->meEffect == rEffect )
792 : {
793 0 : rPresetId = OUString::createFromAscii( p->mpPresetId );
794 0 : rPresetSubType = OUString::createFromAscii( p->mpPresetSubType );
795 0 : return true;
796 : }
797 0 : p++;
798 : }
799 :
800 0 : return false;
801 : }
802 :
803 :
804 :
805 0 : double EffectMigration::ConvertAnimationSpeed( AnimationSpeed eSpeed )
806 : {
807 : double fDuration;
808 0 : switch( eSpeed )
809 : {
810 0 : case AnimationSpeed_SLOW: fDuration = 2.0; break;
811 0 : case AnimationSpeed_FAST: fDuration = 0.5; break;
812 : default:
813 0 : fDuration = 1.0; break;
814 : }
815 0 : return fDuration;
816 : }
817 :
818 :
819 0 : void EffectMigration::SetAnimationSpeed( SvxShape* pShape, AnimationSpeed eSpeed )
820 : {
821 : DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
822 : "sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
823 0 : if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
824 0 : return;
825 :
826 0 : SdrObject* pObj = pShape->GetSdrObject();
827 0 : if( implIsInsideGroup( pObj ) )
828 0 : return;
829 :
830 0 : double fDuration = ConvertAnimationSpeed( eSpeed );
831 :
832 0 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
833 :
834 0 : const Reference< XShape > xShape( pShape );
835 :
836 0 : EffectSequence::iterator aIter;
837 0 : bool bNeedRebuild = false;
838 :
839 0 : for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
840 : {
841 0 : CustomAnimationEffectPtr pEffect( (*aIter) );
842 0 : if( pEffect->getTargetShape() == xShape )
843 : {
844 0 : if( pEffect->getDuration() != 0.1 )
845 0 : pEffect->setDuration( fDuration );
846 0 : bNeedRebuild = true;
847 : }
848 0 : }
849 :
850 0 : if( bNeedRebuild )
851 0 : pMainSequence->rebuild();
852 : }
853 :
854 :
855 :
856 0 : AnimationSpeed EffectMigration::GetAnimationSpeed( SvxShape* pShape )
857 : {
858 0 : SdrObject* pObj = pShape->GetSdrObject();
859 0 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
860 :
861 0 : const Reference< XShape > xShape( pShape );
862 :
863 0 : EffectSequence::iterator aIter;
864 :
865 0 : double fDuration = 1.0;
866 :
867 0 : for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
868 : {
869 0 : CustomAnimationEffectPtr pEffect( (*aIter) );
870 0 : if( pEffect->getTargetShape() == xShape )
871 : {
872 0 : if( pEffect->getDuration() != 0.1 )
873 : {
874 0 : fDuration = pEffect->getDuration();
875 0 : break;
876 : }
877 : }
878 0 : }
879 :
880 0 : return ConvertDuration( fDuration );
881 : }
882 :
883 :
884 :
885 0 : AnimationSpeed EffectMigration::ConvertDuration( double fDuration )
886 : {
887 : AnimationSpeed eSpeed;
888 :
889 0 : if( fDuration < 1.0 )
890 0 : eSpeed = AnimationSpeed_FAST;
891 0 : else if( fDuration > 1.5 )
892 0 : eSpeed = AnimationSpeed_SLOW;
893 : else
894 0 : eSpeed = AnimationSpeed_MEDIUM;
895 :
896 0 : return eSpeed;
897 : }
898 :
899 :
900 :
901 0 : void EffectMigration::SetDimColor( SvxShape* pShape, sal_Int32 nColor )
902 : {
903 : DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
904 : "sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
905 0 : if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
906 0 : return;
907 :
908 0 : SdrObject* pObj = pShape->GetSdrObject();
909 0 : if( implIsInsideGroup( pObj ) )
910 0 : return;
911 :
912 0 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
913 :
914 0 : const Reference< XShape > xShape( pShape );
915 :
916 0 : EffectSequence::iterator aIter;
917 0 : bool bNeedRebuild = false;
918 :
919 0 : for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
920 : {
921 0 : CustomAnimationEffectPtr pEffect( (*aIter) );
922 0 : if( pEffect->getTargetShape() == xShape )
923 : {
924 0 : pEffect->setHasAfterEffect( true );
925 0 : pEffect->setDimColor( makeAny( nColor ) );
926 0 : pEffect->setAfterEffectOnNext( true );
927 0 : bNeedRebuild = true;
928 : }
929 0 : }
930 :
931 0 : if( bNeedRebuild )
932 0 : pMainSequence->rebuild();
933 : }
934 :
935 :
936 :
937 0 : sal_Int32 EffectMigration::GetDimColor( SvxShape* pShape )
938 : {
939 0 : sal_Int32 nColor = 0;
940 0 : if( pShape )
941 : {
942 0 : SdrObject* pObj = pShape->GetSdrObject();
943 0 : if( pObj && pObj->GetPage() )
944 : {
945 0 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
946 :
947 0 : const Reference< XShape > xShape( pShape );
948 0 : EffectSequence::iterator aIter;
949 :
950 0 : for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
951 : {
952 0 : CustomAnimationEffectPtr pEffect( (*aIter) );
953 0 : if( (pEffect->getTargetShape() == xShape) &&
954 0 : pEffect->getDimColor().hasValue() &&
955 0 : pEffect->hasAfterEffect())
956 : {
957 0 : pEffect->getDimColor() >>= nColor;
958 0 : break;
959 : }
960 0 : }
961 : }
962 : }
963 :
964 0 : return nColor;
965 : }
966 :
967 :
968 :
969 :
970 0 : void EffectMigration::SetDimHide( SvxShape* pShape, sal_Bool bDimHide )
971 : {
972 : DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
973 : "sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
974 0 : if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
975 0 : return;
976 :
977 0 : SdrObject* pObj = pShape->GetSdrObject();
978 0 : if( implIsInsideGroup( pObj ) )
979 0 : return;
980 :
981 0 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
982 :
983 0 : const Reference< XShape > xShape( pShape );
984 :
985 0 : EffectSequence::iterator aIter;
986 0 : bool bNeedRebuild = false;
987 :
988 0 : for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
989 : {
990 0 : CustomAnimationEffectPtr pEffect( (*aIter) );
991 0 : if( pEffect->getTargetShape() == xShape )
992 : {
993 0 : pEffect->setHasAfterEffect( bDimHide ? true : false );
994 0 : if( bDimHide ) {
995 0 : Any aEmpty;
996 0 : pEffect->setDimColor( aEmpty );
997 : }
998 0 : pEffect->setAfterEffectOnNext( false );
999 0 : bNeedRebuild = true;
1000 : }
1001 0 : }
1002 :
1003 0 : if( bNeedRebuild )
1004 0 : pMainSequence->rebuild();
1005 : }
1006 :
1007 :
1008 :
1009 0 : sal_Bool EffectMigration::GetDimHide( SvxShape* pShape )
1010 : {
1011 0 : sal_Bool bRet = sal_False;
1012 0 : if( pShape )
1013 : {
1014 0 : SdrObject* pObj = pShape->GetSdrObject();
1015 0 : if( pObj && pObj->GetPage() )
1016 : {
1017 0 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1018 :
1019 0 : const Reference< XShape > xShape( pShape );
1020 :
1021 0 : EffectSequence::iterator aIter;
1022 0 : for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
1023 : {
1024 0 : CustomAnimationEffectPtr pEffect( (*aIter) );
1025 0 : if( pEffect->getTargetShape() == xShape )
1026 : {
1027 0 : bRet = pEffect->hasAfterEffect() &&
1028 0 : !pEffect->getDimColor().hasValue() &&
1029 0 : (!pEffect->IsAfterEffectOnNext());
1030 0 : break;
1031 : }
1032 0 : }
1033 : }
1034 : }
1035 :
1036 0 : return bRet;
1037 : }
1038 :
1039 :
1040 :
1041 0 : void EffectMigration::SetDimPrevious( SvxShape* pShape, sal_Bool bDimPrevious )
1042 : {
1043 : DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
1044 : "sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
1045 0 : if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
1046 0 : return;
1047 :
1048 0 : SdrObject* pObj = pShape->GetSdrObject();
1049 0 : if( implIsInsideGroup( pObj ) )
1050 0 : return;
1051 :
1052 0 : Any aColor;
1053 :
1054 0 : if( bDimPrevious )
1055 0 : aColor <<= (sal_Int32)COL_LIGHTGRAY;
1056 :
1057 0 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1058 :
1059 0 : const Reference< XShape > xShape( pShape );
1060 :
1061 0 : EffectSequence::iterator aIter;
1062 0 : bool bNeedRebuild = false;
1063 :
1064 0 : for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
1065 : {
1066 0 : CustomAnimationEffectPtr pEffect( (*aIter) );
1067 0 : if( pEffect->getTargetShape() == xShape )
1068 : {
1069 0 : pEffect->setHasAfterEffect( bDimPrevious );
1070 0 : if( !bDimPrevious || !pEffect->getDimColor().hasValue() )
1071 0 : pEffect->setDimColor( aColor );
1072 0 : pEffect->setAfterEffectOnNext( true );
1073 0 : bNeedRebuild = true;
1074 : }
1075 0 : }
1076 :
1077 0 : if( bNeedRebuild )
1078 0 : pMainSequence->rebuild();
1079 : }
1080 :
1081 :
1082 :
1083 0 : sal_Bool EffectMigration::GetDimPrevious( SvxShape* pShape )
1084 : {
1085 0 : sal_Bool bRet = sal_False;
1086 0 : if( pShape )
1087 : {
1088 0 : SdrObject* pObj = pShape->GetSdrObject();
1089 0 : if( pObj && pObj->GetPage() )
1090 : {
1091 0 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1092 :
1093 0 : const Reference< XShape > xShape( pShape );
1094 :
1095 0 : EffectSequence::iterator aIter;
1096 0 : for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
1097 : {
1098 0 : CustomAnimationEffectPtr pEffect( (*aIter) );
1099 0 : if( pEffect->getTargetShape() == xShape )
1100 : {
1101 0 : bRet = pEffect->hasAfterEffect() &&
1102 0 : pEffect->getDimColor().hasValue() &&
1103 0 : pEffect->IsAfterEffectOnNext();
1104 0 : break;
1105 : }
1106 0 : }
1107 : }
1108 : }
1109 :
1110 0 : return bRet;
1111 : }
1112 :
1113 :
1114 :
1115 0 : void EffectMigration::SetPresentationOrder( SvxShape* pShape, sal_Int32 nNewPos )
1116 : {
1117 0 : if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
1118 0 : return;
1119 :
1120 0 : SdrObject* pObj = pShape->GetSdrObject();
1121 0 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1122 :
1123 0 : EffectSequence& rSequence = pMainSequence->getSequence();
1124 : sal_Int32 nPos;
1125 0 : sal_Int32 nCurrentPos = -1;
1126 0 : std::vector< std::vector< EffectSequence::iterator > > aEffectVector(1);
1127 :
1128 0 : if( !rSequence.empty() )
1129 : {
1130 0 : Reference< XShape > xThis( pShape );
1131 0 : Reference< XShape > xCurrent;
1132 :
1133 0 : EffectSequence::iterator aIter( rSequence.begin() );
1134 0 : EffectSequence::iterator aEnd( rSequence.end() );
1135 0 : for( nPos = 0; aIter != aEnd; ++aIter )
1136 : {
1137 0 : CustomAnimationEffectPtr pEffect = (*aIter);
1138 :
1139 0 : if( !xCurrent.is() )
1140 : {
1141 0 : xCurrent = pEffect->getTargetShape();
1142 : }
1143 0 : else if( pEffect->getTargetShape() != xCurrent )
1144 : {
1145 0 : nPos++;
1146 0 : xCurrent = pEffect->getTargetShape();
1147 0 : aEffectVector.resize( nPos+1 );
1148 : }
1149 :
1150 : // is this the first effect for xThis shape?
1151 0 : if(( nCurrentPos == -1 ) && ( xCurrent == xThis ) )
1152 : {
1153 0 : nCurrentPos = nPos;
1154 : }
1155 :
1156 0 : aEffectVector[nPos].push_back( aIter );
1157 0 : }
1158 : }
1159 :
1160 : // check if there is at least one effect for xThis
1161 0 : if( nCurrentPos == -1 )
1162 : {
1163 : OSL_FAIL("sd::EffectMigration::SetPresentationOrder() failed cause this shape has no effect" );
1164 0 : return;
1165 : }
1166 :
1167 : // check trivial case
1168 0 : if( nCurrentPos != nNewPos )
1169 : {
1170 0 : std::vector< CustomAnimationEffectPtr > aEffects;
1171 :
1172 0 : std::vector< EffectSequence::iterator >::iterator aIter( aEffectVector[nCurrentPos].begin() );
1173 0 : std::vector< EffectSequence::iterator >::iterator aEnd( aEffectVector[nCurrentPos].end() );
1174 0 : while( aIter != aEnd )
1175 : {
1176 0 : aEffects.push_back( (*(*aIter)) );
1177 0 : rSequence.erase( (*aIter++) );
1178 : }
1179 :
1180 0 : if( nNewPos > nCurrentPos )
1181 0 : nNewPos++;
1182 :
1183 0 : std::vector< CustomAnimationEffectPtr >::iterator aTempIter( aEffects.begin() );
1184 0 : std::vector< CustomAnimationEffectPtr >::iterator aTempEnd( aEffects.end() );
1185 :
1186 0 : if( nNewPos == (sal_Int32)aEffectVector.size() )
1187 : {
1188 0 : while( aTempIter != aTempEnd )
1189 : {
1190 0 : rSequence.push_back( (*aTempIter++) );
1191 : }
1192 : }
1193 : else
1194 : {
1195 0 : EffectSequence::iterator aPos( aEffectVector[nNewPos][0] );
1196 0 : while( aTempIter != aTempEnd )
1197 : {
1198 0 : rSequence.insert( aPos, (*aTempIter++) );
1199 : }
1200 0 : }
1201 0 : }
1202 : }
1203 :
1204 :
1205 :
1206 : /** Returns the position of the given SdrObject in the Presentation order.
1207 : * This function returns -1 if the SdrObject is not in the Presentation order
1208 : * or if its the path-object.
1209 : */
1210 0 : sal_Int32 EffectMigration::GetPresentationOrder( SvxShape* pShape )
1211 : {
1212 0 : sal_Int32 nPos = -1, nFound = -1;
1213 :
1214 0 : SdrObject* pObj = pShape->GetSdrObject();
1215 0 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1216 :
1217 0 : EffectSequence& rSequence = pMainSequence->getSequence();
1218 :
1219 0 : Reference< XShape > xThis( pShape );
1220 0 : Reference< XShape > xCurrent;
1221 :
1222 0 : EffectSequence::iterator aIter( rSequence.begin() );
1223 0 : EffectSequence::iterator aEnd( rSequence.end() );
1224 0 : for( ; aIter != aEnd; ++aIter )
1225 : {
1226 0 : CustomAnimationEffectPtr pEffect = (*aIter);
1227 :
1228 0 : if( !xCurrent.is() || pEffect->getTargetShape() != xCurrent )
1229 : {
1230 0 : nPos++;
1231 0 : xCurrent = pEffect->getTargetShape();
1232 :
1233 : // is this the first effect for xThis shape?
1234 0 : if( xCurrent == xThis )
1235 : {
1236 0 : nFound = nPos;
1237 0 : break;
1238 : }
1239 : }
1240 0 : }
1241 :
1242 0 : return nFound;
1243 : }
1244 :
1245 :
1246 :
1247 0 : void EffectMigration::UpdateSoundEffect( SvxShape* pShape, SdAnimationInfo* pInfo )
1248 : {
1249 0 : if( pInfo )
1250 : {
1251 0 : SdrObject* pObj = pShape->GetSdrObject();
1252 0 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1253 :
1254 0 : const Reference< XShape > xShape( pShape );
1255 :
1256 0 : EffectSequence::iterator aIter;
1257 0 : bool bNeedRebuild = false;
1258 :
1259 0 : OUString aSoundFile;
1260 0 : if( pInfo->mbSoundOn )
1261 0 : aSoundFile = pInfo->maSoundFile;
1262 :
1263 0 : for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
1264 : {
1265 0 : CustomAnimationEffectPtr pEffect( (*aIter) );
1266 0 : if( pEffect->getTargetShape() == xShape )
1267 : {
1268 0 : if( !aSoundFile.isEmpty() )
1269 : {
1270 0 : pEffect->createAudio( makeAny( aSoundFile ) );
1271 : }
1272 : else
1273 : {
1274 0 : pEffect->removeAudio();
1275 : }
1276 0 : bNeedRebuild = true;
1277 : }
1278 0 : }
1279 :
1280 0 : if( bNeedRebuild )
1281 0 : pMainSequence->rebuild();
1282 : }
1283 0 : }
1284 :
1285 :
1286 :
1287 0 : OUString EffectMigration::GetSoundFile( SvxShape* pShape )
1288 : {
1289 0 : OUString aSoundFile;
1290 :
1291 0 : if( pShape )
1292 : {
1293 0 : SdrObject* pObj = pShape->GetSdrObject();
1294 0 : if( pObj && pObj->GetPage() )
1295 : {
1296 0 : sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1297 :
1298 0 : const Reference< XShape > xShape( pShape );
1299 :
1300 0 : EffectSequence::iterator aIter;
1301 :
1302 0 : for( aIter = pMainSequence->getBegin();
1303 0 : (aSoundFile.isEmpty()) && (aIter != pMainSequence->getEnd());
1304 : ++aIter )
1305 : {
1306 0 : CustomAnimationEffectPtr pEffect( (*aIter) );
1307 0 : if( pEffect->getTargetShape() == xShape )
1308 : {
1309 0 : if( pEffect->getAudio().is() )
1310 0 : pEffect->getAudio()->getSource() >>= aSoundFile;
1311 : }
1312 0 : }
1313 : }
1314 : }
1315 0 : return aSoundFile;
1316 : }
1317 :
1318 :
1319 :
1320 0 : sal_Bool EffectMigration::GetSoundOn( SvxShape* pShape )
1321 : {
1322 0 : return !GetSoundFile( pShape ).isEmpty();
1323 : }
1324 :
1325 :
1326 :
1327 0 : void EffectMigration::SetAnimationPath( SvxShape* pShape, SdrPathObj* pPathObj )
1328 : {
1329 0 : if( pShape && pPathObj )
1330 : {
1331 0 : SdrObject* pObj = pShape->GetSdrObject();
1332 :
1333 0 : if( pObj )
1334 : {
1335 0 : const Reference< XShape > xShape( pShape );
1336 0 : SdPage* pPage = dynamic_cast< SdPage* >(pPathObj->GetPage());
1337 0 : if( pPage )
1338 : {
1339 0 : boost::shared_ptr< sd::MainSequence > pMainSequence( pPage->getMainSequence() );
1340 0 : if( pMainSequence.get() )
1341 0 : CustomAnimationEffectPtr pCreated( pMainSequence->append( *pPathObj, makeAny( xShape ), -1.0 ) );
1342 0 : }
1343 : }
1344 : }
1345 0 : }
1346 :
1347 : // #i42894# helper which creates the needed XAnimate for changing visibility and all the (currently) needed embeddings
1348 0 : void createVisibilityOnOffNode(Reference< XTimeContainer >& rxParentContainer, SdrObject& rCandidate, bool bVisible, bool bOnClick, double fDuration)
1349 : {
1350 0 : Reference< XMultiServiceFactory > xMsf(::comphelper::getProcessServiceFactory());
1351 0 : Any aAny;
1352 :
1353 : // create par container node
1354 0 : Reference< XAnimationNode > xOuterSeqTimeContainer(xMsf->createInstance("com.sun.star.animations.ParallelTimeContainer"), UNO_QUERY_THROW);
1355 :
1356 : // set begin
1357 0 : aAny <<= (double)(0.0);
1358 0 : xOuterSeqTimeContainer->setBegin(aAny);
1359 :
1360 : // set fill
1361 0 : xOuterSeqTimeContainer->setFill(AnimationFill::HOLD);
1362 :
1363 : // set named values
1364 0 : Sequence< NamedValue > aUserDataSequence;
1365 0 : aUserDataSequence.realloc(1);
1366 :
1367 0 : aUserDataSequence[0].Name = OUString("node-type");
1368 0 : aUserDataSequence[0].Value <<= bOnClick ? EffectNodeType::ON_CLICK : EffectNodeType::AFTER_PREVIOUS;
1369 :
1370 0 : xOuterSeqTimeContainer->setUserData(aUserDataSequence);
1371 :
1372 : // create animate set to change visibility for rCandidate
1373 0 : Reference< XAnimationNode > xAnimateSetForLast(xMsf->createInstance("com.sun.star.animations.AnimateSet"), UNO_QUERY_THROW);
1374 :
1375 : // set begin
1376 0 : aAny <<= (double)(0.0);
1377 0 : xAnimateSetForLast->setBegin(aAny);
1378 :
1379 : // set duration
1380 0 : aAny <<= fDuration;
1381 0 : xAnimateSetForLast->setDuration(aAny);
1382 :
1383 : // set fill
1384 0 : xAnimateSetForLast->setFill(AnimationFill::HOLD);
1385 :
1386 : // set target
1387 0 : Reference< XAnimate > xAnimate(xAnimateSetForLast, UNO_QUERY);
1388 0 : Reference< XShape > xTargetShape(rCandidate.getUnoShape(), UNO_QUERY);
1389 0 : aAny <<= xTargetShape;
1390 0 : xAnimate->setTarget(aAny);
1391 :
1392 : // set AttributeName
1393 0 : xAnimate->setAttributeName(OUString("Visibility"));
1394 :
1395 : // set attribute value
1396 0 : aAny <<= bVisible ? sal_True : sal_False;
1397 0 : xAnimate->setTo(aAny);
1398 :
1399 : // ad set node to par node
1400 0 : Reference< XTimeContainer > xParentContainer(xOuterSeqTimeContainer, UNO_QUERY_THROW);
1401 0 : xParentContainer->appendChild(xAnimateSetForLast);
1402 :
1403 : // add node
1404 0 : rxParentContainer->appendChild(xOuterSeqTimeContainer);
1405 0 : }
1406 :
1407 : // #i42894# older native formats supported animated group objects, that means all members of the group
1408 : // were shown animated by showing one after the other. This is no longer supported, but the following
1409 : // fallback will create the needed SMIL animation stuff. Unfortunately the members of the group
1410 : // have to be moved directly to the page, else the (explained to be generic, thus I expected this to
1411 : // work) animations will not work in slideshow
1412 0 : void EffectMigration::CreateAnimatedGroup(SdrObjGroup& rGroupObj, SdPage& rPage)
1413 : {
1414 : // aw080 will give a vector immeditately
1415 0 : SdrObjListIter aIter(rGroupObj);
1416 :
1417 0 : if(aIter.Count())
1418 : {
1419 0 : boost::shared_ptr< sd::MainSequence > pMainSequence(rPage.getMainSequence());
1420 :
1421 0 : if(pMainSequence.get())
1422 : {
1423 0 : std::vector< SdrObject* > aObjects;
1424 0 : aObjects.reserve(aIter.Count());
1425 :
1426 0 : while(aIter.IsMore())
1427 : {
1428 : // do move to page rough with old/current stuff, will be different in aw080 anyways
1429 0 : SdrObject* pCandidate = aIter.Next();
1430 0 : rGroupObj.GetSubList()->NbcRemoveObject(pCandidate->GetOrdNum());
1431 0 : rPage.NbcInsertObject(pCandidate);
1432 0 : aObjects.push_back(pCandidate);
1433 : }
1434 :
1435 : // create main node
1436 0 : Reference< XMultiServiceFactory > xMsf(::comphelper::getProcessServiceFactory());
1437 0 : Reference< XAnimationNode > xOuterSeqTimeContainer(xMsf->createInstance("com.sun.star.animations.ParallelTimeContainer"), UNO_QUERY_THROW);
1438 0 : Any aAny;
1439 :
1440 : // set begin
1441 0 : aAny <<= (double)(0.0);
1442 0 : xOuterSeqTimeContainer->setBegin(aAny);
1443 :
1444 : // prepare parent container
1445 0 : Reference< XTimeContainer > xParentContainer(xOuterSeqTimeContainer, UNO_QUERY_THROW);
1446 :
1447 : // prepare loop over objects
1448 0 : SdrObject* pLast = 0;
1449 0 : SdrObject* pNext = 0;
1450 0 : const double fDurationShow(0.2);
1451 0 : const double fDurationHide(0.001);
1452 :
1453 0 : for(sal_uInt32 a(0); a < aObjects.size(); a++)
1454 : {
1455 0 : pLast = pNext;
1456 0 : pNext = aObjects[a];
1457 :
1458 : // create node
1459 0 : if(pLast)
1460 : {
1461 0 : createVisibilityOnOffNode(xParentContainer, *pLast, false, false, fDurationHide);
1462 : }
1463 :
1464 0 : if(pNext)
1465 : {
1466 0 : createVisibilityOnOffNode(xParentContainer, *pNext, true, !a, fDurationShow);
1467 : }
1468 : }
1469 :
1470 : // create end node
1471 0 : if(pNext)
1472 : {
1473 0 : createVisibilityOnOffNode(xParentContainer, *pNext, false, false, fDurationHide);
1474 : }
1475 :
1476 : // add to main sequence and rebuild
1477 0 : pMainSequence->createEffects(xOuterSeqTimeContainer);
1478 0 : pMainSequence->rebuild();
1479 0 : }
1480 0 : }
1481 0 : }
1482 :
1483 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|