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