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/animations/XAnimationNode.hpp> 31 #include <com/sun/star/animations/Event.hpp> 32 #ifndef _COM_SUN_STAR_ANIMATIONS_XAnimateColor_HPP_ 33 #include <com/sun/star/animations/XAnimateColor.hpp> 34 #endif 35 #ifndef _COM_SUN_STAR_ANIMATIONS_XAnimateSet_HPP_ 36 #include <com/sun/star/animations/XAnimateSet.hpp> 37 #endif 38 #include <com/sun/star/animations/XCommand.hpp> 39 #ifndef _COM_SUN_STAR_ANIMATIONS_XAnimateMotion_HPP_ 40 #include <com/sun/star/animations/XAnimateMotion.hpp> 41 #endif 42 #ifndef _COM_SUN_STAR_ANIMATIONS_XAnimateTransform_HPP_ 43 #include <com/sun/star/animations/XAnimateTransform.hpp> 44 #endif 45 #ifndef _COM_SUN_STAR_ANIMATIONS_XTransitionFilter_HPP_ 46 #include <com/sun/star/animations/XTransitionFilter.hpp> 47 #endif 48 #include <com/sun/star/animations/XIterateContainer.hpp> 49 #include <com/sun/star/animations/XAudio.hpp> 50 #include <com/sun/star/animations/AnimationNodeType.hpp> 51 #include <com/sun/star/animations/ValuePair.hpp> 52 #include <com/sun/star/presentation/EffectNodeType.hpp> 53 #include <com/sun/star/util/XCloneable.hpp> 54 #include <com/sun/star/presentation/ParagraphTarget.hpp> 55 #include <com/sun/star/container/XEnumerationAccess.hpp> 56 #include <com/sun/star/beans/NamedValue.hpp> 57 58 #include <map> 59 60 #include "comphelper/anytostring.hxx" 61 #include "cppuhelper/exc_hlp.hxx" 62 #include "rtl/ref.hxx" 63 #include <animations/animationnodehelper.hxx> 64 65 // header for class SdrObjListIter 66 #include <svx/svditer.hxx> 67 68 #include "sdpage.hxx" 69 70 using namespace ::com::sun::star::uno; 71 using namespace ::com::sun::star::animations; 72 using namespace ::com::sun::star::presentation; 73 using namespace ::com::sun::star::container; 74 75 using ::rtl::OUString; 76 using ::rtl::OString; 77 using ::com::sun::star::drawing::XShape; 78 using ::com::sun::star::beans::NamedValue; 79 80 namespace sd 81 { 82 class CustomAnimationClonerImpl 83 { 84 public: 85 CustomAnimationClonerImpl(); 86 Reference< XAnimationNode > Clone( const Reference< XAnimationNode >& xSourceNode, const SdPage* pSource = 0, const SdPage* pTarget = 0 ); 87 88 private: 89 void transformNode( const Reference< XAnimationNode >& xNode ); 90 Any transformValue( const Any& rValue ); 91 92 Reference< XShape > getClonedShape( const Reference< XShape >& xSource ) const; 93 Reference< XAnimationNode > getClonedNode( const Reference< XAnimationNode >& xSource ) const; 94 95 mutable ::std::map< Reference< XShape >, Reference< XShape > > maShapeMap; 96 std::vector< Reference< XAnimationNode > > maSourceNodeVector; 97 std::vector< Reference< XAnimationNode > > maCloneNodeVector; 98 }; 99 100 CustomAnimationClonerImpl::CustomAnimationClonerImpl() 101 { 102 } 103 104 Reference< XAnimationNode > Clone( const Reference< XAnimationNode >& xSourceNode, const SdPage* pSource, const SdPage* pTarget ) 105 { 106 CustomAnimationClonerImpl aCloner; 107 return aCloner.Clone( xSourceNode, pSource, pTarget ); 108 } 109 110 Reference< XAnimationNode > CustomAnimationClonerImpl::Clone( const Reference< XAnimationNode >& xSourceNode, const SdPage* pSourcePage, const SdPage* pTargetPage ) 111 { 112 try 113 { 114 // clone animation hierarchie 115 Reference< ::com::sun::star::util::XCloneable > xClonable( xSourceNode, UNO_QUERY_THROW ); 116 Reference< XAnimationNode > xCloneNode( xClonable->createClone(), UNO_QUERY_THROW ); 117 118 // create a dictionary to map source to cloned shapes 119 if( pSourcePage && pTargetPage ) 120 { 121 SdrObjListIter aSourceIter( *pSourcePage, IM_DEEPWITHGROUPS ); 122 SdrObjListIter aTargetIter( *pTargetPage, IM_DEEPWITHGROUPS ); 123 124 while( aSourceIter.IsMore() && aTargetIter.IsMore() ) 125 { 126 SdrObject* pSource = aSourceIter.Next(); 127 SdrObject* pTarget = aTargetIter.Next(); 128 129 if( pSource && pTarget) 130 { 131 Reference< XShape > xSource( pSource->getUnoShape(), UNO_QUERY ); 132 Reference< XShape > xTarget( pTarget->getUnoShape(), UNO_QUERY ); 133 if( xSource.is() && xTarget.is() ) 134 { 135 maShapeMap[xSource] = xTarget; 136 } 137 } 138 } 139 } 140 141 // create a dictionary to map source to cloned nodes 142 ::anim::create_deep_vector( xSourceNode, maSourceNodeVector ); 143 ::anim::create_deep_vector( xCloneNode, maCloneNodeVector ); 144 145 transformNode( xCloneNode ); 146 147 return xCloneNode; 148 } 149 catch( Exception& e ) 150 { 151 (void)e; 152 DBG_ERROR( 153 (OString("sd::CustomAnimationClonerImpl::Clone(), " 154 "exception caught: ") + 155 rtl::OUStringToOString( 156 comphelper::anyToString( cppu::getCaughtException() ), 157 RTL_TEXTENCODING_UTF8 )).getStr() ); 158 159 Reference< XAnimationNode > xEmpty; 160 return xEmpty; 161 } 162 } 163 164 void CustomAnimationClonerImpl::transformNode( const Reference< XAnimationNode >& xNode ) 165 { 166 try 167 { 168 xNode->setBegin( transformValue( xNode->getBegin() ) ); 169 xNode->setEnd( transformValue( xNode->getEnd() ) ); 170 171 sal_Int16 nNodeType( xNode->getType() ); 172 switch( nNodeType ) 173 { 174 case AnimationNodeType::ITERATE: 175 { 176 Reference< XIterateContainer > xIter( xNode, UNO_QUERY_THROW ); 177 xIter->setTarget( transformValue( xIter->getTarget() ) ); 178 } 179 // its intended that here is no break! 180 case AnimationNodeType::PAR: 181 case AnimationNodeType::SEQ: 182 { 183 Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY_THROW ); 184 Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW ); 185 while( xEnumeration->hasMoreElements() ) 186 { 187 Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY_THROW ); 188 transformNode( xChildNode ); 189 } 190 } 191 break; 192 193 case AnimationNodeType::ANIMATE: 194 case AnimationNodeType::SET: 195 case AnimationNodeType::ANIMATEMOTION: 196 case AnimationNodeType::ANIMATECOLOR: 197 case AnimationNodeType::ANIMATETRANSFORM: 198 case AnimationNodeType::TRANSITIONFILTER: 199 { 200 Reference< XAnimate > xAnimate( xNode, UNO_QUERY_THROW ); 201 xAnimate->setTarget( transformValue( xAnimate->getTarget() ) ); 202 } 203 break; 204 205 case AnimationNodeType::COMMAND: 206 { 207 Reference< XCommand > xCommand( xNode, UNO_QUERY_THROW ); 208 xCommand->setTarget( transformValue( xCommand->getTarget() ) ); 209 } 210 break; 211 212 case AnimationNodeType::AUDIO: 213 { 214 Reference< XAudio > xAudio( xNode, UNO_QUERY_THROW ); 215 xAudio->setSource( transformValue( xAudio->getSource() ) ); 216 } 217 break; 218 } 219 220 Sequence< NamedValue > aUserData( xNode->getUserData() ); 221 if( aUserData.hasElements() ) 222 { 223 NamedValue* pValue = aUserData.getArray(); 224 const sal_Int32 nLength = aUserData.getLength(); 225 sal_Int32 nElement; 226 for( nElement = 0; nElement < nLength; nElement++, pValue++ ) 227 { 228 pValue->Value = transformValue( pValue->Value ); 229 } 230 231 xNode->setUserData( aUserData ); 232 } 233 } 234 catch( Exception& e ) 235 { 236 (void)e; 237 DBG_ERROR( 238 (OString("sd::CustomAnimationClonerImpl::transformNode(), " 239 "exception caught: ") + 240 rtl::OUStringToOString( 241 comphelper::anyToString( cppu::getCaughtException() ), 242 RTL_TEXTENCODING_UTF8 )).getStr() ); 243 } 244 } 245 246 Any CustomAnimationClonerImpl::transformValue( const Any& rValue ) 247 { 248 if( rValue.hasValue() ) try 249 { 250 if( rValue.getValueType() == ::getCppuType((const ValuePair*)0) ) 251 { 252 ValuePair aValuePair; 253 rValue >>= aValuePair; 254 255 aValuePair.First = transformValue( aValuePair.First ); 256 aValuePair.Second = transformValue( aValuePair.Second ); 257 258 return makeAny( aValuePair ); 259 } 260 else if( rValue.getValueType() == ::getCppuType((Sequence<Any>*)0) ) 261 { 262 Sequence<Any> aSequence; 263 rValue >>= aSequence; 264 265 const sal_Int32 nLength = aSequence.getLength(); 266 sal_Int32 nElement; 267 Any* pAny = aSequence.getArray(); 268 269 for( nElement = 0; nElement < nLength; nElement++, pAny++ ) 270 *pAny = transformValue( *pAny ); 271 272 return makeAny( aSequence ); 273 } 274 else if( rValue.getValueTypeClass() == TypeClass_INTERFACE ) 275 { 276 Reference< XShape > xShape; 277 rValue >>= xShape; 278 if( xShape.is() ) 279 { 280 return makeAny( getClonedShape( xShape ) ); 281 } 282 else 283 { 284 Reference< XAnimationNode > xNode; 285 rValue >>= xNode; 286 if( xNode.is() ) 287 return makeAny( getClonedNode( xNode ) ); 288 } 289 } 290 else if( rValue.getValueType() == ::getCppuType((const ParagraphTarget*)0) ) 291 { 292 ParagraphTarget aParaTarget; 293 rValue >>= aParaTarget; 294 295 aParaTarget.Shape = getClonedShape( aParaTarget.Shape ); 296 297 return makeAny( aParaTarget ); 298 } 299 else if( rValue.getValueType() == ::getCppuType((const Event*)0) ) 300 { 301 Event aEvent; 302 rValue >>= aEvent; 303 304 aEvent.Source = transformValue( aEvent.Source ); 305 306 return makeAny( aEvent ); 307 } 308 } 309 catch( Exception& e ) 310 { 311 (void)e; 312 DBG_ERROR( 313 (OString("sd::CustomAnimationClonerImpl::transformValue(), " 314 "exception caught: ") + 315 rtl::OUStringToOString( 316 comphelper::anyToString( cppu::getCaughtException() ), 317 RTL_TEXTENCODING_UTF8 )).getStr() ); 318 } 319 320 return rValue; 321 } 322 323 Reference< XShape > CustomAnimationClonerImpl::getClonedShape( const Reference< XShape >& xSource ) const 324 { 325 if( xSource.is() ) 326 { 327 if( maShapeMap.find(xSource) != maShapeMap.end() ) 328 { 329 return maShapeMap[xSource]; 330 } 331 332 DBG_ASSERT( maShapeMap.empty(), "sd::CustomAnimationClonerImpl::getClonedShape() failed!" ); 333 } 334 return xSource; 335 } 336 337 Reference< XAnimationNode > CustomAnimationClonerImpl::getClonedNode( const Reference< XAnimationNode >& xSource ) const 338 { 339 sal_Int32 nNode, nNodeCount = maSourceNodeVector.size(); 340 341 for( nNode = 0; nNode < nNodeCount; nNode++ ) 342 { 343 if( maSourceNodeVector[nNode] == xSource ) 344 return maCloneNodeVector[nNode]; 345 } 346 347 DBG_ERROR( "sd::CustomAnimationClonerImpl::getClonedNode() failed!" ); 348 return xSource; 349 } 350 } 351