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