LibreOffice Module oox (master)  1
timenodelistcontext.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
21 
22 #include <rtl/math.hxx>
23 #include <sal/log.hxx>
24 #include <tools/diagnose_ex.h>
25 
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>
33 
39 #include <oox/token/namespaces.hxx>
40 #include <oox/token/tokens.hxx>
41 #include <o3tl/string_view.hxx>
42 
43 #include "animvariantcontext.hxx"
45 #include "conditioncontext.hxx"
47 #include "timeanimvaluecontext.hxx"
48 #include "animationtypes.hxx"
50 
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;
60 
61 namespace {
62 
63  oox::ppt::AnimationAttributeEnum getAttributeEnumByAPIName(std::u16string_view rAPIName)
64  {
67  while(attrConv->mpAPIName != nullptr)
68  {
69  if(o3tl::equalsAscii(rAPIName, attrConv->mpAPIName))
70  {
71  eResult = attrConv->meAttribute;
72  break;
73  }
74  attrConv++;
75  }
76  return eResult;
77  }
78 
79  bool convertAnimationValueWithTimeNode(const oox::ppt::TimeNodePtr& pNode, css::uno::Any &rAny)
80  {
81  css::uno::Any aAny = pNode->getNodeProperties()[oox::ppt::NP_ATTRIBUTENAME];
82  OUString aNameList;
83  aAny >>= aNameList;
84 
85  // only get first token.
86  return oox::ppt::convertAnimationValue(getAttributeEnumByAPIName(o3tl::getToken(aNameList, 0, ';')), rAny);
87  }
88 
89  css::uno::Any convertPointPercent(const css::awt::Point& rPoint)
90  {
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 Any(aPair);
96  }
97 }
98 
99 namespace oox::ppt {
100 
101  namespace {
102 
103  struct AnimColor
104  {
105  AnimColor(sal_Int16 cs, sal_Int32 o, sal_Int32 t, sal_Int32 th )
106  : colorSpace( cs ), one( o ), two( t ), three( th )
107  {
108  }
109 
110  Any get() const
111  {
112  sal_Int32 nColor;
113  Any aColor;
114 
115  switch( colorSpace )
116  {
117  case AnimationColorSpace::HSL:
118  aColor <<= Sequence< double >{ one / 100000.0, two / 100000.0, three / 100000.0 };
119  break;
120  case AnimationColorSpace::RGB:
121  nColor = ( ( ( one * 128 ) / 1000 ) & 0xff ) << 16
122  | ( ( ( two * 128 ) / 1000 ) & 0xff ) << 8
123  | ( ( ( three * 128 ) / 1000 ) & 0xff );
124  aColor <<= nColor;
125  break;
126  default:
127  nColor = 0;
128  aColor <<= nColor;
129  break;
130  }
131  return aColor;
132  }
133 
134  sal_Int16 colorSpace;
135  sal_Int32 one;
136  sal_Int32 two;
137  sal_Int32 three;
138  };
139 
142  class MediaNodeContext
143  : public TimeNodeContext
144  {
145  public:
146  MediaNodeContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
147  const Reference< XFastAttributeList >& xAttribs,
148  const TimeNodePtr & pNode )
149  : TimeNodeContext( rParent, aElement, pNode )
150  , mbIsNarration( false )
151  , mbFullScrn( false )
152  , mbHideDuringShow(false)
153  {
154  AttributeList attribs( xAttribs );
155 
156  switch( aElement )
157  {
158  case PPT_TOKEN( audio ):
159  mbIsNarration = attribs.getBool( XML_isNarration, false );
160  break;
161  case PPT_TOKEN( video ):
162  mbFullScrn = attribs.getBool( XML_fullScrn, false );
163  break;
164  default:
165  break;
166  }
167  }
168 
169  virtual void onEndElement() override
170  {
171  sal_Int32 aElement = getCurrentElement();
172  if( aElement == PPT_TOKEN( audio ) )
173  {
174  mpNode->getNodeProperties()[NP_ISNARRATION] <<= mbIsNarration;
175  }
176  else if( aElement == PPT_TOKEN( video ) )
177  {
178  // TODO deal with mbFullScrn
179  }
180  else if (aElement == PPT_TOKEN(cMediaNode))
181  {
182  mpNode->getNodeProperties()[NP_HIDEDURINGSHOW] <<= mbHideDuringShow;
183  }
184  }
185 
186  virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs) override
187  {
188  switch ( aElementToken )
189  {
190  case PPT_TOKEN( cTn ):
191  return new CommonTimeNodeContext( *this, aElementToken, rAttribs.getFastAttributeList(), mpNode );
192  case PPT_TOKEN( tgtEl ):
193  return new TimeTargetElementContext( *this, mpNode->getTarget() );
194  case PPT_TOKEN(cMediaNode):
195  mbHideDuringShow = !rAttribs.getBool(XML_showWhenStopped, true);
196  break;
197  default:
198  break;
199  }
200 
201  return this;
202  }
203 
204  private:
208  };
209 
212  class SetTimeNodeContext
213  : public TimeNodeContext
214  {
215  public:
216  SetTimeNodeContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
217  const TimeNodePtr & pNode )
218  : TimeNodeContext( rParent, aElement, pNode )
219  {
220 
221  }
222 
223  virtual ~SetTimeNodeContext() noexcept override
224  {
225  if(maTo.hasValue())
226  {
227  convertAnimationValueWithTimeNode(mpNode, maTo);
228  mpNode->setTo(maTo);
229  }
230 
231  }
232 
233  virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& /*rAttribs*/ ) override
234  {
235  switch ( aElementToken )
236  {
237  case PPT_TOKEN( cBhvr ):
238  return new CommonBehaviorContext ( *this, mpNode );
239  case PPT_TOKEN( to ):
240  // CT_TLAnimVariant
241  return new AnimVariantContext( *this, aElementToken, maTo );
242  default:
243  break;
244  }
245 
246  return this;
247  }
248  private:
250  };
251 
254  class CmdTimeNodeContext
255  : public TimeNodeContext
256  {
257  public:
258  CmdTimeNodeContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
259  const Reference< XFastAttributeList >& xAttribs,
260  const TimeNodePtr & pNode )
261  : TimeNodeContext( rParent, aElement, pNode )
262  , maType(0)
263  {
264  switch ( aElement )
265  {
266  case PPT_TOKEN( cmd ):
267  msCommand = xAttribs->getOptionalValue( XML_cmd );
268  maType = xAttribs->getOptionalValueToken( XML_type, 0 );
269  break;
270  default:
271  break;
272  }
273  }
274 
275  virtual void onEndElement() override
276  {
277  if( !isCurrentElement( PPT_TOKEN( cmd ) ) )
278  return;
279 
280  try {
281  // see sd/source/filter/ppt/pptinanimations.cxx
282  // in AnimationImporter::importCommandContainer()
283  // REFACTOR?
284  // a good chunk of this code has been copied verbatim *sigh*
285  sal_Int16 nCommand = EffectCommands::CUSTOM;
286  NamedValue aParamValue;
287 
288  switch( maType )
289  {
290  case XML_verb:
291  aParamValue.Name = "Verb";
292  // TODO make sure msCommand has what we want
293  aParamValue.Value <<= msCommand.toInt32();
294  nCommand = EffectCommands::VERB;
295  break;
296  case XML_evt:
297  case XML_call:
298  if ( msCommand == "onstopaudio" )
299  {
300  nCommand = EffectCommands::STOPAUDIO;
301  }
302  else if ( msCommand == "play" )
303  {
304  nCommand = EffectCommands::PLAY;
305  }
306  else if (msCommand.startsWith("playFrom"))
307  {
308  std::u16string_view aMediaTime( msCommand.subView( 9, msCommand.getLength() - 10 ) );
309  rtl_math_ConversionStatus eStatus;
310  double fMediaTime = ::rtl::math::stringToDouble( aMediaTime, u'.', u',', &eStatus );
311  if( eStatus == rtl_math_ConversionStatus_Ok )
312  {
313  aParamValue.Name = "MediaTime";
314  aParamValue.Value <<= fMediaTime;
315  }
316  nCommand = EffectCommands::PLAY;
317  }
318  else if ( msCommand == "togglePause" )
319  {
320  nCommand = EffectCommands::TOGGLEPAUSE;
321  }
322  else if ( msCommand == "stop" )
323  {
324  nCommand = EffectCommands::STOP;
325  }
326  break;
327  }
328  mpNode->getNodeProperties()[ NP_COMMAND ] <<= nCommand;
329  if( nCommand == EffectCommands::CUSTOM )
330  {
331  SAL_WARN("oox.ppt", "OOX: CmdTimeNodeContext::endFastElement(), unknown command!");
332  aParamValue.Name = "UserDefined";
333  aParamValue.Value <<= msCommand;
334  }
335  if( aParamValue.Value.hasValue() )
336  {
337  Sequence< NamedValue > aParamSeq( &aParamValue, 1 );
338  mpNode->getNodeProperties()[ NP_PARAMETER ] <<= aParamSeq;
339  }
340  }
341  catch( RuntimeException& )
342  {
343  TOOLS_WARN_EXCEPTION("oox.ppt", "OOX: Exception in CmdTimeNodeContext::endFastElement()" );
344  }
345  }
346 
347  virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& /*rAttribs*/ ) override
348  {
349  switch ( aElementToken )
350  {
351  case PPT_TOKEN( cBhvr ):
352  return new CommonBehaviorContext ( *this, mpNode );
353  default:
354  break;
355  }
356 
357  return this;
358  }
359 
360  private:
361  OUString msCommand;
362  sal_Int32 maType;
363  };
364 
367  class SequenceTimeNodeContext
368  : public TimeNodeContext
369  {
370  public:
371  SequenceTimeNodeContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
372  const Reference< XFastAttributeList >& xAttribs,
373  const TimeNodePtr & pNode )
374  : TimeNodeContext( rParent, aElement, pNode )
375  , mnNextAc(0)
376  , mnPrevAc(0)
377  {
378  AttributeList attribs(xAttribs);
379  mbConcurrent = attribs.getBool( XML_concurrent, false );
380  mnNextAc = xAttribs->getOptionalValueToken( XML_nextAc, 0 );
381  mnPrevAc = xAttribs->getOptionalValueToken( XML_prevAc, 0 );
382  }
383 
384  virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
385  {
386  switch ( aElementToken )
387  {
388  case PPT_TOKEN( cTn ):
389  return new CommonTimeNodeContext( *this, aElementToken, rAttribs.getFastAttributeList(), mpNode );
390  case PPT_TOKEN( nextCondLst ):
391  return new CondListContext( *this, aElementToken, mpNode, mpNode->getNextCondition() );
392  case PPT_TOKEN( prevCondLst ):
393  return new CondListContext( *this, aElementToken, mpNode, mpNode->getPrevCondition() );
394  default:
395  break;
396  }
397 
398  return this;
399  }
400  private:
402  sal_Int32 mnNextAc, mnPrevAc;
403  };
404 
408  class ParallelExclTimeNodeContext
409  : public TimeNodeContext
410  {
411  public:
412  ParallelExclTimeNodeContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
413  const TimeNodePtr & pNode )
414  : TimeNodeContext( rParent, aElement, pNode )
415  {
416  }
417 
418  virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
419  {
420  switch ( aElementToken )
421  {
422  case PPT_TOKEN( cTn ):
423  return new CommonTimeNodeContext( *this, aElementToken, rAttribs.getFastAttributeList(), mpNode );
424  default:
425  break;
426  }
427 
428  return this;
429  }
430 
431  protected:
432 
433  };
434 
436  class AnimColorContext
437  : public TimeNodeContext
438  {
439  public:
440  AnimColorContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
441  const Reference< XFastAttributeList >& xAttribs,
442  const TimeNodePtr & pNode ) noexcept
443  : TimeNodeContext( rParent, aElement, pNode )
444  , mnColorSpace( xAttribs->getOptionalValueToken( XML_clrSpc, 0 ) )
445  , mnDir( xAttribs->getOptionalValueToken( XML_dir, 0 ) )
446  , mbHasByColor( false )
447  , m_byColor( AnimationColorSpace::RGB, 0, 0, 0)
448  {
449  }
450 
451  virtual void onEndElement() override
452  {
453  //xParentNode
454  if( !isCurrentElement( mnElement ) )
455  return;
456 
457  NodePropertyMap & rProps(mpNode->getNodeProperties());
458  rProps[ NP_DIRECTION ] <<= mnDir == XML_cw;
459  rProps[ NP_COLORINTERPOLATION ] <<= mnColorSpace == XML_hsl ? AnimationColorSpace::HSL : AnimationColorSpace::RGB;
460  const GraphicHelper& rGraphicHelper = getFilter().getGraphicHelper();
461  if( maToClr.isUsed() )
462  mpNode->setTo( Any( maToClr.getColor( rGraphicHelper ) ) );
463  if( maFromClr.isUsed() )
464  mpNode->setFrom( Any( maFromClr.getColor( rGraphicHelper ) ) );
465  if( mbHasByColor )
466  mpNode->setBy( m_byColor.get() );
467  }
468 
469  virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
470  {
471  switch ( aElementToken )
472  {
473  case PPT_TOKEN( hsl ):
474  // CT_TLByHslColorTransform
475  {
476  if( mbHasByColor )
477  {
478  m_byColor.colorSpace = AnimationColorSpace::HSL;
479  m_byColor.one = rAttribs.getInteger( XML_h, 0 );
480  m_byColor.two = rAttribs.getInteger( XML_s, 0 );
481  m_byColor.three = rAttribs.getInteger( XML_l, 0 );
482  }
483  return this;
484  }
485  case PPT_TOKEN( rgb ):
486  {
487  if( mbHasByColor )
488  {
489  // CT_TLByRgbColorTransform
490  m_byColor.colorSpace = AnimationColorSpace::RGB;
491  m_byColor.one = rAttribs.getInteger( XML_r, 0 );
492  m_byColor.two = rAttribs.getInteger( XML_g, 0 );
493  m_byColor.three = rAttribs.getInteger( XML_b, 0 );
494  }
495  return this;
496  }
497  case PPT_TOKEN( by ):
498  // CT_TLByAnimateColorTransform
499  mbHasByColor = true;
500  return this;
501  case PPT_TOKEN( cBhvr ):
502  return new CommonBehaviorContext ( *this, mpNode );
503  case PPT_TOKEN( to ):
504  // CT_Color
505  return new ColorContext( *this, maToClr );
506  case PPT_TOKEN( from ):
507  // CT_Color
508  return new ColorContext( *this, maFromClr );
509 
510  default:
511  break;
512  }
513 
514  return this;
515  }
516 
517  private:
518  sal_Int32 mnColorSpace;
519  sal_Int32 mnDir;
521  AnimColor m_byColor;
524  };
525 
527  class AnimContext
528  : public TimeNodeContext
529  {
530  public:
531  AnimContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
532  const Reference< XFastAttributeList >& xAttribs,
533  const TimeNodePtr & pNode ) noexcept
534  : TimeNodeContext( rParent, aElement, pNode )
535  {
536  NodePropertyMap & aProps( pNode->getNodeProperties() );
537  sal_Int32 nCalcMode = xAttribs->getOptionalValueToken( XML_calcmode, 0 );
538  if(nCalcMode)
539  {
540  sal_Int16 nEnum = 0;
541  switch(nCalcMode)
542  {
543  case XML_discrete:
544  nEnum = AnimationCalcMode::DISCRETE;
545  break;
546  case XML_lin:
547  nEnum = AnimationCalcMode::LINEAR;
548  break;
549  case XML_fmla:
550  default:
551  // TODO what value is good ?
552  nEnum = AnimationCalcMode::DISCRETE;
553  break;
554  }
555  aProps[ NP_CALCMODE ] <<= nEnum;
556  }
557 
558  msFrom = xAttribs->getOptionalValue(XML_from);
559  msTo = xAttribs->getOptionalValue(XML_to);
560  msBy = xAttribs->getOptionalValue(XML_by);
561 
562  mnValueType = xAttribs->getOptionalValueToken( XML_valueType, 0 );
563  }
564 
565  virtual ~AnimContext() noexcept override
566  {
567  if (!msFrom.isEmpty())
568  {
569  css::uno::Any aAny;
570  aAny <<= msFrom;
571  convertAnimationValueWithTimeNode(mpNode, aAny);
572  mpNode->setFrom(aAny);
573  }
574 
575  if (!msTo.isEmpty())
576  {
577  css::uno::Any aAny;
578  aAny <<= msTo;
579  convertAnimationValueWithTimeNode(mpNode, aAny);
580  mpNode->setTo(aAny);
581  }
582 
583  if (!msBy.isEmpty())
584  {
585  css::uno::Any aAny;
586  aAny <<= msBy;
587  convertAnimationValueWithTimeNode(mpNode, aAny);
588  mpNode->setBy(aAny);
589  }
590 
591  int nKeyTimes = maTavList.size();
592  if( nKeyTimes <= 0)
593  return;
594 
595  int i=0;
596  Sequence< double > aKeyTimes( nKeyTimes );
597  auto pKeyTimes = aKeyTimes.getArray();
598  Sequence< Any > aValues( nKeyTimes );
599  auto pValues = aValues.getArray();
600 
601  NodePropertyMap & aProps( mpNode->getNodeProperties() );
602  for (auto const& tav : maTavList)
603  {
604  // TODO what to do if it is Timing_INFINITE ?
605  Any aTime = GetTimeAnimateValueTime( tav.msTime );
606  aTime >>= pKeyTimes[i];
607  pValues[i] = tav.maValue;
608  convertAnimationValueWithTimeNode(mpNode, pValues[i]);
609 
610  // Examine pptx documents and find that only the first tav
611  // has the formula set. The formula can be used for the whole.
612  if (!tav.msFormula.isEmpty())
613  {
614  OUString sFormula = tav.msFormula;
615  (void)convertMeasure(sFormula);
616  aProps[NP_FORMULA] <<= sFormula;
617  }
618 
619  ++i;
620  }
621  aProps[ NP_VALUES ] <<= aValues;
622  aProps[ NP_KEYTIMES ] <<= aKeyTimes;
623  }
624 
625  virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& /*rAttribs*/ ) override
626  {
627  switch ( aElementToken )
628  {
629  case PPT_TOKEN( cBhvr ):
630  return new CommonBehaviorContext ( *this, mpNode );
631  case PPT_TOKEN( tavLst ):
632  return new TimeAnimValueListContext ( *this, maTavList );
633  default:
634  break;
635  }
636 
637  return this;
638  }
639  private:
640  sal_Int32 mnValueType;
642  OUString msFrom;
643  OUString msTo;
644  OUString msBy;
645  };
646 
648  class AnimScaleContext
649  : public TimeNodeContext
650  {
651  public:
652  AnimScaleContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
653  const Reference< XFastAttributeList >& xAttribs,
654  const TimeNodePtr & pNode ) noexcept
655  : TimeNodeContext( rParent, aElement, pNode )
656  , mbZoomContents( false )
657  {
658  AttributeList attribs( xAttribs );
659  // TODO what to do with mbZoomContents
660  mbZoomContents = attribs.getBool( XML_zoomContents, false );
661  pNode->getNodeProperties()[ NP_TRANSFORMTYPE ]
662  <<= sal_Int16(AnimationTransformType::SCALE);
663  }
664 
665  virtual void onEndElement() override
666  {
667  if( !isCurrentElement( mnElement ) )
668  return;
669 
670  if( maTo.hasValue() )
671  {
672  mpNode->setTo( maTo );
673  }
674  if( maBy.hasValue() )
675  {
676  mpNode->setBy( maBy );
677  }
678  if( maFrom.hasValue() )
679  {
680  mpNode->setFrom( maFrom );
681  }
682  }
683 
684  virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
685  {
686  switch ( aElementToken )
687  {
688  case PPT_TOKEN( cBhvr ):
689  return new CommonBehaviorContext ( *this, mpNode );
690  case PPT_TOKEN( to ):
691  {
692  // CT_TLPoint
693  maTo = convertPointPercent(GetPointPercent(rAttribs.getFastAttributeList()));
694  return this;
695  }
696  case PPT_TOKEN( from ):
697  {
698  // CT_TLPoint
699  maFrom = convertPointPercent(GetPointPercent(rAttribs.getFastAttributeList()));
700  return this;
701  }
702  case PPT_TOKEN( by ):
703  {
704  // CT_TLPoint
705  css::awt::Point aPoint = GetPointPercent(rAttribs.getFastAttributeList());
706  // We got ending values instead of offset values, so subtract 100% from them.
707  aPoint.X -= 100000;
708  aPoint.Y -= 100000;
709  maBy = convertPointPercent(aPoint);
710  return this;
711  }
712  default:
713  break;
714  }
715 
716  return this;
717  }
718  private:
721  Any maTo;
723  };
724 
726  class AnimRotContext
727  : public TimeNodeContext
728  {
729  public:
730  AnimRotContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
731  const Reference< XFastAttributeList >& xAttribs,
732  const TimeNodePtr & pNode ) noexcept
733  : TimeNodeContext( rParent, aElement, pNode )
734  {
735  AttributeList attribs( xAttribs );
736 
737  pNode->getNodeProperties()[ NP_TRANSFORMTYPE ]
738  <<= sal_Int16(AnimationTransformType::ROTATE);
739  // see also DFF_msofbtAnimateRotationData in
740  // sd/source/filter/ppt/pptinanimations.cxx
741  if(attribs.hasAttribute( XML_by ) )
742  {
743  double fBy = attribs.getDouble( XML_by, 0.0 ) / PER_DEGREE; //1 PowerPoint-angle-unit = 1/60000 degree
744  pNode->setBy( Any( fBy ) );
745  }
746  if(attribs.hasAttribute( XML_from ) )
747  {
748  double fFrom = attribs.getDouble( XML_from, 0.0 ) / PER_DEGREE;
749  pNode->setFrom( Any( fFrom ) );
750  }
751  if(attribs.hasAttribute( XML_to ) )
752  {
753  double fTo = attribs.getDouble( XML_to, 0.0 ) / PER_DEGREE;
754  pNode->setTo( Any( fTo ) );
755  }
756  }
757 
758  virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& /*rAttribs*/ ) override
759  {
760  switch ( aElementToken )
761  {
762  case PPT_TOKEN( cBhvr ):
763  return new CommonBehaviorContext ( *this, mpNode );
764  default:
765  break;
766  }
767 
768  return this;
769  }
770  };
771 
773  class AnimMotionContext
774  : public TimeNodeContext
775  {
776  public:
777  AnimMotionContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
778  const Reference< XFastAttributeList >& xAttribs,
779  const TimeNodePtr & pNode ) noexcept
780  : TimeNodeContext( rParent, aElement, pNode )
781  {
782  pNode->getNodeProperties()[ NP_TRANSFORMTYPE ]
783  <<= sal_Int16(AnimationTransformType::TRANSLATE);
784 
785  AttributeList attribs( xAttribs );
786  sal_Int32 nOrigin = xAttribs->getOptionalValueToken( XML_origin, 0 );
787  if( nOrigin != 0 )
788  {
789  switch(nOrigin)
790  {
791  case XML_layout:
792  case XML_parent:
793  break;
794  }
795  // TODO
796  }
797 
798  OUString aStr = xAttribs->getOptionalValue( XML_path );
799  // E can appear inside a number, so we only check for its presence at the end
800  aStr = aStr.trim();
801  if (aStr.endsWith("E"))
802  aStr = aStr.copy(0, aStr.getLength() - 1);
803  aStr = aStr.trim();
804  pNode->getNodeProperties()[ NP_PATH ] <<= aStr;
805  mnPathEditMode = xAttribs->getOptionalValueToken( XML_pathEditMode, 0 );
806  msPtsTypes = xAttribs->getOptionalValue( XML_ptsTypes );
807  mnAngle = attribs.getInteger( XML_rAng, 0 );
808  // TODO make sure the units are right. Likely not.
809  }
810 
811  virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& rAttribs ) override
812  {
813  switch ( aElementToken )
814  {
815  case PPT_TOKEN( cBhvr ):
816  return new CommonBehaviorContext ( *this, mpNode );
817  case PPT_TOKEN( to ):
818  {
819  // CT_TLPoint
820  awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
821  Any rAny;
822  rAny <<= p.X;
823  rAny <<= p.Y;
824  mpNode->setTo( rAny );
825  return this;
826  }
827  case PPT_TOKEN( from ):
828  {
829  // CT_TLPoint
830  awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
831  Any rAny;
832  rAny <<= p.X;
833  rAny <<= p.Y;
834  mpNode->setFrom( rAny );
835  return this;
836  }
837  case PPT_TOKEN( by ):
838  {
839  // CT_TLPoint
840  awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
841  Any rAny;
842  rAny <<= p.X;
843  rAny <<= p.Y;
844  mpNode->setBy( rAny );
845  return this;
846  }
847  case PPT_TOKEN( rCtr ):
848  {
849  // CT_TLPoint
850  awt::Point p = GetPointPercent( rAttribs.getFastAttributeList() );
851  // TODO push
852  (void)p;
853  return this;
854  }
855  default:
856  break;
857  }
858 
859  return this;
860  }
861  private:
862  OUString msPtsTypes;
863  sal_Int32 mnPathEditMode;
864  sal_Int32 mnAngle;
865  };
866 
868  class AnimEffectContext
869  : public TimeNodeContext
870  {
871  public:
872  AnimEffectContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
873  const Reference< XFastAttributeList >& xAttribs,
874  const TimeNodePtr & pNode ) noexcept
875  : TimeNodeContext( rParent, aElement, pNode )
876  {
877  sal_Int32 nDir = xAttribs->getOptionalValueToken( XML_transition, 0 );
878  OUString sFilter = xAttribs->getOptionalValue( XML_filter );
879  // TODO
880 // OUString sPrList = xAttribs->getOptionalValue( XML_prLst );
881 
882  if( !sFilter.isEmpty() )
883  {
884  SlideTransition aFilter( sFilter );
885  aFilter.setMode( nDir != XML_out );
886  pNode->setTransitionFilter( aFilter );
887  }
888  }
889 
890  virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 aElementToken, const AttributeList& /*rAttribs*/ ) override
891  {
892  switch ( aElementToken )
893  {
894  case PPT_TOKEN( cBhvr ):
895  return new CommonBehaviorContext ( *this, mpNode );
896  case PPT_TOKEN( progress ):
897  return new AnimVariantContext( *this, aElementToken, maProgress );
898  // TODO handle it.
899  default:
900  break;
901  }
902 
903  return this;
904  }
905  private:
907  };
908 
909  }
910 
912  FragmentHandler2 const & rParent, sal_Int32 aElement,
913  const Reference< XFastAttributeList >& xAttribs,
914  const TimeNodePtr & pNode )
915  {
917  switch( aElement )
918  {
919  case PPT_TOKEN( animClr ):
920  pCtx = new AnimColorContext( rParent, aElement, xAttribs, pNode );
921  break;
922  case PPT_TOKEN( par ):
923  pCtx = new ParallelExclTimeNodeContext( rParent, aElement, pNode );
924  break;
925  case PPT_TOKEN( seq ):
926  pCtx = new SequenceTimeNodeContext( rParent, aElement, xAttribs, pNode );
927  break;
928  case PPT_TOKEN( excl ):
929  pCtx = new ParallelExclTimeNodeContext( rParent, aElement, pNode );
930  break;
931  case PPT_TOKEN( anim ):
932  pCtx = new AnimContext ( rParent, aElement, xAttribs, pNode );
933  break;
934  case PPT_TOKEN( animEffect ):
935  pCtx = new AnimEffectContext( rParent, aElement, xAttribs, pNode );
936  break;
937  case PPT_TOKEN( animMotion ):
938  pCtx = new AnimMotionContext( rParent, aElement, xAttribs, pNode );
939  break;
940  case PPT_TOKEN( animRot ):
941  pCtx = new AnimRotContext( rParent, aElement, xAttribs, pNode );
942  break;
943  case PPT_TOKEN( animScale ):
944  pCtx = new AnimScaleContext( rParent, aElement, xAttribs, pNode );
945  break;
946  case PPT_TOKEN( cmd ):
947  pCtx = new CmdTimeNodeContext( rParent, aElement, xAttribs, pNode );
948  break;
949  case PPT_TOKEN( set ):
950  pCtx = new SetTimeNodeContext( rParent, aElement, pNode );
951  break;
952  case PPT_TOKEN( audio ):
953  case PPT_TOKEN( video ):
954  pCtx = new MediaNodeContext( rParent, aElement, xAttribs, pNode );
955  break;
956  default:
957  break;
958  }
959  return pCtx;
960  }
961 
962  TimeNodeContext::TimeNodeContext( FragmentHandler2 const & rParent, sal_Int32 aElement,
963  const TimeNodePtr & pNode ) noexcept
964  : FragmentHandler2( rParent )
965  , mnElement( aElement )
966  , mpNode( pNode )
967  {
968  }
969 
971  {
972 
973  }
974 
975  TimeNodeListContext::TimeNodeListContext( FragmentHandler2 const & rParent, TimeNodePtrList & aList )
976  noexcept
977  : FragmentHandler2( rParent )
978  , maList( aList )
979  {
980  }
981 
983  {
984  }
985 
987  {
988  sal_Int16 nNodeType;
989 
990  switch( aElementToken )
991  {
992  case PPT_TOKEN( par ):
993  nNodeType = AnimationNodeType::PAR;
994  break;
995  case PPT_TOKEN( seq ):
996  nNodeType = AnimationNodeType::SEQ;
997  break;
998  case PPT_TOKEN( excl ):
999  // TODO pick the right type. We choose parallel for now as
1000  // there does not seem to be an "Exclusive"
1001  nNodeType = AnimationNodeType::PAR;
1002  break;
1003  case PPT_TOKEN( anim ):
1004  nNodeType = AnimationNodeType::ANIMATE;
1005  break;
1006  case PPT_TOKEN( animClr ):
1007  nNodeType = AnimationNodeType::ANIMATECOLOR;
1008  break;
1009  case PPT_TOKEN( animEffect ):
1010  nNodeType = AnimationNodeType::TRANSITIONFILTER;
1011  break;
1012  case PPT_TOKEN( animMotion ):
1013  nNodeType = AnimationNodeType::ANIMATEMOTION;
1014  break;
1015  case PPT_TOKEN( animRot ):
1016  case PPT_TOKEN( animScale ):
1017  nNodeType = AnimationNodeType::ANIMATETRANSFORM;
1018  break;
1019  case PPT_TOKEN( cmd ):
1020  nNodeType = AnimationNodeType::COMMAND;
1021  break;
1022  case PPT_TOKEN( set ):
1023  nNodeType = AnimationNodeType::SET;
1024  break;
1025  case PPT_TOKEN( audio ):
1026  nNodeType = AnimationNodeType::AUDIO;
1027  break;
1028  case PPT_TOKEN( video ):
1029  nNodeType = AnimationNodeType::AUDIO;
1030  SAL_WARN("oox.ppt", "OOX: video requested, gave Audio instead" );
1031  break;
1032 
1033  default:
1034  nNodeType = AnimationNodeType::CUSTOM;
1035  SAL_INFO("oox.ppt", "unhandled token " << aElementToken);
1036  break;
1037  }
1038 
1039  TimeNodePtr pNode = std::make_shared<TimeNode>(nNodeType);
1040  maList.push_back( pNode );
1041  rtl::Reference<FragmentHandler2> pContext = TimeNodeContext::makeContext( *this, aElementToken, rAttribs.getFastAttributeList(), pNode );
1042 
1043  return pContext ? pContext : this;
1044  }
1045 
1046 }
1047 
1048 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_Int32 mnValueType
bool convertMeasure(OUString &rString)
convert the measure string to LibreOffice format.
bool mbIsNarration
std::vector< TimeNodePtr > TimeNodePtrList
Definition: timenode.hxx:47
bool mbConcurrent
const sal_Int32 PER_DEGREE
sal_Int32 mnPathEditMode
virtual ~TimeNodeListContext() noexcept override
AlgAtomPtr mpNode
OString sFormula
Definition: drawingml.cxx:3865
oox::drawingml::Color maFromClr
sal_Int32 maType
bool mbZoomContents
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
OUString msFrom
oox::drawingml::Color maToClr
bool convertAnimationValue(AnimationAttributeEnum eAttribute, css::uno::Any &rValue)
convert attribute values of the animation target so that LibreOffice understand.
OUString msBy
bool equalsAscii(std::u16string_view s1, const char *s2)
const ImplAttributeNameConversion * getAttributeConversionList()
std::array< css::uno::Any, NP_SIZE_ > NodePropertyMap
TimeAnimationValueList maTavList
sal_Int32 mnColorSpace
Any maFrom
virtual ~TimeNodeContext() noexcept override
sal_Int32 mnDir
sal_Int32 mnNextAc
Any GetTimeAnimateValueTime(const OUString &val)
#define TOOLS_WARN_EXCEPTION(area, stream)
::Color getColor(const GraphicHelper &rGraphicHelper,::Color nPhClr=API_RGB_TRANSPARENT) const
Returns the final RGB color value.
Definition: color.cxx:531
::std::vector< TimeAnimationValue > TimeAnimationValueList
bool isUsed() const
Returns true, if the color is initialized.
Definition: color.hxx:87
OUString msTo
sal_Int32 two
Any maProgress
virtual ::oox::core::ContextHandlerRef onCreateContext(sal_Int32 aElementToken, const AttributeList &rAttribs) override
Will be called to create a context handler for the passed element.
XML_type
OUString msPtsTypes
Provides access to attribute values of an element.
sal_Int16 colorSpace
sal_Int32 mnPrevAc
bool mbFullScrn
const PropertyValue * pValues
sal_Int32 three
OUString msCommand
bool mbHideDuringShow
#define SAL_INFO(area, stream)
awt::Point GetPointPercent(const Reference< XFastAttributeList > &xAttribs)
converts the attributes from a CT_TLPoint into an awt Point with 1/1000%
::rtl::Reference< ContextHandler > ContextHandlerRef
const css::uno::Reference< css::xml::sax::XFastAttributeList > & getFastAttributeList() const
Returns the wrapped com.sun.star.xml.sax.XFastAttributeList object.
void * p
std::shared_ptr< TimeNode > TimeNodePtr
Definition: timenode.hxx:44
#define SAL_WARN(area, stream)
TimeNodeListContext(::oox::core::FragmentHandler2 const &rParent, TimeNodePtrList &aList) noexcept
TimeNodeContext(::oox::core::FragmentHandler2 const &rParent, sal_Int32 aElement, const TimeNodePtr &pNode) noexcept
sal_Int32 one
static rtl::Reference< TimeNodeContext > makeContext(::oox::core::FragmentHandler2 const &rParent, sal_Int32 aElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttribs, const TimeNodePtr &pNode)
bool mbHasByColor
aStr
sal_Int32 mnAngle
void set(css::uno::UnoInterfaceReference const &value)
AnimColor m_byColor
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo