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