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