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