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