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 :
21 : #include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
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 <xmloff/nmspmap.hxx>
65 : #include "anim.hxx"
66 :
67 : #include "animations.hxx"
68 : #include "animationimport.hxx"
69 :
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 : namespace xmloff
91 : {
92 :
93 : ///////////////////////////////////////////////////////////////////////
94 :
95 :
96 :
97 : ///////////////////////////////////////////////////////////////////////
98 :
99 :
100 : ///////////////////////////////////////////////////////////////////////
101 :
102 : class AnimationsImportHelperImpl
103 : {
104 : private:
105 : SvXMLImport& mrImport;
106 :
107 : SvXMLTokenMap* mpAnimationNodeTokenMap;
108 : SvXMLTokenMap* mpAnimationNodeAttributeTokenMap;
109 :
110 : public:
111 : AnimationsImportHelperImpl( SvXMLImport& rImport );
112 : ~AnimationsImportHelperImpl();
113 :
114 : const SvXMLTokenMap& getAnimationNodeTokenMap();
115 : const SvXMLTokenMap& getAnimationNodeAttributeTokenMap();
116 :
117 : Any convertValue( XMLTokenEnum eAttributeName, const OUString& rValue );
118 : Sequence< Any > convertValueSequence( XMLTokenEnum eAttributeName, const OUString& rValue );
119 :
120 : Any convertTarget( const OUString& rValue );
121 : Any convertPath( const OUString& rValue );
122 : Any convertTiming( const OUString& rValue );
123 : Sequence< double > convertKeyTimes( const OUString& rValue );
124 : Sequence< TimeFilterPair > convertTimeFilter( const OUString& rValue );
125 :
126 : bool convertAnimationValue( XMLTokenEnum eAttributeName, Any& rValue );
127 : const OUString mastrHSL;
128 : };
129 :
130 3 : AnimationsImportHelperImpl::AnimationsImportHelperImpl( SvXMLImport& rImport )
131 : : mrImport( rImport ),
132 : mpAnimationNodeTokenMap( NULL ),
133 : mpAnimationNodeAttributeTokenMap( NULL ),
134 3 : mastrHSL( "hsl" )
135 : {
136 3 : }
137 :
138 6 : AnimationsImportHelperImpl::~AnimationsImportHelperImpl()
139 : {
140 3 : delete mpAnimationNodeTokenMap;
141 3 : delete mpAnimationNodeAttributeTokenMap;
142 3 : }
143 :
144 169 : const SvXMLTokenMap& AnimationsImportHelperImpl::getAnimationNodeTokenMap()
145 : {
146 169 : if( mpAnimationNodeTokenMap == NULL )
147 : {
148 : static SvXMLTokenMapEntry aAnimationNodeTokenMap[] =
149 : {
150 : { XML_NAMESPACE_ANIMATION, XML_PAR, (sal_uInt16)AnimationNodeType::PAR },
151 : { XML_NAMESPACE_ANIMATION, XML_SEQ, (sal_uInt16)AnimationNodeType::SEQ },
152 : { XML_NAMESPACE_ANIMATION, XML_ITERATE, (sal_uInt16)AnimationNodeType::ITERATE },
153 : { XML_NAMESPACE_ANIMATION, XML_ANIMATE, (sal_uInt16)AnimationNodeType::ANIMATE },
154 : { XML_NAMESPACE_ANIMATION, XML_SET, (sal_uInt16)AnimationNodeType::SET },
155 : { XML_NAMESPACE_ANIMATION, XML_ANIMATEMOTION, (sal_uInt16)AnimationNodeType::ANIMATEMOTION },
156 : { XML_NAMESPACE_ANIMATION, XML_ANIMATECOLOR, (sal_uInt16)AnimationNodeType::ANIMATECOLOR },
157 : { XML_NAMESPACE_ANIMATION, XML_ANIMATETRANSFORM, (sal_uInt16)AnimationNodeType::ANIMATETRANSFORM },
158 : { XML_NAMESPACE_ANIMATION, XML_TRANSITIONFILTER, (sal_uInt16)AnimationNodeType::TRANSITIONFILTER },
159 : { XML_NAMESPACE_ANIMATION, XML_AUDIO, (sal_uInt16)AnimationNodeType::AUDIO },
160 : { XML_NAMESPACE_ANIMATION, XML_COMMAND, (sal_uInt16)AnimationNodeType::COMMAND },
161 : XML_TOKEN_MAP_END
162 : };
163 :
164 3 : mpAnimationNodeTokenMap = new SvXMLTokenMap( aAnimationNodeTokenMap );
165 : }
166 :
167 169 : return *mpAnimationNodeTokenMap;
168 : }
169 :
170 : enum AnimationNodeAttributes
171 : {
172 : ANA_Begin,
173 : ANA_Dur,
174 : ANA_End,
175 : ANA_Fill,
176 : ANA_FillDefault,
177 : ANA_Restart,
178 : ANA_RestartDefault,
179 : ANA_Accelerate,
180 : ANA_Decelerate,
181 : ANA_AutoReverse,
182 : ANA_RepeatCount,
183 : ANA_RepeatDur,
184 : ANA_EndSync,
185 : ANA_Node_Type,
186 : ANA_Preset_ID,
187 : ANA_Preset_Sub_Type,
188 : ANA_Preset_Class,
189 : ANA_After_Effect,
190 : ANA_Target,
191 : ANA_XLink,
192 : ANA_MasterElement,
193 : ANA_SubItem,
194 : ANA_AttributeName,
195 : ANA_Values,
196 : ANA_From,
197 : ANA_By,
198 : ANA_To,
199 : ANA_KeyTimes,
200 : ANA_CalcMode,
201 : ANA_Accumulate,
202 : ANA_AdditiveMode,
203 : ANA_KeySplines,
204 : ANA_Path,
205 : ANA_ColorSpace,
206 : ANA_ColorDirection,
207 : ANA_TransformType,
208 : ANA_TransitionType,
209 : ANA_TransitionSubType,
210 : ANA_Mode,
211 : ANA_Direction,
212 : ANA_FadeColor,
213 : ANA_IterateType,
214 : ANA_IterateInterval,
215 : ANA_Formula,
216 : ANA_ANIMID,
217 : ANA_XMLID,
218 : ANA_Group_Id,
219 : ANA_Command,
220 : ANA_Volume
221 : };
222 :
223 291 : const SvXMLTokenMap& AnimationsImportHelperImpl::getAnimationNodeAttributeTokenMap()
224 : {
225 291 : if( mpAnimationNodeAttributeTokenMap == NULL )
226 : {
227 : static SvXMLTokenMapEntry aAnimationNodeAttributeTokenMap[] =
228 : {
229 : { XML_NAMESPACE_SMIL, XML_BEGIN, (sal_uInt16)ANA_Begin },
230 : { XML_NAMESPACE_SMIL, XML_DUR, (sal_uInt16)ANA_Dur },
231 : { XML_NAMESPACE_SMIL, XML_END, (sal_uInt16)ANA_End },
232 : { XML_NAMESPACE_SMIL, XML_FILL, (sal_uInt16)ANA_Fill },
233 : { XML_NAMESPACE_SMIL, XML_FILLDEFAULT, (sal_uInt16)ANA_FillDefault },
234 : { XML_NAMESPACE_SMIL, XML_RESTART, (sal_uInt16)ANA_Restart },
235 : { XML_NAMESPACE_SMIL, XML_RESTARTDEFAULT, (sal_uInt16)ANA_RestartDefault },
236 : { XML_NAMESPACE_SMIL, XML_ACCELERATE, (sal_uInt16)ANA_Accelerate },
237 : { XML_NAMESPACE_SMIL, XML_DECELERATE, (sal_uInt16)ANA_Decelerate },
238 : { XML_NAMESPACE_SMIL, XML_AUTOREVERSE, (sal_uInt16)ANA_AutoReverse },
239 : { XML_NAMESPACE_SMIL, XML_REPEATCOUNT, (sal_uInt16)ANA_RepeatCount },
240 : { XML_NAMESPACE_SMIL, XML_REPEATDUR, (sal_uInt16)ANA_RepeatDur },
241 : { XML_NAMESPACE_SMIL, XML_ENDSYNC, (sal_uInt16)ANA_EndSync },
242 : { XML_NAMESPACE_PRESENTATION, XML_NODE_TYPE, (sal_uInt16)ANA_Node_Type },
243 : { XML_NAMESPACE_PRESENTATION, XML_PRESET_ID, (sal_uInt16)ANA_Preset_ID },
244 : { XML_NAMESPACE_PRESENTATION, XML_PRESET_SUB_TYPE, (sal_uInt16)ANA_Preset_Sub_Type },
245 : { XML_NAMESPACE_PRESENTATION, XML_PRESET_CLASS, (sal_uInt16)ANA_Preset_Class },
246 : { XML_NAMESPACE_PRESENTATION, XML_AFTER_EFFECT, (sal_uInt16)ANA_After_Effect },
247 : { XML_NAMESPACE_SMIL, XML_TARGETELEMENT, (sal_uInt16)ANA_Target },
248 : { XML_NAMESPACE_XLINK, XML_HREF, (sal_uInt16)ANA_XLink },
249 : { XML_NAMESPACE_PRESENTATION, XML_MASTER_ELEMENT, (sal_uInt16)ANA_MasterElement },
250 : { XML_NAMESPACE_ANIMATION, XML_SUB_ITEM, (sal_uInt16)ANA_SubItem },
251 : { XML_NAMESPACE_SMIL, XML_ATTRIBUTENAME, (sal_uInt16)ANA_AttributeName },
252 : { XML_NAMESPACE_SMIL, XML_VALUES, (sal_uInt16)ANA_Values },
253 : { XML_NAMESPACE_SMIL, XML_FROM, (sal_uInt16)ANA_From },
254 : { XML_NAMESPACE_SMIL, XML_BY, (sal_uInt16)ANA_By },
255 : { XML_NAMESPACE_SMIL, XML_TO, (sal_uInt16)ANA_To },
256 : { XML_NAMESPACE_SMIL, XML_KEYTIMES, (sal_uInt16)ANA_KeyTimes },
257 : { XML_NAMESPACE_SMIL, XML_CALCMODE, (sal_uInt16)ANA_CalcMode },
258 : { XML_NAMESPACE_SMIL, XML_ACCUMULATE, (sal_uInt16)ANA_Accumulate },
259 : { XML_NAMESPACE_PRESENTATION, XML_ADDITIVE, (sal_uInt16)ANA_AdditiveMode },
260 : { XML_NAMESPACE_SMIL, XML_ADDITIVE, (sal_uInt16)ANA_AdditiveMode },
261 : { XML_NAMESPACE_SMIL, XML_KEYSPLINES, (sal_uInt16)ANA_KeySplines },
262 : { XML_NAMESPACE_SVG, XML_PATH, (sal_uInt16)ANA_Path },
263 : { XML_NAMESPACE_ANIMATION, XML_COLOR_INTERPOLATION, (sal_uInt16)ANA_ColorSpace },
264 : { XML_NAMESPACE_ANIMATION, XML_COLOR_INTERPOLATION_DIRECTION, (sal_uInt16)ANA_ColorDirection },
265 : { XML_NAMESPACE_SVG, XML_TYPE, (sal_uInt16)ANA_TransformType },
266 : { XML_NAMESPACE_SMIL, XML_TYPE, (sal_uInt16)ANA_TransitionType },
267 : { XML_NAMESPACE_SMIL, XML_SUBTYPE, (sal_uInt16)ANA_TransitionSubType },
268 : { XML_NAMESPACE_SMIL, XML_MODE, (sal_uInt16)ANA_Mode },
269 : { XML_NAMESPACE_SMIL, XML_DIRECTION, (sal_uInt16)ANA_Direction },
270 : { XML_NAMESPACE_SMIL, XML_FADECOLOR, (sal_uInt16)ANA_FadeColor },
271 : { XML_NAMESPACE_ANIMATION, XML_ITERATE_TYPE, (sal_uInt16)ANA_IterateType },
272 : { XML_NAMESPACE_ANIMATION, XML_ITERATE_INTERVAL, (sal_uInt16)ANA_IterateInterval },
273 : { XML_NAMESPACE_ANIMATION, XML_FORMULA, (sal_uInt16)ANA_Formula },
274 : { XML_NAMESPACE_ANIMATION, XML_ID, (sal_uInt16)ANA_ANIMID },
275 : { XML_NAMESPACE_XML, XML_ID, (sal_uInt16)ANA_XMLID },
276 : { XML_NAMESPACE_PRESENTATION, XML_GROUP_ID, (sal_uInt16)ANA_Group_Id },
277 : { XML_NAMESPACE_ANIMATION, XML_AUDIO_LEVEL, (sal_uInt16)ANA_Volume },
278 : { XML_NAMESPACE_ANIMATION, XML_COMMAND, (sal_uInt16)ANA_Command },
279 :
280 : XML_TOKEN_MAP_END
281 : };
282 :
283 3 : mpAnimationNodeAttributeTokenMap = new SvXMLTokenMap( aAnimationNodeAttributeTokenMap );
284 : }
285 :
286 291 : return *mpAnimationNodeAttributeTokenMap;
287 : }
288 :
289 0 : static bool isDouble( const OUString& rValue )
290 : {
291 0 : sal_Int32 nLength = rValue.getLength();
292 0 : const sal_Unicode * pStr = rValue.getStr();
293 0 : while( nLength )
294 : {
295 0 : if( (*pStr >= '0' && *pStr <= '9') || *pStr == '-' || *pStr == '.' || *pStr == '+' || *pStr == 'e' || *pStr == 'E' )
296 : {
297 0 : pStr++;
298 0 : nLength--;
299 : }
300 : else
301 : {
302 0 : return false;
303 : }
304 : }
305 :
306 0 : return true;
307 : }
308 :
309 7 : static bool isTime( const OUString& rValue )
310 : {
311 7 : sal_Int32 nLength = rValue.getLength();
312 : const sal_Unicode * pStr;
313 21 : for( pStr = rValue.getStr(); nLength; pStr++, nLength-- )
314 : {
315 21 : if( !( (*pStr >= '0' && *pStr <= '9') || *pStr == '-' || *pStr == '.' || *pStr == '+' || *pStr == 'e' || *pStr == 'E' ) )
316 7 : break;
317 : }
318 :
319 : // return true if this is a double (if someone forgot the 's' we silently ignore it)
320 : // or if its a double that ends with a 's' or 'S'
321 7 : return (nLength == 0) || ((*pStr == 's' || *pStr == 'S') && (nLength == 1));
322 : }
323 :
324 11 : static sal_Int32 count_codes( const OUString& rString, sal_Unicode nCode )
325 : {
326 11 : sal_Int32 nCount = 0;
327 11 : sal_Int32 fromIndex = 0;
328 :
329 : while(true)
330 : {
331 15 : fromIndex = rString.indexOf( nCode, fromIndex );
332 15 : if( fromIndex == -1 )
333 11 : break;
334 :
335 4 : fromIndex++;
336 4 : nCount++;
337 : }
338 :
339 4 : return nCount;
340 : }
341 :
342 3 : Any AnimationsImportHelperImpl::convertTarget( const OUString& rValue )
343 : {
344 : try
345 : {
346 3 : Reference< XInterface > xRef( mrImport.getInterfaceToIdentifierMapper().getReference( rValue ) );
347 :
348 3 : Reference< XShape > _xShape( xRef, UNO_QUERY );
349 3 : if( _xShape.is() )
350 3 : return makeAny( _xShape );
351 :
352 0 : Reference< XTextCursor > xTextCursor( xRef, UNO_QUERY );
353 0 : if( xTextCursor.is() )
354 : {
355 0 : Reference< XTextRange > xStart( xTextCursor->getStart() ), xRange;
356 0 : Reference< XShape > xShape( xTextCursor->getText(), UNO_QUERY_THROW );
357 0 : Reference< XTextRangeCompare > xTextRangeCompare( xShape, UNO_QUERY_THROW );
358 :
359 0 : Reference< XEnumerationAccess > xParaEnumAccess( xShape, UNO_QUERY_THROW );
360 0 : Reference< XEnumeration > xEnumeration( xParaEnumAccess->createEnumeration(), UNO_QUERY_THROW );
361 0 : sal_Int16 nParagraph = 0;
362 :
363 0 : while( xEnumeration->hasMoreElements() )
364 : {
365 0 : xEnumeration->nextElement() >>= xRange;
366 :
367 : // break if start of selection is prior to end of current paragraph
368 0 : if( xRange.is() && (xTextRangeCompare->compareRegionEnds( xStart, xRange ) >= 0 ) )
369 : {
370 0 : return makeAny( ParagraphTarget( xShape, nParagraph ) );
371 : }
372 :
373 0 : nParagraph++;
374 0 : }
375 0 : }
376 : }
377 0 : catch (const RuntimeException&)
378 : {
379 : OSL_FAIL( "xmloff::AnimationsImportImpl::convertTarget(), RuntimeException caught!" );
380 : }
381 :
382 0 : Any aAny;
383 0 : return aAny;
384 : }
385 :
386 5 : Any AnimationsImportHelperImpl::convertValue( XMLTokenEnum eAttributeName, const OUString& rValue )
387 : {
388 5 : sal_Int32 nCommaPos = -1, nPos;
389 5 : sal_Int32 nOpenBrakets = 0;
390 25 : for( nPos = 0; (nPos < rValue.getLength()) && (nCommaPos == -1); nPos++ )
391 : {
392 20 : switch( rValue[nPos] )
393 : {
394 : case ',':
395 0 : if( nOpenBrakets == 0 )
396 0 : nCommaPos = nPos;
397 0 : break;
398 : case '(':
399 : case '[':
400 : case '{':
401 0 : nOpenBrakets++;
402 0 : break;
403 : case ')':
404 : case ']':
405 : case '}':
406 0 : nOpenBrakets--;
407 0 : break;
408 : }
409 : }
410 :
411 5 : if( nCommaPos >= 0 )
412 : {
413 0 : ValuePair aPair;
414 0 : aPair.First = convertValue( eAttributeName, rValue.copy( 0, nCommaPos ) );
415 0 : aPair.Second = convertValue( eAttributeName, rValue.copy( nCommaPos+1, rValue.getLength() - nCommaPos - 1 ) );
416 0 : return makeAny( aPair );
417 : }
418 : else
419 : {
420 5 : Any aAny;
421 5 : sal_Int32 nType = XML_TYPE_STRING;
422 :
423 5 : if( rValue.getLength() ) switch( eAttributeName )
424 : {
425 : case XML_X:
426 : case XML_Y:
427 : case XML_WIDTH:
428 : case XML_HEIGHT:
429 : case XML_TRANSLATE:
430 : {
431 4 : return makeAny( rValue );
432 : }
433 :
434 : case XML_SCALE:
435 : case XML_SKEWY:
436 : case XML_SKEWX:
437 : case XML_OPACITY:
438 0 : case XML_ROTATE: nType = XML_TYPE_DOUBLE; break;
439 0 : case XML_TEXT_ROTATION_ANGLE:nType = XML_TYPE_TEXT_ROTATION_ANGLE; break;
440 : case XML_FILL_COLOR:
441 : case XML_STROKE_COLOR:
442 : case XML_DIM:
443 0 : case XML_COLOR: nType = XML_TYPE_COLOR; break;
444 0 : case XML_FILL: nType = XML_SD_TYPE_FILLSTYLE; break;
445 0 : case XML_STROKE: nType = XML_SD_TYPE_STROKE; break;
446 0 : case XML_FONT_WEIGHT: nType = XML_TYPE_TEXT_WEIGHT; break;
447 0 : case XML_FONT_STYLE: nType = XML_TYPE_TEXT_POSTURE; break;
448 0 : case XML_TEXT_UNDERLINE: nType = XML_TYPE_TEXT_UNDERLINE_STYLE; break;
449 0 : case XML_FONT_SIZE: nType = XML_TYPE_DOUBLE_PERCENT; break;
450 1 : case XML_VISIBILITY: nType = XML_SD_TYPE_PRESPAGE_VISIBILITY; break;
451 :
452 : default:
453 0 : if( !rValue.isEmpty() )
454 0 : aAny <<= rValue;
455 0 : return aAny;
456 : }
457 :
458 1 : const XMLPropertyHandler* pHandler = mrImport.GetShapeImport()->GetSdPropHdlFactory()->GetPropertyHandler( nType );
459 1 : if( pHandler )
460 1 : pHandler->importXML( rValue, aAny, mrImport.GetMM100UnitConverter() );
461 :
462 1 : return aAny;
463 : }
464 : }
465 :
466 2 : Sequence< Any > AnimationsImportHelperImpl::convertValueSequence( XMLTokenEnum eAttributeName, const OUString& rValue )
467 : {
468 2 : Sequence< Any > aValues;
469 :
470 : // do we have any value at all?
471 2 : if( !rValue.isEmpty() )
472 : {
473 2 : sal_Int32 nElements = count_codes( rValue, (sal_Unicode)';') + 1; // a non empty string has at least one value
474 :
475 : // prepare the sequence
476 2 : aValues.realloc( nElements );
477 :
478 : // fill the sequence
479 2 : Any* pValues = aValues.getArray();
480 : sal_Int32 nIndex;
481 6 : for( nIndex = 0; nElements && (nIndex >= 0); nElements-- )
482 : {
483 4 : *pValues++ = convertValue( eAttributeName, rValue.getToken( 0, ';', nIndex ) );
484 : }
485 : }
486 :
487 2 : return aValues;
488 : }
489 :
490 7 : Any AnimationsImportHelperImpl::convertTiming( const OUString& rValue )
491 : {
492 7 : Any aAny;
493 :
494 : // do we have any value at all?
495 7 : if( !rValue.isEmpty() )
496 : {
497 : // count the values
498 7 : sal_Int32 nElements = count_codes( rValue, (sal_Unicode)';' ) + 1; // a non empty string has at least one value
499 :
500 7 : if( nElements == 1 )
501 : {
502 7 : if( IsXMLToken( rValue, XML_MEDIA ) )
503 : {
504 0 : aAny <<= Timing_MEDIA;
505 : }
506 7 : else if( IsXMLToken( rValue, XML_INDEFINITE ) )
507 : {
508 0 : aAny <<= Timing_INDEFINITE;
509 : }
510 7 : else if( isTime( rValue ) )
511 : {
512 6 : aAny <<= rValue.toDouble();
513 : }
514 : else
515 : {
516 1 : Event aEvent;
517 1 : aEvent.Repeat = 0;
518 1 : aEvent.Trigger = 0;
519 :
520 2 : OUString aEventTrigger;
521 :
522 1 : sal_Int32 nPos = rValue.indexOf( (sal_Unicode)'+' );
523 1 : if( nPos == -1 )
524 : {
525 1 : aEventTrigger = rValue;
526 : }
527 : else
528 : {
529 0 : aEventTrigger = rValue.copy( 0, nPos );
530 :
531 : // convert offset
532 0 : aEvent.Offset <<= convertTiming( rValue.copy( nPos + 1 ) );
533 : }
534 :
535 1 : nPos = aEventTrigger.indexOf( (sal_Unicode)'.' );
536 1 : if( nPos != -1 )
537 : {
538 0 : aEvent.Source <<= mrImport.getInterfaceToIdentifierMapper().getReference( aEventTrigger.copy( 0, nPos ) );
539 0 : aEventTrigger = aEventTrigger.copy( nPos + 1 );
540 : }
541 :
542 : sal_uInt16 nEnum;
543 1 : if( SvXMLUnitConverter::convertEnum( nEnum, aEventTrigger, getAnimationsEnumMap(Animations_EnumMap_EventTrigger) ) )
544 : {
545 1 : aEvent.Trigger = (sal_Int16)nEnum;
546 : }
547 : else
548 : {
549 : OSL_FAIL("AnimationsImportHelperImpl::convertTiming(), unknown event trigger!");
550 : }
551 :
552 2 : aAny <<= aEvent;
553 : }
554 : }
555 : else
556 : {
557 : // fill the sequence
558 0 : Sequence< Any > aValues( nElements );
559 0 : Any* pValues = aValues.getArray();
560 0 : sal_Int32 nIndex = 0;
561 0 : while( (nElements--) && (nIndex >= 0) )
562 0 : *pValues++ = convertTiming( rValue.getToken( 0, ';', nIndex ) );
563 :
564 0 : aAny <<= aValues;
565 : }
566 : }
567 7 : return aAny;
568 : }
569 :
570 2 : Sequence< double > AnimationsImportHelperImpl::convertKeyTimes( const OUString& rValue )
571 : {
572 2 : sal_Int32 nElements = 0;
573 :
574 2 : if( !rValue.isEmpty() )
575 2 : nElements = count_codes( rValue, (sal_Unicode)';' ) + 1; // a non empty string has at least one value
576 :
577 2 : Sequence< double > aKeyTimes( nElements );
578 :
579 2 : if( nElements )
580 : {
581 2 : double* pValues = aKeyTimes.getArray();
582 2 : sal_Int32 nIndex = 0;
583 8 : while( (nElements--) && (nIndex >= 0) )
584 4 : *pValues++ = rValue.getToken( 0, ';', nIndex ).toDouble();
585 : }
586 :
587 2 : return aKeyTimes;
588 : }
589 :
590 0 : Sequence< TimeFilterPair > AnimationsImportHelperImpl::convertTimeFilter( const OUString& rValue )
591 : {
592 0 : sal_Int32 nElements = 0;
593 :
594 0 : if( !rValue.isEmpty() )
595 0 : nElements = count_codes( rValue, (sal_Unicode)';' ) + 1; // a non empty string has at least one value
596 :
597 0 : Sequence< TimeFilterPair > aTimeFilter( nElements );
598 :
599 0 : if( nElements )
600 : {
601 0 : TimeFilterPair* pValues = aTimeFilter.getArray();
602 0 : sal_Int32 nIndex = 0;
603 0 : while( (nElements--) && (nIndex >= 0) )
604 : {
605 0 : const OUString aToken( rValue.getToken( 0, ';', nIndex ) );
606 :
607 0 : sal_Int32 nPos = aToken.indexOf( ',' );
608 0 : if( nPos >= 0 )
609 : {
610 0 : pValues->Time = aToken.copy( 0, nPos ).toDouble();
611 0 : pValues->Progress = aToken.copy( nPos+1, aToken.getLength() - nPos - 1 ).toDouble();
612 : }
613 0 : pValues++;
614 0 : }
615 : }
616 :
617 0 : return aTimeFilter;
618 : }
619 :
620 0 : Any AnimationsImportHelperImpl::convertPath( const OUString& rValue )
621 : {
622 0 : return makeAny( rValue );
623 : }
624 :
625 : ///////////////////////////////////////////////////////////////////////
626 :
627 0 : TYPEINIT1( AnimationNodeContext, SvXMLImportContext );
628 :
629 172 : 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 172 : mbRootContext( pHelper == NULL )
637 : {
638 : try
639 : {
640 172 : if( mbRootContext )
641 : {
642 3 : mpHelper = new AnimationsImportHelperImpl( rImport );
643 3 : mxNode = xParentNode;
644 : }
645 : else
646 : {
647 169 : sal_Int16 nPresetClass = EffectPresetClass::CUSTOM;
648 :
649 169 : const sal_Char* pServiceName = 0;
650 :
651 169 : sal_Int16 nNodeType = (sal_Int16)mpHelper->getAnimationNodeTokenMap().Get( nPrfx, rLocalName );
652 169 : switch( nNodeType )
653 : {
654 1 : case AnimationNodeType::SEQ: pServiceName = "com.sun.star.animations.SequenceTimeContainer"; break;
655 0 : case AnimationNodeType::ITERATE: pServiceName = "com.sun.star.animations.IterateContainer"; break;
656 2 : case AnimationNodeType::ANIMATE: pServiceName = "com.sun.star.animations.Animate"; break;
657 1 : 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 81 : 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 84 : const sal_Int16 nCount = xAttrList.is() ? xAttrList->getLength() : 0;
667 : sal_Int16 nAttribute;
668 173 : for( nAttribute = 0; nAttribute < nCount; nAttribute++ )
669 : {
670 89 : OUString aLocalName;
671 89 : sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( nAttribute ), &aLocalName );
672 89 : if( (nPrefix == XML_NAMESPACE_PRESENTATION) && IsXMLToken( aLocalName, XML_PRESET_ID ) )
673 : {
674 82 : const OUString& rValue = xAttrList->getValueByIndex( nAttribute );
675 82 : if ( rValue == "ooo-entrance-random" )
676 : {
677 0 : nPresetClass = EffectPresetClass::ENTRANCE;
678 : }
679 82 : else if ( rValue == "ooo-exit-random" )
680 : {
681 0 : nPresetClass = EffectPresetClass::EXIT;
682 : }
683 :
684 82 : if( nPresetClass != EffectPresetClass::CUSTOM )
685 : {
686 0 : pServiceName = "com.sun.star.comp.sd.RandomAnimationNode";
687 0 : break;
688 82 : }
689 : }
690 89 : }
691 84 : if( !pServiceName )
692 84 : pServiceName = "com.sun.star.animations.ParallelTimeContainer";
693 : }
694 84 : break;
695 : default:
696 0 : pServiceName = 0;
697 : }
698 :
699 169 : if( pServiceName )
700 : {
701 169 : Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
702 :
703 338 : mxNode = Reference< XAnimationNode >(
704 338 : xContext->getServiceManager()->createInstanceWithContext(OUString::createFromAscii(pServiceName), xContext),
705 169 : UNO_QUERY_THROW );
706 :
707 169 : 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 169 : init_node( xAttrList );
716 :
717 338 : Reference< XTimeContainer > xParentContainer( xParentNode, UNO_QUERY_THROW );
718 338 : xParentContainer->appendChild( mxNode );
719 : }
720 : }
721 : }
722 0 : catch (const RuntimeException&)
723 : {
724 : OSL_FAIL( "xmloff::AnimationsImportImpl::AnimationsImportImpl(), RuntimeException caught!" );
725 : }
726 172 : }
727 :
728 516 : AnimationNodeContext::~AnimationNodeContext()
729 : {
730 172 : if( mbRootContext )
731 3 : delete mpHelper;
732 344 : }
733 :
734 172 : 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 172 : }
741 :
742 169 : void AnimationNodeContext::init_node( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList )
743 : {
744 169 : if( mxNode.is() ) try
745 : {
746 169 : const sal_Int16 nNodeType = mxNode->getType();
747 :
748 : // query for optional interfaces that are often used later
749 169 : Reference< XAnimate > xAnimate( mxNode, UNO_QUERY );
750 338 : Reference< XCommand > xCommand( mxNode, UNO_QUERY );
751 338 : Reference< XTransitionFilter > xTransitionFilter( mxNode, UNO_QUERY );
752 338 : Reference< XIterateContainer > xIter( mxNode, UNO_QUERY );
753 :
754 338 : std::list< NamedValue > aUserData;
755 169 : XMLTokenEnum meAttributeName = XML_TOKEN_INVALID;
756 338 : OUString aFrom, aBy, aTo, aValues;
757 169 : bool bHaveXmlId( false );
758 338 : OUString sXmlId;
759 :
760 169 : const sal_Int16 nCount = xAttrList.is() ? xAttrList->getLength() : 0;
761 : sal_uInt16 nEnum;
762 : sal_Int16 nAttribute;
763 460 : for( nAttribute = 0; nAttribute < nCount; nAttribute++ )
764 : {
765 291 : const OUString& rAttrName = xAttrList->getNameByIndex( nAttribute );
766 582 : const OUString& rValue = xAttrList->getValueByIndex( nAttribute );
767 :
768 582 : OUString aLocalName;
769 291 : sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName );
770 291 : switch( mpHelper->getAnimationNodeAttributeTokenMap().Get( nPrefix, aLocalName ) )
771 : {
772 : case ANA_Begin:
773 : {
774 4 : mxNode->setBegin( mpHelper->convertTiming( rValue ) );
775 : }
776 4 : break;
777 : case ANA_Dur:
778 : {
779 3 : mxNode->setDuration( mpHelper->convertTiming( rValue ) );
780 : }
781 3 : break;
782 : case ANA_End:
783 : {
784 0 : mxNode->setEnd( mpHelper->convertTiming( rValue ) );
785 : }
786 0 : break;
787 : case ANA_Fill:
788 : {
789 4 : if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_Fill) ) )
790 4 : mxNode->setFill( (sal_Int16)nEnum );
791 : }
792 4 : 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 2 : if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_EffectNodeType) ) )
849 2 : aUserData.push_back( NamedValue( GetXMLToken( XML_NODE_TYPE ), makeAny( (sal_Int16)nEnum ) ) );
850 : }
851 2 : break;
852 : case ANA_Preset_ID:
853 : {
854 82 : aUserData.push_back( NamedValue( GetXMLToken( XML_PRESET_ID ), makeAny( rValue ) ) );
855 : }
856 82 : break;
857 : case ANA_Preset_Sub_Type:
858 : {
859 1 : aUserData.push_back( NamedValue( GetXMLToken( XML_PRESET_SUB_TYPE ), makeAny( rValue ) ) );
860 : }
861 1 : break;
862 : case ANA_Preset_Class:
863 : {
864 1 : if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_EffectPresetClass) ) )
865 1 : aUserData.push_back( NamedValue( GetXMLToken( XML_PRESET_CLASS ), makeAny( (sal_Int16)nEnum ) ) );
866 : }
867 1 : 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 3 : Any aTarget( mpHelper->convertTarget( rValue ) );
890 :
891 3 : if( xAnimate.is() )
892 : {
893 3 : 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 3 : }
903 : }
904 : }
905 3 : 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 3 : if( xAnimate.is() )
946 : {
947 3 : OUString aName( rValue );
948 :
949 3 : ImplAttributeNameConversion* p = getAnimationAttributeNamesConversionList();
950 24 : while( p->mpAPIName )
951 : {
952 21 : if( IsXMLToken( aName, p->meXMLToken ) )
953 : {
954 3 : aName = OUString::createFromAscii( p->mpAPIName );
955 3 : meAttributeName = p->meXMLToken;
956 3 : break;
957 : }
958 :
959 18 : p++;
960 : }
961 :
962 3 : xAnimate->setAttributeName( aName );
963 : }
964 : }
965 3 : break;
966 :
967 : case ANA_Values:
968 : {
969 2 : aValues = rValue;
970 : }
971 2 : 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 1 : aTo = rValue;
988 : }
989 1 : break;
990 :
991 : case ANA_KeyTimes:
992 : {
993 2 : if( xAnimate.is() )
994 2 : xAnimate->setKeyTimes( mpHelper->convertKeyTimes( rValue ) );
995 : }
996 2 : 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 81 : if( xTransitionFilter.is() )
1101 : {
1102 81 : if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_TransitionType) ) )
1103 81 : xTransitionFilter->setTransition( (sal_Int16)nEnum );
1104 : }
1105 : }
1106 81 : break;
1107 :
1108 : case ANA_TransitionSubType:
1109 : {
1110 80 : if( xTransitionFilter.is() )
1111 : {
1112 80 : if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_TransitionSubType) ) )
1113 80 : xTransitionFilter->setSubtype( (sal_Int16)nEnum );
1114 : }
1115 : }
1116 80 : 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 20 : if( xTransitionFilter.is() )
1128 20 : xTransitionFilter->setDirection( IsXMLToken( rValue, XML_FORWARD ) );
1129 : }
1130 20 : break;
1131 :
1132 : case ANA_FadeColor:
1133 : {
1134 2 : if( xTransitionFilter.is() )
1135 : {
1136 2 : sal_Int32 nColor(0);
1137 2 : ::sax::Converter::convertColor(nColor, rValue);
1138 2 : xTransitionFilter->setFadeColor(nColor);
1139 : }
1140 : }
1141 2 : 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 291 : }
1204 :
1205 169 : 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 169 : sal_Int32 nUserDataCount = aUserData.size();
1213 169 : if( nUserDataCount )
1214 : {
1215 83 : Sequence< NamedValue > aUnoUserData( nUserDataCount );
1216 83 : NamedValue* pData = aUnoUserData.getArray();
1217 83 : std::list< NamedValue >::iterator aIter( aUserData.begin() );
1218 83 : const std::list< NamedValue >::iterator aEnd( aUserData.end() );
1219 252 : while( aIter != aEnd )
1220 86 : *pData++ = (*aIter++);
1221 :
1222 83 : mxNode->setUserData( aUnoUserData );
1223 : }
1224 :
1225 : // convert values
1226 169 : if( xAnimate.is() )
1227 : {
1228 84 : if( !aFrom.isEmpty() )
1229 0 : xAnimate->setFrom( mpHelper->convertValue( meAttributeName, aFrom ) );
1230 :
1231 84 : if( !aBy.isEmpty() )
1232 0 : xAnimate->setBy( mpHelper->convertValue( meAttributeName, aBy ) );
1233 :
1234 84 : if( !aTo.isEmpty() )
1235 1 : xAnimate->setTo( mpHelper->convertValue( meAttributeName, aTo ) );
1236 :
1237 84 : if( !aValues.isEmpty() )
1238 2 : xAnimate->setValues( mpHelper->convertValueSequence( meAttributeName, aValues ) );
1239 169 : }
1240 : }
1241 0 : catch (const RuntimeException&)
1242 : {
1243 : OSL_FAIL( "xmloff::AnimationNodeContext::StartElement(), RuntimeException caught!" );
1244 : }
1245 169 : }
1246 :
1247 169 : 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 169 : if( mxNode.is())
1251 169 : return new AnimationNodeContext( mxNode, GetImport(), nPrefix, rLocalName, xAttrList, mpHelper );
1252 : else
1253 0 : return new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
1254 : }
1255 :
1256 : // --------------------------------------------------------------------
1257 :
1258 : class AnimationsImport: public SvXMLImport, public XAnimationNodeSupplier
1259 : {
1260 : public:
1261 : AnimationsImport( const Reference< XComponentContext > & rxContext );
1262 : ~AnimationsImport() throw ();
1263 :
1264 : SvXMLImportContext* CreateContext(sal_uInt16 nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& xAttrList);
1265 :
1266 : // XInterface
1267 : virtual Any SAL_CALL queryInterface( const Type& aType ) throw (RuntimeException);
1268 : virtual void SAL_CALL acquire() throw ();
1269 : virtual void SAL_CALL release() throw ();
1270 :
1271 : // XAnimationNodeSupplier
1272 : Reference< XAnimationNode > SAL_CALL getAnimationNode() throw (RuntimeException);
1273 :
1274 : // XServiceInfo
1275 : virtual OUString SAL_CALL getImplementationName() throw(RuntimeException);
1276 : virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException);
1277 : virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(RuntimeException);
1278 :
1279 : private:
1280 : Reference< XAnimationNode > mxRootNode;
1281 : };
1282 :
1283 2 : AnimationsImport::AnimationsImport( const Reference< XComponentContext > & rxContext )
1284 2 : : SvXMLImport( rxContext , true )
1285 : {
1286 : // add namespaces
1287 2 : GetNamespaceMap().Add(
1288 2 : GetXMLToken(XML_NP_PRESENTATION),
1289 2 : GetXMLToken(XML_N_PRESENTATION),
1290 2 : XML_NAMESPACE_PRESENTATION);
1291 :
1292 2 : GetNamespaceMap().Add(
1293 2 : GetXMLToken(XML_NP_SMIL),
1294 2 : GetXMLToken(XML_N_SMIL),
1295 2 : XML_NAMESPACE_SMIL);
1296 :
1297 2 : GetNamespaceMap().Add(
1298 2 : GetXMLToken(XML_NP_ANIMATION),
1299 2 : GetXMLToken(XML_N_ANIMATION),
1300 2 : XML_NAMESPACE_ANIMATION);
1301 :
1302 2 : mxRootNode = Reference<XAnimationNode>( SequenceTimeContainer::create(rxContext), UNO_QUERY_THROW );
1303 2 : }
1304 :
1305 4 : AnimationsImport::~AnimationsImport() throw ()
1306 : {
1307 4 : }
1308 :
1309 : // XInterface
1310 6 : Any SAL_CALL AnimationsImport::queryInterface( const Type& aType ) throw (RuntimeException)
1311 : {
1312 6 : if ( aType == ::getCppuType((Reference<XAnimationNodeSupplier> *)0) )
1313 : {
1314 2 : return makeAny( Reference<XAnimationNodeSupplier>( this ) );
1315 : }
1316 : else
1317 : {
1318 4 : return SvXMLImport::queryInterface( aType );
1319 : }
1320 : }
1321 :
1322 14 : void SAL_CALL AnimationsImport::acquire() throw ()
1323 : {
1324 14 : SvXMLImport::acquire();
1325 14 : }
1326 :
1327 14 : void SAL_CALL AnimationsImport::release() throw ()
1328 : {
1329 14 : SvXMLImport::release();
1330 14 : }
1331 :
1332 2 : SvXMLImportContext *AnimationsImport::CreateContext(sal_uInt16 nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& xAttrList)
1333 : {
1334 2 : SvXMLImportContext* pContext = 0;
1335 :
1336 2 : if( (XML_NAMESPACE_ANIMATION == nPrefix) && IsXMLToken( rLocalName, XML_SEQ ) )
1337 : {
1338 2 : pContext = new AnimationNodeContext( mxRootNode, *this, nPrefix, rLocalName, xAttrList );
1339 : }
1340 : else
1341 : {
1342 0 : pContext = SvXMLImport::CreateContext(nPrefix, rLocalName, xAttrList);
1343 : }
1344 :
1345 2 : return pContext;
1346 : }
1347 :
1348 : // XAnimationNodeSupplier
1349 2 : Reference< XAnimationNode > SAL_CALL AnimationsImport::getAnimationNode() throw (RuntimeException)
1350 : {
1351 2 : return mxRootNode;
1352 : }
1353 :
1354 1 : void AnimationNodeContext::postProcessRootNode( SvXMLImport& /*rImport*/, const Reference< XAnimationNode >& xRootNode, Reference< XPropertySet >& xPageProps )
1355 : {
1356 1 : if( xRootNode.is() && xPageProps.is() ) try
1357 : {
1358 1 : Reference< XEnumerationAccess > xEnumerationAccess( xRootNode, UNO_QUERY_THROW );
1359 2 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
1360 1 : if( xEnumeration->hasMoreElements() )
1361 : {
1362 1 : Reference< XAnimationNode > xNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
1363 1 : if( xNode->getType() == AnimationNodeType::PAR )
1364 : {
1365 0 : Event aEvent;
1366 0 : if( (xNode->getBegin() >>= aEvent) && (aEvent.Trigger == EventTrigger::BEGIN_EVENT) )
1367 : {
1368 : // found transition node
1369 0 : Reference< XEnumerationAccess > xChildEnumerationAccess( xNode, UNO_QUERY_THROW );
1370 0 : Reference< XEnumeration > xChildEnumeration( xChildEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
1371 0 : while( xChildEnumeration->hasMoreElements() )
1372 : {
1373 0 : Reference< XAnimationNode > xChildNode( xChildEnumeration->nextElement(), UNO_QUERY_THROW );
1374 0 : switch( xChildNode->getType() )
1375 : {
1376 : case AnimationNodeType::TRANSITIONFILTER:
1377 : {
1378 0 : Reference< XTransitionFilter > xTransFilter( xChildNode, UNO_QUERY_THROW );
1379 :
1380 :
1381 0 : xPageProps->setPropertyValue("TransitionType", Any( xTransFilter->getTransition() ) );
1382 0 : xPageProps->setPropertyValue("TransitionSubtype", Any( xTransFilter->getSubtype() ) );
1383 0 : xPageProps->setPropertyValue("TransitionDirection", Any( xTransFilter->getDirection() ) );
1384 0 : xPageProps->setPropertyValue("TransitionFadeColor", Any( xTransFilter->getFadeColor() ) );
1385 :
1386 : double fDuration;
1387 0 : if( xTransFilter->getDuration() >>= fDuration )
1388 0 : xPageProps->setPropertyValue("TransitionDuration", Any( fDuration ) );
1389 :
1390 : }
1391 0 : break;
1392 :
1393 : case AnimationNodeType::COMMAND:
1394 : {
1395 0 : Reference< XCommand > xCommand( xChildNode, UNO_QUERY_THROW );
1396 0 : if( xCommand->getCommand() == EffectCommands::STOPAUDIO )
1397 : {
1398 0 : xPageProps->setPropertyValue("Sound", Any(sal_True) );
1399 0 : }
1400 : }
1401 0 : break;
1402 :
1403 : case AnimationNodeType::AUDIO:
1404 : {
1405 0 : Reference< XAudio > xAudio( xChildNode, UNO_QUERY_THROW );
1406 0 : OUString sSoundURL;
1407 0 : if( (xAudio->getSource() >>= sSoundURL) && !sSoundURL.isEmpty() )
1408 : {
1409 0 : xPageProps->setPropertyValue("Sound", Any(sSoundURL) );
1410 :
1411 : Timing eTiming;
1412 0 : if( (xAudio->getRepeatCount() >>= eTiming) && (eTiming == Timing_INDEFINITE) )
1413 0 : xPageProps->setPropertyValue("LoopSound", Any( sal_True ) );
1414 0 : }
1415 : }
1416 0 : break;
1417 :
1418 : }
1419 0 : }
1420 :
1421 0 : Reference< XTimeContainer > xRootContainer( xRootNode, UNO_QUERY_THROW );
1422 0 : xRootContainer->removeChild( xNode );
1423 0 : }
1424 1 : }
1425 1 : }
1426 : }
1427 0 : catch (const Exception&)
1428 : {
1429 : OSL_FAIL("xmloff::AnimationsImport::postProcessRootNode(), exception caught!");
1430 : }
1431 1 : }
1432 :
1433 : } // namespace xmloff
1434 :
1435 1 : Sequence< OUString > SAL_CALL AnimationsImport_getSupportedServiceNames() throw()
1436 : {
1437 1 : const OUString aServiceName( "com.sun.star.comp.Xmloff.AnimationsImport" );
1438 1 : const Sequence< OUString > aSeq( &aServiceName, 1 );
1439 1 : return aSeq;
1440 : }
1441 :
1442 85 : OUString SAL_CALL AnimationsImport_getImplementationName() throw()
1443 : {
1444 85 : return OUString( "xmloff::AnimationsImport" );
1445 : }
1446 :
1447 2 : Reference< XInterface > SAL_CALL AnimationsImport_createInstance(const Reference< XMultiServiceFactory > & rSMgr) throw( Exception )
1448 : {
1449 2 : return (cppu::OWeakObject*)new xmloff::AnimationsImport( comphelper::getComponentContext(rSMgr) );
1450 : }
1451 :
1452 : namespace xmloff
1453 : {
1454 :
1455 0 : OUString SAL_CALL AnimationsImport::getImplementationName() throw(RuntimeException)
1456 : {
1457 0 : return AnimationsImport_getImplementationName();
1458 : }
1459 :
1460 0 : sal_Bool SAL_CALL AnimationsImport::supportsService( const OUString& ServiceName ) throw(RuntimeException)
1461 : {
1462 0 : return ServiceName == "com.sun.star.comp.Xmloff.AnimationsImport";
1463 : }
1464 :
1465 0 : Sequence< OUString > SAL_CALL AnimationsImport::getSupportedServiceNames() throw(RuntimeException)
1466 : {
1467 0 : return AnimationsImport_getSupportedServiceNames();
1468 : }
1469 :
1470 : } // namespace xmloff
1471 :
1472 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|