Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / oox / source / ppt / timenodelistcontext.cxx
blobb965dfea1b6fbda3d14cb17df4244c65fa552347
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 <cppuhelper/exc_hlp.hxx>
23 #include <rtl/math.hxx>
24 #include <sal/log.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/lang/XMultiServiceFactory.hpp>
32 #include <com/sun/star/presentation/EffectCommands.hpp>
33 #include <com/sun/star/beans/NamedValue.hpp>
35 #include <oox/helper/attributelist.hxx>
36 #include <oox/core/xmlfilterbase.hxx>
37 #include <oox/drawingml/drawingmltypes.hxx>
38 #include <drawingml/colorchoicecontext.hxx>
39 #include <oox/ppt/slidetransition.hxx>
40 #include <oox/token/namespaces.hxx>
41 #include <oox/token/tokens.hxx>
43 #include "animvariantcontext.hxx"
44 #include "commonbehaviorcontext.hxx"
45 #include "conditioncontext.hxx"
46 #include "commontimenodecontext.hxx"
47 #include "timeanimvaluecontext.hxx"
48 #include "animationtypes.hxx"
49 #include "timetargetelementcontext.hxx"
51 using namespace ::oox::core;
52 using namespace ::oox::drawingml;
53 using namespace ::com::sun::star;
54 using namespace ::com::sun::star::uno;
55 using namespace ::com::sun::star::lang;
56 using namespace ::com::sun::star::animations;
57 using namespace ::com::sun::star::presentation;
58 using namespace ::com::sun::star::xml::sax;
59 using ::com::sun::star::beans::NamedValue;
61 namespace {
63 oox::ppt::AnimationAttributeEnum getAttributeEnumByAPIName(const OUString &rAPIName)
65 oox::ppt::AnimationAttributeEnum eResult = oox::ppt::AnimationAttributeEnum::UNKNOWN;
66 const oox::ppt::ImplAttributeNameConversion *attrConv = oox::ppt::getAttributeConversionList();
67 while(attrConv->mpAPIName != nullptr)
69 if(rAPIName.equalsAscii(attrConv->mpAPIName))
71 eResult = attrConv->meAttribute;
72 break;
74 attrConv++;
76 return eResult;
79 bool convertAnimationValueWithTimeNode(const oox::ppt::TimeNodePtr& pNode, css::uno::Any &rAny)
81 css::uno::Any aAny = pNode->getNodeProperties()[oox::ppt::NP_ATTRIBUTENAME];
82 OUString aNameList;
83 aAny >>= aNameList;
85 // only get first token.
86 return oox::ppt::convertAnimationValue(getAttributeEnumByAPIName(aNameList.getToken(0, ';')), rAny);
89 css::uno::Any convertPointPercent(const css::awt::Point& rPoint)
91 css::animations::ValuePair aPair;
92 // rPoint.X and rPoint.Y are in 1000th of a percent, but we only need ratio.
93 aPair.First <<= static_cast<double>(rPoint.X) / 100000.0;
94 aPair.Second <<= static_cast<double>(rPoint.Y) / 100000.0;
95 return makeAny(aPair);
99 namespace oox { namespace ppt {
101 struct AnimColor
103 AnimColor(sal_Int16 cs, sal_Int32 o, sal_Int32 t, sal_Int32 th )
104 : colorSpace( cs ), one( o ), two( t ), three( th )
108 Any get() const
110 sal_Int32 nColor;
111 Sequence< double > aHSL( 3 );
112 Any aColor;
114 switch( colorSpace )
116 case AnimationColorSpace::HSL:
117 aHSL[ 0 ] = double(one) / 100000;
118 aHSL[ 1 ] = double(two) / 100000;
119 aHSL[ 2 ] = double(three) / 100000;
120 aColor <<= aHSL;
121 break;
122 case AnimationColorSpace::RGB:
123 nColor = ( ( ( one * 128 ) / 1000 ) & 0xff ) << 16
124 | ( ( ( two * 128 ) / 1000 ) & 0xff ) << 8
125 | ( ( ( three * 128 ) / 1000 ) & 0xff );
126 aColor <<= nColor;
127 break;
128 default:
129 nColor = 0;
130 aColor <<= nColor;
131 break;
133 return aColor;
136 sal_Int16 colorSpace;
137 sal_Int32 one;
138 sal_Int32 two;
139 sal_Int32 three;
142 /** CT_TLMediaNodeAudio
143 CT_TLMediaNodeVideo */
144 class MediaNodeContext
145 : public TimeNodeContext
147 public:
148 MediaNodeContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
149 const Reference< XFastAttributeList >& xAttribs,
150 const TimeNodePtr & pNode )
151 : TimeNodeContext( rParent, aElement, pNode )
152 , mbIsNarration( false )
153 , mbFullScrn( false )
155 AttributeList attribs( xAttribs );
157 switch( aElement )
159 case PPT_TOKEN( audio ):
160 mbIsNarration = attribs.getBool( XML_isNarration, false );
161 break;
162 case PPT_TOKEN( video ):
163 mbFullScrn = attribs.getBool( XML_fullScrn, false );
164 break;
165 default:
166 break;
170 virtual void onEndElement() override
172 sal_Int32 aElement = getCurrentElement();
173 if( aElement == PPT_TOKEN( audio ) )
175 // TODO deal with mbIsNarration
177 else if( aElement == PPT_TOKEN( video ) )
179 // TODO deal with mbFullScrn
183 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs) override
185 switch ( aElementToken )
187 case PPT_TOKEN( cTn ):
188 return new CommonTimeNodeContext( *this, aElementToken, rAttribs.getFastAttributeList(), mpNode );
189 case PPT_TOKEN( tgtEl ):
190 return new TimeTargetElementContext( *this, mpNode->getTarget() );
191 default:
192 break;
195 return this;
198 private:
199 bool mbIsNarration;
200 bool mbFullScrn;
203 /** CT_TLSetBehavior
205 class SetTimeNodeContext
206 : public TimeNodeContext
208 public:
209 SetTimeNodeContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
210 const TimeNodePtr & pNode )
211 : TimeNodeContext( rParent, aElement, pNode )
216 virtual ~SetTimeNodeContext() throw () override
218 if(maTo.hasValue())
220 convertAnimationValueWithTimeNode(mpNode, maTo);
221 mpNode->setTo(maTo);
226 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& /*rAttribs*/ ) override
228 switch ( aElementToken )
230 case PPT_TOKEN( cBhvr ):
231 return new CommonBehaviorContext ( *this, mpNode );
232 case PPT_TOKEN( to ):
233 // CT_TLAnimVariant
234 return new AnimVariantContext( *this, aElementToken, maTo );
235 default:
236 break;
239 return this;
241 private:
242 Any maTo;
245 /** CT_TLCommandBehavior
247 class CmdTimeNodeContext
248 : public TimeNodeContext
250 public:
251 CmdTimeNodeContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
252 const Reference< XFastAttributeList >& xAttribs,
253 const TimeNodePtr & pNode )
254 : TimeNodeContext( rParent, aElement, pNode )
255 , maType(0)
257 switch ( aElement )
259 case PPT_TOKEN( cmd ):
260 msCommand = xAttribs->getOptionalValue( XML_cmd );
261 maType = xAttribs->getOptionalValueToken( XML_type, 0 );
262 break;
263 default:
264 break;
268 virtual void onEndElement() override
270 if( isCurrentElement( PPT_TOKEN( cmd ) ) )
272 try {
273 // see sd/source/filter/ppt/pptinanimations.cxx
274 // in AnimationImporter::importCommandContainer()
275 // REFACTOR?
276 // a good chunk of this code has been copied verbatim *sigh*
277 sal_Int16 nCommand = EffectCommands::CUSTOM;
278 NamedValue aParamValue;
280 switch( maType )
282 case XML_verb:
283 aParamValue.Name = "Verb";
284 // TODO make sure msCommand has what we want
285 aParamValue.Value <<= msCommand.toInt32();
286 nCommand = EffectCommands::VERB;
287 break;
288 case XML_evt:
289 case XML_call:
290 if ( msCommand == "onstopaudio" )
292 nCommand = EffectCommands::STOPAUDIO;
294 else if ( msCommand == "play" )
296 nCommand = EffectCommands::PLAY;
298 else if( msCommand == "playFrom" )
300 const OUString aMediaTime( msCommand.copy( 9, msCommand.getLength() - 10 ) );
301 rtl_math_ConversionStatus eStatus;
302 double fMediaTime = ::rtl::math::stringToDouble( aMediaTime, u'.', u',', &eStatus );
303 if( eStatus == rtl_math_ConversionStatus_Ok )
305 aParamValue.Name = "MediaTime";
306 aParamValue.Value <<= fMediaTime;
308 nCommand = EffectCommands::PLAY;
310 else if ( msCommand == "togglePause" )
312 nCommand = EffectCommands::TOGGLEPAUSE;
314 else if ( msCommand == "stop" )
316 nCommand = EffectCommands::STOP;
318 break;
320 mpNode->getNodeProperties()[ NP_COMMAND ] <<= nCommand;
321 if( nCommand == EffectCommands::CUSTOM )
323 SAL_WARN("oox.ppt", "OOX: CmdTimeNodeContext::endFastElement(), unknown command!");
324 aParamValue.Name = "UserDefined";
325 aParamValue.Value <<= msCommand;
327 if( aParamValue.Value.hasValue() )
329 Sequence< NamedValue > aParamSeq( &aParamValue, 1 );
330 mpNode->getNodeProperties()[ NP_PARAMETER ] <<= aParamSeq;
333 catch( RuntimeException& )
335 SAL_WARN("oox.ppt", "OOX: Exception in CmdTimeNodeContext::endFastElement()" );
340 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& /*rAttribs*/ ) override
342 switch ( aElementToken )
344 case PPT_TOKEN( cBhvr ):
345 return new CommonBehaviorContext ( *this, mpNode );
346 default:
347 break;
350 return this;
353 private:
354 OUString msCommand;
355 sal_Int32 maType;
358 /** CT_TLTimeNodeSequence
360 class SequenceTimeNodeContext
361 : public TimeNodeContext
363 public:
364 SequenceTimeNodeContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
365 const Reference< XFastAttributeList >& xAttribs,
366 const TimeNodePtr & pNode )
367 : TimeNodeContext( rParent, aElement, pNode )
368 , mnNextAc(0)
369 , mnPrevAc(0)
371 AttributeList attribs(xAttribs);
372 mbConcurrent = attribs.getBool( XML_concurrent, false );
373 mnNextAc = xAttribs->getOptionalValueToken( XML_nextAc, 0 );
374 mnPrevAc = xAttribs->getOptionalValueToken( XML_prevAc, 0 );
377 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
379 switch ( aElementToken )
381 case PPT_TOKEN( cTn ):
382 return new CommonTimeNodeContext( *this, aElementToken, rAttribs.getFastAttributeList(), mpNode );
383 case PPT_TOKEN( nextCondLst ):
384 return new CondListContext( *this, aElementToken, mpNode, mpNode->getNextCondition() );
385 case PPT_TOKEN( prevCondLst ):
386 return new CondListContext( *this, aElementToken, mpNode, mpNode->getPrevCondition() );
387 default:
388 break;
391 return this;
393 private:
394 bool mbConcurrent;
395 sal_Int32 mnNextAc, mnPrevAc;
398 /** CT_TLTimeNodeParallel
399 * CT_TLTimeNodeExclusive
401 class ParallelExclTimeNodeContext
402 : public TimeNodeContext
404 public:
405 ParallelExclTimeNodeContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
406 const TimeNodePtr & pNode )
407 : TimeNodeContext( rParent, aElement, pNode )
411 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
413 switch ( aElementToken )
415 case PPT_TOKEN( cTn ):
416 return new CommonTimeNodeContext( *this, aElementToken, rAttribs.getFastAttributeList(), mpNode );
417 default:
418 break;
421 return this;
424 protected:
428 /** CT_TLAnimateColorBehavior */
429 class AnimColorContext
430 : public TimeNodeContext
432 public:
433 AnimColorContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
434 const Reference< XFastAttributeList >& xAttribs,
435 const TimeNodePtr & pNode ) throw()
436 : TimeNodeContext( rParent, aElement, pNode )
437 , mnColorSpace( xAttribs->getOptionalValueToken( XML_clrSpc, 0 ) )
438 , mnDir( xAttribs->getOptionalValueToken( XML_dir, 0 ) )
439 , mbHasByColor( false )
440 , m_byColor( AnimationColorSpace::RGB, 0, 0, 0)
444 virtual void onEndElement() override
446 //xParentNode
447 if( isCurrentElement( mnElement ) )
449 NodePropertyMap & rProps(mpNode->getNodeProperties());
450 rProps[ NP_DIRECTION ] <<= mnDir == XML_cw;
451 rProps[ NP_COLORINTERPOLATION ] <<= mnColorSpace == XML_hsl ? AnimationColorSpace::HSL : AnimationColorSpace::RGB;
452 const GraphicHelper& rGraphicHelper = getFilter().getGraphicHelper();
453 if( maToClr.isUsed() )
454 mpNode->setTo( makeAny( maToClr.getColor( rGraphicHelper ) ) );
455 if( maFromClr.isUsed() )
456 mpNode->setFrom( makeAny( maFromClr.getColor( rGraphicHelper ) ) );
457 if( mbHasByColor )
458 mpNode->setBy( m_byColor.get() );
462 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
464 switch ( aElementToken )
466 case PPT_TOKEN( hsl ):
467 // CT_TLByHslColorTransform
469 if( mbHasByColor )
471 m_byColor.colorSpace = AnimationColorSpace::HSL;
472 m_byColor.one = rAttribs.getInteger( XML_h, 0 );
473 m_byColor.two = rAttribs.getInteger( XML_s, 0 );
474 m_byColor.three = rAttribs.getInteger( XML_l, 0 );
476 return this;
478 case PPT_TOKEN( rgb ):
480 if( mbHasByColor )
482 // CT_TLByRgbColorTransform
483 m_byColor.colorSpace = AnimationColorSpace::RGB;
484 m_byColor.one = rAttribs.getInteger( XML_r, 0 );
485 m_byColor.two = rAttribs.getInteger( XML_g, 0 );
486 m_byColor.three = rAttribs.getInteger( XML_b, 0 );
488 return this;
490 case PPT_TOKEN( by ):
491 // CT_TLByAnimateColorTransform
492 mbHasByColor = true;
493 return this;
494 case PPT_TOKEN( cBhvr ):
495 return new CommonBehaviorContext ( *this, mpNode );
496 case PPT_TOKEN( to ):
497 // CT_Color
498 return new ColorContext( *this, maToClr );
499 case PPT_TOKEN( from ):
500 // CT_Color
501 return new ColorContext( *this, maFromClr );
503 default:
504 break;
507 return this;
510 private:
511 sal_Int32 const mnColorSpace;
512 sal_Int32 const mnDir;
513 bool mbHasByColor;
514 AnimColor m_byColor;
515 oox::drawingml::Color maToClr;
516 oox::drawingml::Color maFromClr;
519 /** CT_TLAnimateBehavior */
520 class AnimContext
521 : public TimeNodeContext
523 public:
524 AnimContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
525 const Reference< XFastAttributeList >& xAttribs,
526 const TimeNodePtr & pNode ) throw()
527 : TimeNodeContext( rParent, aElement, pNode )
529 NodePropertyMap & aProps( pNode->getNodeProperties() );
530 sal_Int32 nCalcMode = xAttribs->getOptionalValueToken( XML_calcmode, 0 );
531 if(nCalcMode)
533 sal_Int16 nEnum = 0;
534 switch(nCalcMode)
536 case XML_discrete:
537 nEnum = AnimationCalcMode::DISCRETE;
538 break;
539 case XML_lin:
540 nEnum = AnimationCalcMode::LINEAR;
541 break;
542 case XML_fmla:
543 default:
544 // TODO what value is good ?
545 nEnum = AnimationCalcMode::DISCRETE;
546 break;
548 aProps[ NP_CALCMODE ] <<= nEnum;
551 msFrom = xAttribs->getOptionalValue(XML_from);
552 msTo = xAttribs->getOptionalValue(XML_to);
553 msBy = xAttribs->getOptionalValue(XML_by);
555 mnValueType = xAttribs->getOptionalValueToken( XML_valueType, 0 );
558 virtual ~AnimContext() throw () override
560 if (!msFrom.isEmpty())
562 css::uno::Any aAny;
563 aAny <<= msFrom;
564 convertAnimationValueWithTimeNode(mpNode, aAny);
565 mpNode->setFrom(aAny);
568 if (!msTo.isEmpty())
570 css::uno::Any aAny;
571 aAny <<= msTo;
572 convertAnimationValueWithTimeNode(mpNode, aAny);
573 mpNode->setTo(aAny);
576 if (!msBy.isEmpty())
578 css::uno::Any aAny;
579 aAny <<= msBy;
580 convertAnimationValueWithTimeNode(mpNode, aAny);
581 mpNode->setBy(aAny);
584 int nKeyTimes = maTavList.size();
585 if( nKeyTimes > 0)
587 int i=0;
588 Sequence< double > aKeyTimes( nKeyTimes );
589 Sequence< Any > aValues( nKeyTimes );
591 NodePropertyMap & aProps( mpNode->getNodeProperties() );
592 for (auto const& tav : maTavList)
594 // TODO what to do if it is Timing_INFINITE ?
595 Any aTime = GetTimeAnimateValueTime( tav.msTime );
596 aTime >>= aKeyTimes[i];
597 aValues[i] = tav.maValue;
598 convertAnimationValueWithTimeNode(mpNode, aValues[i]);
600 // Examine pptx documents and find that only the first tav
601 // has the formula set. The formula can be used for the whole.
602 if (!tav.msFormula.isEmpty())
604 OUString sFormula = tav.msFormula;
605 (void)convertMeasure(sFormula);
606 aProps[NP_FORMULA] <<= sFormula;
609 ++i;
611 aProps[ NP_VALUES ] <<= aValues;
612 aProps[ NP_KEYTIMES ] <<= aKeyTimes;
616 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& /*rAttribs*/ ) override
618 switch ( aElementToken )
620 case PPT_TOKEN( cBhvr ):
621 return new CommonBehaviorContext ( *this, mpNode );
622 case PPT_TOKEN( tavLst ):
623 return new TimeAnimValueListContext ( *this, maTavList );
624 default:
625 break;
628 return this;
630 private:
631 sal_Int32 mnValueType;
632 TimeAnimationValueList maTavList;
633 OUString msFrom;
634 OUString msTo;
635 OUString msBy;
638 /** CT_TLAnimateScaleBehavior */
639 class AnimScaleContext
640 : public TimeNodeContext
642 public:
643 AnimScaleContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
644 const Reference< XFastAttributeList >& xAttribs,
645 const TimeNodePtr & pNode ) throw()
646 : TimeNodeContext( rParent, aElement, pNode )
647 , mbZoomContents( false )
649 AttributeList attribs( xAttribs );
650 // TODO what to do with mbZoomContents
651 mbZoomContents = attribs.getBool( XML_zoomContents, false );
652 pNode->getNodeProperties()[ NP_TRANSFORMTYPE ]
653 <<= sal_Int16(AnimationTransformType::SCALE);
656 virtual void onEndElement() override
658 if( isCurrentElement( mnElement ) )
660 if( maTo.hasValue() )
662 mpNode->setTo( maTo );
664 if( maBy.hasValue() )
666 mpNode->setBy( maBy );
668 if( maFrom.hasValue() )
670 mpNode->setFrom( maFrom );
675 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
677 switch ( aElementToken )
679 case PPT_TOKEN( cBhvr ):
680 return new CommonBehaviorContext ( *this, mpNode );
681 case PPT_TOKEN( to ):
683 // CT_TLPoint
684 maTo = convertPointPercent(GetPointPercent(rAttribs.getFastAttributeList()));
685 return this;
687 case PPT_TOKEN( from ):
689 // CT_TLPoint
690 maFrom = convertPointPercent(GetPointPercent(rAttribs.getFastAttributeList()));
691 return this;
693 case PPT_TOKEN( by ):
695 // CT_TLPoint
696 css::awt::Point aPoint = GetPointPercent(rAttribs.getFastAttributeList());
697 // We got ending values instead of offset values, so subtract 100% from them.
698 aPoint.X -= 100000;
699 aPoint.Y -= 100000;
700 maBy = convertPointPercent(aPoint);
701 return this;
703 default:
704 break;
707 return this;
709 private:
710 Any maBy;
711 Any maFrom;
712 Any maTo;
713 bool mbZoomContents;
716 /** CT_TLAnimateRotationBehavior */
717 class AnimRotContext
718 : public TimeNodeContext
720 public:
721 AnimRotContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
722 const Reference< XFastAttributeList >& xAttribs,
723 const TimeNodePtr & pNode ) throw()
724 : TimeNodeContext( rParent, aElement, pNode )
726 AttributeList attribs( xAttribs );
728 pNode->getNodeProperties()[ NP_TRANSFORMTYPE ]
729 <<= sal_Int16(AnimationTransformType::ROTATE);
730 // see also DFF_msofbtAnimateRotationData in
731 // sd/source/filter/ppt/pptinanimations.cxx
732 if(attribs.hasAttribute( XML_by ) )
734 double fBy = attribs.getDouble( XML_by, 0.0 ) / PER_DEGREE; //1 PowerPoint-angle-unit = 1/60000 degree
735 pNode->setBy( makeAny( fBy ) );
737 if(attribs.hasAttribute( XML_from ) )
739 double fFrom = attribs.getDouble( XML_from, 0.0 ) / PER_DEGREE;
740 pNode->setFrom( makeAny( fFrom ) );
742 if(attribs.hasAttribute( XML_to ) )
744 double fTo = attribs.getDouble( XML_to, 0.0 ) / PER_DEGREE;
745 pNode->setTo( makeAny( fTo ) );
749 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& /*rAttribs*/ ) override
751 switch ( aElementToken )
753 case PPT_TOKEN( cBhvr ):
754 return new CommonBehaviorContext ( *this, mpNode );
755 default:
756 break;
759 return this;
763 /** CT_TLAnimateMotionBehavior */
764 class AnimMotionContext
765 : public TimeNodeContext
767 public:
768 AnimMotionContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
769 const Reference< XFastAttributeList >& xAttribs,
770 const TimeNodePtr & pNode ) throw()
771 : TimeNodeContext( rParent, aElement, pNode )
773 pNode->getNodeProperties()[ NP_TRANSFORMTYPE ]
774 <<= sal_Int16(AnimationTransformType::TRANSLATE);
776 AttributeList attribs( xAttribs );
777 sal_Int32 nOrigin = xAttribs->getOptionalValueToken( XML_origin, 0 );
778 if( nOrigin != 0 )
780 switch(nOrigin)
782 case XML_layout:
783 case XML_parent:
784 break;
786 // TODO
789 OUString aStr = xAttribs->getOptionalValue( XML_path );
790 // E can appear inside a number, so we only check for its presence at the end
791 aStr = aStr.trim();
792 if (aStr.endsWith("E"))
793 aStr = aStr.copy(0, aStr.getLength() - 1);
794 aStr = aStr.trim();
795 pNode->getNodeProperties()[ NP_PATH ] <<= aStr;
796 mnPathEditMode = xAttribs->getOptionalValueToken( XML_pathEditMode, 0 );
797 msPtsTypes = xAttribs->getOptionalValue( XML_ptsTypes );
798 mnAngle = attribs.getInteger( XML_rAng, 0 );
799 // TODO make sure the units are right. Likely not.
802 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
804 switch ( aElementToken )
806 case PPT_TOKEN( cBhvr ):
807 return new CommonBehaviorContext ( *this, mpNode );
808 case PPT_TOKEN( to ):
810 // CT_TLPoint
811 awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
812 Any rAny;
813 rAny <<= p.X;
814 rAny <<= p.Y;
815 mpNode->setTo( rAny );
816 return this;
818 case PPT_TOKEN( from ):
820 // CT_TLPoint
821 awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
822 Any rAny;
823 rAny <<= p.X;
824 rAny <<= p.Y;
825 mpNode->setFrom( rAny );
826 return this;
828 case PPT_TOKEN( by ):
830 // CT_TLPoint
831 awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
832 Any rAny;
833 rAny <<= p.X;
834 rAny <<= p.Y;
835 mpNode->setBy( rAny );
836 return this;
838 case PPT_TOKEN( rCtr ):
840 // CT_TLPoint
841 awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
842 // TODO push
843 (void)p;
844 return this;
846 default:
847 break;
850 return this;
852 private:
853 OUString msPtsTypes;
854 sal_Int32 mnPathEditMode;
855 sal_Int32 mnAngle;
858 /** CT_TLAnimateEffectBehavior */
859 class AnimEffectContext
860 : public TimeNodeContext
862 public:
863 AnimEffectContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
864 const Reference< XFastAttributeList >& xAttribs,
865 const TimeNodePtr & pNode ) throw()
866 : TimeNodeContext( rParent, aElement, pNode )
868 sal_Int32 nDir = xAttribs->getOptionalValueToken( XML_transition, 0 );
869 OUString sFilter = xAttribs->getOptionalValue( XML_filter );
870 // TODO
871 // OUString sPrList = xAttribs->getOptionalValue( XML_prLst );
873 if( !sFilter.isEmpty() )
875 SlideTransition aFilter( sFilter );
876 aFilter.setMode( nDir != XML_out );
877 pNode->setTransitionFilter( aFilter );
881 virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& /*rAttribs*/ ) override
883 switch ( aElementToken )
885 case PPT_TOKEN( cBhvr ):
886 return new CommonBehaviorContext ( *this, mpNode );
887 case PPT_TOKEN( progress ):
888 return new AnimVariantContext( *this, aElementToken, maProgress );
889 // TODO handle it.
890 default:
891 break;
894 return this;
896 private:
897 Any maProgress;
900 TimeNodeContext * TimeNodeContext::makeContext(
901 FragmentHandler2 const & rParent, sal_Int32 aElement,
902 const Reference< XFastAttributeList >& xAttribs,
903 const TimeNodePtr & pNode )
905 TimeNodeContext *pCtx = nullptr;
906 switch( aElement )
908 case PPT_TOKEN( animClr ):
909 pCtx = new AnimColorContext( rParent, aElement, xAttribs, pNode );
910 break;
911 case PPT_TOKEN( par ):
912 pCtx = new ParallelExclTimeNodeContext( rParent, aElement, pNode );
913 break;
914 case PPT_TOKEN( seq ):
915 pCtx = new SequenceTimeNodeContext( rParent, aElement, xAttribs, pNode );
916 break;
917 case PPT_TOKEN( excl ):
918 pCtx = new ParallelExclTimeNodeContext( rParent, aElement, pNode );
919 break;
920 case PPT_TOKEN( anim ):
921 pCtx = new AnimContext ( rParent, aElement, xAttribs, pNode );
922 break;
923 case PPT_TOKEN( animEffect ):
924 pCtx = new AnimEffectContext( rParent, aElement, xAttribs, pNode );
925 break;
926 case PPT_TOKEN( animMotion ):
927 pCtx = new AnimMotionContext( rParent, aElement, xAttribs, pNode );
928 break;
929 case PPT_TOKEN( animRot ):
930 pCtx = new AnimRotContext( rParent, aElement, xAttribs, pNode );
931 break;
932 case PPT_TOKEN( animScale ):
933 pCtx = new AnimScaleContext( rParent, aElement, xAttribs, pNode );
934 break;
935 case PPT_TOKEN( cmd ):
936 pCtx = new CmdTimeNodeContext( rParent, aElement, xAttribs, pNode );
937 break;
938 case PPT_TOKEN( set ):
939 pCtx = new SetTimeNodeContext( rParent, aElement, pNode );
940 break;
941 case PPT_TOKEN( audio ):
942 case PPT_TOKEN( video ):
943 pCtx = new MediaNodeContext( rParent, aElement, xAttribs, pNode );
944 break;
945 default:
946 break;
948 return pCtx;
951 TimeNodeContext::TimeNodeContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
952 const TimeNodePtr & pNode ) throw()
953 : FragmentHandler2( rParent )
954 , mnElement( aElement )
955 , mpNode( pNode )
959 TimeNodeContext::~TimeNodeContext( ) throw()
964 TimeNodeListContext::TimeNodeListContext( FragmentHandler2 const & rParent, TimeNodePtrList & aList )
965 throw()
966 : FragmentHandler2( rParent )
967 , maList( aList )
971 TimeNodeListContext::~TimeNodeListContext( ) throw()
975 ::oox::core::ContextHandlerRef TimeNodeListContext::onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs )
977 sal_Int16 nNodeType;
979 switch( aElementToken )
981 case PPT_TOKEN( par ):
982 nNodeType = AnimationNodeType::PAR;
983 break;
984 case PPT_TOKEN( seq ):
985 nNodeType = AnimationNodeType::SEQ;
986 break;
987 case PPT_TOKEN( excl ):
988 // TODO pick the right type. We choose parallel for now as
989 // there does not seem to be an "Exclusive"
990 nNodeType = AnimationNodeType::PAR;
991 break;
992 case PPT_TOKEN( anim ):
993 nNodeType = AnimationNodeType::ANIMATE;
994 break;
995 case PPT_TOKEN( animClr ):
996 nNodeType = AnimationNodeType::ANIMATECOLOR;
997 break;
998 case PPT_TOKEN( animEffect ):
999 nNodeType = AnimationNodeType::TRANSITIONFILTER;
1000 break;
1001 case PPT_TOKEN( animMotion ):
1002 nNodeType = AnimationNodeType::ANIMATEMOTION;
1003 break;
1004 case PPT_TOKEN( animRot ):
1005 case PPT_TOKEN( animScale ):
1006 nNodeType = AnimationNodeType::ANIMATETRANSFORM;
1007 break;
1008 case PPT_TOKEN( cmd ):
1009 nNodeType = AnimationNodeType::COMMAND;
1010 break;
1011 case PPT_TOKEN( set ):
1012 nNodeType = AnimationNodeType::SET;
1013 break;
1014 case PPT_TOKEN( audio ):
1015 nNodeType = AnimationNodeType::AUDIO;
1016 break;
1017 case PPT_TOKEN( video ):
1018 nNodeType = AnimationNodeType::AUDIO;
1019 SAL_WARN("oox.ppt", "OOX: video requested, gave Audio instead" );
1020 break;
1022 default:
1023 nNodeType = AnimationNodeType::CUSTOM;
1024 SAL_INFO("oox.ppt", "uhandled token " << aElementToken);
1025 break;
1028 TimeNodePtr pNode(new TimeNode(nNodeType));
1029 maList.push_back( pNode );
1030 FragmentHandler2 * pContext = TimeNodeContext::makeContext( *this, aElementToken, rAttribs.getFastAttributeList(), pNode );
1032 return pContext ? pContext : this;
1037 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */