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