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 <comphelper/diagnose_ex.hxx>
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>
41 #include <o3tl/string_view.hxx>
44 #include "animvariantcontext.hxx"
45 #include "commonbehaviorcontext.hxx"
46 #include "conditioncontext.hxx"
47 #include "commontimenodecontext.hxx"
48 #include "timeanimvaluecontext.hxx"
49 #include "animationtypes.hxx"
50 #include "timetargetelementcontext.hxx"
52 using namespace ::oox::core
;
53 using namespace ::oox::drawingml
;
54 using namespace ::com::sun::star
;
55 using namespace ::com::sun::star::uno
;
56 using namespace ::com::sun::star::lang
;
57 using namespace ::com::sun::star::animations
;
58 using namespace ::com::sun::star::presentation
;
59 using namespace ::com::sun::star::xml::sax
;
60 using ::com::sun::star::beans::NamedValue
;
64 oox::ppt::AnimationAttributeEnum
getAttributeEnumByAPIName(std::u16string_view rAPIName
)
66 oox::ppt::AnimationAttributeEnum eResult
= oox::ppt::AnimationAttributeEnum::UNKNOWN
;
67 const oox::ppt::ImplAttributeNameConversion
*attrConv
= oox::ppt::getAttributeConversionList();
68 while(attrConv
->mpAPIName
!= nullptr)
70 if(o3tl::equalsAscii(rAPIName
, attrConv
->mpAPIName
))
72 eResult
= attrConv
->meAttribute
;
80 bool convertAnimationValueWithTimeNode(const oox::ppt::TimeNodePtr
& pNode
, css::uno::Any
&rAny
)
82 css::uno::Any aAny
= pNode
->getNodeProperties()[oox::ppt::NP_ATTRIBUTENAME
];
86 // only get first token.
87 return oox::ppt::convertAnimationValue(getAttributeEnumByAPIName(o3tl::getToken(aNameList
, 0, ';')), rAny
);
90 css::uno::Any
convertPointPercent(const css::awt::Point
& rPoint
)
92 css::animations::ValuePair aPair
;
93 // rPoint.X and rPoint.Y are in 1000th of a percent, but we only need ratio.
94 aPair
.First
<<= static_cast<double>(rPoint
.X
) / 100000.0;
95 aPair
.Second
<<= static_cast<double>(rPoint
.Y
) / 100000.0;
106 AnimColor(sal_Int16 cs
, sal_Int32 o
, sal_Int32 t
, sal_Int32 th
)
107 : colorSpace( cs
), one( o
), two( t
), three( th
)
118 case AnimationColorSpace::HSL
:
119 aColor
<<= Sequence
< double >{ one
/ 100000.0, two
/ 100000.0, three
/ 100000.0 };
121 case AnimationColorSpace::RGB
:
122 nColor
= ( ( ( one
* 128 ) / 1000 ) & 0xff ) << 16
123 | ( ( ( two
* 128 ) / 1000 ) & 0xff ) << 8
124 | ( ( ( three
* 128 ) / 1000 ) & 0xff );
135 sal_Int16 colorSpace
;
141 /** CT_TLMediaNodeAudio
142 CT_TLMediaNodeVideo */
143 class MediaNodeContext
144 : public TimeNodeContext
147 MediaNodeContext( FragmentHandler2
const & rParent
, sal_Int32 aElement
,
148 const Reference
< XFastAttributeList
>& xAttribs
,
149 const TimeNodePtr
& pNode
)
150 : TimeNodeContext( rParent
, aElement
, pNode
)
151 , mbIsNarration( false )
152 , mbFullScrn( false )
153 , mbHideDuringShow(false)
155 AttributeList
attribs( xAttribs
);
159 case PPT_TOKEN( audio
):
160 mbIsNarration
= attribs
.getBool( XML_isNarration
, false );
162 case PPT_TOKEN( video
):
163 mbFullScrn
= attribs
.getBool( XML_fullScrn
, false );
170 virtual void onEndElement() override
172 sal_Int32 aElement
= getCurrentElement();
173 if( aElement
== PPT_TOKEN( audio
) )
175 mpNode
->getNodeProperties()[NP_ISNARRATION
] <<= mbIsNarration
;
177 else if( aElement
== PPT_TOKEN( video
) )
179 // TODO deal with mbFullScrn
181 else if (aElement
== PPT_TOKEN(cMediaNode
))
183 mpNode
->getNodeProperties()[NP_HIDEDURINGSHOW
] <<= mbHideDuringShow
;
187 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
) override
189 switch ( aElementToken
)
191 case PPT_TOKEN( cTn
):
192 return new CommonTimeNodeContext( *this, aElementToken
, rAttribs
.getFastAttributeList(), mpNode
);
193 case PPT_TOKEN( tgtEl
):
194 return new TimeTargetElementContext( *this, mpNode
->getTarget() );
195 case PPT_TOKEN(cMediaNode
):
196 mbHideDuringShow
= !rAttribs
.getBool(XML_showWhenStopped
, true);
208 bool mbHideDuringShow
;
213 class SetTimeNodeContext
214 : public TimeNodeContext
217 SetTimeNodeContext( FragmentHandler2
const & rParent
, sal_Int32 aElement
,
218 const TimeNodePtr
& pNode
)
219 : TimeNodeContext( rParent
, aElement
, pNode
)
224 virtual ~SetTimeNodeContext() noexcept override
228 convertAnimationValueWithTimeNode(mpNode
, maTo
);
234 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const AttributeList
& /*rAttribs*/ ) override
236 switch ( aElementToken
)
238 case PPT_TOKEN( cBhvr
):
239 return new CommonBehaviorContext ( *this, mpNode
);
240 case PPT_TOKEN( to
):
242 return new AnimVariantContext( *this, aElementToken
, maTo
);
253 /** CT_TLCommandBehavior
255 class CmdTimeNodeContext
256 : public TimeNodeContext
259 CmdTimeNodeContext( FragmentHandler2
const & rParent
, sal_Int32 aElement
,
260 const Reference
< XFastAttributeList
>& xAttribs
,
261 const TimeNodePtr
& pNode
)
262 : TimeNodeContext( rParent
, aElement
, pNode
)
267 case PPT_TOKEN( cmd
):
268 msCommand
= xAttribs
->getOptionalValue( XML_cmd
);
269 maType
= xAttribs
->getOptionalValueToken( XML_type
, 0 );
276 virtual void onEndElement() override
278 if( !isCurrentElement( PPT_TOKEN( cmd
) ) )
282 // see sd/source/filter/ppt/pptinanimations.cxx
283 // in AnimationImporter::importCommandContainer()
285 // a good chunk of this code has been copied verbatim *sigh*
286 sal_Int16 nCommand
= EffectCommands::CUSTOM
;
287 NamedValue aParamValue
;
292 aParamValue
.Name
= "Verb";
293 // TODO make sure msCommand has what we want
294 aParamValue
.Value
<<= msCommand
.toInt32();
295 nCommand
= EffectCommands::VERB
;
299 if ( msCommand
== "onstopaudio" )
301 nCommand
= EffectCommands::STOPAUDIO
;
303 else if ( msCommand
== "play" )
305 nCommand
= EffectCommands::PLAY
;
307 else if (msCommand
.startsWith("playFrom"))
309 std::u16string_view
aMediaTime( msCommand
.subView( 9, msCommand
.getLength() - 10 ) );
310 rtl_math_ConversionStatus eStatus
;
311 double fMediaTime
= ::rtl::math::stringToDouble( aMediaTime
, u
'.', u
',', &eStatus
);
312 if( eStatus
== rtl_math_ConversionStatus_Ok
)
314 aParamValue
.Name
= "MediaTime";
315 aParamValue
.Value
<<= fMediaTime
;
317 nCommand
= EffectCommands::PLAY
;
319 else if ( msCommand
== "togglePause" )
321 nCommand
= EffectCommands::TOGGLEPAUSE
;
323 else if ( msCommand
== "stop" )
325 nCommand
= EffectCommands::STOP
;
329 mpNode
->getNodeProperties()[ NP_COMMAND
] <<= nCommand
;
330 if( nCommand
== EffectCommands::CUSTOM
)
332 SAL_WARN("oox.ppt", "OOX: CmdTimeNodeContext::endFastElement(), unknown command!");
333 aParamValue
.Name
= "UserDefined";
334 aParamValue
.Value
<<= msCommand
;
336 if( aParamValue
.Value
.hasValue() )
338 Sequence
< NamedValue
> aParamSeq( &aParamValue
, 1 );
339 mpNode
->getNodeProperties()[ NP_PARAMETER
] <<= aParamSeq
;
342 catch( RuntimeException
& )
344 TOOLS_WARN_EXCEPTION("oox.ppt", "OOX: Exception in CmdTimeNodeContext::endFastElement()" );
348 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const AttributeList
& /*rAttribs*/ ) override
350 switch ( aElementToken
)
352 case PPT_TOKEN( cBhvr
):
353 return new CommonBehaviorContext ( *this, mpNode
);
366 /** CT_TLTimeNodeSequence
368 class SequenceTimeNodeContext
369 : public TimeNodeContext
372 SequenceTimeNodeContext( FragmentHandler2
const & rParent
, sal_Int32 aElement
,
373 const Reference
< XFastAttributeList
>& xAttribs
,
374 const TimeNodePtr
& pNode
)
375 : TimeNodeContext( rParent
, aElement
, pNode
)
379 AttributeList
attribs(xAttribs
);
380 mbConcurrent
= attribs
.getBool( XML_concurrent
, false );
381 mnNextAc
= xAttribs
->getOptionalValueToken( XML_nextAc
, 0 );
382 mnPrevAc
= xAttribs
->getOptionalValueToken( XML_prevAc
, 0 );
385 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
) override
387 switch ( aElementToken
)
389 case PPT_TOKEN( cTn
):
390 return new CommonTimeNodeContext( *this, aElementToken
, rAttribs
.getFastAttributeList(), mpNode
);
391 case PPT_TOKEN( nextCondLst
):
392 return new CondListContext( *this, aElementToken
, mpNode
, mpNode
->getNextCondition() );
393 case PPT_TOKEN( prevCondLst
):
394 return new CondListContext( *this, aElementToken
, mpNode
, mpNode
->getPrevCondition() );
403 sal_Int32 mnNextAc
, mnPrevAc
;
406 /** CT_TLTimeNodeParallel
407 * CT_TLTimeNodeExclusive
409 class ParallelExclTimeNodeContext
410 : public TimeNodeContext
413 ParallelExclTimeNodeContext( FragmentHandler2
const & rParent
, sal_Int32 aElement
,
414 const TimeNodePtr
& pNode
)
415 : TimeNodeContext( rParent
, aElement
, pNode
)
419 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
) override
421 switch ( aElementToken
)
423 case PPT_TOKEN( cTn
):
424 return new CommonTimeNodeContext( *this, aElementToken
, rAttribs
.getFastAttributeList(), mpNode
);
436 /** CT_TLAnimateColorBehavior */
437 class AnimColorContext
438 : public TimeNodeContext
441 AnimColorContext( FragmentHandler2
const & rParent
, sal_Int32 aElement
,
442 const Reference
< XFastAttributeList
>& xAttribs
,
443 const TimeNodePtr
& pNode
) noexcept
444 : TimeNodeContext( rParent
, aElement
, pNode
)
445 , mnColorSpace( xAttribs
->getOptionalValueToken( XML_clrSpc
, 0 ) )
446 , mnDir( xAttribs
->getOptionalValueToken( XML_dir
, 0 ) )
447 , mbHasByColor( false )
448 , m_byColor( AnimationColorSpace::RGB
, 0, 0, 0)
452 virtual void onEndElement() override
455 if( !isCurrentElement( mnElement
) )
458 NodePropertyMap
& rProps(mpNode
->getNodeProperties());
459 rProps
[ NP_DIRECTION
] <<= mnDir
== XML_cw
;
460 rProps
[ NP_COLORINTERPOLATION
] <<= mnColorSpace
== XML_hsl
? AnimationColorSpace::HSL
: AnimationColorSpace::RGB
;
461 const GraphicHelper
& rGraphicHelper
= getFilter().getGraphicHelper();
462 if( maToClr
.isUsed() )
463 mpNode
->setTo( Any( maToClr
.getColor( rGraphicHelper
) ) );
464 if( maFromClr
.isUsed() )
465 mpNode
->setFrom( Any( maFromClr
.getColor( rGraphicHelper
) ) );
467 mpNode
->setBy( m_byColor
.get() );
470 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
) override
472 switch ( aElementToken
)
474 case PPT_TOKEN( hsl
):
475 // CT_TLByHslColorTransform
479 m_byColor
.colorSpace
= AnimationColorSpace::HSL
;
480 m_byColor
.one
= rAttribs
.getInteger( XML_h
, 0 );
481 m_byColor
.two
= rAttribs
.getInteger( XML_s
, 0 );
482 m_byColor
.three
= rAttribs
.getInteger( XML_l
, 0 );
486 case PPT_TOKEN( rgb
):
490 // CT_TLByRgbColorTransform
491 m_byColor
.colorSpace
= AnimationColorSpace::RGB
;
492 m_byColor
.one
= rAttribs
.getInteger( XML_r
, 0 );
493 m_byColor
.two
= rAttribs
.getInteger( XML_g
, 0 );
494 m_byColor
.three
= rAttribs
.getInteger( XML_b
, 0 );
498 case PPT_TOKEN( by
):
499 // CT_TLByAnimateColorTransform
502 case PPT_TOKEN( cBhvr
):
503 return new CommonBehaviorContext ( *this, mpNode
);
504 case PPT_TOKEN( to
):
506 return new ColorContext( *this, maToClr
);
507 case PPT_TOKEN( from
):
509 return new ColorContext( *this, maFromClr
);
519 sal_Int32 mnColorSpace
;
523 oox::drawingml::Color maToClr
;
524 oox::drawingml::Color maFromClr
;
527 /** CT_TLAnimateBehavior */
529 : public TimeNodeContext
532 AnimContext( FragmentHandler2
const & rParent
, sal_Int32 aElement
,
533 const Reference
< XFastAttributeList
>& xAttribs
,
534 const TimeNodePtr
& pNode
) noexcept
535 : TimeNodeContext( rParent
, aElement
, pNode
)
537 NodePropertyMap
& aProps( pNode
->getNodeProperties() );
538 sal_Int32 nCalcMode
= xAttribs
->getOptionalValueToken( XML_calcmode
, 0 );
545 nEnum
= AnimationCalcMode::DISCRETE
;
548 nEnum
= AnimationCalcMode::LINEAR
;
552 // TODO what value is good ?
553 nEnum
= AnimationCalcMode::DISCRETE
;
556 aProps
[ NP_CALCMODE
] <<= nEnum
;
559 msFrom
= xAttribs
->getOptionalValue(XML_from
);
560 msTo
= xAttribs
->getOptionalValue(XML_to
);
561 msBy
= xAttribs
->getOptionalValue(XML_by
);
563 mnValueType
= xAttribs
->getOptionalValueToken( XML_valueType
, 0 );
566 virtual ~AnimContext() noexcept override
568 if (!msFrom
.isEmpty())
572 convertAnimationValueWithTimeNode(mpNode
, aAny
);
573 mpNode
->setFrom(aAny
);
580 convertAnimationValueWithTimeNode(mpNode
, aAny
);
588 convertAnimationValueWithTimeNode(mpNode
, aAny
);
592 int nKeyTimes
= maTavList
.size();
597 Sequence
< double > aKeyTimes( nKeyTimes
);
598 auto pKeyTimes
= aKeyTimes
.getArray();
599 Sequence
< Any
> aValues( nKeyTimes
);
600 auto pValues
= aValues
.getArray();
602 NodePropertyMap
& aProps( mpNode
->getNodeProperties() );
603 for (auto const& tav
: maTavList
)
605 // TODO what to do if it is Timing_INFINITE ?
606 Any aTime
= GetTimeAnimateValueTime( tav
.msTime
);
607 aTime
>>= pKeyTimes
[i
];
608 pValues
[i
] = tav
.maValue
;
609 convertAnimationValueWithTimeNode(mpNode
, pValues
[i
]);
611 // Examine pptx documents and find that only the first tav
612 // has the formula set. The formula can be used for the whole.
613 if (!tav
.msFormula
.isEmpty())
615 OUString sFormula
= tav
.msFormula
;
616 (void)convertMeasure(sFormula
);
617 aProps
[NP_FORMULA
] <<= sFormula
;
622 aProps
[ NP_VALUES
] <<= aValues
;
623 aProps
[ NP_KEYTIMES
] <<= aKeyTimes
;
626 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const AttributeList
& /*rAttribs*/ ) override
628 switch ( aElementToken
)
630 case PPT_TOKEN( cBhvr
):
631 return new CommonBehaviorContext ( *this, mpNode
);
632 case PPT_TOKEN( tavLst
):
633 return new TimeAnimValueListContext ( *this, maTavList
);
641 sal_Int32 mnValueType
;
642 TimeAnimationValueList maTavList
;
648 /** CT_TLAnimateScaleBehavior */
649 class AnimScaleContext
650 : public TimeNodeContext
653 AnimScaleContext( FragmentHandler2
const & rParent
, sal_Int32 aElement
,
654 const Reference
< XFastAttributeList
>& xAttribs
,
655 const TimeNodePtr
& pNode
)
656 : TimeNodeContext( rParent
, aElement
, pNode
)
657 , mbZoomContents( false )
659 AttributeList
attribs( xAttribs
);
660 // TODO what to do with mbZoomContents
661 mbZoomContents
= attribs
.getBool( XML_zoomContents
, false );
662 pNode
->getNodeProperties()[ NP_TRANSFORMTYPE
]
663 <<= sal_Int16(AnimationTransformType::SCALE
);
666 virtual void onEndElement() override
668 if( !isCurrentElement( mnElement
) )
671 if( maTo
.hasValue() )
673 mpNode
->setTo( maTo
);
675 if( maBy
.hasValue() )
677 mpNode
->setBy( maBy
);
679 if( maFrom
.hasValue() )
681 mpNode
->setFrom( maFrom
);
685 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
) override
687 switch ( aElementToken
)
689 case PPT_TOKEN( cBhvr
):
690 return new CommonBehaviorContext ( *this, mpNode
);
691 case PPT_TOKEN( to
):
694 maTo
= convertPointPercent(GetPointPercent(rAttribs
.getFastAttributeList()));
697 case PPT_TOKEN( from
):
700 maFrom
= convertPointPercent(GetPointPercent(rAttribs
.getFastAttributeList()));
703 case PPT_TOKEN( by
):
706 css::awt::Point aPoint
= GetPointPercent(rAttribs
.getFastAttributeList());
707 // We got ending values instead of offset values, so subtract 100% from them.
710 maBy
= convertPointPercent(aPoint
);
726 /** CT_TLAnimateRotationBehavior */
728 : public TimeNodeContext
731 AnimRotContext( FragmentHandler2
const & rParent
, sal_Int32 aElement
,
732 const Reference
< XFastAttributeList
>& xAttribs
,
733 const TimeNodePtr
& pNode
) noexcept
734 : TimeNodeContext( rParent
, aElement
, pNode
)
736 AttributeList
attribs( xAttribs
);
738 pNode
->getNodeProperties()[ NP_TRANSFORMTYPE
]
739 <<= sal_Int16(AnimationTransformType::ROTATE
);
740 // see also DFF_msofbtAnimateRotationData in
741 // sd/source/filter/ppt/pptinanimations.cxx
742 if(attribs
.hasAttribute( XML_by
) )
744 double fBy
= attribs
.getDouble( XML_by
, 0.0 ) / PER_DEGREE
; //1 PowerPoint-angle-unit = 1/60000 degree
745 pNode
->setBy( Any( fBy
) );
747 if(attribs
.hasAttribute( XML_from
) )
749 double fFrom
= attribs
.getDouble( XML_from
, 0.0 ) / PER_DEGREE
;
750 pNode
->setFrom( Any( fFrom
) );
752 if(attribs
.hasAttribute( XML_to
) )
754 double fTo
= attribs
.getDouble( XML_to
, 0.0 ) / PER_DEGREE
;
755 pNode
->setTo( Any( fTo
) );
759 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const AttributeList
& /*rAttribs*/ ) override
761 switch ( aElementToken
)
763 case PPT_TOKEN( cBhvr
):
764 return new CommonBehaviorContext ( *this, mpNode
);
773 /** CT_TLAnimateMotionBehavior */
774 class AnimMotionContext
775 : public TimeNodeContext
778 AnimMotionContext( FragmentHandler2
const & rParent
, sal_Int32 aElement
,
779 const Reference
< XFastAttributeList
>& xAttribs
,
780 const TimeNodePtr
& pNode
) noexcept
781 : TimeNodeContext( rParent
, aElement
, pNode
)
783 pNode
->getNodeProperties()[ NP_TRANSFORMTYPE
]
784 <<= sal_Int16(AnimationTransformType::TRANSLATE
);
786 AttributeList
attribs( xAttribs
);
787 sal_Int32 nOrigin
= xAttribs
->getOptionalValueToken( XML_origin
, 0 );
799 OUString aStr
= xAttribs
->getOptionalValue( XML_path
);
800 // E can appear inside a number, so we only check for its presence at the end
802 if (aStr
.endsWith("E"))
803 aStr
= aStr
.copy(0, aStr
.getLength() - 1);
805 pNode
->getNodeProperties()[ NP_PATH
] <<= aStr
;
806 mnPathEditMode
= xAttribs
->getOptionalValueToken( XML_pathEditMode
, 0 );
807 msPtsTypes
= xAttribs
->getOptionalValue( XML_ptsTypes
);
808 mnAngle
= attribs
.getInteger( XML_rAng
, 0 );
809 // TODO make sure the units are right. Likely not.
812 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
) override
814 switch ( aElementToken
)
816 case PPT_TOKEN( cBhvr
):
817 return new CommonBehaviorContext ( *this, mpNode
);
818 case PPT_TOKEN( to
):
821 awt::Point p
= GetPointPercent( rAttribs
.getFastAttributeList() );
825 mpNode
->setTo( rAny
);
828 case PPT_TOKEN( from
):
831 awt::Point p
= GetPointPercent( rAttribs
.getFastAttributeList() );
835 mpNode
->setFrom( rAny
);
838 case PPT_TOKEN( by
):
841 awt::Point p
= GetPointPercent( rAttribs
.getFastAttributeList() );
845 mpNode
->setBy( rAny
);
848 case PPT_TOKEN( rCtr
):
851 awt::Point p
= GetPointPercent( rAttribs
.getFastAttributeList() );
864 sal_Int32 mnPathEditMode
;
868 /** CT_TLAnimateEffectBehavior */
869 class AnimEffectContext
870 : public TimeNodeContext
873 AnimEffectContext( FragmentHandler2
const & rParent
, sal_Int32 aElement
,
874 const Reference
< XFastAttributeList
>& xAttribs
,
875 const TimeNodePtr
& pNode
) noexcept
876 : TimeNodeContext( rParent
, aElement
, pNode
)
878 sal_Int32 nDir
= xAttribs
->getOptionalValueToken( XML_transition
, 0 );
879 OUString sFilter
= xAttribs
->getOptionalValue( XML_filter
);
881 // OUString sPrList = xAttribs->getOptionalValue( XML_prLst );
883 if( !sFilter
.isEmpty() )
885 SlideTransition
aFilter( sFilter
);
886 aFilter
.setMode( nDir
!= XML_out
);
887 pNode
->setTransitionFilter( aFilter
);
891 virtual ::oox::core::ContextHandlerRef
onCreateContext( sal_Int32 aElementToken
, const AttributeList
& /*rAttribs*/ ) override
893 switch ( aElementToken
)
895 case PPT_TOKEN( cBhvr
):
896 return new CommonBehaviorContext ( *this, mpNode
);
897 case PPT_TOKEN( progress
):
898 return new AnimVariantContext( *this, aElementToken
, maProgress
);
912 rtl::Reference
<TimeNodeContext
> TimeNodeContext::makeContext(
913 FragmentHandler2
const & rParent
, sal_Int32 aElement
,
914 const Reference
< XFastAttributeList
>& xAttribs
,
915 const TimeNodePtr
& pNode
)
917 rtl::Reference
<TimeNodeContext
> pCtx
;
920 case PPT_TOKEN( animClr
):
921 pCtx
= new AnimColorContext( rParent
, aElement
, xAttribs
, pNode
);
923 case PPT_TOKEN( par
):
924 pCtx
= new ParallelExclTimeNodeContext( rParent
, aElement
, pNode
);
926 case PPT_TOKEN( seq
):
927 pCtx
= new SequenceTimeNodeContext( rParent
, aElement
, xAttribs
, pNode
);
929 case PPT_TOKEN( excl
):
930 pCtx
= new ParallelExclTimeNodeContext( rParent
, aElement
, pNode
);
932 case PPT_TOKEN( anim
):
933 pCtx
= new AnimContext ( rParent
, aElement
, xAttribs
, pNode
);
935 case PPT_TOKEN( animEffect
):
936 pCtx
= new AnimEffectContext( rParent
, aElement
, xAttribs
, pNode
);
938 case PPT_TOKEN( animMotion
):
939 pCtx
= new AnimMotionContext( rParent
, aElement
, xAttribs
, pNode
);
941 case PPT_TOKEN( animRot
):
942 pCtx
= new AnimRotContext( rParent
, aElement
, xAttribs
, pNode
);
944 case PPT_TOKEN( animScale
):
945 pCtx
= new AnimScaleContext( rParent
, aElement
, xAttribs
, pNode
);
947 case PPT_TOKEN( cmd
):
948 pCtx
= new CmdTimeNodeContext( rParent
, aElement
, xAttribs
, pNode
);
950 case PPT_TOKEN( set
):
951 pCtx
= new SetTimeNodeContext( rParent
, aElement
, pNode
);
953 case PPT_TOKEN( audio
):
954 case PPT_TOKEN( video
):
955 pCtx
= new MediaNodeContext( rParent
, aElement
, xAttribs
, pNode
);
963 TimeNodeContext::TimeNodeContext( FragmentHandler2
const & rParent
, sal_Int32 aElement
,
964 TimeNodePtr pNode
) noexcept
965 : FragmentHandler2( rParent
)
966 , mnElement( aElement
)
967 , mpNode(std::move( pNode
))
971 TimeNodeContext::~TimeNodeContext( ) noexcept
976 TimeNodeListContext::TimeNodeListContext( FragmentHandler2
const & rParent
, TimeNodePtrList
& aList
)
978 : FragmentHandler2( rParent
)
983 TimeNodeListContext::~TimeNodeListContext( ) noexcept
987 ::oox::core::ContextHandlerRef
TimeNodeListContext::onCreateContext( sal_Int32 aElementToken
, const AttributeList
& rAttribs
)
991 switch( aElementToken
)
993 case PPT_TOKEN( par
):
994 nNodeType
= AnimationNodeType::PAR
;
996 case PPT_TOKEN( seq
):
997 nNodeType
= AnimationNodeType::SEQ
;
999 case PPT_TOKEN( excl
):
1000 // TODO pick the right type. We choose parallel for now as
1001 // there does not seem to be an "Exclusive"
1002 nNodeType
= AnimationNodeType::PAR
;
1004 case PPT_TOKEN( anim
):
1005 nNodeType
= AnimationNodeType::ANIMATE
;
1007 case PPT_TOKEN( animClr
):
1008 nNodeType
= AnimationNodeType::ANIMATECOLOR
;
1010 case PPT_TOKEN( animEffect
):
1011 nNodeType
= AnimationNodeType::TRANSITIONFILTER
;
1013 case PPT_TOKEN( animMotion
):
1014 nNodeType
= AnimationNodeType::ANIMATEMOTION
;
1016 case PPT_TOKEN( animRot
):
1017 case PPT_TOKEN( animScale
):
1018 nNodeType
= AnimationNodeType::ANIMATETRANSFORM
;
1020 case PPT_TOKEN( cmd
):
1021 nNodeType
= AnimationNodeType::COMMAND
;
1023 case PPT_TOKEN( set
):
1024 nNodeType
= AnimationNodeType::SET
;
1026 case PPT_TOKEN( audio
):
1027 nNodeType
= AnimationNodeType::AUDIO
;
1029 case PPT_TOKEN( video
):
1030 nNodeType
= AnimationNodeType::AUDIO
;
1031 SAL_WARN("oox.ppt", "OOX: video requested, gave Audio instead" );
1035 nNodeType
= AnimationNodeType::CUSTOM
;
1036 SAL_INFO("oox.ppt", "unhandled token " << aElementToken
);
1040 TimeNodePtr pNode
= std::make_shared
<TimeNode
>(nNodeType
);
1041 maList
.push_back( pNode
);
1042 rtl::Reference
<FragmentHandler2
> pContext
= TimeNodeContext::makeContext( *this, aElementToken
, rAttribs
.getFastAttributeList(), pNode
);
1044 return pContext
? pContext
: this;
1049 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */