xref: /trunk/main/oox/source/ppt/timenodelistcontext.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #include "oox/ppt/timenodelistcontext.hxx"
29 
30 #include "comphelper/anytostring.hxx"
31 #include "cppuhelper/exc_hlp.hxx"
32 #include <osl/diagnose.h>
33 #include <rtl/math.hxx>
34 
35 #include <com/sun/star/animations/XTimeContainer.hpp>
36 #include <com/sun/star/animations/XAnimationNode.hpp>
37 #include <com/sun/star/animations/XAnimateColor.hpp>
38 #include <com/sun/star/animations/XAnimateSet.hpp>
39 #include <com/sun/star/animations/XAnimateTransform.hpp>
40 #include <com/sun/star/animations/AnimationTransformType.hpp>
41 #include <com/sun/star/animations/AnimationCalcMode.hpp>
42 #include <com/sun/star/animations/AnimationColorSpace.hpp>
43 #include <com/sun/star/animations/AnimationNodeType.hpp>
44 #include <com/sun/star/animations/XCommand.hpp>
45 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
46 #include <com/sun/star/presentation/EffectCommands.hpp>
47 #include <com/sun/star/beans/NamedValue.hpp>
48 
49 #include "oox/helper/attributelist.hxx"
50 #include "oox/core/xmlfilterbase.hxx"
51 #include "oox/drawingml/drawingmltypes.hxx"
52 #include "oox/drawingml/colorchoicecontext.hxx"
53 #include "oox/ppt/slidetransition.hxx"
54 
55 #include "animvariantcontext.hxx"
56 #include "commonbehaviorcontext.hxx"
57 #include "conditioncontext.hxx"
58 #include "commontimenodecontext.hxx"
59 #include "timeanimvaluecontext.hxx"
60 #include "animationtypes.hxx"
61 
62 using namespace ::oox::core;
63 using namespace ::oox::drawingml;
64 using namespace ::com::sun::star::uno;
65 using namespace ::com::sun::star::lang;
66 using namespace ::com::sun::star::animations;
67 using namespace ::com::sun::star::presentation;
68 using namespace ::com::sun::star::xml::sax;
69 using namespace ::com::sun::star::awt;
70 using ::com::sun::star::beans::NamedValue;
71 
72 using ::rtl::OUString;
73 
74 namespace oox { namespace ppt {
75 
76     struct AnimColor
77     {
78         AnimColor(sal_Int16 cs, sal_Int32 o, sal_Int32 t, sal_Int32 th )
79             : colorSpace( cs ), one( o ), two( t ), three( th )
80             {
81             }
82 
83         sal_Int32 get()
84             {
85                 sal_Int32 nColor;
86 
87                 switch( colorSpace )
88                 {
89                 case AnimationColorSpace::HSL:
90                     nColor = ( ( ( one * 128 ) / 360 ) & 0xff ) << 16
91                         | ( ( ( two * 128 ) / 1000 ) & 0xff ) << 8
92                         | ( ( ( three * 128 ) / 1000 )  & 0xff );
93                     break;
94                 case AnimationColorSpace::RGB:
95                     nColor = ( ( ( one * 128 ) / 1000 ) & 0xff ) << 16
96                         | ( ( ( two * 128 ) / 1000 ) & 0xff ) << 8
97                         | ( ( ( three * 128 ) / 1000 )  & 0xff );
98                     break;
99                 default:
100                     nColor = 0;
101                     break;
102                 }
103                 return  nColor;
104             }
105 
106         sal_Int16 colorSpace;
107         sal_Int32 one;
108         sal_Int32 two;
109         sal_Int32 three;
110     };
111 
112 
113     /** CT_TLMediaNodeAudio
114             CT_TLMediaNodeVideo */
115     class MediaNodeContext
116         : public TimeNodeContext
117     {
118     public:
119         MediaNodeContext( ContextHandler& rParent, sal_Int32  aElement,
120                             const Reference< XFastAttributeList >& xAttribs,
121                             const TimeNodePtr & pNode )
122             : TimeNodeContext( rParent, aElement, xAttribs, pNode )
123                 , mbIsNarration( false )
124                 , mbFullScrn( false )
125             {
126                 AttributeList attribs( xAttribs );
127 
128                 switch( aElement )
129                 {
130                 case PPT_TOKEN( audio ):
131                     mbIsNarration = attribs.getBool( XML_isNarration, false );
132                     break;
133                 case PPT_TOKEN( video ):
134                     mbFullScrn = attribs.getBool( XML_fullScrn, false );
135                     break;
136                 default:
137                     break;
138                 }
139             }
140 
141         virtual void SAL_CALL endFastElement( sal_Int32 aElement )
142             throw ( SAXException, RuntimeException)
143             {
144                 if( aElement == PPT_TOKEN( audio ) )
145                 {
146                     // TODO deal with mbIsNarration
147                 }
148                 else if( aElement == PPT_TOKEN( video ) )
149                 {
150                     // TODO deal with mbFullScrn
151                 }
152             }
153 
154         virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken,
155                                                                                                                                                             const Reference< XFastAttributeList >& xAttribs )
156             throw ( SAXException, RuntimeException )
157             {
158                 Reference< XFastContextHandler > xRet;
159 
160                 switch ( aElementToken )
161                 {
162                 case PPT_TOKEN( cBhvr ):
163                     xRet.set( new CommonBehaviorContext ( *this, xAttribs, mpNode ) );
164                     break;
165                 default:
166                     break;
167                 }
168 
169                 if( !xRet.is() )
170                     xRet.set( this );
171 
172                 return xRet;
173             }
174 
175     private:
176         bool mbIsNarration;
177         bool mbFullScrn;
178     };
179 
180 
181     /** CT_TLSetBehavior
182      */
183     class SetTimeNodeContext
184         : public TimeNodeContext
185     {
186     public:
187         SetTimeNodeContext( ContextHandler& rParent, sal_Int32  aElement,
188                             const Reference< XFastAttributeList >& xAttribs,
189                             const TimeNodePtr & pNode )
190             : TimeNodeContext( rParent, aElement, xAttribs, pNode )
191             {
192 
193             }
194 
195         ~SetTimeNodeContext() throw ()
196             {
197                 if( maTo.hasValue() )
198                 {
199                     // TODO
200                     // HACK !!! discard and refactor
201                     OUString aString;
202                     if( maTo >>= aString )
203                     {
204                         OSL_TRACE( "Magic conversion %s", OUSTRING_TO_CSTR( aString ) );
205                         maTo = makeAny( aString.equalsAscii( "visible" ) ? sal_True : sal_False );
206                         if( !maTo.has<sal_Bool>() )
207                             OSL_TRACE( "conversion failed" );
208                     }
209                     mpNode->setTo( maTo );
210                 }
211 
212             }
213 
214         virtual void SAL_CALL endFastElement( sal_Int32 /*aElement*/ )
215             throw ( SAXException, RuntimeException)
216             {
217             }
218 
219 
220         virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken,
221                                                                                                                                                             const Reference< XFastAttributeList >& xAttribs )
222             throw ( SAXException, RuntimeException )
223             {
224                 Reference< XFastContextHandler > xRet;
225 
226                 switch ( aElementToken )
227                 {
228                 case PPT_TOKEN( cBhvr ):
229                     xRet.set( new CommonBehaviorContext ( *this, xAttribs, mpNode ) );
230                     break;
231                 case PPT_TOKEN( to ):
232                     // CT_TLAnimVariant
233                     xRet.set( new AnimVariantContext( *this, aElementToken, maTo ) );
234                     break;
235                 default:
236                     break;
237                 }
238 
239                 if( !xRet.is() )
240                     xRet.set( this );
241 
242                 return xRet;
243             }
244     private:
245         Any  maTo;
246     };
247 
248     /** CT_TLCommandBehavior
249      */
250     class CmdTimeNodeContext
251         : public TimeNodeContext
252     {
253     public:
254         CmdTimeNodeContext( ContextHandler& rParent, sal_Int32  aElement,
255                             const Reference< XFastAttributeList >& xAttribs,
256                             const TimeNodePtr & pNode )
257             : TimeNodeContext( rParent, aElement, xAttribs, pNode )
258                 , maType(0)
259             {
260                 switch ( aElement )
261                 {
262                 case PPT_TOKEN( cmd ):
263                     msCommand = xAttribs->getOptionalValue( XML_cmd );
264                     maType = xAttribs->getOptionalValueToken( XML_type, 0 );
265                     break;
266                 default:
267                     break;
268                 }
269             }
270 
271         ~CmdTimeNodeContext() throw ()
272             {
273             }
274 
275         virtual void SAL_CALL endFastElement( sal_Int32 aElement )
276             throw ( SAXException, RuntimeException)
277             {
278                 if( aElement == PPT_TOKEN( cmd ) )
279                 {
280                     try {
281                         // see sd/source/filter/ppt/pptinanimations.cxx
282                         // in AnimationImporter::importCommandContainer()
283                         // REFACTOR?
284                         // a good chunk of this code has been copied verbatim *sigh*
285                         sal_Int16 nCommand = EffectCommands::CUSTOM;
286                         NamedValue aParamValue;
287 
288                         switch( maType )
289                         {
290                         case XML_verb:
291                             aParamValue.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("Verb"));
292                             // TODO make sure msCommand has what we want
293                             aParamValue.Value <<= msCommand.toInt32();
294                             nCommand = EffectCommands::VERB;
295                             break;
296                         case XML_evt:
297                         case XML_call:
298                             if( msCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "onstopaudio" ) ) )
299                             {
300                                 nCommand = EffectCommands::STOPAUDIO;
301                             }
302                             else if( msCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("play") ) )
303                             {
304                                 nCommand = EffectCommands::PLAY;
305                             }
306                             else if( msCommand.compareToAscii( RTL_CONSTASCII_STRINGPARAM("playFrom") ) == 0 )
307                             {
308                                 const OUString aMediaTime( msCommand.copy( 9, msCommand.getLength() - 10 ) );
309                                 rtl_math_ConversionStatus eStatus;
310                                 double fMediaTime = ::rtl::math::stringToDouble( aMediaTime, (sal_Unicode)('.'), (sal_Unicode)(','), &eStatus, NULL );
311                                 if( eStatus == rtl_math_ConversionStatus_Ok )
312                                 {
313                                     aParamValue.Name = CREATE_OUSTRING("MediaTime");
314                                     aParamValue.Value <<= fMediaTime;
315                                 }
316                                 nCommand = EffectCommands::PLAY;
317                             }
318                             else if( msCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("togglePause") ) )
319                             {
320                                 nCommand = EffectCommands::TOGGLEPAUSE;
321                             }
322                             else if( msCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("stop") ) )
323                             {
324                                 nCommand = EffectCommands::STOP;
325                             }
326                             break;
327                         }
328                         mpNode->getNodeProperties()[ NP_COMMAND ] = makeAny((sal_Int16)nCommand);
329                         if( nCommand == EffectCommands::CUSTOM )
330                         {
331                             OSL_TRACE("OOX: CmdTimeNodeContext::endFastElement(), unknown command!");
332                             aParamValue.Name = CREATE_OUSTRING("UserDefined");
333                             aParamValue.Value <<= msCommand;
334                         }
335                         if( aParamValue.Value.hasValue() )
336                         {
337                             Sequence< NamedValue > aParamSeq( &aParamValue, 1 );
338                             mpNode->getNodeProperties()[ NP_PARAMETER ] = makeAny( aParamSeq );
339                         }
340                     }
341                     catch( RuntimeException& )
342                     {
343                         OSL_TRACE( "OOX: Exception in CmdTimeNodeContext::endFastElement()" );
344                     }
345                 }
346             }
347 
348 
349         virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken,
350                                                                                                                                                             const Reference< XFastAttributeList >& xAttribs )
351             throw ( SAXException, RuntimeException )
352             {
353                 Reference< XFastContextHandler > xRet;
354 
355                 switch ( aElementToken )
356                 {
357                 case PPT_TOKEN( cBhvr ):
358                     xRet.set( new CommonBehaviorContext ( *this, xAttribs, mpNode ) );
359                     break;
360                 default:
361                     break;
362                 }
363 
364                 if( !xRet.is() )
365                     xRet.set( this );
366 
367                 return xRet;
368             }
369 
370     private:
371         OUString msCommand;
372         sal_Int32 maType;
373     };
374 
375 
376     /** CT_TLTimeNodeSequence
377      */
378     class SequenceTimeNodeContext
379         : public TimeNodeContext
380     {
381     public:
382         SequenceTimeNodeContext( ContextHandler& rParent, sal_Int32  aElement,
383                                  const Reference< XFastAttributeList >& xAttribs,
384                                  const TimeNodePtr & pNode )
385             : TimeNodeContext( rParent, aElement, xAttribs, pNode )
386                 , mnNextAc(0)
387                 , mnPrevAc(0)
388             {
389                 AttributeList attribs(xAttribs);
390                 mbConcurrent = attribs.getBool( XML_concurrent, false );
391                 // ST_TLNextActionType { none, seek }
392                 mnNextAc = xAttribs->getOptionalValueToken( XML_nextAc, 0 );
393                 // ST_TLPreviousActionType { none, skipTimed }
394                 mnPrevAc = xAttribs->getOptionalValueToken( XML_prevAc, 0 );
395             }
396 
397         ~SequenceTimeNodeContext() throw()
398             {
399             }
400 
401 
402         virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken,
403                                                                                                                                                             const Reference< XFastAttributeList >& xAttribs )
404             throw ( SAXException, RuntimeException )
405             {
406                 Reference< XFastContextHandler > xRet;
407 
408                 switch ( aElementToken )
409                 {
410                 case PPT_TOKEN( cTn ):
411                     xRet.set( new CommonTimeNodeContext( *this, aElementToken, xAttribs, mpNode ) );
412                     break;
413                 case PPT_TOKEN( nextCondLst ):
414                     xRet.set( new CondListContext( *this, aElementToken, xAttribs, mpNode,
415                                                    mpNode->getNextCondition() ) );
416                     break;
417                 case PPT_TOKEN( prevCondLst ):
418                     xRet.set( new CondListContext( *this, aElementToken, xAttribs, mpNode,
419                                                    mpNode->getPrevCondition() ) );
420                     break;
421                 default:
422                     break;
423                 }
424 
425                 if( !xRet.is() )
426                     xRet.set( this );
427 
428                 return xRet;
429             }
430     private:
431         bool mbConcurrent;
432         sal_Int32 mnNextAc, mnPrevAc;
433     };
434 
435 
436     /** CT_TLTimeNodeParallel
437      *  CT_TLTimeNodeExclusive
438      */
439     class ParallelExclTimeNodeContext
440         : public TimeNodeContext
441     {
442     public:
443         ParallelExclTimeNodeContext( ContextHandler& rParent, sal_Int32  aElement,
444                                      const Reference< XFastAttributeList >& xAttribs,
445                                      const TimeNodePtr & pNode )
446             : TimeNodeContext( rParent, aElement, xAttribs, pNode )
447             {
448             }
449 
450         virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken,
451                                                                                                                                                             const Reference< XFastAttributeList >& xAttribs )
452             throw ( SAXException, RuntimeException )
453             {
454                 Reference< XFastContextHandler > xRet;
455 
456                 switch ( aElementToken )
457                 {
458                 case PPT_TOKEN( cTn ):
459                     xRet.set( new CommonTimeNodeContext( *this, aElementToken, xAttribs, mpNode ) );
460                     break;
461                 default:
462                     break;
463                 }
464 
465                 if( !xRet.is() )
466                     xRet.set( this );
467 
468                 return xRet;
469             }
470 
471     protected:
472 
473     };
474 
475 
476     /** CT_TLAnimateColorBehavior */
477     class AnimColorContext
478         : public TimeNodeContext
479     {
480     public:
481         AnimColorContext( ContextHandler& rParent, sal_Int32  aElement,
482                             const Reference< XFastAttributeList >& xAttribs,
483                             const TimeNodePtr & pNode ) throw()
484             : TimeNodeContext( rParent, aElement, xAttribs, pNode )
485                 // ST_TLAnimateColorSpace ( XML_rgb, XML_hsl }
486             , mnColorSpace( xAttribs->getOptionalValueToken( XML_clrSpc, 0 ) )
487                 // ST_TLAnimateColorDirection { XML_cw, XML_ccw }
488             , mnDir( xAttribs->getOptionalValueToken( XML_dir, 0 ) )
489             , mbHasByColor( false )
490             , m_byColor( AnimationColorSpace::RGB, 0, 0, 0)
491             {
492             }
493         ~AnimColorContext() throw()
494             {
495             }
496 
497         virtual void SAL_CALL endFastElement( sal_Int32 aElement ) throw ( SAXException, RuntimeException)
498             {
499                 //xParentNode
500                 if( aElement == mnElement )
501                 {
502                     NodePropertyMap & pProps(mpNode->getNodeProperties());
503                     pProps[ NP_DIRECTION ] = makeAny( mnDir == XML_cw );
504                     pProps[ NP_COLORINTERPOLATION ] = makeAny( mnColorSpace == XML_hsl ? AnimationColorSpace::HSL : AnimationColorSpace::RGB );
505                     const GraphicHelper& rGraphicHelper = getFilter().getGraphicHelper();
506                     if( maToClr.isUsed() )
507                         mpNode->setTo( Any( maToClr.getColor( rGraphicHelper ) ) );
508                     if( maFromClr.isUsed() )
509                         mpNode->setFrom( Any( maFromClr.getColor( rGraphicHelper ) ) );
510                     if( mbHasByColor )
511                         mpNode->setBy( Any ( m_byColor.get() ) );
512                 }
513             }
514 
515 
516         virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw ( SAXException, RuntimeException )
517             {
518                 Reference< XFastContextHandler > xRet;
519 
520                 switch ( aElementToken )
521                 {
522                 case PPT_TOKEN( hsl ):
523                     // CT_TLByHslColorTransform
524                 {
525                     if( mbHasByColor )
526                     {
527                         m_byColor.colorSpace = AnimationColorSpace::HSL;
528                         m_byColor.one = xAttribs->getOptionalValue( XML_h ).toInt32( );
529                         m_byColor.two = xAttribs->getOptionalValue( XML_s ).toInt32( );
530                         m_byColor.three = xAttribs->getOptionalValue( XML_l ).toInt32( );
531                     }
532                     xRet.set(this);
533                     break;
534                 }
535                 case PPT_TOKEN( rgb ):
536                 {
537                     if( mbHasByColor )
538                     {
539                         // CT_TLByRgbColorTransform
540                         m_byColor.colorSpace = AnimationColorSpace::RGB;
541                         m_byColor.one = xAttribs->getOptionalValue( XML_r ).toInt32();
542                         m_byColor.two = xAttribs->getOptionalValue( XML_g ).toInt32();
543                         m_byColor.three = xAttribs->getOptionalValue( XML_b ).toInt32();
544                     }
545                     xRet.set(this);
546                     break;
547                 }
548                 case PPT_TOKEN( by ):
549                     // CT_TLByAnimateColorTransform
550                     mbHasByColor = true;
551                     xRet.set(this);
552                     break;
553                 case PPT_TOKEN( cBhvr ):
554                     xRet.set( new CommonBehaviorContext ( *this, xAttribs, mpNode ) );
555                     break;
556                 case PPT_TOKEN( to ):
557                     // CT_Color
558                     xRet.set( new ColorContext( *this, maToClr ) );
559                     break;
560                 case PPT_TOKEN( from ):
561                     // CT_Color
562                     xRet.set( new ColorContext( *this, maFromClr ) );
563                     break;
564 
565                 default:
566                     break;
567                 }
568 
569                 if( !xRet.is() )
570                     xRet.set( this );
571 
572                 return xRet;
573             }
574 
575 
576     private:
577         sal_Int32 mnColorSpace;
578         sal_Int32 mnDir;
579         bool mbHasByColor;
580         AnimColor m_byColor;
581         oox::drawingml::Color maToClr;
582         oox::drawingml::Color maFromClr;
583     };
584 
585 
586     /** CT_TLAnimateBehavior */
587     class AnimContext
588         : public TimeNodeContext
589     {
590     public:
591         AnimContext( ContextHandler& rParent, sal_Int32  aElement,
592                      const Reference< XFastAttributeList >& xAttribs,
593                       const TimeNodePtr & pNode ) throw()
594             : TimeNodeContext( rParent, aElement, xAttribs, pNode )
595             {
596                 NodePropertyMap & aProps( pNode->getNodeProperties() );
597                 sal_Int32 nCalcMode = xAttribs->getOptionalValueToken( XML_calcmode, 0 );
598                 if(nCalcMode)
599                 {
600                     sal_Int16 nEnum = 0;
601                     switch(nCalcMode)
602                     {
603                     case XML_discrete:
604                         nEnum = AnimationCalcMode::DISCRETE;
605                         break;
606                     case XML_lin:
607                         nEnum = AnimationCalcMode::LINEAR;
608                         break;
609                     case XML_fmla:
610                     default:
611                         // TODO what value is good ?
612                         nEnum = AnimationCalcMode::DISCRETE;
613                         break;
614                     }
615                     aProps[ NP_CALCMODE ] = makeAny(nEnum);
616                 }
617                 OUString aStr;
618                 aStr = xAttribs->getOptionalValue( XML_from );
619                 if( aStr.getLength() )
620                 {
621                     pNode->setFrom( makeAny( aStr ) );
622                 }
623                 aStr = xAttribs->getOptionalValue( XML_by );
624                 if( aStr.getLength() )
625                 {
626                     pNode->setBy( makeAny( aStr ) );
627                 }
628                 aStr = xAttribs->getOptionalValue( XML_to );
629                 if( aStr.getLength() )
630                 {
631                     pNode->setTo( makeAny( aStr ) );
632                 }
633                 mnValueType = xAttribs->getOptionalValueToken( XML_valueType, 0 );
634             }
635 
636 
637         ~AnimContext() throw ()
638             {
639                 ::std::list< TimeAnimationValue >::iterator iter, end;
640                 int nKeyTimes = maTavList.size();
641                 if( nKeyTimes > 0)
642                 {
643                     int i;
644                     Sequence< double > aKeyTimes( nKeyTimes );
645                     Sequence< Any > aValues( nKeyTimes );
646 
647                     NodePropertyMap & aProps( mpNode->getNodeProperties() );
648                     end = maTavList.end();
649                     for(iter = maTavList.begin(), i=0; iter != end; iter++,i++)
650                     {
651                         // TODO what to do if it is Timing_INFINITE ?
652                         Any aTime = GetTimeAnimateValueTime( iter->msTime );
653                         aTime >>= aKeyTimes[i];
654                         aValues[i] = iter->maValue;
655 
656                         OUString aTest;
657                         iter->maValue >>= aTest;
658                         if( aTest.getLength() != 0 )
659                         {
660                             aValues[i] = iter->maValue;
661                         }
662                         else
663                         {
664                             aProps[ NP_FORMULA ] <<= iter->msFormula;
665                         }
666                     }
667                     aProps[ NP_VALUES ] <<= aValues;
668                     aProps[ NP_KEYTIMES ] <<= aKeyTimes;
669                 }
670             }
671 
672 
673         virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw ( SAXException, RuntimeException )
674             {
675                 Reference< XFastContextHandler > xRet;
676 
677                 switch ( aElementToken )
678                 {
679                 case PPT_TOKEN( cBhvr ):
680                     xRet.set( new CommonBehaviorContext ( *this, xAttribs, mpNode ) );
681                     break;
682                 case PPT_TOKEN( tavLst ):
683                     xRet.set( new TimeAnimValueListContext ( *this, xAttribs, maTavList ) );
684                     break;
685                 default:
686                     break;
687                 }
688 
689                 if( !xRet.is() )
690                     xRet.set( this );
691 
692                 return xRet;
693             }
694     private:
695         sal_Int32              mnValueType;
696         TimeAnimationValueList maTavList;
697     };
698 
699 
700     /** CT_TLAnimateScaleBehavior */
701     class AnimScaleContext
702         : public TimeNodeContext
703     {
704     public:
705         AnimScaleContext( ContextHandler& rParent, sal_Int32  aElement,
706                             const Reference< XFastAttributeList >& xAttribs,
707                             const TimeNodePtr & pNode ) throw()
708             : TimeNodeContext( rParent, aElement, xAttribs, pNode )
709                 , mbZoomContents( false )
710             {
711                 AttributeList attribs( xAttribs );
712                 // TODO what to do with mbZoomContents
713                 mbZoomContents = attribs.getBool( XML_zoomContents, false );
714                 pNode->getNodeProperties()[ NP_TRANSFORMTYPE ]
715                     = makeAny((sal_Int16)AnimationTransformType::SCALE);
716             }
717 
718         ~AnimScaleContext( ) throw( )
719             {
720             }
721 
722         virtual void SAL_CALL endFastElement( sal_Int32 aElement ) throw ( SAXException, RuntimeException)
723             {
724                 if( aElement == mnElement )
725                 {
726                     if( maTo.hasValue() )
727                     {
728                         mpNode->setTo( maTo );
729                     }
730                     if( maBy.hasValue() )
731                     {
732                         mpNode->setBy( maBy );
733                     }
734                     if( maFrom.hasValue() )
735                     {
736                         mpNode->setFrom( maFrom );
737                     }
738                 }
739             }
740 
741         virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken,
742                                                                                                                                                             const Reference< XFastAttributeList >& xAttribs )
743             throw ( SAXException, RuntimeException )
744             {
745                 Reference< XFastContextHandler > xRet;
746 
747                 switch ( aElementToken )
748                 {
749                 case PPT_TOKEN( cBhvr ):
750                     xRet.set( new CommonBehaviorContext ( *this, xAttribs, mpNode ) );
751                     break;
752                 case PPT_TOKEN( to ):
753                 {
754                     // CT_TLPoint
755                     Point p = GetPointPercent( xAttribs );
756                     maTo <<= p.X;
757                     maTo <<= p.Y;
758                     break;
759                 }
760                 case PPT_TOKEN( from ):
761                 {
762                     // CT_TLPoint
763                     Point p = GetPointPercent( xAttribs );
764                     maFrom <<= p.X;
765                     maFrom <<= p.Y;
766                     break;
767                 }
768                 case PPT_TOKEN( by ):
769                 {
770                     // CT_TLPoint
771                     Point p = GetPointPercent( xAttribs );
772                     maBy <<= p.X;
773                     maBy <<= p.Y;
774                     break;
775                 }
776                 default:
777                     break;
778                 }
779 
780                 if( !xRet.is() )
781                     xRet.set( this );
782 
783                 return xRet;
784             }
785     private:
786         Any maBy;
787         Any maFrom;
788         Any maTo;
789         bool mbZoomContents;
790     };
791 
792 
793     /** CT_TLAnimateRotationBehavior */
794     class AnimRotContext
795         : public TimeNodeContext
796     {
797     public:
798         AnimRotContext( ContextHandler& rParent, sal_Int32  aElement,
799                         const Reference< XFastAttributeList >& xAttribs,
800                          const TimeNodePtr & pNode ) throw()
801             : TimeNodeContext( rParent, aElement, xAttribs, pNode )
802             {
803                 AttributeList attribs( xAttribs );
804 
805                 pNode->getNodeProperties()[ NP_TRANSFORMTYPE ]
806                     = makeAny((sal_Int16)AnimationTransformType::ROTATE);
807                 // TODO make sure the units are OK
808                 if(attribs.hasAttribute( XML_by ) )
809                 {
810                     sal_Int32 nBy = attribs.getInteger( XML_by, 0 );
811                     pNode->setBy( makeAny( nBy ) );
812                 }
813                 if(attribs.hasAttribute( XML_from ) )
814                 {
815                     sal_Int32 nFrom = attribs.getInteger( XML_from, 0 );
816                     pNode->setFrom( makeAny( nFrom ) );
817                 }
818                 if(attribs.hasAttribute( XML_to ) )
819                 {
820                     sal_Int32 nTo = attribs.getInteger( XML_to, 0 );
821                     pNode->setTo( makeAny( nTo ) );
822                 }
823             }
824 
825         ~AnimRotContext( ) throw( )
826             {
827             }
828 
829         virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw ( SAXException, RuntimeException )
830             {
831                 Reference< XFastContextHandler > xRet;
832 
833                 switch ( aElementToken )
834                 {
835                 case PPT_TOKEN( cBhvr ):
836                     xRet.set( new CommonBehaviorContext ( *this, xAttribs, mpNode ) );
837                     break;
838                 default:
839                     break;
840                 }
841 
842                 if( !xRet.is() )
843                     xRet.set( this );
844 
845                 return xRet;
846             }
847     };
848 
849 
850 
851     /** CT_TLAnimateMotionBehavior */
852     class AnimMotionContext
853         : public TimeNodeContext
854     {
855     public:
856         AnimMotionContext( ContextHandler& rParent, sal_Int32  aElement,
857                          const Reference< XFastAttributeList >& xAttribs,
858                           const TimeNodePtr & pNode ) throw()
859             : TimeNodeContext( rParent, aElement, xAttribs, pNode )
860             {
861                 pNode->getNodeProperties()[ NP_TRANSFORMTYPE ]
862                     = makeAny((sal_Int16)AnimationTransformType::TRANSLATE);
863 
864                 AttributeList attribs( xAttribs );
865                 // ST_TLAnimateMotionBehaviorOrigin { parent, layour }
866                 sal_Int32 nOrigin = xAttribs->getOptionalValueToken( XML_origin, 0 );
867                 if( nOrigin != 0 )
868                 {
869                     switch(nOrigin)
870                     {
871                     case XML_layout:
872                     case XML_parent:
873                         break;
874                     }
875                     // TODO
876                 }
877 
878                 OUString aStr = xAttribs->getOptionalValue( XML_path );
879                 aStr = aStr.replace( 'E', ' ' );
880                 aStr = aStr.trim();
881                 pNode->getNodeProperties()[ NP_PATH ] = makeAny(aStr);
882 
883                 // ST_TLAnimateMotionPathEditMode{ fixed, relative }
884                 mnPathEditMode = xAttribs->getOptionalValueToken( XML_pathEditMode, 0 );
885                 msPtsTypes = xAttribs->getOptionalValue( XML_ptsTypes );
886                 mnAngle = attribs.getInteger( XML_rAng, 0 );
887                 // TODO make sure the units are right. Likely not.
888             }
889 
890         ~AnimMotionContext( ) throw()
891             {
892             }
893 
894 
895         virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken,
896                                                                                                                                                             const Reference< XFastAttributeList >& xAttribs )
897             throw ( SAXException, RuntimeException )
898             {
899                 Reference< XFastContextHandler > xRet;
900 
901                 switch ( aElementToken )
902                 {
903                 case PPT_TOKEN( cBhvr ):
904                     xRet.set( new CommonBehaviorContext ( *this, xAttribs, mpNode ) );
905                     break;
906                 case PPT_TOKEN( to ):
907                 {
908                     // CT_TLPoint
909                     Point p = GetPointPercent( xAttribs );
910                     Any rAny;
911                     rAny <<= p.X;
912                     rAny <<= p.Y;
913                     mpNode->setTo( rAny );
914                     break;
915                 }
916                 case PPT_TOKEN( from ):
917                 {
918                     // CT_TLPoint
919                     Point p = GetPointPercent( xAttribs );
920                     Any rAny;
921                     rAny <<= p.X;
922                     rAny <<= p.Y;
923                     mpNode->setFrom( rAny );
924                     break;
925                 }
926                 case PPT_TOKEN( by ):
927                 {
928                     // CT_TLPoint
929                     Point p = GetPointPercent( xAttribs );
930                     Any rAny;
931                     rAny <<= p.X;
932                     rAny <<= p.Y;
933                     mpNode->setBy( rAny );
934                     break;
935                 }
936                 case PPT_TOKEN( rCtr ):
937                 {
938                     // CT_TLPoint
939                     Point p = GetPointPercent( xAttribs );
940                     // TODO push
941                     break;
942                 }
943                 default:
944                     break;
945                 }
946 
947                 if( !xRet.is() )
948                     xRet.set( this );
949 
950                 return xRet;
951             }
952     private:
953         OUString msPtsTypes;
954         sal_Int32 mnPathEditMode;
955         sal_Int32 mnAngle;
956     };
957 
958 
959     /** CT_TLAnimateEffectBehavior */
960     class AnimEffectContext
961         : public TimeNodeContext
962     {
963     public:
964         AnimEffectContext( ContextHandler& rParent, sal_Int32  aElement,
965                              const Reference< XFastAttributeList >& xAttribs,
966                              const TimeNodePtr & pNode ) throw()
967             : TimeNodeContext( rParent, aElement, xAttribs, pNode )
968             {
969                 sal_Int32 nDir = xAttribs->getOptionalValueToken( XML_transition, 0 );
970                 OUString sFilter = xAttribs->getOptionalValue( XML_filter );
971                 // TODO
972 //              OUString sPrList = xAttribs->getOptionalValue( XML_prLst );
973 
974                 if( sFilter.getLength() )
975                 {
976                     SlideTransition aFilter( sFilter );
977                     aFilter.setMode( nDir == XML_out ? false : true );
978                     pNode->setTransitionFilter( aFilter );
979                 }
980             }
981 
982 
983         ~AnimEffectContext( ) throw()
984             {
985             }
986 
987 
988         virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw ( SAXException, RuntimeException )
989             {
990                 Reference< XFastContextHandler > xRet;
991 
992                 switch ( aElementToken )
993                 {
994                 case PPT_TOKEN( cBhvr ):
995                     xRet.set( new CommonBehaviorContext ( *this, xAttribs, mpNode ) );
996                     break;
997                 case PPT_TOKEN( progress ):
998                     xRet.set( new AnimVariantContext( *this, aElementToken, maProgress ) );
999                     // TODO handle it.
1000                     break;
1001                 default:
1002                     break;
1003                 }
1004 
1005                 if( !xRet.is() )
1006                     xRet.set( this );
1007 
1008                 return xRet;
1009             }
1010     private:
1011         Any maProgress;
1012         OUString msFilter;
1013         OUString msPrList;
1014     };
1015 
1016 
1017 
1018     TimeNodeContext * TimeNodeContext::makeContext(
1019             ContextHandler& rParent, sal_Int32  aElement,
1020             const Reference< XFastAttributeList >& xAttribs,
1021             const TimeNodePtr & pNode )
1022     {
1023         TimeNodeContext *pCtx = NULL;
1024         switch( aElement )
1025         {
1026         case PPT_TOKEN( animClr ):
1027             pCtx = new AnimColorContext( rParent, aElement, xAttribs, pNode );
1028             break;
1029         case PPT_TOKEN( par ):
1030             pCtx = new ParallelExclTimeNodeContext( rParent, aElement, xAttribs, pNode );
1031             break;
1032         case PPT_TOKEN( seq ):
1033             pCtx = new SequenceTimeNodeContext( rParent, aElement, xAttribs, pNode );
1034             break;
1035         case PPT_TOKEN( excl ):
1036             pCtx = new ParallelExclTimeNodeContext( rParent, aElement, xAttribs, pNode );
1037             break;
1038         case PPT_TOKEN( anim ):
1039             pCtx = new AnimContext ( rParent, aElement, xAttribs, pNode );
1040             break;
1041         case PPT_TOKEN( animEffect ):
1042             pCtx = new AnimEffectContext( rParent, aElement, xAttribs, pNode );
1043             break;
1044         case PPT_TOKEN( animMotion ):
1045             pCtx = new AnimMotionContext( rParent, aElement, xAttribs, pNode );
1046             break;
1047         case PPT_TOKEN( animRot ):
1048             pCtx = new AnimRotContext( rParent, aElement, xAttribs, pNode );
1049             break;
1050         case PPT_TOKEN( animScale ):
1051             pCtx = new AnimScaleContext( rParent, aElement, xAttribs, pNode );
1052             break;
1053         case PPT_TOKEN( cmd ):
1054             pCtx = new CmdTimeNodeContext( rParent, aElement, xAttribs, pNode );
1055             break;
1056         case PPT_TOKEN( set ):
1057             pCtx = new SetTimeNodeContext( rParent, aElement, xAttribs, pNode );
1058             break;
1059         case PPT_TOKEN( audio ):
1060         case PPT_TOKEN( video ):
1061             pCtx = new MediaNodeContext( rParent, aElement, xAttribs, pNode );
1062             break;
1063         default:
1064             break;
1065         }
1066         return pCtx;
1067     }
1068 
1069 
1070     TimeNodeContext::TimeNodeContext( ContextHandler& rParent, sal_Int32 aElement,
1071             const Reference< XFastAttributeList >& /*xAttribs*/,
1072             const TimeNodePtr & pNode ) throw()
1073         : ContextHandler( rParent )
1074         , mnElement( aElement )
1075         , mpNode( pNode )
1076     {
1077     }
1078 
1079 
1080     TimeNodeContext::~TimeNodeContext( ) throw()
1081     {
1082 
1083     }
1084 
1085 
1086     TimeNodeListContext::TimeNodeListContext( ContextHandler& rParent, TimeNodePtrList & aList )
1087         throw()
1088         : ContextHandler( rParent )
1089             , maList( aList )
1090     {
1091     }
1092 
1093 
1094     TimeNodeListContext::~TimeNodeListContext( ) throw()
1095     {
1096     }
1097 
1098 
1099     Reference< XFastContextHandler > SAL_CALL TimeNodeListContext::createFastChildContext( ::sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException)
1100     {
1101         Reference< XFastContextHandler > xRet;
1102 
1103         sal_Int16 nNodeType;
1104 
1105         switch( aElementToken )
1106         {
1107         case PPT_TOKEN( par ):
1108             nNodeType = AnimationNodeType::PAR;
1109             break;
1110         case PPT_TOKEN( seq ):
1111             nNodeType = AnimationNodeType::SEQ;
1112             break;
1113         case PPT_TOKEN( excl ):
1114             // TODO pick the right type. We choose parallel for now as
1115             // there does not seem to be an "Exclusive"
1116             nNodeType = AnimationNodeType::PAR;
1117             break;
1118         case PPT_TOKEN( anim ):
1119             nNodeType = AnimationNodeType::ANIMATE;
1120             break;
1121         case PPT_TOKEN( animClr ):
1122             nNodeType = AnimationNodeType::ANIMATECOLOR;
1123             break;
1124         case PPT_TOKEN( animEffect ):
1125             nNodeType = AnimationNodeType::TRANSITIONFILTER;
1126             break;
1127         case PPT_TOKEN( animMotion ):
1128             nNodeType = AnimationNodeType::ANIMATEMOTION;
1129             break;
1130         case PPT_TOKEN( animRot ):
1131         case PPT_TOKEN( animScale ):
1132             nNodeType = AnimationNodeType::ANIMATETRANSFORM;
1133             break;
1134         case PPT_TOKEN( cmd ):
1135             nNodeType = AnimationNodeType::COMMAND;
1136             break;
1137         case PPT_TOKEN( set ):
1138             nNodeType = AnimationNodeType::SET;
1139             break;
1140         case PPT_TOKEN( audio ):
1141             nNodeType = AnimationNodeType::AUDIO;
1142             break;
1143         case PPT_TOKEN( video ):
1144             nNodeType = AnimationNodeType::AUDIO;
1145             OSL_TRACE( "OOX: video requested, gave Audio instead" );
1146             break;
1147 
1148         default:
1149             nNodeType = AnimationNodeType::CUSTOM;
1150             OSL_TRACE( "OOX: uhandled token %x", aElementToken );
1151             break;
1152         }
1153 
1154         TimeNodePtr pNode(new TimeNode(nNodeType));
1155         maList.push_back( pNode );
1156         ContextHandler * pContext = TimeNodeContext::makeContext( *this, aElementToken, xAttribs, pNode );
1157         xRet.set( pContext ? pContext : this );
1158 
1159         return xRet;
1160     }
1161 
1162 
1163 } }
1164