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