1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #include "oox/ppt/timenodelistcontext.hxx" 25 26 #include "comphelper/anytostring.hxx" 27 #include "cppuhelper/exc_hlp.hxx" 28 #include <osl/diagnose.h> 29 #include <rtl/math.hxx> 30 31 #include <com/sun/star/animations/XTimeContainer.hpp> 32 #include <com/sun/star/animations/XAnimationNode.hpp> 33 #include <com/sun/star/animations/XAnimateColor.hpp> 34 #include <com/sun/star/animations/XAnimateSet.hpp> 35 #include <com/sun/star/animations/XAnimateTransform.hpp> 36 #include <com/sun/star/animations/AnimationTransformType.hpp> 37 #include <com/sun/star/animations/AnimationCalcMode.hpp> 38 #include <com/sun/star/animations/AnimationColorSpace.hpp> 39 #include <com/sun/star/animations/AnimationNodeType.hpp> 40 #include <com/sun/star/animations/XCommand.hpp> 41 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 42 #include <com/sun/star/presentation/EffectCommands.hpp> 43 #include <com/sun/star/beans/NamedValue.hpp> 44 45 #include "oox/helper/attributelist.hxx" 46 #include "oox/core/xmlfilterbase.hxx" 47 #include "oox/drawingml/drawingmltypes.hxx" 48 #include "oox/drawingml/colorchoicecontext.hxx" 49 #include "oox/ppt/slidetransition.hxx" 50 51 #include "animvariantcontext.hxx" 52 #include "commonbehaviorcontext.hxx" 53 #include "conditioncontext.hxx" 54 #include "commontimenodecontext.hxx" 55 #include "timeanimvaluecontext.hxx" 56 #include "animationtypes.hxx" 57 58 using namespace ::oox::core; 59 using namespace ::oox::drawingml; 60 using namespace ::com::sun::star::uno; 61 using namespace ::com::sun::star::lang; 62 using namespace ::com::sun::star::animations; 63 using namespace ::com::sun::star::presentation; 64 using namespace ::com::sun::star::xml::sax; 65 using namespace ::com::sun::star::awt; 66 using ::com::sun::star::beans::NamedValue; 67 68 using ::rtl::OUString; 69 70 namespace oox { namespace ppt { 71 72 struct AnimColor 73 { AnimColoroox::ppt::AnimColor74 AnimColor(sal_Int16 cs, sal_Int32 o, sal_Int32 t, sal_Int32 th ) 75 : colorSpace( cs ), one( o ), two( t ), three( th ) 76 { 77 } 78 getoox::ppt::AnimColor79 Any get() 80 { 81 sal_Int32 nColor; 82 Sequence< double > aHSL( 3 ); 83 Any aColor; 84 85 switch( colorSpace ) 86 { 87 case AnimationColorSpace::HSL: 88 aHSL[ 0 ] = double(one) / 100000; 89 aHSL[ 1 ] = double(two) / 100000; 90 aHSL[ 2 ] = double(three) / 100000; 91 aColor = Any(aHSL); 92 break; 93 case AnimationColorSpace::RGB: 94 nColor = ( ( ( one * 128 ) / 1000 ) & 0xff ) << 16 95 | ( ( ( two * 128 ) / 1000 ) & 0xff ) << 8 96 | ( ( ( three * 128 ) / 1000 ) & 0xff ); 97 aColor = Any(nColor); 98 break; 99 default: 100 nColor = 0; 101 aColor = Any( nColor ); 102 break; 103 } 104 return aColor; 105 } 106 107 sal_Int16 colorSpace; 108 sal_Int32 one; 109 sal_Int32 two; 110 sal_Int32 three; 111 }; 112 113 114 /** CT_TLMediaNodeAudio 115 CT_TLMediaNodeVideo */ 116 class MediaNodeContext 117 : public TimeNodeContext 118 { 119 public: MediaNodeContext(ContextHandler & rParent,sal_Int32 aElement,const Reference<XFastAttributeList> & xAttribs,const TimeNodePtr & pNode)120 MediaNodeContext( ContextHandler& rParent, sal_Int32 aElement, 121 const Reference< XFastAttributeList >& xAttribs, 122 const TimeNodePtr & pNode ) 123 : TimeNodeContext( rParent, aElement, xAttribs, pNode ) 124 , mbIsNarration( false ) 125 , mbFullScrn( false ) 126 { 127 AttributeList attribs( xAttribs ); 128 129 switch( aElement ) 130 { 131 case PPT_TOKEN( audio ): 132 mbIsNarration = attribs.getBool( XML_isNarration, false ); 133 break; 134 case PPT_TOKEN( video ): 135 mbFullScrn = attribs.getBool( XML_fullScrn, false ); 136 break; 137 default: 138 break; 139 } 140 } 141 endFastElement(sal_Int32 aElement)142 virtual void SAL_CALL endFastElement( sal_Int32 aElement ) 143 throw ( SAXException, RuntimeException) 144 { 145 if( aElement == PPT_TOKEN( audio ) ) 146 { 147 // TODO deal with mbIsNarration 148 } 149 else if( aElement == PPT_TOKEN( video ) ) 150 { 151 // TODO deal with mbFullScrn 152 } 153 } 154 createFastChildContext(::sal_Int32 aElementToken,const Reference<XFastAttributeList> & xAttribs)155 virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken, 156 const Reference< XFastAttributeList >& xAttribs ) 157 throw ( SAXException, RuntimeException ) 158 { 159 Reference< XFastContextHandler > xRet; 160 161 switch ( aElementToken ) 162 { 163 case PPT_TOKEN( cBhvr ): 164 xRet.set( new CommonBehaviorContext ( *this, xAttribs, mpNode ) ); 165 break; 166 default: 167 break; 168 } 169 170 if( !xRet.is() ) 171 xRet.set( this ); 172 173 return xRet; 174 } 175 176 private: 177 bool mbIsNarration; 178 bool mbFullScrn; 179 }; 180 181 182 /** CT_TLSetBehavior 183 */ 184 class SetTimeNodeContext 185 : public TimeNodeContext 186 { 187 public: SetTimeNodeContext(ContextHandler & rParent,sal_Int32 aElement,const Reference<XFastAttributeList> & xAttribs,const TimeNodePtr & pNode)188 SetTimeNodeContext( ContextHandler& rParent, sal_Int32 aElement, 189 const Reference< XFastAttributeList >& xAttribs, 190 const TimeNodePtr & pNode ) 191 : TimeNodeContext( rParent, aElement, xAttribs, pNode ) 192 { 193 194 } 195 ~SetTimeNodeContext()196 ~SetTimeNodeContext() throw () 197 { 198 if( maTo.hasValue() ) 199 { 200 // TODO 201 // HACK !!! discard and refactor 202 OUString aString; 203 if( maTo >>= aString ) 204 { 205 OSL_TRACE( "Magic conversion %s", OUSTRING_TO_CSTR( aString ) ); 206 maTo = makeAny( aString.equalsAscii( "visible" ) ? sal_True : sal_False ); 207 if( !maTo.has<sal_Bool>() ) 208 OSL_TRACE( "conversion failed" ); 209 } 210 mpNode->setTo( maTo ); 211 } 212 213 } 214 endFastElement(sal_Int32)215 virtual void SAL_CALL endFastElement( sal_Int32 /*aElement*/ ) 216 throw ( SAXException, RuntimeException) 217 { 218 } 219 220 createFastChildContext(::sal_Int32 aElementToken,const Reference<XFastAttributeList> & xAttribs)221 virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken, 222 const Reference< XFastAttributeList >& xAttribs ) 223 throw ( SAXException, RuntimeException ) 224 { 225 Reference< XFastContextHandler > xRet; 226 227 switch ( aElementToken ) 228 { 229 case PPT_TOKEN( cBhvr ): 230 xRet.set( new CommonBehaviorContext ( *this, xAttribs, mpNode ) ); 231 break; 232 case PPT_TOKEN( to ): 233 // CT_TLAnimVariant 234 xRet.set( new AnimVariantContext( *this, aElementToken, maTo ) ); 235 break; 236 default: 237 break; 238 } 239 240 if( !xRet.is() ) 241 xRet.set( this ); 242 243 return xRet; 244 } 245 private: 246 Any maTo; 247 }; 248 249 /** CT_TLCommandBehavior 250 */ 251 class CmdTimeNodeContext 252 : public TimeNodeContext 253 { 254 public: CmdTimeNodeContext(ContextHandler & rParent,sal_Int32 aElement,const Reference<XFastAttributeList> & xAttribs,const TimeNodePtr & pNode)255 CmdTimeNodeContext( ContextHandler& rParent, sal_Int32 aElement, 256 const Reference< XFastAttributeList >& xAttribs, 257 const TimeNodePtr & pNode ) 258 : TimeNodeContext( rParent, aElement, xAttribs, pNode ) 259 , maType(0) 260 { 261 switch ( aElement ) 262 { 263 case PPT_TOKEN( cmd ): 264 msCommand = xAttribs->getOptionalValue( XML_cmd ); 265 maType = xAttribs->getOptionalValueToken( XML_type, 0 ); 266 break; 267 default: 268 break; 269 } 270 } 271 ~CmdTimeNodeContext()272 ~CmdTimeNodeContext() throw () 273 { 274 } 275 endFastElement(sal_Int32 aElement)276 virtual void SAL_CALL endFastElement( sal_Int32 aElement ) 277 throw ( SAXException, RuntimeException) 278 { 279 if( aElement == PPT_TOKEN( cmd ) ) 280 { 281 try { 282 // see sd/source/filter/ppt/pptinanimations.cxx 283 // in AnimationImporter::importCommandContainer() 284 // REFACTOR? 285 // a good chunk of this code has been copied verbatim *sigh* 286 sal_Int16 nCommand = EffectCommands::CUSTOM; 287 NamedValue aParamValue; 288 289 switch( maType ) 290 { 291 case XML_verb: 292 aParamValue.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("Verb")); 293 // TODO make sure msCommand has what we want 294 aParamValue.Value <<= msCommand.toInt32(); 295 nCommand = EffectCommands::VERB; 296 break; 297 case XML_evt: 298 case XML_call: 299 if( msCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "onstopaudio" ) ) ) 300 { 301 nCommand = EffectCommands::STOPAUDIO; 302 } 303 else if( msCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("play") ) ) 304 { 305 nCommand = EffectCommands::PLAY; 306 } 307 else if( msCommand.compareToAscii( RTL_CONSTASCII_STRINGPARAM("playFrom") ) == 0 ) 308 { 309 const OUString aMediaTime( msCommand.copy( 9, msCommand.getLength() - 10 ) ); 310 rtl_math_ConversionStatus eStatus; 311 double fMediaTime = ::rtl::math::stringToDouble( aMediaTime, (sal_Unicode)('.'), (sal_Unicode)(','), &eStatus, NULL ); 312 if( eStatus == rtl_math_ConversionStatus_Ok ) 313 { 314 aParamValue.Name = CREATE_OUSTRING("MediaTime"); 315 aParamValue.Value <<= fMediaTime; 316 } 317 nCommand = EffectCommands::PLAY; 318 } 319 else if( msCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("togglePause") ) ) 320 { 321 nCommand = EffectCommands::TOGGLEPAUSE; 322 } 323 else if( msCommand.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("stop") ) ) 324 { 325 nCommand = EffectCommands::STOP; 326 } 327 break; 328 } 329 mpNode->getNodeProperties()[ NP_COMMAND ] = makeAny((sal_Int16)nCommand); 330 if( nCommand == EffectCommands::CUSTOM ) 331 { 332 OSL_TRACE("OOX: CmdTimeNodeContext::endFastElement(), unknown command!"); 333 aParamValue.Name = CREATE_OUSTRING("UserDefined"); 334 aParamValue.Value <<= msCommand; 335 } 336 if( aParamValue.Value.hasValue() ) 337 { 338 Sequence< NamedValue > aParamSeq( &aParamValue, 1 ); 339 mpNode->getNodeProperties()[ NP_PARAMETER ] = makeAny( aParamSeq ); 340 } 341 } 342 catch( RuntimeException& ) 343 { 344 OSL_TRACE( "OOX: Exception in CmdTimeNodeContext::endFastElement()" ); 345 } 346 } 347 } 348 349 createFastChildContext(::sal_Int32 aElementToken,const Reference<XFastAttributeList> & xAttribs)350 virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken, 351 const Reference< XFastAttributeList >& xAttribs ) 352 throw ( SAXException, RuntimeException ) 353 { 354 Reference< XFastContextHandler > xRet; 355 356 switch ( aElementToken ) 357 { 358 case PPT_TOKEN( cBhvr ): 359 xRet.set( new CommonBehaviorContext ( *this, xAttribs, mpNode ) ); 360 break; 361 default: 362 break; 363 } 364 365 if( !xRet.is() ) 366 xRet.set( this ); 367 368 return xRet; 369 } 370 371 private: 372 OUString msCommand; 373 sal_Int32 maType; 374 }; 375 376 377 /** CT_TLTimeNodeSequence 378 */ 379 class SequenceTimeNodeContext 380 : public TimeNodeContext 381 { 382 public: SequenceTimeNodeContext(ContextHandler & rParent,sal_Int32 aElement,const Reference<XFastAttributeList> & xAttribs,const TimeNodePtr & pNode)383 SequenceTimeNodeContext( ContextHandler& rParent, sal_Int32 aElement, 384 const Reference< XFastAttributeList >& xAttribs, 385 const TimeNodePtr & pNode ) 386 : TimeNodeContext( rParent, aElement, xAttribs, pNode ) 387 , mnNextAc(0) 388 , mnPrevAc(0) 389 { 390 AttributeList attribs(xAttribs); 391 mbConcurrent = attribs.getBool( XML_concurrent, false ); 392 // ST_TLNextActionType { none, seek } 393 mnNextAc = xAttribs->getOptionalValueToken( XML_nextAc, 0 ); 394 // ST_TLPreviousActionType { none, skipTimed } 395 mnPrevAc = xAttribs->getOptionalValueToken( XML_prevAc, 0 ); 396 } 397 ~SequenceTimeNodeContext()398 ~SequenceTimeNodeContext() throw() 399 { 400 } 401 402 createFastChildContext(::sal_Int32 aElementToken,const Reference<XFastAttributeList> & xAttribs)403 virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken, 404 const Reference< XFastAttributeList >& xAttribs ) 405 throw ( SAXException, RuntimeException ) 406 { 407 Reference< XFastContextHandler > xRet; 408 409 switch ( aElementToken ) 410 { 411 case PPT_TOKEN( cTn ): 412 xRet.set( new CommonTimeNodeContext( *this, aElementToken, xAttribs, mpNode ) ); 413 break; 414 case PPT_TOKEN( nextCondLst ): 415 xRet.set( new CondListContext( *this, aElementToken, xAttribs, mpNode, 416 mpNode->getNextCondition() ) ); 417 break; 418 case PPT_TOKEN( prevCondLst ): 419 xRet.set( new CondListContext( *this, aElementToken, xAttribs, mpNode, 420 mpNode->getPrevCondition() ) ); 421 break; 422 default: 423 break; 424 } 425 426 if( !xRet.is() ) 427 xRet.set( this ); 428 429 return xRet; 430 } 431 private: 432 bool mbConcurrent; 433 sal_Int32 mnNextAc, mnPrevAc; 434 }; 435 436 437 /** CT_TLTimeNodeParallel 438 * CT_TLTimeNodeExclusive 439 */ 440 class ParallelExclTimeNodeContext 441 : public TimeNodeContext 442 { 443 public: ParallelExclTimeNodeContext(ContextHandler & rParent,sal_Int32 aElement,const Reference<XFastAttributeList> & xAttribs,const TimeNodePtr & pNode)444 ParallelExclTimeNodeContext( ContextHandler& rParent, sal_Int32 aElement, 445 const Reference< XFastAttributeList >& xAttribs, 446 const TimeNodePtr & pNode ) 447 : TimeNodeContext( rParent, aElement, xAttribs, pNode ) 448 { 449 } 450 createFastChildContext(::sal_Int32 aElementToken,const Reference<XFastAttributeList> & xAttribs)451 virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken, 452 const Reference< XFastAttributeList >& xAttribs ) 453 throw ( SAXException, RuntimeException ) 454 { 455 Reference< XFastContextHandler > xRet; 456 457 switch ( aElementToken ) 458 { 459 case PPT_TOKEN( cTn ): 460 xRet.set( new CommonTimeNodeContext( *this, aElementToken, xAttribs, mpNode ) ); 461 break; 462 default: 463 break; 464 } 465 466 if( !xRet.is() ) 467 xRet.set( this ); 468 469 return xRet; 470 } 471 472 protected: 473 474 }; 475 476 477 /** CT_TLAnimateColorBehavior */ 478 class AnimColorContext 479 : public TimeNodeContext 480 { 481 public: AnimColorContext(ContextHandler & rParent,sal_Int32 aElement,const Reference<XFastAttributeList> & xAttribs,const TimeNodePtr & pNode)482 AnimColorContext( ContextHandler& rParent, sal_Int32 aElement, 483 const Reference< XFastAttributeList >& xAttribs, 484 const TimeNodePtr & pNode ) throw() 485 : TimeNodeContext( rParent, aElement, xAttribs, pNode ) 486 // ST_TLAnimateColorSpace ( XML_rgb, XML_hsl } 487 , mnColorSpace( xAttribs->getOptionalValueToken( XML_clrSpc, 0 ) ) 488 // ST_TLAnimateColorDirection { XML_cw, XML_ccw } 489 , mnDir( xAttribs->getOptionalValueToken( XML_dir, 0 ) ) 490 , mbHasByColor( false ) 491 , m_byColor( AnimationColorSpace::RGB, 0, 0, 0) 492 { 493 } ~AnimColorContext()494 ~AnimColorContext() throw() 495 { 496 } 497 endFastElement(sal_Int32 aElement)498 virtual void SAL_CALL endFastElement( sal_Int32 aElement ) throw ( SAXException, RuntimeException) 499 { 500 //xParentNode 501 if( aElement == mnElement ) 502 { 503 NodePropertyMap & pProps(mpNode->getNodeProperties()); 504 pProps[ NP_DIRECTION ] = makeAny( mnDir == XML_cw ); 505 pProps[ NP_COLORINTERPOLATION ] = makeAny( mnColorSpace == XML_hsl ? AnimationColorSpace::HSL : AnimationColorSpace::RGB ); 506 const GraphicHelper& rGraphicHelper = getFilter().getGraphicHelper(); 507 if( maToClr.isUsed() ) 508 mpNode->setTo( Any( maToClr.getColor( rGraphicHelper ) ) ); 509 if( maFromClr.isUsed() ) 510 mpNode->setFrom( Any( maFromClr.getColor( rGraphicHelper ) ) ); 511 if( mbHasByColor ) 512 mpNode->setBy( m_byColor.get() ); 513 } 514 } 515 516 createFastChildContext(::sal_Int32 aElementToken,const Reference<XFastAttributeList> & xAttribs)517 virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw ( SAXException, RuntimeException ) 518 { 519 Reference< XFastContextHandler > xRet; 520 521 switch ( aElementToken ) 522 { 523 case PPT_TOKEN( hsl ): 524 // CT_TLByHslColorTransform 525 { 526 if( mbHasByColor ) 527 { 528 m_byColor.colorSpace = AnimationColorSpace::HSL; 529 m_byColor.one = xAttribs->getOptionalValue( XML_h ).toInt32( ); 530 m_byColor.two = xAttribs->getOptionalValue( XML_s ).toInt32( ); 531 m_byColor.three = xAttribs->getOptionalValue( XML_l ).toInt32( ); 532 } 533 xRet.set(this); 534 break; 535 } 536 case PPT_TOKEN( rgb ): 537 { 538 if( mbHasByColor ) 539 { 540 // CT_TLByRgbColorTransform 541 m_byColor.colorSpace = AnimationColorSpace::RGB; 542 m_byColor.one = xAttribs->getOptionalValue( XML_r ).toInt32(); 543 m_byColor.two = xAttribs->getOptionalValue( XML_g ).toInt32(); 544 m_byColor.three = xAttribs->getOptionalValue( XML_b ).toInt32(); 545 } 546 xRet.set(this); 547 break; 548 } 549 case PPT_TOKEN( by ): 550 // CT_TLByAnimateColorTransform 551 mbHasByColor = true; 552 xRet.set(this); 553 break; 554 case PPT_TOKEN( cBhvr ): 555 xRet.set( new CommonBehaviorContext ( *this, xAttribs, mpNode ) ); 556 break; 557 case PPT_TOKEN( to ): 558 // CT_Color 559 xRet.set( new ColorContext( *this, maToClr ) ); 560 break; 561 case PPT_TOKEN( from ): 562 // CT_Color 563 xRet.set( new ColorContext( *this, maFromClr ) ); 564 break; 565 566 default: 567 break; 568 } 569 570 if( !xRet.is() ) 571 xRet.set( this ); 572 573 return xRet; 574 } 575 576 577 private: 578 sal_Int32 mnColorSpace; 579 sal_Int32 mnDir; 580 bool mbHasByColor; 581 AnimColor m_byColor; 582 oox::drawingml::Color maToClr; 583 oox::drawingml::Color maFromClr; 584 }; 585 586 587 /** CT_TLAnimateBehavior */ 588 class AnimContext 589 : public TimeNodeContext 590 { 591 public: AnimContext(ContextHandler & rParent,sal_Int32 aElement,const Reference<XFastAttributeList> & xAttribs,const TimeNodePtr & pNode)592 AnimContext( ContextHandler& rParent, sal_Int32 aElement, 593 const Reference< XFastAttributeList >& xAttribs, 594 const TimeNodePtr & pNode ) throw() 595 : TimeNodeContext( rParent, aElement, xAttribs, pNode ) 596 { 597 NodePropertyMap & aProps( pNode->getNodeProperties() ); 598 sal_Int32 nCalcMode = xAttribs->getOptionalValueToken( XML_calcmode, 0 ); 599 if(nCalcMode) 600 { 601 sal_Int16 nEnum = 0; 602 switch(nCalcMode) 603 { 604 case XML_discrete: 605 nEnum = AnimationCalcMode::DISCRETE; 606 break; 607 case XML_lin: 608 nEnum = AnimationCalcMode::LINEAR; 609 break; 610 case XML_fmla: 611 default: 612 // TODO what value is good ? 613 nEnum = AnimationCalcMode::DISCRETE; 614 break; 615 } 616 aProps[ NP_CALCMODE ] = makeAny(nEnum); 617 } 618 OUString aStr; 619 aStr = xAttribs->getOptionalValue( XML_from ); 620 if( aStr.getLength() ) 621 { 622 pNode->setFrom( makeAny( aStr ) ); 623 } 624 aStr = xAttribs->getOptionalValue( XML_by ); 625 if( aStr.getLength() ) 626 { 627 pNode->setBy( makeAny( aStr ) ); 628 } 629 aStr = xAttribs->getOptionalValue( XML_to ); 630 if( aStr.getLength() ) 631 { 632 pNode->setTo( makeAny( aStr ) ); 633 } 634 mnValueType = xAttribs->getOptionalValueToken( XML_valueType, 0 ); 635 } 636 637 ~AnimContext()638 ~AnimContext() throw () 639 { 640 ::std::list< TimeAnimationValue >::iterator iter, end; 641 int nKeyTimes = maTavList.size(); 642 if( nKeyTimes > 0) 643 { 644 int i; 645 Sequence< double > aKeyTimes( nKeyTimes ); 646 Sequence< Any > aValues( nKeyTimes ); 647 648 NodePropertyMap & aProps( mpNode->getNodeProperties() ); 649 end = maTavList.end(); 650 for(iter = maTavList.begin(), i=0; iter != end; iter++,i++) 651 { 652 // TODO what to do if it is Timing_INFINITE ? 653 Any aTime = GetTimeAnimateValueTime( iter->msTime ); 654 aTime >>= aKeyTimes[i]; 655 aValues[i] = iter->maValue; 656 657 OUString aTest; 658 iter->maValue >>= aTest; 659 if( aTest.getLength() != 0 ) 660 { 661 aValues[i] = iter->maValue; 662 } 663 else 664 { 665 aProps[ NP_FORMULA ] <<= iter->msFormula; 666 } 667 } 668 aProps[ NP_VALUES ] <<= aValues; 669 aProps[ NP_KEYTIMES ] <<= aKeyTimes; 670 } 671 } 672 673 createFastChildContext(::sal_Int32 aElementToken,const Reference<XFastAttributeList> & xAttribs)674 virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw ( SAXException, RuntimeException ) 675 { 676 Reference< XFastContextHandler > xRet; 677 678 switch ( aElementToken ) 679 { 680 case PPT_TOKEN( cBhvr ): 681 xRet.set( new CommonBehaviorContext ( *this, xAttribs, mpNode ) ); 682 break; 683 case PPT_TOKEN( tavLst ): 684 xRet.set( new TimeAnimValueListContext ( *this, xAttribs, maTavList ) ); 685 break; 686 default: 687 break; 688 } 689 690 if( !xRet.is() ) 691 xRet.set( this ); 692 693 return xRet; 694 } 695 private: 696 sal_Int32 mnValueType; 697 TimeAnimationValueList maTavList; 698 }; 699 700 701 /** CT_TLAnimateScaleBehavior */ 702 class AnimScaleContext 703 : public TimeNodeContext 704 { 705 public: AnimScaleContext(ContextHandler & rParent,sal_Int32 aElement,const Reference<XFastAttributeList> & xAttribs,const TimeNodePtr & pNode)706 AnimScaleContext( ContextHandler& rParent, sal_Int32 aElement, 707 const Reference< XFastAttributeList >& xAttribs, 708 const TimeNodePtr & pNode ) throw() 709 : TimeNodeContext( rParent, aElement, xAttribs, pNode ) 710 , mbZoomContents( false ) 711 { 712 AttributeList attribs( xAttribs ); 713 // TODO what to do with mbZoomContents 714 mbZoomContents = attribs.getBool( XML_zoomContents, false ); 715 pNode->getNodeProperties()[ NP_TRANSFORMTYPE ] 716 = makeAny((sal_Int16)AnimationTransformType::SCALE); 717 } 718 ~AnimScaleContext()719 ~AnimScaleContext( ) throw( ) 720 { 721 } 722 endFastElement(sal_Int32 aElement)723 virtual void SAL_CALL endFastElement( sal_Int32 aElement ) throw ( SAXException, RuntimeException) 724 { 725 if( aElement == mnElement ) 726 { 727 if( maTo.hasValue() ) 728 { 729 mpNode->setTo( maTo ); 730 } 731 if( maBy.hasValue() ) 732 { 733 mpNode->setBy( maBy ); 734 } 735 if( maFrom.hasValue() ) 736 { 737 mpNode->setFrom( maFrom ); 738 } 739 } 740 } 741 createFastChildContext(::sal_Int32 aElementToken,const Reference<XFastAttributeList> & xAttribs)742 virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken, 743 const Reference< XFastAttributeList >& xAttribs ) 744 throw ( SAXException, RuntimeException ) 745 { 746 Reference< XFastContextHandler > xRet; 747 748 switch ( aElementToken ) 749 { 750 case PPT_TOKEN( cBhvr ): 751 xRet.set( new CommonBehaviorContext ( *this, xAttribs, mpNode ) ); 752 break; 753 case PPT_TOKEN( to ): 754 { 755 // CT_TLPoint 756 Point p = GetPointPercent( xAttribs ); 757 maTo <<= p.X; 758 maTo <<= p.Y; 759 break; 760 } 761 case PPT_TOKEN( from ): 762 { 763 // CT_TLPoint 764 Point p = GetPointPercent( xAttribs ); 765 maFrom <<= p.X; 766 maFrom <<= p.Y; 767 break; 768 } 769 case PPT_TOKEN( by ): 770 { 771 // CT_TLPoint 772 Point p = GetPointPercent( xAttribs ); 773 maBy <<= p.X; 774 maBy <<= p.Y; 775 break; 776 } 777 default: 778 break; 779 } 780 781 if( !xRet.is() ) 782 xRet.set( this ); 783 784 return xRet; 785 } 786 private: 787 Any maBy; 788 Any maFrom; 789 Any maTo; 790 bool mbZoomContents; 791 }; 792 793 794 /** CT_TLAnimateRotationBehavior */ 795 class AnimRotContext 796 : public TimeNodeContext 797 { 798 public: AnimRotContext(ContextHandler & rParent,sal_Int32 aElement,const Reference<XFastAttributeList> & xAttribs,const TimeNodePtr & pNode)799 AnimRotContext( ContextHandler& rParent, sal_Int32 aElement, 800 const Reference< XFastAttributeList >& xAttribs, 801 const TimeNodePtr & pNode ) throw() 802 : TimeNodeContext( rParent, aElement, xAttribs, pNode ) 803 { 804 AttributeList attribs( xAttribs ); 805 806 pNode->getNodeProperties()[ NP_TRANSFORMTYPE ] 807 = makeAny((sal_Int16)AnimationTransformType::ROTATE); 808 // TODO make sure the units are OK 809 if(attribs.hasAttribute( XML_by ) ) 810 { 811 sal_Int32 nBy = attribs.getInteger( XML_by, 0 ); 812 pNode->setBy( makeAny( (double)nBy ) ); 813 } 814 if(attribs.hasAttribute( XML_from ) ) 815 { 816 sal_Int32 nFrom = attribs.getInteger( XML_from, 0 ); 817 pNode->setFrom( makeAny( nFrom ) ); 818 } 819 if(attribs.hasAttribute( XML_to ) ) 820 { 821 sal_Int32 nTo = attribs.getInteger( XML_to, 0 ); 822 pNode->setTo( makeAny( nTo ) ); 823 } 824 } 825 ~AnimRotContext()826 ~AnimRotContext( ) throw( ) 827 { 828 } 829 createFastChildContext(::sal_Int32 aElementToken,const Reference<XFastAttributeList> & xAttribs)830 virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw ( SAXException, RuntimeException ) 831 { 832 Reference< XFastContextHandler > xRet; 833 834 switch ( aElementToken ) 835 { 836 case PPT_TOKEN( cBhvr ): 837 xRet.set( new CommonBehaviorContext ( *this, xAttribs, mpNode ) ); 838 break; 839 default: 840 break; 841 } 842 843 if( !xRet.is() ) 844 xRet.set( this ); 845 846 return xRet; 847 } 848 }; 849 850 851 852 /** CT_TLAnimateMotionBehavior */ 853 class AnimMotionContext 854 : public TimeNodeContext 855 { 856 public: AnimMotionContext(ContextHandler & rParent,sal_Int32 aElement,const Reference<XFastAttributeList> & xAttribs,const TimeNodePtr & pNode)857 AnimMotionContext( ContextHandler& rParent, sal_Int32 aElement, 858 const Reference< XFastAttributeList >& xAttribs, 859 const TimeNodePtr & pNode ) throw() 860 : TimeNodeContext( rParent, aElement, xAttribs, pNode ) 861 { 862 pNode->getNodeProperties()[ NP_TRANSFORMTYPE ] 863 = makeAny((sal_Int16)AnimationTransformType::TRANSLATE); 864 865 AttributeList attribs( xAttribs ); 866 // ST_TLAnimateMotionBehaviorOrigin { parent, layour } 867 sal_Int32 nOrigin = xAttribs->getOptionalValueToken( XML_origin, 0 ); 868 if( nOrigin != 0 ) 869 { 870 switch(nOrigin) 871 { 872 case XML_layout: 873 case XML_parent: 874 break; 875 } 876 // TODO 877 } 878 879 OUString aStr = xAttribs->getOptionalValue( XML_path ); 880 aStr = aStr.replace( 'E', ' ' ); 881 aStr = aStr.trim(); 882 pNode->getNodeProperties()[ NP_PATH ] = makeAny(aStr); 883 884 // ST_TLAnimateMotionPathEditMode{ fixed, relative } 885 mnPathEditMode = xAttribs->getOptionalValueToken( XML_pathEditMode, 0 ); 886 msPtsTypes = xAttribs->getOptionalValue( XML_ptsTypes ); 887 mnAngle = attribs.getInteger( XML_rAng, 0 ); 888 // TODO make sure the units are right. Likely not. 889 } 890 ~AnimMotionContext()891 ~AnimMotionContext( ) throw() 892 { 893 } 894 895 createFastChildContext(::sal_Int32 aElementToken,const Reference<XFastAttributeList> & xAttribs)896 virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken, 897 const Reference< XFastAttributeList >& xAttribs ) 898 throw ( SAXException, RuntimeException ) 899 { 900 Reference< XFastContextHandler > xRet; 901 902 switch ( aElementToken ) 903 { 904 case PPT_TOKEN( cBhvr ): 905 xRet.set( new CommonBehaviorContext ( *this, xAttribs, mpNode ) ); 906 break; 907 case PPT_TOKEN( to ): 908 { 909 // CT_TLPoint 910 Point p = GetPointPercent( xAttribs ); 911 Any rAny; 912 rAny <<= p.X; 913 rAny <<= p.Y; 914 mpNode->setTo( rAny ); 915 break; 916 } 917 case PPT_TOKEN( from ): 918 { 919 // CT_TLPoint 920 Point p = GetPointPercent( xAttribs ); 921 Any rAny; 922 rAny <<= p.X; 923 rAny <<= p.Y; 924 mpNode->setFrom( rAny ); 925 break; 926 } 927 case PPT_TOKEN( by ): 928 { 929 // CT_TLPoint 930 Point p = GetPointPercent( xAttribs ); 931 Any rAny; 932 rAny <<= p.X; 933 rAny <<= p.Y; 934 mpNode->setBy( rAny ); 935 break; 936 } 937 case PPT_TOKEN( rCtr ): 938 { 939 // CT_TLPoint 940 Point p = GetPointPercent( xAttribs ); 941 // TODO push 942 break; 943 } 944 default: 945 break; 946 } 947 948 if( !xRet.is() ) 949 xRet.set( this ); 950 951 return xRet; 952 } 953 private: 954 OUString msPtsTypes; 955 sal_Int32 mnPathEditMode; 956 sal_Int32 mnAngle; 957 }; 958 959 960 /** CT_TLAnimateEffectBehavior */ 961 class AnimEffectContext 962 : public TimeNodeContext 963 { 964 public: AnimEffectContext(ContextHandler & rParent,sal_Int32 aElement,const Reference<XFastAttributeList> & xAttribs,const TimeNodePtr & pNode)965 AnimEffectContext( ContextHandler& rParent, sal_Int32 aElement, 966 const Reference< XFastAttributeList >& xAttribs, 967 const TimeNodePtr & pNode ) throw() 968 : TimeNodeContext( rParent, aElement, xAttribs, pNode ) 969 { 970 sal_Int32 nDir = xAttribs->getOptionalValueToken( XML_transition, 0 ); 971 OUString sFilter = xAttribs->getOptionalValue( XML_filter ); 972 // TODO 973 // OUString sPrList = xAttribs->getOptionalValue( XML_prLst ); 974 975 if( sFilter.getLength() ) 976 { 977 SlideTransition aFilter( sFilter ); 978 aFilter.setMode( nDir == XML_out ? false : true ); 979 pNode->setTransitionFilter( aFilter ); 980 } 981 } 982 983 ~AnimEffectContext()984 ~AnimEffectContext( ) throw() 985 { 986 } 987 988 createFastChildContext(::sal_Int32 aElementToken,const Reference<XFastAttributeList> & xAttribs)989 virtual Reference< XFastContextHandler > SAL_CALL createFastChildContext( ::sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw ( SAXException, RuntimeException ) 990 { 991 Reference< XFastContextHandler > xRet; 992 993 switch ( aElementToken ) 994 { 995 case PPT_TOKEN( cBhvr ): 996 xRet.set( new CommonBehaviorContext ( *this, xAttribs, mpNode ) ); 997 break; 998 case PPT_TOKEN( progress ): 999 xRet.set( new AnimVariantContext( *this, aElementToken, maProgress ) ); 1000 // TODO handle it. 1001 break; 1002 default: 1003 break; 1004 } 1005 1006 if( !xRet.is() ) 1007 xRet.set( this ); 1008 1009 return xRet; 1010 } 1011 private: 1012 Any maProgress; 1013 OUString msFilter; 1014 OUString msPrList; 1015 }; 1016 1017 1018 makeContext(ContextHandler & rParent,sal_Int32 aElement,const Reference<XFastAttributeList> & xAttribs,const TimeNodePtr & pNode)1019 TimeNodeContext * TimeNodeContext::makeContext( 1020 ContextHandler& rParent, sal_Int32 aElement, 1021 const Reference< XFastAttributeList >& xAttribs, 1022 const TimeNodePtr & pNode ) 1023 { 1024 TimeNodeContext *pCtx = NULL; 1025 switch( aElement ) 1026 { 1027 case PPT_TOKEN( animClr ): 1028 pCtx = new AnimColorContext( rParent, aElement, xAttribs, pNode ); 1029 break; 1030 case PPT_TOKEN( par ): 1031 pCtx = new ParallelExclTimeNodeContext( rParent, aElement, xAttribs, pNode ); 1032 break; 1033 case PPT_TOKEN( seq ): 1034 pCtx = new SequenceTimeNodeContext( rParent, aElement, xAttribs, pNode ); 1035 break; 1036 case PPT_TOKEN( excl ): 1037 pCtx = new ParallelExclTimeNodeContext( rParent, aElement, xAttribs, pNode ); 1038 break; 1039 case PPT_TOKEN( anim ): 1040 pCtx = new AnimContext ( rParent, aElement, xAttribs, pNode ); 1041 break; 1042 case PPT_TOKEN( animEffect ): 1043 pCtx = new AnimEffectContext( rParent, aElement, xAttribs, pNode ); 1044 break; 1045 case PPT_TOKEN( animMotion ): 1046 pCtx = new AnimMotionContext( rParent, aElement, xAttribs, pNode ); 1047 break; 1048 case PPT_TOKEN( animRot ): 1049 pCtx = new AnimRotContext( rParent, aElement, xAttribs, pNode ); 1050 break; 1051 case PPT_TOKEN( animScale ): 1052 pCtx = new AnimScaleContext( rParent, aElement, xAttribs, pNode ); 1053 break; 1054 case PPT_TOKEN( cmd ): 1055 pCtx = new CmdTimeNodeContext( rParent, aElement, xAttribs, pNode ); 1056 break; 1057 case PPT_TOKEN( set ): 1058 pCtx = new SetTimeNodeContext( rParent, aElement, xAttribs, pNode ); 1059 break; 1060 case PPT_TOKEN( audio ): 1061 case PPT_TOKEN( video ): 1062 pCtx = new MediaNodeContext( rParent, aElement, xAttribs, pNode ); 1063 break; 1064 default: 1065 break; 1066 } 1067 return pCtx; 1068 } 1069 1070 TimeNodeContext(ContextHandler & rParent,sal_Int32 aElement,const Reference<XFastAttributeList> &,const TimeNodePtr & pNode)1071 TimeNodeContext::TimeNodeContext( ContextHandler& rParent, sal_Int32 aElement, 1072 const Reference< XFastAttributeList >& /*xAttribs*/, 1073 const TimeNodePtr & pNode ) throw() 1074 : ContextHandler( rParent ) 1075 , mnElement( aElement ) 1076 , mpNode( pNode ) 1077 { 1078 } 1079 1080 ~TimeNodeContext()1081 TimeNodeContext::~TimeNodeContext( ) throw() 1082 { 1083 1084 } 1085 1086 TimeNodeListContext(ContextHandler & rParent,TimeNodePtrList & aList)1087 TimeNodeListContext::TimeNodeListContext( ContextHandler& rParent, TimeNodePtrList & aList ) 1088 throw() 1089 : ContextHandler( rParent ) 1090 , maList( aList ) 1091 { 1092 } 1093 1094 ~TimeNodeListContext()1095 TimeNodeListContext::~TimeNodeListContext( ) throw() 1096 { 1097 } 1098 1099 createFastChildContext(::sal_Int32 aElementToken,const Reference<XFastAttributeList> & xAttribs)1100 Reference< XFastContextHandler > SAL_CALL TimeNodeListContext::createFastChildContext( ::sal_Int32 aElementToken, const Reference< XFastAttributeList >& xAttribs ) throw (SAXException, RuntimeException) 1101 { 1102 Reference< XFastContextHandler > xRet; 1103 1104 sal_Int16 nNodeType; 1105 1106 switch( aElementToken ) 1107 { 1108 case PPT_TOKEN( par ): 1109 nNodeType = AnimationNodeType::PAR; 1110 break; 1111 case PPT_TOKEN( seq ): 1112 nNodeType = AnimationNodeType::SEQ; 1113 break; 1114 case PPT_TOKEN( excl ): 1115 // TODO pick the right type. We choose parallel for now as 1116 // there does not seem to be an "Exclusive" 1117 nNodeType = AnimationNodeType::PAR; 1118 break; 1119 case PPT_TOKEN( anim ): 1120 nNodeType = AnimationNodeType::ANIMATE; 1121 break; 1122 case PPT_TOKEN( animClr ): 1123 nNodeType = AnimationNodeType::ANIMATECOLOR; 1124 break; 1125 case PPT_TOKEN( animEffect ): 1126 nNodeType = AnimationNodeType::TRANSITIONFILTER; 1127 break; 1128 case PPT_TOKEN( animMotion ): 1129 nNodeType = AnimationNodeType::ANIMATEMOTION; 1130 break; 1131 case PPT_TOKEN( animRot ): 1132 case PPT_TOKEN( animScale ): 1133 nNodeType = AnimationNodeType::ANIMATETRANSFORM; 1134 break; 1135 case PPT_TOKEN( cmd ): 1136 nNodeType = AnimationNodeType::COMMAND; 1137 break; 1138 case PPT_TOKEN( set ): 1139 nNodeType = AnimationNodeType::SET; 1140 break; 1141 case PPT_TOKEN( audio ): 1142 nNodeType = AnimationNodeType::AUDIO; 1143 break; 1144 case PPT_TOKEN( video ): 1145 nNodeType = AnimationNodeType::AUDIO; 1146 OSL_TRACE( "OOX: video requested, gave Audio instead" ); 1147 break; 1148 1149 default: 1150 nNodeType = AnimationNodeType::CUSTOM; 1151 OSL_TRACE( "OOX: uhandled token %x", aElementToken ); 1152 break; 1153 } 1154 1155 TimeNodePtr pNode(new TimeNode(nNodeType)); 1156 maList.push_back( pNode ); 1157 ContextHandler * pContext = TimeNodeContext::makeContext( *this, aElementToken, xAttribs, pNode ); 1158 xRet.set( pContext ? pContext : this ); 1159 1160 return xRet; 1161 } 1162 1163 1164 } } 1165