bump product version to 5.0.4.1
[LibreOffice.git] / oox / source / ppt / timenodelistcontext.cxx
blobb6d978e1ac96df65768559ff28e54789e197a755
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "oox/ppt/timenodelistcontext.hxx"
22 #include "comphelper/anytostring.hxx"
23 #include "cppuhelper/exc_hlp.hxx"
24 #include <osl/diagnose.h>
25 #include <rtl/math.hxx>
27 #include <com/sun/star/animations/XTimeContainer.hpp>
28 #include <com/sun/star/animations/XAnimationNode.hpp>
29 #include <com/sun/star/animations/XAnimateColor.hpp>
30 #include <com/sun/star/animations/XAnimateSet.hpp>
31 #include <com/sun/star/animations/XAnimateTransform.hpp>
32 #include <com/sun/star/animations/AnimationTransformType.hpp>
33 #include <com/sun/star/animations/AnimationCalcMode.hpp>
34 #include <com/sun/star/animations/AnimationColorSpace.hpp>
35 #include <com/sun/star/animations/AnimationNodeType.hpp>
36 #include <com/sun/star/animations/XCommand.hpp>
37 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
38 #include <com/sun/star/presentation/EffectCommands.hpp>
39 #include <com/sun/star/beans/NamedValue.hpp>
41 #include "oox/helper/attributelist.hxx"
42 #include "oox/core/xmlfilterbase.hxx"
43 #include "oox/drawingml/drawingmltypes.hxx"
44 #include "drawingml/colorchoicecontext.hxx"
45 #include "oox/ppt/slidetransition.hxx"
47 #include "animvariantcontext.hxx"
48 #include "commonbehaviorcontext.hxx"
49 #include "conditioncontext.hxx"
50 #include "commontimenodecontext.hxx"
51 #include "timeanimvaluecontext.hxx"
52 #include "animationtypes.hxx"
54 using namespace ::oox::core;
55 using namespace ::oox::drawingml;
56 using namespace ::com::sun::star;
57 using namespace ::com::sun::star::uno;
58 using namespace ::com::sun::star::lang;
59 using namespace ::com::sun::star::animations;
60 using namespace ::com::sun::star::presentation;
61 using namespace ::com::sun::star::xml::sax;
62 using ::com::sun::star::beans::NamedValue;
64 namespace oox { namespace ppt {
66 struct AnimColor
68 AnimColor(sal_Int16 cs, sal_Int32 o, sal_Int32 t, sal_Int32 th )
69 : colorSpace( cs ), one( o ), two( t ), three( th )
73 Any get()
75 sal_Int32 nColor;
76 Sequence< double > aHSL( 3 );
77 Any aColor;
79 switch( colorSpace )
81 case AnimationColorSpace::HSL:
82 aHSL[ 0 ] = double(one) / 100000;
83 aHSL[ 1 ] = double(two) / 100000;
84 aHSL[ 2 ] = double(three) / 100000;
85 aColor = Any(aHSL);
86 break;
87 case AnimationColorSpace::RGB:
88 nColor = ( ( ( one * 128 ) / 1000 ) & 0xff ) << 16
89 | ( ( ( two * 128 ) / 1000 ) & 0xff ) << 8
90 | ( ( ( three * 128 ) / 1000 ) & 0xff );
91 aColor = Any(nColor);
92 break;
93 default:
94 nColor = 0;
95 aColor = Any( nColor );
96 break;
98 return aColor;
101 sal_Int16 colorSpace;
102 sal_Int32 one;
103 sal_Int32 two;
104 sal_Int32 three;
107 /** CT_TLMediaNodeAudio
108 CT_TLMediaNodeVideo */
109 class MediaNodeContext
110 : public TimeNodeContext
112 public:
113 MediaNodeContext( FragmentHandler2& rParent, sal_Int32 aElement,
114 const Reference< XFastAttributeList >& xAttribs,
115 const TimeNodePtr & pNode )
116 : TimeNodeContext( rParent, aElement, xAttribs, pNode )
117 , mbIsNarration( false )
118 , mbFullScrn( false )
120 AttributeList attribs( xAttribs );
122 switch( aElement )
124 case PPT_TOKEN( audio ):
125 mbIsNarration = attribs.getBool( XML_isNarration, false );
126 break;
127 case PPT_TOKEN( video ):
128 mbFullScrn = attribs.getBool( XML_fullScrn, false );
129 break;
130 default:
131 break;
135 virtual void onEndElement() SAL_OVERRIDE
137 sal_Int32 aElement = getCurrentElement();
138 if( aElement == PPT_TOKEN( audio ) )
140 // TODO deal with mbIsNarration
142 else if( aElement == PPT_TOKEN( video ) )
144 // TODO deal with mbFullScrn
148 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) SAL_OVERRIDE
150 switch ( aElementToken )
152 case PPT_TOKEN( cBhvr ):
153 return new CommonBehaviorContext ( *this, rAttribs.getFastAttributeList(), mpNode );
154 default:
155 break;
158 return this;
161 private:
162 bool mbIsNarration;
163 bool mbFullScrn;
166 /** CT_TLSetBehavior
168 class SetTimeNodeContext
169 : public TimeNodeContext
171 public:
172 SetTimeNodeContext( FragmentHandler2& rParent, sal_Int32 aElement,
173 const Reference< XFastAttributeList >& xAttribs,
174 const TimeNodePtr & pNode )
175 : TimeNodeContext( rParent, aElement, xAttribs, pNode )
180 virtual ~SetTimeNodeContext() throw ()
182 if( maTo.hasValue() )
184 // TODO
185 // HACK !!! discard and refactor
186 OUString aString;
187 if( maTo >>= aString )
189 OSL_TRACE( "Magic conversion %s", OUSTRING_TO_CSTR( aString ) );
190 maTo = makeAny( aString == "visible" ? sal_True : sal_False );
191 if( !maTo.has<sal_Bool>() )
192 OSL_TRACE( "conversion failed" );
194 mpNode->setTo( maTo );
199 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) SAL_OVERRIDE
201 switch ( aElementToken )
203 case PPT_TOKEN( cBhvr ):
204 return new CommonBehaviorContext ( *this, rAttribs.getFastAttributeList(), mpNode );
205 case PPT_TOKEN( to ):
206 // CT_TLAnimVariant
207 return new AnimVariantContext( *this, aElementToken, maTo );
208 default:
209 break;
212 return this;
214 private:
215 Any maTo;
218 /** CT_TLCommandBehavior
220 class CmdTimeNodeContext
221 : public TimeNodeContext
223 public:
224 CmdTimeNodeContext( FragmentHandler2& rParent, sal_Int32 aElement,
225 const Reference< XFastAttributeList >& xAttribs,
226 const TimeNodePtr & pNode )
227 : TimeNodeContext( rParent, aElement, xAttribs, pNode )
228 , maType(0)
230 switch ( aElement )
232 case PPT_TOKEN( cmd ):
233 msCommand = xAttribs->getOptionalValue( XML_cmd );
234 maType = xAttribs->getOptionalValueToken( XML_type, 0 );
235 break;
236 default:
237 break;
241 virtual ~CmdTimeNodeContext() throw ()
245 virtual void onEndElement() SAL_OVERRIDE
247 if( isCurrentElement( PPT_TOKEN( cmd ) ) )
249 try {
250 // see sd/source/filter/ppt/pptinanimations.cxx
251 // in AnimationImporter::importCommandContainer()
252 // REFACTOR?
253 // a good chunk of this code has been copied verbatim *sigh*
254 sal_Int16 nCommand = EffectCommands::CUSTOM;
255 NamedValue aParamValue;
257 switch( maType )
259 case XML_verb:
260 aParamValue.Name = "Verb";
261 // TODO make sure msCommand has what we want
262 aParamValue.Value <<= msCommand.toInt32();
263 nCommand = EffectCommands::VERB;
264 break;
265 case XML_evt:
266 case XML_call:
267 if ( msCommand == "onstopaudio" )
269 nCommand = EffectCommands::STOPAUDIO;
271 else if ( msCommand == "play" )
273 nCommand = EffectCommands::PLAY;
275 else if( msCommand == "playFrom" )
277 const OUString aMediaTime( msCommand.copy( 9, msCommand.getLength() - 10 ) );
278 rtl_math_ConversionStatus eStatus;
279 double fMediaTime = ::rtl::math::stringToDouble( aMediaTime, (sal_Unicode)('.'), (sal_Unicode)(','), &eStatus, NULL );
280 if( eStatus == rtl_math_ConversionStatus_Ok )
282 aParamValue.Name = "MediaTime";
283 aParamValue.Value <<= fMediaTime;
285 nCommand = EffectCommands::PLAY;
287 else if ( msCommand == "togglePause" )
289 nCommand = EffectCommands::TOGGLEPAUSE;
291 else if ( msCommand == "stop" )
293 nCommand = EffectCommands::STOP;
295 break;
297 mpNode->getNodeProperties()[ NP_COMMAND ] = makeAny((sal_Int16)nCommand);
298 if( nCommand == EffectCommands::CUSTOM )
300 OSL_TRACE("OOX: CmdTimeNodeContext::endFastElement(), unknown command!");
301 aParamValue.Name = "UserDefined";
302 aParamValue.Value <<= msCommand;
304 if( aParamValue.Value.hasValue() )
306 Sequence< NamedValue > aParamSeq( &aParamValue, 1 );
307 mpNode->getNodeProperties()[ NP_PARAMETER ] = makeAny( aParamSeq );
310 catch( RuntimeException& )
312 OSL_TRACE( "OOX: Exception in CmdTimeNodeContext::endFastElement()" );
317 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) SAL_OVERRIDE
319 switch ( aElementToken )
321 case PPT_TOKEN( cBhvr ):
322 return new CommonBehaviorContext ( *this, rAttribs.getFastAttributeList(), mpNode );
323 default:
324 break;
327 return this;
330 private:
331 OUString msCommand;
332 sal_Int32 maType;
335 /** CT_TLTimeNodeSequence
337 class SequenceTimeNodeContext
338 : public TimeNodeContext
340 public:
341 SequenceTimeNodeContext( FragmentHandler2& rParent, sal_Int32 aElement,
342 const Reference< XFastAttributeList >& xAttribs,
343 const TimeNodePtr & pNode )
344 : TimeNodeContext( rParent, aElement, xAttribs, pNode )
345 , mnNextAc(0)
346 , mnPrevAc(0)
348 AttributeList attribs(xAttribs);
349 mbConcurrent = attribs.getBool( XML_concurrent, false );
350 mnNextAc = xAttribs->getOptionalValueToken( XML_nextAc, 0 );
351 mnPrevAc = xAttribs->getOptionalValueToken( XML_prevAc, 0 );
354 virtual ~SequenceTimeNodeContext() throw()
358 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) SAL_OVERRIDE
360 switch ( aElementToken )
362 case PPT_TOKEN( cTn ):
363 return new CommonTimeNodeContext( *this, aElementToken, rAttribs.getFastAttributeList(), mpNode );
364 case PPT_TOKEN( nextCondLst ):
365 return new CondListContext( *this, aElementToken, rAttribs.getFastAttributeList(), mpNode,
366 mpNode->getNextCondition() );
367 case PPT_TOKEN( prevCondLst ):
368 return new CondListContext( *this, aElementToken, rAttribs.getFastAttributeList(), mpNode,
369 mpNode->getPrevCondition() );
370 default:
371 break;
374 return this;
376 private:
377 bool mbConcurrent;
378 sal_Int32 mnNextAc, mnPrevAc;
381 /** CT_TLTimeNodeParallel
382 * CT_TLTimeNodeExclusive
384 class ParallelExclTimeNodeContext
385 : public TimeNodeContext
387 public:
388 ParallelExclTimeNodeContext( FragmentHandler2& rParent, sal_Int32 aElement,
389 const Reference< XFastAttributeList >& xAttribs,
390 const TimeNodePtr & pNode )
391 : TimeNodeContext( rParent, aElement, xAttribs, pNode )
395 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) SAL_OVERRIDE
397 switch ( aElementToken )
399 case PPT_TOKEN( cTn ):
400 return new CommonTimeNodeContext( *this, aElementToken, rAttribs.getFastAttributeList(), mpNode );
401 default:
402 break;
405 return this;
408 protected:
412 /** CT_TLAnimateColorBehavior */
413 class AnimColorContext
414 : public TimeNodeContext
416 public:
417 AnimColorContext( FragmentHandler2& rParent, sal_Int32 aElement,
418 const Reference< XFastAttributeList >& xAttribs,
419 const TimeNodePtr & pNode ) throw()
420 : TimeNodeContext( rParent, aElement, xAttribs, pNode )
421 , mnColorSpace( xAttribs->getOptionalValueToken( XML_clrSpc, 0 ) )
422 , mnDir( xAttribs->getOptionalValueToken( XML_dir, 0 ) )
423 , mbHasByColor( false )
424 , m_byColor( AnimationColorSpace::RGB, 0, 0, 0)
427 virtual ~AnimColorContext() throw()
431 virtual void onEndElement() SAL_OVERRIDE
433 //xParentNode
434 if( isCurrentElement( mnElement ) )
436 NodePropertyMap & pProps(mpNode->getNodeProperties());
437 pProps[ NP_DIRECTION ] = makeAny( mnDir == XML_cw );
438 pProps[ NP_COLORINTERPOLATION ] = makeAny( mnColorSpace == XML_hsl ? AnimationColorSpace::HSL : AnimationColorSpace::RGB );
439 const GraphicHelper& rGraphicHelper = getFilter().getGraphicHelper();
440 if( maToClr.isUsed() )
441 mpNode->setTo( Any( maToClr.getColor( rGraphicHelper ) ) );
442 if( maFromClr.isUsed() )
443 mpNode->setFrom( Any( maFromClr.getColor( rGraphicHelper ) ) );
444 if( mbHasByColor )
445 mpNode->setBy( m_byColor.get() );
449 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) SAL_OVERRIDE
451 switch ( aElementToken )
453 case PPT_TOKEN( hsl ):
454 // CT_TLByHslColorTransform
456 if( mbHasByColor )
458 m_byColor.colorSpace = AnimationColorSpace::HSL;
459 m_byColor.one = rAttribs.getInteger( XML_h, 0 );
460 m_byColor.two = rAttribs.getInteger( XML_s, 0 );
461 m_byColor.three = rAttribs.getInteger( XML_l, 0 );
463 return this;
465 case PPT_TOKEN( rgb ):
467 if( mbHasByColor )
469 // CT_TLByRgbColorTransform
470 m_byColor.colorSpace = AnimationColorSpace::RGB;
471 m_byColor.one = rAttribs.getInteger( XML_r, 0 );
472 m_byColor.two = rAttribs.getInteger( XML_g, 0 );
473 m_byColor.three = rAttribs.getInteger( XML_b, 0 );
475 return this;
477 case PPT_TOKEN( by ):
478 // CT_TLByAnimateColorTransform
479 mbHasByColor = true;
480 return this;
481 case PPT_TOKEN( cBhvr ):
482 return new CommonBehaviorContext ( *this, rAttribs.getFastAttributeList(), mpNode );
483 case PPT_TOKEN( to ):
484 // CT_Color
485 return new ColorContext( *this, maToClr );
486 case PPT_TOKEN( from ):
487 // CT_Color
488 return new ColorContext( *this, maFromClr );
490 default:
491 break;
494 return this;
497 private:
498 sal_Int32 mnColorSpace;
499 sal_Int32 mnDir;
500 bool mbHasByColor;
501 AnimColor m_byColor;
502 oox::drawingml::Color maToClr;
503 oox::drawingml::Color maFromClr;
506 /** CT_TLAnimateBehavior */
507 class AnimContext
508 : public TimeNodeContext
510 public:
511 AnimContext( FragmentHandler2& rParent, sal_Int32 aElement,
512 const Reference< XFastAttributeList >& xAttribs,
513 const TimeNodePtr & pNode ) throw()
514 : TimeNodeContext( rParent, aElement, xAttribs, pNode )
516 NodePropertyMap & aProps( pNode->getNodeProperties() );
517 sal_Int32 nCalcMode = xAttribs->getOptionalValueToken( XML_calcmode, 0 );
518 if(nCalcMode)
520 sal_Int16 nEnum = 0;
521 switch(nCalcMode)
523 case XML_discrete:
524 nEnum = AnimationCalcMode::DISCRETE;
525 break;
526 case XML_lin:
527 nEnum = AnimationCalcMode::LINEAR;
528 break;
529 case XML_fmla:
530 default:
531 // TODO what value is good ?
532 nEnum = AnimationCalcMode::DISCRETE;
533 break;
535 aProps[ NP_CALCMODE ] = makeAny(nEnum);
537 OUString aStr;
538 aStr = xAttribs->getOptionalValue( XML_from );
539 if( !aStr.isEmpty() )
541 pNode->setFrom( makeAny( aStr ) );
543 aStr = xAttribs->getOptionalValue( XML_by );
544 if( !aStr.isEmpty() )
546 pNode->setBy( makeAny( aStr ) );
548 aStr = xAttribs->getOptionalValue( XML_to );
549 if( !aStr.isEmpty() )
551 pNode->setTo( makeAny( aStr ) );
553 mnValueType = xAttribs->getOptionalValueToken( XML_valueType, 0 );
556 virtual ~AnimContext() throw ()
558 ::std::list< TimeAnimationValue >::iterator iter, end;
559 int nKeyTimes = maTavList.size();
560 if( nKeyTimes > 0)
562 int i;
563 Sequence< double > aKeyTimes( nKeyTimes );
564 Sequence< Any > aValues( nKeyTimes );
566 NodePropertyMap & aProps( mpNode->getNodeProperties() );
567 end = maTavList.end();
568 for(iter = maTavList.begin(), i=0; iter != end; ++iter,++i)
570 // TODO what to do if it is Timing_INFINITE ?
571 Any aTime = GetTimeAnimateValueTime( iter->msTime );
572 aTime >>= aKeyTimes[i];
573 aValues[i] = iter->maValue;
575 OUString aTest;
576 iter->maValue >>= aTest;
577 if( !aTest.isEmpty() )
579 aValues[i] = iter->maValue;
581 else
583 aProps[ NP_FORMULA ] <<= iter->msFormula;
586 aProps[ NP_VALUES ] <<= aValues;
587 aProps[ NP_KEYTIMES ] <<= aKeyTimes;
591 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) SAL_OVERRIDE
593 switch ( aElementToken )
595 case PPT_TOKEN( cBhvr ):
596 return new CommonBehaviorContext ( *this, rAttribs.getFastAttributeList(), mpNode );
597 case PPT_TOKEN( tavLst ):
598 return new TimeAnimValueListContext ( *this, rAttribs.getFastAttributeList(), maTavList );
599 default:
600 break;
603 return this;
605 private:
606 sal_Int32 mnValueType;
607 TimeAnimationValueList maTavList;
610 /** CT_TLAnimateScaleBehavior */
611 class AnimScaleContext
612 : public TimeNodeContext
614 public:
615 AnimScaleContext( FragmentHandler2& rParent, sal_Int32 aElement,
616 const Reference< XFastAttributeList >& xAttribs,
617 const TimeNodePtr & pNode ) throw()
618 : TimeNodeContext( rParent, aElement, xAttribs, pNode )
619 , mbZoomContents( false )
621 AttributeList attribs( xAttribs );
622 // TODO what to do with mbZoomContents
623 mbZoomContents = attribs.getBool( XML_zoomContents, false );
624 pNode->getNodeProperties()[ NP_TRANSFORMTYPE ]
625 = makeAny((sal_Int16)AnimationTransformType::SCALE);
628 virtual ~AnimScaleContext( ) throw( )
632 virtual void onEndElement() SAL_OVERRIDE
634 if( isCurrentElement( mnElement ) )
636 if( maTo.hasValue() )
638 mpNode->setTo( maTo );
640 if( maBy.hasValue() )
642 mpNode->setBy( maBy );
644 if( maFrom.hasValue() )
646 mpNode->setFrom( maFrom );
651 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) SAL_OVERRIDE
653 switch ( aElementToken )
655 case PPT_TOKEN( cBhvr ):
656 return new CommonBehaviorContext ( *this, rAttribs.getFastAttributeList(), mpNode );
657 case PPT_TOKEN( to ):
659 // CT_TLPoint
660 awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
661 maTo <<= p.X;
662 maTo <<= p.Y;
663 return this;
665 case PPT_TOKEN( from ):
667 // CT_TLPoint
668 awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
669 maFrom <<= p.X;
670 maFrom <<= p.Y;
671 return this;
673 case PPT_TOKEN( by ):
675 // CT_TLPoint
676 awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
677 maBy <<= p.X;
678 maBy <<= p.Y;
679 return this;
681 default:
682 break;
685 return this;
687 private:
688 Any maBy;
689 Any maFrom;
690 Any maTo;
691 bool mbZoomContents;
694 /** CT_TLAnimateRotationBehavior */
695 class AnimRotContext
696 : public TimeNodeContext
698 public:
699 AnimRotContext( FragmentHandler2& rParent, sal_Int32 aElement,
700 const Reference< XFastAttributeList >& xAttribs,
701 const TimeNodePtr & pNode ) throw()
702 : TimeNodeContext( rParent, aElement, xAttribs, pNode )
704 AttributeList attribs( xAttribs );
706 pNode->getNodeProperties()[ NP_TRANSFORMTYPE ]
707 = makeAny((sal_Int16)AnimationTransformType::ROTATE);
708 // see also DFF_msofbtAnimateRotationData in
709 // sd/source/filter/ppt/pptinanimations.cxx
710 if(attribs.hasAttribute( XML_by ) )
712 sal_Int32 nBy = attribs.getInteger( XML_by, 0 );
713 pNode->setBy( makeAny( (double) nBy ) );
715 if(attribs.hasAttribute( XML_from ) )
717 sal_Int32 nFrom = attribs.getInteger( XML_from, 0 );
718 pNode->setFrom( makeAny( (double) nFrom ) );
720 if(attribs.hasAttribute( XML_to ) )
722 sal_Int32 nTo = attribs.getInteger( XML_to, 0 );
723 pNode->setTo( makeAny( (double) nTo ) );
727 virtual ~AnimRotContext( ) throw( )
731 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) SAL_OVERRIDE
733 switch ( aElementToken )
735 case PPT_TOKEN( cBhvr ):
736 return new CommonBehaviorContext ( *this, rAttribs.getFastAttributeList(), mpNode );
737 default:
738 break;
741 return this;
745 /** CT_TLAnimateMotionBehavior */
746 class AnimMotionContext
747 : public TimeNodeContext
749 public:
750 AnimMotionContext( FragmentHandler2& rParent, sal_Int32 aElement,
751 const Reference< XFastAttributeList >& xAttribs,
752 const TimeNodePtr & pNode ) throw()
753 : TimeNodeContext( rParent, aElement, xAttribs, pNode )
755 pNode->getNodeProperties()[ NP_TRANSFORMTYPE ]
756 = makeAny((sal_Int16)AnimationTransformType::TRANSLATE);
758 AttributeList attribs( xAttribs );
759 sal_Int32 nOrigin = xAttribs->getOptionalValueToken( XML_origin, 0 );
760 if( nOrigin != 0 )
762 switch(nOrigin)
764 case XML_layout:
765 case XML_parent:
766 break;
768 // TODO
771 OUString aStr = xAttribs->getOptionalValue( XML_path );
772 // E can appear inside a number, so we only check for its presence at the end
773 aStr = aStr.trim();
774 if (aStr.endsWith("E"))
775 aStr = aStr.copy(0, aStr.getLength() - 1);
776 aStr = aStr.trim();
777 pNode->getNodeProperties()[ NP_PATH ] = makeAny(aStr);
778 mnPathEditMode = xAttribs->getOptionalValueToken( XML_pathEditMode, 0 );
779 msPtsTypes = xAttribs->getOptionalValue( XML_ptsTypes );
780 mnAngle = attribs.getInteger( XML_rAng, 0 );
781 // TODO make sure the units are right. Likely not.
784 virtual ~AnimMotionContext( ) throw()
788 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) SAL_OVERRIDE
790 switch ( aElementToken )
792 case PPT_TOKEN( cBhvr ):
793 return new CommonBehaviorContext ( *this, rAttribs.getFastAttributeList(), mpNode );
794 case PPT_TOKEN( to ):
796 // CT_TLPoint
797 awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
798 Any rAny;
799 rAny <<= p.X;
800 rAny <<= p.Y;
801 mpNode->setTo( rAny );
802 return this;
804 case PPT_TOKEN( from ):
806 // CT_TLPoint
807 awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
808 Any rAny;
809 rAny <<= p.X;
810 rAny <<= p.Y;
811 mpNode->setFrom( rAny );
812 return this;
814 case PPT_TOKEN( by ):
816 // CT_TLPoint
817 awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
818 Any rAny;
819 rAny <<= p.X;
820 rAny <<= p.Y;
821 mpNode->setBy( rAny );
822 return this;
824 case PPT_TOKEN( rCtr ):
826 // CT_TLPoint
827 awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
828 // TODO push
829 (void)p;
830 return this;
832 default:
833 break;
836 return this;
838 private:
839 OUString msPtsTypes;
840 sal_Int32 mnPathEditMode;
841 sal_Int32 mnAngle;
844 /** CT_TLAnimateEffectBehavior */
845 class AnimEffectContext
846 : public TimeNodeContext
848 public:
849 AnimEffectContext( FragmentHandler2& rParent, sal_Int32 aElement,
850 const Reference< XFastAttributeList >& xAttribs,
851 const TimeNodePtr & pNode ) throw()
852 : TimeNodeContext( rParent, aElement, xAttribs, pNode )
854 sal_Int32 nDir = xAttribs->getOptionalValueToken( XML_transition, 0 );
855 OUString sFilter = xAttribs->getOptionalValue( XML_filter );
856 // TODO
857 // OUString sPrList = xAttribs->getOptionalValue( XML_prLst );
859 if( !sFilter.isEmpty() )
861 SlideTransition aFilter( sFilter );
862 aFilter.setMode( nDir != XML_out );
863 pNode->setTransitionFilter( aFilter );
867 virtual ~AnimEffectContext( ) throw()
871 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) SAL_OVERRIDE
873 switch ( aElementToken )
875 case PPT_TOKEN( cBhvr ):
876 return new CommonBehaviorContext ( *this, rAttribs.getFastAttributeList(), mpNode );
877 case PPT_TOKEN( progress ):
878 return new AnimVariantContext( *this, aElementToken, maProgress );
879 // TODO handle it.
880 default:
881 break;
884 return this;
886 private:
887 Any maProgress;
890 TimeNodeContext * TimeNodeContext::makeContext(
891 FragmentHandler2& rParent, sal_Int32 aElement,
892 const Reference< XFastAttributeList >& xAttribs,
893 const TimeNodePtr & pNode )
895 TimeNodeContext *pCtx = NULL;
896 switch( aElement )
898 case PPT_TOKEN( animClr ):
899 pCtx = new AnimColorContext( rParent, aElement, xAttribs, pNode );
900 break;
901 case PPT_TOKEN( par ):
902 pCtx = new ParallelExclTimeNodeContext( rParent, aElement, xAttribs, pNode );
903 break;
904 case PPT_TOKEN( seq ):
905 pCtx = new SequenceTimeNodeContext( rParent, aElement, xAttribs, pNode );
906 break;
907 case PPT_TOKEN( excl ):
908 pCtx = new ParallelExclTimeNodeContext( rParent, aElement, xAttribs, pNode );
909 break;
910 case PPT_TOKEN( anim ):
911 pCtx = new AnimContext ( rParent, aElement, xAttribs, pNode );
912 break;
913 case PPT_TOKEN( animEffect ):
914 pCtx = new AnimEffectContext( rParent, aElement, xAttribs, pNode );
915 break;
916 case PPT_TOKEN( animMotion ):
917 pCtx = new AnimMotionContext( rParent, aElement, xAttribs, pNode );
918 break;
919 case PPT_TOKEN( animRot ):
920 pCtx = new AnimRotContext( rParent, aElement, xAttribs, pNode );
921 break;
922 case PPT_TOKEN( animScale ):
923 pCtx = new AnimScaleContext( rParent, aElement, xAttribs, pNode );
924 break;
925 case PPT_TOKEN( cmd ):
926 pCtx = new CmdTimeNodeContext( rParent, aElement, xAttribs, pNode );
927 break;
928 case PPT_TOKEN( set ):
929 pCtx = new SetTimeNodeContext( rParent, aElement, xAttribs, pNode );
930 break;
931 case PPT_TOKEN( audio ):
932 case PPT_TOKEN( video ):
933 pCtx = new MediaNodeContext( rParent, aElement, xAttribs, pNode );
934 break;
935 default:
936 break;
938 return pCtx;
941 TimeNodeContext::TimeNodeContext( FragmentHandler2& rParent, sal_Int32 aElement,
942 const Reference< XFastAttributeList >& /*xAttribs*/,
943 const TimeNodePtr & pNode ) throw()
944 : FragmentHandler2( rParent )
945 , mnElement( aElement )
946 , mpNode( pNode )
950 TimeNodeContext::~TimeNodeContext( ) throw()
955 TimeNodeListContext::TimeNodeListContext( FragmentHandler2& rParent, TimeNodePtrList & aList )
956 throw()
957 : FragmentHandler2( rParent )
958 , maList( aList )
962 TimeNodeListContext::~TimeNodeListContext( ) throw()
966 ::oox::core::ContextHandlerRef TimeNodeListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
968 sal_Int16 nNodeType;
970 switch( aElementToken )
972 case PPT_TOKEN( par ):
973 nNodeType = AnimationNodeType::PAR;
974 break;
975 case PPT_TOKEN( seq ):
976 nNodeType = AnimationNodeType::SEQ;
977 break;
978 case PPT_TOKEN( excl ):
979 // TODO pick the right type. We choose parallel for now as
980 // there does not seem to be an "Exclusive"
981 nNodeType = AnimationNodeType::PAR;
982 break;
983 case PPT_TOKEN( anim ):
984 nNodeType = AnimationNodeType::ANIMATE;
985 break;
986 case PPT_TOKEN( animClr ):
987 nNodeType = AnimationNodeType::ANIMATECOLOR;
988 break;
989 case PPT_TOKEN( animEffect ):
990 nNodeType = AnimationNodeType::TRANSITIONFILTER;
991 break;
992 case PPT_TOKEN( animMotion ):
993 nNodeType = AnimationNodeType::ANIMATEMOTION;
994 break;
995 case PPT_TOKEN( animRot ):
996 case PPT_TOKEN( animScale ):
997 nNodeType = AnimationNodeType::ANIMATETRANSFORM;
998 break;
999 case PPT_TOKEN( cmd ):
1000 nNodeType = AnimationNodeType::COMMAND;
1001 break;
1002 case PPT_TOKEN( set ):
1003 nNodeType = AnimationNodeType::SET;
1004 break;
1005 case PPT_TOKEN( audio ):
1006 nNodeType = AnimationNodeType::AUDIO;
1007 break;
1008 case PPT_TOKEN( video ):
1009 nNodeType = AnimationNodeType::AUDIO;
1010 OSL_TRACE( "OOX: video requested, gave Audio instead" );
1011 break;
1013 default:
1014 nNodeType = AnimationNodeType::CUSTOM;
1015 SAL_INFO("oox.ppt", "uhandled token " << aElementToken);
1016 break;
1019 TimeNodePtr pNode(new TimeNode(nNodeType));
1020 maList.push_back( pNode );
1021 FragmentHandler2 * pContext = TimeNodeContext::makeContext( *this, aElementToken, rAttribs.getFastAttributeList(), pNode );
1023 return pContext ? pContext : this;
1028 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */