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