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