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