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