diff options
Diffstat (limited to 'xmloff/source/draw/animationimport.cxx')
-rw-r--r-- | xmloff/source/draw/animationimport.cxx | 1523 |
1 files changed, 1523 insertions, 0 deletions
diff --git a/xmloff/source/draw/animationimport.cxx b/xmloff/source/draw/animationimport.cxx new file mode 100644 index 000000000000..0920ef4f0992 --- /dev/null +++ b/xmloff/source/draw/animationimport.cxx @@ -0,0 +1,1523 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmloff.hxx" + +#include <tools/debug.hxx> +#include <tools/time.hxx> +#include "unointerfacetouniqueidentifiermapper.hxx" +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/animations/AnimationTransformType.hpp> +#include <com/sun/star/animations/XAnimationNodeSupplier.hpp> +#include <com/sun/star/presentation/AnimationEffect.hpp> +#include <com/sun/star/presentation/AnimationSpeed.hpp> +#include <com/sun/star/animations/AnimationNodeType.hpp> +#include <com/sun/star/animations/XIterateContainer.hpp> +#include <com/sun/star/animations/XAnimateMotion.hpp> +#include <com/sun/star/animations/XAnimateColor.hpp> +#include <com/sun/star/animations/XAnimateTransform.hpp> +#include <com/sun/star/animations/XTransitionFilter.hpp> +#include <com/sun/star/animations/XCommand.hpp> +#include <com/sun/star/animations/XAudio.hpp> +#include <com/sun/star/animations/ValuePair.hpp> +#include <com/sun/star/animations/AnimationColorSpace.hpp> +#include <com/sun/star/presentation/EffectPresetClass.hpp> +#include <com/sun/star/animations/Timing.hpp> +#include <com/sun/star/animations/Event.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/xml/sax/XAttributeList.hpp> +#include <com/sun/star/text/XTextCursor.hpp> +#include <com/sun/star/text/XTextRangeCompare.hpp> +#include <com/sun/star/presentation/ParagraphTarget.hpp> +#include <com/sun/star/container/XEnumerationAccess.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/animations/EventTrigger.hpp> +#include <com/sun/star/presentation/EffectCommands.hpp> +#include <comphelper/processfactory.hxx> +#include <cppuhelper/implbase1.hxx> + +#include <list> +#include <xmloff/xmltypes.hxx> +#include "sdpropls.hxx" +#include <xmloff/xmltoken.hxx> +#include <xmloff/xmlimp.hxx> +#include "xmloff/xmlnmspe.hxx" +#include <xmloff/xmluconv.hxx> +#include <osl/mutex.hxx> +#include <xmloff/nmspmap.hxx> +#include "anim.hxx" + +#include "animations.hxx" +#include "animationimport.hxx" + +using ::rtl::OUString; +using ::rtl::OUStringBuffer; + +using namespace ::std; +using namespace ::cppu; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::animations; +using namespace ::com::sun::star::presentation; +using namespace ::com::sun::star::drawing; +using namespace ::xmloff::token; + +using ::com::sun::star::xml::sax::XAttributeList; +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::makeAny; +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::uno::UNO_QUERY_THROW; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::RuntimeException; +using ::com::sun::star::uno::Exception; +using ::com::sun::star::uno::XInterface; +using ::com::sun::star::uno::Type; +using ::com::sun::star::beans::NamedValue; +using ::com::sun::star::text::XTextRange; +using ::com::sun::star::text::XTextCursor; +using ::com::sun::star::text::XTextRangeCompare; +using ::com::sun::star::container::XEnumerationAccess; +using ::com::sun::star::container::XEnumeration; +using ::com::sun::star::lang::XMultiServiceFactory; +using ::com::sun::star::lang::XInitialization; + +namespace xmloff +{ + +/////////////////////////////////////////////////////////////////////// + + + +/////////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////// + +class AnimationsImportHelperImpl +{ +private: + SvXMLImport& mrImport; + + SvXMLTokenMap* mpAnimationNodeTokenMap; + SvXMLTokenMap* mpAnimationNodeAttributeTokenMap; + +public: + AnimationsImportHelperImpl( SvXMLImport& rImport ); + ~AnimationsImportHelperImpl(); + + const SvXMLTokenMap& getAnimationNodeTokenMap(); + const SvXMLTokenMap& getAnimationNodeAttributeTokenMap(); + + Any convertValue( XMLTokenEnum eAttributeName, const OUString& rValue ); + Sequence< Any > convertValueSequence( XMLTokenEnum eAttributeName, const OUString& rValue ); + + Any convertTarget( const OUString& rValue ); + Any convertPath( const OUString& rValue ); + Any convertTiming( const OUString& rValue ); + Sequence< double > convertKeyTimes( const OUString& rValue ); + Sequence< TimeFilterPair > convertTimeFilter( const OUString& rValue ); + + bool convertAnimationValue( XMLTokenEnum eAttributeName, Any& rValue ); + const OUString mastrHSL; +}; + +AnimationsImportHelperImpl::AnimationsImportHelperImpl( SvXMLImport& rImport ) +: mrImport( rImport ), + mpAnimationNodeTokenMap( NULL ), + mpAnimationNodeAttributeTokenMap( NULL ), + mastrHSL( RTL_CONSTASCII_USTRINGPARAM( "hsl" ) ) +{ +} + +AnimationsImportHelperImpl::~AnimationsImportHelperImpl() +{ + delete mpAnimationNodeTokenMap; + delete mpAnimationNodeAttributeTokenMap; +} + +const SvXMLTokenMap& AnimationsImportHelperImpl::getAnimationNodeTokenMap() +{ + if( mpAnimationNodeTokenMap == NULL ) + { + static __FAR_DATA SvXMLTokenMapEntry aAnimationNodeTokenMap[] = + { + { XML_NAMESPACE_ANIMATION, XML_PAR, (sal_uInt16)AnimationNodeType::PAR }, + { XML_NAMESPACE_ANIMATION, XML_SEQ, (sal_uInt16)AnimationNodeType::SEQ }, + { XML_NAMESPACE_ANIMATION, XML_ITERATE, (sal_uInt16)AnimationNodeType::ITERATE }, + { XML_NAMESPACE_ANIMATION, XML_ANIMATE, (sal_uInt16)AnimationNodeType::ANIMATE }, + { XML_NAMESPACE_ANIMATION, XML_SET, (sal_uInt16)AnimationNodeType::SET }, + { XML_NAMESPACE_ANIMATION, XML_ANIMATEMOTION, (sal_uInt16)AnimationNodeType::ANIMATEMOTION }, + { XML_NAMESPACE_ANIMATION, XML_ANIMATECOLOR, (sal_uInt16)AnimationNodeType::ANIMATECOLOR }, + { XML_NAMESPACE_ANIMATION, XML_ANIMATETRANSFORM, (sal_uInt16)AnimationNodeType::ANIMATETRANSFORM }, + { XML_NAMESPACE_ANIMATION, XML_TRANSITIONFILTER, (sal_uInt16)AnimationNodeType::TRANSITIONFILTER }, + { XML_NAMESPACE_ANIMATION, XML_AUDIO, (sal_uInt16)AnimationNodeType::AUDIO }, + { XML_NAMESPACE_ANIMATION, XML_COMMAND, (sal_uInt16)AnimationNodeType::COMMAND }, + XML_TOKEN_MAP_END + }; + + mpAnimationNodeTokenMap = new SvXMLTokenMap( aAnimationNodeTokenMap ); + } + + return *mpAnimationNodeTokenMap; +} + +enum AnimationNodeAttributes +{ + ANA_Begin, + ANA_Dur, + ANA_End, + ANA_Fill, + ANA_FillDefault, + ANA_Restart, + ANA_RestartDefault, + ANA_Accelerate, + ANA_Decelerate, + ANA_AutoReverse, + ANA_RepeatCount, + ANA_RepeatDur, + ANA_EndSync, + ANA_Node_Type, + ANA_Preset_ID, + ANA_Preset_Sub_Type, + ANA_Preset_Class, + ANA_After_Effect, + ANA_Target, + ANA_XLink, + ANA_MasterElement, + ANA_SubItem, + ANA_AttributeName, + ANA_Values, + ANA_From, + ANA_By, + ANA_To, + ANA_KeyTimes, + ANA_CalcMode, + ANA_Accumulate, + ANA_AdditiveMode, + ANA_KeySplines, + ANA_Path, + ANA_ColorSpace, + ANA_ColorDirection, + ANA_TransformType, + ANA_TransitionType, + ANA_TransitionSubType, + ANA_Mode, + ANA_Direction, + ANA_FadeColor, + ANA_IterateType, + ANA_IterateInterval, + ANA_Formula, + ANA_ANIMID, + ANA_XMLID, + ANA_Group_Id, + ANA_Command, + ANA_Volume +}; + +const SvXMLTokenMap& AnimationsImportHelperImpl::getAnimationNodeAttributeTokenMap() +{ + if( mpAnimationNodeAttributeTokenMap == NULL ) + { + static __FAR_DATA SvXMLTokenMapEntry aAnimationNodeAttributeTokenMap[] = + { + { XML_NAMESPACE_SMIL, XML_BEGIN, (sal_uInt16)ANA_Begin }, + { XML_NAMESPACE_SMIL, XML_DUR, (sal_uInt16)ANA_Dur }, + { XML_NAMESPACE_SMIL, XML_END, (sal_uInt16)ANA_End }, + { XML_NAMESPACE_SMIL, XML_FILL, (sal_uInt16)ANA_Fill }, + { XML_NAMESPACE_SMIL, XML_FILLDEFAULT, (sal_uInt16)ANA_FillDefault }, + { XML_NAMESPACE_SMIL, XML_RESTART, (sal_uInt16)ANA_Restart }, + { XML_NAMESPACE_SMIL, XML_RESTARTDEFAULT, (sal_uInt16)ANA_RestartDefault }, + { XML_NAMESPACE_SMIL, XML_ACCELERATE, (sal_uInt16)ANA_Accelerate }, + { XML_NAMESPACE_SMIL, XML_DECELERATE, (sal_uInt16)ANA_Decelerate }, + { XML_NAMESPACE_SMIL, XML_AUTOREVERSE, (sal_uInt16)ANA_AutoReverse }, + { XML_NAMESPACE_SMIL, XML_REPEATCOUNT, (sal_uInt16)ANA_RepeatCount }, + { XML_NAMESPACE_SMIL, XML_REPEATDUR, (sal_uInt16)ANA_RepeatDur }, + { XML_NAMESPACE_SMIL, XML_ENDSYNC, (sal_uInt16)ANA_EndSync }, + { XML_NAMESPACE_PRESENTATION, XML_NODE_TYPE, (sal_uInt16)ANA_Node_Type }, + { XML_NAMESPACE_PRESENTATION, XML_PRESET_ID, (sal_uInt16)ANA_Preset_ID }, + { XML_NAMESPACE_PRESENTATION, XML_PRESET_SUB_TYPE, (sal_uInt16)ANA_Preset_Sub_Type }, + { XML_NAMESPACE_PRESENTATION, XML_PRESET_CLASS, (sal_uInt16)ANA_Preset_Class }, + { XML_NAMESPACE_PRESENTATION, XML_AFTER_EFFECT, (sal_uInt16)ANA_After_Effect }, + { XML_NAMESPACE_SMIL, XML_TARGETELEMENT, (sal_uInt16)ANA_Target }, + { XML_NAMESPACE_XLINK, XML_HREF, (sal_uInt16)ANA_XLink }, + { XML_NAMESPACE_PRESENTATION, XML_MASTER_ELEMENT, (sal_uInt16)ANA_MasterElement }, + { XML_NAMESPACE_ANIMATION, XML_SUB_ITEM, (sal_uInt16)ANA_SubItem }, + { XML_NAMESPACE_SMIL, XML_ATTRIBUTENAME, (sal_uInt16)ANA_AttributeName }, + { XML_NAMESPACE_SMIL, XML_VALUES, (sal_uInt16)ANA_Values }, + { XML_NAMESPACE_SMIL, XML_FROM, (sal_uInt16)ANA_From }, + { XML_NAMESPACE_SMIL, XML_BY, (sal_uInt16)ANA_By }, + { XML_NAMESPACE_SMIL, XML_TO, (sal_uInt16)ANA_To }, + { XML_NAMESPACE_SMIL, XML_KEYTIMES, (sal_uInt16)ANA_KeyTimes }, + { XML_NAMESPACE_SMIL, XML_CALCMODE, (sal_uInt16)ANA_CalcMode }, + { XML_NAMESPACE_SMIL, XML_ACCUMULATE, (sal_uInt16)ANA_Accumulate }, + { XML_NAMESPACE_PRESENTATION, XML_ADDITIVE, (sal_uInt16)ANA_AdditiveMode }, + { XML_NAMESPACE_SMIL, XML_ADDITIVE, (sal_uInt16)ANA_AdditiveMode }, + { XML_NAMESPACE_SMIL, XML_KEYSPLINES, (sal_uInt16)ANA_KeySplines }, + { XML_NAMESPACE_SVG, XML_PATH, (sal_uInt16)ANA_Path }, + { XML_NAMESPACE_ANIMATION, XML_COLOR_INTERPOLATION, (sal_uInt16)ANA_ColorSpace }, + { XML_NAMESPACE_ANIMATION, XML_COLOR_INTERPOLATION_DIRECTION, (sal_uInt16)ANA_ColorDirection }, + { XML_NAMESPACE_SVG, XML_TYPE, (sal_uInt16)ANA_TransformType }, + { XML_NAMESPACE_SMIL, XML_TYPE, (sal_uInt16)ANA_TransitionType }, + { XML_NAMESPACE_SMIL, XML_SUBTYPE, (sal_uInt16)ANA_TransitionSubType }, + { XML_NAMESPACE_SMIL, XML_MODE, (sal_uInt16)ANA_Mode }, + { XML_NAMESPACE_SMIL, XML_DIRECTION, (sal_uInt16)ANA_Direction }, + { XML_NAMESPACE_SMIL, XML_FADECOLOR, (sal_uInt16)ANA_FadeColor }, + { XML_NAMESPACE_ANIMATION, XML_ITERATE_TYPE, (sal_uInt16)ANA_IterateType }, + { XML_NAMESPACE_ANIMATION, XML_ITERATE_INTERVAL, (sal_uInt16)ANA_IterateInterval }, + { XML_NAMESPACE_ANIMATION, XML_FORMULA, (sal_uInt16)ANA_Formula }, + { XML_NAMESPACE_ANIMATION, XML_ID, (sal_uInt16)ANA_ANIMID }, + { XML_NAMESPACE_XML, XML_ID, (sal_uInt16)ANA_XMLID }, + { XML_NAMESPACE_PRESENTATION, XML_GROUP_ID, (sal_uInt16)ANA_Group_Id }, + { XML_NAMESPACE_ANIMATION, XML_AUDIO_LEVEL, (sal_uInt16)ANA_Volume }, + { XML_NAMESPACE_ANIMATION, XML_COMMAND, (sal_uInt16)ANA_Command }, + + XML_TOKEN_MAP_END + }; + + mpAnimationNodeAttributeTokenMap = new SvXMLTokenMap( aAnimationNodeAttributeTokenMap ); + } + + return *mpAnimationNodeAttributeTokenMap; +} + +static bool isDouble( const OUString& rValue ) +{ + sal_Int32 nLength = rValue.getLength(); + const sal_Unicode * pStr = rValue.getStr(); + while( nLength ) + { + if( (*pStr >= '0' && *pStr <= '9') || *pStr == '-' || *pStr == '.' || *pStr == '+' || *pStr == 'e' || *pStr == 'E' ) + { + pStr++; + nLength--; + } + else + { + return false; + } + } + + return true; +} + +static bool isTime( const OUString& rValue ) +{ + sal_Int32 nLength = rValue.getLength(); + const sal_Unicode * pStr; + for( pStr = rValue.getStr(); nLength; pStr++, nLength-- ) + { + if( !( (*pStr >= '0' && *pStr <= '9') || *pStr == '-' || *pStr == '.' || *pStr == '+' || *pStr == 'e' || *pStr == 'E' ) ) + break; + } + + // return true if this is a double (if someone forgot the 's' we silently ignore it) + // or if its a double that ends with a 's' or 'S' + return (nLength == 0) || ((*pStr == 's' || *pStr == 'S') && (nLength == 1)); +} + +static sal_Int32 count_codes( const OUString& rString, sal_Unicode nCode ) +{ + sal_Int32 nCount = 0; + sal_Int32 fromIndex = 0; + + while(true) + { + fromIndex = rString.indexOf( nCode, fromIndex ); + if( fromIndex == -1 ) + break; + + fromIndex++; + nCount++; + } + + return nCount; +} + +Any AnimationsImportHelperImpl::convertTarget( const OUString& rValue ) +{ + try + { + Reference< XInterface > xRef( mrImport.getInterfaceToIdentifierMapper().getReference( rValue ) ); + + Reference< XShape > _xShape( xRef, UNO_QUERY ); + if( _xShape.is() ) + return makeAny( _xShape ); + + Reference< XTextCursor > xTextCursor( xRef, UNO_QUERY ); + if( xTextCursor.is() ) + { + Reference< XTextRange > xStart( xTextCursor->getStart() ), xRange; + Reference< XShape > xShape( xTextCursor->getText(), UNO_QUERY_THROW ); + Reference< XTextRangeCompare > xTextRangeCompare( xShape, UNO_QUERY_THROW ); + + Reference< XEnumerationAccess > xParaEnumAccess( xShape, UNO_QUERY_THROW ); + Reference< XEnumeration > xEnumeration( xParaEnumAccess->createEnumeration(), UNO_QUERY_THROW ); + sal_Int16 nParagraph = 0; + + while( xEnumeration->hasMoreElements() ) + { + xEnumeration->nextElement() >>= xRange; + + // break if start of selection is prior to end of current paragraph + if( xRange.is() && (xTextRangeCompare->compareRegionEnds( xStart, xRange ) >= 0 ) ) + { + return makeAny( ParagraphTarget( xShape, nParagraph ) ); + } + + nParagraph++; + } + } + } + catch( RuntimeException& ) + { + DBG_ERROR( "xmloff::AnimationsImportImpl::convertTarget(), RuntimeException catched!" ); + } + + Any aAny; + return aAny; +} + +Any AnimationsImportHelperImpl::convertValue( XMLTokenEnum eAttributeName, const OUString& rValue ) +{ + sal_Int32 nCommaPos = -1, nPos; + sal_Int32 nOpenBrakets = 0; + for( nPos = 0; (nPos < rValue.getLength()) && (nCommaPos == -1); nPos++ ) + { + switch( rValue[nPos] ) + { + case ',': + if( nOpenBrakets == 0 ) + nCommaPos = nPos; + break; + case '(': + case '[': + case '{': + nOpenBrakets++; + break; + case ')': + case ']': + case '}': + nOpenBrakets--; + break; + } + } + + if( nCommaPos >= 0 ) + { + ValuePair aPair; + aPair.First = convertValue( eAttributeName, rValue.copy( 0, nCommaPos ) ); + aPair.Second = convertValue( eAttributeName, rValue.copy( nCommaPos+1, rValue.getLength() - nCommaPos - 1 ) ); + return makeAny( aPair ); + } + else + { + Any aAny; + sal_Int32 nType = XML_TYPE_STRING; + + if( rValue.getLength() ) switch( eAttributeName ) + { + case XML_X: + case XML_Y: + case XML_WIDTH: + case XML_HEIGHT: + case XML_TRANSLATE: + { + return makeAny( rValue ); + } + + case XML_SCALE: + case XML_SKEWY: + case XML_SKEWX: + case XML_OPACITY: + case XML_ROTATE: nType = XML_TYPE_DOUBLE; break; + case XML_TEXT_ROTATION_ANGLE:nType = XML_TYPE_TEXT_ROTATION_ANGLE; break; + case XML_FILL_COLOR: + case XML_STROKE_COLOR: + case XML_DIM: + case XML_COLOR: nType = XML_TYPE_COLOR; break; + case XML_FILL: nType = XML_SD_TYPE_FILLSTYLE; break; + case XML_STROKE: nType = XML_SD_TYPE_STROKE; break; + case XML_FONT_WEIGHT: nType = XML_TYPE_TEXT_WEIGHT; break; + case XML_FONT_STYLE: nType = XML_TYPE_TEXT_POSTURE; break; + case XML_TEXT_UNDERLINE: nType = XML_TYPE_TEXT_UNDERLINE_STYLE; break; + case XML_FONT_SIZE: nType = XML_TYPE_DOUBLE_PERCENT; break; + case XML_VISIBILITY: nType = XML_SD_TYPE_PRESPAGE_VISIBILITY; break; + + default: + if( rValue.getLength() ) + aAny <<= rValue; + return aAny; + } + + const XMLPropertyHandler* pHandler = mrImport.GetShapeImport()->GetSdPropHdlFactory()->GetPropertyHandler( nType ); + if( pHandler ) + pHandler->importXML( rValue, aAny, mrImport.GetMM100UnitConverter() ); + + return aAny; + +/* + if( rValue.getLength() == 0 ) + { + Any aAny; + return aAny; + } + else if( rValue.indexOf( '#' ) == 0 ) + { + // color + Color aColor; + SvXMLUnitConverter::convertColor( aColor, rValue ); + + return makeAny( static_cast< sal_Int32 >( aColor.GetRGBColor() ) ); + } + else if( rValue.indexOf( '$' ) != -1 ) + { + // formula + return makeAny( rValue ); + } + else + { + if( isDouble( rValue ) ) + { + return makeAny( rValue.toDouble() ); + } + else + { + return makeAny( rValue ); + } + } +*/ + } +} + +Sequence< Any > AnimationsImportHelperImpl::convertValueSequence( XMLTokenEnum eAttributeName, const OUString& rValue ) +{ + Sequence< Any > aValues; + + // do we have any value at all? + if( rValue.getLength() ) + { + sal_Int32 nElements = count_codes( rValue, (sal_Unicode)';') + 1; // a non empty string has at least one value + + // prepare the sequence + aValues.realloc( nElements ); + + // fill the sequence + Any* pValues = aValues.getArray(); + sal_Int32 nIndex, nElement; + for( nIndex = 0, nElement = 0; nElements && (nIndex >= 0); nElements-- ) + { + *pValues++ = convertValue( eAttributeName, rValue.getToken( 0, ';', nIndex ) ); + } + } + + return aValues; +} + +Any AnimationsImportHelperImpl::convertTiming( const OUString& rValue ) +{ + Any aAny; + + // do we have any value at all? + if( rValue.getLength() ) + { + // count the values + sal_Int32 nElements = count_codes( rValue, (sal_Unicode)';' ) + 1; // a non empty string has at least one value + + if( nElements == 1 ) + { + if( IsXMLToken( rValue, XML_MEDIA ) ) + { + aAny <<= Timing_MEDIA; + } + else if( IsXMLToken( rValue, XML_INDEFINITE ) ) + { + aAny <<= Timing_INDEFINITE; + } + else if( isTime( rValue ) ) + { + aAny <<= rValue.toDouble(); + } + else + { + Event aEvent; + aEvent.Repeat = 0; + aEvent.Trigger = 0; + + OUString aEventTrigger; + + sal_Int32 nPos = rValue.indexOf( (sal_Unicode)'+' ); + if( nPos == -1 ) + { + aEventTrigger = rValue; + } + else + { + aEventTrigger = rValue.copy( 0, nPos ); + + // convert offset + aEvent.Offset <<= convertTiming( rValue.copy( nPos + 1 ) ); + } + + nPos = aEventTrigger.indexOf( (sal_Unicode)'.' ); + if( nPos != -1 ) + { + aEvent.Source <<= mrImport.getInterfaceToIdentifierMapper().getReference( aEventTrigger.copy( 0, nPos ) ); + aEventTrigger = aEventTrigger.copy( nPos + 1 ); + } + + sal_uInt16 nEnum; + if( SvXMLUnitConverter::convertEnum( nEnum, aEventTrigger, getAnimationsEnumMap(Animations_EnumMap_EventTrigger) ) ) + { + aEvent.Trigger = (sal_Int16)nEnum; + } + else + { + DBG_ERROR("AnimationsImportHelperImpl::convertTiming(), unknown event trigger!"); + } + + aAny <<= aEvent; + } + } + else + { + // fill the sequence + Sequence< Any > aValues( nElements ); + Any* pValues = aValues.getArray(); + sal_Int32 nIndex = 0; + while( (nElements--) && (nIndex >= 0) ) + *pValues++ = convertTiming( rValue.getToken( 0, ';', nIndex ) ); + + aAny <<= aValues; + } + } + return aAny; +} + +Sequence< double > AnimationsImportHelperImpl::convertKeyTimes( const OUString& rValue ) +{ + sal_Int32 nElements = 0; + + if( rValue.getLength() ) + nElements = count_codes( rValue, (sal_Unicode)';' ) + 1; // a non empty string has at least one value + + Sequence< double > aKeyTimes( nElements ); + + if( nElements ) + { + double* pValues = aKeyTimes.getArray(); + sal_Int32 nIndex = 0; + while( (nElements--) && (nIndex >= 0) ) + *pValues++ = rValue.getToken( 0, ';', nIndex ).toDouble(); + } + + return aKeyTimes; +} + +Sequence< TimeFilterPair > AnimationsImportHelperImpl::convertTimeFilter( const OUString& rValue ) +{ + sal_Int32 nElements = 0; + + if( rValue.getLength() ) + nElements = count_codes( rValue, (sal_Unicode)';' ) + 1; // a non empty string has at least one value + + Sequence< TimeFilterPair > aTimeFilter( nElements ); + + if( nElements ) + { + TimeFilterPair* pValues = aTimeFilter.getArray(); + sal_Int32 nIndex = 0; + while( (nElements--) && (nIndex >= 0) ) + { + const OUString aToken( rValue.getToken( 0, ';', nIndex ) ); + + sal_Int32 nPos = aToken.indexOf( ',' ); + if( nPos >= 0 ) + { + pValues->Time = aToken.copy( 0, nPos ).toDouble(); + pValues->Progress = aToken.copy( nPos+1, aToken.getLength() - nPos - 1 ).toDouble(); + } + pValues++; + } + } + + return aTimeFilter; +} + +Any AnimationsImportHelperImpl::convertPath( const OUString& rValue ) +{ + return makeAny( rValue ); +} + +/////////////////////////////////////////////////////////////////////// + +TYPEINIT1( AnimationNodeContext, SvXMLImportContext ); + +AnimationNodeContext::AnimationNodeContext( + const Reference< XAnimationNode >& xParentNode, + SvXMLImport& rImport, sal_uInt16 nPrfx, const rtl::OUString& rLocalName, + const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList, + AnimationsImportHelperImpl* pHelper /* = NULL */ ) +: SvXMLImportContext(rImport, nPrfx, rLocalName), + mpHelper( pHelper ), + mbRootContext( pHelper == NULL ) +{ + try + { + if( mbRootContext ) + { + mpHelper = new AnimationsImportHelperImpl( rImport ); + mxNode = xParentNode; + } + else + { + Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() ); + + sal_Int16 nPresetClass = EffectPresetClass::CUSTOM; + + const sal_Char* pServiceName = 0; + + sal_Int16 nNodeType = (sal_Int16)mpHelper->getAnimationNodeTokenMap().Get( nPrfx, rLocalName ); + switch( nNodeType ) + { + case AnimationNodeType::SEQ: pServiceName = "com.sun.star.animations.SequenceTimeContainer"; break; + case AnimationNodeType::ITERATE: pServiceName = "com.sun.star.animations.IterateContainer"; break; + case AnimationNodeType::ANIMATE: pServiceName = "com.sun.star.animations.Animate"; break; + case AnimationNodeType::SET: pServiceName = "com.sun.star.animations.AnimateSet"; break; + case AnimationNodeType::ANIMATEMOTION: pServiceName = "com.sun.star.animations.AnimateMotion"; break; + case AnimationNodeType::ANIMATECOLOR: pServiceName = "com.sun.star.animations.AnimateColor"; break; + case AnimationNodeType::ANIMATETRANSFORM: pServiceName = "com.sun.star.animations.AnimateTransform"; break; + case AnimationNodeType::TRANSITIONFILTER: pServiceName = "com.sun.star.animations.TransitionFilter"; break; + case AnimationNodeType::AUDIO: pServiceName = "com.sun.star.animations.Audio"; break; + case AnimationNodeType::COMMAND: pServiceName = "com.sun.star.animations.Command"; break; + case AnimationNodeType::PAR: + { + const sal_Int16 nCount = xAttrList.is() ? xAttrList->getLength() : 0; + sal_Int16 nAttribute; + for( nAttribute = 0; nAttribute < nCount; nAttribute++ ) + { + OUString aLocalName; + sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( nAttribute ), &aLocalName ); + if( (nPrefix == XML_NAMESPACE_PRESENTATION) && IsXMLToken( aLocalName, XML_PRESET_ID ) ) + { + const OUString& rValue = xAttrList->getValueByIndex( nAttribute ); + if( rValue.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ooo-entrance-random" ) ) ) + { + nPresetClass = EffectPresetClass::ENTRANCE; + } + else if( rValue.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ooo-exit-random" ) ) ) + { + nPresetClass = EffectPresetClass::EXIT; + } + + if( nPresetClass != EffectPresetClass::CUSTOM ) + { + pServiceName = "com.sun.star.comp.sd.RandomAnimationNode"; + break; + } + } + } + if( !pServiceName ) + pServiceName = "com.sun.star.animations.ParallelTimeContainer"; + } + break; + default: + pServiceName = 0; + } + + if( pServiceName && xFactory.is() ) + { + mxNode = Reference< XAnimationNode >( xFactory->createInstance( + OUString::createFromAscii(pServiceName) ), UNO_QUERY_THROW ); + + if( nPresetClass != EffectPresetClass::CUSTOM ) + { + Reference< XInitialization > xInit( mxNode, UNO_QUERY_THROW ); + const Any aAny( makeAny( nPresetClass ) ); + Sequence< Any > aArgs( &aAny, 1 ) ; + xInit->initialize( aArgs ); + } + + init_node( xAttrList ); + + Reference< XTimeContainer > xParentContainer( xParentNode, UNO_QUERY_THROW ); + xParentContainer->appendChild( mxNode ); + } + } + } + catch( RuntimeException& ) + { + DBG_ERROR( "xmloff::AnimationsImportImpl::AnimationsImportImpl(), RuntimeException catched!" ); + } +} + +AnimationNodeContext::~AnimationNodeContext() +{ + if( mbRootContext ) + delete mpHelper; +} + +void AnimationNodeContext::StartElement( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& ) +{ + // code of StartElement is moved to init_node that is now called + // in c'tor before appending this node to its parent. + // This is needed for random nodes that need the correct target + // set when child nodes are appended. +} + +void AnimationNodeContext::init_node( const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList >& xAttrList ) +{ + if( mxNode.is() ) try + { + const sal_Int16 nNodeType = mxNode->getType(); + + // query for optional interfaces that are often used later + Reference< XAnimate > xAnimate( mxNode, UNO_QUERY ); + Reference< XCommand > xCommand( mxNode, UNO_QUERY ); + Reference< XTransitionFilter > xTransitionFilter( mxNode, UNO_QUERY ); + Reference< XIterateContainer > xIter( mxNode, UNO_QUERY ); + + std::list< NamedValue > aUserData; + XMLTokenEnum meAttributeName = XML_TOKEN_INVALID; + OUString aFrom, aBy, aTo, aValues; + bool bHaveXmlId( false ); + OUString sXmlId; + + const sal_Int16 nCount = xAttrList.is() ? xAttrList->getLength() : 0; + sal_uInt16 nEnum; + sal_Int16 nAttribute; + for( nAttribute = 0; nAttribute < nCount; nAttribute++ ) + { + const OUString& rAttrName = xAttrList->getNameByIndex( nAttribute ); + const OUString& rValue = xAttrList->getValueByIndex( nAttribute ); + + OUString aLocalName; + sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName ); + switch( mpHelper->getAnimationNodeAttributeTokenMap().Get( nPrefix, aLocalName ) ) + { + case ANA_Begin: + { + mxNode->setBegin( mpHelper->convertTiming( rValue ) ); + } + break; + case ANA_Dur: + { + mxNode->setDuration( mpHelper->convertTiming( rValue ) ); + } + break; + case ANA_End: + { + mxNode->setEnd( mpHelper->convertTiming( rValue ) ); + } + break; + case ANA_Fill: + { + if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_Fill) ) ) + mxNode->setFill( (sal_Int16)nEnum ); + } + break; + case ANA_FillDefault: + { + if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_FillDefault) ) ) + mxNode->setFillDefault( (sal_Int16)nEnum ); + } + break; + case ANA_Restart: + { + if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_Restart) ) ) + mxNode->setRestart( (sal_Int16)nEnum ); + } + break; + case ANA_RestartDefault: + { + if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_RestartDefault) ) ) + mxNode->setRestartDefault( (sal_Int16)nEnum ); + } + break; + case ANA_Accelerate: + { + if( isDouble( rValue ) ) + mxNode->setAcceleration( rValue.toDouble() ); + } + break; + case ANA_Decelerate: + { + if( isDouble( rValue ) ) + mxNode->setDecelerate( rValue.toDouble() ); + } + break; + case ANA_AutoReverse: + { + sal_Bool bTemp; + if( SvXMLUnitConverter::convertBool( bTemp, rValue ) ) + mxNode->setAutoReverse( bTemp ); + } + break; + case ANA_RepeatCount: + { + mxNode->setRepeatCount( mpHelper->convertTiming( rValue ) ); + } + break; + case ANA_RepeatDur: + { + mxNode->setRepeatDuration( mpHelper->convertTiming( rValue ) ); + } + break; + case ANA_EndSync: + { + if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_Endsync) ) ) + mxNode->setEndSync( makeAny( (sal_Int16)nEnum ) ); + } + break; + case ANA_Node_Type: + { + if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_EffectNodeType) ) ) + aUserData.push_back( NamedValue( GetXMLToken( XML_NODE_TYPE ), makeAny( (sal_Int16)nEnum ) ) ); + } + break; + case ANA_Preset_ID: + { + aUserData.push_back( NamedValue( GetXMLToken( XML_PRESET_ID ), makeAny( rValue ) ) ); + } + break; + case ANA_Preset_Sub_Type: + { + aUserData.push_back( NamedValue( GetXMLToken( XML_PRESET_SUB_TYPE ), makeAny( rValue ) ) ); + } + break; + case ANA_Preset_Class: + { + if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_EffectPresetClass) ) ) + aUserData.push_back( NamedValue( GetXMLToken( XML_PRESET_CLASS ), makeAny( (sal_Int16)nEnum ) ) ); + } + break; + case ANA_After_Effect: + { + sal_Bool bTemp; + if( SvXMLUnitConverter::convertBool( bTemp, rValue ) ) + aUserData.push_back( NamedValue( GetXMLToken( XML_AFTER_EFFECT ), makeAny( bTemp ) ) ); + } + break; + case ANA_XLink: + { + if( nNodeType == AnimationNodeType::AUDIO ) + { + Reference< XAudio > xAudio( mxNode, UNO_QUERY_THROW ); + xAudio->setSource( makeAny( GetImport().GetAbsoluteReference( rValue ) ) ); + break; + } + + } + // fall through intented! + case ANA_Target: + { + { + Any aTarget( mpHelper->convertTarget( rValue ) ); + + if( xAnimate.is() ) + { + xAnimate->setTarget( aTarget ); + } + else if( xIter.is() ) + { + xIter->setTarget( aTarget ); + } + else if( xCommand.is() ) + { + xCommand->setTarget( aTarget ); + } + } + } + break; + + case ANA_Volume: + { + if( nNodeType == AnimationNodeType::AUDIO ) + { + if( isDouble( rValue ) ) + { + Reference< XAudio > xAudio( mxNode, UNO_QUERY_THROW ); + xAudio->setVolume( rValue.toDouble() ); + } + } + } + break; + + case ANA_MasterElement: + { + Reference< XAnimationNode > xMaster( GetImport().getInterfaceToIdentifierMapper().getReference( rValue ), UNO_QUERY ); + aUserData.push_back( NamedValue( GetXMLToken( XML_MASTER_ELEMENT ), makeAny( xMaster ) ) ); + } + break; + + case ANA_SubItem: + { + if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_SubItem) ) ) + { + if( xAnimate.is() ) + { + xAnimate->setSubItem( (sal_Int16)nEnum ); + } + else if( xIter.is() ) + { + xIter->setSubItem( (sal_Int16)nEnum ); + } + } + } + break; + + case ANA_AttributeName: + { + if( xAnimate.is() ) + { + OUString aName( rValue ); + + ImplAttributeNameConversion* p = getAnimationAttributeNamesConversionList(); + while( p->mpAPIName ) + { + if( IsXMLToken( aName, p->meXMLToken ) ) + { + aName = OUString::createFromAscii( p->mpAPIName ); + meAttributeName = p->meXMLToken; + break; + } + + p++; + } + + xAnimate->setAttributeName( aName ); + } + } + break; + + case ANA_Values: + { + aValues = rValue; + } + break; + + case ANA_From: + { + aFrom = rValue; + } + break; + + case ANA_By: + { + aBy = rValue; + } + break; + + case ANA_To: + { + aTo = rValue; + } + break; + + case ANA_KeyTimes: + { + if( xAnimate.is() ) + xAnimate->setKeyTimes( mpHelper->convertKeyTimes( rValue ) ); + } + break; + + case ANA_Formula: + { + if( xAnimate.is() ) + xAnimate->setFormula( rValue ); + } + break; + + case ANA_ANIMID: + { + if (!bHaveXmlId) { sXmlId = rValue; } + } + break; + case ANA_XMLID: + { + sXmlId = rValue; + bHaveXmlId = true; + } + break; + + case ANA_CalcMode: + { + if( xAnimate.is() ) + { + if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_CalcMode) ) ) + xAnimate->setCalcMode( (sal_Int16)nEnum ); + } + } + break; + + case ANA_Accumulate: + { + if( xAnimate.is() ) + xAnimate->setAccumulate( IsXMLToken( rValue, XML_SUM ) ); + } + break; + + case ANA_AdditiveMode: + { + if( xAnimate.is() ) + { + if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_AdditiveMode) ) ) + xAnimate->setAdditive( (sal_Int16)nEnum ); + } + } + break; + + case ANA_KeySplines: + { + if( xAnimate.is() ) + xAnimate->setTimeFilter( mpHelper->convertTimeFilter( rValue ) ); + } + break; + + case ANA_Path: + { + Reference< XAnimateMotion > xAnimateMotion( mxNode, UNO_QUERY ); + if( xAnimateMotion.is() ) + xAnimateMotion->setPath( mpHelper->convertPath( rValue ) ); + } + break; + + case ANA_ColorSpace: + { + Reference< XAnimateColor > xAnimateColor( mxNode, UNO_QUERY ); + if( xAnimateColor.is() ) + xAnimateColor->setColorInterpolation( IsXMLToken( rValue, XML_HSL ) ? AnimationColorSpace::HSL : AnimationColorSpace::RGB ); + } + break; + + case ANA_ColorDirection: + { + Reference< XAnimateColor > xAnimateColor( mxNode, UNO_QUERY ); + if( xAnimateColor.is() ) + xAnimateColor->setDirection( IsXMLToken( rValue, XML_CLOCKWISE ) ); + } + break; + + case ANA_TransformType: + { + Reference< XAnimateTransform > xTransform( mxNode, UNO_QUERY ); + if( xTransform.is() ) + { + if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_TransformType) ) ) + { + xTransform->setTransformType( (sal_Int16)nEnum ); + switch( nEnum ) + { + case AnimationTransformType::SCALE: meAttributeName = XML_SCALE; break; + case AnimationTransformType::ROTATE: meAttributeName = XML_ROTATE; break; + case AnimationTransformType::SKEWX: meAttributeName = XML_SKEWX; break; + case AnimationTransformType::SKEWY: meAttributeName = XML_SKEWY; break; + //case AnimationTransformType::TRANSLATE: + default: + meAttributeName = XML_TRANSLATE; break; + } + } + } + } + break; + + case ANA_TransitionType: + { + if( xTransitionFilter.is() ) + { + if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_TransitionType) ) ) + xTransitionFilter->setTransition( (sal_Int16)nEnum ); + } + } + break; + + case ANA_TransitionSubType: + { + if( xTransitionFilter.is() ) + { + if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_TransitionSubType) ) ) + xTransitionFilter->setSubtype( (sal_Int16)nEnum ); + } + } + break; + + case ANA_Mode: + { + if( xTransitionFilter.is() ) + xTransitionFilter->setMode( IsXMLToken( rValue, XML_IN ) ); + } + break; + + case ANA_Direction: + { + if( xTransitionFilter.is() ) + xTransitionFilter->setDirection( IsXMLToken( rValue, XML_FORWARD ) ); + } + break; + + case ANA_FadeColor: + { + if( xTransitionFilter.is() ) + { + Color aColor; + SvXMLUnitConverter::convertColor( aColor, rValue ); + xTransitionFilter->setFadeColor( static_cast< sal_Int32 >( aColor.GetRGBColor() ) ); + } + } + break; + + case ANA_IterateType: + { + if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_IterateType) ) ) + { + if( xIter.is() ) + xIter->setIterateType( (sal_Int16)nEnum ); + } + } + break; + + case ANA_IterateInterval: + { + if( xIter.is() ) + { + double fInterval = 0.0; + if( rValue.matchAsciiL(RTL_CONSTASCII_STRINGPARAM("P")) ) + { + ::Time aTime; + sal_Int32 nSecondsFraction = 0; + if( SvXMLUnitConverter::convertTimeDuration( rValue, aTime, &nSecondsFraction ) ) + { + fInterval = ((((aTime.GetHour() * 60) + aTime.GetMin()) * 60) + aTime.GetSec()) + (nSecondsFraction / 1000.0); + } + } + else + { + fInterval = rValue.toDouble(); + } + + xIter->setIterateInterval( fInterval ); + } + } + break; + + case ANA_Group_Id: + { + aUserData.push_back( NamedValue( aLocalName, makeAny( rValue.toInt32() ) ) ); + } + break; + + case ANA_Command: + { + if( xCommand.is() && nNodeType == AnimationNodeType::COMMAND ) + { + if( SvXMLUnitConverter::convertEnum( nEnum, rValue, getAnimationsEnumMap(Animations_EnumMap_Command) ) ) + { + xCommand->setCommand( (sal_Int16)nEnum ); + } + } + } + break; + + default: + // push all unknown attributes within the presentation namespace as user data + if( nPrefix == XML_NAMESPACE_PRESENTATION ) + { + aUserData.push_back( NamedValue( aLocalName, makeAny( rValue ) ) ); + } + } + } + + if (sXmlId.getLength()) + { + Reference< XInterface > const xRef( mxNode, UNO_QUERY ); + GetImport().getInterfaceToIdentifierMapper().registerReference( + sXmlId, xRef ); + } + + sal_Int32 nUserDataCount = aUserData.size(); + if( nUserDataCount ) + { + Sequence< NamedValue > aUnoUserData( nUserDataCount ); + NamedValue* pData = aUnoUserData.getArray(); + std::list< NamedValue >::iterator aIter( aUserData.begin() ); + const std::list< NamedValue >::iterator aEnd( aUserData.end() ); + while( aIter != aEnd ) + *pData++ = (*aIter++); + + mxNode->setUserData( aUnoUserData ); + } + + // convert values + if( xAnimate.is() ) + { + if( aFrom.getLength() ) + xAnimate->setFrom( mpHelper->convertValue( meAttributeName, aFrom ) ); + + if( aBy.getLength() ) + xAnimate->setBy( mpHelper->convertValue( meAttributeName, aBy ) ); + + if( aTo.getLength() ) + xAnimate->setTo( mpHelper->convertValue( meAttributeName, aTo ) ); + + if( aValues.getLength() ) + xAnimate->setValues( mpHelper->convertValueSequence( meAttributeName, aValues ) ); + } + } + catch( RuntimeException& ) + { + DBG_ERROR( "xmloff::AnimationNodeContext::StartElement(), RuntimeException catched!" ); + } +} + +SvXMLImportContext * AnimationNodeContext::CreateChildContext( USHORT nPrefix, const ::rtl::OUString& rLocalName, + const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList ) +{ + if( mxNode.is()) + return new AnimationNodeContext( mxNode, GetImport(), nPrefix, rLocalName, xAttrList, mpHelper ); + else + return new SvXMLImportContext( GetImport(), nPrefix, rLocalName ); +} + +// -------------------------------------------------------------------- + +class AnimationsImport: public SvXMLImport, public XAnimationNodeSupplier +{ +public: + AnimationsImport( const Reference< XMultiServiceFactory > & rSMgr ); + ~AnimationsImport() throw (); + + SvXMLImportContext* CreateContext(USHORT nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& xAttrList); + + // XInterface + virtual Any SAL_CALL queryInterface( const Type& aType ) throw (RuntimeException); + virtual void SAL_CALL acquire() throw (); + virtual void SAL_CALL release() throw (); + + // XAnimationNodeSupplier + Reference< XAnimationNode > SAL_CALL getAnimationNode() throw (RuntimeException); + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() throw(RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException); + virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(RuntimeException); + +private: + Reference< XAnimationNode > mxRootNode; +}; + +AnimationsImport::AnimationsImport( const Reference< XMultiServiceFactory > & rSMgr ) +: SvXMLImport( rSMgr, true ) +{ + // add namespaces + GetNamespaceMap().Add( + GetXMLToken(XML_NP_PRESENTATION), + GetXMLToken(XML_N_PRESENTATION), + XML_NAMESPACE_PRESENTATION); + + GetNamespaceMap().Add( + GetXMLToken(XML_NP_SMIL), + GetXMLToken(XML_N_SMIL), + XML_NAMESPACE_SMIL); + + GetNamespaceMap().Add( + GetXMLToken(XML_NP_ANIMATION), + GetXMLToken(XML_N_ANIMATION), + XML_NAMESPACE_ANIMATION); + + mxRootNode = Reference< XAnimationNode >::query(rSMgr->createInstance( + OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.animations.SequenceTimeContainer")))); +} + +AnimationsImport::~AnimationsImport() throw () +{ +} + +// XInterface +Any SAL_CALL AnimationsImport::queryInterface( const Type& aType ) throw (RuntimeException) +{ + if ( aType == ::getCppuType((Reference<XAnimationNodeSupplier> *)0) ) + { + return makeAny( Reference<XAnimationNodeSupplier>( this ) ); + } + else + { + return SvXMLImport::queryInterface( aType ); + } +} + +void SAL_CALL AnimationsImport::acquire() throw () +{ + SvXMLImport::acquire(); +} + +void SAL_CALL AnimationsImport::release() throw () +{ + SvXMLImport::release(); +} + +SvXMLImportContext *AnimationsImport::CreateContext(USHORT nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& xAttrList) +{ + SvXMLImportContext* pContext = 0; + + if( (XML_NAMESPACE_ANIMATION == nPrefix) && IsXMLToken( rLocalName, XML_SEQ ) ) + { + pContext = new AnimationNodeContext( mxRootNode, *this, nPrefix, rLocalName, xAttrList ); + } + else + { + pContext = SvXMLImport::CreateContext(nPrefix, rLocalName, xAttrList); + } + + return pContext; +} + +// XAnimationNodeSupplier +Reference< XAnimationNode > SAL_CALL AnimationsImport::getAnimationNode() throw (RuntimeException) +{ + return mxRootNode; +} + +void AnimationNodeContext::postProcessRootNode( SvXMLImport& /*rImport*/, const Reference< XAnimationNode >& xRootNode, Reference< XPropertySet >& xPageProps ) +{ + if( xRootNode.is() && xPageProps.is() ) try + { + Reference< XEnumerationAccess > xEnumerationAccess( xRootNode, UNO_QUERY_THROW ); + Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW ); + if( xEnumeration->hasMoreElements() ) + { + Reference< XAnimationNode > xNode( xEnumeration->nextElement(), UNO_QUERY_THROW ); + if( xNode->getType() == AnimationNodeType::PAR ) + { + Event aEvent; + if( (xNode->getBegin() >>= aEvent) && (aEvent.Trigger == EventTrigger::BEGIN_EVENT) ) + { + // found transition node + Reference< XEnumerationAccess > xChildEnumerationAccess( xNode, UNO_QUERY_THROW ); + Reference< XEnumeration > xChildEnumeration( xChildEnumerationAccess->createEnumeration(), UNO_QUERY_THROW ); + while( xChildEnumeration->hasMoreElements() ) + { + Reference< XAnimationNode > xChildNode( xChildEnumeration->nextElement(), UNO_QUERY_THROW ); + switch( xChildNode->getType() ) + { + case AnimationNodeType::TRANSITIONFILTER: + { + Reference< XTransitionFilter > xTransFilter( xChildNode, UNO_QUERY_THROW ); + + + xPageProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "TransitionType" ) ), Any( xTransFilter->getTransition() ) ); + xPageProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "TransitionSubtype" ) ), Any( xTransFilter->getSubtype() ) ); + xPageProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "TransitionDirection" ) ), Any( xTransFilter->getDirection() ) ); + xPageProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "TransitionFadeColor" ) ), Any( xTransFilter->getFadeColor() ) ); + + double fDuration; + if( xTransFilter->getDuration() >>= fDuration ) + xPageProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "TransitionDuration" ) ), Any( fDuration ) ); + + } + break; + + case AnimationNodeType::COMMAND: + { + Reference< XCommand > xCommand( xChildNode, UNO_QUERY_THROW ); + if( xCommand->getCommand() == EffectCommands::STOPAUDIO ) + { + xPageProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Sound" ) ), Any(sal_True) ); + } + } + break; + + case AnimationNodeType::AUDIO: + { + Reference< XAudio > xAudio( xChildNode, UNO_QUERY_THROW ); + OUString sSoundURL; + if( (xAudio->getSource() >>= sSoundURL) && (sSoundURL.getLength() != 0) ) + { + xPageProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Sound" ) ), Any(sSoundURL) ); + + Timing eTiming; + if( (xAudio->getRepeatCount() >>= eTiming) && (eTiming == Timing_INDEFINITE) ) + xPageProps->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "LoopSound" ) ), Any( sal_True ) ); + } + } + break; + + } + } + + Reference< XTimeContainer > xRootContainer( xRootNode, UNO_QUERY_THROW ); + xRootContainer->removeChild( xNode ); + } + } + } + } + catch( Exception& ) + { + DBG_ERROR("xmloff::AnimationsImport::postProcessRootNode(), exception caught!"); + } +} + +} // namespace xmloff + +Sequence< OUString > SAL_CALL AnimationsImport_getSupportedServiceNames() throw() +{ + const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Xmloff.AnimationsImport" ) ); + const Sequence< OUString > aSeq( &aServiceName, 1 ); + return aSeq; +} + +OUString SAL_CALL AnimationsImport_getImplementationName() throw() +{ + return OUString( RTL_CONSTASCII_USTRINGPARAM( "xmloff::AnimationsImport" ) ); +} + +Reference< XInterface > SAL_CALL AnimationsImport_createInstance(const Reference< XMultiServiceFactory > & rSMgr) throw( Exception ) +{ + return (cppu::OWeakObject*)new xmloff::AnimationsImport( rSMgr ); + +} + +namespace xmloff +{ + +OUString SAL_CALL AnimationsImport::getImplementationName() throw(RuntimeException) +{ + return AnimationsImport_getImplementationName(); +} + +sal_Bool SAL_CALL AnimationsImport::supportsService( const OUString& ServiceName ) throw(RuntimeException) +{ + return ServiceName.equalsAscii( "com.sun.star.comp.Xmloff.AnimationsImport" ); +} + +Sequence< OUString > SAL_CALL AnimationsImport::getSupportedServiceNames() throw(RuntimeException) +{ + return AnimationsImport_getSupportedServiceNames(); +} + +} // namespace xmloff + |