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_sd.hxx" 30 #include <com/sun/star/util/XCloneable.hpp> 31 #include <com/sun/star/util/XMacroExpander.hpp> 32 #include <com/sun/star/animations/XAnimationNodeSupplier.hpp> 33 #include <com/sun/star/container/XNameAccess.hpp> 34 #include <com/sun/star/xml/sax/InputSource.hpp> 35 #include <com/sun/star/xml/sax/XParser.hpp> 36 #include <com/sun/star/xml/sax/SAXParseException.hpp> 37 #include <com/sun/star/beans/PropertyValue.hpp> 38 #include <com/sun/star/beans/XPropertySet.hpp> 39 #include <com/sun/star/presentation/EffectPresetClass.hpp> 40 #include <com/sun/star/beans/NamedValue.hpp> 41 #include <tools/urlobj.hxx> 42 #include <unotools/streamwrap.hxx> 43 #include <comphelper/processfactory.hxx> 44 #include <unotools/pathoptions.hxx> 45 #include <tools/stream.hxx> 46 47 #include <tools/debug.hxx> 48 #include <rtl/uri.hxx> 49 #include <vcl/svapp.hxx> 50 #include <vos/mutex.hxx> 51 #include <unotools/ucbstreamhelper.hxx> 52 #include <CustomAnimationPreset.hxx> 53 54 #include <algorithm> 55 56 using namespace ::vos; 57 using namespace ::com::sun::star; 58 using namespace ::com::sun::star::animations; 59 using namespace ::com::sun::star::presentation; 60 61 using ::rtl::OUString; 62 using ::com::sun::star::uno::UNO_QUERY; 63 using ::com::sun::star::uno::UNO_QUERY_THROW; 64 using ::com::sun::star::uno::Any; 65 using ::com::sun::star::uno::Sequence; 66 using ::com::sun::star::uno::Reference; 67 using ::com::sun::star::uno::Exception; 68 using ::com::sun::star::io::XInputStream; 69 using ::com::sun::star::lang::XMultiServiceFactory; 70 using ::com::sun::star::container::XNameAccess; 71 using ::com::sun::star::beans::PropertyValue; 72 using ::com::sun::star::util::XCloneable; 73 using ::com::sun::star::beans::NamedValue; 74 75 namespace sd { 76 77 static Reference< XNameAccess > getNodeAccess( const Reference< XMultiServiceFactory >& xConfigProvider, const OUString& rNodePath ) 78 { 79 Reference< XNameAccess > xConfigAccess; 80 81 try 82 { 83 Sequence< Any > aArgs( 1 ); 84 PropertyValue aPropValue; 85 aPropValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" )); 86 aPropValue.Value <<= rNodePath; 87 aArgs[0] <<= aPropValue; 88 89 xConfigAccess = Reference< XNameAccess >::query( 90 xConfigProvider->createInstanceWithArguments( 91 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationAccess" )), 92 aArgs )); 93 } 94 catch( Exception& e ) 95 { 96 (void)e; 97 DBG_ERROR( "sd::getNodeAccess(), Exception catched!" ); 98 } 99 100 return xConfigAccess; 101 } 102 103 void implImportLabels( const Reference< XMultiServiceFactory >& xConfigProvider, const OUString& rNodePath, UStringMap& rStringMap ) 104 { 105 try 106 { 107 Reference< XNameAccess > xConfigAccess( getNodeAccess( xConfigProvider, rNodePath ) ); 108 if( xConfigAccess.is() ) 109 { 110 OUString aLabel( RTL_CONSTASCII_USTRINGPARAM( "Label" ) ); 111 Reference< XNameAccess > xNameAccess; 112 Sequence< OUString > aNames( xConfigAccess->getElementNames() ); 113 const OUString* p = aNames.getConstArray(); 114 sal_Int32 n = aNames.getLength(); 115 while(n--) 116 { 117 xConfigAccess->getByName( *p ) >>= xNameAccess; 118 if( xNameAccess.is() ) 119 { 120 OUString aUIName; 121 xNameAccess->getByName( aLabel ) >>= aUIName; 122 if( aUIName.getLength() ) 123 { 124 rStringMap[ *p ] = aUIName; 125 } 126 } 127 128 p++; 129 } 130 } 131 } 132 catch( lang::WrappedTargetException& e ) 133 { 134 (void)e; 135 DBG_ERROR( "sd::implImportLabels(), WrappedTargetException catched!" ); 136 } 137 catch( Exception& e ) 138 { 139 (void)e; 140 DBG_ERROR( "sd::implImportLabels(), Exception catched!" ); 141 } 142 } 143 144 CustomAnimationPreset::CustomAnimationPreset( CustomAnimationEffectPtr pEffect ) 145 { 146 maPresetId = pEffect->getPresetId(); 147 maProperty = pEffect->getProperty(); 148 mnPresetClass = pEffect->getPresetClass(); 149 150 add( pEffect ); 151 152 mfDuration = pEffect->getDuration(); 153 maDefaultSubTyp = pEffect->getPresetSubType(); 154 155 mbIsTextOnly = false; 156 157 Sequence< NamedValue > aUserData( pEffect->getNode()->getUserData() ); 158 sal_Int32 nLength = aUserData.getLength(); 159 const NamedValue* p = aUserData.getConstArray(); 160 161 while( nLength-- ) 162 { 163 if( p->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "text-only" ) ) ) 164 { 165 mbIsTextOnly = true; 166 break; 167 } 168 p++; 169 } 170 171 } 172 173 void CustomAnimationPreset::add( CustomAnimationEffectPtr pEffect ) 174 { 175 maSubTypes[ pEffect->getPresetSubType() ] = pEffect; 176 } 177 178 UStringList CustomAnimationPreset::getSubTypes() 179 { 180 UStringList aSubTypes; 181 182 if( maSubTypes.size() > 1 ) 183 { 184 EffectsSubTypeMap::iterator aIter( maSubTypes.begin() ); 185 const EffectsSubTypeMap::iterator aEnd( maSubTypes.end() ); 186 while( aIter != aEnd ) 187 aSubTypes.push_back( (*aIter++).first ); 188 } 189 190 return aSubTypes; 191 } 192 193 Reference< XAnimationNode > CustomAnimationPreset::create( const rtl::OUString& rstrSubType ) 194 { 195 try 196 { 197 OUString strSubType( rstrSubType ); 198 if( strSubType.getLength() == 0 ) 199 strSubType = maDefaultSubTyp; 200 201 CustomAnimationEffectPtr pEffect = maSubTypes[strSubType]; 202 if( pEffect.get() ) 203 { 204 Reference< XCloneable > xCloneable( pEffect->getNode(), UNO_QUERY_THROW ); 205 Reference< XAnimationNode > xNode( xCloneable->createClone(), UNO_QUERY_THROW ); 206 return xNode; 207 } 208 } 209 catch( Exception& e ) 210 { 211 (void)e; 212 DBG_ERROR( "sd::CustomAnimationPresets::create(), exception catched!" ); 213 } 214 215 Reference< XAnimationNode > xNode; 216 return xNode; 217 } 218 219 UStringList CustomAnimationPreset::getProperties() const 220 { 221 String aProperties( maProperty ); 222 sal_uInt16 nTokens = aProperties.GetTokenCount(); 223 sal_uInt16 nToken; 224 UStringList aPropertyList; 225 for( nToken = 0; nToken < nTokens; nToken++ ) 226 aPropertyList.push_back( aProperties.GetToken( nToken ) ); 227 228 return aPropertyList; 229 230 } 231 232 bool CustomAnimationPreset::hasProperty( const OUString& rProperty )const 233 { 234 String aProperties( maProperty ); 235 String aProperty( rProperty ); 236 sal_uInt16 nTokens = aProperties.GetTokenCount(); 237 sal_uInt16 nToken; 238 for( nToken = 0; nToken < nTokens; nToken++ ) 239 { 240 if( aProperties.GetToken( nToken ) == aProperty ) 241 return true; 242 } 243 244 return false; 245 } 246 247 CustomAnimationPresets::CustomAnimationPresets() 248 { 249 } 250 251 CustomAnimationPresets::~CustomAnimationPresets() 252 { 253 } 254 255 void CustomAnimationPresets::init() 256 { 257 importResources(); 258 } 259 260 Reference< XAnimationNode > implImportEffects( const Reference< XMultiServiceFactory >& xServiceFactory, const OUString& rPath ) 261 { 262 Reference< XAnimationNode > xRootNode; 263 264 try 265 { 266 // create stream 267 SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( rPath, STREAM_READ ); 268 Reference<XInputStream> xInputStream( new utl::OInputStreamWrapper( pIStm, sal_True ) ); 269 270 // prepare ParserInputSrouce 271 xml::sax::InputSource aParserInput; 272 aParserInput.sSystemId = rPath; 273 aParserInput.aInputStream = xInputStream; 274 275 // get parser 276 Reference< xml::sax::XParser > xParser( 277 xServiceFactory->createInstance( 278 OUString::createFromAscii("com.sun.star.xml.sax.Parser") ), 279 UNO_QUERY ); 280 281 DBG_ASSERT( xParser.is(), "Can't create parser" ); 282 if( !xParser.is() ) 283 return xRootNode; 284 285 // get filter 286 Reference< xml::sax::XDocumentHandler > xFilter( 287 xServiceFactory->createInstance( 288 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Xmloff.AnimationsImport" ) ) ), UNO_QUERY ); 289 290 DBG_ASSERT( xFilter.is(), "Can't instantiate filter component." ); 291 if( !xFilter.is() ) 292 return xRootNode; 293 294 // connect parser and filter 295 xParser->setDocumentHandler( xFilter ); 296 297 // finally, parser the stream 298 xParser->parseStream( aParserInput ); 299 300 Reference< XAnimationNodeSupplier > xAnimationNodeSupplier( xFilter, UNO_QUERY ); 301 if( xAnimationNodeSupplier.is() ) 302 xRootNode = xAnimationNodeSupplier->getAnimationNode(); 303 } 304 catch( xml::sax::SAXParseException& r ) 305 { 306 (void)r; 307 DBG_ERROR( "sd::implImportEffects(), SAXParseException catched!" ); 308 } 309 catch( xml::sax::SAXException& r ) 310 { 311 (void)r; 312 DBG_ERROR( "sd::implImportEffects(), SAXException catched!" ); 313 } 314 catch( io::IOException& r ) 315 { 316 (void)r; 317 DBG_ERROR( "sd::implImportEffects(), IOException catched!" ); 318 } 319 catch( Exception& r ) 320 { 321 (void)r; 322 DBG_ERROR( "sd::importEffects(), Exception catched!" ); 323 } 324 325 return xRootNode; 326 } 327 328 #define EXPAND_PROTOCOL "vnd.sun.star.expand:" 329 330 void CustomAnimationPresets::importEffects() 331 { 332 try 333 { 334 // Get service factory 335 Reference< XMultiServiceFactory > xServiceFactory( comphelper::getProcessServiceFactory() ); 336 DBG_ASSERT( xServiceFactory.is(), "sd::CustomAnimationPresets::import(), got no service manager" ); 337 if( !xServiceFactory.is() ) 338 return; 339 340 uno::Reference< beans::XPropertySet > xProps( xServiceFactory, UNO_QUERY ); 341 uno::Reference< uno::XComponentContext > xContext; 342 xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xContext; 343 344 uno::Reference< util::XMacroExpander > xMacroExpander; 345 if( xContext.is() ) 346 xMacroExpander.set( xContext->getValueByName( 347 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/singletons/com.sun.star.util.theMacroExpander"))), 348 UNO_QUERY ); 349 350 Reference< XMultiServiceFactory > xConfigProvider( 351 xServiceFactory->createInstance( 352 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ))), 353 UNO_QUERY_THROW ); 354 355 // read path to transition effects files from config 356 Any propValue = uno::makeAny( 357 beans::PropertyValue( 358 OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" )), -1, 359 uno::makeAny( OUString( RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Office.Impress/Misc") )), 360 beans::PropertyState_DIRECT_VALUE ) ); 361 362 Reference<container::XNameAccess> xNameAccess( 363 xConfigProvider->createInstanceWithArguments( 364 OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationAccess")), 365 Sequence<Any>( &propValue, 1 ) ), UNO_QUERY_THROW ); 366 uno::Sequence< rtl::OUString > aFiles; 367 xNameAccess->getByName( 368 OUString( RTL_CONSTASCII_USTRINGPARAM("EffectFiles"))) >>= aFiles; 369 370 for( sal_Int32 i=0; i<aFiles.getLength(); ++i ) 371 { 372 rtl::OUString aURL = aFiles[i]; 373 if( aURL.compareToAscii( RTL_CONSTASCII_STRINGPARAM( EXPAND_PROTOCOL )) == 0 ) 374 { 375 // cut protocol 376 rtl::OUString aMacro( aURL.copy( sizeof ( EXPAND_PROTOCOL ) -1 ) ); 377 // decode uric class chars 378 aMacro = rtl::Uri::decode( aMacro, rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8 ); 379 // expand macro string 380 aURL = xMacroExpander->expandMacros( aMacro ); 381 } 382 383 mxRootNode = implImportEffects( xServiceFactory, aURL ); 384 385 if( mxRootNode.is() ) 386 { 387 Reference< XTimeContainer > xRootContainer( mxRootNode, UNO_QUERY_THROW ); 388 EffectSequenceHelper aSequence( xRootContainer ); 389 390 EffectSequence::iterator aIter( aSequence.getBegin() ); 391 const EffectSequence::iterator aEnd( aSequence.getEnd() ); 392 393 while( aIter != aEnd ) 394 { 395 CustomAnimationEffectPtr pEffect = (*aIter); 396 397 const OUString aPresetId( pEffect->getPresetId() ); 398 CustomAnimationPresetPtr pDescriptor = getEffectDescriptor( aPresetId ); 399 if( pDescriptor.get() ) 400 pDescriptor->add( pEffect ); 401 else 402 { 403 pDescriptor.reset( new CustomAnimationPreset( pEffect ) ); 404 pDescriptor->maLabel = getUINameForPresetId( pEffect->getPresetId() ); 405 maEffectDiscriptorMap[aPresetId] = pDescriptor; 406 } 407 408 aIter++; 409 } 410 } 411 } 412 } 413 catch( xml::sax::SAXParseException& r ) 414 { 415 (void)r; 416 DBG_ERROR( "sd::CustomAnimationPresets::importEffects(), SAXParseException catched!" ); 417 } 418 catch( xml::sax::SAXException& r ) 419 { 420 (void)r; 421 DBG_ERROR( "sd::CustomAnimationPresets::importEffects(), SAXException catched!" ); 422 } 423 catch( io::IOException& r ) 424 { 425 (void)r; 426 DBG_ERROR( "sd::CustomAnimationPresets::importEffects(), IOException catched!" ); 427 } 428 catch( Exception& r ) 429 { 430 (void)r; 431 DBG_ERROR( "sd::CustomAnimationPresets::importEffects(), Exception catched!" ); 432 } 433 } 434 435 void CustomAnimationPresets::importResources() 436 { 437 try 438 { 439 // Get service factory 440 Reference< XMultiServiceFactory > xServiceFactory( comphelper::getProcessServiceFactory() ); 441 DBG_ASSERT( xServiceFactory.is(), "sd::CustomAnimationPresets::import(), got no service manager" ); 442 if( !xServiceFactory.is() ) 443 return; 444 445 Reference< XMultiServiceFactory > xConfigProvider( 446 xServiceFactory->createInstance( 447 OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ))), 448 UNO_QUERY ); 449 450 const OUString aPropertyPath( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI.Effects/UserInterface/Properties" ) ); 451 implImportLabels( xConfigProvider, aPropertyPath, maPropertyNameMap ); 452 453 const OUString aEffectsPath( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI.Effects/UserInterface/Effects" ) ); 454 implImportLabels( xConfigProvider, aEffectsPath, maEffectNameMap ); 455 456 importEffects(); 457 458 const OUString aEntrancePath( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI.Effects/Presets/Entrance" ) ); 459 importPresets( xConfigProvider, aEntrancePath, maEntrancePresets ); 460 461 const OUString aEmphasisPath( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI.Effects/Presets/Emphasis" ) ); 462 importPresets( xConfigProvider, aEmphasisPath, maEmphasisPresets ); 463 464 const OUString aExitPath( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI.Effects/Presets/Exit" ) ); 465 importPresets( xConfigProvider, aExitPath, maExitPresets ); 466 467 const OUString aMotionPathsPath( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI.Effects/Presets/MotionPaths" ) ); 468 importPresets( xConfigProvider, aMotionPathsPath, maMotionPathsPresets ); 469 470 const OUString aMiscPath( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI.Effects/Presets/Misc" ) ); 471 importPresets( xConfigProvider, aMiscPath, maMiscPresets ); 472 } 473 catch( lang::WrappedTargetException& e ) 474 { 475 (void)e; 476 DBG_ERROR( "sd::CustomAnimationPresets::importResources(), WrappedTargetException catched!" ); 477 } 478 catch( Exception& e ) 479 { 480 (void)e; 481 DBG_ERROR( "sd::CustomAnimationPresets::importResources(), Exception catched!" ); 482 } 483 } 484 485 void CustomAnimationPresets::importPresets( const Reference< XMultiServiceFactory >& xConfigProvider, const OUString& rNodePath, PresetCategoryList& rPresetMap ) 486 { 487 #ifdef DEBUG 488 String aMissedPresetIds; 489 #endif 490 491 try 492 { 493 Reference< XNameAccess > xTypeAccess( getNodeAccess( xConfigProvider, rNodePath ) ); 494 if( xTypeAccess.is() ) 495 { 496 Reference< XNameAccess > xCategoryAccess; 497 const OUString aEffectsName( RTL_CONSTASCII_USTRINGPARAM( "Effects" ) ); 498 const OUString aLabelName( RTL_CONSTASCII_USTRINGPARAM( "Label" ) ); 499 500 Sequence< OUString > aNames( xTypeAccess->getElementNames() ); 501 const OUString* p = aNames.getConstArray(); 502 sal_Int32 n = aNames.getLength(); 503 while(n--) 504 { 505 xTypeAccess->getByName( *p ) >>= xCategoryAccess; 506 507 if( xCategoryAccess.is() && xCategoryAccess->hasByName( aLabelName ) && xCategoryAccess->hasByName( aEffectsName ) ) 508 { 509 OUString aLabel; 510 xCategoryAccess->getByName( aLabelName ) >>= aLabel; 511 512 Sequence< OUString > aEffects; 513 xCategoryAccess->getByName( aEffectsName ) >>= aEffects; 514 515 EffectDescriptorList aEffectsList; 516 517 const OUString* pEffectNames = aEffects.getConstArray(); 518 sal_Int32 nEffectCount = aEffects.getLength(); 519 while( nEffectCount-- ) 520 { 521 CustomAnimationPresetPtr pEffect = getEffectDescriptor( *pEffectNames ); 522 if( pEffect.get() ) 523 { 524 aEffectsList.push_back( pEffect ); 525 } 526 #ifdef DEBUG 527 else 528 { 529 aMissedPresetIds += String(*pEffectNames); 530 aMissedPresetIds += String( RTL_CONSTASCII_USTRINGPARAM("\n") ); 531 } 532 #endif 533 pEffectNames++; 534 } 535 rPresetMap.push_back( PresetCategoryPtr( new PresetCategory( aLabel, aEffectsList ) ) ); 536 } 537 538 p++; 539 } 540 } 541 } 542 catch( Exception& e ) 543 { 544 (void)e; 545 DBG_ERROR( "sd::CustomAnimationPresets::importPresets(), Exception catched!" ); 546 } 547 548 #ifdef DEBUG 549 if( aMissedPresetIds.Len() ) 550 { 551 ByteString aTmp( "sd::CustomAnimationPresets::importPresets(), invalid preset id!\n" ); 552 aTmp += ByteString( aMissedPresetIds, RTL_TEXTENCODING_ASCII_US ); 553 DBG_ERROR( aTmp.GetBuffer() ); 554 } 555 #endif 556 } 557 558 CustomAnimationPresetPtr CustomAnimationPresets::getEffectDescriptor( const rtl::OUString& rPresetId ) const 559 { 560 EffectDescriptorMap::const_iterator aIter( maEffectDiscriptorMap.find( rPresetId ) ); 561 562 if( aIter != maEffectDiscriptorMap.end() ) 563 { 564 return (*aIter).second; 565 } 566 else 567 { 568 return CustomAnimationPresetPtr((CustomAnimationPreset*)0); 569 } 570 } 571 572 const rtl::OUString& CustomAnimationPresets::getUINameForPresetId( const rtl::OUString& rPresetId ) const 573 { 574 return translateName( rPresetId, maEffectNameMap ); 575 } 576 577 const rtl::OUString& CustomAnimationPresets::getUINameForProperty( const rtl::OUString& rPresetId ) const 578 { 579 return translateName( rPresetId, maPropertyNameMap ); 580 } 581 582 const rtl::OUString& CustomAnimationPresets::translateName( const rtl::OUString& rId, const UStringMap& rNameMap ) const 583 { 584 UStringMap::const_iterator aIter( rNameMap.find( rId ) ); 585 586 if( aIter != rNameMap.end() ) 587 { 588 return (*aIter).second; 589 } 590 else 591 { 592 return rId; 593 } 594 } 595 void CustomAnimationPresets::changePresetSubType( CustomAnimationEffectPtr pEffect, const rtl::OUString& rPresetSubType ) const 596 { 597 if( pEffect.get() && pEffect->getPresetSubType() != rPresetSubType ) 598 { 599 CustomAnimationPresetPtr pDescriptor( getEffectDescriptor( pEffect->getPresetId() ) ); 600 601 if( pDescriptor.get() ) 602 { 603 Reference< XAnimationNode > xNewNode( pDescriptor->create( rPresetSubType ) ); 604 if( xNewNode.is() ) 605 pEffect->replaceNode( xNewNode ); 606 } 607 } 608 } 609 610 CustomAnimationPresets* CustomAnimationPresets::mpCustomAnimationPresets = 0; 611 612 const CustomAnimationPresets& CustomAnimationPresets::getCustomAnimationPresets() 613 { 614 if( !mpCustomAnimationPresets ) 615 { 616 OGuard aGuard( Application::GetSolarMutex() ); 617 618 if( !mpCustomAnimationPresets ) 619 { 620 mpCustomAnimationPresets = new sd::CustomAnimationPresets(); 621 mpCustomAnimationPresets->init(); 622 } 623 } 624 625 return *mpCustomAnimationPresets; 626 } 627 628 Reference< XAnimationNode > CustomAnimationPresets::getRandomPreset( sal_Int16 nPresetClass ) const 629 { 630 Reference< XAnimationNode > xNode; 631 632 const PresetCategoryList* pCategoryList = 0; 633 switch( nPresetClass ) 634 { 635 case EffectPresetClass::ENTRANCE: pCategoryList = &maEntrancePresets; break; 636 case EffectPresetClass::EXIT: pCategoryList = &maExitPresets; break; 637 case EffectPresetClass::EMPHASIS: pCategoryList = &maEmphasisPresets; break; 638 case EffectPresetClass::MOTIONPATH: pCategoryList = &maMotionPathsPresets; break; 639 default: 640 pCategoryList = 0; 641 } 642 643 if( pCategoryList && pCategoryList->size() ) 644 { 645 sal_Int32 nCategory = (rand() * pCategoryList->size() / RAND_MAX); 646 647 PresetCategoryPtr pCategory = (*pCategoryList)[nCategory]; 648 if( pCategory.get() && !pCategory->maEffects.empty() ) 649 { 650 sal_Int32 nDescriptor = (rand() * pCategory->maEffects.size() / RAND_MAX); 651 CustomAnimationPresetPtr pPreset = pCategory->maEffects[nDescriptor]; 652 if( pPreset.get() ) 653 { 654 UStringList aSubTypes = pPreset->getSubTypes(); 655 656 OUString aSubType; 657 if( !aSubTypes.empty() ) 658 { 659 sal_Int32 nSubType = (rand() * aSubTypes.size() / RAND_MAX); 660 aSubType = aSubTypes[nSubType]; 661 } 662 xNode = pPreset->create( aSubType ); 663 } 664 } 665 } 666 667 return xNode; 668 } 669 670 671 } 672 673