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