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