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 <tools/debug.hxx>
28 #include <tools/time.hxx>
29 #include "unointerfacetouniqueidentifiermapper.hxx"
30 #include <com/sun/star/lang/XServiceInfo.hpp>
31 #include <com/sun/star/lang/XInitialization.hpp>
32 #include <com/sun/star/animations/AnimationTransformType.hpp>
33 #include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
34 #include <com/sun/star/presentation/AnimationEffect.hpp>
35 #include <com/sun/star/presentation/AnimationSpeed.hpp>
36 #include <com/sun/star/animations/AnimationNodeType.hpp>
37 #include <com/sun/star/animations/XIterateContainer.hpp>
38 #include <com/sun/star/animations/XAnimateMotion.hpp>
39 #include <com/sun/star/animations/XAnimateColor.hpp>
40 #include <com/sun/star/animations/XAnimateTransform.hpp>
41 #include <com/sun/star/animations/XTransitionFilter.hpp>
42 #include <com/sun/star/animations/XCommand.hpp>
43 #include <com/sun/star/animations/XAudio.hpp>
44 #include <com/sun/star/animations/ValuePair.hpp>
45 #include <com/sun/star/animations/AnimationColorSpace.hpp>
46 #include <com/sun/star/presentation/EffectPresetClass.hpp>
47 #include <com/sun/star/animations/Timing.hpp>
48 #include <com/sun/star/animations/Event.hpp>
49 #include <com/sun/star/beans/XPropertySet.hpp>
50 #include <com/sun/star/xml/sax/XAttributeList.hpp>
51 #include <com/sun/star/text/XTextCursor.hpp>
52 #include <com/sun/star/text/XTextRangeCompare.hpp>
53 #include <com/sun/star/presentation/ParagraphTarget.hpp>
54 #include <com/sun/star/container/XEnumerationAccess.hpp>
55 #include <com/sun/star/beans/XPropertySet.hpp>
56 #include <com/sun/star/animations/EventTrigger.hpp>
57 #include <com/sun/star/presentation/EffectCommands.hpp>
58 #include <comphelper/processfactory.hxx>
59 #include <cppuhelper/implbase1.hxx>
60 
61 #include <list>
62 #include <xmloff/xmltypes.hxx>
63 #include "sdpropls.hxx"
64 #include <xmloff/xmltoken.hxx>
65 #include <xmloff/xmlimp.hxx>
66 #include "xmloff/xmlnmspe.hxx"
67 #include <xmloff/xmluconv.hxx>
68 #include <osl/mutex.hxx>
69 #include <xmloff/nmspmap.hxx>
70 #include "anim.hxx"
71 
72 #include "animations.hxx"
73 #include "animationimport.hxx"
74 
75 using ::rtl::OUString;
76 using ::rtl::OUStringBuffer;
77 
78 using namespace ::std;
79 using namespace ::cppu;
80 using namespace ::com::sun::star::beans;
81 using namespace ::com::sun::star::animations;
82 using namespace ::com::sun::star::presentation;
83 using namespace ::com::sun::star::drawing;
84 using namespace ::xmloff::token;
85 
86 using ::com::sun::star::xml::sax::XAttributeList;
87 using ::com::sun::star::uno::Any;
88 using ::com::sun::star::uno::makeAny;
89 using ::com::sun::star::uno::UNO_QUERY;
90 using ::com::sun::star::uno::UNO_QUERY_THROW;
91 using ::com::sun::star::uno::Reference;
92 using ::com::sun::star::uno::Sequence;
93 using ::com::sun::star::uno::RuntimeException;
94 using ::com::sun::star::uno::Exception;
95 using ::com::sun::star::uno::XInterface;
96 using ::com::sun::star::uno::Type;
97 using ::com::sun::star::beans::NamedValue;
98 using ::com::sun::star::text::XTextRange;
99 using ::com::sun::star::text::XTextCursor;
100 using ::com::sun::star::text::XTextRangeCompare;
101 using ::com::sun::star::container::XEnumerationAccess;
102 using ::com::sun::star::container::XEnumeration;
103 using ::com::sun::star::lang::XMultiServiceFactory;
104 using ::com::sun::star::lang::XInitialization;
105 
106 namespace xmloff
107 {
108 
109 ///////////////////////////////////////////////////////////////////////
110 
111 
112 
113 ///////////////////////////////////////////////////////////////////////
114 
115 
116 ///////////////////////////////////////////////////////////////////////
117 
118 class AnimationsImportHelperImpl
119 {
120 private:
121 	SvXMLImport& mrImport;
122 
123 	SvXMLTokenMap* mpAnimationNodeTokenMap;
124 	SvXMLTokenMap* mpAnimationNodeAttributeTokenMap;
125 
126 public:
127 	AnimationsImportHelperImpl( SvXMLImport& rImport );
128 	~AnimationsImportHelperImpl();
129 
130 	const SvXMLTokenMap& getAnimationNodeTokenMap();
131 	const SvXMLTokenMap& getAnimationNodeAttributeTokenMap();
132 
133 	Any convertValue( XMLTokenEnum eAttributeName, const OUString& rValue );
134 	Sequence< Any > convertValueSequence( XMLTokenEnum eAttributeName, const OUString& rValue );
135 
136 	Any convertTarget( const OUString& rValue );
137 	Any convertPath( const OUString& rValue );
138 	Any convertTiming( const OUString& rValue );
139 	Sequence< double > convertKeyTimes( const OUString& rValue );
140 	Sequence< TimeFilterPair > convertTimeFilter( const OUString& rValue );
141 
142 	bool convertAnimationValue( XMLTokenEnum eAttributeName, Any& rValue );
143 	const OUString mastrHSL;
144 };
145 
AnimationsImportHelperImpl(SvXMLImport & rImport)146 AnimationsImportHelperImpl::AnimationsImportHelperImpl( SvXMLImport& rImport )
147 :	mrImport( rImport ),
148 	mpAnimationNodeTokenMap( NULL ),
149 	mpAnimationNodeAttributeTokenMap( NULL ),
150 	mastrHSL( RTL_CONSTASCII_USTRINGPARAM( "hsl" ) )
151 {
152 }
153 
~AnimationsImportHelperImpl()154 AnimationsImportHelperImpl::~AnimationsImportHelperImpl()
155 {
156 	delete mpAnimationNodeTokenMap;
157 	delete mpAnimationNodeAttributeTokenMap;
158 }
159 
getAnimationNodeTokenMap()160 const SvXMLTokenMap& AnimationsImportHelperImpl::getAnimationNodeTokenMap()
161 {
162 	if( mpAnimationNodeTokenMap == NULL )
163 	{
164 		static __FAR_DATA SvXMLTokenMapEntry aAnimationNodeTokenMap[] =
165 		{
166 			{ XML_NAMESPACE_ANIMATION,	XML_PAR,				(sal_uInt16)AnimationNodeType::PAR },
167 			{ XML_NAMESPACE_ANIMATION,	XML_SEQ,				(sal_uInt16)AnimationNodeType::SEQ },
168 			{ XML_NAMESPACE_ANIMATION,	XML_ITERATE,			(sal_uInt16)AnimationNodeType::ITERATE },
169 			{ XML_NAMESPACE_ANIMATION,	XML_ANIMATE,			(sal_uInt16)AnimationNodeType::ANIMATE },
170 			{ XML_NAMESPACE_ANIMATION,	XML_SET,				(sal_uInt16)AnimationNodeType::SET },
171 			{ XML_NAMESPACE_ANIMATION,	XML_ANIMATEMOTION,		(sal_uInt16)AnimationNodeType::ANIMATEMOTION },
172 			{ XML_NAMESPACE_ANIMATION,	XML_ANIMATECOLOR,		(sal_uInt16)AnimationNodeType::ANIMATECOLOR },
173 			{ XML_NAMESPACE_ANIMATION,	XML_ANIMATETRANSFORM,	(sal_uInt16)AnimationNodeType::ANIMATETRANSFORM },
174 			{ XML_NAMESPACE_ANIMATION,	XML_TRANSITIONFILTER,	(sal_uInt16)AnimationNodeType::TRANSITIONFILTER	},
175 			{ XML_NAMESPACE_ANIMATION,	XML_AUDIO,				(sal_uInt16)AnimationNodeType::AUDIO },
176 			{ XML_NAMESPACE_ANIMATION,	XML_COMMAND,			(sal_uInt16)AnimationNodeType::COMMAND },
177 			XML_TOKEN_MAP_END
178 		};
179 
180 		mpAnimationNodeTokenMap = new SvXMLTokenMap( aAnimationNodeTokenMap );
181 	}
182 
183 	return *mpAnimationNodeTokenMap;
184 }
185 
186 enum AnimationNodeAttributes
187 {
188 	ANA_Begin,
189 	ANA_Dur,
190 	ANA_End,
191 	ANA_Fill,
192 	ANA_FillDefault,
193 	ANA_Restart,
194 	ANA_RestartDefault,
195 	ANA_Accelerate,
196 	ANA_Decelerate,
197 	ANA_AutoReverse,
198 	ANA_RepeatCount,
199 	ANA_RepeatDur,
200 	ANA_EndSync,
201 	ANA_Node_Type,
202 	ANA_Preset_ID,
203 	ANA_Preset_Sub_Type,
204 	ANA_Preset_Class,
205 	ANA_After_Effect,
206 	ANA_Target,
207 	ANA_XLink,
208 	ANA_MasterElement,
209 	ANA_SubItem,
210 	ANA_AttributeName,
211 	ANA_Values,
212 	ANA_From,
213 	ANA_By,
214 	ANA_To,
215 	ANA_KeyTimes,
216 	ANA_CalcMode,
217 	ANA_Accumulate,
218 	ANA_AdditiveMode,
219 	ANA_KeySplines,
220 	ANA_Path,
221 	ANA_ColorSpace,
222 	ANA_ColorDirection,
223 	ANA_TransformType,
224 	ANA_TransitionType,
225 	ANA_TransitionSubType,
226 	ANA_Mode,
227 	ANA_Direction,
228 	ANA_FadeColor,
229 	ANA_IterateType,
230 	ANA_IterateInterval,
231 	ANA_Formula,
232     ANA_ANIMID,
233     ANA_XMLID,
234 	ANA_Group_Id,
235 	ANA_Command,
236 	ANA_Volume
237 };
238 
getAnimationNodeAttributeTokenMap()239 const SvXMLTokenMap& AnimationsImportHelperImpl::getAnimationNodeAttributeTokenMap()
240 {
241 	if( mpAnimationNodeAttributeTokenMap == NULL )
242 	{
243 		static __FAR_DATA SvXMLTokenMapEntry aAnimationNodeAttributeTokenMap[] =
244 		{
245 			{ XML_NAMESPACE_SMIL, XML_BEGIN,					(sal_uInt16)ANA_Begin },
246 			{ XML_NAMESPACE_SMIL, XML_DUR,						(sal_uInt16)ANA_Dur },
247 			{ XML_NAMESPACE_SMIL, XML_END,						(sal_uInt16)ANA_End },
248 			{ XML_NAMESPACE_SMIL, XML_FILL,						(sal_uInt16)ANA_Fill },
249 			{ XML_NAMESPACE_SMIL, XML_FILLDEFAULT,				(sal_uInt16)ANA_FillDefault },
250 			{ XML_NAMESPACE_SMIL, XML_RESTART,					(sal_uInt16)ANA_Restart },
251 			{ XML_NAMESPACE_SMIL, XML_RESTARTDEFAULT,			(sal_uInt16)ANA_RestartDefault },
252 			{ XML_NAMESPACE_SMIL, XML_ACCELERATE,				(sal_uInt16)ANA_Accelerate },
253 			{ XML_NAMESPACE_SMIL, XML_DECELERATE,				(sal_uInt16)ANA_Decelerate },
254 			{ XML_NAMESPACE_SMIL, XML_AUTOREVERSE,				(sal_uInt16)ANA_AutoReverse },
255 			{ XML_NAMESPACE_SMIL, XML_REPEATCOUNT,				(sal_uInt16)ANA_RepeatCount },
256 			{ XML_NAMESPACE_SMIL, XML_REPEATDUR,				(sal_uInt16)ANA_RepeatDur },
257 			{ XML_NAMESPACE_SMIL, XML_ENDSYNC,					(sal_uInt16)ANA_EndSync },
258 			{ XML_NAMESPACE_PRESENTATION, XML_NODE_TYPE,		(sal_uInt16)ANA_Node_Type },
259 			{ XML_NAMESPACE_PRESENTATION, XML_PRESET_ID,		(sal_uInt16)ANA_Preset_ID },
260 			{ XML_NAMESPACE_PRESENTATION, XML_PRESET_SUB_TYPE,	(sal_uInt16)ANA_Preset_Sub_Type },
261 			{ XML_NAMESPACE_PRESENTATION, XML_PRESET_CLASS,		(sal_uInt16)ANA_Preset_Class },
262 			{ XML_NAMESPACE_PRESENTATION, XML_AFTER_EFFECT,		(sal_uInt16)ANA_After_Effect },
263 			{ XML_NAMESPACE_SMIL, XML_TARGETELEMENT,			(sal_uInt16)ANA_Target },
264 			{ XML_NAMESPACE_XLINK, XML_HREF,					(sal_uInt16)ANA_XLink },
265 			{ XML_NAMESPACE_PRESENTATION, XML_MASTER_ELEMENT,	(sal_uInt16)ANA_MasterElement },
266 			{ XML_NAMESPACE_ANIMATION, XML_SUB_ITEM,			(sal_uInt16)ANA_SubItem },
267 			{ XML_NAMESPACE_SMIL, XML_ATTRIBUTENAME,			(sal_uInt16)ANA_AttributeName },
268 			{ XML_NAMESPACE_SMIL, XML_VALUES,					(sal_uInt16)ANA_Values },
269 			{ XML_NAMESPACE_SMIL, XML_FROM,						(sal_uInt16)ANA_From },
270 			{ XML_NAMESPACE_SMIL, XML_BY,						(sal_uInt16)ANA_By },
271 			{ XML_NAMESPACE_SMIL, XML_TO,						(sal_uInt16)ANA_To },
272 			{ XML_NAMESPACE_SMIL, XML_KEYTIMES,					(sal_uInt16)ANA_KeyTimes },
273 			{ XML_NAMESPACE_SMIL, XML_CALCMODE,					(sal_uInt16)ANA_CalcMode },
274 			{ XML_NAMESPACE_SMIL, XML_ACCUMULATE,				(sal_uInt16)ANA_Accumulate },
275 			{ XML_NAMESPACE_PRESENTATION, XML_ADDITIVE,			(sal_uInt16)ANA_AdditiveMode },
276 			{ XML_NAMESPACE_SMIL, XML_ADDITIVE,					(sal_uInt16)ANA_AdditiveMode },
277 			{ XML_NAMESPACE_SMIL, XML_KEYSPLINES,				(sal_uInt16)ANA_KeySplines },
278 			{ XML_NAMESPACE_SVG, XML_PATH,						(sal_uInt16)ANA_Path },
279 			{ XML_NAMESPACE_ANIMATION, XML_COLOR_INTERPOLATION,	(sal_uInt16)ANA_ColorSpace },
280 			{ XML_NAMESPACE_ANIMATION, XML_COLOR_INTERPOLATION_DIRECTION,		(sal_uInt16)ANA_ColorDirection },
281 			{ XML_NAMESPACE_SVG, XML_TYPE,						(sal_uInt16)ANA_TransformType },
282 			{ XML_NAMESPACE_SMIL, XML_TYPE,						(sal_uInt16)ANA_TransitionType },
283 			{ XML_NAMESPACE_SMIL, XML_SUBTYPE,					(sal_uInt16)ANA_TransitionSubType },
284 			{ XML_NAMESPACE_SMIL, XML_MODE,						(sal_uInt16)ANA_Mode },
285 			{ XML_NAMESPACE_SMIL, XML_DIRECTION,				(sal_uInt16)ANA_Direction },
286 			{ XML_NAMESPACE_SMIL, XML_FADECOLOR,				(sal_uInt16)ANA_FadeColor },
287 			{ XML_NAMESPACE_ANIMATION, XML_ITERATE_TYPE,		(sal_uInt16)ANA_IterateType },
288 			{ XML_NAMESPACE_ANIMATION, XML_ITERATE_INTERVAL,	(sal_uInt16)ANA_IterateInterval },
289 			{ XML_NAMESPACE_ANIMATION, XML_FORMULA,				(sal_uInt16)ANA_Formula },
290             { XML_NAMESPACE_ANIMATION, XML_ID,                  (sal_uInt16)ANA_ANIMID },
291             { XML_NAMESPACE_XML, XML_ID,                        (sal_uInt16)ANA_XMLID },
292 			{ XML_NAMESPACE_PRESENTATION, XML_GROUP_ID,			(sal_uInt16)ANA_Group_Id },
293 			{ XML_NAMESPACE_ANIMATION, XML_AUDIO_LEVEL,			(sal_uInt16)ANA_Volume },
294 			{ XML_NAMESPACE_ANIMATION, XML_COMMAND,				(sal_uInt16)ANA_Command },
295 
296 			XML_TOKEN_MAP_END
297 		};
298 
299 		mpAnimationNodeAttributeTokenMap = new SvXMLTokenMap( aAnimationNodeAttributeTokenMap );
300 	}
301 
302 	return *mpAnimationNodeAttributeTokenMap;
303 }
304 
isDouble(const OUString & rValue)305 static bool isDouble( const OUString& rValue )
306 {
307 	sal_Int32 nLength = rValue.getLength();
308 	const sal_Unicode * pStr = rValue.getStr();
309 	while( nLength )
310 	{
311 		if( (*pStr >= '0' && *pStr <= '9') || *pStr == '-' || *pStr == '.' || *pStr == '+' || *pStr == 'e' || *pStr == 'E' )
312 		{
313 			pStr++;
314 			nLength--;
315 		}
316 		else
317 		{
318 			return false;
319 		}
320 	}
321 
322 	return true;
323 }
324 
isTime(const OUString & rValue)325 static bool isTime( const OUString& rValue )
326 {
327 	sal_Int32 nLength = rValue.getLength();
328 	const sal_Unicode * pStr;
329 	for( pStr = rValue.getStr(); nLength; pStr++, nLength-- )
330 	{
331 		if( !( (*pStr >= '0' && *pStr <= '9') || *pStr == '-' || *pStr == '.' || *pStr == '+' || *pStr == 'e' || *pStr == 'E' ) )
332 			break;
333 	}
334 
335 	// return true if this is a double (if someone forgot the 's' we silently ignore it)
336 	// or if its a double that ends with a 's' or 'S'
337 	return (nLength == 0) || ((*pStr == 's' || *pStr == 'S') && (nLength == 1));
338 }
339 
count_codes(const OUString & rString,sal_Unicode nCode)340 static sal_Int32 count_codes( const OUString& rString, sal_Unicode nCode )
341 {
342 	sal_Int32 nCount = 0;
343 	sal_Int32 fromIndex = 0;
344 
345 	while(true)
346 	{
347 		fromIndex = rString.indexOf( nCode, fromIndex );
348 		if( fromIndex == -1 )
349 			break;
350 
351 		fromIndex++;
352 		nCount++;
353 	}
354 
355 	return nCount;
356 }
357 
convertTarget(const OUString & rValue)358 Any AnimationsImportHelperImpl::convertTarget( const OUString& rValue )
359 {
360 	try
361 	{
362 		Reference< XInterface > xRef( mrImport.getInterfaceToIdentifierMapper().getReference( rValue ) );
363 
364 		Reference< XShape > _xShape( xRef, UNO_QUERY );
365 		if( _xShape.is() )
366 			return makeAny( _xShape );
367 
368 		Reference< XTextCursor > xTextCursor( xRef, UNO_QUERY );
369 		if( xTextCursor.is() )
370 		{
371 			Reference< XTextRange > xStart( xTextCursor->getStart() ), xRange;
372 			Reference< XShape > xShape( xTextCursor->getText(), UNO_QUERY_THROW );
373 			Reference< XTextRangeCompare > xTextRangeCompare( xShape, UNO_QUERY_THROW );
374 
375 			Reference< XEnumerationAccess > xParaEnumAccess( xShape, UNO_QUERY_THROW );
376 			Reference< XEnumeration > xEnumeration( xParaEnumAccess->createEnumeration(), UNO_QUERY_THROW );
377 			sal_Int16 nParagraph = 0;
378 
379 			while( xEnumeration->hasMoreElements() )
380 			{
381 				xEnumeration->nextElement() >>= xRange;
382 
383 				// break if start of selection is prior to end of current paragraph
384 				if( xRange.is() && (xTextRangeCompare->compareRegionEnds( xStart, xRange ) >= 0 ) )
385 				{
386 					return makeAny( ParagraphTarget( xShape, nParagraph ) );
387 				}
388 
389 				nParagraph++;
390 			}
391 		}
392 	}
393 	catch( RuntimeException& )
394 	{
395 		DBG_ERROR( "xmloff::AnimationsImportImpl::convertTarget(), RuntimeException catched!" );
396 	}
397 
398 	Any aAny;
399 	return aAny;
400 }
401 
convertValue(XMLTokenEnum eAttributeName,const OUString & rValue)402 Any AnimationsImportHelperImpl::convertValue( XMLTokenEnum eAttributeName, const OUString& rValue )
403 {
404 	sal_Int32 nCommaPos = -1, nPos;
405 	sal_Int32 nOpenBrakets = 0;
406 	for( nPos = 0; (nPos < rValue.getLength()) && (nCommaPos == -1); nPos++ )
407 	{
408 		switch( rValue[nPos] )
409 		{
410 		case ',':
411 			if( nOpenBrakets == 0 )
412 				nCommaPos = nPos;
413 			break;
414 		case '(':
415 		case '[':
416 		case '{':
417 			nOpenBrakets++;
418 			break;
419 		case ')':
420 		case ']':
421 		case '}':
422 			nOpenBrakets--;
423 			break;
424 		}
425 	}
426 
427 	if( nCommaPos >= 0 )
428 	{
429 		ValuePair aPair;
430 		aPair.First = convertValue( eAttributeName, rValue.copy( 0, nCommaPos ) );
431 		aPair.Second = convertValue( eAttributeName, rValue.copy( nCommaPos+1, rValue.getLength() - nCommaPos - 1 ) );
432 		return makeAny( aPair );
433 	}
434 	else
435 	{
436 		Any aAny;
437 		sal_Int32 nType = XML_TYPE_STRING;
438 
439 		if( rValue.getLength() ) switch( eAttributeName )
440 		{
441 		case XML_X:
442 		case XML_Y:
443 		case XML_WIDTH:
444 		case XML_HEIGHT:
445 		case XML_TRANSLATE:
446 		{
447 			return makeAny( rValue );
448 		}
449 
450 		case XML_SCALE:
451 		case XML_SKEWY:
452 		case XML_SKEWX:
453 		case XML_OPACITY:
454 		case XML_ROTATE:			nType = XML_TYPE_DOUBLE;					break;
455 		case XML_TEXT_ROTATION_ANGLE:nType = XML_TYPE_TEXT_ROTATION_ANGLE;		break;
456 		case XML_FILL_COLOR:
457 		case XML_STROKE_COLOR:
458 		case XML_DIM:
459 		case XML_COLOR:				nType = XML_TYPE_COLOR;						break;
460 		case XML_FILL:				nType = XML_SD_TYPE_FILLSTYLE;				break;
461 		case XML_STROKE:			nType = XML_SD_TYPE_STROKE;					break;
462 		case XML_FONT_WEIGHT:		nType = XML_TYPE_TEXT_WEIGHT;				break;
463 		case XML_FONT_STYLE:		nType = XML_TYPE_TEXT_POSTURE;				break;
464 		case XML_TEXT_UNDERLINE:	nType = XML_TYPE_TEXT_UNDERLINE_STYLE;		break;
465 		case XML_FONT_SIZE:			nType = XML_TYPE_DOUBLE_PERCENT;			break;
466 		case XML_VISIBILITY:		nType = XML_SD_TYPE_PRESPAGE_VISIBILITY;	break;
467 
468 		default:
469 			if( rValue.getLength() )
470 				aAny <<= rValue;
471 			return aAny;
472 		}
473 
474 		const XMLPropertyHandler* pHandler = mrImport.GetShapeImport()->GetSdPropHdlFactory()->GetPropertyHandler( nType );
475 		if( pHandler )
476 			pHandler->importXML( rValue, aAny, mrImport.GetMM100UnitConverter() );
477 
478 		return aAny;
479 
480 /*
481 		if( rValue.getLength() == 0 )
482 		{
483 			Any aAny;
484 			return aAny;
485 		}
486 		else if( rValue.indexOf( '#' ) == 0 )
487 		{
488 			// color
489 			Color aColor;
490 			SvXMLUnitConverter::convertColor( aColor, rValue );
491 
492 			return makeAny( static_cast< sal_Int32 >( aColor.GetRGBColor() ) );
493 		}
494 		else if( rValue.indexOf( '$' ) != -1 )
495 		{
496 			// formula
497 			return makeAny( rValue );
498 		}
499 		else
500 		{
501 			if( isDouble( rValue ) )
502 			{
503 				return makeAny( rValue.toDouble() );
504 			}
505 			else
506 			{
507 				return makeAny( rValue );
508 			}
509 		}
510 */
511 	}
512 }
513 
convertValueSequence(XMLTokenEnum eAttributeName,const OUString & rValue)514 Sequence< Any > AnimationsImportHelperImpl::convertValueSequence( XMLTokenEnum eAttributeName, const OUString& rValue )
515 {
516 	Sequence< Any > aValues;
517 
518 	// do we have any value at all?
519 	if( rValue.getLength() )
520 	{
521 		sal_Int32 nElements = count_codes( rValue, (sal_Unicode)';') + 1; // a non empty string has at least one value
522 
523 		// prepare the sequence
524 		aValues.realloc( nElements );
525 
526 		// fill the sequence
527 		Any* pValues = aValues.getArray();
528 		sal_Int32 nIndex, nElement;
529 		for( nIndex = 0, nElement = 0; nElements && (nIndex >= 0); nElements-- )
530 		{
531 			*pValues++ = convertValue( eAttributeName, rValue.getToken( 0, ';', nIndex ) );
532 		}
533 	}
534 
535 	return aValues;
536 }
537 
convertTiming(const OUString & rValue)538 Any AnimationsImportHelperImpl::convertTiming( const OUString& rValue )
539 {
540 	Any aAny;
541 
542 	// do we have any value at all?
543 	if( rValue.getLength() )
544 	{
545 		// count the values
546 		sal_Int32 nElements = count_codes( rValue, (sal_Unicode)';' ) + 1; // a non empty string has at least one value
547 
548 		if( nElements == 1 )
549 		{
550 			if( IsXMLToken( rValue, XML_MEDIA ) )
551 			{
552 				aAny <<= Timing_MEDIA;
553 			}
554 			else if( IsXMLToken( rValue, XML_INDEFINITE ) )
555 			{
556 				aAny <<= Timing_INDEFINITE;
557 			}
558 			else if( isTime( rValue ) )
559 			{
560 				aAny <<= rValue.toDouble();
561 			}
562 			else
563 			{
564 				Event aEvent;
565 				aEvent.Repeat = 0;
566 				aEvent.Trigger = 0;
567 
568 				OUString aEventTrigger;
569 
570 				sal_Int32 nPos = rValue.indexOf( (sal_Unicode)'+' );
571 				if( nPos == -1 )
572 				{
573 					aEventTrigger = rValue;
574 				}
575 				else
576 				{
577 					aEventTrigger = rValue.copy( 0, nPos );
578 
579 					// convert offset
580 					aEvent.Offset <<= convertTiming( rValue.copy( nPos + 1 ) );
581 				}
582 
583 				nPos = aEventTrigger.indexOf( (sal_Unicode)'.' );
584 				if( nPos != -1 )
585 				{
586 					aEvent.Source <<= mrImport.getInterfaceToIdentifierMapper().getReference( aEventTrigger.copy( 0, nPos ) );
587 					aEventTrigger = aEventTrigger.copy( nPos + 1 );
588 				}
589 
590 				sal_uInt16 nEnum;
591 				if( SvXMLUnitConverter::convertEnum( nEnum, aEventTrigger, getAnimationsEnumMap(Animations_EnumMap_EventTrigger) ) )
592 				{
593 					aEvent.Trigger = (sal_Int16)nEnum;
594 				}
595 				else
596 				{
597 					DBG_ERROR("AnimationsImportHelperImpl::convertTiming(), unknown event trigger!");
598 				}
599 
600 				aAny <<= aEvent;
601 			}
602 		}
603 		else
604 		{
605 			// fill the sequence
606 			Sequence< Any > aValues( nElements );
607 			Any* pValues = aValues.getArray();
608 			sal_Int32 nIndex = 0;
609 			while( (nElements--) && (nIndex >= 0) )
610 				*pValues++ = convertTiming( rValue.getToken( 0, ';', nIndex ) );
611 
612 			aAny <<= aValues;
613 		}
614 	}
615 	return aAny;
616 }
617 
convertKeyTimes(const OUString & rValue)618 Sequence< double > AnimationsImportHelperImpl::convertKeyTimes( const OUString& rValue )
619 {
620 	sal_Int32 nElements = 0;
621 
622 	if( rValue.getLength() )
623 		nElements = count_codes( rValue, (sal_Unicode)';' ) + 1; // a non empty string has at least one value
624 
625 	Sequence< double > aKeyTimes( nElements );
626 
627 	if( nElements )
628 	{
629 		double* pValues = aKeyTimes.getArray();
630 		sal_Int32 nIndex = 0;
631 		while( (nElements--) && (nIndex >= 0) )
632 			*pValues++ = rValue.getToken( 0, ';', nIndex ).toDouble();
633 	}
634 
635 	return aKeyTimes;
636 }
637 
convertTimeFilter(const OUString & rValue)638 Sequence< TimeFilterPair > AnimationsImportHelperImpl::convertTimeFilter( const OUString& rValue )
639 {
640 	sal_Int32 nElements = 0;
641 
642 	if( rValue.getLength() )
643 		nElements = count_codes( rValue, (sal_Unicode)';' ) + 1; // a non empty string has at least one value
644 
645 	Sequence< TimeFilterPair > aTimeFilter( nElements );
646 
647 	if( nElements )
648 	{
649 		TimeFilterPair* pValues = aTimeFilter.getArray();
650 		sal_Int32 nIndex = 0;
651 		while( (nElements--) && (nIndex >= 0) )
652 		{
653 			const OUString aToken( rValue.getToken( 0, ';', nIndex ) );
654 
655 			sal_Int32 nPos = aToken.indexOf( ',' );
656 			if( nPos >= 0 )
657 			{
658 				pValues->Time = aToken.copy( 0, nPos ).toDouble();
659 				pValues->Progress = aToken.copy( nPos+1, aToken.getLength() - nPos - 1 ).toDouble();
660 			}
661 			pValues++;
662 		}
663 	}
664 
665 	return aTimeFilter;
666 }
667 
convertPath(const OUString & rValue)668 Any AnimationsImportHelperImpl::convertPath( const OUString& rValue )
669 {
670 	return makeAny( rValue );
671 }
672 
673 ///////////////////////////////////////////////////////////////////////
674 
675 TYPEINIT1( AnimationNodeContext, SvXMLImportContext );
676 
AnimationNodeContext(const Reference<XAnimationNode> & xParentNode,SvXMLImport & rImport,sal_uInt16 nPrfx,const rtl::OUString & rLocalName,const com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList> & xAttrList,AnimationsImportHelperImpl * pHelper)677 AnimationNodeContext::AnimationNodeContext(
678 		const Reference< XAnimationNode >& xParentNode,
679 		SvXMLImport& rImport, sal_uInt16 nPrfx,	const rtl::OUString& rLocalName,
680 		const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
681 		AnimationsImportHelperImpl* pHelper /* = NULL */ )
682 :	SvXMLImportContext(rImport, nPrfx, rLocalName),
683 	mpHelper( pHelper ),
684 	mbRootContext( pHelper == NULL )
685 {
686 	try
687 	{
688 		if( mbRootContext )
689 		{
690 			mpHelper = new AnimationsImportHelperImpl( rImport );
691 			mxNode = xParentNode;
692 		}
693 		else
694 		{
695 			Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
696 
697 			sal_Int16 nPresetClass = EffectPresetClass::CUSTOM;
698 
699 			const sal_Char* pServiceName = 0;
700 
701 			sal_Int16 nNodeType = (sal_Int16)mpHelper->getAnimationNodeTokenMap().Get( nPrfx, rLocalName );
702 			switch( nNodeType )
703 			{
704 			case AnimationNodeType::SEQ:				pServiceName = "com.sun.star.animations.SequenceTimeContainer"; break;
705 			case AnimationNodeType::ITERATE:			pServiceName = "com.sun.star.animations.IterateContainer"; break;
706 			case AnimationNodeType::ANIMATE:			pServiceName = "com.sun.star.animations.Animate"; break;
707 			case AnimationNodeType::SET:				pServiceName = "com.sun.star.animations.AnimateSet"; break;
708 			case AnimationNodeType::ANIMATEMOTION:		pServiceName = "com.sun.star.animations.AnimateMotion"; break;
709 			case AnimationNodeType::ANIMATECOLOR:		pServiceName = "com.sun.star.animations.AnimateColor"; break;
710 			case AnimationNodeType::ANIMATETRANSFORM:	pServiceName = "com.sun.star.animations.AnimateTransform"; break;
711 			case AnimationNodeType::TRANSITIONFILTER:	pServiceName = "com.sun.star.animations.TransitionFilter"; break;
712 			case AnimationNodeType::AUDIO:				pServiceName = "com.sun.star.animations.Audio"; break;
713 			case AnimationNodeType::COMMAND:			pServiceName = "com.sun.star.animations.Command"; break;
714 			case AnimationNodeType::PAR:
715 				{
716 					const sal_Int16 nCount = xAttrList.is() ? xAttrList->getLength() : 0;
717 					sal_Int16 nAttribute;
718 					for( nAttribute = 0; nAttribute < nCount; nAttribute++ )
719 					{
720 						OUString aLocalName;
721 						sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( nAttribute ), &aLocalName );
722 						if( (nPrefix == XML_NAMESPACE_PRESENTATION) && IsXMLToken( aLocalName, XML_PRESET_ID ) )
723 						{
724 							const OUString& rValue = xAttrList->getValueByIndex( nAttribute );
725 							if( rValue.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ooo-entrance-random" ) ) )
726 							{
727 								nPresetClass = EffectPresetClass::ENTRANCE;
728 							}
729 							else if( rValue.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ooo-exit-random" ) ) )
730 							{
731 								nPresetClass = EffectPresetClass::EXIT;
732 							}
733 
734 							if( nPresetClass != EffectPresetClass::CUSTOM )
735 							{
736 								pServiceName = "com.sun.star.comp.sd.RandomAnimationNode";
737 								break;
738 							}
739 						}
740 					}
741 					if( !pServiceName )
742 						pServiceName = "com.sun.star.animations.ParallelTimeContainer";
743 				}
744 				break;
745 			default:
746 				pServiceName = 0;
747 			}
748 
749 			if( pServiceName && xFactory.is() )
750 			{
751 				mxNode = Reference< XAnimationNode >( xFactory->createInstance(
752 					OUString::createFromAscii(pServiceName) ), UNO_QUERY_THROW );
753 
754 				if( nPresetClass != EffectPresetClass::CUSTOM )
755 				{
756 					Reference< XInitialization > xInit( mxNode, UNO_QUERY_THROW );
757 					const Any aAny( makeAny( nPresetClass ) );
758 					Sequence< Any > aArgs( &aAny, 1 ) ;
759 					xInit->initialize( aArgs );
760 				}
761 
762 				init_node( xAttrList );
763 
764 				Reference< XTimeContainer > xParentContainer( xParentNode, UNO_QUERY_THROW );
765 				xParentContainer->appendChild( mxNode );
766 			}
767 		}
768 	}
769 	catch( RuntimeException& )
770 	{
771 		DBG_ERROR( "xmloff::AnimationsImportImpl::AnimationsImportImpl(), RuntimeException catched!" );
772 	}
773 }
774 
~AnimationNodeContext()775 AnimationNodeContext::~AnimationNodeContext()
776 {
777 	if( mbRootContext )
778 		delete mpHelper;
779 }
780 
StartElement(const::com::sun::star::uno::Reference<::com::sun::star::xml::sax::XAttributeList> &)781 void AnimationNodeContext::StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& )
782 {
783 	// code of StartElement is moved to init_node that is now called
784 	// in c'tor before appending this node to its parent.
785 	// This is needed for random nodes that need the correct target
786 	// set when child nodes are appended.
787 }
788 
init_node(const::com::sun::star::uno::Reference<::com::sun::star::xml::sax::XAttributeList> & xAttrList)789 void AnimationNodeContext::init_node(  const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList )
790 {
791 	if( mxNode.is() ) try
792 	{
793 		const sal_Int16 nNodeType = mxNode->getType();
794 
795 		// query for optional interfaces that are often used later
796 		Reference< XAnimate > xAnimate( mxNode, UNO_QUERY );
797 		Reference< XCommand > xCommand( mxNode, UNO_QUERY );
798 		Reference< XTransitionFilter > xTransitionFilter( mxNode, UNO_QUERY );
799 		Reference< XIterateContainer > xIter( mxNode, UNO_QUERY );
800 
801 		std::list< NamedValue > aUserData;
802 		XMLTokenEnum meAttributeName = XML_TOKEN_INVALID;
803 		OUString aFrom, aBy, aTo, aValues;
804         bool bHaveXmlId( false );
805         OUString sXmlId;
806 
807 		const sal_Int16 nCount = xAttrList.is() ? xAttrList->getLength() : 0;
808 		sal_uInt16 nEnum;
809 		sal_Int16 nAttribute;
810 		for( nAttribute = 0; nAttribute < nCount; nAttribute++ )
811 		{
812 			const OUString& rAttrName = xAttrList->getNameByIndex( nAttribute );
813 			const OUString& rValue = xAttrList->getValueByIndex( nAttribute );
814 
815 			OUString aLocalName;
816 			sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName );
817 			switch( mpHelper->getAnimationNodeAttributeTokenMap().Get( nPrefix, aLocalName ) )
818 			{
819 			case ANA_Begin:
820 			{
821 				mxNode->setBegin( mpHelper->convertTiming( rValue ) );
822 			}
823 			break;
824 			case ANA_Dur:
825 			{
826 				mxNode->setDuration( mpHelper->convertTiming( rValue ) );
827 			}
828 			break;
829 			case ANA_End:
830 			{
831 				mxNode->setEnd( mpHelper->convertTiming( rValue ) );
832 			}
833 			break;
834 			case ANA_Fill:
835 			{
836 				if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_Fill) ) )
837 					mxNode->setFill( (sal_Int16)nEnum );
838 			}
839 			break;
840 			case ANA_FillDefault:
841 			{
842 				if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_FillDefault) ) )
843 					mxNode->setFillDefault( (sal_Int16)nEnum );
844 			}
845 			break;
846 			case ANA_Restart:
847 			{
848 				if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_Restart) ) )
849 					mxNode->setRestart( (sal_Int16)nEnum );
850 			}
851 			break;
852 			case ANA_RestartDefault:
853 			{
854 				if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_RestartDefault) ) )
855 					mxNode->setRestartDefault( (sal_Int16)nEnum );
856 			}
857 			break;
858 			case ANA_Accelerate:
859 			{
860 				if( isDouble( rValue ) )
861 					mxNode->setAcceleration( rValue.toDouble() );
862 			}
863 			break;
864 			case ANA_Decelerate:
865 			{
866 				if( isDouble( rValue ) )
867 					mxNode->setDecelerate( rValue.toDouble() );
868 			}
869 			break;
870 			case ANA_AutoReverse:
871 			{
872 				sal_Bool bTemp;
873 				if( SvXMLUnitConverter::convertBool( bTemp, rValue ) )
874 					mxNode->setAutoReverse( bTemp  );
875 			}
876 			break;
877 			case ANA_RepeatCount:
878 			{
879 				mxNode->setRepeatCount( mpHelper->convertTiming( rValue ) );
880 			}
881 			break;
882 			case ANA_RepeatDur:
883 			{
884 				mxNode->setRepeatDuration( mpHelper->convertTiming( rValue ) );
885 			}
886 			break;
887 			case ANA_EndSync:
888 			{
889 				if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_Endsync) ) )
890 					mxNode->setEndSync( makeAny( (sal_Int16)nEnum ) );
891 			}
892 			break;
893 			case ANA_Node_Type:
894 			{
895 				if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_EffectNodeType) ) )
896 					aUserData.push_back( NamedValue( GetXMLToken( XML_NODE_TYPE ), makeAny( (sal_Int16)nEnum ) ) );
897 			}
898 			break;
899 			case ANA_Preset_ID:
900 			{
901 				aUserData.push_back( NamedValue( GetXMLToken( XML_PRESET_ID ), makeAny( rValue ) ) );
902 			}
903 			break;
904 			case ANA_Preset_Sub_Type:
905 			{
906 				aUserData.push_back( NamedValue( GetXMLToken( XML_PRESET_SUB_TYPE ), makeAny( rValue ) ) );
907 			}
908 			break;
909 			case ANA_Preset_Class:
910 			{
911 				if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_EffectPresetClass) ) )
912 					aUserData.push_back( NamedValue( GetXMLToken( XML_PRESET_CLASS ), makeAny( (sal_Int16)nEnum ) ) );
913 			}
914 			break;
915 			case ANA_After_Effect:
916 			{
917 				sal_Bool bTemp;
918 				if( SvXMLUnitConverter::convertBool( bTemp, rValue ) )
919 					aUserData.push_back( NamedValue( GetXMLToken( XML_AFTER_EFFECT ), makeAny( bTemp ) ) );
920 			}
921 			break;
922 			case ANA_XLink:
923 			{
924 				if( nNodeType == AnimationNodeType::AUDIO )
925 				{
926 					Reference< XAudio > xAudio( mxNode, UNO_QUERY_THROW );
927 					xAudio->setSource( makeAny( GetImport().GetAbsoluteReference( rValue ) ) );
928 					break;
929 				}
930 
931 			}
932 			// fall through intented!
933 			case ANA_Target:
934 			{
935 				{
936 					Any aTarget( mpHelper->convertTarget( rValue ) );
937 
938 					if( xAnimate.is() )
939 					{
940 						xAnimate->setTarget( aTarget );
941 					}
942 					else if( xIter.is() )
943 					{
944 						xIter->setTarget( aTarget );
945 					}
946                     else if( xCommand.is() )
947 					{
948 						xCommand->setTarget( aTarget );
949 					}
950 				}
951 			}
952 			break;
953 
954 			case ANA_Volume:
955 			{
956 				if( nNodeType == AnimationNodeType::AUDIO )
957 				{
958 					if( isDouble( rValue ) )
959 					{
960 						Reference< XAudio > xAudio( mxNode, UNO_QUERY_THROW );
961 						xAudio->setVolume( rValue.toDouble() );
962 					}
963 				}
964 			}
965 			break;
966 
967 			case ANA_MasterElement:
968 			{
969 				Reference< XAnimationNode > xMaster( GetImport().getInterfaceToIdentifierMapper().getReference( rValue ), UNO_QUERY );
970 				aUserData.push_back( NamedValue( GetXMLToken( XML_MASTER_ELEMENT ), makeAny( xMaster ) ) );
971 			}
972 			break;
973 
974 			case ANA_SubItem:
975 			{
976 				if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_SubItem) ) )
977 				{
978 					if( xAnimate.is() )
979 					{
980 						xAnimate->setSubItem( (sal_Int16)nEnum );
981 					}
982 					else if( xIter.is() )
983 					{
984 						xIter->setSubItem( (sal_Int16)nEnum );
985 					}
986 				}
987 			}
988 			break;
989 
990 			case ANA_AttributeName:
991 			{
992 				if( xAnimate.is() )
993 				{
994 					OUString aName( rValue );
995 
996 					ImplAttributeNameConversion* p = getAnimationAttributeNamesConversionList();
997 					while( p->mpAPIName )
998 					{
999 						if( IsXMLToken( aName, p->meXMLToken ) )
1000 						{
1001 							aName = OUString::createFromAscii( p->mpAPIName );
1002 							meAttributeName = p->meXMLToken;
1003 							break;
1004 						}
1005 
1006 						p++;
1007 					}
1008 
1009 					xAnimate->setAttributeName( aName );
1010 				}
1011 			}
1012 			break;
1013 
1014 			case ANA_Values:
1015 			{
1016 				aValues = rValue;
1017 			}
1018 			break;
1019 
1020 			case ANA_From:
1021 			{
1022 				aFrom = rValue;
1023 			}
1024 			break;
1025 
1026 			case ANA_By:
1027 			{
1028 				aBy = rValue;
1029 			}
1030 			break;
1031 
1032 			case ANA_To:
1033 			{
1034 				aTo = rValue;
1035 			}
1036 			break;
1037 
1038 			case ANA_KeyTimes:
1039 			{
1040 				if( xAnimate.is() )
1041 					xAnimate->setKeyTimes( mpHelper->convertKeyTimes( rValue ) );
1042 			}
1043 			break;
1044 
1045 			case ANA_Formula:
1046 			{
1047 				if( xAnimate.is() )
1048 					xAnimate->setFormula( rValue );
1049 			}
1050 			break;
1051 
1052             case ANA_ANIMID:
1053             {
1054                 if (!bHaveXmlId) { sXmlId = rValue; }
1055             }
1056             break;
1057             case ANA_XMLID:
1058             {
1059                 sXmlId = rValue;
1060                 bHaveXmlId = true;
1061             }
1062             break;
1063 
1064 			case ANA_CalcMode:
1065 			{
1066 				if( xAnimate.is() )
1067 				{
1068 					if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_CalcMode) ) )
1069 						xAnimate->setCalcMode( (sal_Int16)nEnum );
1070 				}
1071 			}
1072 			break;
1073 
1074 			case ANA_Accumulate:
1075 			{
1076 				if( xAnimate.is() )
1077 					xAnimate->setAccumulate( IsXMLToken( rValue, XML_SUM ) );
1078 			}
1079 			break;
1080 
1081 			case ANA_AdditiveMode:
1082 			{
1083 				if( xAnimate.is() )
1084 				{
1085 					if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_AdditiveMode) ) )
1086 						xAnimate->setAdditive( (sal_Int16)nEnum );
1087 				}
1088 			}
1089 			break;
1090 
1091 			case ANA_KeySplines:
1092 			{
1093 				if( xAnimate.is() )
1094 					xAnimate->setTimeFilter( mpHelper->convertTimeFilter( rValue ) );
1095 			}
1096 			break;
1097 
1098 			case ANA_Path:
1099 			{
1100 				Reference< XAnimateMotion > xAnimateMotion( mxNode, UNO_QUERY );
1101 				if( xAnimateMotion.is() )
1102 					xAnimateMotion->setPath( mpHelper->convertPath( rValue ) );
1103 			}
1104 			break;
1105 
1106 			case ANA_ColorSpace:
1107 			{
1108 				Reference< XAnimateColor > xAnimateColor( mxNode, UNO_QUERY );
1109 				if( xAnimateColor.is() )
1110 					xAnimateColor->setColorInterpolation( IsXMLToken( rValue, XML_HSL ) ? AnimationColorSpace::HSL : AnimationColorSpace::RGB );
1111 			}
1112 			break;
1113 
1114 			case ANA_ColorDirection:
1115 			{
1116 				Reference< XAnimateColor > xAnimateColor( mxNode, UNO_QUERY );
1117 				if( xAnimateColor.is() )
1118 					xAnimateColor->setDirection( IsXMLToken( rValue, XML_CLOCKWISE ) );
1119 			}
1120 			break;
1121 
1122 			case ANA_TransformType:
1123 			{
1124 				Reference< XAnimateTransform > xTransform( mxNode, UNO_QUERY );
1125 				if( xTransform.is() )
1126 				{
1127 					if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_TransformType) ) )
1128 					{
1129 						xTransform->setTransformType( (sal_Int16)nEnum );
1130 						switch( nEnum )
1131 						{
1132 						case AnimationTransformType::SCALE: meAttributeName = XML_SCALE; break;
1133 						case AnimationTransformType::ROTATE: meAttributeName = XML_ROTATE; break;
1134 						case AnimationTransformType::SKEWX: meAttributeName = XML_SKEWX; break;
1135 						case AnimationTransformType::SKEWY: meAttributeName = XML_SKEWY; break;
1136 						//case AnimationTransformType::TRANSLATE:
1137 						default:
1138 							meAttributeName = XML_TRANSLATE; break;
1139 						}
1140 					}
1141 				}
1142 			}
1143 			break;
1144 
1145 			case ANA_TransitionType:
1146 			{
1147 				if( xTransitionFilter.is() )
1148 				{
1149 					if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_TransitionType) ) )
1150 						xTransitionFilter->setTransition( (sal_Int16)nEnum );
1151 				}
1152 			}
1153 			break;
1154 
1155 			case ANA_TransitionSubType:
1156 			{
1157 				if( xTransitionFilter.is() )
1158 				{
1159 					if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_TransitionSubType) ) )
1160 						xTransitionFilter->setSubtype( (sal_Int16)nEnum );
1161 				}
1162 			}
1163 			break;
1164 
1165 			case ANA_Mode:
1166 			{
1167 				if( xTransitionFilter.is() )
1168 					xTransitionFilter->setMode( IsXMLToken( rValue, XML_IN ) );
1169 			}
1170 			break;
1171 
1172 			case ANA_Direction:
1173 			{
1174 				if( xTransitionFilter.is() )
1175 					xTransitionFilter->setDirection( IsXMLToken( rValue, XML_FORWARD ) );
1176 			}
1177 			break;
1178 
1179 			case ANA_FadeColor:
1180 			{
1181 				if( xTransitionFilter.is() )
1182 				{
1183 					Color aColor;
1184 					SvXMLUnitConverter::convertColor( aColor, rValue );
1185 					xTransitionFilter->setFadeColor( static_cast< sal_Int32 >( aColor.GetRGBColor() ) );
1186 				}
1187 			}
1188 			break;
1189 
1190 			case ANA_IterateType:
1191 			{
1192 				if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_IterateType) ) )
1193 				{
1194 					if( xIter.is() )
1195 						xIter->setIterateType( (sal_Int16)nEnum );
1196 				}
1197 			}
1198 			break;
1199 
1200 			case ANA_IterateInterval:
1201 			{
1202 				if( xIter.is() )
1203 				{
1204 					double fInterval = 0.0;
1205 					if( rValue.matchAsciiL(RTL_CONSTASCII_STRINGPARAM("P")) )
1206 					{
1207 						::Time aTime;
1208 						sal_Int32 nSecondsFraction = 0;
1209 						if( SvXMLUnitConverter::convertTimeDuration( rValue, aTime, &nSecondsFraction ) )
1210 						{
1211 							fInterval = ((((aTime.GetHour() * 60) + aTime.GetMin()) * 60) + aTime.GetSec()) + (nSecondsFraction / 1000.0);
1212 						}
1213 					}
1214 					else
1215 					{
1216 						fInterval = rValue.toDouble();
1217 					}
1218 
1219 					xIter->setIterateInterval( fInterval );
1220 				}
1221 			}
1222 			break;
1223 
1224 			case ANA_Group_Id:
1225 			{
1226 				aUserData.push_back( NamedValue( aLocalName, makeAny( rValue.toInt32() ) ) );
1227 			}
1228 			break;
1229 
1230 			case ANA_Command:
1231 			{
1232 				if( xCommand.is() && nNodeType == AnimationNodeType::COMMAND )
1233 				{
1234 					if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_Command) ) )
1235 					{
1236 						xCommand->setCommand( (sal_Int16)nEnum );
1237 					}
1238 				}
1239 			}
1240 			break;
1241 
1242 			default:
1243 				// push all unknown attributes within the presentation namespace as user data
1244 				if( nPrefix == XML_NAMESPACE_PRESENTATION )
1245 				{
1246 					aUserData.push_back( NamedValue( aLocalName, makeAny( rValue ) ) );
1247 				}
1248 			}
1249 		}
1250 
1251         if (sXmlId.getLength())
1252         {
1253             Reference< XInterface > const xRef( mxNode, UNO_QUERY );
1254             GetImport().getInterfaceToIdentifierMapper().registerReference(
1255                 sXmlId, xRef );
1256         }
1257 
1258 		sal_Int32 nUserDataCount = aUserData.size();
1259 		if( nUserDataCount )
1260 		{
1261 			Sequence< NamedValue > aUnoUserData( nUserDataCount );
1262 			NamedValue* pData = aUnoUserData.getArray();
1263 			std::list< NamedValue >::iterator aIter( aUserData.begin() );
1264 			const std::list< NamedValue >::iterator aEnd( aUserData.end() );
1265 			while( aIter != aEnd )
1266 				*pData++ = (*aIter++);
1267 
1268 			mxNode->setUserData( aUnoUserData );
1269 		}
1270 
1271 		// convert values
1272 		if( xAnimate.is() )
1273 		{
1274 			if( aFrom.getLength() )
1275 				xAnimate->setFrom( mpHelper->convertValue( meAttributeName, aFrom ) );
1276 
1277 			if( aBy.getLength() )
1278 				xAnimate->setBy( mpHelper->convertValue( meAttributeName, aBy ) );
1279 
1280 			if( aTo.getLength() )
1281 				xAnimate->setTo( mpHelper->convertValue( meAttributeName, aTo ) );
1282 
1283 			if( aValues.getLength() )
1284 				xAnimate->setValues( mpHelper->convertValueSequence( meAttributeName, aValues ) );
1285 		}
1286 	}
1287 	catch( RuntimeException& )
1288 	{
1289 		DBG_ERROR( "xmloff::AnimationNodeContext::StartElement(), RuntimeException catched!" );
1290 	}
1291 }
1292 
CreateChildContext(sal_uInt16 nPrefix,const::rtl::OUString & rLocalName,const com::sun::star::uno::Reference<com::sun::star::xml::sax::XAttributeList> & xAttrList)1293 SvXMLImportContext * AnimationNodeContext::CreateChildContext( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName,
1294 		const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList )
1295 {
1296 	if( mxNode.is())
1297 		return new AnimationNodeContext( mxNode, GetImport(), nPrefix, rLocalName, xAttrList, mpHelper );
1298 	else
1299 		return new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
1300 }
1301 
1302 // --------------------------------------------------------------------
1303 
1304 class AnimationsImport: public SvXMLImport, public XAnimationNodeSupplier
1305 {
1306 public:
1307 	AnimationsImport( const Reference< XMultiServiceFactory > & rSMgr );
1308 	~AnimationsImport() throw ();
1309 
1310 	SvXMLImportContext* CreateContext(sal_uInt16 nPrefix, const OUString& rLocalName,	const Reference<XAttributeList>& xAttrList);
1311 
1312 	// XInterface
1313     virtual Any SAL_CALL queryInterface( const Type& aType ) throw (RuntimeException);
1314     virtual void SAL_CALL acquire() throw ();
1315     virtual void SAL_CALL release() throw ();
1316 
1317 	// XAnimationNodeSupplier
1318 	Reference< XAnimationNode > SAL_CALL getAnimationNode() throw (RuntimeException);
1319 
1320 	// XServiceInfo
1321     virtual OUString SAL_CALL getImplementationName() throw(RuntimeException);
1322     virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException);
1323     virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(RuntimeException);
1324 
1325 private:
1326 	Reference< XAnimationNode > mxRootNode;
1327 };
1328 
AnimationsImport(const Reference<XMultiServiceFactory> & rSMgr)1329 AnimationsImport::AnimationsImport( const Reference< XMultiServiceFactory > & rSMgr )
1330 : SvXMLImport( rSMgr, true )
1331 {
1332 	// add namespaces
1333 	GetNamespaceMap().Add(
1334 		GetXMLToken(XML_NP_PRESENTATION),
1335         GetXMLToken(XML_N_PRESENTATION),
1336 		XML_NAMESPACE_PRESENTATION);
1337 
1338 	GetNamespaceMap().Add(
1339 		GetXMLToken(XML_NP_SMIL),
1340         GetXMLToken(XML_N_SMIL),
1341 		XML_NAMESPACE_SMIL);
1342 
1343 	GetNamespaceMap().Add(
1344 		GetXMLToken(XML_NP_ANIMATION),
1345         GetXMLToken(XML_N_ANIMATION),
1346 		XML_NAMESPACE_ANIMATION);
1347 
1348 	mxRootNode = Reference< XAnimationNode >::query(rSMgr->createInstance(
1349 		OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.animations.SequenceTimeContainer"))));
1350 }
1351 
~AnimationsImport()1352 AnimationsImport::~AnimationsImport() throw ()
1353 {
1354 }
1355 
1356 // XInterface
queryInterface(const Type & aType)1357 Any SAL_CALL AnimationsImport::queryInterface( const Type& aType ) throw (RuntimeException)
1358 {
1359     if ( aType == ::getCppuType((Reference<XAnimationNodeSupplier> *)0) )
1360     {
1361         return makeAny( Reference<XAnimationNodeSupplier>( this ) );
1362     }
1363 	else
1364 	{
1365 		return SvXMLImport::queryInterface( aType );
1366 	}
1367 }
1368 
acquire()1369 void SAL_CALL AnimationsImport::acquire() throw ()
1370 {
1371 	SvXMLImport::acquire();
1372 }
1373 
release()1374 void SAL_CALL AnimationsImport::release() throw ()
1375 {
1376 	SvXMLImport::release();
1377 }
1378 
CreateContext(sal_uInt16 nPrefix,const OUString & rLocalName,const Reference<XAttributeList> & xAttrList)1379 SvXMLImportContext *AnimationsImport::CreateContext(sal_uInt16 nPrefix, const OUString& rLocalName,	const Reference<XAttributeList>& xAttrList)
1380 {
1381 	SvXMLImportContext* pContext = 0;
1382 
1383 	if( (XML_NAMESPACE_ANIMATION == nPrefix) && IsXMLToken( rLocalName, XML_SEQ ) )
1384 	{
1385 		 pContext = new AnimationNodeContext( mxRootNode, *this, nPrefix, rLocalName, xAttrList );
1386 	}
1387 	else
1388 	{
1389 		pContext = SvXMLImport::CreateContext(nPrefix, rLocalName, xAttrList);
1390 	}
1391 
1392 	return pContext;
1393 }
1394 
1395 // XAnimationNodeSupplier
getAnimationNode()1396 Reference< XAnimationNode > SAL_CALL AnimationsImport::getAnimationNode() throw (RuntimeException)
1397 {
1398 	return mxRootNode;
1399 }
1400 
postProcessRootNode(SvXMLImport &,const Reference<XAnimationNode> & xRootNode,Reference<XPropertySet> & xPageProps)1401 void AnimationNodeContext::postProcessRootNode( SvXMLImport& /*rImport*/, const Reference< XAnimationNode >& xRootNode, Reference< XPropertySet >& xPageProps )
1402 {
1403 	if( xRootNode.is() && xPageProps.is() ) try
1404 	{
1405 		Reference< XEnumerationAccess > xEnumerationAccess( xRootNode, UNO_QUERY_THROW );
1406 		Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
1407 		if( xEnumeration->hasMoreElements() )
1408 		{
1409 			Reference< XAnimationNode > xNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
1410 			if( xNode->getType() == AnimationNodeType::PAR )
1411 			{
1412 				Event aEvent;
1413 				if( (xNode->getBegin() >>= aEvent) && (aEvent.Trigger == EventTrigger::BEGIN_EVENT) )
1414 				{
1415 					// found transition node
1416 					Reference< XEnumerationAccess > xChildEnumerationAccess( xNode, UNO_QUERY_THROW );
1417 					Reference< XEnumeration > xChildEnumeration( xChildEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
1418 					while( xChildEnumeration->hasMoreElements() )
1419 					{
1420 						Reference< XAnimationNode > xChildNode( xChildEnumeration->nextElement(), UNO_QUERY_THROW );
1421 						switch( xChildNode->getType() )
1422 						{
1423 						case AnimationNodeType::TRANSITIONFILTER:
1424 						{
1425 							Reference< XTransitionFilter > xTransFilter( xChildNode, UNO_QUERY_THROW );
1426 
1427 
1428 							xPageProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "TransitionType" ) ), Any( xTransFilter->getTransition() ) );
1429 							xPageProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "TransitionSubtype" ) ), Any( xTransFilter->getSubtype() ) );
1430 							xPageProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "TransitionDirection" ) ), Any( xTransFilter->getDirection() ) );
1431 							xPageProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "TransitionFadeColor" ) ), Any( xTransFilter->getFadeColor() ) );
1432 
1433 							double fDuration;
1434 							if( xTransFilter->getDuration() >>= fDuration )
1435 								xPageProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "TransitionDuration" ) ), Any( fDuration ) );
1436 
1437 						}
1438 						break;
1439 
1440 						case AnimationNodeType::COMMAND:
1441 						{
1442 							Reference< XCommand > xCommand( xChildNode, UNO_QUERY_THROW );
1443 							if( xCommand->getCommand() == EffectCommands::STOPAUDIO )
1444 							{
1445 								xPageProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Sound" ) ), Any(sal_True) );
1446 							}
1447 						}
1448 						break;
1449 
1450 						case AnimationNodeType::AUDIO:
1451 						{
1452 							Reference< XAudio > xAudio( xChildNode, UNO_QUERY_THROW );
1453 							OUString sSoundURL;
1454 							if( (xAudio->getSource() >>= sSoundURL) && (sSoundURL.getLength() != 0) )
1455 							{
1456 								xPageProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Sound" ) ), Any(sSoundURL) );
1457 
1458 								Timing eTiming;
1459 								if( (xAudio->getRepeatCount() >>= eTiming) && (eTiming == Timing_INDEFINITE) )
1460 									xPageProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "LoopSound" ) ), Any( sal_True ) );
1461 							}
1462 						}
1463 						break;
1464 
1465 						}
1466 					}
1467 
1468 					Reference< XTimeContainer > xRootContainer( xRootNode, UNO_QUERY_THROW );
1469 					xRootContainer->removeChild( xNode );
1470 				}
1471 			}
1472 		}
1473 	}
1474 	catch( Exception& )
1475 	{
1476 		DBG_ERROR("xmloff::AnimationsImport::postProcessRootNode(), exception caught!");
1477 	}
1478 }
1479 
1480 } // namespace xmloff
1481 
AnimationsImport_getSupportedServiceNames()1482 Sequence< OUString > SAL_CALL AnimationsImport_getSupportedServiceNames() throw()
1483 {
1484 	const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Xmloff.AnimationsImport" ) );
1485 	const Sequence< OUString > aSeq( &aServiceName, 1 );
1486 	return aSeq;
1487 }
1488 
AnimationsImport_getImplementationName()1489 OUString SAL_CALL AnimationsImport_getImplementationName() throw()
1490 {
1491 	return OUString( RTL_CONSTASCII_USTRINGPARAM( "xmloff::AnimationsImport" ) );
1492 }
1493 
AnimationsImport_createInstance(const Reference<XMultiServiceFactory> & rSMgr)1494 Reference< XInterface > SAL_CALL AnimationsImport_createInstance(const Reference< XMultiServiceFactory > & rSMgr) throw( Exception )
1495 {
1496 	return (cppu::OWeakObject*)new xmloff::AnimationsImport( rSMgr );
1497 
1498 }
1499 
1500 namespace xmloff
1501 {
1502 
getImplementationName()1503 OUString SAL_CALL AnimationsImport::getImplementationName() throw(RuntimeException)
1504 {
1505 	return AnimationsImport_getImplementationName();
1506 }
1507 
supportsService(const OUString & ServiceName)1508 sal_Bool SAL_CALL AnimationsImport::supportsService( const OUString& ServiceName ) throw(RuntimeException)
1509 {
1510 	return ServiceName.equalsAscii( "com.sun.star.comp.Xmloff.AnimationsImport" );
1511 }
1512 
getSupportedServiceNames()1513 Sequence< OUString > SAL_CALL AnimationsImport::getSupportedServiceNames() throw(RuntimeException)
1514 {
1515 	return AnimationsImport_getSupportedServiceNames();
1516 }
1517 
1518 } // namespace xmloff
1519 
1520