xref: /AOO41X/main/xmloff/source/draw/animationimport.cxx (revision 63bba73cc51e0afb45f8a8d578158724bb5afee8)
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