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