| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sd.hxx" |
| #include <com/sun/star/animations/XAnimationNode.hpp> |
| #include <com/sun/star/animations/Event.hpp> |
| #ifndef _COM_SUN_STAR_ANIMATIONS_XAnimateColor_HPP_ |
| #include <com/sun/star/animations/XAnimateColor.hpp> |
| #endif |
| #ifndef _COM_SUN_STAR_ANIMATIONS_XAnimateSet_HPP_ |
| #include <com/sun/star/animations/XAnimateSet.hpp> |
| #endif |
| #include <com/sun/star/animations/XCommand.hpp> |
| #ifndef _COM_SUN_STAR_ANIMATIONS_XAnimateMotion_HPP_ |
| #include <com/sun/star/animations/XAnimateMotion.hpp> |
| #endif |
| #ifndef _COM_SUN_STAR_ANIMATIONS_XAnimateTransform_HPP_ |
| #include <com/sun/star/animations/XAnimateTransform.hpp> |
| #endif |
| #ifndef _COM_SUN_STAR_ANIMATIONS_XTransitionFilter_HPP_ |
| #include <com/sun/star/animations/XTransitionFilter.hpp> |
| #endif |
| #include <com/sun/star/animations/XIterateContainer.hpp> |
| #include <com/sun/star/animations/XAudio.hpp> |
| #include <com/sun/star/animations/AnimationNodeType.hpp> |
| #include <com/sun/star/animations/ValuePair.hpp> |
| #include <com/sun/star/presentation/EffectNodeType.hpp> |
| #include <com/sun/star/util/XCloneable.hpp> |
| #include <com/sun/star/presentation/ParagraphTarget.hpp> |
| #include <com/sun/star/container/XEnumerationAccess.hpp> |
| #include <com/sun/star/beans/NamedValue.hpp> |
| |
| #include <map> |
| |
| #include "comphelper/anytostring.hxx" |
| #include "cppuhelper/exc_hlp.hxx" |
| #include "rtl/ref.hxx" |
| #include <animations/animationnodehelper.hxx> |
| |
| // header for class SdrObjListIter |
| #include <svx/svditer.hxx> |
| |
| #include "sdpage.hxx" |
| |
| using namespace ::com::sun::star::uno; |
| using namespace ::com::sun::star::animations; |
| using namespace ::com::sun::star::presentation; |
| using namespace ::com::sun::star::container; |
| |
| using ::rtl::OUString; |
| using ::rtl::OString; |
| using ::com::sun::star::drawing::XShape; |
| using ::com::sun::star::beans::NamedValue; |
| |
| namespace sd |
| { |
| class CustomAnimationClonerImpl |
| { |
| public: |
| CustomAnimationClonerImpl(); |
| Reference< XAnimationNode > Clone( const Reference< XAnimationNode >& xSourceNode, const SdPage* pSource = 0, const SdPage* pTarget = 0 ); |
| |
| private: |
| void transformNode( const Reference< XAnimationNode >& xNode ); |
| Any transformValue( const Any& rValue ); |
| |
| Reference< XShape > getClonedShape( const Reference< XShape >& xSource ) const; |
| Reference< XAnimationNode > getClonedNode( const Reference< XAnimationNode >& xSource ) const; |
| |
| mutable ::std::map< Reference< XShape >, Reference< XShape > > maShapeMap; |
| std::vector< Reference< XAnimationNode > > maSourceNodeVector; |
| std::vector< Reference< XAnimationNode > > maCloneNodeVector; |
| }; |
| |
| CustomAnimationClonerImpl::CustomAnimationClonerImpl() |
| { |
| } |
| |
| Reference< XAnimationNode > Clone( const Reference< XAnimationNode >& xSourceNode, const SdPage* pSource, const SdPage* pTarget ) |
| { |
| CustomAnimationClonerImpl aCloner; |
| return aCloner.Clone( xSourceNode, pSource, pTarget ); |
| } |
| |
| Reference< XAnimationNode > CustomAnimationClonerImpl::Clone( const Reference< XAnimationNode >& xSourceNode, const SdPage* pSourcePage, const SdPage* pTargetPage ) |
| { |
| try |
| { |
| // clone animation hierarchie |
| Reference< ::com::sun::star::util::XCloneable > xClonable( xSourceNode, UNO_QUERY_THROW ); |
| Reference< XAnimationNode > xCloneNode( xClonable->createClone(), UNO_QUERY_THROW ); |
| |
| // create a dictionary to map source to cloned shapes |
| if( pSourcePage && pTargetPage ) |
| { |
| SdrObjListIter aSourceIter( *pSourcePage, IM_DEEPWITHGROUPS ); |
| SdrObjListIter aTargetIter( *pTargetPage, IM_DEEPWITHGROUPS ); |
| |
| while( aSourceIter.IsMore() && aTargetIter.IsMore() ) |
| { |
| SdrObject* pSource = aSourceIter.Next(); |
| SdrObject* pTarget = aTargetIter.Next(); |
| |
| if( pSource && pTarget) |
| { |
| Reference< XShape > xSource( pSource->getUnoShape(), UNO_QUERY ); |
| Reference< XShape > xTarget( pTarget->getUnoShape(), UNO_QUERY ); |
| if( xSource.is() && xTarget.is() ) |
| { |
| maShapeMap[xSource] = xTarget; |
| } |
| } |
| } |
| } |
| |
| // create a dictionary to map source to cloned nodes |
| ::anim::create_deep_vector( xSourceNode, maSourceNodeVector ); |
| ::anim::create_deep_vector( xCloneNode, maCloneNodeVector ); |
| |
| transformNode( xCloneNode ); |
| |
| return xCloneNode; |
| } |
| catch( Exception& e ) |
| { |
| (void)e; |
| DBG_ERROR( |
| (OString("sd::CustomAnimationClonerImpl::Clone(), " |
| "exception caught: ") + |
| rtl::OUStringToOString( |
| comphelper::anyToString( cppu::getCaughtException() ), |
| RTL_TEXTENCODING_UTF8 )).getStr() ); |
| |
| Reference< XAnimationNode > xEmpty; |
| return xEmpty; |
| } |
| } |
| |
| void CustomAnimationClonerImpl::transformNode( const Reference< XAnimationNode >& xNode ) |
| { |
| try |
| { |
| xNode->setBegin( transformValue( xNode->getBegin() ) ); |
| xNode->setEnd( transformValue( xNode->getEnd() ) ); |
| |
| sal_Int16 nNodeType( xNode->getType() ); |
| switch( nNodeType ) |
| { |
| case AnimationNodeType::ITERATE: |
| { |
| Reference< XIterateContainer > xIter( xNode, UNO_QUERY_THROW ); |
| xIter->setTarget( transformValue( xIter->getTarget() ) ); |
| } |
| // its intended that here is no break! |
| case AnimationNodeType::PAR: |
| case AnimationNodeType::SEQ: |
| { |
| Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY_THROW ); |
| Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW ); |
| while( xEnumeration->hasMoreElements() ) |
| { |
| Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY_THROW ); |
| transformNode( xChildNode ); |
| } |
| } |
| break; |
| |
| case AnimationNodeType::ANIMATE: |
| case AnimationNodeType::SET: |
| case AnimationNodeType::ANIMATEMOTION: |
| case AnimationNodeType::ANIMATECOLOR: |
| case AnimationNodeType::ANIMATETRANSFORM: |
| case AnimationNodeType::TRANSITIONFILTER: |
| { |
| Reference< XAnimate > xAnimate( xNode, UNO_QUERY_THROW ); |
| xAnimate->setTarget( transformValue( xAnimate->getTarget() ) ); |
| } |
| break; |
| |
| case AnimationNodeType::COMMAND: |
| { |
| Reference< XCommand > xCommand( xNode, UNO_QUERY_THROW ); |
| xCommand->setTarget( transformValue( xCommand->getTarget() ) ); |
| } |
| break; |
| |
| case AnimationNodeType::AUDIO: |
| { |
| Reference< XAudio > xAudio( xNode, UNO_QUERY_THROW ); |
| xAudio->setSource( transformValue( xAudio->getSource() ) ); |
| } |
| break; |
| } |
| |
| Sequence< NamedValue > aUserData( xNode->getUserData() ); |
| if( aUserData.hasElements() ) |
| { |
| NamedValue* pValue = aUserData.getArray(); |
| const sal_Int32 nLength = aUserData.getLength(); |
| sal_Int32 nElement; |
| for( nElement = 0; nElement < nLength; nElement++, pValue++ ) |
| { |
| pValue->Value = transformValue( pValue->Value ); |
| } |
| |
| xNode->setUserData( aUserData ); |
| } |
| } |
| catch( Exception& e ) |
| { |
| (void)e; |
| DBG_ERROR( |
| (OString("sd::CustomAnimationClonerImpl::transformNode(), " |
| "exception caught: ") + |
| rtl::OUStringToOString( |
| comphelper::anyToString( cppu::getCaughtException() ), |
| RTL_TEXTENCODING_UTF8 )).getStr() ); |
| } |
| } |
| |
| Any CustomAnimationClonerImpl::transformValue( const Any& rValue ) |
| { |
| if( rValue.hasValue() ) try |
| { |
| if( rValue.getValueType() == ::getCppuType((const ValuePair*)0) ) |
| { |
| ValuePair aValuePair; |
| rValue >>= aValuePair; |
| |
| aValuePair.First = transformValue( aValuePair.First ); |
| aValuePair.Second = transformValue( aValuePair.Second ); |
| |
| return makeAny( aValuePair ); |
| } |
| else if( rValue.getValueType() == ::getCppuType((Sequence<Any>*)0) ) |
| { |
| Sequence<Any> aSequence; |
| rValue >>= aSequence; |
| |
| const sal_Int32 nLength = aSequence.getLength(); |
| sal_Int32 nElement; |
| Any* pAny = aSequence.getArray(); |
| |
| for( nElement = 0; nElement < nLength; nElement++, pAny++ ) |
| *pAny = transformValue( *pAny ); |
| |
| return makeAny( aSequence ); |
| } |
| else if( rValue.getValueTypeClass() == TypeClass_INTERFACE ) |
| { |
| Reference< XShape > xShape; |
| rValue >>= xShape; |
| if( xShape.is() ) |
| { |
| return makeAny( getClonedShape( xShape ) ); |
| } |
| else |
| { |
| Reference< XAnimationNode > xNode; |
| rValue >>= xNode; |
| if( xNode.is() ) |
| return makeAny( getClonedNode( xNode ) ); |
| } |
| } |
| else if( rValue.getValueType() == ::getCppuType((const ParagraphTarget*)0) ) |
| { |
| ParagraphTarget aParaTarget; |
| rValue >>= aParaTarget; |
| |
| aParaTarget.Shape = getClonedShape( aParaTarget.Shape ); |
| |
| return makeAny( aParaTarget ); |
| } |
| else if( rValue.getValueType() == ::getCppuType((const Event*)0) ) |
| { |
| Event aEvent; |
| rValue >>= aEvent; |
| |
| aEvent.Source = transformValue( aEvent.Source ); |
| |
| return makeAny( aEvent ); |
| } |
| } |
| catch( Exception& e ) |
| { |
| (void)e; |
| DBG_ERROR( |
| (OString("sd::CustomAnimationClonerImpl::transformValue(), " |
| "exception caught: ") + |
| rtl::OUStringToOString( |
| comphelper::anyToString( cppu::getCaughtException() ), |
| RTL_TEXTENCODING_UTF8 )).getStr() ); |
| } |
| |
| return rValue; |
| } |
| |
| Reference< XShape > CustomAnimationClonerImpl::getClonedShape( const Reference< XShape >& xSource ) const |
| { |
| if( xSource.is() ) |
| { |
| if( maShapeMap.find(xSource) != maShapeMap.end() ) |
| { |
| return maShapeMap[xSource]; |
| } |
| |
| DBG_ASSERT( maShapeMap.empty(), "sd::CustomAnimationClonerImpl::getClonedShape() failed!" ); |
| } |
| return xSource; |
| } |
| |
| Reference< XAnimationNode > CustomAnimationClonerImpl::getClonedNode( const Reference< XAnimationNode >& xSource ) const |
| { |
| sal_Int32 nNode, nNodeCount = maSourceNodeVector.size(); |
| |
| for( nNode = 0; nNode < nNodeCount; nNode++ ) |
| { |
| if( maSourceNodeVector[nNode] == xSource ) |
| return maCloneNodeVector[nNode]; |
| } |
| |
| DBG_ERROR( "sd::CustomAnimationClonerImpl::getClonedNode() failed!" ); |
| return xSource; |
| } |
| } |