1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <rtl/math.hxx>
23 #include <sal/log.hxx>
24 #include <tools/diagnose_ex.h>
26 #include <com/sun/star/animations/AnimationTransformType.hpp>
27 #include <com/sun/star/animations/AnimationCalcMode.hpp>
28 #include <com/sun/star/animations/AnimationColorSpace.hpp>
29 #include <com/sun/star/animations/AnimationNodeType.hpp>
30 #include <com/sun/star/animations/ValuePair.hpp>
31 #include <com/sun/star/presentation/EffectCommands.hpp>
32 #include <com/sun/star/beans/NamedValue.hpp>
34 #include <oox/helper/attributelist.hxx>
35 #include <oox/core/xmlfilterbase.hxx>
36 #include <oox/drawingml/drawingmltypes.hxx>
37 #include <drawingml/colorchoicecontext.hxx>
38 #include <oox/ppt/slidetransition.hxx>
39 #include <oox/token/namespaces.hxx>
40 #include <oox/token/tokens.hxx>
42 #include "animvariantcontext.hxx"
43 #include "commonbehaviorcontext.hxx"
44 #include "conditioncontext.hxx"
45 #include "commontimenodecontext.hxx"
46 #include "timeanimvaluecontext.hxx"
47 #include "animationtypes.hxx"
48 #include "timetargetelementcontext.hxx"
50 using namespace ::oox::core
;
51 using namespace ::oox::drawingml
;
52 using namespace ::com::sun::star
;
53 using namespace ::com::sun::star::uno
;
54 using namespace ::com::sun::star::lang
;
55 using namespace ::com::sun::star::animations
;
56 using namespace ::com::sun::star::presentation
;
57 using namespace ::com::sun::star::xml::sax
;
58 using ::com::sun::star::beans::NamedValue
;
62 oox::ppt::AnimationAttributeEnum
getAttributeEnumByAPIName(const OUString
&rAPIName
)
64 oox::ppt::AnimationAttributeEnum eResult
= oox::ppt::AnimationAttributeEnum::UNKNOWN
;
65 const oox::ppt::ImplAttributeNameConversion
*attrConv
= oox::ppt::getAttributeConversionList();
66 while(attrConv
->mpAPIName
!= nullptr)
68 if(rAPIName
.equalsAscii(attrConv
->mpAPIName
))
70 eResult
= attrConv
->meAttribute
;
78 bool convertAnimationValueWithTimeNode(const oox::ppt::TimeNodePtr
& pNode
, css::uno::Any
&rAny
)
80 css::uno::Any aAny
= pNode
->getNodeProperties()[oox::ppt::NP_ATTRIBUTENAME
];
84 // only get first token.
85 return oox::ppt::convertAnimationValue(getAttributeEnumByAPIName(aNameList
.getToken(0, ';')), rAny
);
88 css::uno::Any
convertPointPercent(const css::awt::Point
& rPoint
)
90 css::animations::ValuePair aPair
;
91 // rPoint.X and rPoint.Y are in 1000th of a percent, but we only need ratio.
92 aPair
.First
<<= static_cast<double>(rPoint
.X
) / 100000.0;
93 aPair
.Second
<<= static_cast<double>(rPoint
.Y
) / 100000.0;
94 return makeAny(aPair
);
104 AnimColor(sal_Int16 cs
, sal_Int32 o
, sal_Int32 t
, sal_Int32 th
)
105 : colorSpace( cs
), one( o
), two( t
), three( th
)
116 case AnimationColorSpace::HSL
:
117 aColor
<<= Sequence
< double >{ one
/ 100000.0, two
/ 100000.0, three
/ 100000.0 };
119 case AnimationColorSpace::RGB
:
120 nColor
= ( ( ( one
* 128 ) / 1000 ) & 0xff ) << 16
121 | ( ( ( two
* 128 ) / 1000 ) & 0xff ) << 8
122 | ( ( ( three
* 128 ) / 1000 ) & 0xff );
133 sal_Int16 colorSpace
;
139 /** CT_TLMediaNodeAudio
140 CT_TLMediaNodeVideo */
141 class MediaNodeContext
142 : public TimeNodeContext
145 MediaNodeContext( FragmentHandler2
const & rParent
, sal_Int32 aElement
,
146 const Reference
< XFastAttributeList
>& xAttribs
,
147 const TimeNodePtr
& pNode
)
148 : TimeNodeContext( rParent
, aElement
, pNode
)
149 , mbIsNarration( false )
150 , mbFullScrn( false )
151 , mbHideDuringShow(false)
153 AttributeList
attribs( xAttribs
);
157 case PPT_TOKEN( audio
):
158 mbIsNarration
= attribs
.getBool( XML_isNarration
, false );
160 case PPT_TOKEN( video
):
161 mbFullScrn
= attribs
.getBool( XML_fullScrn
, false );
168 virtual void onEndElement() override
170 sal_Int32 aElement
= getCurrentElement();
171 if( aElement
== PPT_TOKEN( audio
) )
173 mpNode
->getNodeProperties()[NP_ISNARRATION
] <<= mbIsNarration
;
175 else if( aElement
== PPT_TOKEN( video
) )
177 // TODO deal with mbFullScrn
179 else if (aElement
== PPT_TOKEN(cMediaNode
))
181 mpNode
->getNodeProperties()[NP_HIDEDURINGSHOW
] <<= mbHideDuringShow
;
185 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
) override
187 switch ( aElementToken
)
189 case PPT_TOKEN( cTn
):
190 return new CommonTimeNodeContext( *this, aElementToken
, rAttribs
.getFastAttributeList(), mpNode
);
191 case PPT_TOKEN( tgtEl
):
192 return new TimeTargetElementContext( *this, mpNode
->getTarget() );
193 case PPT_TOKEN(cMediaNode
):
194 mbHideDuringShow
= !rAttribs
.getBool(XML_showWhenStopped
, true);
206 bool mbHideDuringShow
;
211 class SetTimeNodeContext
212 : public TimeNodeContext
215 SetTimeNodeContext( FragmentHandler2
const & rParent
, sal_Int32 aElement
,
216 const TimeNodePtr
& pNode
)
217 : TimeNodeContext( rParent
, aElement
, pNode
)
222 virtual ~SetTimeNodeContext() noexcept override
226 convertAnimationValueWithTimeNode(mpNode
, maTo
);
232 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const AttributeList
& /*rAttribs*/ ) override
234 switch ( aElementToken
)
236 case PPT_TOKEN( cBhvr
):
237 return new CommonBehaviorContext ( *this, mpNode
);
238 case PPT_TOKEN( to
):
240 return new AnimVariantContext( *this, aElementToken
, maTo
);
251 /** CT_TLCommandBehavior
253 class CmdTimeNodeContext
254 : public TimeNodeContext
257 CmdTimeNodeContext( FragmentHandler2
const & rParent
, sal_Int32 aElement
,
258 const Reference
< XFastAttributeList
>& xAttribs
,
259 const TimeNodePtr
& pNode
)
260 : TimeNodeContext( rParent
, aElement
, pNode
)
265 case PPT_TOKEN( cmd
):
266 msCommand
= xAttribs
->getOptionalValue( XML_cmd
);
267 maType
= xAttribs
->getOptionalValueToken( XML_type
, 0 );
274 virtual void onEndElement() override
276 if( !isCurrentElement( PPT_TOKEN( cmd
) ) )
280 // see sd/source/filter/ppt/pptinanimations.cxx
281 // in AnimationImporter::importCommandContainer()
283 // a good chunk of this code has been copied verbatim *sigh*
284 sal_Int16 nCommand
= EffectCommands::CUSTOM
;
285 NamedValue aParamValue
;
290 aParamValue
.Name
= "Verb";
291 // TODO make sure msCommand has what we want
292 aParamValue
.Value
<<= msCommand
.toInt32();
293 nCommand
= EffectCommands::VERB
;
297 if ( msCommand
== "onstopaudio" )
299 nCommand
= EffectCommands::STOPAUDIO
;
301 else if ( msCommand
== "play" )
303 nCommand
= EffectCommands::PLAY
;
305 else if (msCommand
.startsWith("playFrom"))
307 const OUString
aMediaTime( msCommand
.copy( 9, msCommand
.getLength() - 10 ) );
308 rtl_math_ConversionStatus eStatus
;
309 double fMediaTime
= ::rtl::math::stringToDouble( aMediaTime
, u
'.', u
',', &eStatus
);
310 if( eStatus
== rtl_math_ConversionStatus_Ok
)
312 aParamValue
.Name
= "MediaTime";
313 aParamValue
.Value
<<= fMediaTime
;
315 nCommand
= EffectCommands::PLAY
;
317 else if ( msCommand
== "togglePause" )
319 nCommand
= EffectCommands::TOGGLEPAUSE
;
321 else if ( msCommand
== "stop" )
323 nCommand
= EffectCommands::STOP
;
327 mpNode
->getNodeProperties()[ NP_COMMAND
] <<= nCommand
;
328 if( nCommand
== EffectCommands::CUSTOM
)
330 SAL_WARN("oox.ppt", "OOX: CmdTimeNodeContext::endFastElement(), unknown command!");
331 aParamValue
.Name
= "UserDefined";
332 aParamValue
.Value
<<= msCommand
;
334 if( aParamValue
.Value
.hasValue() )
336 Sequence
< NamedValue
> aParamSeq( &aParamValue
, 1 );
337 mpNode
->getNodeProperties()[ NP_PARAMETER
] <<= aParamSeq
;
340 catch( RuntimeException
& )
342 TOOLS_WARN_EXCEPTION("oox.ppt", "OOX: Exception in CmdTimeNodeContext::endFastElement()" );
346 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const AttributeList
& /*rAttribs*/ ) override
348 switch ( aElementToken
)
350 case PPT_TOKEN( cBhvr
):
351 return new CommonBehaviorContext ( *this, mpNode
);
364 /** CT_TLTimeNodeSequence
366 class SequenceTimeNodeContext
367 : public TimeNodeContext
370 SequenceTimeNodeContext( FragmentHandler2
const & rParent
, sal_Int32 aElement
,
371 const Reference
< XFastAttributeList
>& xAttribs
,
372 const TimeNodePtr
& pNode
)
373 : TimeNodeContext( rParent
, aElement
, pNode
)
377 AttributeList
attribs(xAttribs
);
378 mbConcurrent
= attribs
.getBool( XML_concurrent
, false );
379 mnNextAc
= xAttribs
->getOptionalValueToken( XML_nextAc
, 0 );
380 mnPrevAc
= xAttribs
->getOptionalValueToken( XML_prevAc
, 0 );
383 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
) override
385 switch ( aElementToken
)
387 case PPT_TOKEN( cTn
):
388 return new CommonTimeNodeContext( *this, aElementToken
, rAttribs
.getFastAttributeList(), mpNode
);
389 case PPT_TOKEN( nextCondLst
):
390 return new CondListContext( *this, aElementToken
, mpNode
, mpNode
->getNextCondition() );
391 case PPT_TOKEN( prevCondLst
):
392 return new CondListContext( *this, aElementToken
, mpNode
, mpNode
->getPrevCondition() );
401 sal_Int32 mnNextAc
, mnPrevAc
;
404 /** CT_TLTimeNodeParallel
405 * CT_TLTimeNodeExclusive
407 class ParallelExclTimeNodeContext
408 : public TimeNodeContext
411 ParallelExclTimeNodeContext( FragmentHandler2
const & rParent
, sal_Int32 aElement
,
412 const TimeNodePtr
& pNode
)
413 : TimeNodeContext( rParent
, aElement
, pNode
)
417 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
) override
419 switch ( aElementToken
)
421 case PPT_TOKEN( cTn
):
422 return new CommonTimeNodeContext( *this, aElementToken
, rAttribs
.getFastAttributeList(), mpNode
);
434 /** CT_TLAnimateColorBehavior */
435 class AnimColorContext
436 : public TimeNodeContext
439 AnimColorContext( FragmentHandler2
const & rParent
, sal_Int32 aElement
,
440 const Reference
< XFastAttributeList
>& xAttribs
,
441 const TimeNodePtr
& pNode
) noexcept
442 : TimeNodeContext( rParent
, aElement
, pNode
)
443 , mnColorSpace( xAttribs
->getOptionalValueToken( XML_clrSpc
, 0 ) )
444 , mnDir( xAttribs
->getOptionalValueToken( XML_dir
, 0 ) )
445 , mbHasByColor( false )
446 , m_byColor( AnimationColorSpace::RGB
, 0, 0, 0)
450 virtual void onEndElement() override
453 if( !isCurrentElement( mnElement
) )
456 NodePropertyMap
& rProps(mpNode
->getNodeProperties());
457 rProps
[ NP_DIRECTION
] <<= mnDir
== XML_cw
;
458 rProps
[ NP_COLORINTERPOLATION
] <<= mnColorSpace
== XML_hsl
? AnimationColorSpace::HSL
: AnimationColorSpace::RGB
;
459 const GraphicHelper
& rGraphicHelper
= getFilter().getGraphicHelper();
460 if( maToClr
.isUsed() )
461 mpNode
->setTo( makeAny( maToClr
.getColor( rGraphicHelper
) ) );
462 if( maFromClr
.isUsed() )
463 mpNode
->setFrom( makeAny( maFromClr
.getColor( rGraphicHelper
) ) );
465 mpNode
->setBy( m_byColor
.get() );
468 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
) override
470 switch ( aElementToken
)
472 case PPT_TOKEN( hsl
):
473 // CT_TLByHslColorTransform
477 m_byColor
.colorSpace
= AnimationColorSpace::HSL
;
478 m_byColor
.one
= rAttribs
.getInteger( XML_h
, 0 );
479 m_byColor
.two
= rAttribs
.getInteger( XML_s
, 0 );
480 m_byColor
.three
= rAttribs
.getInteger( XML_l
, 0 );
484 case PPT_TOKEN( rgb
):
488 // CT_TLByRgbColorTransform
489 m_byColor
.colorSpace
= AnimationColorSpace::RGB
;
490 m_byColor
.one
= rAttribs
.getInteger( XML_r
, 0 );
491 m_byColor
.two
= rAttribs
.getInteger( XML_g
, 0 );
492 m_byColor
.three
= rAttribs
.getInteger( XML_b
, 0 );
496 case PPT_TOKEN( by
):
497 // CT_TLByAnimateColorTransform
500 case PPT_TOKEN( cBhvr
):
501 return new CommonBehaviorContext ( *this, mpNode
);
502 case PPT_TOKEN( to
):
504 return new ColorContext( *this, maToClr
);
505 case PPT_TOKEN( from
):
507 return new ColorContext( *this, maFromClr
);
517 sal_Int32 mnColorSpace
;
521 oox::drawingml::Color maToClr
;
522 oox::drawingml::Color maFromClr
;
525 /** CT_TLAnimateBehavior */
527 : public TimeNodeContext
530 AnimContext( FragmentHandler2
const & rParent
, sal_Int32 aElement
,
531 const Reference
< XFastAttributeList
>& xAttribs
,
532 const TimeNodePtr
& pNode
) noexcept
533 : TimeNodeContext( rParent
, aElement
, pNode
)
535 NodePropertyMap
& aProps( pNode
->getNodeProperties() );
536 sal_Int32 nCalcMode
= xAttribs
->getOptionalValueToken( XML_calcmode
, 0 );
543 nEnum
= AnimationCalcMode::DISCRETE
;
546 nEnum
= AnimationCalcMode::LINEAR
;
550 // TODO what value is good ?
551 nEnum
= AnimationCalcMode::DISCRETE
;
554 aProps
[ NP_CALCMODE
] <<= nEnum
;
557 msFrom
= xAttribs
->getOptionalValue(XML_from
);
558 msTo
= xAttribs
->getOptionalValue(XML_to
);
559 msBy
= xAttribs
->getOptionalValue(XML_by
);
561 mnValueType
= xAttribs
->getOptionalValueToken( XML_valueType
, 0 );
564 virtual ~AnimContext() noexcept override
566 if (!msFrom
.isEmpty())
570 convertAnimationValueWithTimeNode(mpNode
, aAny
);
571 mpNode
->setFrom(aAny
);
578 convertAnimationValueWithTimeNode(mpNode
, aAny
);
586 convertAnimationValueWithTimeNode(mpNode
, aAny
);
590 int nKeyTimes
= maTavList
.size();
595 Sequence
< double > aKeyTimes( nKeyTimes
);
596 auto pKeyTimes
= aKeyTimes
.getArray();
597 Sequence
< Any
> aValues( nKeyTimes
);
598 auto pValues
= aValues
.getArray();
600 NodePropertyMap
& aProps( mpNode
->getNodeProperties() );
601 for (auto const& tav
: maTavList
)
603 // TODO what to do if it is Timing_INFINITE ?
604 Any aTime
= GetTimeAnimateValueTime( tav
.msTime
);
605 aTime
>>= pKeyTimes
[i
];
606 pValues
[i
] = tav
.maValue
;
607 convertAnimationValueWithTimeNode(mpNode
, pValues
[i
]);
609 // Examine pptx documents and find that only the first tav
610 // has the formula set. The formula can be used for the whole.
611 if (!tav
.msFormula
.isEmpty())
613 OUString sFormula
= tav
.msFormula
;
614 (void)convertMeasure(sFormula
);
615 aProps
[NP_FORMULA
] <<= sFormula
;
620 aProps
[ NP_VALUES
] <<= aValues
;
621 aProps
[ NP_KEYTIMES
] <<= aKeyTimes
;
624 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const AttributeList
& /*rAttribs*/ ) override
626 switch ( aElementToken
)
628 case PPT_TOKEN( cBhvr
):
629 return new CommonBehaviorContext ( *this, mpNode
);
630 case PPT_TOKEN( tavLst
):
631 return new TimeAnimValueListContext ( *this, maTavList
);
639 sal_Int32 mnValueType
;
640 TimeAnimationValueList maTavList
;
646 /** CT_TLAnimateScaleBehavior */
647 class AnimScaleContext
648 : public TimeNodeContext
651 AnimScaleContext( FragmentHandler2
const & rParent
, sal_Int32 aElement
,
652 const Reference
< XFastAttributeList
>& xAttribs
,
653 const TimeNodePtr
& pNode
) noexcept
654 : TimeNodeContext( rParent
, aElement
, pNode
)
655 , mbZoomContents( false )
657 AttributeList
attribs( xAttribs
);
658 // TODO what to do with mbZoomContents
659 mbZoomContents
= attribs
.getBool( XML_zoomContents
, false );
660 pNode
->getNodeProperties()[ NP_TRANSFORMTYPE
]
661 <<= sal_Int16(AnimationTransformType::SCALE
);
664 virtual void onEndElement() override
666 if( !isCurrentElement( mnElement
) )
669 if( maTo
.hasValue() )
671 mpNode
->setTo( maTo
);
673 if( maBy
.hasValue() )
675 mpNode
->setBy( maBy
);
677 if( maFrom
.hasValue() )
679 mpNode
->setFrom( maFrom
);
683 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
) override
685 switch ( aElementToken
)
687 case PPT_TOKEN( cBhvr
):
688 return new CommonBehaviorContext ( *this, mpNode
);
689 case PPT_TOKEN( to
):
692 maTo
= convertPointPercent(GetPointPercent(rAttribs
.getFastAttributeList()));
695 case PPT_TOKEN( from
):
698 maFrom
= convertPointPercent(GetPointPercent(rAttribs
.getFastAttributeList()));
701 case PPT_TOKEN( by
):
704 css::awt::Point aPoint
= GetPointPercent(rAttribs
.getFastAttributeList());
705 // We got ending values instead of offset values, so subtract 100% from them.
708 maBy
= convertPointPercent(aPoint
);
724 /** CT_TLAnimateRotationBehavior */
726 : public TimeNodeContext
729 AnimRotContext( FragmentHandler2
const & rParent
, sal_Int32 aElement
,
730 const Reference
< XFastAttributeList
>& xAttribs
,
731 const TimeNodePtr
& pNode
) noexcept
732 : TimeNodeContext( rParent
, aElement
, pNode
)
734 AttributeList
attribs( xAttribs
);
736 pNode
->getNodeProperties()[ NP_TRANSFORMTYPE
]
737 <<= sal_Int16(AnimationTransformType::ROTATE
);
738 // see also DFF_msofbtAnimateRotationData in
739 // sd/source/filter/ppt/pptinanimations.cxx
740 if(attribs
.hasAttribute( XML_by
) )
742 double fBy
= attribs
.getDouble( XML_by
, 0.0 ) / PER_DEGREE
; //1 PowerPoint-angle-unit = 1/60000 degree
743 pNode
->setBy( makeAny( fBy
) );
745 if(attribs
.hasAttribute( XML_from
) )
747 double fFrom
= attribs
.getDouble( XML_from
, 0.0 ) / PER_DEGREE
;
748 pNode
->setFrom( makeAny( fFrom
) );
750 if(attribs
.hasAttribute( XML_to
) )
752 double fTo
= attribs
.getDouble( XML_to
, 0.0 ) / PER_DEGREE
;
753 pNode
->setTo( makeAny( fTo
) );
757 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const AttributeList
& /*rAttribs*/ ) override
759 switch ( aElementToken
)
761 case PPT_TOKEN( cBhvr
):
762 return new CommonBehaviorContext ( *this, mpNode
);
771 /** CT_TLAnimateMotionBehavior */
772 class AnimMotionContext
773 : public TimeNodeContext
776 AnimMotionContext( FragmentHandler2
const & rParent
, sal_Int32 aElement
,
777 const Reference
< XFastAttributeList
>& xAttribs
,
778 const TimeNodePtr
& pNode
) noexcept
779 : TimeNodeContext( rParent
, aElement
, pNode
)
781 pNode
->getNodeProperties()[ NP_TRANSFORMTYPE
]
782 <<= sal_Int16(AnimationTransformType::TRANSLATE
);
784 AttributeList
attribs( xAttribs
);
785 sal_Int32 nOrigin
= xAttribs
->getOptionalValueToken( XML_origin
, 0 );
797 OUString aStr
= xAttribs
->getOptionalValue( XML_path
);
798 // E can appear inside a number, so we only check for its presence at the end
800 if (aStr
.endsWith("E"))
801 aStr
= aStr
.copy(0, aStr
.getLength() - 1);
803 pNode
->getNodeProperties()[ NP_PATH
] <<= aStr
;
804 mnPathEditMode
= xAttribs
->getOptionalValueToken( XML_pathEditMode
, 0 );
805 msPtsTypes
= xAttribs
->getOptionalValue( XML_ptsTypes
);
806 mnAngle
= attribs
.getInteger( XML_rAng
, 0 );
807 // TODO make sure the units are right. Likely not.
810 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
) override
812 switch ( aElementToken
)
814 case PPT_TOKEN( cBhvr
):
815 return new CommonBehaviorContext ( *this, mpNode
);
816 case PPT_TOKEN( to
):
819 awt::Point p
= GetPointPercent( rAttribs
.getFastAttributeList() );
823 mpNode
->setTo( rAny
);
826 case PPT_TOKEN( from
):
829 awt::Point p
= GetPointPercent( rAttribs
.getFastAttributeList() );
833 mpNode
->setFrom( rAny
);
836 case PPT_TOKEN( by
):
839 awt::Point p
= GetPointPercent( rAttribs
.getFastAttributeList() );
843 mpNode
->setBy( rAny
);
846 case PPT_TOKEN( rCtr
):
849 awt::Point p
= GetPointPercent( rAttribs
.getFastAttributeList() );
862 sal_Int32 mnPathEditMode
;
866 /** CT_TLAnimateEffectBehavior */
867 class AnimEffectContext
868 : public TimeNodeContext
871 AnimEffectContext( FragmentHandler2
const & rParent
, sal_Int32 aElement
,
872 const Reference
< XFastAttributeList
>& xAttribs
,
873 const TimeNodePtr
& pNode
) noexcept
874 : TimeNodeContext( rParent
, aElement
, pNode
)
876 sal_Int32 nDir
= xAttribs
->getOptionalValueToken( XML_transition
, 0 );
877 OUString sFilter
= xAttribs
->getOptionalValue( XML_filter
);
879 // OUString sPrList = xAttribs->getOptionalValue( XML_prLst );
881 if( !sFilter
.isEmpty() )
883 SlideTransition
aFilter( sFilter
);
884 aFilter
.setMode( nDir
!= XML_out
);
885 pNode
->setTransitionFilter( aFilter
);
889 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const AttributeList
& /*rAttribs*/ ) override
891 switch ( aElementToken
)
893 case PPT_TOKEN( cBhvr
):
894 return new CommonBehaviorContext ( *this, mpNode
);
895 case PPT_TOKEN( progress
):
896 return new AnimVariantContext( *this, aElementToken
, maProgress
);
910 rtl::Reference
<TimeNodeContext
> TimeNodeContext::makeContext(
911 FragmentHandler2
const & rParent
, sal_Int32 aElement
,
912 const Reference
< XFastAttributeList
>& xAttribs
,
913 const TimeNodePtr
& pNode
)
915 rtl::Reference
<TimeNodeContext
> pCtx
;
918 case PPT_TOKEN( animClr
):
919 pCtx
= new AnimColorContext( rParent
, aElement
, xAttribs
, pNode
);
921 case PPT_TOKEN( par
):
922 pCtx
= new ParallelExclTimeNodeContext( rParent
, aElement
, pNode
);
924 case PPT_TOKEN( seq
):
925 pCtx
= new SequenceTimeNodeContext( rParent
, aElement
, xAttribs
, pNode
);
927 case PPT_TOKEN( excl
):
928 pCtx
= new ParallelExclTimeNodeContext( rParent
, aElement
, pNode
);
930 case PPT_TOKEN( anim
):
931 pCtx
= new AnimContext ( rParent
, aElement
, xAttribs
, pNode
);
933 case PPT_TOKEN( animEffect
):
934 pCtx
= new AnimEffectContext( rParent
, aElement
, xAttribs
, pNode
);
936 case PPT_TOKEN( animMotion
):
937 pCtx
= new AnimMotionContext( rParent
, aElement
, xAttribs
, pNode
);
939 case PPT_TOKEN( animRot
):
940 pCtx
= new AnimRotContext( rParent
, aElement
, xAttribs
, pNode
);
942 case PPT_TOKEN( animScale
):
943 pCtx
= new AnimScaleContext( rParent
, aElement
, xAttribs
, pNode
);
945 case PPT_TOKEN( cmd
):
946 pCtx
= new CmdTimeNodeContext( rParent
, aElement
, xAttribs
, pNode
);
948 case PPT_TOKEN( set
):
949 pCtx
= new SetTimeNodeContext( rParent
, aElement
, pNode
);
951 case PPT_TOKEN( audio
):
952 case PPT_TOKEN( video
):
953 pCtx
= new MediaNodeContext( rParent
, aElement
, xAttribs
, pNode
);
961 TimeNodeContext::TimeNodeContext( FragmentHandler2
const & rParent
, sal_Int32 aElement
,
962 const TimeNodePtr
& pNode
) noexcept
963 : FragmentHandler2( rParent
)
964 , mnElement( aElement
)
969 TimeNodeContext::~TimeNodeContext( ) noexcept
974 TimeNodeListContext::TimeNodeListContext( FragmentHandler2
const & rParent
, TimeNodePtrList
& aList
)
976 : FragmentHandler2( rParent
)
981 TimeNodeListContext::~TimeNodeListContext( ) noexcept
985 ::oox::core::ContextHandlerRef
TimeNodeListContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
)
989 switch( aElementToken
)
991 case PPT_TOKEN( par
):
992 nNodeType
= AnimationNodeType::PAR
;
994 case PPT_TOKEN( seq
):
995 nNodeType
= AnimationNodeType::SEQ
;
997 case PPT_TOKEN( excl
):
998 // TODO pick the right type. We choose parallel for now as
999 // there does not seem to be an "Exclusive"
1000 nNodeType
= AnimationNodeType::PAR
;
1002 case PPT_TOKEN( anim
):
1003 nNodeType
= AnimationNodeType::ANIMATE
;
1005 case PPT_TOKEN( animClr
):
1006 nNodeType
= AnimationNodeType::ANIMATECOLOR
;
1008 case PPT_TOKEN( animEffect
):
1009 nNodeType
= AnimationNodeType::TRANSITIONFILTER
;
1011 case PPT_TOKEN( animMotion
):
1012 nNodeType
= AnimationNodeType::ANIMATEMOTION
;
1014 case PPT_TOKEN( animRot
):
1015 case PPT_TOKEN( animScale
):
1016 nNodeType
= AnimationNodeType::ANIMATETRANSFORM
;
1018 case PPT_TOKEN( cmd
):
1019 nNodeType
= AnimationNodeType::COMMAND
;
1021 case PPT_TOKEN( set
):
1022 nNodeType
= AnimationNodeType::SET
;
1024 case PPT_TOKEN( audio
):
1025 nNodeType
= AnimationNodeType::AUDIO
;
1027 case PPT_TOKEN( video
):
1028 nNodeType
= AnimationNodeType::AUDIO
;
1029 SAL_WARN("oox.ppt", "OOX: video requested, gave Audio instead" );
1033 nNodeType
= AnimationNodeType::CUSTOM
;
1034 SAL_INFO("oox.ppt", "unhandled token " << aElementToken
);
1038 TimeNodePtr pNode
= std::make_shared
<TimeNode
>(nNodeType
);
1039 maList
.push_back( pNode
);
1040 rtl::Reference
<FragmentHandler2
> pContext
= TimeNodeContext::makeContext( *this, aElementToken
, rAttribs
.getFastAttributeList(), pNode
);
1042 return pContext
? pContext
: this;
1047 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */