Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / oox / source / ppt / timenodelistcontext.cxx
blob34c7e3eeeb553bc06d771582758fa43ddc22a524
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 <rtl/math.hxx>
26 #include <com/sun/star/animations/XTimeContainer.hpp>
27 #include <com/sun/star/animations/XAnimationNode.hpp>
28 #include <com/sun/star/animations/XAnimateColor.hpp>
29 #include <com/sun/star/animations/XAnimateSet.hpp>
30 #include <com/sun/star/animations/XAnimateTransform.hpp>
31 #include <com/sun/star/animations/AnimationTransformType.hpp>
32 #include <com/sun/star/animations/AnimationCalcMode.hpp>
33 #include <com/sun/star/animations/AnimationColorSpace.hpp>
34 #include <com/sun/star/animations/AnimationNodeType.hpp>
35 #include <com/sun/star/animations/XCommand.hpp>
36 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
37 #include <com/sun/star/presentation/EffectCommands.hpp>
38 #include <com/sun/star/beans/NamedValue.hpp>
40 #include "oox/helper/attributelist.hxx"
41 #include "oox/core/xmlfilterbase.hxx"
42 #include "oox/drawingml/drawingmltypes.hxx"
43 #include "drawingml/colorchoicecontext.hxx"
44 #include "oox/ppt/slidetransition.hxx"
45 #include <oox/token/namespaces.hxx>
46 #include <oox/token/tokens.hxx>
48 #include "animvariantcontext.hxx"
49 #include "commonbehaviorcontext.hxx"
50 #include "conditioncontext.hxx"
51 #include "commontimenodecontext.hxx"
52 #include "timeanimvaluecontext.hxx"
53 #include "animationtypes.hxx"
55 using namespace ::oox::core;
56 using namespace ::oox::drawingml;
57 using namespace ::com::sun::star;
58 using namespace ::com::sun::star::uno;
59 using namespace ::com::sun::star::lang;
60 using namespace ::com::sun::star::animations;
61 using namespace ::com::sun::star::presentation;
62 using namespace ::com::sun::star::xml::sax;
63 using ::com::sun::star::beans::NamedValue;
65 namespace oox { namespace ppt {
67 struct AnimColor
69 AnimColor(sal_Int16 cs, sal_Int32 o, sal_Int32 t, sal_Int32 th )
70 : colorSpace( cs ), one( o ), two( t ), three( th )
74 Any get()
76 sal_Int32 nColor;
77 Sequence< double > aHSL( 3 );
78 Any aColor;
80 switch( colorSpace )
82 case AnimationColorSpace::HSL:
83 aHSL[ 0 ] = double(one) / 100000;
84 aHSL[ 1 ] = double(two) / 100000;
85 aHSL[ 2 ] = double(three) / 100000;
86 aColor <<= aHSL;
87 break;
88 case AnimationColorSpace::RGB:
89 nColor = ( ( ( one * 128 ) / 1000 ) & 0xff ) << 16
90 | ( ( ( two * 128 ) / 1000 ) & 0xff ) << 8
91 | ( ( ( three * 128 ) / 1000 ) & 0xff );
92 aColor <<= nColor;
93 break;
94 default:
95 nColor = 0;
96 aColor <<= nColor;
97 break;
99 return aColor;
102 sal_Int16 colorSpace;
103 sal_Int32 one;
104 sal_Int32 two;
105 sal_Int32 three;
108 /** CT_TLMediaNodeAudio
109 CT_TLMediaNodeVideo */
110 class MediaNodeContext
111 : public TimeNodeContext
113 public:
114 MediaNodeContext( FragmentHandler2& rParent, sal_Int32 aElement,
115 const Reference< XFastAttributeList >& xAttribs,
116 const TimeNodePtr & pNode )
117 : TimeNodeContext( rParent, aElement, xAttribs, pNode )
118 , mbIsNarration( false )
119 , mbFullScrn( false )
121 AttributeList attribs( xAttribs );
123 switch( aElement )
125 case PPT_TOKEN( audio ):
126 mbIsNarration = attribs.getBool( XML_isNarration, false );
127 break;
128 case PPT_TOKEN( video ):
129 mbFullScrn = attribs.getBool( XML_fullScrn, false );
130 break;
131 default:
132 break;
136 virtual void onEndElement() override
138 sal_Int32 aElement = getCurrentElement();
139 if( aElement == PPT_TOKEN( audio ) )
141 // TODO deal with mbIsNarration
143 else if( aElement == PPT_TOKEN( video ) )
145 // TODO deal with mbFullScrn
149 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
151 switch ( aElementToken )
153 case PPT_TOKEN( cBhvr ):
154 return new CommonBehaviorContext ( *this, rAttribs.getFastAttributeList(), mpNode );
155 default:
156 break;
159 return this;
162 private:
163 bool mbIsNarration;
164 bool mbFullScrn;
167 /** CT_TLSetBehavior
169 class SetTimeNodeContext
170 : public TimeNodeContext
172 public:
173 SetTimeNodeContext( FragmentHandler2& rParent, sal_Int32 aElement,
174 const Reference< XFastAttributeList >& xAttribs,
175 const TimeNodePtr & pNode )
176 : TimeNodeContext( rParent, aElement, xAttribs, pNode )
181 virtual ~SetTimeNodeContext() throw () override
183 if( maTo.hasValue() )
185 // TODO
186 // HACK !!! discard and refactor
187 OUString aString;
188 if( maTo >>= aString )
190 maTo <<= aString == "visible";
191 if( !maTo.has<sal_Bool>() )
192 SAL_WARN("oox.ppt", "conversion failed" );
194 mpNode->setTo( maTo );
199 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) 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 void onEndElement() override
243 if( isCurrentElement( PPT_TOKEN( cmd ) ) )
245 try {
246 // see sd/source/filter/ppt/pptinanimations.cxx
247 // in AnimationImporter::importCommandContainer()
248 // REFACTOR?
249 // a good chunk of this code has been copied verbatim *sigh*
250 sal_Int16 nCommand = EffectCommands::CUSTOM;
251 NamedValue aParamValue;
253 switch( maType )
255 case XML_verb:
256 aParamValue.Name = "Verb";
257 // TODO make sure msCommand has what we want
258 aParamValue.Value <<= msCommand.toInt32();
259 nCommand = EffectCommands::VERB;
260 break;
261 case XML_evt:
262 case XML_call:
263 if ( msCommand == "onstopaudio" )
265 nCommand = EffectCommands::STOPAUDIO;
267 else if ( msCommand == "play" )
269 nCommand = EffectCommands::PLAY;
271 else if( msCommand == "playFrom" )
273 const OUString aMediaTime( msCommand.copy( 9, msCommand.getLength() - 10 ) );
274 rtl_math_ConversionStatus eStatus;
275 double fMediaTime = ::rtl::math::stringToDouble( aMediaTime, u'.', u',', &eStatus );
276 if( eStatus == rtl_math_ConversionStatus_Ok )
278 aParamValue.Name = "MediaTime";
279 aParamValue.Value <<= fMediaTime;
281 nCommand = EffectCommands::PLAY;
283 else if ( msCommand == "togglePause" )
285 nCommand = EffectCommands::TOGGLEPAUSE;
287 else if ( msCommand == "stop" )
289 nCommand = EffectCommands::STOP;
291 break;
293 mpNode->getNodeProperties()[ NP_COMMAND ] <<= nCommand;
294 if( nCommand == EffectCommands::CUSTOM )
296 SAL_WARN("oox.ppt", "OOX: CmdTimeNodeContext::endFastElement(), unknown command!");
297 aParamValue.Name = "UserDefined";
298 aParamValue.Value <<= msCommand;
300 if( aParamValue.Value.hasValue() )
302 Sequence< NamedValue > aParamSeq( &aParamValue, 1 );
303 mpNode->getNodeProperties()[ NP_PARAMETER ] <<= aParamSeq;
306 catch( RuntimeException& )
308 SAL_WARN("oox.ppt", "OOX: Exception in CmdTimeNodeContext::endFastElement()" );
313 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
315 switch ( aElementToken )
317 case PPT_TOKEN( cBhvr ):
318 return new CommonBehaviorContext ( *this, rAttribs.getFastAttributeList(), mpNode );
319 default:
320 break;
323 return this;
326 private:
327 OUString msCommand;
328 sal_Int32 maType;
331 /** CT_TLTimeNodeSequence
333 class SequenceTimeNodeContext
334 : public TimeNodeContext
336 public:
337 SequenceTimeNodeContext( FragmentHandler2& rParent, sal_Int32 aElement,
338 const Reference< XFastAttributeList >& xAttribs,
339 const TimeNodePtr & pNode )
340 : TimeNodeContext( rParent, aElement, xAttribs, pNode )
341 , mnNextAc(0)
342 , mnPrevAc(0)
344 AttributeList attribs(xAttribs);
345 mbConcurrent = attribs.getBool( XML_concurrent, false );
346 mnNextAc = xAttribs->getOptionalValueToken( XML_nextAc, 0 );
347 mnPrevAc = xAttribs->getOptionalValueToken( XML_prevAc, 0 );
350 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
352 switch ( aElementToken )
354 case PPT_TOKEN( cTn ):
355 return new CommonTimeNodeContext( *this, aElementToken, rAttribs.getFastAttributeList(), mpNode );
356 case PPT_TOKEN( nextCondLst ):
357 return new CondListContext( *this, aElementToken, rAttribs.getFastAttributeList(), mpNode,
358 mpNode->getNextCondition() );
359 case PPT_TOKEN( prevCondLst ):
360 return new CondListContext( *this, aElementToken, rAttribs.getFastAttributeList(), mpNode,
361 mpNode->getPrevCondition() );
362 default:
363 break;
366 return this;
368 private:
369 bool mbConcurrent;
370 sal_Int32 mnNextAc, mnPrevAc;
373 /** CT_TLTimeNodeParallel
374 * CT_TLTimeNodeExclusive
376 class ParallelExclTimeNodeContext
377 : public TimeNodeContext
379 public:
380 ParallelExclTimeNodeContext( FragmentHandler2& rParent, sal_Int32 aElement,
381 const Reference< XFastAttributeList >& xAttribs,
382 const TimeNodePtr & pNode )
383 : TimeNodeContext( rParent, aElement, xAttribs, pNode )
387 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
389 switch ( aElementToken )
391 case PPT_TOKEN( cTn ):
392 return new CommonTimeNodeContext( *this, aElementToken, rAttribs.getFastAttributeList(), mpNode );
393 default:
394 break;
397 return this;
400 protected:
404 /** CT_TLAnimateColorBehavior */
405 class AnimColorContext
406 : public TimeNodeContext
408 public:
409 AnimColorContext( FragmentHandler2& rParent, sal_Int32 aElement,
410 const Reference< XFastAttributeList >& xAttribs,
411 const TimeNodePtr & pNode ) throw()
412 : TimeNodeContext( rParent, aElement, xAttribs, pNode )
413 , mnColorSpace( xAttribs->getOptionalValueToken( XML_clrSpc, 0 ) )
414 , mnDir( xAttribs->getOptionalValueToken( XML_dir, 0 ) )
415 , mbHasByColor( false )
416 , m_byColor( AnimationColorSpace::RGB, 0, 0, 0)
420 virtual void onEndElement() override
422 //xParentNode
423 if( isCurrentElement( mnElement ) )
425 NodePropertyMap & rProps(mpNode->getNodeProperties());
426 rProps[ NP_DIRECTION ] <<= mnDir == XML_cw;
427 rProps[ NP_COLORINTERPOLATION ] <<= mnColorSpace == XML_hsl ? AnimationColorSpace::HSL : AnimationColorSpace::RGB;
428 const GraphicHelper& rGraphicHelper = getFilter().getGraphicHelper();
429 if( maToClr.isUsed() )
430 mpNode->setTo( Any( maToClr.getColor( rGraphicHelper ) ) );
431 if( maFromClr.isUsed() )
432 mpNode->setFrom( Any( maFromClr.getColor( rGraphicHelper ) ) );
433 if( mbHasByColor )
434 mpNode->setBy( m_byColor.get() );
438 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
440 switch ( aElementToken )
442 case PPT_TOKEN( hsl ):
443 // CT_TLByHslColorTransform
445 if( mbHasByColor )
447 m_byColor.colorSpace = AnimationColorSpace::HSL;
448 m_byColor.one = rAttribs.getInteger( XML_h, 0 );
449 m_byColor.two = rAttribs.getInteger( XML_s, 0 );
450 m_byColor.three = rAttribs.getInteger( XML_l, 0 );
452 return this;
454 case PPT_TOKEN( rgb ):
456 if( mbHasByColor )
458 // CT_TLByRgbColorTransform
459 m_byColor.colorSpace = AnimationColorSpace::RGB;
460 m_byColor.one = rAttribs.getInteger( XML_r, 0 );
461 m_byColor.two = rAttribs.getInteger( XML_g, 0 );
462 m_byColor.three = rAttribs.getInteger( XML_b, 0 );
464 return this;
466 case PPT_TOKEN( by ):
467 // CT_TLByAnimateColorTransform
468 mbHasByColor = true;
469 return this;
470 case PPT_TOKEN( cBhvr ):
471 return new CommonBehaviorContext ( *this, rAttribs.getFastAttributeList(), mpNode );
472 case PPT_TOKEN( to ):
473 // CT_Color
474 return new ColorContext( *this, maToClr );
475 case PPT_TOKEN( from ):
476 // CT_Color
477 return new ColorContext( *this, maFromClr );
479 default:
480 break;
483 return this;
486 private:
487 sal_Int32 mnColorSpace;
488 sal_Int32 mnDir;
489 bool mbHasByColor;
490 AnimColor m_byColor;
491 oox::drawingml::Color maToClr;
492 oox::drawingml::Color maFromClr;
495 /** CT_TLAnimateBehavior */
496 class AnimContext
497 : public TimeNodeContext
499 public:
500 AnimContext( FragmentHandler2& rParent, sal_Int32 aElement,
501 const Reference< XFastAttributeList >& xAttribs,
502 const TimeNodePtr & pNode ) throw()
503 : TimeNodeContext( rParent, aElement, xAttribs, pNode )
505 NodePropertyMap & aProps( pNode->getNodeProperties() );
506 sal_Int32 nCalcMode = xAttribs->getOptionalValueToken( XML_calcmode, 0 );
507 if(nCalcMode)
509 sal_Int16 nEnum = 0;
510 switch(nCalcMode)
512 case XML_discrete:
513 nEnum = AnimationCalcMode::DISCRETE;
514 break;
515 case XML_lin:
516 nEnum = AnimationCalcMode::LINEAR;
517 break;
518 case XML_fmla:
519 default:
520 // TODO what value is good ?
521 nEnum = AnimationCalcMode::DISCRETE;
522 break;
524 aProps[ NP_CALCMODE ] <<= nEnum;
526 OUString aStr;
527 aStr = xAttribs->getOptionalValue( XML_from );
528 if( !aStr.isEmpty() )
530 pNode->setFrom( makeAny( aStr ) );
532 aStr = xAttribs->getOptionalValue( XML_by );
533 if( !aStr.isEmpty() )
535 pNode->setBy( makeAny( aStr ) );
537 aStr = xAttribs->getOptionalValue( XML_to );
538 if( !aStr.isEmpty() )
540 pNode->setTo( makeAny( aStr ) );
542 mnValueType = xAttribs->getOptionalValueToken( XML_valueType, 0 );
545 virtual ~AnimContext() throw () override
547 ::std::list< TimeAnimationValue >::iterator iter, end;
548 int nKeyTimes = maTavList.size();
549 if( nKeyTimes > 0)
551 int i;
552 Sequence< double > aKeyTimes( nKeyTimes );
553 Sequence< Any > aValues( nKeyTimes );
555 NodePropertyMap & aProps( mpNode->getNodeProperties() );
556 end = maTavList.end();
557 for(iter = maTavList.begin(), i=0; iter != end; ++iter,++i)
559 // TODO what to do if it is Timing_INFINITE ?
560 Any aTime = GetTimeAnimateValueTime( iter->msTime );
561 aTime >>= aKeyTimes[i];
562 aValues[i] = iter->maValue;
564 OUString aTest;
565 iter->maValue >>= aTest;
566 if( !aTest.isEmpty() )
568 aValues[i] = iter->maValue;
570 else
572 aProps[ NP_FORMULA ] <<= iter->msFormula;
575 aProps[ NP_VALUES ] <<= aValues;
576 aProps[ NP_KEYTIMES ] <<= aKeyTimes;
580 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
582 switch ( aElementToken )
584 case PPT_TOKEN( cBhvr ):
585 return new CommonBehaviorContext ( *this, rAttribs.getFastAttributeList(), mpNode );
586 case PPT_TOKEN( tavLst ):
587 return new TimeAnimValueListContext ( *this, rAttribs.getFastAttributeList(), maTavList );
588 default:
589 break;
592 return this;
594 private:
595 sal_Int32 mnValueType;
596 TimeAnimationValueList maTavList;
599 /** CT_TLAnimateScaleBehavior */
600 class AnimScaleContext
601 : public TimeNodeContext
603 public:
604 AnimScaleContext( FragmentHandler2& rParent, sal_Int32 aElement,
605 const Reference< XFastAttributeList >& xAttribs,
606 const TimeNodePtr & pNode ) throw()
607 : TimeNodeContext( rParent, aElement, xAttribs, pNode )
608 , mbZoomContents( false )
610 AttributeList attribs( xAttribs );
611 // TODO what to do with mbZoomContents
612 mbZoomContents = attribs.getBool( XML_zoomContents, false );
613 pNode->getNodeProperties()[ NP_TRANSFORMTYPE ]
614 <<= (sal_Int16)AnimationTransformType::SCALE;
617 virtual void onEndElement() override
619 if( isCurrentElement( mnElement ) )
621 if( maTo.hasValue() )
623 mpNode->setTo( maTo );
625 if( maBy.hasValue() )
627 mpNode->setBy( maBy );
629 if( maFrom.hasValue() )
631 mpNode->setFrom( maFrom );
636 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
638 switch ( aElementToken )
640 case PPT_TOKEN( cBhvr ):
641 return new CommonBehaviorContext ( *this, rAttribs.getFastAttributeList(), mpNode );
642 case PPT_TOKEN( to ):
644 // CT_TLPoint
645 awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
646 maTo <<= p.X;
647 maTo <<= p.Y;
648 return this;
650 case PPT_TOKEN( from ):
652 // CT_TLPoint
653 awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
654 maFrom <<= p.X;
655 maFrom <<= p.Y;
656 return this;
658 case PPT_TOKEN( by ):
660 // CT_TLPoint
661 awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
662 maBy <<= p.X;
663 maBy <<= p.Y;
664 return this;
666 default:
667 break;
670 return this;
672 private:
673 Any maBy;
674 Any maFrom;
675 Any maTo;
676 bool mbZoomContents;
679 /** CT_TLAnimateRotationBehavior */
680 class AnimRotContext
681 : public TimeNodeContext
683 public:
684 AnimRotContext( FragmentHandler2& rParent, sal_Int32 aElement,
685 const Reference< XFastAttributeList >& xAttribs,
686 const TimeNodePtr & pNode ) throw()
687 : TimeNodeContext( rParent, aElement, xAttribs, pNode )
689 AttributeList attribs( xAttribs );
691 pNode->getNodeProperties()[ NP_TRANSFORMTYPE ]
692 <<= (sal_Int16)AnimationTransformType::ROTATE;
693 // see also DFF_msofbtAnimateRotationData in
694 // sd/source/filter/ppt/pptinanimations.cxx
695 if(attribs.hasAttribute( XML_by ) )
697 double fBy = attribs.getDouble( XML_by, 0.0 ) / PER_DEGREE; //1 PowerPoint-angle-unit = 1/60000 degree
698 pNode->setBy( makeAny( fBy ) );
700 if(attribs.hasAttribute( XML_from ) )
702 double fFrom = attribs.getDouble( XML_from, 0.0 ) / PER_DEGREE;
703 pNode->setFrom( makeAny( fFrom ) );
705 if(attribs.hasAttribute( XML_to ) )
707 double fTo = attribs.getDouble( XML_to, 0.0 ) / PER_DEGREE;
708 pNode->setTo( makeAny( fTo ) );
712 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
714 switch ( aElementToken )
716 case PPT_TOKEN( cBhvr ):
717 return new CommonBehaviorContext ( *this, rAttribs.getFastAttributeList(), mpNode );
718 default:
719 break;
722 return this;
726 /** CT_TLAnimateMotionBehavior */
727 class AnimMotionContext
728 : public TimeNodeContext
730 public:
731 AnimMotionContext( FragmentHandler2& rParent, sal_Int32 aElement,
732 const Reference< XFastAttributeList >& xAttribs,
733 const TimeNodePtr & pNode ) throw()
734 : TimeNodeContext( rParent, aElement, xAttribs, pNode )
736 pNode->getNodeProperties()[ NP_TRANSFORMTYPE ]
737 <<= (sal_Int16)AnimationTransformType::TRANSLATE;
739 AttributeList attribs( xAttribs );
740 sal_Int32 nOrigin = xAttribs->getOptionalValueToken( XML_origin, 0 );
741 if( nOrigin != 0 )
743 switch(nOrigin)
745 case XML_layout:
746 case XML_parent:
747 break;
749 // TODO
752 OUString aStr = xAttribs->getOptionalValue( XML_path );
753 // E can appear inside a number, so we only check for its presence at the end
754 aStr = aStr.trim();
755 if (aStr.endsWith("E"))
756 aStr = aStr.copy(0, aStr.getLength() - 1);
757 aStr = aStr.trim();
758 pNode->getNodeProperties()[ NP_PATH ] <<= aStr;
759 mnPathEditMode = xAttribs->getOptionalValueToken( XML_pathEditMode, 0 );
760 msPtsTypes = xAttribs->getOptionalValue( XML_ptsTypes );
761 mnAngle = attribs.getInteger( XML_rAng, 0 );
762 // TODO make sure the units are right. Likely not.
765 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
767 switch ( aElementToken )
769 case PPT_TOKEN( cBhvr ):
770 return new CommonBehaviorContext ( *this, rAttribs.getFastAttributeList(), mpNode );
771 case PPT_TOKEN( to ):
773 // CT_TLPoint
774 awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
775 Any rAny;
776 rAny <<= p.X;
777 rAny <<= p.Y;
778 mpNode->setTo( rAny );
779 return this;
781 case PPT_TOKEN( from ):
783 // CT_TLPoint
784 awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
785 Any rAny;
786 rAny <<= p.X;
787 rAny <<= p.Y;
788 mpNode->setFrom( rAny );
789 return this;
791 case PPT_TOKEN( by ):
793 // CT_TLPoint
794 awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
795 Any rAny;
796 rAny <<= p.X;
797 rAny <<= p.Y;
798 mpNode->setBy( rAny );
799 return this;
801 case PPT_TOKEN( rCtr ):
803 // CT_TLPoint
804 awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
805 // TODO push
806 (void)p;
807 return this;
809 default:
810 break;
813 return this;
815 private:
816 OUString msPtsTypes;
817 sal_Int32 mnPathEditMode;
818 sal_Int32 mnAngle;
821 /** CT_TLAnimateEffectBehavior */
822 class AnimEffectContext
823 : public TimeNodeContext
825 public:
826 AnimEffectContext( FragmentHandler2& rParent, sal_Int32 aElement,
827 const Reference< XFastAttributeList >& xAttribs,
828 const TimeNodePtr & pNode ) throw()
829 : TimeNodeContext( rParent, aElement, xAttribs, pNode )
831 sal_Int32 nDir = xAttribs->getOptionalValueToken( XML_transition, 0 );
832 OUString sFilter = xAttribs->getOptionalValue( XML_filter );
833 // TODO
834 // OUString sPrList = xAttribs->getOptionalValue( XML_prLst );
836 if( !sFilter.isEmpty() )
838 SlideTransition aFilter( sFilter );
839 aFilter.setMode( nDir != XML_out );
840 pNode->setTransitionFilter( aFilter );
844 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
846 switch ( aElementToken )
848 case PPT_TOKEN( cBhvr ):
849 return new CommonBehaviorContext ( *this, rAttribs.getFastAttributeList(), mpNode );
850 case PPT_TOKEN( progress ):
851 return new AnimVariantContext( *this, aElementToken, maProgress );
852 // TODO handle it.
853 default:
854 break;
857 return this;
859 private:
860 Any maProgress;
863 TimeNodeContext * TimeNodeContext::makeContext(
864 FragmentHandler2& rParent, sal_Int32 aElement,
865 const Reference< XFastAttributeList >& xAttribs,
866 const TimeNodePtr & pNode )
868 TimeNodeContext *pCtx = nullptr;
869 switch( aElement )
871 case PPT_TOKEN( animClr ):
872 pCtx = new AnimColorContext( rParent, aElement, xAttribs, pNode );
873 break;
874 case PPT_TOKEN( par ):
875 pCtx = new ParallelExclTimeNodeContext( rParent, aElement, xAttribs, pNode );
876 break;
877 case PPT_TOKEN( seq ):
878 pCtx = new SequenceTimeNodeContext( rParent, aElement, xAttribs, pNode );
879 break;
880 case PPT_TOKEN( excl ):
881 pCtx = new ParallelExclTimeNodeContext( rParent, aElement, xAttribs, pNode );
882 break;
883 case PPT_TOKEN( anim ):
884 pCtx = new AnimContext ( rParent, aElement, xAttribs, pNode );
885 break;
886 case PPT_TOKEN( animEffect ):
887 pCtx = new AnimEffectContext( rParent, aElement, xAttribs, pNode );
888 break;
889 case PPT_TOKEN( animMotion ):
890 pCtx = new AnimMotionContext( rParent, aElement, xAttribs, pNode );
891 break;
892 case PPT_TOKEN( animRot ):
893 pCtx = new AnimRotContext( rParent, aElement, xAttribs, pNode );
894 break;
895 case PPT_TOKEN( animScale ):
896 pCtx = new AnimScaleContext( rParent, aElement, xAttribs, pNode );
897 break;
898 case PPT_TOKEN( cmd ):
899 pCtx = new CmdTimeNodeContext( rParent, aElement, xAttribs, pNode );
900 break;
901 case PPT_TOKEN( set ):
902 pCtx = new SetTimeNodeContext( rParent, aElement, xAttribs, pNode );
903 break;
904 case PPT_TOKEN( audio ):
905 case PPT_TOKEN( video ):
906 pCtx = new MediaNodeContext( rParent, aElement, xAttribs, pNode );
907 break;
908 default:
909 break;
911 return pCtx;
914 TimeNodeContext::TimeNodeContext( FragmentHandler2& rParent, sal_Int32 aElement,
915 const Reference< XFastAttributeList >& /*xAttribs*/,
916 const TimeNodePtr & pNode ) throw()
917 : FragmentHandler2( rParent )
918 , mnElement( aElement )
919 , mpNode( pNode )
923 TimeNodeContext::~TimeNodeContext( ) throw()
928 TimeNodeListContext::TimeNodeListContext( FragmentHandler2& rParent, TimeNodePtrList & aList )
929 throw()
930 : FragmentHandler2( rParent )
931 , maList( aList )
935 TimeNodeListContext::~TimeNodeListContext( ) throw()
939 ::oox::core::ContextHandlerRef TimeNodeListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
941 sal_Int16 nNodeType;
943 switch( aElementToken )
945 case PPT_TOKEN( par ):
946 nNodeType = AnimationNodeType::PAR;
947 break;
948 case PPT_TOKEN( seq ):
949 nNodeType = AnimationNodeType::SEQ;
950 break;
951 case PPT_TOKEN( excl ):
952 // TODO pick the right type. We choose parallel for now as
953 // there does not seem to be an "Exclusive"
954 nNodeType = AnimationNodeType::PAR;
955 break;
956 case PPT_TOKEN( anim ):
957 nNodeType = AnimationNodeType::ANIMATE;
958 break;
959 case PPT_TOKEN( animClr ):
960 nNodeType = AnimationNodeType::ANIMATECOLOR;
961 break;
962 case PPT_TOKEN( animEffect ):
963 nNodeType = AnimationNodeType::TRANSITIONFILTER;
964 break;
965 case PPT_TOKEN( animMotion ):
966 nNodeType = AnimationNodeType::ANIMATEMOTION;
967 break;
968 case PPT_TOKEN( animRot ):
969 case PPT_TOKEN( animScale ):
970 nNodeType = AnimationNodeType::ANIMATETRANSFORM;
971 break;
972 case PPT_TOKEN( cmd ):
973 nNodeType = AnimationNodeType::COMMAND;
974 break;
975 case PPT_TOKEN( set ):
976 nNodeType = AnimationNodeType::SET;
977 break;
978 case PPT_TOKEN( audio ):
979 nNodeType = AnimationNodeType::AUDIO;
980 break;
981 case PPT_TOKEN( video ):
982 nNodeType = AnimationNodeType::AUDIO;
983 SAL_WARN("oox.ppt", "OOX: video requested, gave Audio instead" );
984 break;
986 default:
987 nNodeType = AnimationNodeType::CUSTOM;
988 SAL_INFO("oox.ppt", "uhandled token " << aElementToken);
989 break;
992 TimeNodePtr pNode(new TimeNode(nNodeType));
993 maList.push_back( pNode );
994 FragmentHandler2 * pContext = TimeNodeContext::makeContext( *this, aElementToken, rAttribs.getFastAttributeList(), pNode );
996 return pContext ? pContext : this;
1001 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */