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