LibreOffice Module xmloff (master)  1
animationimport.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 
20 #include <memory>
22 #include <com/sun/star/lang/XInitialization.hpp>
23 #include <com/sun/star/animations/AnimationTransformType.hpp>
24 #include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
25 #include <com/sun/star/animations/AnimationNodeType.hpp>
26 #include <com/sun/star/animations/SequenceTimeContainer.hpp>
27 #include <com/sun/star/animations/XIterateContainer.hpp>
28 #include <com/sun/star/animations/XAnimateMotion.hpp>
29 #include <com/sun/star/animations/XAnimatePhysics.hpp>
30 #include <com/sun/star/animations/XAnimateColor.hpp>
31 #include <com/sun/star/animations/XAnimateTransform.hpp>
32 #include <com/sun/star/animations/XTransitionFilter.hpp>
33 #include <com/sun/star/animations/XCommand.hpp>
34 #include <com/sun/star/animations/XAudio.hpp>
35 #include <com/sun/star/animations/ValuePair.hpp>
36 #include <com/sun/star/animations/AnimationColorSpace.hpp>
37 #include <com/sun/star/presentation/EffectPresetClass.hpp>
38 #include <com/sun/star/animations/Timing.hpp>
39 #include <com/sun/star/animations/Event.hpp>
40 #include <com/sun/star/beans/XPropertySet.hpp>
41 #include <com/sun/star/io/WrongFormatException.hpp>
42 #include <com/sun/star/xml/sax/XFastAttributeList.hpp>
43 #include <com/sun/star/text/XTextCursor.hpp>
44 #include <com/sun/star/text/XTextRangeCompare.hpp>
45 #include <com/sun/star/presentation/ParagraphTarget.hpp>
46 #include <com/sun/star/container/XEnumerationAccess.hpp>
47 #include <com/sun/star/animations/EventTrigger.hpp>
48 #include <com/sun/star/presentation/EffectCommands.hpp>
49 #include <com/sun/star/util/Duration.hpp>
51 #include <comphelper/string.hxx>
52 
53 #include <sal/log.hxx>
54 #include <sax/tools/converter.hxx>
55 
56 #include <vector>
57 
58 #include <xmloff/xmltypes.hxx>
59 #include "sdpropls.hxx"
60 #include <xmloff/xmltoken.hxx>
61 #include <xmloff/xmlimp.hxx>
62 #include <xmloff/xmlnamespace.hxx>
63 #include <xmloff/xmluconv.hxx>
64 #include <osl/diagnose.h>
65 #include <xmloff/xmlprhdl.hxx>
66 #include <xmlsdtypes.hxx>
67 
68 #include <animations.hxx>
69 #include <animationimport.hxx>
70 
71 using namespace ::std;
72 using namespace ::cppu;
73 using namespace ::com::sun::star;
74 using namespace ::com::sun::star::beans;
75 using namespace ::com::sun::star::animations;
76 using namespace ::com::sun::star::presentation;
77 using namespace ::com::sun::star::drawing;
78 using namespace ::com::sun::star::uno;
79 using namespace ::xmloff::token;
80 
81 using ::com::sun::star::xml::sax::XFastAttributeList;
82 using ::com::sun::star::beans::NamedValue;
83 using ::com::sun::star::text::XTextRange;
84 using ::com::sun::star::text::XTextCursor;
85 using ::com::sun::star::text::XTextRangeCompare;
86 using ::com::sun::star::container::XEnumerationAccess;
87 using ::com::sun::star::container::XEnumeration;
88 using ::com::sun::star::lang::XInitialization;
89 
90 static OUString
91 lcl_GetMediaReference(SvXMLImport const& rImport, OUString const& rURL)
92 {
93  if (rImport.IsPackageURL(rURL))
94  return "vnd.sun.star.Package:" + rURL;
95 
96  return rImport.GetAbsoluteReference(rURL);
97 }
98 
99 namespace xmloff
100 {
101 
103 {
104 private:
106 
107 public:
108  explicit AnimationsImportHelperImpl( SvXMLImport& rImport );
109 
110  Any convertValue( XMLTokenEnum eAttributeName, const OUString& rValue );
111  Sequence< Any > convertValueSequence( XMLTokenEnum eAttributeName, const OUString& rValue );
112 
113  Any convertTarget( const OUString& rValue );
114  static Any convertPath( const OUString& rValue );
115  Any convertTiming( const OUString& rValue );
116  static Sequence< double > convertKeyTimes( const OUString& rValue );
117  static Sequence< TimeFilterPair > convertTimeFilter( const OUString& rValue );
118 };
119 
121 : mrImport( rImport )
122 {
123 }
124 
125 static bool isDouble( const OUString& rValue )
126 {
127  sal_Int32 nLength = rValue.getLength();
128  const sal_Unicode * pStr = rValue.getStr();
129  while( nLength )
130  {
131  if( (*pStr >= '0' && *pStr <= '9') || *pStr == '-' || *pStr == '.' || *pStr == '+' || *pStr == 'e' || *pStr == 'E' )
132  {
133  pStr++;
134  nLength--;
135  }
136  else
137  {
138  return false;
139  }
140  }
141 
142  return true;
143 }
144 
145 static bool isTime( const OUString& rValue )
146 {
147  sal_Int32 nLength = rValue.getLength();
148  const sal_Unicode * pStr;
149  for( pStr = rValue.getStr(); nLength; pStr++, nLength-- )
150  {
151  if( !( (*pStr >= '0' && *pStr <= '9') || *pStr == '-' || *pStr == '.' || *pStr == '+' || *pStr == 'e' || *pStr == 'E' ) )
152  break;
153  }
154 
155  // return true if this is a double (if someone forgot the 's' we silently ignore it)
156  // or if it's a double that ends with a 's' or 'S'
157  return (nLength == 0) || ((*pStr == 's' || *pStr == 'S') && (nLength == 1));
158 }
159 
161 {
162  try
163  {
165 
166  Reference< XShape > _xShape( xRef, UNO_QUERY );
167  if( _xShape.is() )
168  return makeAny( _xShape );
169 
170  Reference< XTextCursor > xTextCursor( xRef, UNO_QUERY );
171  if( xTextCursor.is() )
172  {
173  Reference< XTextRange > xStart( xTextCursor->getStart() ), xRange;
174  Reference< XShape > xShape( xTextCursor->getText(), UNO_QUERY_THROW );
175  Reference< XTextRangeCompare > xTextRangeCompare( xShape, UNO_QUERY_THROW );
176 
177  Reference< XEnumerationAccess > xParaEnumAccess( xShape, UNO_QUERY_THROW );
178  Reference< XEnumeration > xEnumeration( xParaEnumAccess->createEnumeration(), UNO_SET_THROW );
179  sal_Int16 nParagraph = 0;
180 
181  while( xEnumeration->hasMoreElements() )
182  {
183  xEnumeration->nextElement() >>= xRange;
184 
185  // break if start of selection is prior to end of current paragraph
186  if( xRange.is() && (xTextRangeCompare->compareRegionEnds( xStart, xRange ) >= 0 ) )
187  {
188  return makeAny( ParagraphTarget( xShape, nParagraph ) );
189  }
190 
191  nParagraph++;
192  }
193  }
194  }
195  catch (const RuntimeException&)
196  {
197  OSL_FAIL( "xmloff::AnimationsImportImpl::convertTarget(), RuntimeException caught!" );
198  }
199 
200  Any aAny;
201  return aAny;
202 }
203 
205 {
206  sal_Int32 nCommaPos = -1, nPos;
207  sal_Int32 nOpenBrakets = 0;
208  for( nPos = 0; (nPos < rValue.getLength()) && (nCommaPos == -1); nPos++ )
209  {
210  switch( rValue[nPos] )
211  {
212  case ',':
213  if( nOpenBrakets == 0 )
214  nCommaPos = nPos;
215  break;
216  case '(':
217  case '[':
218  case '{':
219  nOpenBrakets++;
220  break;
221  case ')':
222  case ']':
223  case '}':
224  nOpenBrakets--;
225  break;
226  }
227  }
228 
229  if( nCommaPos >= 0 )
230  {
231  ValuePair aPair;
232  aPair.First = convertValue( eAttributeName, rValue.copy( 0, nCommaPos ) );
233  aPair.Second = convertValue( eAttributeName, rValue.copy( nCommaPos+1 ) );
234  return makeAny( aPair );
235  }
236  else
237  {
238  Any aAny;
239  sal_Int32 nType = XML_TYPE_STRING;
240 
241  if( rValue.getLength() ) switch( eAttributeName )
242  {
243  case XML_X:
244  case XML_Y:
245  case XML_WIDTH:
246  case XML_HEIGHT:
247  case XML_TRANSLATE:
248  {
249  return makeAny( rValue );
250  }
251 
252  case XML_SCALE:
253  case XML_SKEWY:
254  case XML_SKEWX:
255  case XML_OPACITY:
256  case XML_ROTATE: nType = XML_TYPE_DOUBLE; break;
258  case XML_FILL_COLOR:
259  case XML_STROKE_COLOR:
260  case XML_DIM:
261  case XML_COLOR: nType = XML_TYPE_COLOR; break;
262  case XML_FILL: nType = XML_SD_TYPE_FILLSTYLE; break;
263  case XML_STROKE: nType = XML_SD_TYPE_STROKE; break;
264  case XML_FONT_WEIGHT: nType = XML_TYPE_TEXT_WEIGHT; break;
265  case XML_FONT_STYLE: nType = XML_TYPE_TEXT_POSTURE; break;
267  case XML_FONT_SIZE: nType = XML_TYPE_DOUBLE_PERCENT; break;
268  case XML_VISIBILITY: nType = XML_SD_TYPE_PRESPAGE_VISIBILITY; break;
269 
270  default:
271  if( !rValue.isEmpty() )
272  aAny <<= rValue;
273  return aAny;
274  }
275 
276  const XMLPropertyHandler* pHandler = mrImport.GetShapeImport()->GetSdPropHdlFactory()->GetPropertyHandler( nType );
277  if( pHandler )
278  pHandler->importXML( rValue, aAny, mrImport.GetMM100UnitConverter() );
279 
280  return aAny;
281  }
282 }
283 
284 Sequence< Any > AnimationsImportHelperImpl::convertValueSequence( XMLTokenEnum eAttributeName, const OUString& rValue )
285 {
286  Sequence< Any > aValues;
287 
288  const sal_Int32 nElements { comphelper::string::getTokenCount(rValue, ';') };
289  if ( nElements>0 )
290  {
291  // prepare the sequence
292  aValues.realloc( nElements );
293 
294  // fill the sequence
295  Any* pValues = aValues.getArray();
296  for (sal_Int32 nIndex = 0; nIndex >= 0; )
297  *pValues++ = convertValue( eAttributeName, rValue.getToken( 0, ';', nIndex ) );
298  }
299 
300  return aValues;
301 }
302 
304 {
305  Any aAny;
306 
307  const sal_Int32 nElements { comphelper::string::getTokenCount(rValue, ';') };
308  if ( nElements>0 )
309  {
310  if( nElements == 1 )
311  {
312  if( IsXMLToken( rValue, XML_MEDIA ) )
313  {
314  aAny <<= Timing_MEDIA;
315  }
316  else if( IsXMLToken( rValue, XML_INDEFINITE ) )
317  {
318  aAny <<= Timing_INDEFINITE;
319  }
320  else if( isTime( rValue ) )
321  {
322  aAny <<= rValue.toDouble();
323  }
324  else
325  {
326  Event aEvent;
327  aEvent.Repeat = 0;
328  aEvent.Trigger = 0;
329 
330  OUString aEventTrigger;
331 
332  sal_Int32 nPos = rValue.indexOf( '+' );
333  if( nPos == -1 )
334  {
335  aEventTrigger = rValue;
336  }
337  else
338  {
339  aEventTrigger = rValue.copy( 0, nPos );
340 
341  // convert offset
342  aEvent.Offset = convertTiming( rValue.copy( nPos + 1 ) );
343  }
344 
345  nPos = aEventTrigger.indexOf( '.' );
346  if( nPos != -1 )
347  {
348  aEvent.Source <<= mrImport.getInterfaceToIdentifierMapper().getReference( aEventTrigger.copy( 0, nPos ) );
349  aEventTrigger = aEventTrigger.copy( nPos + 1 );
350  }
351 
352  sal_Int16 nEnum;
354  {
355  aEvent.Trigger = nEnum;
356  }
357  else
358  {
359  OSL_FAIL("AnimationsImportHelperImpl::convertTiming(), unknown event trigger!");
360  }
361 
362  aAny <<= aEvent;
363  }
364  }
365  else
366  {
367  // fill the sequence
368  Sequence< Any > aValues( nElements );
369  Any* pValues = aValues.getArray();
370  for (sal_Int32 nIndex = 0; nIndex >= 0; )
371  *pValues++ = convertTiming( rValue.getToken( 0, ';', nIndex ) );
372 
373  aAny <<= aValues;
374  }
375  }
376  return aAny;
377 }
378 
379 Sequence< double > AnimationsImportHelperImpl::convertKeyTimes( const OUString& rValue )
380 {
381  const sal_Int32 nElements { comphelper::string::getTokenCount(rValue, ';') };
382 
383  Sequence< double > aKeyTimes( nElements );
384 
385  if( nElements )
386  {
387  double* pValues = aKeyTimes.getArray();
388  for (sal_Int32 nIndex = 0; nIndex >= 0; )
389  *pValues++ = rValue.getToken( 0, ';', nIndex ).toDouble();
390  }
391 
392  return aKeyTimes;
393 }
394 
395 Sequence< TimeFilterPair > AnimationsImportHelperImpl::convertTimeFilter( const OUString& rValue )
396 {
397  const sal_Int32 nElements { comphelper::string::getTokenCount(rValue, ';') };
398 
399  Sequence< TimeFilterPair > aTimeFilter( nElements );
400 
401  if( nElements )
402  {
403  TimeFilterPair* pValues = aTimeFilter.getArray();
404  for (sal_Int32 nIndex = 0; nIndex >= 0; )
405  {
406  const OUString aToken( rValue.getToken( 0, ';', nIndex ) );
407 
408  sal_Int32 nPos = aToken.indexOf( ',' );
409  if( nPos >= 0 )
410  {
411  pValues->Time = aToken.copy( 0, nPos ).toDouble();
412  pValues->Progress = aToken.copy( nPos+1 ).toDouble();
413  }
414  pValues++;
415  }
416  }
417 
418  return aTimeFilter;
419 }
420 
422 {
423  return makeAny( rValue );
424 }
425 
426 
428  const Reference< XAnimationNode >& xParentNode,
429  SvXMLImport& rImport, sal_Int32 nElement,
430  const css::uno::Reference< css::xml::sax::XFastAttributeList>& xAttrList,
431  const std::shared_ptr<AnimationsImportHelperImpl>& pHelper )
432 : SvXMLImportContext(rImport),
433  mpHelper( pHelper )
434 {
435  bool bRootContext = !pHelper;
436  try
437  {
438  if( bRootContext )
439  {
440  mpHelper = std::make_shared<AnimationsImportHelperImpl>( rImport );
441  mxNode = xParentNode;
442  }
443  else
444  {
445  sal_Int16 nPresetClass = EffectPresetClass::CUSTOM;
446 
447  const char* pServiceName = nullptr;
448 
449  // we see namespace ANIMATION and ANIMATION_OOO and PRESENTATION_OASIS and PRESENTATION_SO52 and PRESENTATION_OOO
450  switch( nElement & TOKEN_MASK )
451  {
452  case XML_SEQ:
453  pServiceName = "com.sun.star.animations.SequenceTimeContainer"; break;
454  case XML_ITERATE:
455  pServiceName = "com.sun.star.animations.IterateContainer"; break;
456  case XML_ANIMATE:
457  pServiceName = "com.sun.star.animations.Animate"; break;
458  case XML_SET:
459  pServiceName = "com.sun.star.animations.AnimateSet"; break;
460  case XML_ANIMATEMOTION:
461  pServiceName = "com.sun.star.animations.AnimateMotion"; break;
462  case XML_ANIMATEPHYSICS:
463  pServiceName = "com.sun.star.animations.AnimatePhysics"; break;
464  case XML_ANIMATECOLOR:
465  pServiceName = "com.sun.star.animations.AnimateColor"; break;
467  pServiceName = "com.sun.star.animations.AnimateTransform"; break;
469  pServiceName = "com.sun.star.animations.TransitionFilter"; break;
470  case XML_AUDIO:
471  pServiceName = "com.sun.star.animations.Audio"; break;
472  case XML_COMMAND:
473  pServiceName = "com.sun.star.animations.Command"; break;
474  case XML_PAR:
475  {
476  for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
477  {
478  if( (aIter.getToken() & TOKEN_MASK) == XML_PRESET_ID)
479  {
480  const OUString& rValue = aIter.toString();
481  if ( rValue == "ooo-entrance-random" )
482  {
483  nPresetClass = EffectPresetClass::ENTRANCE;
484  }
485  else if ( rValue == "ooo-exit-random" )
486  {
487  nPresetClass = EffectPresetClass::EXIT;
488  }
489 
490  if( nPresetClass != EffectPresetClass::CUSTOM )
491  {
492  pServiceName = "com.sun.star.comp.sd.RandomAnimationNode";
493  break;
494  }
495  }
496  }
497  if( !pServiceName )
498  pServiceName = "com.sun.star.animations.ParallelTimeContainer";
499  }
500  break;
501  default:
502  SAL_WARN("xmloff", "unexpected token '" + SvXMLImport::getNameFromToken(nElement)
503  << "' 0x" << std::hex << nElement);
504  break;
505  }
506 
507  if( pServiceName )
508  {
510 
511  mxNode.set(
512  xContext->getServiceManager()->createInstanceWithContext(OUString::createFromAscii(pServiceName), xContext),
513  UNO_QUERY_THROW );
514 
515  if( nPresetClass != EffectPresetClass::CUSTOM )
516  {
517  Reference< XInitialization > xInit( mxNode, UNO_QUERY_THROW );
518  const Any aAny( makeAny( nPresetClass ) );
519  Sequence< Any > aArgs( &aAny, 1 ) ;
520  xInit->initialize( aArgs );
521  }
522 
523  init_node( xAttrList );
524 
525  Reference< XTimeContainer > xParentContainer( xParentNode, UNO_QUERY_THROW );
526  xParentContainer->appendChild( mxNode );
527  }
528  }
529  }
530  catch (const RuntimeException&)
531  {
532  OSL_FAIL( "xmloff::AnimationsImportImpl::AnimationsImportImpl(), RuntimeException caught!" );
533  }
534 }
535 
536 void AnimationNodeContext::startFastElement( sal_Int32 /*nElement*/, const css::uno::Reference< css::xml::sax::XFastAttributeList >& )
537 {
538  // code of StartElement is moved to init_node that is now called
539  // in c'tor before appending this node to its parent.
540  // This is needed for random nodes that need the correct target
541  // set when child nodes are appended.
542 }
543 
544 void AnimationNodeContext::init_node( const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
545 {
546  if( !mxNode.is() )
547  return;
548 
549  try
550  {
551  const sal_Int16 nNodeType = mxNode->getType();
552 
553  // query for optional interfaces that are often used later
554  Reference< XAnimate > xAnimate( mxNode, UNO_QUERY );
555  Reference< XCommand > xCommand( mxNode, UNO_QUERY );
556  Reference< XTransitionFilter > xTransitionFilter( mxNode, UNO_QUERY );
557  Reference< XIterateContainer > xIter( mxNode, UNO_QUERY );
558 
559  std::vector< NamedValue > aUserData;
560  XMLTokenEnum meAttributeName = XML_TOKEN_INVALID;
561  OUString aFrom, aBy, aTo, aValues;
562  bool bHaveXmlId( false );
563  OUString sXmlId;
564 
565  sal_Int16 nEnum;
566  for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
567  {
568  OUString rValue = aIter.toString();
569  auto nToken = aIter.getToken();
570  switch( nToken )
571  {
572  case XML_ELEMENT(SMIL, XML_BEGIN):
573  case XML_ELEMENT(SMIL_COMPAT, XML_BEGIN):
574  case XML_ELEMENT(SMIL_SO52, XML_BEGIN):
575  {
576  mxNode->setBegin( mpHelper->convertTiming( rValue ) );
577  }
578  break;
579  case XML_ELEMENT(SMIL, XML_DUR):
580  case XML_ELEMENT(SMIL_COMPAT, XML_DUR):
581  case XML_ELEMENT(SMIL_SO52, XML_DUR):
582  {
583  mxNode->setDuration( mpHelper->convertTiming( rValue ) );
584  }
585  break;
586  case XML_ELEMENT(SMIL, XML_END):
587  case XML_ELEMENT(SMIL_COMPAT, XML_END):
588  case XML_ELEMENT(SMIL_SO52, XML_END):
589  {
590  mxNode->setEnd( mpHelper->convertTiming( rValue ) );
591  }
592  break;
593  case XML_ELEMENT(SMIL, XML_FILL):
594  case XML_ELEMENT(SMIL_COMPAT, XML_FILL):
595  case XML_ELEMENT(SMIL_SO52, XML_FILL):
596  {
598  mxNode->setFill( nEnum );
599  }
600  break;
601  case XML_ELEMENT(SMIL, XML_FILLDEFAULT):
602  case XML_ELEMENT(SMIL_COMPAT, XML_FILLDEFAULT):
603  case XML_ELEMENT(SMIL_SO52, XML_FILLDEFAULT):
604  {
606  mxNode->setFillDefault( nEnum );
607  }
608  break;
609  case XML_ELEMENT(SMIL, XML_RESTART):
610  case XML_ELEMENT(SMIL_COMPAT, XML_RESTART):
611  case XML_ELEMENT(SMIL_SO52, XML_RESTART):
612  {
614  mxNode->setRestart( nEnum );
615  }
616  break;
617  case XML_ELEMENT(SMIL, XML_RESTARTDEFAULT):
618  case XML_ELEMENT(SMIL_COMPAT, XML_RESTARTDEFAULT):
619  case XML_ELEMENT(SMIL_SO52, XML_RESTARTDEFAULT):
620  {
622  mxNode->setRestartDefault( nEnum );
623  }
624  break;
625  case XML_ELEMENT(SMIL, XML_ACCELERATE):
626  case XML_ELEMENT(SMIL_COMPAT, XML_ACCELERATE):
627  case XML_ELEMENT(SMIL_SO52, XML_ACCELERATE):
628  {
629  if( isDouble( rValue ) )
630  mxNode->setAcceleration( rValue.toDouble() );
631  }
632  break;
633  case XML_ELEMENT(SMIL, XML_DECELERATE):
634  case XML_ELEMENT(SMIL_COMPAT, XML_DECELERATE):
635  case XML_ELEMENT(SMIL_SO52, XML_DECELERATE):
636  {
637  if( isDouble( rValue ) )
638  mxNode->setDecelerate( rValue.toDouble() );
639  }
640  break;
641  case XML_ELEMENT(SMIL, XML_AUTOREVERSE):
642  case XML_ELEMENT(SMIL_COMPAT, XML_AUTOREVERSE):
643  case XML_ELEMENT(SMIL_SO52, XML_AUTOREVERSE):
644  {
645  bool bTemp;
646  if (::sax::Converter::convertBool( bTemp, rValue ))
647  mxNode->setAutoReverse( bTemp );
648  }
649  break;
650  case XML_ELEMENT(SMIL, XML_REPEATCOUNT):
651  case XML_ELEMENT(SMIL_COMPAT, XML_REPEATCOUNT):
652  case XML_ELEMENT(SMIL_SO52, XML_REPEATCOUNT):
653  {
654  mxNode->setRepeatCount( mpHelper->convertTiming( rValue ) );
655  }
656  break;
657  case XML_ELEMENT(SMIL, XML_REPEATDUR):
658  case XML_ELEMENT(SMIL_COMPAT, XML_REPEATDUR):
659  case XML_ELEMENT(SMIL_SO52, XML_REPEATDUR):
660  {
661  mxNode->setRepeatDuration( mpHelper->convertTiming( rValue ) );
662  }
663  break;
664  case XML_ELEMENT(SMIL, XML_ENDSYNC):
665  case XML_ELEMENT(SMIL_COMPAT, XML_ENDSYNC):
666  case XML_ELEMENT(SMIL_SO52, XML_ENDSYNC):
667  {
669  mxNode->setEndSync( makeAny( nEnum ) );
670  }
671  break;
672  case XML_ELEMENT(PRESENTATION, XML_NODE_TYPE):
673  case XML_ELEMENT(PRESENTATION_SO52, XML_NODE_TYPE):
674  case XML_ELEMENT(PRESENTATION_OOO, XML_NODE_TYPE):
675  case XML_ELEMENT(PRESENTATION_OASIS, XML_NODE_TYPE):
676  {
678  aUserData.emplace_back( GetXMLToken( XML_NODE_TYPE ), makeAny( nEnum ) );
679  }
680  break;
681  case XML_ELEMENT(PRESENTATION, XML_PRESET_ID):
682  case XML_ELEMENT(PRESENTATION_SO52, XML_PRESET_ID):
683  case XML_ELEMENT(PRESENTATION_OOO, XML_PRESET_ID):
684  case XML_ELEMENT(PRESENTATION_OASIS, XML_PRESET_ID):
685  {
686  aUserData.emplace_back( GetXMLToken( XML_PRESET_ID ), makeAny( rValue ) );
687  }
688  break;
689  case XML_ELEMENT(PRESENTATION, XML_PRESET_SUB_TYPE):
690  case XML_ELEMENT(PRESENTATION_SO52, XML_PRESET_SUB_TYPE):
691  case XML_ELEMENT(PRESENTATION_OOO, XML_PRESET_SUB_TYPE):
692  case XML_ELEMENT(PRESENTATION_OASIS, XML_PRESET_SUB_TYPE):
693  {
694  aUserData.emplace_back( GetXMLToken( XML_PRESET_SUB_TYPE ), makeAny( rValue ) );
695  }
696  break;
697  case XML_ELEMENT(PRESENTATION, XML_PRESET_CLASS):
698  case XML_ELEMENT(PRESENTATION_SO52, XML_PRESET_CLASS):
699  case XML_ELEMENT(PRESENTATION_OOO, XML_PRESET_CLASS):
700  case XML_ELEMENT(PRESENTATION_OASIS, XML_PRESET_CLASS):
701  {
703  aUserData.emplace_back( GetXMLToken( XML_PRESET_CLASS ), makeAny( nEnum ) );
704  }
705  break;
706  case XML_ELEMENT(PRESENTATION, XML_AFTER_EFFECT):
707  case XML_ELEMENT(PRESENTATION_SO52, XML_AFTER_EFFECT):
708  case XML_ELEMENT(PRESENTATION_OOO, XML_AFTER_EFFECT):
709  {
710  bool bTemp;
711  if (::sax::Converter::convertBool( bTemp, rValue ))
712  aUserData.emplace_back( GetXMLToken( XML_AFTER_EFFECT ), makeAny( bTemp ) );
713  }
714  break;
715  case XML_ELEMENT(XLINK, XML_HREF):
716  {
717  if( nNodeType == AnimationNodeType::AUDIO )
718  {
719  Reference< XAudio > xAudio( mxNode, UNO_QUERY_THROW );
720  xAudio->setSource( makeAny(lcl_GetMediaReference(GetImport(), rValue)) );
721  break;
722  }
723  [[fallthrough]];
724  }
725  case XML_ELEMENT(SMIL, XML_TARGETELEMENT):
726  case XML_ELEMENT(SMIL_COMPAT, XML_TARGETELEMENT):
727  case XML_ELEMENT(SMIL_SO52, XML_TARGETELEMENT):
728  {
729  Any aTarget( mpHelper->convertTarget( rValue ) );
730 
731  if( xAnimate.is() )
732  {
733  xAnimate->setTarget( aTarget );
734  }
735  else if( xIter.is() )
736  {
737  xIter->setTarget( aTarget );
738  }
739  else if( xCommand.is() )
740  {
741  xCommand->setTarget( aTarget );
742  }
743  }
744  break;
745 
746  case XML_ELEMENT(ANIMATION, XML_AUDIO_LEVEL):
747  case XML_ELEMENT(ANIMATION_OOO, XML_AUDIO_LEVEL):
748  {
749  if( nNodeType == AnimationNodeType::AUDIO )
750  {
751  if( isDouble( rValue ) )
752  {
753  Reference< XAudio > xAudio( mxNode, UNO_QUERY_THROW );
754  xAudio->setVolume( rValue.toDouble() );
755  }
756  }
757  }
758  break;
759 
760  case XML_ELEMENT(PRESENTATION, XML_MASTER_ELEMENT):
761  case XML_ELEMENT(PRESENTATION_SO52, XML_MASTER_ELEMENT):
762  case XML_ELEMENT(PRESENTATION_OOO, XML_MASTER_ELEMENT):
763  {
764  Reference< XAnimationNode > xMaster( GetImport().getInterfaceToIdentifierMapper().getReference( rValue ), UNO_QUERY );
765  aUserData.emplace_back( GetXMLToken( XML_MASTER_ELEMENT ), makeAny( xMaster ) );
766  }
767  break;
768 
769  case XML_ELEMENT(ANIMATION, XML_SUB_ITEM):
770  case XML_ELEMENT(ANIMATION_OOO, XML_SUB_ITEM):
771  {
773  {
774  if( xAnimate.is() )
775  {
776  xAnimate->setSubItem( nEnum );
777  }
778  else if( xIter.is() )
779  {
780  xIter->setSubItem( nEnum );
781  }
782  }
783  }
784  break;
785 
786  case XML_ELEMENT(SMIL, XML_ATTRIBUTENAME):
787  case XML_ELEMENT(SMIL_COMPAT, XML_ATTRIBUTENAME):
788  case XML_ELEMENT(SMIL_SO52, XML_ATTRIBUTENAME):
789  {
790  if( xAnimate.is() )
791  {
792  OUString aName( rValue );
793 
795  while( p->mpAPIName )
796  {
797  if( IsXMLToken( aName, p->meXMLToken ) )
798  {
799  aName = OUString::createFromAscii( p->mpAPIName );
800  meAttributeName = p->meXMLToken;
801  break;
802  }
803 
804  p++;
805  }
806 
807  xAnimate->setAttributeName( aName );
808  }
809  }
810  break;
811 
812  case XML_ELEMENT(SMIL, XML_VALUES):
813  case XML_ELEMENT(SMIL_COMPAT, XML_VALUES):
814  case XML_ELEMENT(SMIL_SO52, XML_VALUES):
815  {
816  aValues = rValue;
817  }
818  break;
819 
820  case XML_ELEMENT(SMIL, XML_FROM):
821  case XML_ELEMENT(SMIL_COMPAT, XML_FROM):
822  case XML_ELEMENT(SMIL_SO52, XML_FROM):
823  {
824  aFrom = rValue;
825  }
826  break;
827 
828  case XML_ELEMENT(SMIL, XML_BY):
829  case XML_ELEMENT(SMIL_COMPAT, XML_BY):
830  case XML_ELEMENT(SMIL_SO52, XML_BY):
831  {
832  aBy = rValue;
833  }
834  break;
835 
836  case XML_ELEMENT(SMIL, XML_TO):
837  case XML_ELEMENT(SMIL_COMPAT, XML_TO):
838  case XML_ELEMENT(SMIL_SO52, XML_TO):
839  {
840  aTo = rValue;
841  }
842  break;
843 
844  case XML_ELEMENT(SMIL, XML_KEYTIMES):
845  case XML_ELEMENT(SMIL_COMPAT, XML_KEYTIMES):
846  case XML_ELEMENT(SMIL_SO52, XML_KEYTIMES):
847  {
848  if( xAnimate.is() )
849  xAnimate->setKeyTimes( AnimationsImportHelperImpl::convertKeyTimes( rValue ) );
850  }
851  break;
852 
853  case XML_ELEMENT(ANIMATION, XML_FORMULA):
854  case XML_ELEMENT(ANIMATION_OOO, XML_FORMULA):
855  {
856  if( xAnimate.is() )
857  xAnimate->setFormula( rValue );
858  }
859  break;
860 
861  case XML_ELEMENT(ANIMATION, XML_ID):
862  case XML_ELEMENT(ANIMATION_OOO, XML_ID):
863  {
864  if (!bHaveXmlId) { sXmlId = rValue; }
865  }
866  break;
867  case XML_ELEMENT(XML, XML_ID):
868  {
869  sXmlId = rValue;
870  bHaveXmlId = true;
871  }
872  break;
873 
874  case XML_ELEMENT(SMIL, XML_CALCMODE):
875  case XML_ELEMENT(SMIL_COMPAT, XML_CALCMODE):
876  case XML_ELEMENT(SMIL_SO52, XML_CALCMODE):
877  {
878  if( xAnimate.is() )
879  {
881  xAnimate->setCalcMode( nEnum );
882  }
883  }
884  break;
885 
886  case XML_ELEMENT(SMIL, XML_ACCUMULATE):
887  case XML_ELEMENT(SMIL_COMPAT, XML_ACCUMULATE):
888  case XML_ELEMENT(SMIL_SO52, XML_ACCUMULATE):
889  {
890  if( xAnimate.is() )
891  xAnimate->setAccumulate( IsXMLToken( rValue, XML_SUM ) );
892  }
893  break;
894 
895  case XML_ELEMENT(PRESENTATION, XML_ADDITIVE):
896  case XML_ELEMENT(PRESENTATION_SO52, XML_ADDITIVE):
897  case XML_ELEMENT(PRESENTATION_OOO, XML_ADDITIVE):
898  case XML_ELEMENT(SMIL, XML_ADDITIVE):
899  case XML_ELEMENT(SMIL_COMPAT, XML_ADDITIVE):
900  case XML_ELEMENT(SMIL_SO52, XML_ADDITIVE):
901  {
902  if( xAnimate.is() )
903  {
905  xAnimate->setAdditive( nEnum );
906  }
907  }
908  break;
909 
910  case XML_ELEMENT(SMIL, XML_KEYSPLINES):
911  case XML_ELEMENT(SMIL_COMPAT, XML_KEYSPLINES):
912  case XML_ELEMENT(SMIL_SO52, XML_KEYSPLINES):
913  {
914  if( xAnimate.is() )
915  xAnimate->setTimeFilter( AnimationsImportHelperImpl::convertTimeFilter( rValue ) );
916  }
917  break;
918 
919  case XML_ELEMENT(SVG, XML_PATH):
920  case XML_ELEMENT(SVG_COMPAT, XML_PATH):
921  {
922  Reference< XAnimateMotion > xAnimateMotion( mxNode, UNO_QUERY );
923  if( xAnimateMotion.is() )
924  xAnimateMotion->setPath( AnimationsImportHelperImpl::convertPath( rValue ) );
925  }
926  break;
927 
931  {
932  Reference< XAnimatePhysics > xAnimatePhysics( mxNode, UNO_QUERY );
933  if( xAnimatePhysics.is() )
934  xAnimatePhysics->setStartVelocityX( makeAny(rValue.toDouble()) );
935  }
936  break;
937 
941  {
942  Reference< XAnimatePhysics > xAnimatePhysics( mxNode, UNO_QUERY );
943  if( xAnimatePhysics.is() )
944  xAnimatePhysics->setStartVelocityY( makeAny(rValue.toDouble()) );
945  }
946  break;
947 
949  case XML_ELEMENT(ANIMATION_OOO, XML_PHYSICS_ANIMATION_DENSITY):
951  {
952  Reference< XAnimatePhysics > xAnimatePhysics( mxNode, UNO_QUERY );
953  if( xAnimatePhysics.is() )
954  xAnimatePhysics->setDensity( makeAny(rValue.toDouble()) );
955  }
956  break;
957 
959  case XML_ELEMENT(ANIMATION_OOO, XML_PHYSICS_ANIMATION_BOUNCINESS):
961  {
962  Reference< XAnimatePhysics > xAnimatePhysics( mxNode, UNO_QUERY );
963  if( xAnimatePhysics.is() )
964  xAnimatePhysics->setBounciness( makeAny(rValue.toDouble()) );
965  }
966  break;
967 
968  case XML_ELEMENT(ANIMATION, XML_COLOR_INTERPOLATION):
969  case XML_ELEMENT(ANIMATION_OOO, XML_COLOR_INTERPOLATION):
970  {
971  Reference< XAnimateColor > xAnimateColor( mxNode, UNO_QUERY );
972  if( xAnimateColor.is() )
973  xAnimateColor->setColorInterpolation( IsXMLToken( rValue, XML_HSL ) ? AnimationColorSpace::HSL : AnimationColorSpace::RGB );
974  }
975  break;
976 
978  case XML_ELEMENT(ANIMATION_OOO, XML_COLOR_INTERPOLATION_DIRECTION):
979  {
980  Reference< XAnimateColor > xAnimateColor( mxNode, UNO_QUERY );
981  if( xAnimateColor.is() )
982  xAnimateColor->setDirection( IsXMLToken( rValue, XML_CLOCKWISE ) );
983  }
984  break;
985 
986  case XML_ELEMENT(SVG, XML_TYPE):
987  case XML_ELEMENT(SVG_COMPAT, XML_TYPE):
988  {
989  Reference< XAnimateTransform > xTransform( mxNode, UNO_QUERY );
990  if( xTransform.is() )
991  {
993  {
994  xTransform->setTransformType( nEnum );
995  switch( nEnum )
996  {
997  case AnimationTransformType::SCALE: meAttributeName = XML_SCALE; break;
998  case AnimationTransformType::ROTATE: meAttributeName = XML_ROTATE; break;
999  case AnimationTransformType::SKEWX: meAttributeName = XML_SKEWX; break;
1000  case AnimationTransformType::SKEWY: meAttributeName = XML_SKEWY; break;
1001  //case AnimationTransformType::TRANSLATE:
1002  default:
1003  meAttributeName = XML_TRANSLATE; break;
1004  }
1005  }
1006  }
1007  }
1008  break;
1009 
1010  case XML_ELEMENT(SMIL, XML_TYPE):
1011  case XML_ELEMENT(SMIL_COMPAT, XML_TYPE):
1012  case XML_ELEMENT(SMIL_SO52, XML_TYPE):
1013  {
1014  if( xTransitionFilter.is() )
1015  {
1017  xTransitionFilter->setTransition( nEnum );
1018  }
1019  }
1020  break;
1021 
1022  case XML_ELEMENT(SMIL, XML_SUBTYPE):
1023  case XML_ELEMENT(SMIL_COMPAT, XML_SUBTYPE):
1024  case XML_ELEMENT(SMIL_SO52, XML_SUBTYPE):
1025  {
1026  if( xTransitionFilter.is() )
1027  {
1029  xTransitionFilter->setSubtype( nEnum );
1030  }
1031  }
1032  break;
1033 
1034  case XML_ELEMENT(SMIL, XML_MODE):
1035  case XML_ELEMENT(SMIL_COMPAT, XML_MODE):
1036  case XML_ELEMENT(SMIL_SO52, XML_MODE):
1037  {
1038  if( xTransitionFilter.is() )
1039  xTransitionFilter->setMode( IsXMLToken( rValue, XML_IN ) );
1040  }
1041  break;
1042 
1043  case XML_ELEMENT(SMIL, XML_DIRECTION):
1044  case XML_ELEMENT(SMIL_COMPAT, XML_DIRECTION):
1045  case XML_ELEMENT(SMIL_SO52, XML_DIRECTION):
1046  {
1047  if( xTransitionFilter.is() )
1048  xTransitionFilter->setDirection( IsXMLToken( rValue, XML_FORWARD ) );
1049  }
1050  break;
1051 
1052  case XML_ELEMENT(SMIL, XML_FADECOLOR):
1053  case XML_ELEMENT(SMIL_COMPAT, XML_FADECOLOR):
1054  case XML_ELEMENT(SMIL_SO52, XML_FADECOLOR):
1055  {
1056  if( xTransitionFilter.is() )
1057  {
1058  sal_Int32 nColor(0);
1059  ::sax::Converter::convertColor(nColor, rValue);
1060  xTransitionFilter->setFadeColor(nColor);
1061  }
1062  }
1063  break;
1064 
1065  case XML_ELEMENT(ANIMATION, XML_ITERATE_TYPE):
1066  case XML_ELEMENT(ANIMATION_OOO, XML_ITERATE_TYPE):
1067  {
1069  {
1070  if( xIter.is() )
1071  xIter->setIterateType( nEnum );
1072  }
1073  }
1074  break;
1075 
1076  case XML_ELEMENT(ANIMATION, XML_ITERATE_INTERVAL):
1077  case XML_ELEMENT(ANIMATION_OOO, XML_ITERATE_INTERVAL):
1078  {
1079  if( xIter.is() )
1080  {
1081  double fInterval = 0.0;
1082  if( rValue.match("P") )
1083  {
1084  css::util::Duration aDuration;
1085  if (::sax::Converter::convertDuration(aDuration, rValue))
1086  {
1087  fInterval = ((((aDuration.Hours * 60)
1088  + aDuration.Minutes) * 60) + aDuration.Seconds)
1089  + (aDuration.NanoSeconds / 1000000000.0);
1090  }
1091  }
1092  else
1093  {
1094  fInterval = rValue.toDouble();
1095  }
1096 
1097  xIter->setIterateInterval( fInterval );
1098  }
1099  }
1100  break;
1101 
1102  case XML_ELEMENT(PRESENTATION, XML_GROUP_ID):
1103  case XML_ELEMENT(PRESENTATION_SO52, XML_GROUP_ID):
1104  case XML_ELEMENT(PRESENTATION_OOO, XML_GROUP_ID):
1105  {
1106  aUserData.emplace_back( "group-id", makeAny( rValue.toInt32() ) );
1107  }
1108  break;
1109 
1110  case XML_ELEMENT(ANIMATION, XML_COMMAND):
1111  case XML_ELEMENT(ANIMATION_OOO, XML_COMMAND):
1112  {
1113  if( xCommand.is() && nNodeType == AnimationNodeType::COMMAND )
1114  {
1116  {
1117  xCommand->setCommand( nEnum );
1118  }
1119  }
1120  }
1121  break;
1122 
1123  default:
1124  {
1125  // push all unknown attributes within the presentation namespace as user data
1130  {
1131  aUserData.emplace_back( SvXMLImport::getNameFromToken(aIter.getToken()), makeAny( rValue ) );
1132  }
1133  else
1134  SAL_WARN("xmloff", "unknown token '" + SvXMLImport::getNameFromToken(aIter.getToken())
1135  << "' 0x" << std::hex << aIter.getToken());
1136  }
1137  }
1138  }
1139 
1140  if (!sXmlId.isEmpty())
1141  {
1142  Reference< XInterface > const xRef( mxNode, UNO_QUERY );
1144  sXmlId, xRef );
1145  }
1146 
1147  sal_Int32 nUserDataCount = aUserData.size();
1148  if( nUserDataCount )
1149  {
1150  Sequence< NamedValue > aUnoUserData( nUserDataCount );
1151  NamedValue* pData = aUnoUserData.getArray();
1152  for (auto const& item : aUserData)
1153  *pData++ = item;
1154 
1155  mxNode->setUserData( aUnoUserData );
1156  }
1157 
1158  // convert values
1159  if( xAnimate.is() )
1160  {
1161  if( !aFrom.isEmpty() )
1162  xAnimate->setFrom( mpHelper->convertValue( meAttributeName, aFrom ) );
1163 
1164  if( !aBy.isEmpty() )
1165  xAnimate->setBy( mpHelper->convertValue( meAttributeName, aBy ) );
1166 
1167  if( !aTo.isEmpty() )
1168  xAnimate->setTo( mpHelper->convertValue( meAttributeName, aTo ) );
1169 
1170  if( !aValues.isEmpty() )
1171  xAnimate->setValues( mpHelper->convertValueSequence( meAttributeName, aValues ) );
1172 
1173  if (xAnimate->getValues().getLength() != xAnimate->getKeyTimes().getLength())
1174  throw css::io::WrongFormatException();
1175  }
1176  }
1177  catch (const css::io::WrongFormatException&)
1178  {
1179  throw;
1180  }
1181  catch (const RuntimeException&)
1182  {
1183  OSL_FAIL( "xmloff::AnimationNodeContext::StartElement(), RuntimeException caught!" );
1184  }
1185 }
1186 
1187 css::uno::Reference< css::xml::sax::XFastContextHandler > AnimationNodeContext::createFastChildContext(sal_Int32 nElement,
1188  const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList)
1189 {
1190  if( mxNode.is())
1191  return new AnimationNodeContext( mxNode, GetImport(), nElement, xAttrList, mpHelper );
1192  return nullptr;
1193 }
1194 
1195 namespace {
1196 
1197 class AnimationsImport: public SvXMLImport, public XAnimationNodeSupplier
1198 {
1199 public:
1200  explicit AnimationsImport( const Reference< XComponentContext > & rxContext );
1201 
1202  SvXMLImportContext* CreateFastContext(sal_Int32 nElement,
1203  const Reference<XFastAttributeList>& xAttrList) override;
1204 
1205  // XInterface
1206  virtual Any SAL_CALL queryInterface( const Type& aType ) override;
1207  virtual void SAL_CALL acquire() throw () override;
1208  virtual void SAL_CALL release() throw () override;
1209 
1210  // XAnimationNodeSupplier
1211  Reference< XAnimationNode > SAL_CALL getAnimationNode() override;
1212 
1213 private:
1214  Reference< XAnimationNode > mxRootNode;
1215 };
1216 
1217 }
1218 
1219 AnimationsImport::AnimationsImport( const Reference< XComponentContext > & rxContext )
1220 : SvXMLImport( rxContext, "xmloff::AnimationsImport", SvXMLImportFlags::META )
1221  //FIXME: the above "IMPORT_META" used to be a nonsensical "true", question
1222  // remains whether this should be IMPORT_META (same numerical value as
1223  // true) or default IMPORT_ALL
1224 {
1225  mxRootNode.set( SequenceTimeContainer::create(rxContext), UNO_QUERY_THROW );
1226 }
1227 
1228 // XInterface
1229 Any SAL_CALL AnimationsImport::queryInterface( const Type& aType )
1230 {
1232  {
1233  return makeAny( Reference<XAnimationNodeSupplier>( this ) );
1234  }
1235  else
1236  {
1237  return SvXMLImport::queryInterface( aType );
1238  }
1239 }
1240 
1241 void SAL_CALL AnimationsImport::acquire() throw ()
1242 {
1243  SvXMLImport::acquire();
1244 }
1245 
1246 void SAL_CALL AnimationsImport::release() throw ()
1247 {
1248  SvXMLImport::release();
1249 }
1250 
1251 SvXMLImportContext *AnimationsImport::CreateFastContext(
1252  sal_Int32 nElement,
1253  const Reference<XFastAttributeList>& xAttrList)
1254 {
1255  SvXMLImportContext* pContext = nullptr;
1256 
1257  if( nElement == XML_ELEMENT(ANIMATION, XML_SEQ) || nElement == XML_ELEMENT(ANIMATION_OOO, XML_SEQ) )
1258  {
1259  pContext = new AnimationNodeContext( mxRootNode, *this, nElement, xAttrList );
1260  }
1261 
1262  return pContext;
1263 }
1264 
1265 // XAnimationNodeSupplier
1266 Reference< XAnimationNode > SAL_CALL AnimationsImport::getAnimationNode()
1267 {
1268  return mxRootNode;
1269 }
1270 
1271 void AnimationNodeContext::postProcessRootNode( const Reference< XAnimationNode >& xRootNode, Reference< XPropertySet > const & xPageProps )
1272 {
1273  if( !(xRootNode.is() && xPageProps.is()) )
1274  return;
1275 
1276  try
1277  {
1278  Reference< XEnumerationAccess > xEnumerationAccess( xRootNode, UNO_QUERY_THROW );
1279  Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_SET_THROW );
1280  if( xEnumeration->hasMoreElements() )
1281  {
1282  Reference< XAnimationNode > xNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
1283  if( xNode->getType() == AnimationNodeType::PAR )
1284  {
1285  Event aEvent;
1286  if( (xNode->getBegin() >>= aEvent) && (aEvent.Trigger == EventTrigger::BEGIN_EVENT) )
1287  {
1288  // found transition node
1289  Reference< XEnumerationAccess > xChildEnumerationAccess( xNode, UNO_QUERY_THROW );
1290  Reference< XEnumeration > xChildEnumeration( xChildEnumerationAccess->createEnumeration(), UNO_SET_THROW );
1291  while( xChildEnumeration->hasMoreElements() )
1292  {
1293  Reference< XAnimationNode > xChildNode( xChildEnumeration->nextElement(), UNO_QUERY_THROW );
1294  switch( xChildNode->getType() )
1295  {
1296  case AnimationNodeType::TRANSITIONFILTER:
1297  {
1298  Reference< XTransitionFilter > xTransFilter( xChildNode, UNO_QUERY_THROW );
1299 
1300  xPageProps->setPropertyValue("TransitionType", Any( xTransFilter->getTransition() ) );
1301  xPageProps->setPropertyValue("TransitionSubtype", Any( xTransFilter->getSubtype() ) );
1302  xPageProps->setPropertyValue("TransitionDirection", Any( xTransFilter->getDirection() ) );
1303  xPageProps->setPropertyValue("TransitionFadeColor", Any( xTransFilter->getFadeColor() ) );
1304 
1305  double fDuration;
1306  if( xTransFilter->getDuration() >>= fDuration )
1307  xPageProps->setPropertyValue("TransitionDuration", Any( fDuration ) );
1308 
1309  }
1310  break;
1311 
1312  case AnimationNodeType::COMMAND:
1313  {
1314  Reference< XCommand > xCommand( xChildNode, UNO_QUERY_THROW );
1315  if( xCommand->getCommand() == EffectCommands::STOPAUDIO )
1316  {
1317  xPageProps->setPropertyValue("Sound", Any(true) );
1318  }
1319  }
1320  break;
1321 
1322  case AnimationNodeType::AUDIO:
1323  {
1324  Reference< XAudio > xAudio( xChildNode, UNO_QUERY_THROW );
1325  OUString sSoundURL;
1326  if( (xAudio->getSource() >>= sSoundURL) && !sSoundURL.isEmpty() )
1327  {
1328  xPageProps->setPropertyValue("Sound", Any(sSoundURL) );
1329 
1330  Timing eTiming;
1331  if( (xAudio->getRepeatCount() >>= eTiming) && (eTiming == Timing_INDEFINITE) )
1332  xPageProps->setPropertyValue("LoopSound", Any( true ) );
1333  }
1334  }
1335  break;
1336 
1337  }
1338  }
1339 
1340  Reference< XTimeContainer > xRootContainer( xRootNode, UNO_QUERY_THROW );
1341  xRootContainer->removeChild( xNode );
1342  }
1343  }
1344  }
1345  }
1346  catch (const Exception&)
1347  {
1348  OSL_FAIL("xmloff::AnimationsImport::postProcessRootNode(), exception caught!");
1349  }
1350 }
1351 
1352 } // namespace xmloff
1353 
1354 extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
1355 com_sun_star_comp_Xmloff_AnimationsImport(uno::XComponentContext* pCtx,
1356  uno::Sequence<uno::Any> const& /*rSeq*/)
1357 {
1358  return cppu::acquire(new xmloff::AnimationsImport(pCtx));
1359 }
1360 
1361 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Any convertValue(XMLTokenEnum eAttributeName, const OUString &rValue)
Type
constexpr sal_uInt16 XML_NAMESPACE_PRESENTATION_SO52
#define XML_TYPE_TEXT_UNDERLINE_STYLE
Definition: xmltypes.hxx:172
bool IsXMLToken(const OUString &rString, enum XMLTokenEnum eToken)
compare eToken to the string
Definition: xmltoken.cxx:3434
virtual void SAL_CALL startFastElement(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList) override
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_TransitionSubType[]
sal_Int32 nIndex
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_EffectPresetClass[]
Any convertTiming(const OUString &rValue)
Reference< XAnimationNode > mxRootNode
static bool convertEnum(EnumT &rEnum, const OUString &rValue, const SvXMLEnumMapEntry< EnumT > *pMap)
convert string to enum using given enum map, if the enum is not found in the map, this method will re...
Definition: xmluconv.hxx:128
#define XML_TYPE_DOUBLE
Definition: xmltypes.hxx:138
static bool convertBool(bool &rBool, const OUString &rString)
virtual css::uno::Reference< XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 Element, const css::uno::Reference< css::xml::sax::XFastAttributeList > &Attribs) override
static OUString lcl_GetMediaReference(SvXMLImport const &rImport, OUString const &rURL)
std::unique_ptr< ContentProperties > pData
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_TransitionType[]
SvXMLImport & GetImport()
Definition: xmlictxt.hxx:62
#define XML_TYPE_TEXT_POSTURE
Definition: xmltypes.hxx:170
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_Restart[]
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_TransformType[]
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
sal_Int32 getTokenCount(const OString &rIn, char cTok)
const css::uno::Reference< css::uno::XInterface > & getReference(const OUString &rIdentifier) const
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_Fill[]
AnimationsImportHelperImpl(SvXMLImport &rImport)
css::uno::Any const & rValue
Definition: ImageStyle.hxx:38
sal_uInt16 sal_Unicode
#define XML_TYPE_DOUBLE_PERCENT
Definition: xmltypes.hxx:154
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_Command[]
#define XML_SD_TYPE_STROKE
Definition: xmlsdtypes.hxx:34
SvXMLImportFlags
Definition: xmlimp.hxx:108
Environment aTo
static Sequence< double > convertKeyTimes(const OUString &rValue)
static Any convertPath(const OUString &rValue)
::comphelper::UnoInterfaceToUniqueIdentifierMapper & getInterfaceToIdentifierMapper()
Definition: xmlimp.cxx:1877
#define XML_SD_TYPE_PRESPAGE_VISIBILITY
Definition: xmlsdtypes.hxx:39
SAL_DLLPUBLIC_EXPORT uno::XInterface * com_sun_star_comp_Xmloff_AnimationsImport(uno::XComponentContext *pCtx, uno::Sequence< uno::Any > const &)
sal_Int32 nElements
XMLTokenEnum
The enumeration of all XML tokens.
Definition: xmltoken.hxx:49
Sequence< Any > convertValueSequence(XMLTokenEnum eAttributeName, const OUString &rValue)
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_EffectNodeType[]
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_Endsync[]
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_CalcMode[]
bool IsPackageURL(const OUString &rURL) const
Definition: xmlimp.cxx:1311
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_EventTrigger[]
const struct ImplAttributeNameConversion * getAnimationAttributeNamesConversionList()
#define XML_SD_TYPE_FILLSTYLE
Definition: xmlsdtypes.hxx:43
static void convertDuration(OUStringBuffer &rBuffer, const double fTime)
css::uno::Reference< css::animations::XAnimationNode > mxNode
void init_node(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
static const OUString & getNameFromToken(sal_Int32 nToken)
Definition: xmlimp.cxx:2020
This class deliberately does not support XWeak, to improve performance when loading large documents...
Definition: xmlictxt.hxx:44
constexpr sal_uInt16 XML_NAMESPACE_PRESENTATION
const PropertyValue * pValues
DefTokenId nToken
#define XML_TYPE_STRING
Definition: xmltypes.hxx:132
static bool isTime(const OUString &rValue)
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_SubItem[]
constexpr bool IsTokenInNamespace(sal_Int32 nToken, sal_uInt16 nNamespacePrefix)
Definition: xmlimp.hxx:101
OUString GetAbsoluteReference(const OUString &rValue) const
Definition: xmlimp.cxx:1690
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
return the OUString representation for eToken
Definition: xmltoken.cxx:3378
Any convertTarget(const OUString &rValue)
static bool convertColor(sal_Int32 &rColor, const OUString &rValue)
Handling of tokens in XML:
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_RestartDefault[]
OUString aName
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_IterateType[]
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_AdditiveMode[]
#define XML_ELEMENT(prefix, name)
Definition: xmlimp.hxx:94
std::shared_ptr< AnimationsImportHelperImpl > mpHelper
const SvXMLUnitConverter & GetMM100UnitConverter() const
Definition: xmlimp.hxx:404
void * p
Reference< XComponentContext > getProcessComponentContext()
QPRO_FUNC_TYPE nType
const SvXMLEnumMapEntry< sal_Int16 > aAnimations_EnumMap_FillDefault[]
#define XML_TYPE_TEXT_ROTATION_ANGLE
Definition: xmltypes.hxx:242
constexpr sal_uInt16 XML_NAMESPACE_PRESENTATION_OOO
#define SAL_WARN(area, stream)
constexpr sal_Int32 TOKEN_MASK
Definition: xmlimp.hxx:91
virtual bool importXML(const OUString &rStrImpValue, css::uno::Any &rValue, const SvXMLUnitConverter &rUnitConverter) const =0
Imports the given value according to the XML-data-type corresponding to the derived class...
Environment aFrom
AnimationNodeContext(const css::uno::Reference< css::animations::XAnimationNode > &xParentNode, SvXMLImport &rImport, sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList, const std::shared_ptr< AnimationsImportHelperImpl > &pImpl=nullptr)
#define XML_TYPE_TEXT_WEIGHT
Definition: xmltypes.hxx:173
static bool isDouble(const OUString &rValue)
Abstract base-class for different XML-types.
Definition: xmlprhdl.hxx:35
sal_Int32 nLength
Definition: xmltoken.cxx:36
const OUString & registerReference(const css::uno::Reference< css::uno::XInterface > &rInterface)
returns a unique identifier for the given uno object.
static void postProcessRootNode(const css::uno::Reference< css::animations::XAnimationNode > &xNode, css::uno::Reference< css::beans::XPropertySet > const &xPageProps)
constexpr sal_uInt16 XML_NAMESPACE_PRESENTATION_OASIS
css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType, Interface1 *p1)
AnyEventRef aEvent
sal_uInt16 nPos
#define XML_TYPE_COLOR
Definition: xmltypes.hxx:133
rtl::Reference< XMLShapeImportHelper > const & GetShapeImport()
Definition: xmlimp.hxx:608
static Sequence< TimeFilterPair > convertTimeFilter(const OUString &rValue)
css::uno::Any SAL_CALL makeAny(const SharedUNOComponent< INTERFACE, COMPONENT > &value)