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