summaryrefslogtreecommitdiff
path: root/sd/source/core/CustomAnimationCloner.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sd/source/core/CustomAnimationCloner.cxx')
-rw-r--r--sd/source/core/CustomAnimationCloner.cxx350
1 files changed, 350 insertions, 0 deletions
diff --git a/sd/source/core/CustomAnimationCloner.cxx b/sd/source/core/CustomAnimationCloner.cxx
new file mode 100644
index 000000000000..a6a925ab63d2
--- /dev/null
+++ b/sd/source/core/CustomAnimationCloner.cxx
@@ -0,0 +1,350 @@
+/*************************************************************************
+ *
+ * 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_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;
+ }
+}