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