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