Version 6.1.0.2, tag libreoffice-6.1.0.2
[LibreOffice.git] / sd / source / core / EffectMigration.cxx
blob305ca6e9a585b73b0f1d54c44a04e0a781fba728
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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 <comphelper/processfactory.hxx>
25 #include <com/sun/star/animations/AnimationFill.hpp>
26 #include <com/sun/star/animations/XAnimate.hpp>
27 #include <com/sun/star/beans/NamedValue.hpp>
28 #include <svx/unoshape.hxx>
29 #include <svx/svdotext.hxx>
30 #include <svx/svdopath.hxx>
31 #include <svx/svdogrp.hxx>
32 #include <svx/svditer.hxx>
33 #include <drawdoc.hxx>
34 #include <sdpage.hxx>
35 #include <CustomAnimationPreset.hxx>
36 #include <TransitionPreset.hxx>
37 #include <EffectMigration.hxx>
38 #include <anminfo.hxx>
40 using namespace ::sd;
41 using namespace ::com::sun::star::uno;
42 using namespace ::com::sun::star::animations;
43 using namespace ::com::sun::star::presentation;
44 using ::com::sun::star::drawing::XShape;
45 using ::com::sun::star::lang::XMultiServiceFactory;
46 using ::com::sun::star::drawing::XShape;
47 using ::com::sun::star::beans::NamedValue;
49 struct deprecated_FadeEffect_conversion_table_entry
51 FadeEffect meFadeEffect;
52 const sal_Char* mpPresetId;
55 const deprecated_FadeEffect_conversion_table[] =
57 // OOo 1.x transitions
58 { FadeEffect_FADE_FROM_LEFT, "wipe-right" },
59 { FadeEffect_FADE_FROM_TOP, "wipe-down" },
60 { FadeEffect_FADE_FROM_RIGHT, "wipe-left" },
61 { FadeEffect_FADE_FROM_BOTTOM, "wipe-up" },
63 { FadeEffect_CLOCKWISE, "wheel-clockwise-1-spoke" },
65 { FadeEffect_UNCOVER_TO_LEFT, "uncover-left" },
66 { FadeEffect_UNCOVER_TO_UPPERLEFT, "uncover-left-up" },
67 { FadeEffect_UNCOVER_TO_TOP, "uncover-up" },
68 { FadeEffect_UNCOVER_TO_UPPERRIGHT, "uncover-right-up" },
69 { FadeEffect_UNCOVER_TO_RIGHT, "uncover-right" },
70 { FadeEffect_UNCOVER_TO_LOWERRIGHT, "uncover-right-down" },
71 { FadeEffect_UNCOVER_TO_BOTTOM, "uncover-down" },
72 { FadeEffect_UNCOVER_TO_LOWERLEFT, "uncover-left-down" },
74 { FadeEffect_VERTICAL_LINES, "random-bars-vertical" },
75 { FadeEffect_HORIZONTAL_LINES, "random-bars-horizontal" },
77 { FadeEffect_VERTICAL_CHECKERBOARD, "checkerboard-down" },
78 { FadeEffect_HORIZONTAL_CHECKERBOARD, "checkerboard-across" },
80 { FadeEffect_FADE_TO_CENTER, "box-in" },
81 { FadeEffect_FADE_FROM_CENTER, "box-out" },
83 { FadeEffect_VERTICAL_STRIPES, "venetian-blinds-vertical" },
84 { FadeEffect_HORIZONTAL_STRIPES, "venetian-blinds-horizontal" },
86 { FadeEffect_MOVE_FROM_LEFT, "cover-right" },
87 { FadeEffect_MOVE_FROM_TOP, "cover-down" },
88 { FadeEffect_MOVE_FROM_RIGHT, "cover-left" },
89 { FadeEffect_MOVE_FROM_BOTTOM, "cover-up" },
90 { FadeEffect_MOVE_FROM_UPPERLEFT, "cover-right-down" },
91 { FadeEffect_MOVE_FROM_UPPERRIGHT, "cover-left-down" },
92 { FadeEffect_MOVE_FROM_LOWERRIGHT, "cover-left-up" },
93 { FadeEffect_MOVE_FROM_LOWERLEFT, "cover-right-up" },
95 { FadeEffect_DISSOLVE, "dissolve" },
97 { FadeEffect_RANDOM, "random-transition" },
99 { FadeEffect_ROLL_FROM_LEFT, "push-right" },
100 { FadeEffect_ROLL_FROM_TOP, "push-down" },
101 { FadeEffect_ROLL_FROM_RIGHT, "push-left" },
102 { FadeEffect_ROLL_FROM_BOTTOM, "push-up" },
104 { FadeEffect_CLOSE_VERTICAL, "split-horizontal-in" },
105 { FadeEffect_CLOSE_HORIZONTAL, "split-vertical-in" },
106 { FadeEffect_OPEN_VERTICAL, "split-horizontal-out" },
107 { FadeEffect_OPEN_HORIZONTAL, "split-vertical-out" },
109 { FadeEffect_FADE_FROM_UPPERLEFT, "diagonal-squares-right-down" },
110 { FadeEffect_FADE_FROM_UPPERRIGHT, "diagonal-squares-left-down" },
111 { FadeEffect_FADE_FROM_LOWERLEFT, "diagonal-squares-right-up" },
112 { FadeEffect_FADE_FROM_LOWERRIGHT, "diagonal-squares-left-up" },
114 // OOo 1.x transitions not in OOo 2.x
115 { FadeEffect_CLOCKWISE, "clock-wipe-twelve" },
116 { FadeEffect_COUNTERCLOCKWISE, "reverse-clock-wipe-twelve" },
117 { FadeEffect_SPIRALIN_LEFT, "spiral-wipe-top-left-clockwise" },
118 { FadeEffect_SPIRALIN_RIGHT, "spiral-wipe-top-right-counter-clockwise" },
119 { FadeEffect_SPIRALOUT_LEFT, "spiral-wipe-out-to-bottom-right-clockwise" },
120 { FadeEffect_SPIRALOUT_RIGHT, "spiral-wipe-out-to-bottom-left-counter-clockwise" },
121 { FadeEffect_WAVYLINE_FROM_LEFT, "snake-wipe-top-left-vertical" },
122 { FadeEffect_WAVYLINE_FROM_TOP, "snake-wipe-top-left-horizontal" },
123 { FadeEffect_WAVYLINE_FROM_RIGHT, "snake-wipe-bottom-right-vertical" },
124 { FadeEffect_WAVYLINE_FROM_BOTTOM, "snake-wipe-bottom-right-horizontal" },
125 { FadeEffect_STRETCH_FROM_LEFT, "wipe-right" }, // todo
126 { FadeEffect_STRETCH_FROM_TOP, "wipe-down" }, // todo
127 { FadeEffect_STRETCH_FROM_RIGHT, "wipe-left" }, // todo
128 { FadeEffect_STRETCH_FROM_BOTTOM, "wipe-up" }, // todo
130 // OOo 1.x not available transitions
132 { FadeEffect_CLOCKWISE, "wheel-clockwise-2-spokes" },
133 { FadeEffect_CLOCKWISE, "wheel-clockwise-3-spokes" },
134 { FadeEffect_CLOCKWISE, "wheel-clockwise-4-spokes" },
135 { FadeEffect_CLOCKWISE, "wheel-clockwise-8-spokes" },
137 { FadeEffect_FADE_FROM_CENTER, "shape-circle" },
138 { FadeEffect_FADE_FROM_CENTER, "shape-diamond" },
139 { FadeEffect_FADE_FROM_CENTER, "shape-plus" },
141 { FadeEffect_CLOCKWISE, "wedge" },
143 { FadeEffect_DISSOLVE, "fade-through-black" },
145 { FadeEffect_CLOCKWISE, "zoom-rotate-in" },
147 { FadeEffect_HORIZONTAL_LINES, "comb-horizontal" },
148 { FadeEffect_VERTICAL_LINES, "comb-vertical" },
150 { FadeEffect_DISSOLVE, "fade-smoothly" },
152 { FadeEffect_NONE, nullptr }
155 /* todo
156 cut cut (same as NONE?)
157 cut-through-black cut toBlack
158 wedge wedge
161 void EffectMigration::SetFadeEffect( SdPage* pPage, css::presentation::FadeEffect eNewEffect)
163 deprecated_FadeEffect_conversion_table_entry const * pEntry = deprecated_FadeEffect_conversion_table;
164 while( (pEntry->meFadeEffect != FadeEffect_NONE) && (pEntry->meFadeEffect != eNewEffect) )
165 pEntry++;
167 if( pEntry->mpPresetId )
169 const OUString aPresetId( OUString::createFromAscii( pEntry->mpPresetId ) );
171 const TransitionPresetList& rPresetList = TransitionPreset::getTransitionPresetList();
173 TransitionPresetList::const_iterator aIt( rPresetList.begin());
174 const TransitionPresetList::const_iterator aEndIt( rPresetList.end());
175 for( ; aIt != aEndIt; ++aIt )
177 if( (*aIt)->getPresetId() == aPresetId)
179 pPage->setTransitionType( (*aIt)->getTransition() );
180 pPage->setTransitionSubtype( (*aIt)->getSubtype() );
181 pPage->setTransitionDirection( (*aIt)->getDirection() );
182 pPage->setTransitionFadeColor( (*aIt)->getFadeColor() );
183 break;
187 else
189 pPage->setTransitionType( 0 );
190 pPage->setTransitionSubtype( 0 );
191 pPage->setTransitionDirection( false );
192 pPage->setTransitionFadeColor( 0 );
196 FadeEffect EffectMigration::GetFadeEffect( const SdPage* pPage )
198 const TransitionPresetList & rPresetList = TransitionPreset::getTransitionPresetList();
199 TransitionPresetList::const_iterator aIt( rPresetList.begin());
200 const TransitionPresetList::const_iterator aEndIt( rPresetList.end());
201 for( ; aIt != aEndIt; ++aIt )
203 if( ( (*aIt)->getTransition() == pPage->getTransitionType() ) &&
204 ( (*aIt)->getSubtype() == pPage->getTransitionSubtype() ) &&
205 ( (*aIt)->getDirection() == pPage->getTransitionDirection() ) &&
206 ( (*aIt)->getFadeColor() == pPage->getTransitionFadeColor() ) )
208 const OUString& aPresetId = (*aIt)->getPresetId();
210 deprecated_FadeEffect_conversion_table_entry const * pEntry = deprecated_FadeEffect_conversion_table;
211 while( (pEntry->meFadeEffect != FadeEffect_NONE) && (!aPresetId.equalsAscii( pEntry->mpPresetId ) ) )
212 pEntry++;
214 return pEntry->meFadeEffect;
217 return FadeEffect_NONE;
220 struct deprecated_AnimationEffect_conversion_table_entry
222 AnimationEffect meEffect;
223 const sal_Char* mpPresetId;
224 const sal_Char* mpPresetSubType;
226 const deprecated_AnimationEffect_conversion_table[] =
228 // OOo 1.x entrance effects
229 { AnimationEffect_APPEAR, "ooo-entrance-appear",nullptr },
231 { AnimationEffect_FADE_TO_CENTER, "ooo-entrance-box","in" },
232 { AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-box","out" },
234 { AnimationEffect_VERTICAL_CHECKERBOARD, "ooo-entrance-checkerboard","downward" },
235 { AnimationEffect_HORIZONTAL_CHECKERBOARD, "ooo-entrance-checkerboard","across" },
237 { AnimationEffect_FADE_FROM_UPPERLEFT, "ooo-entrance-diagonal-squares","right-to-bottom" },
238 { AnimationEffect_FADE_FROM_UPPERRIGHT, "ooo-entrance-diagonal-squares","left-to-bottom" },
239 { AnimationEffect_FADE_FROM_LOWERLEFT, "ooo-entrance-diagonal-squares","right-to-top" },
240 { AnimationEffect_FADE_FROM_LOWERRIGHT, "ooo-entrance-diagonal-squares","left-to-top" },
242 { AnimationEffect_DISSOLVE, "ooo-entrance-dissolve-in",nullptr },
244 { AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-fly-in","from-left" },
245 { AnimationEffect_MOVE_FROM_TOP, "ooo-entrance-fly-in","from-top" },
246 { AnimationEffect_MOVE_FROM_RIGHT, "ooo-entrance-fly-in","from-right" },
247 { AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-fly-in","from-bottom" },
248 { AnimationEffect_MOVE_FROM_UPPERLEFT, "ooo-entrance-fly-in","from-top-left" },
249 { AnimationEffect_MOVE_FROM_UPPERRIGHT, "ooo-entrance-fly-in","from-top-right" },
250 { AnimationEffect_MOVE_FROM_LOWERRIGHT, "ooo-entrance-fly-in","from-bottom-right" },
251 { AnimationEffect_MOVE_FROM_LOWERLEFT, "ooo-entrance-fly-in","from-bottom-left" },
253 { AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-fly-in-slow", "from-bottom" },
254 { AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-fly-in-slow", "from-left" },
255 { AnimationEffect_MOVE_FROM_RIGHT, "ooo-entrance-fly-in-slow", "from-right" },
256 { AnimationEffect_MOVE_FROM_TOP, "ooo-entrance-fly-in-slow", "from-top" },
258 { AnimationEffect_MOVE_SHORT_FROM_LEFT, "ooo-entrance-peek-in","from-left" },
259 { AnimationEffect_MOVE_SHORT_FROM_TOP, "ooo-entrance-peek-in","from-top" },
260 { AnimationEffect_MOVE_SHORT_FROM_RIGHT, "ooo-entrance-peek-in","from-right" },
261 { AnimationEffect_MOVE_SHORT_FROM_BOTTOM, "ooo-entrance-peek-in","from-bottom" },
263 { AnimationEffect_VERTICAL_LINES, "ooo-entrance-random-bars","horizontal" },
264 { AnimationEffect_HORIZONTAL_LINES, "ooo-entrance-random-bars","vertical" },
266 { AnimationEffect_RANDOM, "ooo-entrance-random",nullptr },
268 { AnimationEffect_CLOSE_VERTICAL, "ooo-entrance-split","horizontal-in" },
269 { AnimationEffect_CLOSE_HORIZONTAL, "ooo-entrance-split","vertical-in" },
270 { AnimationEffect_OPEN_VERTICAL, "ooo-entrance-split","horizontal-out" },
271 { AnimationEffect_OPEN_HORIZONTAL, "ooo-entrance-split","vertical-out" },
273 { AnimationEffect_VERTICAL_STRIPES, "ooo-entrance-venetian-blinds","horizontal" },
274 { AnimationEffect_HORIZONTAL_STRIPES, "ooo-entrance-venetian-blinds","vertical" },
276 { AnimationEffect_FADE_FROM_LEFT, "ooo-entrance-wipe","from-left" },
277 { AnimationEffect_FADE_FROM_TOP, "ooo-entrance-wipe","from-bottom" },
278 { AnimationEffect_FADE_FROM_RIGHT, "ooo-entrance-wipe","from-right" },
279 { AnimationEffect_FADE_FROM_BOTTOM, "ooo-entrance-wipe","from-top" },
281 { AnimationEffect_HORIZONTAL_ROTATE, "ooo-entrance-swivel","vertical" },
282 { AnimationEffect_VERTICAL_ROTATE, "ooo-entrance-swivel","horizontal" },
284 { AnimationEffect_STRETCH_FROM_LEFT, "ooo-entrance-stretchy","from-left" },
285 { AnimationEffect_STRETCH_FROM_UPPERLEFT, "ooo-entrance-stretchy","from-top-left" },
286 { AnimationEffect_STRETCH_FROM_TOP, "ooo-entrance-stretchy","from-top" },
287 { AnimationEffect_STRETCH_FROM_UPPERRIGHT, "ooo-entrance-stretchy","from-top-right" },
288 { AnimationEffect_STRETCH_FROM_RIGHT, "ooo-entrance-stretchy","from-right" },
289 { AnimationEffect_STRETCH_FROM_LOWERRIGHT, "ooo-entrance-stretchy","from-bottom-right" },
290 { AnimationEffect_STRETCH_FROM_BOTTOM, "ooo-entrance-stretchy","from-bottom" },
291 { AnimationEffect_STRETCH_FROM_LOWERLEFT, "ooo-entrance-stretchy","from-bottom-left" },
293 { AnimationEffect_HORIZONTAL_STRETCH, "ooo-entrance-expand", nullptr },
295 { AnimationEffect_CLOCKWISE, "ooo-entrance-wheel","1" },
296 { AnimationEffect_COUNTERCLOCKWISE, "ooo-entrance-clock-wipe","counter-clockwise" },
298 { AnimationEffect_SPIRALIN_LEFT, "ooo-entrance-spiral-wipe", "from-top-left-clockwise" },
299 { AnimationEffect_SPIRALIN_RIGHT, "ooo-entrance-spiral-wipe", "from-top-right-counter-clockwise" },
300 { AnimationEffect_SPIRALOUT_LEFT, "ooo-entrance-spiral-wipe", "from-center-clockwise" },
301 { AnimationEffect_SPIRALOUT_RIGHT, "ooo-entrance-spiral-wipe", "from-center-counter-clockwise" },
303 { AnimationEffect_WAVYLINE_FROM_LEFT, "ooo-entrance-snake-wipe","from-top-left-vertical" },
304 { AnimationEffect_WAVYLINE_FROM_TOP, "ooo-entrance-snake-wipe","from-top-left-horizontal" },
305 { AnimationEffect_WAVYLINE_FROM_RIGHT, "ooo-entrance-snake-wipe","from-bottom-right-vertical" },
306 { AnimationEffect_WAVYLINE_FROM_BOTTOM, "ooo-entrance-snake-wipe","from-bottom-right-horizontal" },
308 // ooo 1.x exit effects
309 { AnimationEffect_HIDE, "ooo-exit-disappear",nullptr },
310 { AnimationEffect_MOVE_TO_LEFT, "ooo-exit-fly-out", "from-right" },
311 { AnimationEffect_MOVE_TO_TOP, "ooo-exit-fly-out", "from-bottom" },
312 { AnimationEffect_MOVE_TO_RIGHT, "ooo-exit-fly-out", "from-left" },
313 { AnimationEffect_MOVE_TO_BOTTOM, "ooo-exit-fly-out", "from-top" },
314 { AnimationEffect_MOVE_TO_UPPERLEFT, "ooo-exit-fly-out", "from-top-right" },
315 { AnimationEffect_MOVE_TO_UPPERRIGHT, "ooo-exit-fly-out", "from-top-left" },
316 { AnimationEffect_MOVE_TO_LOWERRIGHT, "ooo-exit-fly-out", "from-bottom-left" },
317 { AnimationEffect_MOVE_TO_LOWERLEFT, "ooo-exit-fly-out", "from-bottom-right" },
318 { AnimationEffect_MOVE_SHORT_TO_LEFT, "ooo-exit-peek-out", "from-right" },
319 { AnimationEffect_MOVE_SHORT_TO_UPPERLEFT, "ooo-exit-peek-out", "from-right" },
320 { AnimationEffect_MOVE_SHORT_TO_TOP, "ooo-exit-peek-out", "from-bottom" },
321 { AnimationEffect_MOVE_SHORT_TO_UPPERRIGHT, "ooo-exit-peek-out", "from-bottom" },
322 { AnimationEffect_MOVE_SHORT_TO_RIGHT, "ooo-exit-peek-out", "from-left" },
323 { AnimationEffect_MOVE_SHORT_TO_LOWERRIGHT, "ooo-exit-peek-out","from-left" },
324 { AnimationEffect_MOVE_SHORT_TO_BOTTOM, "ooo-exit-peek-out", "from-top" },
325 { AnimationEffect_MOVE_SHORT_TO_LOWERLEFT, "ooo-exit-peek-out", "from-top" },
327 // no matching in OOo 2.x
328 { AnimationEffect_MOVE_SHORT_FROM_UPPERLEFT, "ooo-entrance-peek-in","from-left" },
329 { AnimationEffect_MOVE_SHORT_FROM_UPPERRIGHT, "ooo-entrance-peek-in","from-top" },
330 { AnimationEffect_MOVE_SHORT_FROM_LOWERRIGHT, "ooo-entrance-peek-in","from-right" },
331 { AnimationEffect_MOVE_SHORT_FROM_LOWERLEFT, "ooo-entrance-peek-in","from-bottom" },
332 { AnimationEffect_LASER_FROM_LEFT, "ooo-entrance-fly-in","from-left" },
333 { AnimationEffect_LASER_FROM_TOP, "ooo-entrance-fly-in","from-top" },
334 { AnimationEffect_LASER_FROM_RIGHT, "ooo-entrance-fly-in","from-right" },
335 { AnimationEffect_LASER_FROM_BOTTOM, "ooo-entrance-fly-in","from-bottom" },
336 { AnimationEffect_LASER_FROM_UPPERLEFT, "ooo-entrance-fly-in","from-top-left" },
337 { AnimationEffect_LASER_FROM_UPPERRIGHT, "ooo-entrance-fly-in","from-top-right" },
338 { AnimationEffect_LASER_FROM_LOWERLEFT, "ooo-entrance-fly-in","from-bottom-left" },
339 { AnimationEffect_LASER_FROM_LOWERRIGHT, "ooo-entrance-fly-in","from-bottom-right" },
341 // no matching in OOo 1.x
343 { AnimationEffect_FADE_TO_CENTER, "ooo-entrance-circle", "in" },
344 { AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-circle", "out" },
345 { AnimationEffect_FADE_TO_CENTER, "ooo-entrance-diamond", "in" },
346 { AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-diamond", "out" },
347 { AnimationEffect_FADE_TO_CENTER, "ooo-entrance-plus", "in" },
348 { AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-plus", "out" },
349 { AnimationEffect_CLOCKWISE, "ooo-entrance-wedge", nullptr },
350 { AnimationEffect_CLOCKWISE, "ooo-entrance-wheel", "2" },
351 { AnimationEffect_CLOCKWISE, "ooo-entrance-wheel", "3" },
352 { AnimationEffect_CLOCKWISE, "ooo-entrance-wheel", "4" },
353 { AnimationEffect_CLOCKWISE, "ooo-entrance-wheel", "8" },
355 { AnimationEffect_MOVE_FROM_RIGHT, "ooo-entrance-boomerang", nullptr },
356 { AnimationEffect_MOVE_FROM_UPPERRIGHT, "ooo-entrance-bounce", nullptr },
357 { AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-curve-up", nullptr },
358 { AnimationEffect_MOVE_FROM_TOP, "ooo-entrance-float", nullptr },
359 { AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-glide", nullptr },
360 { AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-magnify", nullptr },
361 { AnimationEffect_HORIZONTAL_ROTATE, "ooo-entrance-pinwheel", nullptr },
362 { AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-breaks", nullptr },
363 { AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-sling", nullptr },
364 { AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-spiral-in", nullptr },
365 { AnimationEffect_MOVE_FROM_LEFT, "ooo-entrance-thread", nullptr },
366 { AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-ascend", nullptr },
367 { AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-center-revolve", nullptr },
368 { AnimationEffect_APPEAR, "ooo-entrance-compress", nullptr },
369 { AnimationEffect_MOVE_SHORT_FROM_TOP, "ooo-entrance-descend", nullptr },
370 { AnimationEffect_MOVE_SHORT_FROM_LEFT, "ooo-entrance-ease-in", nullptr },
371 { AnimationEffect_MOVE_FROM_BOTTOM, "ooo-entrance-rise-up", nullptr },
372 { AnimationEffect_HORIZONTAL_ROTATE, "ooo-entrance-spin-in", nullptr },
373 { AnimationEffect_STRETCH_FROM_LEFT, "ooo-entrance-stretchy", "across" },
374 { AnimationEffect_STRETCH_FROM_TOP, "ooo-entrance-stretchy", "downward" },
376 { AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-zoom","in" },
377 { AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-zoom","in-slightly" },
378 { AnimationEffect_FADE_FROM_CENTER, "ooo-entrance-zoom","in-from-screen-center" },
379 { AnimationEffect_FADE_TO_CENTER, "ooo-entrance-zoom","out" },
380 { AnimationEffect_FADE_TO_CENTER, "ooo-entrance-zoom","out-slightly" },
381 { AnimationEffect_FADE_TO_CENTER, "ooo-entrance-zoom","out-from-screen-center" },
383 { AnimationEffect_DISSOLVE, "ooo-entrance-fade-in", nullptr },
384 { AnimationEffect_DISSOLVE, "ooo-entrance-fade-in-and-zoom", nullptr },
385 { AnimationEffect_DISSOLVE, "ooo-entrance-fade-in-and-swivel", nullptr },
387 // still open (no matching effect: AnimationEffect_ZOOM_IN_FROM_*,
388 // AnimationEffect_ZOOM_OUT_FROM_*, AnimationEffect_PATH
390 { AnimationEffect_NONE, nullptr, nullptr }
393 EffectSequence::iterator ImplFindEffect( MainSequencePtr const & pMainSequence, const Reference< XShape >& rShape, sal_Int16 nSubItem )
395 EffectSequence::iterator aIter;
397 for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
399 CustomAnimationEffectPtr pEffect( (*aIter) );
400 if( (pEffect->getTargetShape() == rShape) && (pEffect->getTargetSubItem() == nSubItem) )
401 break;
404 return aIter;
407 static bool implIsInsideGroup( SdrObject const * pObj )
409 return pObj && pObj->getParentOfSdrObject() && pObj->getParentOfSdrObject()->GetUpList();
412 void EffectMigration::SetAnimationEffect( SvxShape* pShape, AnimationEffect eEffect )
414 DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
415 "sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
416 if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
417 return;
419 SdrObject* pObj = pShape->GetSdrObject();
420 if( implIsInsideGroup( pObj ) )
421 return;
423 OUString aPresetId;
424 OUString aPresetSubType;
426 if( !ConvertAnimationEffect( eEffect, aPresetId, aPresetSubType ) )
428 OSL_FAIL( "sd::EffectMigration::SetAnimationEffect(), no mapping for given AnimationEffect value" );
429 return;
432 const CustomAnimationPresets& rPresets = CustomAnimationPresets::getCustomAnimationPresets();
434 CustomAnimationPresetPtr pPreset( rPresets.getEffectDescriptor( aPresetId ) );
435 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
437 if( pPreset.get() && pMainSequence.get() )
439 const Reference< XShape > xShape( pShape );
441 EffectSequence::iterator aIterOnlyBackground( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_BACKGROUND ) );
442 EffectSequence::iterator aIterAsWhole( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::AS_WHOLE ) );
443 const EffectSequence::iterator aEnd( pMainSequence->getEnd() );
445 if( (aIterOnlyBackground == aEnd) && (aIterAsWhole == aEnd) )
447 bool bEffectCreated = false;
449 // check if there is already an text effect for this shape
450 EffectSequence::iterator aIterOnlyText( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_TEXT ) );
451 if( aIterOnlyText != aEnd )
453 // check if this is an animation text group
454 sal_Int32 nGroupId = (*aIterOnlyText)->getGroupId();
455 if( nGroupId >= 0 )
457 CustomAnimationTextGroupPtr pGroup = pMainSequence->findGroup( nGroupId );
458 if( pGroup.get() )
460 // add an effect to animate the shape
461 pMainSequence->setAnimateForm( pGroup, true );
463 // find this effect
464 EffectSequence::iterator aIter( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_BACKGROUND ) );
466 if( aIter != aEnd )
468 if( ((*aIter)->getPresetId() != aPresetId) ||
469 ((*aIter)->getPresetSubType() != aPresetSubType) )
471 (*aIter)->replaceNode( pPreset->create( aPresetSubType ) );
472 pMainSequence->rebuild();
473 bEffectCreated = true;
480 if( !bEffectCreated )
482 // if there is not yet an effect that target this shape, we generate one
483 // we insert the shape effect before it
484 Reference< XAnimationNode > xNode( pPreset->create( aPresetSubType ) );
485 DBG_ASSERT( xNode.is(), "EffectMigration::SetAnimationEffect(), could not create preset!" );
486 if( xNode.is() )
488 CustomAnimationEffectPtr pEffect( new CustomAnimationEffect( xNode ) );
489 pEffect->setTarget( makeAny( xShape ) );
490 SdPage* pPage = dynamic_cast< SdPage* >( pObj->GetPage() );
491 const bool bManual = (pPage == nullptr) || (pPage->GetPresChange() == PRESCHANGE_MANUAL);
492 if( !bManual )
493 pEffect->setNodeType( EffectNodeType::AFTER_PREVIOUS );
495 pMainSequence->append( pEffect );
497 if( ( pObj->GetObjInventor() == SdrInventor::Default ) && ( pObj->GetObjIdentifier() == OBJ_OUTLINETEXT ) )
499 // special case for outline text, effects are always mapped to text group effect
500 pMainSequence->
501 createTextGroup( pEffect, 10, bManual ? -1 : 0.0, false, false );
506 else
508 // if there is already an effect targeting this shape
509 // just replace it
510 CustomAnimationEffectPtr pEffect;
511 if( aIterAsWhole != aEnd )
513 pEffect = (*aIterAsWhole);
515 else
517 pEffect = (*aIterOnlyBackground);
520 if( pEffect.get() )
522 if( (pEffect->getPresetId() != aPresetId) ||
523 (pEffect->getPresetSubType() != aPresetSubType) )
525 pMainSequence->replace( pEffect, pPreset, aPresetSubType, -1.0 );
532 AnimationEffect EffectMigration::GetAnimationEffect( SvxShape* pShape )
534 OUString aPresetId;
535 OUString aPresetSubType;
537 SdrObject* pObj = pShape->GetSdrObject();
538 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
540 if( pMainSequence.get() )
542 const Reference< XShape > xShape( pShape );
544 EffectSequence::iterator aIter;
546 for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
548 CustomAnimationEffectPtr pEffect( (*aIter) );
549 if( pEffect->getTargetShape() == xShape )
551 if( (pEffect->getTargetSubItem() == ShapeAnimationSubType::ONLY_BACKGROUND) ||
552 (pEffect->getTargetSubItem() == ShapeAnimationSubType::AS_WHOLE))
554 if( pEffect->getDuration() != 0.1 ) // ignore appear effects created from old text effect import
556 aPresetId = (*aIter)->getPresetId();
557 aPresetSubType = (*aIter)->getPresetSubType();
558 break;
565 // now find old effect
566 AnimationEffect eEffect = AnimationEffect_NONE;
568 if( !ConvertPreset( aPresetId, &aPresetSubType, eEffect ) )
569 ConvertPreset( aPresetId, nullptr, eEffect );
571 return eEffect;
574 void EffectMigration::SetTextAnimationEffect( SvxShape* pShape, AnimationEffect eEffect )
576 DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
577 "sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
578 if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
579 return;
581 SdrObject* pObj = pShape->GetSdrObject();
582 if( implIsInsideGroup( pObj ) )
583 return;
585 // first map the deprecated AnimationEffect to a preset and subtype
586 OUString aPresetId;
587 OUString aPresetSubType;
589 if( !ConvertAnimationEffect( eEffect, aPresetId, aPresetSubType ) )
591 OSL_FAIL( "sd::EffectMigration::SetAnimationEffect(), no mapping for given AnimationEffect value" );
592 return;
595 SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( pObj );
597 // ignore old text effects on shape without text
598 if( (pTextObj == nullptr) || (!pTextObj->HasText()) )
599 return;
601 const CustomAnimationPresets& rPresets = CustomAnimationPresets::getCustomAnimationPresets();
603 // create an effect from this preset
604 CustomAnimationPresetPtr pPreset( rPresets.getEffectDescriptor( aPresetId ) );
606 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
608 if( pPreset.get() && pMainSequence.get() )
610 const Reference< XShape > xShape( pShape );
612 EffectSequence::iterator aIterOnlyText( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_TEXT ) );
613 const EffectSequence::iterator aEnd( pMainSequence->getEnd() );
615 CustomAnimationTextGroupPtr pGroup;
617 // is there already an animation text group for this shape?
618 if( aIterOnlyText != aEnd )
620 const sal_Int32 nGroupId = (*aIterOnlyText)->getGroupId();
621 if( nGroupId >= 0 )
622 pGroup = pMainSequence->findGroup( nGroupId );
625 // if there is not yet a group, create it
626 if( pGroup.get() == nullptr )
628 CustomAnimationEffectPtr pShapeEffect;
630 EffectSequence::iterator aIterOnlyBackground( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_BACKGROUND ) );
631 if( aIterOnlyBackground != aEnd )
633 pShapeEffect = (*aIterOnlyBackground);
635 else
637 EffectSequence::iterator aIterAsWhole( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::AS_WHOLE ) );
638 if( aIterAsWhole != aEnd )
640 pShapeEffect = (*aIterAsWhole);
642 else
644 CustomAnimationPresetPtr pShapePreset( rPresets.getEffectDescriptor( "ooo-entrance-appear" ) );
646 Reference< XAnimationNode > xNode( pPreset->create( "" ) );
647 DBG_ASSERT( xNode.is(), "EffectMigration::SetTextAnimationEffect(), could not create preset!" );
648 if( xNode.is() )
650 pShapeEffect.reset( new CustomAnimationEffect( xNode ) );
651 pShapeEffect->setTarget( makeAny( xShape ) );
652 pShapeEffect->setDuration( 0.1 );
653 pMainSequence->append( pShapeEffect );
655 SdPage* pPage = dynamic_cast< SdPage* >( pObj->GetPage() );
656 if( pPage && pPage->GetPresChange() != PRESCHANGE_MANUAL )
657 pShapeEffect->setNodeType( EffectNodeType::AFTER_PREVIOUS );
662 if( pShapeEffect.get() )
664 SdPage* pPage = dynamic_cast< SdPage* >( pObj->GetPage() );
665 const bool bManual = (pPage == nullptr) || (pPage->GetPresChange() == PRESCHANGE_MANUAL);
667 // now create effects for each paragraph
668 pGroup =
669 pMainSequence->
670 createTextGroup( pShapeEffect, 10, bManual ? -1 : 0.0, true, false );
674 if( pGroup.get() != nullptr )
676 const bool bLaserEffect = (eEffect >= AnimationEffect_LASER_FROM_LEFT) && (eEffect <= AnimationEffect_LASER_FROM_LOWERRIGHT);
678 // now we have a group, so check if all effects are same as we like to have them
679 const EffectSequence& rEffects = pGroup->getEffects();
681 EffectSequence::const_iterator aIter;
682 for( aIter = rEffects.begin(); aIter != rEffects.end(); ++aIter )
684 // only work on paragraph targets
685 if( (*aIter)->getTarget().getValueType() == ::cppu::UnoType<ParagraphTarget>::get() )
687 if( ((*aIter)->getPresetId() != aPresetId) ||
688 ((*aIter)->getPresetSubType() != aPresetSubType) )
690 (*aIter)->replaceNode( pPreset->create( aPresetSubType ) );
693 if( bLaserEffect )
695 (*aIter)->setIterateType( TextAnimationType::BY_LETTER );
696 (*aIter)->setIterateInterval( 0.5 );// TODO:
697 // Determine
698 // interval
699 // according
700 // to
701 // total
702 // effect
703 // duration
708 pMainSequence->rebuild();
712 AnimationEffect EffectMigration::GetTextAnimationEffect( SvxShape* pShape )
714 OUString aPresetId;
715 OUString aPresetSubType;
717 SdrObject* pObj = pShape->GetSdrObject();
718 if( pObj )
720 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
722 if( pMainSequence.get() )
724 const Reference< XShape > xShape( pShape );
725 EffectSequence::iterator aIter( ImplFindEffect( pMainSequence, xShape, ShapeAnimationSubType::ONLY_TEXT ) );
726 if( aIter != pMainSequence->getEnd() )
728 aPresetId = (*aIter)->getPresetId();
729 aPresetSubType = (*aIter)->getPresetSubType();
734 // now find old effect
735 AnimationEffect eEffect = AnimationEffect_NONE;
737 if( !ConvertPreset( aPresetId, &aPresetSubType, eEffect ) )
738 ConvertPreset( aPresetId, nullptr, eEffect );
740 return eEffect;
743 bool EffectMigration::ConvertPreset( const OUString& rPresetId, const OUString* pPresetSubType, AnimationEffect& rEffect )
745 rEffect = AnimationEffect_NONE;
746 if( !rPresetId.isEmpty() )
748 // first try a match for preset id and subtype
749 deprecated_AnimationEffect_conversion_table_entry const * p = deprecated_AnimationEffect_conversion_table;
750 while( p->mpPresetId )
752 if( rPresetId.equalsAscii( p->mpPresetId ) &&
753 (( p->mpPresetSubType == nullptr ) ||
754 ( pPresetSubType == nullptr) ||
755 ( pPresetSubType->equalsAscii( p->mpPresetSubType )) ) )
757 rEffect = p->meEffect;
758 return true;
760 p++;
762 return false;
764 else
766 // empty preset id means AnimationEffect_NONE
767 return true;
771 bool EffectMigration::ConvertAnimationEffect( const AnimationEffect& rEffect, OUString& rPresetId, OUString& rPresetSubType )
773 deprecated_AnimationEffect_conversion_table_entry const * p = deprecated_AnimationEffect_conversion_table;
774 while( p->mpPresetId )
776 if( p->meEffect == rEffect )
778 rPresetId = OUString::createFromAscii( p->mpPresetId );
779 rPresetSubType = OUString::createFromAscii( p->mpPresetSubType );
780 return true;
782 p++;
785 return false;
788 double EffectMigration::ConvertAnimationSpeed( AnimationSpeed eSpeed )
790 double fDuration;
791 switch( eSpeed )
793 case AnimationSpeed_SLOW: fDuration = 2.0; break;
794 case AnimationSpeed_FAST: fDuration = 0.5; break;
795 default:
796 fDuration = 1.0; break;
798 return fDuration;
801 void EffectMigration::SetAnimationSpeed( SvxShape* pShape, AnimationSpeed eSpeed )
803 DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
804 "sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
805 if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
806 return;
808 SdrObject* pObj = pShape->GetSdrObject();
809 if( implIsInsideGroup( pObj ) )
810 return;
812 double fDuration = ConvertAnimationSpeed( eSpeed );
814 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
816 const Reference< XShape > xShape( pShape );
818 EffectSequence::iterator aIter;
819 bool bNeedRebuild = false;
821 for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
823 CustomAnimationEffectPtr pEffect( (*aIter) );
824 if( pEffect->getTargetShape() == xShape )
826 if( pEffect->getDuration() != 0.1 )
827 pEffect->setDuration( fDuration );
828 bNeedRebuild = true;
832 if( bNeedRebuild )
833 pMainSequence->rebuild();
836 AnimationSpeed EffectMigration::GetAnimationSpeed( SvxShape* pShape )
838 SdrObject* pObj = pShape->GetSdrObject();
839 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
841 const Reference< XShape > xShape( pShape );
843 EffectSequence::iterator aIter;
845 double fDuration = 1.0;
847 for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
849 CustomAnimationEffectPtr pEffect( (*aIter) );
850 if( pEffect->getTargetShape() == xShape )
852 if( pEffect->getDuration() != 0.1 )
854 fDuration = pEffect->getDuration();
855 break;
860 return ConvertDuration( fDuration );
863 AnimationSpeed EffectMigration::ConvertDuration( double fDuration )
865 AnimationSpeed eSpeed;
867 if( fDuration < 1.0 )
868 eSpeed = AnimationSpeed_FAST;
869 else if( fDuration > 1.5 )
870 eSpeed = AnimationSpeed_SLOW;
871 else
872 eSpeed = AnimationSpeed_MEDIUM;
874 return eSpeed;
877 void EffectMigration::SetDimColor( SvxShape* pShape, sal_Int32 nColor )
879 DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
880 "sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
881 if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
882 return;
884 SdrObject* pObj = pShape->GetSdrObject();
885 if( implIsInsideGroup( pObj ) )
886 return;
888 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
890 const Reference< XShape > xShape( pShape );
892 EffectSequence::iterator aIter;
893 bool bNeedRebuild = false;
895 for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
897 CustomAnimationEffectPtr pEffect( (*aIter) );
898 if( pEffect->getTargetShape() == xShape )
900 pEffect->setHasAfterEffect( true );
901 pEffect->setDimColor( makeAny( nColor ) );
902 pEffect->setAfterEffectOnNext( true );
903 bNeedRebuild = true;
907 if( bNeedRebuild )
908 pMainSequence->rebuild();
911 sal_Int32 EffectMigration::GetDimColor( SvxShape* pShape )
913 sal_Int32 nColor = 0;
914 if( pShape )
916 SdrObject* pObj = pShape->GetSdrObject();
917 if( pObj && pObj->GetPage() )
919 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
921 const Reference< XShape > xShape( pShape );
922 EffectSequence::iterator aIter;
924 for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
926 CustomAnimationEffectPtr pEffect( (*aIter) );
927 if( (pEffect->getTargetShape() == xShape) &&
928 pEffect->getDimColor().hasValue() &&
929 pEffect->hasAfterEffect())
931 pEffect->getDimColor() >>= nColor;
932 break;
938 return nColor;
941 void EffectMigration::SetDimHide( SvxShape* pShape, bool bDimHide )
943 DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
944 "sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
945 if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
946 return;
948 SdrObject* pObj = pShape->GetSdrObject();
949 if( implIsInsideGroup( pObj ) )
950 return;
952 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
954 const Reference< XShape > xShape( pShape );
956 EffectSequence::iterator aIter;
957 bool bNeedRebuild = false;
959 for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
961 CustomAnimationEffectPtr pEffect( (*aIter) );
962 if( pEffect->getTargetShape() == xShape )
964 pEffect->setHasAfterEffect( bDimHide );
965 if( bDimHide ) {
966 Any aEmpty;
967 pEffect->setDimColor( aEmpty );
969 pEffect->setAfterEffectOnNext( false );
970 bNeedRebuild = true;
974 if( bNeedRebuild )
975 pMainSequence->rebuild();
978 bool EffectMigration::GetDimHide( SvxShape* pShape )
980 bool bRet = false;
981 if( pShape )
983 SdrObject* pObj = pShape->GetSdrObject();
984 if( pObj && pObj->GetPage() )
986 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
988 const Reference< XShape > xShape( pShape );
990 EffectSequence::iterator aIter;
991 for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
993 CustomAnimationEffectPtr pEffect( (*aIter) );
994 if( pEffect->getTargetShape() == xShape )
996 bRet = pEffect->hasAfterEffect() &&
997 !pEffect->getDimColor().hasValue() &&
998 (!pEffect->IsAfterEffectOnNext());
999 break;
1005 return bRet;
1008 void EffectMigration::SetDimPrevious( SvxShape* pShape, bool bDimPrevious )
1010 DBG_ASSERT( pShape && pShape->GetSdrObject() && pShape->GetSdrObject()->GetPage(),
1011 "sd::EffectMigration::SetAnimationEffect(), invalid argument!" );
1012 if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
1013 return;
1015 SdrObject* pObj = pShape->GetSdrObject();
1016 if( implIsInsideGroup( pObj ) )
1017 return;
1019 Any aColor;
1021 if( bDimPrevious )
1022 aColor <<= COL_LIGHTGRAY;
1024 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1026 const Reference< XShape > xShape( pShape );
1028 EffectSequence::iterator aIter;
1029 bool bNeedRebuild = false;
1031 for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
1033 CustomAnimationEffectPtr pEffect( (*aIter) );
1034 if( pEffect->getTargetShape() == xShape )
1036 pEffect->setHasAfterEffect( bDimPrevious );
1037 if( !bDimPrevious || !pEffect->getDimColor().hasValue() )
1038 pEffect->setDimColor( aColor );
1039 pEffect->setAfterEffectOnNext( true );
1040 bNeedRebuild = true;
1044 if( bNeedRebuild )
1045 pMainSequence->rebuild();
1048 bool EffectMigration::GetDimPrevious( SvxShape* pShape )
1050 bool bRet = false;
1051 if( pShape )
1053 SdrObject* pObj = pShape->GetSdrObject();
1054 if( pObj && pObj->GetPage() )
1056 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1058 const Reference< XShape > xShape( pShape );
1060 EffectSequence::iterator aIter;
1061 for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
1063 CustomAnimationEffectPtr pEffect( (*aIter) );
1064 if( pEffect->getTargetShape() == xShape )
1066 bRet = pEffect->hasAfterEffect() &&
1067 pEffect->getDimColor().hasValue() &&
1068 pEffect->IsAfterEffectOnNext();
1069 break;
1075 return bRet;
1078 void EffectMigration::SetPresentationOrder( SvxShape* pShape, sal_Int32 nNewPos )
1080 if( !pShape || !pShape->GetSdrObject() || !pShape->GetSdrObject()->GetPage() )
1081 return;
1083 SdrObject* pObj = pShape->GetSdrObject();
1084 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1086 EffectSequence& rSequence = pMainSequence->getSequence();
1087 sal_Int32 nPos;
1088 sal_Int32 nCurrentPos = -1;
1089 std::vector< std::vector< EffectSequence::iterator > > aEffectVector(1);
1091 if( !rSequence.empty() )
1093 Reference< XShape > xThis( pShape );
1094 Reference< XShape > xCurrent;
1096 EffectSequence::iterator aIter( rSequence.begin() );
1097 EffectSequence::iterator aEnd( rSequence.end() );
1098 for( nPos = 0; aIter != aEnd; ++aIter )
1100 CustomAnimationEffectPtr pEffect = (*aIter);
1102 if( !xCurrent.is() )
1104 xCurrent = pEffect->getTargetShape();
1106 else if( pEffect->getTargetShape() != xCurrent )
1108 nPos++;
1109 xCurrent = pEffect->getTargetShape();
1110 aEffectVector.resize( nPos+1 );
1113 // is this the first effect for xThis shape?
1114 if(( nCurrentPos == -1 ) && ( xCurrent == xThis ) )
1116 nCurrentPos = nPos;
1119 aEffectVector[nPos].push_back( aIter );
1123 // check if there is at least one effect for xThis
1124 if( nCurrentPos == -1 )
1126 OSL_FAIL("sd::EffectMigration::SetPresentationOrder() failed cause this shape has no effect" );
1127 return;
1130 // check trivial case
1131 if( nCurrentPos != nNewPos )
1133 std::vector< CustomAnimationEffectPtr > aEffects;
1135 std::vector< EffectSequence::iterator >::iterator aIter( aEffectVector[nCurrentPos].begin() );
1136 std::vector< EffectSequence::iterator >::iterator aEnd( aEffectVector[nCurrentPos].end() );
1137 while( aIter != aEnd )
1139 aEffects.push_back( *(*aIter) );
1140 rSequence.erase( *aIter++ );
1143 if( nNewPos > nCurrentPos )
1144 nNewPos++;
1146 std::vector< CustomAnimationEffectPtr >::iterator aTempIter( aEffects.begin() );
1147 std::vector< CustomAnimationEffectPtr >::iterator aTempEnd( aEffects.end() );
1149 if( nNewPos == static_cast<sal_Int32>(aEffectVector.size()) )
1151 while( aTempIter != aTempEnd )
1153 rSequence.push_back( *aTempIter++ );
1156 else
1158 EffectSequence::iterator aPos( aEffectVector[nNewPos][0] );
1159 while( aTempIter != aTempEnd )
1161 rSequence.insert( aPos, (*aTempIter++) );
1167 /** Returns the position of the given SdrObject in the Presentation order.
1168 * This function returns -1 if the SdrObject is not in the Presentation order
1169 * or if it's the path-object.
1171 sal_Int32 EffectMigration::GetPresentationOrder( SvxShape* pShape )
1173 sal_Int32 nPos = -1, nFound = -1;
1175 SdrObject* pObj = pShape->GetSdrObject();
1176 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1178 EffectSequence& rSequence = pMainSequence->getSequence();
1180 Reference< XShape > xThis( pShape );
1181 Reference< XShape > xCurrent;
1183 EffectSequence::iterator aIter( rSequence.begin() );
1184 EffectSequence::iterator aEnd( rSequence.end() );
1185 for( ; aIter != aEnd; ++aIter )
1187 CustomAnimationEffectPtr pEffect = (*aIter);
1189 if( !xCurrent.is() || pEffect->getTargetShape() != xCurrent )
1191 nPos++;
1192 xCurrent = pEffect->getTargetShape();
1194 // is this the first effect for xThis shape?
1195 if( xCurrent == xThis )
1197 nFound = nPos;
1198 break;
1203 return nFound;
1206 void EffectMigration::UpdateSoundEffect( SvxShape* pShape, SdAnimationInfo const * pInfo )
1208 if( pInfo )
1210 SdrObject* pObj = pShape->GetSdrObject();
1211 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1213 const Reference< XShape > xShape( pShape );
1215 EffectSequence::iterator aIter;
1216 bool bNeedRebuild = false;
1218 OUString aSoundFile;
1219 if( pInfo->mbSoundOn )
1220 aSoundFile = pInfo->maSoundFile;
1222 for( aIter = pMainSequence->getBegin(); aIter != pMainSequence->getEnd(); ++aIter )
1224 CustomAnimationEffectPtr pEffect( (*aIter) );
1225 if( pEffect->getTargetShape() == xShape )
1227 if( !aSoundFile.isEmpty() )
1229 pEffect->createAudio( makeAny( aSoundFile ) );
1231 else
1233 pEffect->removeAudio();
1235 bNeedRebuild = true;
1239 if( bNeedRebuild )
1240 pMainSequence->rebuild();
1244 OUString EffectMigration::GetSoundFile( SvxShape* pShape )
1246 OUString aSoundFile;
1248 if( pShape )
1250 SdrObject* pObj = pShape->GetSdrObject();
1251 if( pObj && pObj->GetPage() )
1253 sd::MainSequencePtr pMainSequence = static_cast<SdPage*>(pObj->GetPage())->getMainSequence();
1255 const Reference< XShape > xShape( pShape );
1257 EffectSequence::iterator aIter;
1259 for( aIter = pMainSequence->getBegin();
1260 (aSoundFile.isEmpty()) && (aIter != pMainSequence->getEnd());
1261 ++aIter )
1263 CustomAnimationEffectPtr pEffect( (*aIter) );
1264 if( pEffect->getTargetShape() == xShape )
1266 if( pEffect->getAudio().is() )
1267 pEffect->getAudio()->getSource() >>= aSoundFile;
1272 return aSoundFile;
1275 bool EffectMigration::GetSoundOn( SvxShape* pShape )
1277 return !GetSoundFile( pShape ).isEmpty();
1280 void EffectMigration::SetAnimationPath( SvxShape* pShape, SdrPathObj const * pPathObj )
1282 if( pShape && pPathObj )
1284 SdrObject* pObj = pShape->GetSdrObject();
1286 if( pObj )
1288 const Reference< XShape > xShape( pShape );
1289 SdPage* pPage = dynamic_cast< SdPage* >(pPathObj->GetPage());
1290 if( pPage )
1292 std::shared_ptr< sd::MainSequence > pMainSequence( pPage->getMainSequence() );
1293 if( pMainSequence.get() )
1294 CustomAnimationEffectPtr pCreated( pMainSequence->append( *pPathObj, makeAny( xShape ), -1.0 ) );
1300 // #i42894# helper which creates the needed XAnimate for changing visibility and all the (currently) needed embeddings
1301 void createVisibilityOnOffNode(Reference< XTimeContainer > const & rxParentContainer, SdrObject& rCandidate, bool bVisible, bool bOnClick, double fDuration)
1303 Reference< XMultiServiceFactory > xMsf(::comphelper::getProcessServiceFactory());
1305 // create par container node
1306 Reference< XAnimationNode > xOuterSeqTimeContainer(xMsf->createInstance("com.sun.star.animations.ParallelTimeContainer"), UNO_QUERY_THROW);
1308 // set begin
1309 xOuterSeqTimeContainer->setBegin(Any(0.0));
1311 // set fill
1312 xOuterSeqTimeContainer->setFill(AnimationFill::HOLD);
1314 // set named values
1315 Sequence< NamedValue > aUserDataSequence;
1316 aUserDataSequence.realloc(1);
1318 aUserDataSequence[0].Name = "node-type";
1319 aUserDataSequence[0].Value <<= bOnClick ? EffectNodeType::ON_CLICK : EffectNodeType::AFTER_PREVIOUS;
1321 xOuterSeqTimeContainer->setUserData(aUserDataSequence);
1323 // create animate set to change visibility for rCandidate
1324 Reference< XAnimationNode > xAnimateSetForLast(xMsf->createInstance("com.sun.star.animations.AnimateSet"), UNO_QUERY_THROW);
1326 // set begin
1327 xAnimateSetForLast->setBegin(Any(0.0));
1329 // set duration
1330 xAnimateSetForLast->setDuration(Any(fDuration));
1332 // set fill
1333 xAnimateSetForLast->setFill(AnimationFill::HOLD);
1335 // set target
1336 Reference< XAnimate > xAnimate(xAnimateSetForLast, UNO_QUERY);
1337 Reference< XShape > xTargetShape(rCandidate.getUnoShape(), UNO_QUERY);
1338 xAnimate->setTarget(Any(xTargetShape));
1340 // set AttributeName
1341 xAnimate->setAttributeName("Visibility");
1343 // set attribute value
1344 xAnimate->setTo(Any(bVisible));
1346 // ad set node to par node
1347 Reference< XTimeContainer > xParentContainer(xOuterSeqTimeContainer, UNO_QUERY_THROW);
1348 xParentContainer->appendChild(xAnimateSetForLast);
1350 // add node
1351 rxParentContainer->appendChild(xOuterSeqTimeContainer);
1354 // #i42894# older native formats supported animated group objects, that means all members of the group
1355 // were shown animated by showing one after the other. This is no longer supported, but the following
1356 // fallback will create the needed SMIL animation stuff. Unfortunately the members of the group
1357 // have to be moved directly to the page, else the (explained to be generic, thus I expected this to
1358 // work) animations will not work in slideshow
1359 void EffectMigration::CreateAnimatedGroup(SdrObjGroup const & rGroupObj, SdPage& rPage)
1361 // aw080 will give a vector immediately
1362 SdrObjListIter aIter(rGroupObj);
1364 if(aIter.Count())
1366 std::shared_ptr< sd::MainSequence > pMainSequence(rPage.getMainSequence());
1368 if(pMainSequence.get())
1370 std::vector< SdrObject* > aObjects;
1371 aObjects.reserve(aIter.Count());
1373 while(aIter.IsMore())
1375 // do move to page rough with old/current stuff, will be different in aw080 anyways
1376 SdrObject* pCandidate = aIter.Next();
1377 rGroupObj.GetSubList()->NbcRemoveObject(pCandidate->GetOrdNum());
1378 rPage.NbcInsertObject(pCandidate);
1379 aObjects.push_back(pCandidate);
1382 // create main node
1383 Reference< XMultiServiceFactory > xMsf(::comphelper::getProcessServiceFactory());
1384 Reference< XAnimationNode > xOuterSeqTimeContainer(xMsf->createInstance("com.sun.star.animations.ParallelTimeContainer"), UNO_QUERY_THROW);
1386 // set begin
1387 xOuterSeqTimeContainer->setBegin(Any(0.0));
1389 // prepare parent container
1390 Reference< XTimeContainer > xParentContainer(xOuterSeqTimeContainer, UNO_QUERY_THROW);
1392 // prepare loop over objects
1393 SdrObject* pNext = nullptr;
1394 const double fDurationShow(0.2);
1395 const double fDurationHide(0.001);
1397 for(size_t a(0); a < aObjects.size(); a++)
1399 SdrObject* pLast = pNext;
1400 pNext = aObjects[a];
1402 // create node
1403 if(pLast)
1405 createVisibilityOnOffNode(xParentContainer, *pLast, false, false, fDurationHide);
1408 if(pNext)
1410 createVisibilityOnOffNode(xParentContainer, *pNext, true, !a, fDurationShow);
1414 // create end node
1415 if(pNext)
1417 createVisibilityOnOffNode(xParentContainer, *pNext, false, false, fDurationHide);
1420 // add to main sequence and rebuild
1421 pMainSequence->createEffects(xOuterSeqTimeContainer);
1422 pMainSequence->rebuild();
1427 void EffectMigration::DocumentLoaded(SdDrawDocument & rDoc)
1429 if (DocumentType::Draw == rDoc.GetDocumentType())
1430 return; // no animations in Draw
1431 for (sal_uInt16 n = 0; n < rDoc.GetSdPageCount(PageKind::Standard); ++n)
1433 SdPage *const pPage = rDoc.GetSdPage(n, PageKind::Standard);
1434 if (pPage->hasAnimationNode())
1436 // this will force the equivalent of the MainSequence::onTimerHdl
1437 // so that the animations are present in export-able representation
1438 // *before* the import is finished
1439 pPage->getMainSequence()->getRootNode();
1442 for (sal_uInt16 n = 0; n < rDoc.GetMasterSdPageCount(PageKind::Standard); ++n)
1444 SdPage *const pPage = rDoc.GetMasterSdPage(n, PageKind::Standard);
1445 if (pPage->hasAnimationNode())
1447 pPage->getMainSequence()->getRootNode();
1452 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */