/************************************************************************* * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: CustomAnimationPreset.cxx,v $ * * $Revision: 1.3 $ * * last change: $Author: rt $ $Date: 2005-09-09 03:09:06 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. * * * GNU Lesser General Public License Version 2.1 * ============================================= * Copyright 2005 by Sun Microsystems, Inc. * 901 San Antonio Road, Palo Alto, CA 94303, USA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * ************************************************************************/ #ifndef _COM_SUN_STAR_UTIL_XCLONEABLE_HPP_ #include #endif #ifndef _COM_SUN_STAR_ANIMATIONS_XANIMATIONNODESUPPLIER_HPP_ #include #endif #ifndef _COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_ #include #endif #ifndef _COM_SUN_STAR_XML_SAX_INPUTSOURCE_HPP_ #include #endif #ifndef _COM_SUN_STAR_XML_SAX_XPARSER_HPP_ #include #endif #ifndef _COM_SUN_STAR_XML_SAX_SAXPARSEEXCEPTION_HPP_ #include #endif #ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_ #include #endif #ifndef _COM_SUN_STAR_PRESENTATION_EFFECTPRESETCLASS_HPP_ #include #endif #ifndef _COM_SUN_STAR_BEANS_NAMEDVALUE_HPP_ #include #endif #ifndef _URLOBJ_HXX #include #endif #ifndef _UTL_STREAM_WRAPPER_HXX_ #include #endif #ifndef _COMPHELPER_PROCESSFACTORY_HXX_ #include #endif #ifndef INCLUDED_SVTOOLS_PATHOPTIONS_HXX #include #endif #ifndef _STREAM_HXX #include #endif #include #ifndef _SV_SVAPP_HXX #include #endif #ifndef _VOS_MUTEX_HXX_ //autogen #include #endif #ifndef _UNTOOLS_UCBSTREAMHELPER_HXX #include #endif #ifndef _SD_CUSTOMANIMATIONPRESET_HXX #include #endif #include using namespace ::vos; using namespace ::com::sun::star; using namespace ::com::sun::star::animations; using namespace ::com::sun::star::presentation; using ::rtl::OUString; using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::uno::UNO_QUERY_THROW; using ::com::sun::star::uno::Any; using ::com::sun::star::uno::Sequence; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Exception; using ::com::sun::star::io::XInputStream; using ::com::sun::star::lang::XMultiServiceFactory; using ::com::sun::star::container::XNameAccess; using ::com::sun::star::beans::PropertyValue; using ::com::sun::star::util::XCloneable; using ::com::sun::star::beans::NamedValue; namespace sd { static Reference< XNameAccess > getNodeAccess( const Reference< XMultiServiceFactory >& xConfigProvider, const OUString& rNodePath ) { Reference< XNameAccess > xConfigAccess; try { Sequence< Any > aArgs( 1 ); PropertyValue aPropValue; aPropValue.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" )); aPropValue.Value <<= rNodePath; aArgs[0] <<= aPropValue; xConfigAccess = Reference< XNameAccess >::query( xConfigProvider->createInstanceWithArguments( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationAccess" )), aArgs )); } catch( Exception& e ) { (void)e; DBG_ERROR( "sd::getNodeAccess(), Exception catched!" ); } return xConfigAccess; } void implImportLabels( const Reference< XMultiServiceFactory >& xConfigProvider, const OUString& rNodePath, UStringMap& rStringMap ) { try { Reference< XNameAccess > xConfigAccess( getNodeAccess( xConfigProvider, rNodePath ) ); if( xConfigAccess.is() ) { OUString aLabel( RTL_CONSTASCII_USTRINGPARAM( "Label" ) ); Reference< XNameAccess > xNameAccess; Sequence< OUString > aNames( xConfigAccess->getElementNames() ); const OUString* p = aNames.getConstArray(); sal_Int32 n = aNames.getLength(); while(n--) { xConfigAccess->getByName( *p ) >>= xNameAccess; if( xNameAccess.is() ) { OUString aUIName; xNameAccess->getByName( aLabel ) >>= aUIName; if( aUIName.getLength() ) { rStringMap[ *p ] = aUIName; } } p++; } } } catch( lang::WrappedTargetException& e ) { (void)e; DBG_ERROR( "sd::implImportLabels(), WrappedTargetException catched!" ); } catch( Exception& e ) { (void)e; DBG_ERROR( "sd::implImportLabels(), Exception catched!" ); } false; } CustomAnimationPreset::CustomAnimationPreset( CustomAnimationEffectPtr pEffect ) { maPresetId = pEffect->getPresetId(); maProperty = pEffect->getProperty(); mnPresetClass = pEffect->getPresetClass(); add( pEffect ); mfDuration = pEffect->getDuration(); maDefaultSubTyp = pEffect->getPresetSubType(); mbIsTextOnly = false; Sequence< NamedValue > aUserData( pEffect->getNode()->getUserData() ); sal_Int32 nLength = aUserData.getLength(); const NamedValue* p = aUserData.getConstArray(); while( nLength-- ) { if( p->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "text-only" ) ) ) { mbIsTextOnly = true; break; } p++; } } void CustomAnimationPreset::add( CustomAnimationEffectPtr pEffect ) { maSubTypes[ pEffect->getPresetSubType() ] = pEffect; } UStringList CustomAnimationPreset::getSubTypes() { UStringList aSubTypes; if( maSubTypes.size() > 1 ) { EffectsSubTypeMap::iterator aIter( maSubTypes.begin() ); const EffectsSubTypeMap::iterator aEnd( maSubTypes.end() ); while( aIter != aEnd ) aSubTypes.push_back( (*aIter++).first ); } return aSubTypes; } Reference< XAnimationNode > CustomAnimationPreset::create( const rtl::OUString& rstrSubType ) { try { OUString strSubType( rstrSubType ); if( strSubType.getLength() == 0 ) strSubType = maDefaultSubTyp; CustomAnimationEffectPtr pEffect = maSubTypes[strSubType]; if( pEffect.get() ) { Reference< XCloneable > xCloneable( pEffect->getNode(), UNO_QUERY_THROW ); Reference< XAnimationNode > xNode( xCloneable->createClone(), UNO_QUERY_THROW ); return xNode; } } catch( Exception& e ) { (void)e; DBG_ERROR( "sd::CustomAnimationPresets::create(), exception catched!" ); } Reference< XAnimationNode > xNode; return xNode; } UStringList CustomAnimationPreset::getProperties() const { String aProperties( maProperty ); int nTokens = aProperties.GetTokenCount(); int nToken; UStringList aPropertyList; for( nToken = 0; nToken < nTokens; nToken++ ) aPropertyList.push_back( aProperties.GetToken( nToken ) ); return aPropertyList; } bool CustomAnimationPreset::hasProperty( const OUString& rProperty )const { String aProperties( maProperty ); String aProperty( rProperty ); int nTokens = aProperties.GetTokenCount(); int nToken; for( nToken = 0; nToken < nTokens; nToken++ ) { if( aProperties.GetToken( nToken ) == aProperty ) return true; } return false; } CustomAnimationPresets::CustomAnimationPresets() { } CustomAnimationPresets::~CustomAnimationPresets() { } void CustomAnimationPresets::init() { importResources(); } Reference< XAnimationNode > implImportEffects( const Reference< XMultiServiceFactory >& xServiceFactory, const OUString& rPath ) { Reference< XAnimationNode > xRootNode; try { // create stream SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( rPath, STREAM_READ ); Reference xInputStream( new utl::OInputStreamWrapper( pIStm, sal_True ) ); // prepare ParserInputSrouce xml::sax::InputSource aParserInput; aParserInput.sSystemId = rPath; aParserInput.aInputStream = xInputStream; // get parser Reference< xml::sax::XParser > xParser( xServiceFactory->createInstance( OUString::createFromAscii("com.sun.star.xml.sax.Parser") ), UNO_QUERY ); DBG_ASSERT( xParser.is(), "Can't create parser" ); if( !xParser.is() ) return xRootNode; // get filter Reference< xml::sax::XDocumentHandler > xFilter( xServiceFactory->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Xmloff.AnimationsImport" ) ) ), UNO_QUERY ); DBG_ASSERT( xFilter.is(), "Can't instantiate filter component." ); if( !xFilter.is() ) return xRootNode; // connect parser and filter xParser->setDocumentHandler( xFilter ); // finally, parser the stream xParser->parseStream( aParserInput ); Reference< XAnimationNodeSupplier > xAnimationNodeSupplier( xFilter, UNO_QUERY ); if( xAnimationNodeSupplier.is() ) xRootNode = xAnimationNodeSupplier->getAnimationNode(); } catch( xml::sax::SAXParseException& r ) { (void)r; DBG_ERROR( "sd::implImportEffects(), SAXParseException catched!" ); } catch( xml::sax::SAXException& r ) { (void)r; DBG_ERROR( "sd::implImportEffects(), SAXException catched!" ); } catch( io::IOException& r ) { (void)r; DBG_ERROR( "sd::implImportEffects(), IOException catched!" ); } catch( Exception& r ) { (void)r; DBG_ERROR( "sd::importEffects(), Exception catched!" ); } return xRootNode; } void CustomAnimationPresets::importEffects() { try { // Get service factory Reference< XMultiServiceFactory > xServiceFactory( comphelper::getProcessServiceFactory() ); DBG_ASSERT( xServiceFactory.is(), "sd::CustomAnimationPresets::import(), got no service manager" ); if( !xServiceFactory.is() ) return; INetURLObject aURL( SvtPathOptions().GetConfigPath() ); aURL.Append( String( RTL_CONSTASCII_USTRINGPARAM("soffice.cfg") ) ); aURL.Append( String( RTL_CONSTASCII_USTRINGPARAM("simpress" ) ) ); aURL.Append( String( RTL_CONSTASCII_USTRINGPARAM("effects.xml" ) ) ); const OUString aPath( aURL.GetMainURL( INetURLObject::NO_DECODE ) ); mxRootNode = implImportEffects( xServiceFactory, aPath ); if( mxRootNode.is() ) { Reference< XTimeContainer > xRootContainer( mxRootNode, UNO_QUERY_THROW ); EffectSequenceHelper aSequence( xRootContainer ); EffectSequence::iterator aIter( aSequence.getBegin() ); const EffectSequence::iterator aEnd( aSequence.getEnd() ); while( aIter != aEnd ) { CustomAnimationEffectPtr pEffect = (*aIter); const OUString aPresetId( pEffect->getPresetId() ); CustomAnimationPresetPtr pDescriptor = getEffectDescriptor( aPresetId ); if( pDescriptor.get() ) pDescriptor->add( pEffect ); else { CustomAnimationPresetPtr pDescriptor( new CustomAnimationPreset( pEffect ) ); pDescriptor->maLabel = getUINameForPresetId( pEffect->getPresetId() ); maEffectDiscriptorMap[aPresetId] = pDescriptor; } aIter++; } } } catch( xml::sax::SAXParseException& r ) { (void)r; DBG_ERROR( "sd::CustomAnimationPresets::importEffects(), SAXParseException catched!" ); } catch( xml::sax::SAXException& r ) { (void)r; DBG_ERROR( "sd::CustomAnimationPresets::importEffects(), SAXException catched!" ); } catch( io::IOException& r ) { (void)r; DBG_ERROR( "sd::CustomAnimationPresets::importEffects(), IOException catched!" ); } catch( Exception& r ) { (void)r; DBG_ERROR( "sd::CustomAnimationPresets::importEffects(), Exception catched!" ); } } void CustomAnimationPresets::importResources() { try { // Get service factory Reference< XMultiServiceFactory > xServiceFactory( comphelper::getProcessServiceFactory() ); DBG_ASSERT( xServiceFactory.is(), "sd::CustomAnimationPresets::import(), got no service manager" ); if( !xServiceFactory.is() ) return; Reference< XMultiServiceFactory > xConfigProvider( xServiceFactory->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ))), UNO_QUERY ); const OUString aPropertyPath( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI.Effects/UserInterface/Properties" ) ); implImportLabels( xConfigProvider, aPropertyPath, maPropertyNameMap ); const OUString aEffectsPath( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI.Effects/UserInterface/Effects" ) ); implImportLabels( xConfigProvider, aEffectsPath, maEffectNameMap ); importEffects(); const OUString aEntrancePath( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI.Effects/Presets/Entrance" ) ); importPresets( xConfigProvider, aEntrancePath, maEntrancePresets ); const OUString aEmphasisPath( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI.Effects/Presets/Emphasis" ) ); importPresets( xConfigProvider, aEmphasisPath, maEmphasisPresets ); const OUString aExitPath( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI.Effects/Presets/Exit" ) ); importPresets( xConfigProvider, aExitPath, maExitPresets ); const OUString aMotionPathsPath( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI.Effects/Presets/MotionPaths" ) ); importPresets( xConfigProvider, aMotionPathsPath, maMotionPathsPresets ); } catch( lang::WrappedTargetException& e ) { (void)e; DBG_ERROR( "sd::CustomAnimationPresets::importResources(), WrappedTargetException catched!" ); } catch( Exception& e ) { (void)e; DBG_ERROR( "sd::CustomAnimationPresets::importResources(), Exception catched!" ); } } void CustomAnimationPresets::importPresets( const Reference< XMultiServiceFactory >& xConfigProvider, const OUString& rNodePath, PresetCategoryList& rPresetMap ) { #ifdef DEBUG String aMissedPresetIds; #endif try { Reference< XNameAccess > xTypeAccess( getNodeAccess( xConfigProvider, rNodePath ) ); if( xTypeAccess.is() ) { Reference< XNameAccess > xCategoryAccess; const OUString aEffectsName( RTL_CONSTASCII_USTRINGPARAM( "Effects" ) ); const OUString aLabelName( RTL_CONSTASCII_USTRINGPARAM( "Label" ) ); Sequence< OUString > aNames( xTypeAccess->getElementNames() ); const OUString* p = aNames.getConstArray(); sal_Int32 n = aNames.getLength(); while(n--) { xTypeAccess->getByName( *p ) >>= xCategoryAccess; if( xCategoryAccess.is() && xCategoryAccess->hasByName( aLabelName ) && xCategoryAccess->hasByName( aEffectsName ) ) { OUString aLabel; xCategoryAccess->getByName( aLabelName ) >>= aLabel; Sequence< OUString > aEffects; xCategoryAccess->getByName( aEffectsName ) >>= aEffects; EffectDescriptorList aEffectsList; const OUString* pEffectNames = aEffects.getConstArray(); sal_Int32 nEffectCount = aEffects.getLength(); while( nEffectCount-- ) { CustomAnimationPresetPtr pEffect = getEffectDescriptor( *pEffectNames ); if( pEffect.get() ) { aEffectsList.push_back( pEffect ); } #ifdef DEBUG else { aMissedPresetIds += String(*pEffectNames); aMissedPresetIds += String( RTL_CONSTASCII_USTRINGPARAM("\n") ); } #endif pEffectNames++; } rPresetMap.push_back( PresetCategoryPtr( new PresetCategory( aLabel, aEffectsList ) ) ); } p++; } } } catch( Exception& e ) { (void)e; DBG_ERROR( "sd::CustomAnimationPresets::importPresets(), Exception catched!" ); } #ifdef DEBUG if( aMissedPresetIds.Len() ) { ByteString aTmp( "sd::CustomAnimationPresets::importPresets(), invalid preset id!\n" ); aTmp += ByteString( aMissedPresetIds, RTL_TEXTENCODING_ASCII_US ); DBG_ERROR( aTmp.GetBuffer() ); } #endif } CustomAnimationPresetPtr CustomAnimationPresets::getEffectDescriptor( const rtl::OUString& rPresetId ) const { EffectDescriptorMap::const_iterator aIter( maEffectDiscriptorMap.find( rPresetId ) ); if( aIter != maEffectDiscriptorMap.end() ) { return (*aIter).second; } else { return CustomAnimationPresetPtr((CustomAnimationPreset*)0); } } const rtl::OUString& CustomAnimationPresets::getUINameForPresetId( const rtl::OUString& rPresetId ) const { return translateName( rPresetId, maEffectNameMap ); } const rtl::OUString& CustomAnimationPresets::getUINameForProperty( const rtl::OUString& rPresetId ) const { return translateName( rPresetId, maPropertyNameMap ); } const rtl::OUString& CustomAnimationPresets::translateName( const rtl::OUString& rId, const UStringMap& rNameMap ) const { UStringMap::const_iterator aIter( rNameMap.find( rId ) ); if( aIter != rNameMap.end() ) { return (*aIter).second; } else { return rId; } } void CustomAnimationPresets::changePresetSubType( CustomAnimationEffectPtr pEffect, const rtl::OUString& rPresetSubType ) const { if( pEffect.get() && pEffect->getPresetSubType() != rPresetSubType ) { CustomAnimationPresetPtr pDescriptor( getEffectDescriptor( pEffect->getPresetId() ) ); if( pDescriptor.get() ) { Reference< XAnimationNode > xNewNode( pDescriptor->create( rPresetSubType ) ); if( xNewNode.is() ) pEffect->replaceNode( xNewNode ); } } } CustomAnimationPresets* CustomAnimationPresets::mpCustomAnimationPresets = 0; const CustomAnimationPresets& CustomAnimationPresets::getCustomAnimationPresets() { if( !mpCustomAnimationPresets ) { OGuard aGuard( Application::GetSolarMutex() ); if( !mpCustomAnimationPresets ) { mpCustomAnimationPresets = new sd::CustomAnimationPresets(); mpCustomAnimationPresets->init(); } } return *mpCustomAnimationPresets; } Reference< XAnimationNode > CustomAnimationPresets::getRandomPreset( sal_Int16 nPresetClass ) const { Reference< XAnimationNode > xNode; const PresetCategoryList* pCategoryList = 0; switch( nPresetClass ) { case EffectPresetClass::ENTRANCE: pCategoryList = &maEntrancePresets; break; case EffectPresetClass::EXIT: pCategoryList = &maExitPresets; break; case EffectPresetClass::EMPHASIS: pCategoryList = &maEmphasisPresets; break; case EffectPresetClass::MOTIONPATH: pCategoryList = &maMotionPathsPresets; break; default: pCategoryList = 0; } if( pCategoryList && pCategoryList->size() ) { sal_Int32 nCategory = (rand() * pCategoryList->size() / RAND_MAX); PresetCategoryPtr pCategory = (*pCategoryList)[nCategory]; if( pCategory.get() && pCategory->maEffects.size() ) { sal_Int32 nDescriptor = (rand() * pCategory->maEffects.size() / RAND_MAX); CustomAnimationPresetPtr pPreset = pCategory->maEffects[nDescriptor]; if( pPreset.get() ) { UStringList aSubTypes = pPreset->getSubTypes(); OUString aSubType; if( aSubTypes.size() ) { sal_Int32 nSubType = (rand() * aSubTypes.size() / RAND_MAX); aSubType = aSubTypes[nSubType]; } xNode = pPreset->create( aSubType ); } } } return xNode; } }