LibreOffice Module xmloff (master)  1
animationexport.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 
21 #include <com/sun/star/animations/XAnimateColor.hpp>
22 #include <com/sun/star/animations/XCommand.hpp>
23 #include <com/sun/star/animations/Timing.hpp>
24 #include <com/sun/star/animations/Event.hpp>
25 #include <com/sun/star/animations/XAnimateMotion.hpp>
26 #include <com/sun/star/animations/XAnimatePhysics.hpp>
27 #include <com/sun/star/animations/XAnimateTransform.hpp>
28 #include <com/sun/star/animations/XTransitionFilter.hpp>
29 #include <com/sun/star/animations/XIterateContainer.hpp>
30 #include <com/sun/star/animations/XAudio.hpp>
31 #include <com/sun/star/animations/AnimationColorSpace.hpp>
32 #include <com/sun/star/animations/AnimationNodeType.hpp>
33 #include <com/sun/star/animations/AnimationRestart.hpp>
34 #include <com/sun/star/animations/EventTrigger.hpp>
35 #include <com/sun/star/animations/AnimationFill.hpp>
36 #include <com/sun/star/animations/AnimationEndSync.hpp>
37 #include <com/sun/star/animations/AnimationCalcMode.hpp>
38 #include <com/sun/star/animations/AnimationAdditiveMode.hpp>
39 #include <com/sun/star/animations/AnimationTransformType.hpp>
40 #include <com/sun/star/animations/TransitionType.hpp>
41 #include <com/sun/star/animations/TransitionSubType.hpp>
42 #include <com/sun/star/animations/ValuePair.hpp>
43 #include <com/sun/star/container/XEnumerationAccess.hpp>
44 #include <com/sun/star/beans/NamedValue.hpp>
45 #include <com/sun/star/beans/XPropertySet.hpp>
46 #include <com/sun/star/document/XStorageBasedDocument.hpp>
47 #include <com/sun/star/embed/ElementModes.hpp>
48 #include <com/sun/star/embed/XTransactedObject.hpp>
49 #include <com/sun/star/presentation/EffectNodeType.hpp>
50 #include <com/sun/star/presentation/EffectPresetClass.hpp>
51 #include <com/sun/star/presentation/ParagraphTarget.hpp>
52 #include <com/sun/star/presentation/TextAnimationType.hpp>
53 #include <com/sun/star/presentation/ShapeAnimationSubType.hpp>
54 #include <com/sun/star/presentation/EffectCommands.hpp>
55 #include <o3tl/any.hxx>
56 #include <sax/tools/converter.hxx>
57 #include <sal/log.hxx>
58 #include <osl/diagnose.h>
59 #include <tools/diagnose_ex.h>
60 
62 #include "sdpropls.hxx"
63 #include <xmlsdtypes.hxx>
64 #include <xmloff/xmltoken.hxx>
65 #include <xmloff/xmlnamespace.hxx>
66 #include <xmloff/xmluconv.hxx>
67 #include <xmloff/xmlexp.hxx>
68 #include <xmloff/xmlement.hxx>
69 #include <xmloff/xmlprhdl.hxx>
70 
71 #include <animations.hxx>
73 
74 using namespace css;
75 using namespace ::std;
76 using namespace ::cppu;
77 using namespace ::com::sun::star::animations;
78 using namespace ::com::sun::star::presentation;
79 using namespace ::com::sun::star::drawing;
80 using namespace ::com::sun::star::beans;
81 using namespace ::xmloff::token;
82 
83 using ::com::sun::star::uno::Any;
84 using ::com::sun::star::uno::UNO_QUERY;
85 using ::com::sun::star::uno::UNO_QUERY_THROW;
86 using ::com::sun::star::uno::Reference;
87 using ::com::sun::star::uno::Sequence;
88 using ::com::sun::star::uno::Exception;
89 using ::com::sun::star::uno::RuntimeException;
90 using ::com::sun::star::uno::XInterface;
91 using ::com::sun::star::beans::NamedValue;
92 using ::com::sun::star::container::XEnumerationAccess;
93 using ::com::sun::star::container::XEnumeration;
94 
95 namespace xmloff
96 {
97 
99 {
100  { XML_DEFAULT, AnimationFill::DEFAULT },
101  { XML_REMOVE, AnimationFill::REMOVE },
102  { XML_FREEZE, AnimationFill::FREEZE },
103  { XML_HOLD, AnimationFill::HOLD },
104  { XML_TRANSITION, AnimationFill::TRANSITION },
105  { XML_AUTO, AnimationFill::AUTO },
106  { XML_TOKEN_INVALID, 0 }
107 };
109 {
110  { XML_INHERIT, AnimationFill::INHERIT },
111  { XML_REMOVE, AnimationFill::REMOVE },
112  { XML_FREEZE, AnimationFill::FREEZE },
113  { XML_HOLD, AnimationFill::HOLD },
114  { XML_TRANSITION, AnimationFill::TRANSITION },
115  { XML_AUTO, AnimationFill::AUTO },
116  { XML_TOKEN_INVALID, 0 }
117 };
119 {
120  { XML_DEFAULT, AnimationRestart::DEFAULT },
121  { XML_ALWAYS, AnimationRestart::ALWAYS },
122  { XML_WHENNOTACTIVE,AnimationRestart::WHEN_NOT_ACTIVE },
123  { XML_NEVER, AnimationRestart::NEVER },
124  { XML_TOKEN_INVALID, 0 }
125 };
127 {
128  { XML_INHERIT, AnimationRestart::INHERIT },
129  { XML_ALWAYS, AnimationRestart::ALWAYS },
130  { XML_WHENNOTACTIVE,AnimationRestart::WHEN_NOT_ACTIVE },
131  { XML_NEVER, AnimationRestart::NEVER },
132  { XML_TOKEN_INVALID, 0 }
133 };
135 {
136  { XML_FIRST, AnimationEndSync::FIRST },
137  { XML_LAST, AnimationEndSync::LAST },
138  { XML_ALL, AnimationEndSync::ALL },
139  { XML_MEDIA, AnimationEndSync::MEDIA },
140  { XML_TOKEN_INVALID, 0 }
141 };
143 {
144  { XML_DISCRETE, AnimationCalcMode::DISCRETE },
145  { XML_LINEAR, AnimationCalcMode::LINEAR },
146  { XML_PACED, AnimationCalcMode::PACED },
147  { XML_SPLINE, AnimationCalcMode::SPLINE },
148  { XML_TOKEN_INVALID, 0 }
149 };
151 {
152  { XML_BASE, AnimationAdditiveMode::BASE },
153  { XML_SUM, AnimationAdditiveMode::SUM },
154  { XML_REPLACE, AnimationAdditiveMode::REPLACE },
155  { XML_MULTIPLY, AnimationAdditiveMode::MULTIPLY },
156  { XML_NONE, AnimationAdditiveMode::NONE },
157  { XML_TOKEN_INVALID, 0 }
158 };
160 {
161  { XML_TRANSLATE, AnimationTransformType::TRANSLATE },
162  { XML_SCALE, AnimationTransformType::SCALE },
163  { XML_ROTATE, AnimationTransformType::ROTATE },
164  { XML_SKEWX, AnimationTransformType::SKEWX },
165  { XML_SKEWY, AnimationTransformType::SKEWY },
166  { XML_TOKEN_INVALID, 0 }
167 };
169 {
170  { XML_BARWIPE, TransitionType::BARWIPE },
171  { XML_BOXWIPE, TransitionType::BOXWIPE },
172  { XML_FOURBOXWIPE, TransitionType::FOURBOXWIPE },
173  { XML_BARNDOORWIPE, TransitionType::BARNDOORWIPE },
174  { XML_DIAGONALWIPE, TransitionType::DIAGONALWIPE },
175  { XML_BOWTIEWIPE, TransitionType::BOWTIEWIPE },
176  { XML_MISCDIAGONALWIPE, TransitionType::MISCDIAGONALWIPE },
177  { XML_VEEWIPE, TransitionType::VEEWIPE },
178  { XML_BARNVEEWIPE, TransitionType::BARNVEEWIPE },
179  { XML_ZIGZAGWIPE, TransitionType::ZIGZAGWIPE },
180  { XML_BARNZIGZAGWIPE, TransitionType::BARNZIGZAGWIPE },
181  { XML_IRISWIPE, TransitionType::IRISWIPE },
182  { XML_TRIANGLEWIPE, TransitionType::TRIANGLEWIPE },
183  { XML_ARROWHEADWIPE, TransitionType::ARROWHEADWIPE },
184  { XML_PENTAGONWIPE, TransitionType::PENTAGONWIPE },
185  { XML_HEXAGONWIPE, TransitionType::HEXAGONWIPE },
186  { XML_ELLIPSEWIPE, TransitionType::ELLIPSEWIPE },
187  { XML_EYEWIPE, TransitionType::EYEWIPE },
188  { XML_ROUNDRECTWIPE, TransitionType::ROUNDRECTWIPE },
189  { XML_STARWIPE, TransitionType::STARWIPE },
190  { XML_MISCSHAPEWIPE, TransitionType::MISCSHAPEWIPE },
191  { XML_CLOCKWIPE, TransitionType::CLOCKWIPE },
192  { XML_PINWHEELWIPE, TransitionType::PINWHEELWIPE },
193  { XML_SINGLESWEEPWIPE, TransitionType::SINGLESWEEPWIPE },
194  { XML_FANWIPE, TransitionType::FANWIPE },
195  { XML_DOUBLEFANWIPE, TransitionType::DOUBLEFANWIPE },
196  { XML_DOUBLESWEEPWIPE, TransitionType::DOUBLESWEEPWIPE },
197  { XML_SALOONDOORWIPE, TransitionType::SALOONDOORWIPE },
198  { XML_WINDSHIELDWIPE, TransitionType::WINDSHIELDWIPE },
199  { XML_SNAKEWIPE, TransitionType::SNAKEWIPE },
200  { XML_SPIRALWIPE, TransitionType::SPIRALWIPE },
201  { XML_PARALLELSNAKESWIPE,TransitionType::PARALLELSNAKESWIPE },
202  { XML_BOXSNAKESWIPE, TransitionType::BOXSNAKESWIPE },
203  { XML_WATERFALLWIPE, TransitionType::WATERFALLWIPE },
204  { XML_PUSHWIPE, TransitionType::PUSHWIPE },
205  { XML_SLIDEWIPE, TransitionType::SLIDEWIPE },
206  { XML_FADE, TransitionType::FADE },
207  { XML_RANDOMBARWIPE, TransitionType::RANDOMBARWIPE },
208  { XML_CHECKERBOARDWIPE, TransitionType::CHECKERBOARDWIPE },
209  { XML_DISSOLVE, TransitionType::DISSOLVE },
210  { XML_BLINDSWIPE, TransitionType::BLINDSWIPE },
211  { XML_RANDOM, TransitionType::RANDOM },
212  { XML_ZOOM, TransitionType::ZOOM },
213  { XML_TOKEN_INVALID, 0 }
214 };
216 {
217  { XML_DEFAULT, TransitionSubType::DEFAULT },
218  { XML_LEFTTORIGHT, TransitionSubType::LEFTTORIGHT },
219  { XML_TOPTOBOTTOM, TransitionSubType::TOPTOBOTTOM },
220  { XML_TOPLEFT, TransitionSubType::TOPLEFT },
221  { XML_TOPRIGHT, TransitionSubType::TOPRIGHT },
222  { XML_BOTTOMRIGHT, TransitionSubType::BOTTOMRIGHT },
223  { XML_BOTTOMLEFT, TransitionSubType::BOTTOMLEFT },
224  { XML_TOPCENTER, TransitionSubType::TOPCENTER },
225  { XML_RIGHTCENTER, TransitionSubType::RIGHTCENTER },
226  { XML_BOTTOMCENTER, TransitionSubType::BOTTOMCENTER },
227  { XML_LEFTCENTER, TransitionSubType::LEFTCENTER },
228  { XML_CORNERSIN, TransitionSubType::CORNERSIN },
229  { XML_CORNERSOUT, TransitionSubType::CORNERSOUT },
230  { XML_VERTICAL, TransitionSubType::VERTICAL },
231  { XML_HORIZONTAL, TransitionSubType::HORIZONTAL },
232  { XML_DIAGONALBOTTOMLEFT, TransitionSubType::DIAGONALBOTTOMLEFT },
233  { XML_DIAGONALTOPLEFT, TransitionSubType::DIAGONALTOPLEFT },
234  { XML_DOUBLEBARNDOOR, TransitionSubType::DOUBLEBARNDOOR },
235  { XML_DOUBLEDIAMOND, TransitionSubType::DOUBLEDIAMOND },
236  { XML_DOWN, TransitionSubType::DOWN },
237  { XML_LEFT, TransitionSubType::LEFT },
238  { XML_UP, TransitionSubType::UP },
239  { XML_RIGHT, TransitionSubType::RIGHT },
240  { XML_RECTANGLE, TransitionSubType::RECTANGLE },
241  { XML_DIAMOND, TransitionSubType::DIAMOND },
242  { XML_CIRCLE, TransitionSubType::CIRCLE },
243  { XML_FOURPOINT, TransitionSubType::FOURPOINT },
244  { XML_FIVEPOINT, TransitionSubType::FIVEPOINT },
245  { XML_SIXPOINT, TransitionSubType::SIXPOINT },
246  { XML_HEART, TransitionSubType::HEART },
247  { XML_KEYHOLE, TransitionSubType::KEYHOLE },
248  { XML_CLOCKWISETWELVE, TransitionSubType::CLOCKWISETWELVE },
249  { XML_CLOCKWISETHREE, TransitionSubType::CLOCKWISETHREE },
250  { XML_CLOCKWISESIX, TransitionSubType::CLOCKWISESIX },
251  { XML_CLOCKWISENINE, TransitionSubType::CLOCKWISENINE },
252  { XML_TWOBLADEVERTICAL, TransitionSubType::TWOBLADEVERTICAL },
253  { XML_TWOBLADEHORIZONTAL, TransitionSubType::TWOBLADEHORIZONTAL },
254  { XML_FOURBLADE, TransitionSubType::FOURBLADE },
255  { XML_CLOCKWISETOP, TransitionSubType::CLOCKWISETOP },
256  { XML_CLOCKWISERIGHT, TransitionSubType::CLOCKWISERIGHT },
257  { XML_CLOCKWISEBOTTOM, TransitionSubType::CLOCKWISEBOTTOM },
258  { XML_CLOCKWISELEFT, TransitionSubType::CLOCKWISELEFT },
259  { XML_CLOCKWISETOPLEFT, TransitionSubType::CLOCKWISETOPLEFT },
260  { XML_COUNTERCLOCKWISEBOTTOMLEFT,TransitionSubType::COUNTERCLOCKWISEBOTTOMLEFT },
261  { XML_CLOCKWISEBOTTOMRIGHT, TransitionSubType::CLOCKWISEBOTTOMRIGHT },
262  { XML_COUNTERCLOCKWISETOPRIGHT,TransitionSubType::COUNTERCLOCKWISETOPRIGHT },
263  { XML_CENTERTOP, TransitionSubType::CENTERTOP },
264  { XML_CENTERRIGHT, TransitionSubType::CENTERRIGHT },
265  { XML_TOP, TransitionSubType::TOP },
266  { XML_BOTTOM, TransitionSubType::BOTTOM },
267  { XML_FANOUTVERTICAL, TransitionSubType::FANOUTVERTICAL },
268  { XML_FANOUTHORIZONTAL, TransitionSubType::FANOUTHORIZONTAL },
269  { XML_FANINVERTICAL, TransitionSubType::FANINVERTICAL },
270  { XML_FANINHORIZONTAL, TransitionSubType::FANINHORIZONTAL },
271  { XML_PARALLELVERTICAL, TransitionSubType::PARALLELVERTICAL },
272  { XML_PARALLELDIAGONAL, TransitionSubType::PARALLELDIAGONAL },
273  { XML_OPPOSITEVERTICAL, TransitionSubType::OPPOSITEVERTICAL },
274  { XML_OPPOSITEHORIZONTAL, TransitionSubType::OPPOSITEHORIZONTAL },
275  { XML_PARALLELDIAGONALTOPLEFT,TransitionSubType::PARALLELDIAGONALTOPLEFT },
276  { XML_PARALLELDIAGONALBOTTOMLEFT,TransitionSubType::PARALLELDIAGONALBOTTOMLEFT },
277  { XML_TOPLEFTHORIZONTAL, TransitionSubType::TOPLEFTHORIZONTAL },
278  { XML_TOPLEFTDIAGONAL, TransitionSubType::TOPLEFTDIAGONAL },
279  { XML_TOPRIGHTDIAGONAL, TransitionSubType::TOPRIGHTDIAGONAL },
280  { XML_BOTTOMRIGHTDIAGONAL, TransitionSubType::BOTTOMRIGHTDIAGONAL },
281  { XML_BOTTOMLEFTDIAGONAL, TransitionSubType::BOTTOMLEFTDIAGONAL },
282  { XML_TOPLEFTCLOCKWISE, TransitionSubType::TOPLEFTCLOCKWISE },
283  { XML_TOPRIGHTCLOCKWISE, TransitionSubType::TOPRIGHTCLOCKWISE },
284  { XML_BOTTOMRIGHTCLOCKWISE, TransitionSubType::BOTTOMRIGHTCLOCKWISE },
285  { XML_BOTTOMLEFTCLOCKWISE, TransitionSubType::BOTTOMLEFTCLOCKWISE },
286  { XML_TOPLEFTCOUNTERCLOCKWISE,TransitionSubType::TOPLEFTCOUNTERCLOCKWISE },
287  { XML_TOPRIGHTCOUNTERCLOCKWISE,TransitionSubType::TOPRIGHTCOUNTERCLOCKWISE },
288  { XML_BOTTOMRIGHTCOUNTERCLOCKWISE,TransitionSubType::BOTTOMRIGHTCOUNTERCLOCKWISE },
289  { XML_BOTTOMLEFTCOUNTERCLOCKWISE,TransitionSubType::BOTTOMLEFTCOUNTERCLOCKWISE },
290  { XML_VERTICALTOPSAME, TransitionSubType::VERTICALTOPSAME },
291  { XML_VERTICALBOTTOMSAME, TransitionSubType::VERTICALBOTTOMSAME },
292  { XML_VERTICALTOPLEFTOPPOSITE,TransitionSubType::VERTICALTOPLEFTOPPOSITE },
293  { XML_VERTICALBOTTOMLEFTOPPOSITE,TransitionSubType::VERTICALBOTTOMLEFTOPPOSITE },
294  { XML_HORIZONTALLEFTSAME, TransitionSubType::HORIZONTALLEFTSAME },
295  { XML_HORIZONTALRIGHTSAME, TransitionSubType::HORIZONTALRIGHTSAME },
296  { XML_HORIZONTALTOPLEFTOPPOSITE,TransitionSubType::HORIZONTALTOPLEFTOPPOSITE },
297  { XML_HORIZONTALTOPRIGHTOPPOSITE,TransitionSubType::HORIZONTALTOPRIGHTOPPOSITE },
298  { XML_DIAGONALBOTTOMLEFTOPPOSITE,TransitionSubType::DIAGONALBOTTOMLEFTOPPOSITE },
299  { XML_DIAGONALTOPLEFTOPPOSITE,TransitionSubType::DIAGONALTOPLEFTOPPOSITE },
300  { XML_TWOBOXTOP, TransitionSubType::TWOBOXTOP },
301  { XML_TWOBOXBOTTOM, TransitionSubType::TWOBOXBOTTOM },
302  { XML_TWOBOXLEFT, TransitionSubType::TWOBOXLEFT },
303  { XML_TWOBOXRIGHT, TransitionSubType::TWOBOXRIGHT },
304  { XML_FOURBOXVERTICAL, TransitionSubType::FOURBOXVERTICAL },
305  { XML_FOURBOXHORIZONTAL, TransitionSubType::FOURBOXHORIZONTAL },
306  { XML_VERTICALLEFT, TransitionSubType::VERTICALLEFT },
307  { XML_VERTICALRIGHT, TransitionSubType::VERTICALRIGHT },
308  { XML_HORIZONTALLEFT, TransitionSubType::HORIZONTALLEFT },
309  { XML_HORIZONTALRIGHT, TransitionSubType::HORIZONTALRIGHT },
310  { XML_FROMLEFT, TransitionSubType::FROMLEFT },
311  { XML_FROMTOP, TransitionSubType::FROMTOP },
312  { XML_FROMRIGHT, TransitionSubType::FROMRIGHT },
313  { XML_FROMBOTTOM, TransitionSubType::FROMBOTTOM },
314  { XML_CROSSFADE, TransitionSubType::CROSSFADE },
315  { XML_FADETOCOLOR, TransitionSubType::FADETOCOLOR },
316  { XML_FADEFROMCOLOR, TransitionSubType::FADEFROMCOLOR },
317  { XML_FADEOVERCOLOR, TransitionSubType::FADEOVERCOLOR },
318  { XML_THREEBLADE, TransitionSubType::THREEBLADE },
319  { XML_EIGHTBLADE, TransitionSubType::EIGHTBLADE },
320  { XML_ONEBLADE, TransitionSubType::ONEBLADE },
321  { XML_ACROSS, TransitionSubType::ACROSS },
322  { XML_TOPLEFTVERTICAL, TransitionSubType::TOPLEFTVERTICAL },
323  { XML_COMBHORIZONTAL, TransitionSubType::COMBHORIZONTAL },
324  { XML_COMBVERTICAL, TransitionSubType::COMBVERTICAL },
325  { XML_IN, TransitionSubType::IN },
326  { XML_OUT, TransitionSubType::OUT },
327  { XML_ROTATEIN, TransitionSubType::ROTATEIN },
328  { XML_ROTATEOUT, TransitionSubType::ROTATEOUT },
329  { XML_FROMTOPLEFT, TransitionSubType::FROMTOPLEFT },
330  { XML_FROMTOPRIGHT, TransitionSubType::FROMTOPRIGHT },
331  { XML_FROMBOTTOMLEFT, TransitionSubType::FROMBOTTOMLEFT },
332  { XML_FROMBOTTOMRIGHT, TransitionSubType::FROMBOTTOMRIGHT },
333 
334  { XML_TOKEN_INVALID, 0 }
335 };
337 {
338  { XML_ONBEGIN, EventTrigger::ON_BEGIN },
339  { XML_ONEND, EventTrigger::ON_END },
340  { XML_BEGIN, EventTrigger::BEGIN_EVENT },
341  { XML_END, EventTrigger::END_EVENT },
342  { XML_CLICK, EventTrigger::ON_CLICK },
343  { XML_DOUBLECLICK, EventTrigger::ON_DBL_CLICK },
344  { XML_MOUSEOVER, EventTrigger::ON_MOUSE_ENTER },
345  { XML_MOUSEOUT, EventTrigger::ON_MOUSE_LEAVE },
346  { XML_NEXT, EventTrigger::ON_NEXT },
347  { XML_PREVIOUS, EventTrigger::ON_PREV },
348  { XML_STOP_AUDIO, EventTrigger::ON_STOP_AUDIO },
349  { XML_REPEAT, EventTrigger::REPEAT },
350  { XML_TOKEN_INVALID, 0 }
351 };
353 {
354  { XML_CUSTOM, EffectPresetClass::CUSTOM },
355  { XML_ENTRANCE, EffectPresetClass::ENTRANCE },
356  { XML_EXIT, EffectPresetClass::EXIT },
357  { XML_EMPHASIS, EffectPresetClass::EMPHASIS },
358  { XML_MOTION_PATH, EffectPresetClass::MOTIONPATH },
359  { XML_OLE_ACTION, EffectPresetClass::OLEACTION },
360  { XML_MEDIA_CALL, EffectPresetClass::MEDIACALL },
361  { XML_TOKEN_INVALID, 0 }
362 };
364 {
365  { XML_DEFAULT, EffectNodeType::DEFAULT },
366  { XML_ON_CLICK, EffectNodeType::ON_CLICK },
367  { XML_WITH_PREVIOUS, EffectNodeType::WITH_PREVIOUS },
368  { XML_AFTER_PREVIOUS, EffectNodeType::AFTER_PREVIOUS },
369  { XML_MAIN_SEQUENCE, EffectNodeType::MAIN_SEQUENCE },
370  { XML_TIMING_ROOT, EffectNodeType::TIMING_ROOT },
371  { XML_INTERACTIVE_SEQUENCE, EffectNodeType::INTERACTIVE_SEQUENCE },
372  { XML_TOKEN_INVALID, 0 }
373 };
375 {
376  { XML_WHOLE, ShapeAnimationSubType::AS_WHOLE },
377  { XML_BACKGROUND, ShapeAnimationSubType::ONLY_BACKGROUND },
378  { XML_TEXT, ShapeAnimationSubType::ONLY_TEXT },
379  { XML_TOKEN_INVALID, 0 }
380 };
382 {
383  { XML_BY_PARAGRAPH, TextAnimationType::BY_PARAGRAPH },
384  { XML_BY_WORD, TextAnimationType::BY_WORD },
385  { XML_BY_LETTER, TextAnimationType::BY_LETTER },
386  { XML_TOKEN_INVALID, 0 }
387 };
389 {
390  { XML_CUSTOM, EffectCommands::CUSTOM },
391  { XML_VERB, EffectCommands::VERB },
392  { XML_PLAY, EffectCommands::PLAY },
393  { XML_TOGGLE_PAUSE, EffectCommands::TOGGLEPAUSE },
394  { XML_STOP, EffectCommands::STOP },
395  { XML_STOP_AUDIO, EffectCommands::STOPAUDIO },
396  { XML_TOKEN_INVALID, 0 }
397 };
398 
400 {
401  static const struct ImplAttributeNameConversion gImplConversionList[] =
402  {
403  { XML_X, "X" },
404  { XML_Y, "Y" },
405  { XML_WIDTH, "Width" },
406  { XML_HEIGHT, "Height" },
407  { XML_ROTATE, "Rotate" },
408  { XML_SKEWX, "SkewX" },
409  { XML_FILL_COLOR, "FillColor" },
410  { XML_FILL, "FillStyle" },
411  { XML_STROKE_COLOR, "LineColor" },
412  { XML_STROKE, "LineStyle" },
413  { XML_COLOR, "CharColor" },
414  { XML_TEXT_ROTATION_ANGLE, "CharRotation" },
415  { XML_FONT_WEIGHT, "CharWeight" },
416  { XML_TEXT_UNDERLINE, "CharUnderline" },
417  { XML_FONT_FAMILY, "CharFontName" },
418  { XML_FONT_SIZE, "CharHeight" },
419  { XML_FONT_STYLE, "CharPosture" },
420  { XML_VISIBILITY, "Visibility" },
421  { XML_OPACITY, "Opacity" },
422  { XML_DIM, "DimColor" },
423  { XML_TOKEN_INVALID, nullptr }
424  };
425 
426  return gImplConversionList;
427 }
428 
429 
431 {
432 public:
434 
435  void prepareNode( const Reference< XAnimationNode >& xNode );
436  void exportNode( const Reference< XAnimationNode >& xNode );
437 
438  void exportContainer( const Reference< XTimeContainer >& xNode, sal_Int16 nContainerNodeType );
439  void exportAnimate( const Reference< XAnimate >& xNode );
440  void exportAudio( const Reference< XAudio >& xAudio );
441  void exportCommand( const Reference< XCommand >& xCommand );
442 
443  static Reference< XInterface > getParagraphTarget( const ParagraphTarget& pTarget );
444 
445  static void convertPath( OUStringBuffer& sTmp, const Any& rPath );
446  void convertValue( XMLTokenEnum eAttributeName, OUStringBuffer& sTmp, const Any& rValue ) const;
447  void convertTiming( OUStringBuffer& sTmp, const Any& rTiming ) const;
448  void convertTarget( OUStringBuffer& sTmp, const Any& rTarget ) const;
449 
450  void prepareValue( const Any& rValue );
451 
452  void exportTransitionNode();
453  void prepareTransitionNode();
454 
456 private:
460 };
461 
462 AnimationsExporterImpl::AnimationsExporterImpl( SvXMLExport& rExport, const Reference< XPropertySet >& xPageProps )
463 : mbHasTransition(false)
464 , mxExport( &rExport )
465 , mxPageProps( xPageProps )
466 , mxSdPropHdlFactory(new XMLSdPropHdlFactory( rExport.GetModel(), rExport ))
467 {
468 }
469 
470 
472 static bool splitPath(OUString const & i_rPath,
473  OUString & o_rDir, OUString& o_rRest)
474 {
475  const sal_Int32 idx(i_rPath.indexOf(u'/'));
476  if (idx < 0 || idx >= i_rPath.getLength()) {
477  o_rDir = OUString();
478  o_rRest = i_rPath;
479  return true;
480  } else if (idx == 0 || idx == i_rPath.getLength() - 1) {
481  // input must not start or end with '/'
482  return false;
483  } else {
484  o_rDir = i_rPath.copy(0, idx);
485  o_rRest = i_rPath.copy(idx+1);
486  return true;
487  }
488 }
489 
490 static void lcl_CopyStream(
491  uno::Reference<embed::XStorage> const& xSource,
492  uno::Reference<embed::XStorage> const& xTarget,
493  OUString const& rPath)
494 {
495  OUString dir;
496  OUString rest;
497  if (!splitPath(rPath, dir, rest))
498  throw uno::RuntimeException();
499 
500  if (dir.getLength() == 0)
501  xSource->copyElementTo(rPath, xTarget, rPath);
502  else
503  {
504  uno::Reference<embed::XStorage> const xSubSource(
505  xSource->openStorageElement(dir, embed::ElementModes::READ));
506  uno::Reference<embed::XStorage> const xSubTarget(
507  xTarget->openStorageElement(dir, embed::ElementModes::WRITE));
508  lcl_CopyStream(xSubSource, xSubTarget, rest);
509  }
510  uno::Reference<embed::XTransactedObject> const xTransaction(xTarget, uno::UNO_QUERY);
511  if (xTransaction.is())
512  xTransaction->commit();
513 }
514 
515 char const s_PkgScheme[] = "vnd.sun.star.Package:";
516 
517 static OUString lcl_StoreMediaAndGetURL(SvXMLExport & rExport, OUString const& rURL)
518 {
519  OUString urlPath;
520  if (rURL.startsWithIgnoreAsciiCase(s_PkgScheme, &urlPath))
521  {
522  try // video is embedded
523  {
524  // copy the media stream from document storage to target storage
525  // (not sure if this is the best way to store these?)
526  uno::Reference<document::XStorageBasedDocument> const xSBD(
527  rExport.GetModel(), uno::UNO_QUERY_THROW);
528  uno::Reference<embed::XStorage> const xSource(
529  xSBD->getDocumentStorage(), uno::UNO_SET_THROW);
530  uno::Reference<embed::XStorage> const xTarget(
531  rExport.GetTargetStorage(), uno::UNO_SET_THROW);
532 
533  urlPath = rURL.copy(SAL_N_ELEMENTS(s_PkgScheme)-1);
534 
535  lcl_CopyStream(xSource, xTarget, urlPath);
536 
537  return urlPath;
538  }
539  catch (uno::Exception const&)
540  {
541  TOOLS_INFO_EXCEPTION("xmloff", "exception while storing embedded media");
542  }
543  return OUString();
544  }
545  else
546  {
547  return rExport.GetRelativeReference(rURL); // linked
548  }
549 }
550 
552 {
553  if( !(mbHasTransition && mxPageProps.is()) )
554  return;
555 
556  sal_Int16 nTransition = 0;
557  mxPageProps->getPropertyValue("TransitionType") >>= nTransition;
558 
559  Any aSound( mxPageProps->getPropertyValue("Sound") );
560  OUString sSoundURL;
561  aSound >>= sSoundURL;
562  bool bStopSound = false;
563  if( !(aSound >>= bStopSound) )
564  bStopSound = false;
565 
566 
567  OUStringBuffer sTmp;
568  if( !((nTransition != 0) || !sSoundURL.isEmpty() || bStopSound) )
569  return;
570 
571  Reference< XInterface > xSource( mxPageProps.get() );
572  Event aEvent;
573  aEvent.Source <<= xSource;
574  aEvent.Trigger = EventTrigger::BEGIN_EVENT;
575  aEvent.Repeat = 0;
576 
577  convertTiming( sTmp, Any( aEvent ) );
578  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_BEGIN, sTmp.makeStringAndClear() );
579 
580  SvXMLElementExport aElement( *mxExport, XML_NAMESPACE_ANIMATION, XML_PAR, true, true );
581 
582  if( nTransition != 0 )
583  {
584  sal_Int16 nSubtype = 0;
585  bool bDirection = false;
586  sal_Int32 nFadeColor = 0;
587  double fDuration = 0.0;
588  mxPageProps->getPropertyValue("TransitionSubtype") >>= nSubtype;
589  mxPageProps->getPropertyValue("TransitionDirection") >>= bDirection;
590  mxPageProps->getPropertyValue("TransitionFadeColor") >>= nFadeColor;
591  mxPageProps->getPropertyValue("TransitionDuration") >>= fDuration;
592 
593  ::sax::Converter::convertDouble( sTmp, fDuration );
594  sTmp.append( 's');
595  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_DUR, sTmp.makeStringAndClear() );
596 
597  SvXMLUnitConverter::convertEnum( sTmp, nTransition, aAnimations_EnumMap_TransitionType );
598  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_TYPE, sTmp.makeStringAndClear() );
599 
600  if( nSubtype != TransitionSubType::DEFAULT )
601  {
602  SvXMLUnitConverter::convertEnum( sTmp, nSubtype, aAnimations_EnumMap_TransitionSubType );
603  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_SUBTYPE, sTmp.makeStringAndClear() );
604  }
605 
606  if( !bDirection )
608 
609  if( (nTransition == TransitionType::FADE) && ((nSubtype == TransitionSubType::FADETOCOLOR) || (nSubtype == TransitionSubType::FADEFROMCOLOR) ))
610  {
611  ::sax::Converter::convertColor( sTmp, nFadeColor );
612  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_FADECOLOR, sTmp.makeStringAndClear() );
613  }
615  }
616 
617  if( bStopSound )
618  {
621  }
622  else if( !sSoundURL.isEmpty())
623  {
624  sSoundURL = lcl_StoreMediaAndGetURL(*mxExport, sSoundURL);
625  mxExport->AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sSoundURL );
626 
627  bool bLoopSound = false;
628  mxPageProps->getPropertyValue("LoopSound") >>= bLoopSound;
629 
630  if( bLoopSound )
632  SvXMLElementExport aElement2( *mxExport, XML_NAMESPACE_ANIMATION, XML_AUDIO, true, true );
633  }
634 }
635 
637 {
638  if( !mxPageProps.is() )
639  return;
640 
641  try
642  {
643  sal_Int16 nTransition = 0;
644  mxPageProps->getPropertyValue("TransitionType") >>= nTransition;
645 
646  bool bStopSound = false;
647  OUString sSoundURL;
648 
649  if( nTransition == 0 )
650  {
651  Any aSound( mxPageProps->getPropertyValue("Sound") );
652  aSound >>= sSoundURL;
653 
654  if( !(aSound >>= bStopSound) )
655  bStopSound = false;
656  }
657 
658  if( (nTransition != 0) || !sSoundURL.isEmpty() || bStopSound )
659  {
660  mbHasTransition = true;
661  Reference< XInterface > xInt( mxPageProps.get() );
662  mxExport->getInterfaceToIdentifierMapper().registerReference( xInt );
663  }
664  }
665  catch (const Exception&)
666  {
667  OSL_FAIL( "xmloff::AnimationsExporterImpl::prepareNode(), Exception caught!" );
668  }
669 }
670 
671 void AnimationsExporterImpl::prepareNode( const Reference< XAnimationNode >& xNode )
672 {
673  try
674  {
675  prepareValue( xNode->getBegin() );
676  prepareValue( xNode->getEnd() );
677 
678  sal_Int16 nNodeType = xNode->getType();
679  switch( nNodeType )
680  {
681  case AnimationNodeType::ITERATE:
682  {
683  Reference< XIterateContainer > xIter( xNode, UNO_QUERY_THROW );
684  prepareValue( xIter->getTarget() );
685  [[fallthrough]];
686  }
687  case AnimationNodeType::PAR:
688  case AnimationNodeType::SEQ:
689  {
690  Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY_THROW );
691  Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), css::uno::UNO_SET_THROW );
692  while( xEnumeration->hasMoreElements() )
693  {
694  Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
695  prepareNode( xChildNode );
696  }
697  }
698  break;
699 
700  case AnimationNodeType::ANIMATE:
701  case AnimationNodeType::SET:
702  case AnimationNodeType::ANIMATEMOTION:
703  case AnimationNodeType::ANIMATEPHYSICS:
704  case AnimationNodeType::ANIMATECOLOR:
705  case AnimationNodeType::ANIMATETRANSFORM:
706  case AnimationNodeType::TRANSITIONFILTER:
707  {
708  Reference< XAnimate > xAnimate( xNode, UNO_QUERY_THROW );
709  prepareValue( xAnimate->getTarget() );
710  }
711  break;
712 
713  case AnimationNodeType::COMMAND:
714  {
715  Reference< XCommand > xCommand( xNode, UNO_QUERY_THROW );
716  prepareValue( xCommand->getTarget() );
717  }
718  break;
719 
720  case AnimationNodeType::AUDIO:
721  {
722  Reference< XAudio > xAudio( xNode, UNO_QUERY_THROW );
723  prepareValue( xAudio->getSource() );
724  }
725  break;
726  }
727 
728  const Sequence< NamedValue > aUserData( xNode->getUserData() );
729  for( const auto& rValue : aUserData )
730  {
731  if( IsXMLToken( rValue.Name, XML_MASTER_ELEMENT ) )
732  {
733  Reference< XInterface > xMaster;
734  rValue.Value >>= xMaster;
735  if( xMaster.is() )
736  mxExport->getInterfaceToIdentifierMapper().registerReference( xMaster );
737  }
738  }
739  }
740  catch (const Exception&)
741  {
742  OSL_FAIL( "xmloff::AnimationsExporterImpl::prepareNode(), RuntimeException caught!" );
743  }
744 }
745 
746 void AnimationsExporterImpl::exportNode( const Reference< XAnimationNode >& xNode )
747 {
748  try
749  {
750  OUStringBuffer sTmp;
751 
752  const OUString& rExportIdentifier = mxExport->getInterfaceToIdentifierMapper().getIdentifier( xNode );
753  if( !rExportIdentifier.isEmpty() )
754  {
755  mxExport->AddAttributeIdLegacy(
756  XML_NAMESPACE_ANIMATION, rExportIdentifier);
757  }
758 
759  Any aTemp( xNode->getBegin() );
760  if( aTemp.hasValue() )
761  {
762  convertTiming( sTmp, aTemp );
763  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_BEGIN, sTmp.makeStringAndClear() );
764  }
765 
766  double fTemp = 0;
767  sal_Int16 nTemp;
768 
769  aTemp = xNode->getDuration();
770  if( aTemp.hasValue() )
771  {
772  if( aTemp >>= fTemp )
773  {
774  ::sax::Converter::convertDouble( sTmp, fTemp );
775  sTmp.append( 's');
776  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_DUR, sTmp.makeStringAndClear() );
777  }
778  else
779  {
780  Timing eTiming;
781  if( aTemp >>= eTiming )
782  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_DUR, eTiming == Timing_INDEFINITE ? XML_INDEFINITE : XML_MEDIA );
783  }
784  }
785 
786  aTemp = xNode->getEnd();
787  if( aTemp.hasValue() )
788  {
789  convertTiming( sTmp, aTemp );
790  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_END, sTmp.makeStringAndClear() );
791  }
792 
793  nTemp = xNode->getFill();
794  if( nTemp != AnimationFill::DEFAULT )
795  {
796  SvXMLUnitConverter::convertEnum( sTmp, nTemp, aAnimations_EnumMap_Fill );
797  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_FILL, sTmp.makeStringAndClear() );
798  }
799 
800  nTemp = xNode->getFillDefault();
801  if( nTemp != AnimationFill::INHERIT )
802  {
803  SvXMLUnitConverter::convertEnum( sTmp, nTemp, aAnimations_EnumMap_FillDefault );
804  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_FILLDEFAULT, sTmp.makeStringAndClear() );
805  }
806 
807  nTemp = xNode->getRestart();
808  if( nTemp != AnimationRestart::DEFAULT )
809  {
810  SvXMLUnitConverter::convertEnum( sTmp, nTemp, aAnimations_EnumMap_Restart );
811  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_RESTART, sTmp.makeStringAndClear() );
812  }
813 
814  nTemp = xNode->getRestartDefault();
815  if( nTemp != AnimationRestart::INHERIT )
816  {
817  SvXMLUnitConverter::convertEnum( sTmp, nTemp, aAnimations_EnumMap_RestartDefault );
818  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_RESTARTDEFAULT, sTmp.makeStringAndClear() );
819  }
820 
821  fTemp = xNode->getAcceleration();
822  if( fTemp != 0.0 )
823  {
824  ::sax::Converter::convertDouble( sTmp, fTemp );
825  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_ACCELERATE, sTmp.makeStringAndClear() );
826  }
827 
828  fTemp = xNode->getDecelerate();
829  if( fTemp != 0.0 )
830  {
831  ::sax::Converter::convertDouble( sTmp, fTemp );
832  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_DECELERATE, sTmp.makeStringAndClear() );
833  }
834 
835  bool bTemp = xNode->getAutoReverse();
836  if( bTemp )
837  {
838  ::sax::Converter::convertBool( sTmp, bTemp );
839  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_AUTOREVERSE, sTmp.makeStringAndClear() );
840  }
841 
842  aTemp = xNode->getRepeatCount();
843  if( aTemp.hasValue() )
844  {
845  Timing eTiming;
846  if( (aTemp >>= eTiming ) && (eTiming == Timing_INDEFINITE ) )
848  else if( aTemp >>= fTemp )
849  {
850  ::sax::Converter::convertDouble( sTmp, fTemp );
851  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_REPEATCOUNT, sTmp.makeStringAndClear() );
852  }
853  }
854 
855  aTemp = xNode->getRepeatDuration();
856  if( aTemp.hasValue() )
857  {
858  Timing eTiming;
859  if( ( aTemp >>= eTiming ) && (eTiming == Timing_INDEFINITE) )
860  {
862  }
863  else if( aTemp >>= fTemp )
864  {
865  ::sax::Converter::convertDouble( sTmp, fTemp );
866  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_REPEATDUR, sTmp.makeStringAndClear() );
867  }
868  }
869 
870  aTemp = xNode->getEndSync();
871  if( aTemp.hasValue() && (aTemp >>= nTemp) )
872  {
873  SvXMLUnitConverter::convertEnum( sTmp, nTemp, aAnimations_EnumMap_Endsync );
874  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_ENDSYNC, sTmp.makeStringAndClear() );
875  }
876 
877  sal_Int16 nContainerNodeType = EffectNodeType::DEFAULT;
878  OUString aPresetId;
879  const Sequence< NamedValue > aUserData( xNode->getUserData() );
880  for( const auto& rValue : aUserData )
881  {
882  if( IsXMLToken( rValue.Name, XML_NODE_TYPE ) )
883  {
884  if( (rValue.Value >>= nContainerNodeType) && (nContainerNodeType != EffectNodeType::DEFAULT) )
885  {
886  SvXMLUnitConverter::convertEnum( sTmp, nContainerNodeType, aAnimations_EnumMap_EffectNodeType );
887  mxExport->AddAttribute( XML_NAMESPACE_PRESENTATION, XML_NODE_TYPE, sTmp.makeStringAndClear() );
888  }
889  }
890  else if( IsXMLToken( rValue.Name, XML_PRESET_ID ) )
891  {
892  if( rValue.Value >>= aPresetId )
893  {
894  mxExport->AddAttribute( XML_NAMESPACE_PRESENTATION, XML_PRESET_ID, aPresetId );
895  }
896  }
897  else if( IsXMLToken( rValue.Name, XML_PRESET_SUB_TYPE ) )
898  {
899  OUString aPresetSubType;
900  if( rValue.Value >>= aPresetSubType )
901  {
902  mxExport->AddAttribute( XML_NAMESPACE_PRESENTATION, XML_PRESET_SUB_TYPE, aPresetSubType );
903  }
904  }
905  else if( IsXMLToken( rValue.Name, XML_PRESET_CLASS ) )
906  {
907  sal_Int16 nEffectPresetClass = sal_uInt16();
908  if( rValue.Value >>= nEffectPresetClass )
909  {
910  SvXMLUnitConverter::convertEnum( sTmp, nEffectPresetClass, aAnimations_EnumMap_EffectPresetClass );
911  mxExport->AddAttribute( XML_NAMESPACE_PRESENTATION, XML_PRESET_CLASS, sTmp.makeStringAndClear() );
912  }
913  }
914  else if( IsXMLToken( rValue.Name, XML_MASTER_ELEMENT ) )
915  {
916  Reference< XInterface > xMaster;
917  rValue.Value >>= xMaster;
918  if( xMaster.is() )
919  {
920  const OUString& rIdentifier = mxExport->getInterfaceToIdentifierMapper().getIdentifier(xMaster);
921  if( !rIdentifier.isEmpty() )
922  mxExport->AddAttribute( XML_NAMESPACE_PRESENTATION, XML_MASTER_ELEMENT, rIdentifier );
923  }
924  }
925  else if( IsXMLToken( rValue.Name, XML_GROUP_ID ) )
926  {
927  sal_Int32 nGroupId = 0;
928  if( rValue.Value >>= nGroupId )
929  mxExport->AddAttribute( XML_NAMESPACE_PRESENTATION, XML_GROUP_ID, OUString::number( nGroupId ) );
930  }
931  else
932  {
933  OUString aTmp;
934  if( rValue.Value >>= aTmp )
935  mxExport->AddAttribute( XML_NAMESPACE_PRESENTATION, rValue.Name, aTmp );
936  }
937  }
938 
939  nTemp = xNode->getType();
940  switch( nTemp )
941  {
942  case AnimationNodeType::PAR:
943  case AnimationNodeType::SEQ:
944  case AnimationNodeType::ITERATE:
945  {
946  Reference< XTimeContainer > xContainer( xNode, UNO_QUERY_THROW );
947  exportContainer( xContainer, nContainerNodeType );
948  }
949  break;
950 
951  case AnimationNodeType::ANIMATE:
952  case AnimationNodeType::SET:
953  case AnimationNodeType::ANIMATEMOTION:
954  case AnimationNodeType::ANIMATEPHYSICS:
955  case AnimationNodeType::ANIMATECOLOR:
956  case AnimationNodeType::ANIMATETRANSFORM:
957  case AnimationNodeType::TRANSITIONFILTER:
958  {
959  Reference< XAnimate > xAnimate( xNode, UNO_QUERY_THROW );
960  exportAnimate( xAnimate );
961  }
962  break;
963  case AnimationNodeType::AUDIO:
964  {
965  Reference< XAudio > xAudio( xNode, UNO_QUERY_THROW );
966  exportAudio( xAudio );
967  }
968  break;
969  case AnimationNodeType::COMMAND:
970  {
971  Reference< XCommand > xCommand( xNode, UNO_QUERY_THROW );
972  exportCommand( xCommand );
973  }
974  break;
975  default:
976  OSL_FAIL( "xmloff::AnimationsExporterImpl::exportNode(), invalid AnimationNodeType!" );
977  }
978  }
979  catch (const RuntimeException&)
980  {
981  OSL_FAIL( "xmloff::AnimationsExporterImpl::exportNode(), RuntimeException caught!" );
982  }
983 
984  // if something goes wrong, its always a good idea to clear the attribute list
985  mxExport->ClearAttrList();
986 }
987 
988 void AnimationsExporterImpl::exportContainer( const Reference< XTimeContainer >& xContainer, sal_Int16 nContainerNodeType )
989 {
990  try
991  {
992  const sal_Int32 nNodeType = xContainer->getType();
993 
994  if( nNodeType == AnimationNodeType::ITERATE )
995  {
996  OUStringBuffer sTmp;
997  Reference< XIterateContainer > xIter( xContainer, UNO_QUERY_THROW );
998 
999  Any aTemp( xIter->getTarget() );
1000  if( aTemp.hasValue() )
1001  {
1002  convertTarget( sTmp, aTemp );
1003  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_TARGETELEMENT, sTmp.makeStringAndClear() );
1004  }
1005 
1006  sal_Int16 nTemp = xIter->getSubItem();
1007  if( nTemp )
1008  {
1009  SvXMLUnitConverter::convertEnum( sTmp, nTemp, aAnimations_EnumMap_SubItem );
1010  mxExport->AddAttribute( XML_NAMESPACE_ANIMATION, XML_SUB_ITEM, sTmp.makeStringAndClear() );
1011  }
1012 
1013  nTemp = xIter->getIterateType();
1014  if( nTemp )
1015  {
1016  SvXMLUnitConverter::convertEnum( sTmp, nTemp, aAnimations_EnumMap_IterateType );
1017  mxExport->AddAttribute( XML_NAMESPACE_ANIMATION, XML_ITERATE_TYPE, sTmp.makeStringAndClear() );
1018  }
1019 
1020  double fTemp = xIter->getIterateInterval();
1021  if( fTemp )
1022  {
1023  OUStringBuffer buf;
1024  ::sax::Converter::convertDuration(buf, fTemp / (24*60*60));
1025  mxExport->AddAttribute( XML_NAMESPACE_ANIMATION,
1026  XML_ITERATE_INTERVAL, buf.makeStringAndClear());
1027  }
1028  }
1029 
1030  XMLTokenEnum eElementToken;
1031  switch( nNodeType )
1032  {
1033  case AnimationNodeType::PAR: eElementToken = XML_PAR; break;
1034  case AnimationNodeType::SEQ: eElementToken = XML_SEQ; break;
1035  case AnimationNodeType::ITERATE:eElementToken = XML_ITERATE; break;
1036  default:
1037  OSL_FAIL( "xmloff::AnimationsExporterImpl::exportContainer(), invalid TimeContainerType!" );
1038  return;
1039  }
1040  SvXMLElementExport aElement( *mxExport, XML_NAMESPACE_ANIMATION, eElementToken, true, true );
1041 
1042  if( nContainerNodeType == EffectNodeType::TIMING_ROOT )
1044 
1045  Reference< XEnumerationAccess > xEnumerationAccess( xContainer, UNO_QUERY_THROW );
1046  Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), css::uno::UNO_SET_THROW );
1047  while( xEnumeration->hasMoreElements() )
1048  {
1049  Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
1050  exportNode( xChildNode );
1051  }
1052  }
1053  catch (const RuntimeException&)
1054  {
1055  OSL_FAIL( "xmloff::AnimationsExporterImpl::exportContainer(), RuntimeException caught!" );
1056  }
1057 }
1058 
1059 void AnimationsExporterImpl::exportAnimate( const Reference< XAnimate >& xAnimate )
1060 {
1061  try
1062  {
1063  const sal_Int16 nNodeType = xAnimate->getType();
1064 
1065  OUStringBuffer sTmp;
1066  sal_Int16 nTemp;
1067  bool bTemp;
1068 
1069  Any aTemp( xAnimate->getTarget() );
1070  if( aTemp.hasValue() )
1071  {
1072  convertTarget( sTmp, aTemp );
1073  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_TARGETELEMENT, sTmp.makeStringAndClear() );
1074  }
1075 
1076  nTemp = xAnimate->getSubItem();
1077  if( nTemp )
1078  {
1079  SvXMLUnitConverter::convertEnum( sTmp, nTemp, aAnimations_EnumMap_SubItem );
1080  mxExport->AddAttribute( XML_NAMESPACE_ANIMATION, XML_SUB_ITEM, sTmp.makeStringAndClear() );
1081  }
1082 
1083  XMLTokenEnum eAttributeName = XML_TOKEN_INVALID;
1084 
1085  if( nNodeType == AnimationNodeType::TRANSITIONFILTER )
1086  {
1087  eAttributeName = XML_TRANSITIONFILTER;
1088  }
1089  else if( nNodeType == AnimationNodeType::ANIMATETRANSFORM )
1090  {
1091  eAttributeName = XML_ANIMATETRANSFORM;
1092  }
1093  else if( nNodeType == AnimationNodeType::ANIMATEMOTION )
1094  {
1095  eAttributeName = XML_ANIMATEMOTION;
1096  }
1097  else if( nNodeType == AnimationNodeType::ANIMATEPHYSICS )
1098  {
1099  eAttributeName = XML_ANIMATEPHYSICS;
1100  }
1101  else
1102  {
1103  OUString sTemp( xAnimate->getAttributeName() );
1104  if( !sTemp.isEmpty() )
1105  {
1107  while( p->mpAPIName )
1108  {
1109  if( sTemp.equalsAscii( p->mpAPIName ) )
1110  {
1111  sTemp = GetXMLToken( p->meXMLToken );
1112  eAttributeName = p->meXMLToken;
1113  break;
1114  }
1115 
1116  p++;
1117  }
1118 
1119  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_ATTRIBUTENAME, sTemp );
1120  }
1121  else
1122  {
1123  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_ATTRIBUTENAME, "invalid" );
1124  }
1125  }
1126 
1127  Sequence< Any > aValues( xAnimate->getValues() );
1128  if( aValues.hasElements() )
1129  {
1130  aTemp <<= aValues;
1131  convertValue( eAttributeName, sTmp, aTemp );
1132  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_VALUES, sTmp.makeStringAndClear() );
1133  }
1134  else
1135  {
1136  aTemp = xAnimate->getFrom();
1137  if( aTemp.hasValue() )
1138  {
1139  convertValue( eAttributeName, sTmp, aTemp );
1140  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_FROM, sTmp.makeStringAndClear() );
1141  }
1142 
1143  aTemp = xAnimate->getBy();
1144  if( aTemp.hasValue() )
1145  {
1146  convertValue( eAttributeName, sTmp, aTemp );
1147  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_BY, sTmp.makeStringAndClear() );
1148  }
1149 
1150  aTemp = xAnimate->getTo();
1151  if( aTemp.hasValue() )
1152  {
1153  convertValue( eAttributeName, sTmp, aTemp );
1154  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_TO, sTmp.makeStringAndClear() );
1155  }
1156  }
1157 
1158  if(nNodeType != AnimationNodeType::SET)
1159  {
1160  const Sequence< double > aKeyTimes( xAnimate->getKeyTimes() );
1161  if( aKeyTimes.hasElements() )
1162  {
1163  for( const auto& rKeyTime : aKeyTimes )
1164  {
1165  if( !sTmp.isEmpty() )
1166  sTmp.append( ';' );
1167 
1168  sTmp.append( rKeyTime );
1169  }
1170  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_KEYTIMES, sTmp.makeStringAndClear() );
1171  }
1172 
1173  OUString sTemp( xAnimate->getFormula() );
1174  if( !sTemp.isEmpty() )
1175  mxExport->AddAttribute( XML_NAMESPACE_ANIMATION, XML_FORMULA, sTemp );
1176 
1177  if( (nNodeType != AnimationNodeType::TRANSITIONFILTER) &&
1178  (nNodeType != AnimationNodeType::AUDIO ) )
1179  {
1180  // calcMode = "discrete | linear | paced | spline"
1181  nTemp = xAnimate->getCalcMode();
1182  if( ((nNodeType == AnimationNodeType::ANIMATEMOTION ) && (nTemp != AnimationCalcMode::PACED)) ||
1183  ((nNodeType != AnimationNodeType::ANIMATEMOTION ) && (nTemp != AnimationCalcMode::LINEAR)) )
1184  {
1185  SvXMLUnitConverter::convertEnum( sTmp, nTemp, aAnimations_EnumMap_CalcMode );
1186  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_CALCMODE, sTmp.makeStringAndClear() );
1187  }
1188 
1189  bTemp = xAnimate->getAccumulate();
1190  if( bTemp )
1192 
1193  nTemp = xAnimate->getAdditive();
1194  if( nTemp != AnimationAdditiveMode::REPLACE )
1195  {
1196  SvXMLUnitConverter::convertEnum( sTmp, nTemp, aAnimations_EnumMap_AdditiveMode );
1197  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_ADDITIVE, sTmp.makeStringAndClear() );
1198  }
1199  }
1200 
1201  const Sequence< TimeFilterPair > aTimeFilter( xAnimate->getTimeFilter() );
1202  if( aTimeFilter.hasElements() )
1203  {
1204  for( const auto& rPair : aTimeFilter )
1205  {
1206  if( !sTmp.isEmpty() )
1207  sTmp.append( ';' );
1208 
1209  sTmp.append( OUString::number(rPair.Time) ).append( "," ).append( OUString::number(rPair.Progress) );
1210  }
1211 
1212  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_KEYSPLINES, sTmp.makeStringAndClear() );
1213  }
1214  }
1215 
1216  XMLTokenEnum eElementToken = XML_ANIMATE;
1217 
1218  switch( nNodeType )
1219  {
1220  case AnimationNodeType::ANIMATE:
1221  eElementToken = XML_ANIMATE;
1222  break;
1223 
1224  case AnimationNodeType::SET:
1225  eElementToken = XML_SET;
1226  break;
1227 
1228  case AnimationNodeType::ANIMATEMOTION:
1229  {
1230  eElementToken = XML_ANIMATEMOTION;
1231 
1232  Reference< XAnimateMotion > xAnimateMotion( xAnimate, UNO_QUERY_THROW );
1233 
1234  aTemp = xAnimateMotion->getPath();
1235  if( aTemp.hasValue() )
1236  {
1237  convertPath( sTmp, aTemp );
1238  mxExport->AddAttribute( XML_NAMESPACE_SVG, XML_PATH, sTmp.makeStringAndClear() );
1239  }
1240 
1241  // TODO: origin = ( parent | layout )
1242  aTemp = xAnimateMotion->getOrigin();
1243  }
1244  break;
1245 
1246  case AnimationNodeType::ANIMATEPHYSICS:
1247  {
1248  eElementToken = XML_ANIMATEPHYSICS;
1249  double fTemp = 0;
1250 
1251  Reference< XAnimatePhysics > xAnimatePhysics( xAnimate, UNO_QUERY_THROW );
1252  aTemp = xAnimatePhysics->getStartVelocityX();
1253  if( aTemp.hasValue() )
1254  {
1255  aTemp >>= fTemp;
1256  ::sax::Converter::convertDouble( sTmp, fTemp );
1257  mxExport->AddAttribute( XML_NAMESPACE_LO_EXT, XML_PHYSICS_ANIMATION_START_VELOCITY_X, sTmp.makeStringAndClear() );
1258  }
1259 
1260  aTemp = xAnimatePhysics->getStartVelocityY();
1261  if( aTemp.hasValue() )
1262  {
1263  aTemp >>= fTemp;
1264  ::sax::Converter::convertDouble( sTmp, fTemp );
1265  mxExport->AddAttribute( XML_NAMESPACE_LO_EXT, XML_PHYSICS_ANIMATION_START_VELOCITY_Y, sTmp.makeStringAndClear() );
1266  }
1267 
1268  aTemp = xAnimatePhysics->getDensity();
1269  if( aTemp.hasValue() )
1270  {
1271  aTemp >>= fTemp;
1272  ::sax::Converter::convertDouble( sTmp, fTemp );
1273  mxExport->AddAttribute( XML_NAMESPACE_LO_EXT, XML_PHYSICS_ANIMATION_DENSITY, sTmp.makeStringAndClear() );
1274  }
1275 
1276  aTemp = xAnimatePhysics->getBounciness();
1277  if( aTemp.hasValue() )
1278  {
1279  aTemp >>= fTemp;
1280  ::sax::Converter::convertDouble( sTmp, fTemp );
1281  mxExport->AddAttribute( XML_NAMESPACE_LO_EXT, XML_PHYSICS_ANIMATION_BOUNCINESS, sTmp.makeStringAndClear() );
1282  }
1283  }
1284  break;
1285 
1286  case AnimationNodeType::ANIMATECOLOR:
1287  {
1288  eElementToken = XML_ANIMATECOLOR;
1289 
1290  Reference< XAnimateColor > xAnimateColor( xAnimate, UNO_QUERY_THROW );
1291 
1292  nTemp = xAnimateColor->getColorInterpolation();
1293  mxExport->AddAttribute( XML_NAMESPACE_ANIMATION, XML_COLOR_INTERPOLATION, (nTemp == AnimationColorSpace::RGB) ? XML_RGB : XML_HSL );
1294 
1295  bTemp = xAnimateColor->getDirection();
1297  }
1298  break;
1299 
1300  case AnimationNodeType::ANIMATETRANSFORM:
1301  {
1302  eElementToken = XML_ANIMATETRANSFORM;
1303 
1305 
1306  Reference< XAnimateTransform > xTransform( xAnimate, UNO_QUERY_THROW );
1307  nTemp = xTransform->getTransformType();
1308  SvXMLUnitConverter::convertEnum( sTmp, nTemp, aAnimations_EnumMap_TransformType );
1309  mxExport->AddAttribute( XML_NAMESPACE_SVG, XML_TYPE, sTmp.makeStringAndClear() );
1310  }
1311  break;
1312 
1313  case AnimationNodeType::TRANSITIONFILTER:
1314  {
1315  Reference< XTransitionFilter > xTransitionFilter( xAnimate, UNO_QUERY );
1316  eElementToken = XML_TRANSITIONFILTER;
1317 
1318  sal_Int16 nTransition = xTransitionFilter->getTransition();
1319  SvXMLUnitConverter::convertEnum( sTmp, nTransition, aAnimations_EnumMap_TransitionType );
1320  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_TYPE, sTmp.makeStringAndClear() );
1321 
1322  sal_Int16 nSubtype = xTransitionFilter->getSubtype();
1323  if( nSubtype != TransitionSubType::DEFAULT )
1324  {
1325  SvXMLUnitConverter::convertEnum( sTmp, nSubtype, aAnimations_EnumMap_TransitionSubType );
1326  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_SUBTYPE, sTmp.makeStringAndClear() );
1327  }
1328 
1329  bTemp = xTransitionFilter->getMode();
1330  if( !bTemp )
1331  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_MODE, XML_OUT );
1332 
1333  bTemp = xTransitionFilter->getDirection();
1334  if( !bTemp )
1336 
1337  if( (nTransition == TransitionType::FADE) && ((nSubtype == TransitionSubType::FADETOCOLOR) || (nSubtype == TransitionSubType::FADEFROMCOLOR) ))
1338  {
1339  nTemp = xTransitionFilter->getFadeColor();
1340  ::sax::Converter::convertColor( sTmp, nTemp );
1341  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_FADECOLOR, sTmp.makeStringAndClear() );
1342  }
1343  }
1344  break;
1345  }
1346 
1347  if( eElementToken == XML_ANIMATEPHYSICS ) // not a standard should use the extension namespace
1348  {
1349  SvXMLElementExport aElement( *mxExport, XML_NAMESPACE_LO_EXT, eElementToken, true, true );
1350  }
1351  else
1352  {
1353  SvXMLElementExport aElement( *mxExport, XML_NAMESPACE_ANIMATION, eElementToken, true, true );
1354  }
1355 
1356  }
1357  catch (const Exception&)
1358  {
1359  OSL_FAIL( "xmloff::AnimationsExporterImpl::exportAnimate(), exception caught!" );
1360  }
1361 }
1362 
1363 void AnimationsExporterImpl::exportAudio( const Reference< XAudio >& xAudio )
1364 {
1365  if( !xAudio.is() )
1366  return;
1367 
1368  try
1369  {
1370  OUString aSourceURL;
1371  xAudio->getSource() >>= aSourceURL;
1372  if( !aSourceURL.isEmpty() )
1373  mxExport->AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, mxExport->GetRelativeReference( aSourceURL ) );
1374 
1375  const double fVolume = xAudio->getVolume();
1376  if( fVolume != 1.0 )
1377  {
1378  OUStringBuffer sTmp;
1379  ::sax::Converter::convertDouble( sTmp, fVolume );
1380  mxExport->AddAttribute( XML_NAMESPACE_ANIMATION, XML_AUDIO_LEVEL, sTmp.makeStringAndClear() );
1381  }
1382 
1383  /* todo?
1384  sal_Int32 nEndAfterSlide = 0;
1385  xAudio->getEndAfterSlide() >>= nEndAfterSlide;
1386  if( nEndAfterSlide != 0 )
1387  mxExport->AddAttribute( );
1388  */
1389  SvXMLElementExport aElement( *mxExport, XML_NAMESPACE_ANIMATION, XML_AUDIO, true, true );
1390 
1391  }
1392  catch (const Exception&)
1393  {
1394  OSL_FAIL( "xmloff::AnimationsExporterImpl::exportAudio(), exception caught!" );
1395  }
1396 }
1397 
1398 void AnimationsExporterImpl::exportCommand( const Reference< XCommand >& xCommand )
1399 {
1400  if( !xCommand.is() )
1401  return;
1402 
1403  try
1404  {
1405  OUStringBuffer sTmp;
1406  Any aTemp( xCommand->getTarget() );
1407  if( aTemp.hasValue() )
1408  {
1409  convertTarget( sTmp, aTemp );
1410  mxExport->AddAttribute( XML_NAMESPACE_SMIL, XML_TARGETELEMENT, sTmp.makeStringAndClear() );
1411  }
1412 
1413  sal_Int16 nCommand = xCommand->getCommand();
1414  SvXMLUnitConverter::convertEnum( sTmp, nCommand, aAnimations_EnumMap_Command );
1415  mxExport->AddAttribute( XML_NAMESPACE_ANIMATION, XML_COMMAND, sTmp.makeStringAndClear() );
1416 
1417  // todo virtual css::uno::Any SAL_CALL getParameter() throw (css::uno::RuntimeException) = 0;
1418 
1420 
1421  }
1422  catch (const Exception&)
1423  {
1424  OSL_FAIL( "xmloff::AnimationsExporterImpl::exportCommand(), exception caught!" );
1425  }
1426 }
1427 
1429 {
1430  try
1431  {
1432  Reference< XEnumerationAccess > xParaEnumAccess( pTarget.Shape, UNO_QUERY_THROW );
1433 
1434  Reference< XEnumeration > xEnumeration( xParaEnumAccess->createEnumeration(), css::uno::UNO_SET_THROW );
1435  sal_Int32 nParagraph = pTarget.Paragraph;
1436 
1437  while( xEnumeration->hasMoreElements() )
1438  {
1439  Reference< XInterface > xRef( xEnumeration->nextElement(), UNO_QUERY );
1440  if( nParagraph-- == 0 )
1441  return xRef;
1442  }
1443  }
1444  catch (const RuntimeException&)
1445  {
1446  OSL_FAIL( "xmloff::AnimationsExporterImpl::getParagraphTarget(), RuntimeException caught!" );
1447  }
1448 
1450  return xRef;
1451 }
1452 
1453 void AnimationsExporterImpl::convertPath( OUStringBuffer& sTmp, const Any& rPath )
1454 {
1455  OUString aStr;
1456  rPath >>= aStr;
1457 
1458  sTmp = aStr;
1459 }
1460 
1461 void AnimationsExporterImpl::convertValue( XMLTokenEnum eAttributeName, OUStringBuffer& sTmp, const Any& rValue ) const
1462 {
1463  if( !rValue.hasValue() )
1464  return;
1465 
1466  if( auto pValuePair = o3tl::tryAccess<ValuePair>(rValue) )
1467  {
1468  OUStringBuffer sTmp2;
1469  convertValue( eAttributeName, sTmp, pValuePair->First );
1470  sTmp.append( ',' );
1471  convertValue( eAttributeName, sTmp2, pValuePair->Second );
1472  sTmp.append( sTmp2.makeStringAndClear() );
1473  }
1474  else if( auto pSequence = o3tl::tryAccess<Sequence<Any>>(rValue) )
1475  {
1476  const sal_Int32 nLength = pSequence->getLength();
1477  sal_Int32 nElement;
1478  const Any* pAny = pSequence->getConstArray();
1479 
1480  OUStringBuffer sTmp2;
1481 
1482  for( nElement = 0; nElement < nLength; nElement++, pAny++ )
1483  {
1484  if( !sTmp.isEmpty() )
1485  sTmp.append( ';' );
1486  convertValue( eAttributeName, sTmp2, *pAny );
1487  sTmp.append( sTmp2.makeStringAndClear() );
1488  }
1489  }
1490  else
1491  {
1492  sal_Int32 nType;
1493 
1494  switch( eAttributeName )
1495  {
1496  case XML_X:
1497  case XML_Y:
1498  case XML_WIDTH:
1499  case XML_HEIGHT:
1500  case XML_ANIMATETRANSFORM:
1501  case XML_ANIMATEMOTION:
1502  case XML_ANIMATEPHYSICS:
1503  {
1504  if( auto aString = o3tl::tryAccess<OUString>(rValue) )
1505  {
1506  sTmp.append( *aString );
1507  }
1508  else if( auto x = o3tl::tryAccess<double>(rValue) )
1509  {
1510  sTmp.append( *x );
1511  }
1512  else
1513  {
1514  OSL_FAIL( "xmloff::AnimationsExporterImpl::convertValue(), invalid value type!" );
1515  }
1516  return;
1517  }
1518 
1519  case XML_SKEWX:
1520  case XML_ROTATE: nType = XML_TYPE_DOUBLE; break;
1521  case XML_TEXT_ROTATION_ANGLE: nType = XML_TYPE_NUMBER16; break;
1522  case XML_FILL_COLOR:
1523  case XML_STROKE_COLOR:
1524  case XML_DIM:
1525  case XML_COLOR: nType = XML_TYPE_COLOR; break;
1526  case XML_FILL: nType = XML_SD_TYPE_FILLSTYLE; break;
1527  case XML_STROKE: nType = XML_SD_TYPE_STROKE; break;
1528  case XML_FONT_WEIGHT: nType = XML_TYPE_TEXT_WEIGHT; break;
1529  case XML_FONT_STYLE: nType = XML_TYPE_TEXT_POSTURE; break;
1531  case XML_FONT_SIZE: nType = XML_TYPE_DOUBLE_PERCENT; break;
1532  case XML_VISIBILITY: nType = XML_SD_TYPE_PRESPAGE_VISIBILITY; break;
1533  case XML_OPACITY:
1534  case XML_TRANSITIONFILTER: nType = XML_TYPE_DOUBLE; break;
1535  default:
1536  OSL_FAIL( "xmloff::AnimationsExporterImpl::convertValue(), invalid AttributeName!" );
1537  nType = XML_TYPE_STRING;
1538  }
1539 
1540  //const XMLPropertyHandler* pHandler = static_cast<SdXMLExport*>(&mrExport)->GetSdPropHdlFactory()->GetPropertyHandler( nType );
1541  const XMLPropertyHandler* pHandler = mxSdPropHdlFactory->GetPropertyHandler( nType );
1542  if( pHandler )
1543  {
1544  OUString aString;
1545  pHandler->exportXML( aString, rValue, mxExport->GetMM100UnitConverter() );
1546  sTmp.append( aString );
1547  }
1548  }
1549 }
1550 
1551 void AnimationsExporterImpl::convertTiming( OUStringBuffer& sTmp, const Any& rValue ) const
1552 {
1553  if( !rValue.hasValue() )
1554  return;
1555 
1556  if( auto pSequence = o3tl::tryAccess<Sequence<Any>>(rValue) )
1557  {
1558  const sal_Int32 nLength = pSequence->getLength();
1559  sal_Int32 nElement;
1560  const Any* pAny = pSequence->getConstArray();
1561 
1562  OUStringBuffer sTmp2;
1563 
1564  for( nElement = 0; nElement < nLength; nElement++, pAny++ )
1565  {
1566  if( !sTmp.isEmpty() )
1567  sTmp.append( ';' );
1568  convertTiming( sTmp2, *pAny );
1569  sTmp.append( sTmp2.makeStringAndClear() );
1570  }
1571  }
1572  else if( auto x = o3tl::tryAccess<double>(rValue) )
1573  {
1574  sTmp.append( *x );
1575  sTmp.append( 's');
1576  }
1577  else if( auto pTiming = o3tl::tryAccess<Timing>(rValue) )
1578  {
1579  sTmp.append( GetXMLToken( (*pTiming == Timing_MEDIA) ? XML_MEDIA : XML_INDEFINITE ) );
1580  }
1581  else if( auto pEvent = o3tl::tryAccess<Event>(rValue) )
1582  {
1583  OUStringBuffer sTmp2;
1584 
1585  if( pEvent->Trigger != EventTrigger::NONE )
1586  {
1587  if( pEvent->Source.hasValue() )
1588  {
1589  convertTarget( sTmp, pEvent->Source );
1590  sTmp.append( '.' );
1591  }
1592 
1593  SvXMLUnitConverter::convertEnum( sTmp2, pEvent->Trigger, aAnimations_EnumMap_EventTrigger );
1594 
1595  sTmp.append( sTmp2.makeStringAndClear() );
1596  }
1597 
1598  if( pEvent->Offset.hasValue() )
1599  {
1600  convertTiming( sTmp2, pEvent->Offset );
1601 
1602  if( !sTmp.isEmpty() )
1603  sTmp.append( '+' );
1604 
1605  sTmp.append( sTmp2.makeStringAndClear() );
1606  }
1607  }
1608  else
1609  {
1610  OSL_FAIL( "xmloff::AnimationsExporterImpl::convertTiming(), invalid value type!" );
1611  }
1612 }
1613 
1614 void AnimationsExporterImpl::convertTarget( OUStringBuffer& sTmp, const Any& rTarget ) const
1615 {
1616  if( !rTarget.hasValue() )
1617  return;
1618 
1620 
1621  if( !(rTarget >>= xRef) )
1622  {
1623  if( auto pt = o3tl::tryAccess<ParagraphTarget>(rTarget) )
1624  {
1625  xRef = getParagraphTarget( *pt );
1626  }
1627  }
1628 
1629  SAL_WARN_IF( !xRef.is(), "xmloff", "xmloff::AnimationsExporterImpl::convertTarget(), invalid target type!" );
1630  if( xRef.is() )
1631  {
1632  const OUString& rIdentifier = mxExport->getInterfaceToIdentifierMapper().getIdentifier(xRef);
1633  if( !rIdentifier.isEmpty() )
1634  sTmp.append( rIdentifier );
1635  }
1636 }
1637 
1639 {
1640  if( !rValue.hasValue() )
1641  return;
1642 
1643  if( auto pValuePair = o3tl::tryAccess<ValuePair>(rValue) )
1644  {
1645  prepareValue( pValuePair->First );
1646  prepareValue( pValuePair->Second );
1647  }
1648  else if( auto pSequence = o3tl::tryAccess<Sequence<Any>>(rValue) )
1649  {
1650  const sal_Int32 nLength = pSequence->getLength();
1651  sal_Int32 nElement;
1652  const Any* pAny = pSequence->getConstArray();
1653 
1654  for( nElement = 0; nElement < nLength; nElement++, pAny++ )
1655  prepareValue( *pAny );
1656  }
1657  else if( rValue.getValueTypeClass() == css::uno::TypeClass_INTERFACE )
1658  {
1659  Reference< XInterface> xRef( rValue, UNO_QUERY );
1660  if( xRef.is() )
1661  mxExport->getInterfaceToIdentifierMapper().registerReference( xRef );
1662  }
1663  else if( auto pt = o3tl::tryAccess<ParagraphTarget>(rValue) )
1664  {
1666  if( xRef.is() )
1667  mxExport->getInterfaceToIdentifierMapper().registerReference( xRef );
1668  }
1669  else if( auto pEvent = o3tl::tryAccess<Event>(rValue) )
1670  {
1671  prepareValue( pEvent->Source );
1672  }
1673 }
1674 
1676  : mpImpl( new AnimationsExporterImpl( rExport, xPageProps ) )
1677 {
1678 }
1679 
1681 {
1682 }
1683 
1684 void AnimationsExporter::prepare( const Reference< XAnimationNode >& xRootNode )
1685 {
1686  try
1687  {
1688  if( xRootNode.is() )
1689  {
1690  mpImpl->prepareTransitionNode();
1691  mpImpl->prepareNode( xRootNode );
1692  }
1693  }
1694  catch (const RuntimeException&)
1695  {
1696  OSL_FAIL( "xmloff::AnimationsExporter::prepare(), exception caught" );
1697  }
1698 }
1699 
1700 void AnimationsExporter::exportAnimations( const Reference< XAnimationNode >& xRootNode )
1701 {
1702  try
1703  {
1704  if( xRootNode.is() )
1705  {
1706  bool bHasEffects = mpImpl->mbHasTransition;
1707 
1708  if( !bHasEffects )
1709  {
1710  // first check if there are no animations
1711  Reference< XEnumerationAccess > xEnumerationAccess( xRootNode, UNO_QUERY_THROW );
1712  Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), css::uno::UNO_SET_THROW );
1713  if( xEnumeration->hasMoreElements() )
1714  {
1715  // first child node may be an empty main sequence, check this
1716  Reference< XAnimationNode > xMainNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
1717  Reference< XEnumerationAccess > xMainEnumerationAccess( xMainNode, UNO_QUERY_THROW );
1718  Reference< XEnumeration > xMainEnumeration( xMainEnumerationAccess->createEnumeration(), css::uno::UNO_SET_THROW );
1719 
1720  // only export if the main sequence is not empty or if there are additional
1721  // trigger sequences
1722  bHasEffects = xMainEnumeration->hasMoreElements() || xEnumeration->hasMoreElements();
1723  }
1724  }
1725 
1726  if( bHasEffects )
1727  mpImpl->exportNode( xRootNode );
1728  }
1729  }
1730  catch (const RuntimeException&)
1731  {
1732  OSL_FAIL( "xmloff::AnimationsExporter::exportAnimations(), exception caught" );
1733  }
1734 }
1735 
1736 }
1737 
1738 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void exportCommand(const Reference< XCommand > &xCommand)
css::uno::Reference< css::embed::XStorage > const & GetTargetStorage() const
Definition: xmlexp.cxx:2292
#define XML_TYPE_TEXT_UNDERLINE_STYLE
Definition: xmltypes.hxx:172
bool IsXMLToken(const OUString &rString, enum XMLTokenEnum eToken)
compare eToken to the string
Definition: xmltoken.cxx:3434
virtual ~AnimationsExporter() override
constexpr sal_uInt16 XML_NAMESPACE_ANIMATION
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_TransitionSubType[]
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_EffectPresetClass[]
static bool convertEnum(EnumT &rEnum, const OUString &rValue, const SvXMLEnumMapEntry< EnumT > *pMap)
convert string to enum using given enum map, if the enum is not found in the map, this method will re...
Definition: xmluconv.hxx:128
void convertTiming(OUStringBuffer &sTmp, const Any &rTiming) const
#define XML_TYPE_DOUBLE
Definition: xmltypes.hxx:138
static bool convertBool(bool &rBool, const OUString &rString)
void convertTarget(OUStringBuffer &sTmp, const Any &rTarget) const
std::unique_ptr< AnimationsExporterImpl > mpImpl
char const s_PkgScheme[]
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_TransitionType[]
detail::Optional< double >::type tryAccess< double >(css::uno::Any const &any)
void prepareNode(const Reference< XAnimationNode > &xNode)
FilterGroup & rTarget
Reference< XInterface > xTarget
void exportAnimations(const css::uno::Reference< css::animations::XAnimationNode > &xRootNode)
#define XML_TYPE_TEXT_POSTURE
Definition: xmltypes.hxx:170
void exportContainer(const Reference< XTimeContainer > &xNode, sal_Int16 nContainerNodeType)
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_Restart[]
constexpr sal_uInt16 XML_NAMESPACE_XLINK
rtl::Reference< XMLSdPropHdlFactory > mxSdPropHdlFactory
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_TransformType[]
constexpr sal_uInt16 XML_NAMESPACE_LO_EXT
static void lcl_CopyStream(uno::Reference< embed::XStorage > const &xSource, uno::Reference< embed::XStorage > const &xTarget, OUString const &rPath)
rtl::Reference< SvXMLExport > mxExport
float x
static void convertDouble(OUStringBuffer &rBuffer, double fNumber, bool bWriteUnits, sal_Int16 nSourceUnit, sal_Int16 nTargetUnit)
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_Fill[]
css::uno::Any const & rValue
Definition: ImageStyle.hxx:38
#define XML_TYPE_DOUBLE_PERCENT
Definition: xmltypes.hxx:154
const css::uno::Reference< css::frame::XModel > & GetModel() const
Definition: xmlexp.hxx:414
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_Command[]
#define XML_SD_TYPE_STROKE
Definition: xmlsdtypes.hxx:34
std::enable_if< !(detail::IsDerivedReference< T >::value||detail::IsUnoSequenceType< T >::value||std::is_base_of< css::uno::XInterface, T >::value), typename detail::Optional< T >::type >::type tryAccess(css::uno::Any const &any)
#define XML_SD_TYPE_PRESPAGE_VISIBILITY
Definition: xmlsdtypes.hxx:39
static void convertPath(OUStringBuffer &sTmp, const Any &rPath)
static Reference< XInterface > getParagraphTarget(const ParagraphTarget &pTarget)
Reference< XPropertySet > mxPageProps
OUString GetRelativeReference(const OUString &rValue)
Definition: xmlexp.cxx:2089
XMLTokenEnum
The enumeration of all XML tokens.
Definition: xmltoken.hxx:49
#define SAL_N_ELEMENTS(arr)
constexpr sal_uInt16 XML_NAMESPACE_SVG
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_EffectNodeType[]
static bool splitPath(OUString const &i_rPath, OUString &o_rDir, OUString &o_rRest)
split a uri hierarchy into first segment and rest
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_Endsync[]
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_CalcMode[]
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_EventTrigger[]
void exportNode(const Reference< XAnimationNode > &xNode)
const struct ImplAttributeNameConversion * getAnimationAttributeNamesConversionList()
float u
virtual bool exportXML(OUString &rStrExpValue, const css::uno::Any &rValue, const SvXMLUnitConverter &rUnitConverter) const =0
Exports the given value according to the XML-data-type corresponding to the derived class...
#define XML_SD_TYPE_FILLSTYLE
Definition: xmlsdtypes.hxx:43
static void convertDuration(OUStringBuffer &rBuffer, const double fTime)
void prepare(const css::uno::Reference< css::animations::XAnimationNode > &xRootNode)
#define XML_TYPE_NUMBER16
Definition: xmltypes.hxx:136
void convertValue(XMLTokenEnum eAttributeName, OUStringBuffer &sTmp, const Any &rValue) const
const sal_uInt16 idx[]
AnimationsExporter(SvXMLExport &rExport, const css::uno::Reference< css::beans::XPropertySet > &xPageProps)
void prepareValue(const Any &rValue)
#define TOOLS_INFO_EXCEPTION(area, stream)
Map an XMLTokenEnum to an enum value.
Definition: ximpshap.hxx:40
constexpr sal_uInt16 XML_NAMESPACE_PRESENTATION
#define XML_TYPE_STRING
Definition: xmltypes.hxx:132
void exportAnimate(const Reference< XAnimate > &xNode)
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_SubItem[]
#define SAL_WARN_IF(condition, area, stream)
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
return the OUString representation for eToken
Definition: xmltoken.cxx:3378
constexpr sal_uInt16 XML_NAMESPACE_SMIL
static bool convertColor(sal_Int32 &rColor, const OUString &rValue)
Handling of tokens in XML:
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_RestartDefault[]
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_IterateType[]
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_AdditiveMode[]
void * p
QPRO_FUNC_TYPE nType
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_FillDefault[]
static OUString lcl_StoreMediaAndGetURL(SvXMLExport &rExport, OUString const &rURL)
#define XML_TYPE_TEXT_WEIGHT
Definition: xmltypes.hxx:173
Abstract base-class for different XML-types.
Definition: xmlprhdl.hxx:35
sal_Int32 nLength
Definition: xmltoken.cxx:36
void exportAudio(const Reference< XAudio > &xAudio)
css::uno::Any const SvXMLExport & rExport
Definition: ImageStyle.hxx:38
aStr
AnyEventRef aEvent
#define XML_TYPE_COLOR
Definition: xmltypes.hxx:133