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 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_xmloff.hxx" 30 31 #include <tools/debug.hxx> 32 #include <tools/time.hxx> 33 #include "unointerfacetouniqueidentifiermapper.hxx" 34 #include <com/sun/star/lang/XServiceInfo.hpp> 35 #include <com/sun/star/lang/XInitialization.hpp> 36 #include <com/sun/star/animations/AnimationTransformType.hpp> 37 #include <com/sun/star/animations/XAnimationNodeSupplier.hpp> 38 #include <com/sun/star/presentation/AnimationEffect.hpp> 39 #include <com/sun/star/presentation/AnimationSpeed.hpp> 40 #include <com/sun/star/animations/AnimationNodeType.hpp> 41 #include <com/sun/star/animations/XIterateContainer.hpp> 42 #include <com/sun/star/animations/XAnimateMotion.hpp> 43 #include <com/sun/star/animations/XAnimateColor.hpp> 44 #include <com/sun/star/animations/XAnimateTransform.hpp> 45 #include <com/sun/star/animations/XTransitionFilter.hpp> 46 #include <com/sun/star/animations/XCommand.hpp> 47 #include <com/sun/star/animations/XAudio.hpp> 48 #include <com/sun/star/animations/ValuePair.hpp> 49 #include <com/sun/star/animations/AnimationColorSpace.hpp> 50 #include <com/sun/star/presentation/EffectPresetClass.hpp> 51 #include <com/sun/star/animations/Timing.hpp> 52 #include <com/sun/star/animations/Event.hpp> 53 #include <com/sun/star/beans/XPropertySet.hpp> 54 #include <com/sun/star/xml/sax/XAttributeList.hpp> 55 #include <com/sun/star/text/XTextCursor.hpp> 56 #include <com/sun/star/text/XTextRangeCompare.hpp> 57 #include <com/sun/star/presentation/ParagraphTarget.hpp> 58 #include <com/sun/star/container/XEnumerationAccess.hpp> 59 #include <com/sun/star/beans/XPropertySet.hpp> 60 #include <com/sun/star/animations/EventTrigger.hpp> 61 #include <com/sun/star/presentation/EffectCommands.hpp> 62 #include <comphelper/processfactory.hxx> 63 #include <cppuhelper/implbase1.hxx> 64 65 #include <list> 66 #include <xmloff/xmltypes.hxx> 67 #include "sdpropls.hxx" 68 #include <xmloff/xmltoken.hxx> 69 #include <xmloff/xmlimp.hxx> 70 #include "xmloff/xmlnmspe.hxx" 71 #include <xmloff/xmluconv.hxx> 72 #include <osl/mutex.hxx> 73 #include <xmloff/nmspmap.hxx> 74 #include "anim.hxx" 75 76 #include "animations.hxx" 77 #include "animationimport.hxx" 78 79 using ::rtl::OUString; 80 using ::rtl::OUStringBuffer; 81 82 using namespace ::std; 83 using namespace ::cppu; 84 using namespace ::com::sun::star::beans; 85 using namespace ::com::sun::star::animations; 86 using namespace ::com::sun::star::presentation; 87 using namespace ::com::sun::star::drawing; 88 using namespace ::xmloff::token; 89 90 using ::com::sun::star::xml::sax::XAttributeList; 91 using ::com::sun::star::uno::Any; 92 using ::com::sun::star::uno::makeAny; 93 using ::com::sun::star::uno::UNO_QUERY; 94 using ::com::sun::star::uno::UNO_QUERY_THROW; 95 using ::com::sun::star::uno::Reference; 96 using ::com::sun::star::uno::Sequence; 97 using ::com::sun::star::uno::RuntimeException; 98 using ::com::sun::star::uno::Exception; 99 using ::com::sun::star::uno::XInterface; 100 using ::com::sun::star::uno::Type; 101 using ::com::sun::star::beans::NamedValue; 102 using ::com::sun::star::text::XTextRange; 103 using ::com::sun::star::text::XTextCursor; 104 using ::com::sun::star::text::XTextRangeCompare; 105 using ::com::sun::star::container::XEnumerationAccess; 106 using ::com::sun::star::container::XEnumeration; 107 using ::com::sun::star::lang::XMultiServiceFactory; 108 using ::com::sun::star::lang::XInitialization; 109 110 namespace xmloff 111 { 112 113 /////////////////////////////////////////////////////////////////////// 114 115 116 117 /////////////////////////////////////////////////////////////////////// 118 119 120 /////////////////////////////////////////////////////////////////////// 121 122 class AnimationsImportHelperImpl 123 { 124 private: 125 SvXMLImport& mrImport; 126 127 SvXMLTokenMap* mpAnimationNodeTokenMap; 128 SvXMLTokenMap* mpAnimationNodeAttributeTokenMap; 129 130 public: 131 AnimationsImportHelperImpl( SvXMLImport& rImport ); 132 ~AnimationsImportHelperImpl(); 133 134 const SvXMLTokenMap& getAnimationNodeTokenMap(); 135 const SvXMLTokenMap& getAnimationNodeAttributeTokenMap(); 136 137 Any convertValue( XMLTokenEnum eAttributeName, const OUString& rValue ); 138 Sequence< Any > convertValueSequence( XMLTokenEnum eAttributeName, const OUString& rValue ); 139 140 Any convertTarget( const OUString& rValue ); 141 Any convertPath( const OUString& rValue ); 142 Any convertTiming( const OUString& rValue ); 143 Sequence< double > convertKeyTimes( const OUString& rValue ); 144 Sequence< TimeFilterPair > convertTimeFilter( const OUString& rValue ); 145 146 bool convertAnimationValue( XMLTokenEnum eAttributeName, Any& rValue ); 147 const OUString mastrHSL; 148 }; 149 150 AnimationsImportHelperImpl::AnimationsImportHelperImpl( SvXMLImport& rImport ) 151 : mrImport( rImport ), 152 mpAnimationNodeTokenMap( NULL ), 153 mpAnimationNodeAttributeTokenMap( NULL ), 154 mastrHSL( RTL_CONSTASCII_USTRINGPARAM( "hsl" ) ) 155 { 156 } 157 158 AnimationsImportHelperImpl::~AnimationsImportHelperImpl() 159 { 160 delete mpAnimationNodeTokenMap; 161 delete mpAnimationNodeAttributeTokenMap; 162 } 163 164 const SvXMLTokenMap& AnimationsImportHelperImpl::getAnimationNodeTokenMap() 165 { 166 if( mpAnimationNodeTokenMap == NULL ) 167 { 168 static __FAR_DATA SvXMLTokenMapEntry aAnimationNodeTokenMap[] = 169 { 170 { XML_NAMESPACE_ANIMATION, XML_PAR, (sal_uInt16)AnimationNodeType::PAR }, 171 { XML_NAMESPACE_ANIMATION, XML_SEQ, (sal_uInt16)AnimationNodeType::SEQ }, 172 { XML_NAMESPACE_ANIMATION, XML_ITERATE, (sal_uInt16)AnimationNodeType::ITERATE }, 173 { XML_NAMESPACE_ANIMATION, XML_ANIMATE, (sal_uInt16)AnimationNodeType::ANIMATE }, 174 { XML_NAMESPACE_ANIMATION, XML_SET, (sal_uInt16)AnimationNodeType::SET }, 175 { XML_NAMESPACE_ANIMATION, XML_ANIMATEMOTION, (sal_uInt16)AnimationNodeType::ANIMATEMOTION }, 176 { XML_NAMESPACE_ANIMATION, XML_ANIMATECOLOR, (sal_uInt16)AnimationNodeType::ANIMATECOLOR }, 177 { XML_NAMESPACE_ANIMATION, XML_ANIMATETRANSFORM, (sal_uInt16)AnimationNodeType::ANIMATETRANSFORM }, 178 { XML_NAMESPACE_ANIMATION, XML_TRANSITIONFILTER, (sal_uInt16)AnimationNodeType::TRANSITIONFILTER }, 179 { XML_NAMESPACE_ANIMATION, XML_AUDIO, (sal_uInt16)AnimationNodeType::AUDIO }, 180 { XML_NAMESPACE_ANIMATION, XML_COMMAND, (sal_uInt16)AnimationNodeType::COMMAND }, 181 XML_TOKEN_MAP_END 182 }; 183 184 mpAnimationNodeTokenMap = new SvXMLTokenMap( aAnimationNodeTokenMap ); 185 } 186 187 return *mpAnimationNodeTokenMap; 188 } 189 190 enum AnimationNodeAttributes 191 { 192 ANA_Begin, 193 ANA_Dur, 194 ANA_End, 195 ANA_Fill, 196 ANA_FillDefault, 197 ANA_Restart, 198 ANA_RestartDefault, 199 ANA_Accelerate, 200 ANA_Decelerate, 201 ANA_AutoReverse, 202 ANA_RepeatCount, 203 ANA_RepeatDur, 204 ANA_EndSync, 205 ANA_Node_Type, 206 ANA_Preset_ID, 207 ANA_Preset_Sub_Type, 208 ANA_Preset_Class, 209 ANA_After_Effect, 210 ANA_Target, 211 ANA_XLink, 212 ANA_MasterElement, 213 ANA_SubItem, 214 ANA_AttributeName, 215 ANA_Values, 216 ANA_From, 217 ANA_By, 218 ANA_To, 219 ANA_KeyTimes, 220 ANA_CalcMode, 221 ANA_Accumulate, 222 ANA_AdditiveMode, 223 ANA_KeySplines, 224 ANA_Path, 225 ANA_ColorSpace, 226 ANA_ColorDirection, 227 ANA_TransformType, 228 ANA_TransitionType, 229 ANA_TransitionSubType, 230 ANA_Mode, 231 ANA_Direction, 232 ANA_FadeColor, 233 ANA_IterateType, 234 ANA_IterateInterval, 235 ANA_Formula, 236 ANA_ANIMID, 237 ANA_XMLID, 238 ANA_Group_Id, 239 ANA_Command, 240 ANA_Volume 241 }; 242 243 const SvXMLTokenMap& AnimationsImportHelperImpl::getAnimationNodeAttributeTokenMap() 244 { 245 if( mpAnimationNodeAttributeTokenMap == NULL ) 246 { 247 static __FAR_DATA SvXMLTokenMapEntry aAnimationNodeAttributeTokenMap[] = 248 { 249 { XML_NAMESPACE_SMIL, XML_BEGIN, (sal_uInt16)ANA_Begin }, 250 { XML_NAMESPACE_SMIL, XML_DUR, (sal_uInt16)ANA_Dur }, 251 { XML_NAMESPACE_SMIL, XML_END, (sal_uInt16)ANA_End }, 252 { XML_NAMESPACE_SMIL, XML_FILL, (sal_uInt16)ANA_Fill }, 253 { XML_NAMESPACE_SMIL, XML_FILLDEFAULT, (sal_uInt16)ANA_FillDefault }, 254 { XML_NAMESPACE_SMIL, XML_RESTART, (sal_uInt16)ANA_Restart }, 255 { XML_NAMESPACE_SMIL, XML_RESTARTDEFAULT, (sal_uInt16)ANA_RestartDefault }, 256 { XML_NAMESPACE_SMIL, XML_ACCELERATE, (sal_uInt16)ANA_Accelerate }, 257 { XML_NAMESPACE_SMIL, XML_DECELERATE, (sal_uInt16)ANA_Decelerate }, 258 { XML_NAMESPACE_SMIL, XML_AUTOREVERSE, (sal_uInt16)ANA_AutoReverse }, 259 { XML_NAMESPACE_SMIL, XML_REPEATCOUNT, (sal_uInt16)ANA_RepeatCount }, 260 { XML_NAMESPACE_SMIL, XML_REPEATDUR, (sal_uInt16)ANA_RepeatDur }, 261 { XML_NAMESPACE_SMIL, XML_ENDSYNC, (sal_uInt16)ANA_EndSync }, 262 { XML_NAMESPACE_PRESENTATION, XML_NODE_TYPE, (sal_uInt16)ANA_Node_Type }, 263 { XML_NAMESPACE_PRESENTATION, XML_PRESET_ID, (sal_uInt16)ANA_Preset_ID }, 264 { XML_NAMESPACE_PRESENTATION, XML_PRESET_SUB_TYPE, (sal_uInt16)ANA_Preset_Sub_Type }, 265 { XML_NAMESPACE_PRESENTATION, XML_PRESET_CLASS, (sal_uInt16)ANA_Preset_Class }, 266 { XML_NAMESPACE_PRESENTATION, XML_AFTER_EFFECT, (sal_uInt16)ANA_After_Effect }, 267 { XML_NAMESPACE_SMIL, XML_TARGETELEMENT, (sal_uInt16)ANA_Target }, 268 { XML_NAMESPACE_XLINK, XML_HREF, (sal_uInt16)ANA_XLink }, 269 { XML_NAMESPACE_PRESENTATION, XML_MASTER_ELEMENT, (sal_uInt16)ANA_MasterElement }, 270 { XML_NAMESPACE_ANIMATION, XML_SUB_ITEM, (sal_uInt16)ANA_SubItem }, 271 { XML_NAMESPACE_SMIL, XML_ATTRIBUTENAME, (sal_uInt16)ANA_AttributeName }, 272 { XML_NAMESPACE_SMIL, XML_VALUES, (sal_uInt16)ANA_Values }, 273 { XML_NAMESPACE_SMIL, XML_FROM, (sal_uInt16)ANA_From }, 274 { XML_NAMESPACE_SMIL, XML_BY, (sal_uInt16)ANA_By }, 275 { XML_NAMESPACE_SMIL, XML_TO, (sal_uInt16)ANA_To }, 276 { XML_NAMESPACE_SMIL, XML_KEYTIMES, (sal_uInt16)ANA_KeyTimes }, 277 { XML_NAMESPACE_SMIL, XML_CALCMODE, (sal_uInt16)ANA_CalcMode }, 278 { XML_NAMESPACE_SMIL, XML_ACCUMULATE, (sal_uInt16)ANA_Accumulate }, 279 { XML_NAMESPACE_PRESENTATION, XML_ADDITIVE, (sal_uInt16)ANA_AdditiveMode }, 280 { XML_NAMESPACE_SMIL, XML_ADDITIVE, (sal_uInt16)ANA_AdditiveMode }, 281 { XML_NAMESPACE_SMIL, XML_KEYSPLINES, (sal_uInt16)ANA_KeySplines }, 282 { XML_NAMESPACE_SVG, XML_PATH, (sal_uInt16)ANA_Path }, 283 { XML_NAMESPACE_ANIMATION, XML_COLOR_INTERPOLATION, (sal_uInt16)ANA_ColorSpace }, 284 { XML_NAMESPACE_ANIMATION, XML_COLOR_INTERPOLATION_DIRECTION, (sal_uInt16)ANA_ColorDirection }, 285 { XML_NAMESPACE_SVG, XML_TYPE, (sal_uInt16)ANA_TransformType }, 286 { XML_NAMESPACE_SMIL, XML_TYPE, (sal_uInt16)ANA_TransitionType }, 287 { XML_NAMESPACE_SMIL, XML_SUBTYPE, (sal_uInt16)ANA_TransitionSubType }, 288 { XML_NAMESPACE_SMIL, XML_MODE, (sal_uInt16)ANA_Mode }, 289 { XML_NAMESPACE_SMIL, XML_DIRECTION, (sal_uInt16)ANA_Direction }, 290 { XML_NAMESPACE_SMIL, XML_FADECOLOR, (sal_uInt16)ANA_FadeColor }, 291 { XML_NAMESPACE_ANIMATION, XML_ITERATE_TYPE, (sal_uInt16)ANA_IterateType }, 292 { XML_NAMESPACE_ANIMATION, XML_ITERATE_INTERVAL, (sal_uInt16)ANA_IterateInterval }, 293 { XML_NAMESPACE_ANIMATION, XML_FORMULA, (sal_uInt16)ANA_Formula }, 294 { XML_NAMESPACE_ANIMATION, XML_ID, (sal_uInt16)ANA_ANIMID }, 295 { XML_NAMESPACE_XML, XML_ID, (sal_uInt16)ANA_XMLID }, 296 { XML_NAMESPACE_PRESENTATION, XML_GROUP_ID, (sal_uInt16)ANA_Group_Id }, 297 { XML_NAMESPACE_ANIMATION, XML_AUDIO_LEVEL, (sal_uInt16)ANA_Volume }, 298 { XML_NAMESPACE_ANIMATION, XML_COMMAND, (sal_uInt16)ANA_Command }, 299 300 XML_TOKEN_MAP_END 301 }; 302 303 mpAnimationNodeAttributeTokenMap = new SvXMLTokenMap( aAnimationNodeAttributeTokenMap ); 304 } 305 306 return *mpAnimationNodeAttributeTokenMap; 307 } 308 309 static bool isDouble( const OUString& rValue ) 310 { 311 sal_Int32 nLength = rValue.getLength(); 312 const sal_Unicode * pStr = rValue.getStr(); 313 while( nLength ) 314 { 315 if( (*pStr >= '0' && *pStr <= '9') || *pStr == '-' || *pStr == '.' || *pStr == '+' || *pStr == 'e' || *pStr == 'E' ) 316 { 317 pStr++; 318 nLength--; 319 } 320 else 321 { 322 return false; 323 } 324 } 325 326 return true; 327 } 328 329 static bool isTime( const OUString& rValue ) 330 { 331 sal_Int32 nLength = rValue.getLength(); 332 const sal_Unicode * pStr; 333 for( pStr = rValue.getStr(); nLength; pStr++, nLength-- ) 334 { 335 if( !( (*pStr >= '0' && *pStr <= '9') || *pStr == '-' || *pStr == '.' || *pStr == '+' || *pStr == 'e' || *pStr == 'E' ) ) 336 break; 337 } 338 339 // return true if this is a double (if someone forgot the 's' we silently ignore it) 340 // or if its a double that ends with a 's' or 'S' 341 return (nLength == 0) || ((*pStr == 's' || *pStr == 'S') && (nLength == 1)); 342 } 343 344 static sal_Int32 count_codes( const OUString& rString, sal_Unicode nCode ) 345 { 346 sal_Int32 nCount = 0; 347 sal_Int32 fromIndex = 0; 348 349 while(true) 350 { 351 fromIndex = rString.indexOf( nCode, fromIndex ); 352 if( fromIndex == -1 ) 353 break; 354 355 fromIndex++; 356 nCount++; 357 } 358 359 return nCount; 360 } 361 362 Any AnimationsImportHelperImpl::convertTarget( const OUString& rValue ) 363 { 364 try 365 { 366 Reference< XInterface > xRef( mrImport.getInterfaceToIdentifierMapper().getReference( rValue ) ); 367 368 Reference< XShape > _xShape( xRef, UNO_QUERY ); 369 if( _xShape.is() ) 370 return makeAny( _xShape ); 371 372 Reference< XTextCursor > xTextCursor( xRef, UNO_QUERY ); 373 if( xTextCursor.is() ) 374 { 375 Reference< XTextRange > xStart( xTextCursor->getStart() ), xRange; 376 Reference< XShape > xShape( xTextCursor->getText(), UNO_QUERY_THROW ); 377 Reference< XTextRangeCompare > xTextRangeCompare( xShape, UNO_QUERY_THROW ); 378 379 Reference< XEnumerationAccess > xParaEnumAccess( xShape, UNO_QUERY_THROW ); 380 Reference< XEnumeration > xEnumeration( xParaEnumAccess->createEnumeration(), UNO_QUERY_THROW ); 381 sal_Int16 nParagraph = 0; 382 383 while( xEnumeration->hasMoreElements() ) 384 { 385 xEnumeration->nextElement() >>= xRange; 386 387 // break if start of selection is prior to end of current paragraph 388 if( xRange.is() && (xTextRangeCompare->compareRegionEnds( xStart, xRange ) >= 0 ) ) 389 { 390 return makeAny( ParagraphTarget( xShape, nParagraph ) ); 391 } 392 393 nParagraph++; 394 } 395 } 396 } 397 catch( RuntimeException& ) 398 { 399 DBG_ERROR( "xmloff::AnimationsImportImpl::convertTarget(), RuntimeException catched!" ); 400 } 401 402 Any aAny; 403 return aAny; 404 } 405 406 Any AnimationsImportHelperImpl::convertValue( XMLTokenEnum eAttributeName, const OUString& rValue ) 407 { 408 sal_Int32 nCommaPos = -1, nPos; 409 sal_Int32 nOpenBrakets = 0; 410 for( nPos = 0; (nPos < rValue.getLength()) && (nCommaPos == -1); nPos++ ) 411 { 412 switch( rValue[nPos] ) 413 { 414 case ',': 415 if( nOpenBrakets == 0 ) 416 nCommaPos = nPos; 417 break; 418 case '(': 419 case '[': 420 case '{': 421 nOpenBrakets++; 422 break; 423 case ')': 424 case ']': 425 case '}': 426 nOpenBrakets--; 427 break; 428 } 429 } 430 431 if( nCommaPos >= 0 ) 432 { 433 ValuePair aPair; 434 aPair.First = convertValue( eAttributeName, rValue.copy( 0, nCommaPos ) ); 435 aPair.Second = convertValue( eAttributeName, rValue.copy( nCommaPos+1, rValue.getLength() - nCommaPos - 1 ) ); 436 return makeAny( aPair ); 437 } 438 else 439 { 440 Any aAny; 441 sal_Int32 nType = XML_TYPE_STRING; 442 443 if( rValue.getLength() ) switch( eAttributeName ) 444 { 445 case XML_X: 446 case XML_Y: 447 case XML_WIDTH: 448 case XML_HEIGHT: 449 case XML_TRANSLATE: 450 { 451 return makeAny( rValue ); 452 } 453 454 case XML_SCALE: 455 case XML_SKEWY: 456 case XML_SKEWX: 457 case XML_OPACITY: 458 case XML_ROTATE: nType = XML_TYPE_DOUBLE; break; 459 case XML_TEXT_ROTATION_ANGLE:nType = XML_TYPE_TEXT_ROTATION_ANGLE; break; 460 case XML_FILL_COLOR: 461 case XML_STROKE_COLOR: 462 case XML_DIM: 463 case XML_COLOR: nType = XML_TYPE_COLOR; break; 464 case XML_FILL: nType = XML_SD_TYPE_FILLSTYLE; break; 465 case XML_STROKE: nType = XML_SD_TYPE_STROKE; break; 466 case XML_FONT_WEIGHT: nType = XML_TYPE_TEXT_WEIGHT; break; 467 case XML_FONT_STYLE: nType = XML_TYPE_TEXT_POSTURE; break; 468 case XML_TEXT_UNDERLINE: nType = XML_TYPE_TEXT_UNDERLINE_STYLE; break; 469 case XML_FONT_SIZE: nType = XML_TYPE_DOUBLE_PERCENT; break; 470 case XML_VISIBILITY: nType = XML_SD_TYPE_PRESPAGE_VISIBILITY; break; 471 472 default: 473 if( rValue.getLength() ) 474 aAny <<= rValue; 475 return aAny; 476 } 477 478 const XMLPropertyHandler* pHandler = mrImport.GetShapeImport()->GetSdPropHdlFactory()->GetPropertyHandler( nType ); 479 if( pHandler ) 480 pHandler->importXML( rValue, aAny, mrImport.GetMM100UnitConverter() ); 481 482 return aAny; 483 484 /* 485 if( rValue.getLength() == 0 ) 486 { 487 Any aAny; 488 return aAny; 489 } 490 else if( rValue.indexOf( '#' ) == 0 ) 491 { 492 // color 493 Color aColor; 494 SvXMLUnitConverter::convertColor( aColor, rValue ); 495 496 return makeAny( static_cast< sal_Int32 >( aColor.GetRGBColor() ) ); 497 } 498 else if( rValue.indexOf( '$' ) != -1 ) 499 { 500 // formula 501 return makeAny( rValue ); 502 } 503 else 504 { 505 if( isDouble( rValue ) ) 506 { 507 return makeAny( rValue.toDouble() ); 508 } 509 else 510 { 511 return makeAny( rValue ); 512 } 513 } 514 */ 515 } 516 } 517 518 Sequence< Any > AnimationsImportHelperImpl::convertValueSequence( XMLTokenEnum eAttributeName, const OUString& rValue ) 519 { 520 Sequence< Any > aValues; 521 522 // do we have any value at all? 523 if( rValue.getLength() ) 524 { 525 sal_Int32 nElements = count_codes( rValue, (sal_Unicode)';') + 1; // a non empty string has at least one value 526 527 // prepare the sequence 528 aValues.realloc( nElements ); 529 530 // fill the sequence 531 Any* pValues = aValues.getArray(); 532 sal_Int32 nIndex, nElement; 533 for( nIndex = 0, nElement = 0; nElements && (nIndex >= 0); nElements-- ) 534 { 535 *pValues++ = convertValue( eAttributeName, rValue.getToken( 0, ';', nIndex ) ); 536 } 537 } 538 539 return aValues; 540 } 541 542 Any AnimationsImportHelperImpl::convertTiming( const OUString& rValue ) 543 { 544 Any aAny; 545 546 // do we have any value at all? 547 if( rValue.getLength() ) 548 { 549 // count the values 550 sal_Int32 nElements = count_codes( rValue, (sal_Unicode)';' ) + 1; // a non empty string has at least one value 551 552 if( nElements == 1 ) 553 { 554 if( IsXMLToken( rValue, XML_MEDIA ) ) 555 { 556 aAny <<= Timing_MEDIA; 557 } 558 else if( IsXMLToken( rValue, XML_INDEFINITE ) ) 559 { 560 aAny <<= Timing_INDEFINITE; 561 } 562 else if( isTime( rValue ) ) 563 { 564 aAny <<= rValue.toDouble(); 565 } 566 else 567 { 568 Event aEvent; 569 aEvent.Repeat = 0; 570 aEvent.Trigger = 0; 571 572 OUString aEventTrigger; 573 574 sal_Int32 nPos = rValue.indexOf( (sal_Unicode)'+' ); 575 if( nPos == -1 ) 576 { 577 aEventTrigger = rValue; 578 } 579 else 580 { 581 aEventTrigger = rValue.copy( 0, nPos ); 582 583 // convert offset 584 aEvent.Offset <<= convertTiming( rValue.copy( nPos + 1 ) ); 585 } 586 587 nPos = aEventTrigger.indexOf( (sal_Unicode)'.' ); 588 if( nPos != -1 ) 589 { 590 aEvent.Source <<= mrImport.getInterfaceToIdentifierMapper().getReference( aEventTrigger.copy( 0, nPos ) ); 591 aEventTrigger = aEventTrigger.copy( nPos + 1 ); 592 } 593 594 sal_uInt16 nEnum; 595 if( SvXMLUnitConverter::convertEnum( nEnum, aEventTrigger, getAnimationsEnumMap(Animations_EnumMap_EventTrigger) ) ) 596 { 597 aEvent.Trigger = (sal_Int16)nEnum; 598 } 599 else 600 { 601 DBG_ERROR("AnimationsImportHelperImpl::convertTiming(), unknown event trigger!"); 602 } 603 604 aAny <<= aEvent; 605 } 606 } 607 else 608 { 609 // fill the sequence 610 Sequence< Any > aValues( nElements ); 611 Any* pValues = aValues.getArray(); 612 sal_Int32 nIndex = 0; 613 while( (nElements--) && (nIndex >= 0) ) 614 *pValues++ = convertTiming( rValue.getToken( 0, ';', nIndex ) ); 615 616 aAny <<= aValues; 617 } 618 } 619 return aAny; 620 } 621 622 Sequence< double > AnimationsImportHelperImpl::convertKeyTimes( const OUString& rValue ) 623 { 624 sal_Int32 nElements = 0; 625 626 if( rValue.getLength() ) 627 nElements = count_codes( rValue, (sal_Unicode)';' ) + 1; // a non empty string has at least one value 628 629 Sequence< double > aKeyTimes( nElements ); 630 631 if( nElements ) 632 { 633 double* pValues = aKeyTimes.getArray(); 634 sal_Int32 nIndex = 0; 635 while( (nElements--) && (nIndex >= 0) ) 636 *pValues++ = rValue.getToken( 0, ';', nIndex ).toDouble(); 637 } 638 639 return aKeyTimes; 640 } 641 642 Sequence< TimeFilterPair > AnimationsImportHelperImpl::convertTimeFilter( const OUString& rValue ) 643 { 644 sal_Int32 nElements = 0; 645 646 if( rValue.getLength() ) 647 nElements = count_codes( rValue, (sal_Unicode)';' ) + 1; // a non empty string has at least one value 648 649 Sequence< TimeFilterPair > aTimeFilter( nElements ); 650 651 if( nElements ) 652 { 653 TimeFilterPair* pValues = aTimeFilter.getArray(); 654 sal_Int32 nIndex = 0; 655 while( (nElements--) && (nIndex >= 0) ) 656 { 657 const OUString aToken( rValue.getToken( 0, ';', nIndex ) ); 658 659 sal_Int32 nPos = aToken.indexOf( ',' ); 660 if( nPos >= 0 ) 661 { 662 pValues->Time = aToken.copy( 0, nPos ).toDouble(); 663 pValues->Progress = aToken.copy( nPos+1, aToken.getLength() - nPos - 1 ).toDouble(); 664 } 665 pValues++; 666 } 667 } 668 669 return aTimeFilter; 670 } 671 672 Any AnimationsImportHelperImpl::convertPath( const OUString& rValue ) 673 { 674 return makeAny( rValue ); 675 } 676 677 /////////////////////////////////////////////////////////////////////// 678 679 TYPEINIT1( AnimationNodeContext, SvXMLImportContext ); 680 681 AnimationNodeContext::AnimationNodeContext( 682 const Reference< XAnimationNode >& xParentNode, 683 SvXMLImport& rImport, sal_uInt16 nPrfx, const rtl::OUString& rLocalName, 684 const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList, 685 AnimationsImportHelperImpl* pHelper /* = NULL */ ) 686 : SvXMLImportContext(rImport, nPrfx, rLocalName), 687 mpHelper( pHelper ), 688 mbRootContext( pHelper == NULL ) 689 { 690 try 691 { 692 if( mbRootContext ) 693 { 694 mpHelper = new AnimationsImportHelperImpl( rImport ); 695 mxNode = xParentNode; 696 } 697 else 698 { 699 Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() ); 700 701 sal_Int16 nPresetClass = EffectPresetClass::CUSTOM; 702 703 const sal_Char* pServiceName = 0; 704 705 sal_Int16 nNodeType = (sal_Int16)mpHelper->getAnimationNodeTokenMap().Get( nPrfx, rLocalName ); 706 switch( nNodeType ) 707 { 708 case AnimationNodeType::SEQ: pServiceName = "com.sun.star.animations.SequenceTimeContainer"; break; 709 case AnimationNodeType::ITERATE: pServiceName = "com.sun.star.animations.IterateContainer"; break; 710 case AnimationNodeType::ANIMATE: pServiceName = "com.sun.star.animations.Animate"; break; 711 case AnimationNodeType::SET: pServiceName = "com.sun.star.animations.AnimateSet"; break; 712 case AnimationNodeType::ANIMATEMOTION: pServiceName = "com.sun.star.animations.AnimateMotion"; break; 713 case AnimationNodeType::ANIMATECOLOR: pServiceName = "com.sun.star.animations.AnimateColor"; break; 714 case AnimationNodeType::ANIMATETRANSFORM: pServiceName = "com.sun.star.animations.AnimateTransform"; break; 715 case AnimationNodeType::TRANSITIONFILTER: pServiceName = "com.sun.star.animations.TransitionFilter"; break; 716 case AnimationNodeType::AUDIO: pServiceName = "com.sun.star.animations.Audio"; break; 717 case AnimationNodeType::COMMAND: pServiceName = "com.sun.star.animations.Command"; break; 718 case AnimationNodeType::PAR: 719 { 720 const sal_Int16 nCount = xAttrList.is() ? xAttrList->getLength() : 0; 721 sal_Int16 nAttribute; 722 for( nAttribute = 0; nAttribute < nCount; nAttribute++ ) 723 { 724 OUString aLocalName; 725 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( nAttribute ), &aLocalName ); 726 if( (nPrefix == XML_NAMESPACE_PRESENTATION) && IsXMLToken( aLocalName, XML_PRESET_ID ) ) 727 { 728 const OUString& rValue = xAttrList->getValueByIndex( nAttribute ); 729 if( rValue.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ooo-entrance-random" ) ) ) 730 { 731 nPresetClass = EffectPresetClass::ENTRANCE; 732 } 733 else if( rValue.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ooo-exit-random" ) ) ) 734 { 735 nPresetClass = EffectPresetClass::EXIT; 736 } 737 738 if( nPresetClass != EffectPresetClass::CUSTOM ) 739 { 740 pServiceName = "com.sun.star.comp.sd.RandomAnimationNode"; 741 break; 742 } 743 } 744 } 745 if( !pServiceName ) 746 pServiceName = "com.sun.star.animations.ParallelTimeContainer"; 747 } 748 break; 749 default: 750 pServiceName = 0; 751 } 752 753 if( pServiceName && xFactory.is() ) 754 { 755 mxNode = Reference< XAnimationNode >( xFactory->createInstance( 756 OUString::createFromAscii(pServiceName) ), UNO_QUERY_THROW ); 757 758 if( nPresetClass != EffectPresetClass::CUSTOM ) 759 { 760 Reference< XInitialization > xInit( mxNode, UNO_QUERY_THROW ); 761 const Any aAny( makeAny( nPresetClass ) ); 762 Sequence< Any > aArgs( &aAny, 1 ) ; 763 xInit->initialize( aArgs ); 764 } 765 766 init_node( xAttrList ); 767 768 Reference< XTimeContainer > xParentContainer( xParentNode, UNO_QUERY_THROW ); 769 xParentContainer->appendChild( mxNode ); 770 } 771 } 772 } 773 catch( RuntimeException& ) 774 { 775 DBG_ERROR( "xmloff::AnimationsImportImpl::AnimationsImportImpl(), RuntimeException catched!" ); 776 } 777 } 778 779 AnimationNodeContext::~AnimationNodeContext() 780 { 781 if( mbRootContext ) 782 delete mpHelper; 783 } 784 785 void AnimationNodeContext::StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& ) 786 { 787 // code of StartElement is moved to init_node that is now called 788 // in c'tor before appending this node to its parent. 789 // This is needed for random nodes that need the correct target 790 // set when child nodes are appended. 791 } 792 793 void AnimationNodeContext::init_node( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList ) 794 { 795 if( mxNode.is() ) try 796 { 797 const sal_Int16 nNodeType = mxNode->getType(); 798 799 // query for optional interfaces that are often used later 800 Reference< XAnimate > xAnimate( mxNode, UNO_QUERY ); 801 Reference< XCommand > xCommand( mxNode, UNO_QUERY ); 802 Reference< XTransitionFilter > xTransitionFilter( mxNode, UNO_QUERY ); 803 Reference< XIterateContainer > xIter( mxNode, UNO_QUERY ); 804 805 std::list< NamedValue > aUserData; 806 XMLTokenEnum meAttributeName = XML_TOKEN_INVALID; 807 OUString aFrom, aBy, aTo, aValues; 808 bool bHaveXmlId( false ); 809 OUString sXmlId; 810 811 const sal_Int16 nCount = xAttrList.is() ? xAttrList->getLength() : 0; 812 sal_uInt16 nEnum; 813 sal_Int16 nAttribute; 814 for( nAttribute = 0; nAttribute < nCount; nAttribute++ ) 815 { 816 const OUString& rAttrName = xAttrList->getNameByIndex( nAttribute ); 817 const OUString& rValue = xAttrList->getValueByIndex( nAttribute ); 818 819 OUString aLocalName; 820 sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName ); 821 switch( mpHelper->getAnimationNodeAttributeTokenMap().Get( nPrefix, aLocalName ) ) 822 { 823 case ANA_Begin: 824 { 825 mxNode->setBegin( mpHelper->convertTiming( rValue ) ); 826 } 827 break; 828 case ANA_Dur: 829 { 830 mxNode->setDuration( mpHelper->convertTiming( rValue ) ); 831 } 832 break; 833 case ANA_End: 834 { 835 mxNode->setEnd( mpHelper->convertTiming( rValue ) ); 836 } 837 break; 838 case ANA_Fill: 839 { 840 if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_Fill) ) ) 841 mxNode->setFill( (sal_Int16)nEnum ); 842 } 843 break; 844 case ANA_FillDefault: 845 { 846 if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_FillDefault) ) ) 847 mxNode->setFillDefault( (sal_Int16)nEnum ); 848 } 849 break; 850 case ANA_Restart: 851 { 852 if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_Restart) ) ) 853 mxNode->setRestart( (sal_Int16)nEnum ); 854 } 855 break; 856 case ANA_RestartDefault: 857 { 858 if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_RestartDefault) ) ) 859 mxNode->setRestartDefault( (sal_Int16)nEnum ); 860 } 861 break; 862 case ANA_Accelerate: 863 { 864 if( isDouble( rValue ) ) 865 mxNode->setAcceleration( rValue.toDouble() ); 866 } 867 break; 868 case ANA_Decelerate: 869 { 870 if( isDouble( rValue ) ) 871 mxNode->setDecelerate( rValue.toDouble() ); 872 } 873 break; 874 case ANA_AutoReverse: 875 { 876 sal_Bool bTemp; 877 if( SvXMLUnitConverter::convertBool( bTemp, rValue ) ) 878 mxNode->setAutoReverse( bTemp ); 879 } 880 break; 881 case ANA_RepeatCount: 882 { 883 mxNode->setRepeatCount( mpHelper->convertTiming( rValue ) ); 884 } 885 break; 886 case ANA_RepeatDur: 887 { 888 mxNode->setRepeatDuration( mpHelper->convertTiming( rValue ) ); 889 } 890 break; 891 case ANA_EndSync: 892 { 893 if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_Endsync) ) ) 894 mxNode->setEndSync( makeAny( (sal_Int16)nEnum ) ); 895 } 896 break; 897 case ANA_Node_Type: 898 { 899 if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_EffectNodeType) ) ) 900 aUserData.push_back( NamedValue( GetXMLToken( XML_NODE_TYPE ), makeAny( (sal_Int16)nEnum ) ) ); 901 } 902 break; 903 case ANA_Preset_ID: 904 { 905 aUserData.push_back( NamedValue( GetXMLToken( XML_PRESET_ID ), makeAny( rValue ) ) ); 906 } 907 break; 908 case ANA_Preset_Sub_Type: 909 { 910 aUserData.push_back( NamedValue( GetXMLToken( XML_PRESET_SUB_TYPE ), makeAny( rValue ) ) ); 911 } 912 break; 913 case ANA_Preset_Class: 914 { 915 if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_EffectPresetClass) ) ) 916 aUserData.push_back( NamedValue( GetXMLToken( XML_PRESET_CLASS ), makeAny( (sal_Int16)nEnum ) ) ); 917 } 918 break; 919 case ANA_After_Effect: 920 { 921 sal_Bool bTemp; 922 if( SvXMLUnitConverter::convertBool( bTemp, rValue ) ) 923 aUserData.push_back( NamedValue( GetXMLToken( XML_AFTER_EFFECT ), makeAny( bTemp ) ) ); 924 } 925 break; 926 case ANA_XLink: 927 { 928 if( nNodeType == AnimationNodeType::AUDIO ) 929 { 930 Reference< XAudio > xAudio( mxNode, UNO_QUERY_THROW ); 931 xAudio->setSource( makeAny( GetImport().GetAbsoluteReference( rValue ) ) ); 932 break; 933 } 934 935 } 936 // fall through intented! 937 case ANA_Target: 938 { 939 { 940 Any aTarget( mpHelper->convertTarget( rValue ) ); 941 942 if( xAnimate.is() ) 943 { 944 xAnimate->setTarget( aTarget ); 945 } 946 else if( xIter.is() ) 947 { 948 xIter->setTarget( aTarget ); 949 } 950 else if( xCommand.is() ) 951 { 952 xCommand->setTarget( aTarget ); 953 } 954 } 955 } 956 break; 957 958 case ANA_Volume: 959 { 960 if( nNodeType == AnimationNodeType::AUDIO ) 961 { 962 if( isDouble( rValue ) ) 963 { 964 Reference< XAudio > xAudio( mxNode, UNO_QUERY_THROW ); 965 xAudio->setVolume( rValue.toDouble() ); 966 } 967 } 968 } 969 break; 970 971 case ANA_MasterElement: 972 { 973 Reference< XAnimationNode > xMaster( GetImport().getInterfaceToIdentifierMapper().getReference( rValue ), UNO_QUERY ); 974 aUserData.push_back( NamedValue( GetXMLToken( XML_MASTER_ELEMENT ), makeAny( xMaster ) ) ); 975 } 976 break; 977 978 case ANA_SubItem: 979 { 980 if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_SubItem) ) ) 981 { 982 if( xAnimate.is() ) 983 { 984 xAnimate->setSubItem( (sal_Int16)nEnum ); 985 } 986 else if( xIter.is() ) 987 { 988 xIter->setSubItem( (sal_Int16)nEnum ); 989 } 990 } 991 } 992 break; 993 994 case ANA_AttributeName: 995 { 996 if( xAnimate.is() ) 997 { 998 OUString aName( rValue ); 999 1000 ImplAttributeNameConversion* p = getAnimationAttributeNamesConversionList(); 1001 while( p->mpAPIName ) 1002 { 1003 if( IsXMLToken( aName, p->meXMLToken ) ) 1004 { 1005 aName = OUString::createFromAscii( p->mpAPIName ); 1006 meAttributeName = p->meXMLToken; 1007 break; 1008 } 1009 1010 p++; 1011 } 1012 1013 xAnimate->setAttributeName( aName ); 1014 } 1015 } 1016 break; 1017 1018 case ANA_Values: 1019 { 1020 aValues = rValue; 1021 } 1022 break; 1023 1024 case ANA_From: 1025 { 1026 aFrom = rValue; 1027 } 1028 break; 1029 1030 case ANA_By: 1031 { 1032 aBy = rValue; 1033 } 1034 break; 1035 1036 case ANA_To: 1037 { 1038 aTo = rValue; 1039 } 1040 break; 1041 1042 case ANA_KeyTimes: 1043 { 1044 if( xAnimate.is() ) 1045 xAnimate->setKeyTimes( mpHelper->convertKeyTimes( rValue ) ); 1046 } 1047 break; 1048 1049 case ANA_Formula: 1050 { 1051 if( xAnimate.is() ) 1052 xAnimate->setFormula( rValue ); 1053 } 1054 break; 1055 1056 case ANA_ANIMID: 1057 { 1058 if (!bHaveXmlId) { sXmlId = rValue; } 1059 } 1060 break; 1061 case ANA_XMLID: 1062 { 1063 sXmlId = rValue; 1064 bHaveXmlId = true; 1065 } 1066 break; 1067 1068 case ANA_CalcMode: 1069 { 1070 if( xAnimate.is() ) 1071 { 1072 if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_CalcMode) ) ) 1073 xAnimate->setCalcMode( (sal_Int16)nEnum ); 1074 } 1075 } 1076 break; 1077 1078 case ANA_Accumulate: 1079 { 1080 if( xAnimate.is() ) 1081 xAnimate->setAccumulate( IsXMLToken( rValue, XML_SUM ) ); 1082 } 1083 break; 1084 1085 case ANA_AdditiveMode: 1086 { 1087 if( xAnimate.is() ) 1088 { 1089 if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_AdditiveMode) ) ) 1090 xAnimate->setAdditive( (sal_Int16)nEnum ); 1091 } 1092 } 1093 break; 1094 1095 case ANA_KeySplines: 1096 { 1097 if( xAnimate.is() ) 1098 xAnimate->setTimeFilter( mpHelper->convertTimeFilter( rValue ) ); 1099 } 1100 break; 1101 1102 case ANA_Path: 1103 { 1104 Reference< XAnimateMotion > xAnimateMotion( mxNode, UNO_QUERY ); 1105 if( xAnimateMotion.is() ) 1106 xAnimateMotion->setPath( mpHelper->convertPath( rValue ) ); 1107 } 1108 break; 1109 1110 case ANA_ColorSpace: 1111 { 1112 Reference< XAnimateColor > xAnimateColor( mxNode, UNO_QUERY ); 1113 if( xAnimateColor.is() ) 1114 xAnimateColor->setColorInterpolation( IsXMLToken( rValue, XML_HSL ) ? AnimationColorSpace::HSL : AnimationColorSpace::RGB ); 1115 } 1116 break; 1117 1118 case ANA_ColorDirection: 1119 { 1120 Reference< XAnimateColor > xAnimateColor( mxNode, UNO_QUERY ); 1121 if( xAnimateColor.is() ) 1122 xAnimateColor->setDirection( IsXMLToken( rValue, XML_CLOCKWISE ) ); 1123 } 1124 break; 1125 1126 case ANA_TransformType: 1127 { 1128 Reference< XAnimateTransform > xTransform( mxNode, UNO_QUERY ); 1129 if( xTransform.is() ) 1130 { 1131 if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_TransformType) ) ) 1132 { 1133 xTransform->setTransformType( (sal_Int16)nEnum ); 1134 switch( nEnum ) 1135 { 1136 case AnimationTransformType::SCALE: meAttributeName = XML_SCALE; break; 1137 case AnimationTransformType::ROTATE: meAttributeName = XML_ROTATE; break; 1138 case AnimationTransformType::SKEWX: meAttributeName = XML_SKEWX; break; 1139 case AnimationTransformType::SKEWY: meAttributeName = XML_SKEWY; break; 1140 //case AnimationTransformType::TRANSLATE: 1141 default: 1142 meAttributeName = XML_TRANSLATE; break; 1143 } 1144 } 1145 } 1146 } 1147 break; 1148 1149 case ANA_TransitionType: 1150 { 1151 if( xTransitionFilter.is() ) 1152 { 1153 if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_TransitionType) ) ) 1154 xTransitionFilter->setTransition( (sal_Int16)nEnum ); 1155 } 1156 } 1157 break; 1158 1159 case ANA_TransitionSubType: 1160 { 1161 if( xTransitionFilter.is() ) 1162 { 1163 if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_TransitionSubType) ) ) 1164 xTransitionFilter->setSubtype( (sal_Int16)nEnum ); 1165 } 1166 } 1167 break; 1168 1169 case ANA_Mode: 1170 { 1171 if( xTransitionFilter.is() ) 1172 xTransitionFilter->setMode( IsXMLToken( rValue, XML_IN ) ); 1173 } 1174 break; 1175 1176 case ANA_Direction: 1177 { 1178 if( xTransitionFilter.is() ) 1179 xTransitionFilter->setDirection( IsXMLToken( rValue, XML_FORWARD ) ); 1180 } 1181 break; 1182 1183 case ANA_FadeColor: 1184 { 1185 if( xTransitionFilter.is() ) 1186 { 1187 Color aColor; 1188 SvXMLUnitConverter::convertColor( aColor, rValue ); 1189 xTransitionFilter->setFadeColor( static_cast< sal_Int32 >( aColor.GetRGBColor() ) ); 1190 } 1191 } 1192 break; 1193 1194 case ANA_IterateType: 1195 { 1196 if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_IterateType) ) ) 1197 { 1198 if( xIter.is() ) 1199 xIter->setIterateType( (sal_Int16)nEnum ); 1200 } 1201 } 1202 break; 1203 1204 case ANA_IterateInterval: 1205 { 1206 if( xIter.is() ) 1207 { 1208 double fInterval = 0.0; 1209 if( rValue.matchAsciiL(RTL_CONSTASCII_STRINGPARAM("P")) ) 1210 { 1211 ::Time aTime; 1212 sal_Int32 nSecondsFraction = 0; 1213 if( SvXMLUnitConverter::convertTimeDuration( rValue, aTime, &nSecondsFraction ) ) 1214 { 1215 fInterval = ((((aTime.GetHour() * 60) + aTime.GetMin()) * 60) + aTime.GetSec()) + (nSecondsFraction / 1000.0); 1216 } 1217 } 1218 else 1219 { 1220 fInterval = rValue.toDouble(); 1221 } 1222 1223 xIter->setIterateInterval( fInterval ); 1224 } 1225 } 1226 break; 1227 1228 case ANA_Group_Id: 1229 { 1230 aUserData.push_back( NamedValue( aLocalName, makeAny( rValue.toInt32() ) ) ); 1231 } 1232 break; 1233 1234 case ANA_Command: 1235 { 1236 if( xCommand.is() && nNodeType == AnimationNodeType::COMMAND ) 1237 { 1238 if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_Command) ) ) 1239 { 1240 xCommand->setCommand( (sal_Int16)nEnum ); 1241 } 1242 } 1243 } 1244 break; 1245 1246 default: 1247 // push all unknown attributes within the presentation namespace as user data 1248 if( nPrefix == XML_NAMESPACE_PRESENTATION ) 1249 { 1250 aUserData.push_back( NamedValue( aLocalName, makeAny( rValue ) ) ); 1251 } 1252 } 1253 } 1254 1255 if (sXmlId.getLength()) 1256 { 1257 Reference< XInterface > const xRef( mxNode, UNO_QUERY ); 1258 GetImport().getInterfaceToIdentifierMapper().registerReference( 1259 sXmlId, xRef ); 1260 } 1261 1262 sal_Int32 nUserDataCount = aUserData.size(); 1263 if( nUserDataCount ) 1264 { 1265 Sequence< NamedValue > aUnoUserData( nUserDataCount ); 1266 NamedValue* pData = aUnoUserData.getArray(); 1267 std::list< NamedValue >::iterator aIter( aUserData.begin() ); 1268 const std::list< NamedValue >::iterator aEnd( aUserData.end() ); 1269 while( aIter != aEnd ) 1270 *pData++ = (*aIter++); 1271 1272 mxNode->setUserData( aUnoUserData ); 1273 } 1274 1275 // convert values 1276 if( xAnimate.is() ) 1277 { 1278 if( aFrom.getLength() ) 1279 xAnimate->setFrom( mpHelper->convertValue( meAttributeName, aFrom ) ); 1280 1281 if( aBy.getLength() ) 1282 xAnimate->setBy( mpHelper->convertValue( meAttributeName, aBy ) ); 1283 1284 if( aTo.getLength() ) 1285 xAnimate->setTo( mpHelper->convertValue( meAttributeName, aTo ) ); 1286 1287 if( aValues.getLength() ) 1288 xAnimate->setValues( mpHelper->convertValueSequence( meAttributeName, aValues ) ); 1289 } 1290 } 1291 catch( RuntimeException& ) 1292 { 1293 DBG_ERROR( "xmloff::AnimationNodeContext::StartElement(), RuntimeException catched!" ); 1294 } 1295 } 1296 1297 SvXMLImportContext * AnimationNodeContext::CreateChildContext( sal_uInt16 nPrefix, const ::rtl::OUString& rLocalName, 1298 const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList ) 1299 { 1300 if( mxNode.is()) 1301 return new AnimationNodeContext( mxNode, GetImport(), nPrefix, rLocalName, xAttrList, mpHelper ); 1302 else 1303 return new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); 1304 } 1305 1306 // -------------------------------------------------------------------- 1307 1308 class AnimationsImport: public SvXMLImport, public XAnimationNodeSupplier 1309 { 1310 public: 1311 AnimationsImport( const Reference< XMultiServiceFactory > & rSMgr ); 1312 ~AnimationsImport() throw (); 1313 1314 SvXMLImportContext* CreateContext(sal_uInt16 nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& xAttrList); 1315 1316 // XInterface 1317 virtual Any SAL_CALL queryInterface( const Type& aType ) throw (RuntimeException); 1318 virtual void SAL_CALL acquire() throw (); 1319 virtual void SAL_CALL release() throw (); 1320 1321 // XAnimationNodeSupplier 1322 Reference< XAnimationNode > SAL_CALL getAnimationNode() throw (RuntimeException); 1323 1324 // XServiceInfo 1325 virtual OUString SAL_CALL getImplementationName() throw(RuntimeException); 1326 virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException); 1327 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(RuntimeException); 1328 1329 private: 1330 Reference< XAnimationNode > mxRootNode; 1331 }; 1332 1333 AnimationsImport::AnimationsImport( const Reference< XMultiServiceFactory > & rSMgr ) 1334 : SvXMLImport( rSMgr, true ) 1335 { 1336 // add namespaces 1337 GetNamespaceMap().Add( 1338 GetXMLToken(XML_NP_PRESENTATION), 1339 GetXMLToken(XML_N_PRESENTATION), 1340 XML_NAMESPACE_PRESENTATION); 1341 1342 GetNamespaceMap().Add( 1343 GetXMLToken(XML_NP_SMIL), 1344 GetXMLToken(XML_N_SMIL), 1345 XML_NAMESPACE_SMIL); 1346 1347 GetNamespaceMap().Add( 1348 GetXMLToken(XML_NP_ANIMATION), 1349 GetXMLToken(XML_N_ANIMATION), 1350 XML_NAMESPACE_ANIMATION); 1351 1352 mxRootNode = Reference< XAnimationNode >::query(rSMgr->createInstance( 1353 OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.animations.SequenceTimeContainer")))); 1354 } 1355 1356 AnimationsImport::~AnimationsImport() throw () 1357 { 1358 } 1359 1360 // XInterface 1361 Any SAL_CALL AnimationsImport::queryInterface( const Type& aType ) throw (RuntimeException) 1362 { 1363 if ( aType == ::getCppuType((Reference<XAnimationNodeSupplier> *)0) ) 1364 { 1365 return makeAny( Reference<XAnimationNodeSupplier>( this ) ); 1366 } 1367 else 1368 { 1369 return SvXMLImport::queryInterface( aType ); 1370 } 1371 } 1372 1373 void SAL_CALL AnimationsImport::acquire() throw () 1374 { 1375 SvXMLImport::acquire(); 1376 } 1377 1378 void SAL_CALL AnimationsImport::release() throw () 1379 { 1380 SvXMLImport::release(); 1381 } 1382 1383 SvXMLImportContext *AnimationsImport::CreateContext(sal_uInt16 nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& xAttrList) 1384 { 1385 SvXMLImportContext* pContext = 0; 1386 1387 if( (XML_NAMESPACE_ANIMATION == nPrefix) && IsXMLToken( rLocalName, XML_SEQ ) ) 1388 { 1389 pContext = new AnimationNodeContext( mxRootNode, *this, nPrefix, rLocalName, xAttrList ); 1390 } 1391 else 1392 { 1393 pContext = SvXMLImport::CreateContext(nPrefix, rLocalName, xAttrList); 1394 } 1395 1396 return pContext; 1397 } 1398 1399 // XAnimationNodeSupplier 1400 Reference< XAnimationNode > SAL_CALL AnimationsImport::getAnimationNode() throw (RuntimeException) 1401 { 1402 return mxRootNode; 1403 } 1404 1405 void AnimationNodeContext::postProcessRootNode( SvXMLImport& /*rImport*/, const Reference< XAnimationNode >& xRootNode, Reference< XPropertySet >& xPageProps ) 1406 { 1407 if( xRootNode.is() && xPageProps.is() ) try 1408 { 1409 Reference< XEnumerationAccess > xEnumerationAccess( xRootNode, UNO_QUERY_THROW ); 1410 Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW ); 1411 if( xEnumeration->hasMoreElements() ) 1412 { 1413 Reference< XAnimationNode > xNode( xEnumeration->nextElement(), UNO_QUERY_THROW ); 1414 if( xNode->getType() == AnimationNodeType::PAR ) 1415 { 1416 Event aEvent; 1417 if( (xNode->getBegin() >>= aEvent) && (aEvent.Trigger == EventTrigger::BEGIN_EVENT) ) 1418 { 1419 // found transition node 1420 Reference< XEnumerationAccess > xChildEnumerationAccess( xNode, UNO_QUERY_THROW ); 1421 Reference< XEnumeration > xChildEnumeration( xChildEnumerationAccess->createEnumeration(), UNO_QUERY_THROW ); 1422 while( xChildEnumeration->hasMoreElements() ) 1423 { 1424 Reference< XAnimationNode > xChildNode( xChildEnumeration->nextElement(), UNO_QUERY_THROW ); 1425 switch( xChildNode->getType() ) 1426 { 1427 case AnimationNodeType::TRANSITIONFILTER: 1428 { 1429 Reference< XTransitionFilter > xTransFilter( xChildNode, UNO_QUERY_THROW ); 1430 1431 1432 xPageProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "TransitionType" ) ), Any( xTransFilter->getTransition() ) ); 1433 xPageProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "TransitionSubtype" ) ), Any( xTransFilter->getSubtype() ) ); 1434 xPageProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "TransitionDirection" ) ), Any( xTransFilter->getDirection() ) ); 1435 xPageProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "TransitionFadeColor" ) ), Any( xTransFilter->getFadeColor() ) ); 1436 1437 double fDuration; 1438 if( xTransFilter->getDuration() >>= fDuration ) 1439 xPageProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "TransitionDuration" ) ), Any( fDuration ) ); 1440 1441 } 1442 break; 1443 1444 case AnimationNodeType::COMMAND: 1445 { 1446 Reference< XCommand > xCommand( xChildNode, UNO_QUERY_THROW ); 1447 if( xCommand->getCommand() == EffectCommands::STOPAUDIO ) 1448 { 1449 xPageProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Sound" ) ), Any(sal_True) ); 1450 } 1451 } 1452 break; 1453 1454 case AnimationNodeType::AUDIO: 1455 { 1456 Reference< XAudio > xAudio( xChildNode, UNO_QUERY_THROW ); 1457 OUString sSoundURL; 1458 if( (xAudio->getSource() >>= sSoundURL) && (sSoundURL.getLength() != 0) ) 1459 { 1460 xPageProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Sound" ) ), Any(sSoundURL) ); 1461 1462 Timing eTiming; 1463 if( (xAudio->getRepeatCount() >>= eTiming) && (eTiming == Timing_INDEFINITE) ) 1464 xPageProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "LoopSound" ) ), Any( sal_True ) ); 1465 } 1466 } 1467 break; 1468 1469 } 1470 } 1471 1472 Reference< XTimeContainer > xRootContainer( xRootNode, UNO_QUERY_THROW ); 1473 xRootContainer->removeChild( xNode ); 1474 } 1475 } 1476 } 1477 } 1478 catch( Exception& ) 1479 { 1480 DBG_ERROR("xmloff::AnimationsImport::postProcessRootNode(), exception caught!"); 1481 } 1482 } 1483 1484 } // namespace xmloff 1485 1486 Sequence< OUString > SAL_CALL AnimationsImport_getSupportedServiceNames() throw() 1487 { 1488 const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Xmloff.AnimationsImport" ) ); 1489 const Sequence< OUString > aSeq( &aServiceName, 1 ); 1490 return aSeq; 1491 } 1492 1493 OUString SAL_CALL AnimationsImport_getImplementationName() throw() 1494 { 1495 return OUString( RTL_CONSTASCII_USTRINGPARAM( "xmloff::AnimationsImport" ) ); 1496 } 1497 1498 Reference< XInterface > SAL_CALL AnimationsImport_createInstance(const Reference< XMultiServiceFactory > & rSMgr) throw( Exception ) 1499 { 1500 return (cppu::OWeakObject*)new xmloff::AnimationsImport( rSMgr ); 1501 1502 } 1503 1504 namespace xmloff 1505 { 1506 1507 OUString SAL_CALL AnimationsImport::getImplementationName() throw(RuntimeException) 1508 { 1509 return AnimationsImport_getImplementationName(); 1510 } 1511 1512 sal_Bool SAL_CALL AnimationsImport::supportsService( const OUString& ServiceName ) throw(RuntimeException) 1513 { 1514 return ServiceName.equalsAscii( "com.sun.star.comp.Xmloff.AnimationsImport" ); 1515 } 1516 1517 Sequence< OUString > SAL_CALL AnimationsImport::getSupportedServiceNames() throw(RuntimeException) 1518 { 1519 return AnimationsImport_getSupportedServiceNames(); 1520 } 1521 1522 } // namespace xmloff 1523 1524