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/XAnimationNodeSupplier.hpp>
21 : #include <com/sun/star/animations/AnimationFill.hpp>
22 : #include <com/sun/star/animations/AnimationRestart.hpp>
23 : #include <com/sun/star/animations/Timing.hpp>
24 : #include <com/sun/star/animations/Event.hpp>
25 : #include <com/sun/star/animations/AnimationEndSync.hpp>
26 : #include <com/sun/star/animations/EventTrigger.hpp>
27 : #include <com/sun/star/presentation/EffectNodeType.hpp>
28 : #include <com/sun/star/presentation/EffectPresetClass.hpp>
29 : #include <com/sun/star/animations/AnimationNodeType.hpp>
30 : #include <com/sun/star/animations/AnimationTransformType.hpp>
31 : #include <com/sun/star/animations/AnimationCalcMode.hpp>
32 : #include <com/sun/star/animations/AnimationValueType.hpp>
33 : #include <com/sun/star/util/XCloneable.hpp>
34 : #include <com/sun/star/animations/AnimationAdditiveMode.hpp>
35 : #include <com/sun/star/animations/XAnimateSet.hpp>
36 : #include <com/sun/star/animations/XAudio.hpp>
37 : #include <com/sun/star/animations/XTransitionFilter.hpp>
38 : #include <com/sun/star/animations/XAnimateColor.hpp>
39 : #include <com/sun/star/animations/XAnimateMotion.hpp>
40 : #include <com/sun/star/animations/XAnimateTransform.hpp>
41 : #include <com/sun/star/animations/TransitionType.hpp>
42 : #include <com/sun/star/animations/TransitionSubType.hpp>
43 : #include <com/sun/star/animations/ValuePair.hpp>
44 : #include <com/sun/star/animations/AnimationColorSpace.hpp>
45 : #include <com/sun/star/drawing/FillStyle.hpp>
46 : #include <com/sun/star/drawing/LineStyle.hpp>
47 : #include <com/sun/star/awt/FontWeight.hpp>
48 : #include <com/sun/star/awt/FontUnderline.hpp>
49 : #include <com/sun/star/awt/FontSlant.hpp>
50 : #include <com/sun/star/container/XEnumerationAccess.hpp>
51 : #include <com/sun/star/presentation/ParagraphTarget.hpp>
52 : #include <com/sun/star/text/XSimpleText.hpp>
53 : #include <com/sun/star/animations/XIterateContainer.hpp>
54 : #include <com/sun/star/presentation/TextAnimationType.hpp>
55 : #include <com/sun/star/container/XChild.hpp>
56 : #include <comphelper/processfactory.hxx>
57 : #include <rtl/ustrbuf.hxx>
58 :
59 : #include <vcl/vclenum.hxx>
60 : #include <svx/svdotext.hxx>
61 : #include <editeng/outlobj.hxx>
62 : #include <editeng/editobj.hxx>
63 : #include <pptexanimations.hxx>
64 : #include <osl/endian.h>
65 :
66 : #include <algorithm>
67 :
68 : using ::std::map;
69 : using ::com::sun::star::uno::Any;
70 : using ::com::sun::star::container::XChild;
71 : using ::com::sun::star::util::XCloneable;
72 : using ::com::sun::star::uno::Reference;
73 : using ::com::sun::star::uno::UNO_QUERY;
74 : using ::com::sun::star::uno::UNO_QUERY_THROW;
75 : using ::com::sun::star::uno::Sequence;
76 : using ::com::sun::star::uno::makeAny;
77 : using ::com::sun::star::uno::Exception;
78 : using ::com::sun::star::uno::XInterface;
79 : using ::com::sun::star::beans::NamedValue;
80 : using ::com::sun::star::container::XEnumerationAccess;
81 : using ::com::sun::star::container::XEnumeration;
82 : using ::com::sun::star::lang::XMultiServiceFactory;
83 :
84 : using namespace ::com::sun::star::text;
85 : using namespace ::com::sun::star::drawing;
86 : using namespace ::com::sun::star::animations;
87 : using namespace ::com::sun::star::presentation;
88 :
89 : namespace ppt
90 : {
91 :
92 0 : void ImplTranslateAttribute( OUString& rString, const TranslateMode eTranslateMode )
93 : {
94 0 : if ( eTranslateMode != TRANSLATE_NONE )
95 : {
96 0 : if ( ( eTranslateMode & TRANSLATE_VALUE ) || ( eTranslateMode & TRANSLATE_ATTRIBUTE ) )
97 : {
98 0 : const ImplAttributeNameConversion* p = gImplConversionList;
99 0 : while( p->mpAPIName )
100 : {
101 0 : if( rString.equalsAscii( p->mpAPIName ) )
102 0 : break;
103 0 : p++;
104 : }
105 0 : if( p->mpMSName )
106 : {
107 0 : if ( eTranslateMode & TRANSLATE_VALUE )
108 : {
109 0 : rString = "#";
110 0 : rString += OUString::createFromAscii( p->mpMSName );
111 : }
112 : else
113 0 : rString = OUString::createFromAscii( p->mpMSName );
114 0 : }
115 : }
116 0 : else if ( eTranslateMode & TRANSLATE_MEASURE )
117 : {
118 0 : const sal_Char* pDest[] = { "#ppt_x", "#ppt_y", "#ppt_w", "#ppt_h", NULL };
119 0 : const sal_Char* pSource[] = { "x", "y", "width", "height", NULL };
120 0 : sal_Int32 nIndex = 0;
121 :
122 0 : const sal_Char** ps = pSource;
123 0 : const sal_Char** pd = pDest;
124 :
125 0 : while( *ps )
126 : {
127 0 : const OUString aSearch( OUString::createFromAscii( *ps ) );
128 0 : while( (nIndex = rString.indexOf( aSearch, nIndex )) != -1 )
129 : {
130 0 : sal_Int32 nLength = aSearch.getLength();
131 0 : if( nIndex && ( rString[nIndex-1] == '#' ) )
132 : {
133 0 : nIndex--;
134 0 : nLength++;
135 : }
136 :
137 0 : const OUString aNew( OUString::createFromAscii( *pd ) );
138 0 : rString = rString.replaceAt( nIndex, nLength, aNew );
139 0 : nIndex += aNew.getLength();
140 0 : }
141 0 : ps++;
142 0 : pd++;
143 0 : }
144 : }
145 : }
146 0 : }
147 :
148 0 : sal_uInt32 AnimationExporter::TranslatePresetSubType( const sal_uInt32 nPresetClass, const sal_uInt32 nPresetId, const OUString& rPresetSubType )
149 : {
150 0 : sal_uInt32 nPresetSubType = 0;
151 0 : bool bTranslated = false;
152 :
153 0 : if ( ( nPresetClass == (sal_uInt32)EffectPresetClass::ENTRANCE ) || ( nPresetClass == (sal_uInt32)EffectPresetClass::EXIT ) )
154 : {
155 0 : if ( nPresetId != 21 )
156 : {
157 0 : switch( nPresetId )
158 : {
159 : case 5 :
160 : {
161 0 : if ( rPresetSubType == "downward" )
162 : {
163 0 : nPresetSubType = 5;
164 0 : bTranslated = true;
165 : }
166 0 : else if ( rPresetSubType == "across" )
167 : {
168 0 : nPresetSubType = 10;
169 0 : bTranslated = true;
170 : }
171 : }
172 0 : break;
173 : case 17 :
174 : {
175 0 : if ( rPresetSubType == "across" )
176 : {
177 0 : nPresetSubType = 10;
178 0 : bTranslated = true;
179 : }
180 : }
181 0 : break;
182 : case 18 :
183 : {
184 0 : if ( rPresetSubType == "right-to-top" )
185 : {
186 0 : nPresetSubType = 3;
187 0 : bTranslated = true;
188 : }
189 0 : else if ( rPresetSubType == "right-to-bottom" )
190 : {
191 0 : nPresetSubType = 6;
192 0 : bTranslated = true;
193 : }
194 0 : else if ( rPresetSubType == "left-to-top" )
195 : {
196 0 : nPresetSubType = 9;
197 0 : bTranslated = true;
198 : }
199 0 : else if ( rPresetSubType == "left-to-bottom" )
200 : {
201 0 : nPresetSubType = 12;
202 0 : bTranslated = true;
203 : }
204 : }
205 0 : break;
206 : }
207 : }
208 0 : if ( !bTranslated )
209 : {
210 0 : const convert_subtype* p = gConvertArray;
211 0 : while( p->mpStrSubType )
212 : {
213 0 : if ( rPresetSubType.equalsAscii( p->mpStrSubType ) )
214 : {
215 0 : nPresetSubType = p->mnID;
216 0 : bTranslated = true;
217 0 : break;
218 : }
219 0 : p++;
220 : }
221 : }
222 : }
223 0 : if ( !bTranslated )
224 0 : nPresetSubType = (sal_uInt32)rPresetSubType.toInt32();
225 0 : return nPresetSubType;
226 : }
227 :
228 0 : const sal_Char* AnimationExporter::FindTransitionName( const sal_Int16 nType, const sal_Int16 nSubType, const bool bDirection )
229 : {
230 0 : const sal_Char* pRet = NULL;
231 0 : int nFit = 0;
232 :
233 0 : const transition* p = gTransitions;
234 0 : while( p->mpName )
235 : {
236 0 : int nF = 0;
237 0 : if ( nType == p->mnType )
238 0 : nF += 4;
239 0 : if ( nSubType == p->mnSubType )
240 0 : nF += 2;
241 0 : if ( bDirection == p->mbDirection )
242 0 : nF += 1;
243 0 : if ( nF > nFit )
244 : {
245 0 : pRet = p->mpName;
246 0 : nFit = nF;
247 : }
248 0 : if ( nFit == 7 ) // maximum
249 0 : break;
250 0 : p++;
251 : }
252 0 : return pRet;
253 : }
254 :
255 10 : SvStream& WriteAnimationNode(SvStream& rOut, AnimationNode& rNode )
256 : {
257 10 : rOut.WriteInt32( rNode.mnU1 );
258 10 : rOut.WriteInt32( rNode.mnRestart );
259 10 : rOut.WriteInt32( rNode.mnGroupType );
260 10 : rOut.WriteInt32( rNode.mnFill );
261 10 : rOut.WriteInt32( rNode.mnU3 );
262 10 : rOut.WriteInt32( rNode.mnU4 );
263 10 : rOut.WriteInt32( rNode.mnDuration );
264 10 : rOut.WriteInt32( rNode.mnNodeType );
265 :
266 10 : return rOut;
267 : }
268 :
269 5 : AnimationExporter::AnimationExporter( const EscherSolverContainer& rSolverContainer, ppt::ExSoundCollection& rExSoundCollection ) :
270 : mrSolverContainer ( rSolverContainer ),
271 : mrExSoundCollection ( rExSoundCollection ),
272 5 : mnCurrentGroup(0)
273 : {
274 5 : }
275 :
276 10 : sal_Int16 AnimationExporter::GetFillMode( const Reference< XAnimationNode >& xNode, const sal_Int16 nFillDefault )
277 : {
278 10 : sal_Int16 nFill = xNode->getFill();
279 : //#i119699 <Animation> The animation effect "Emphasis->FlashBulb" play incorrectly in Aoo saves a .ppt to another .ppt and plays the saved one.
280 : //#i119740 <Animation> The animation effect "Entrance->Flash Once" fails to play in Aoo while Aoo saves a .ppt to another .ppt and plays the saved one.
281 20 : if ((xNode->getType() == AnimationNodeType::ANIMATE)
282 10 : ||(xNode->getType() == AnimationNodeType::SET)
283 20 : ||(xNode->getType() == AnimationNodeType::TRANSITIONFILTER))
284 : {
285 0 : if ( nFill == AnimationFill::DEFAULT )
286 0 : return nFill;
287 : }
288 :
289 10 : if ( ( nFill == AnimationFill::DEFAULT ) ||
290 : ( nFill == AnimationFill::INHERIT ) )
291 : {
292 10 : if ( nFill != AnimationFill::AUTO )
293 10 : nFill = nFillDefault;
294 : }
295 10 : if( nFill == AnimationFill::AUTO )
296 : {
297 5 : nFill = AnimationFill::REMOVE;
298 5 : bool bIsIndefiniteTiming = true;
299 5 : Any aAny = xNode->getDuration();
300 5 : if( aAny.hasValue() )
301 : {
302 : Timing eTiming;
303 0 : if( aAny >>= eTiming )
304 0 : bIsIndefiniteTiming = eTiming == Timing_INDEFINITE;
305 : }
306 5 : if ( bIsIndefiniteTiming )
307 : {
308 5 : aAny = xNode->getEnd();
309 5 : if( aAny.hasValue() )
310 : {
311 : Timing eTiming;
312 0 : if( aAny >>= eTiming )
313 0 : bIsIndefiniteTiming = eTiming == Timing_INDEFINITE;
314 : }
315 5 : if ( bIsIndefiniteTiming )
316 : {
317 5 : if ( !xNode->getRepeatCount().hasValue() )
318 : {
319 5 : aAny = xNode->getRepeatDuration();
320 5 : if( aAny.hasValue() )
321 : {
322 : Timing eTiming;
323 0 : if( aAny >>= eTiming )
324 0 : bIsIndefiniteTiming = eTiming == Timing_INDEFINITE;
325 : }
326 5 : if ( bIsIndefiniteTiming )
327 5 : nFill = AnimationFill::FREEZE;
328 : }
329 : }
330 5 : }
331 : }
332 10 : return nFill;
333 : }
334 :
335 5 : void AnimationExporter::doexport( const Reference< XDrawPage >& xPage, SvStream& rStrm )
336 : {
337 5 : Reference< XAnimationNodeSupplier > xNodeSupplier( xPage, UNO_QUERY );
338 5 : if( xNodeSupplier.is() )
339 : {
340 5 : const Reference< XAnimationNode > xRootNode( xNodeSupplier->getAnimationNode() );
341 5 : if( xRootNode.is() )
342 : {
343 5 : processAfterEffectNodes( xRootNode );
344 5 : exportNode( rStrm, xRootNode, NULL, DFF_msofbtAnimGroup, 1, 0, false, AnimationFill::AUTO );
345 5 : }
346 5 : }
347 5 : }
348 :
349 5 : void AnimationExporter::processAfterEffectNodes( const Reference< XAnimationNode >& xRootNode )
350 : {
351 : try
352 : {
353 5 : Reference< XEnumerationAccess > xEnumerationAccess( xRootNode, UNO_QUERY_THROW );
354 10 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY_THROW );
355 15 : while( xEnumeration->hasMoreElements() )
356 : {
357 5 : Reference< XAnimationNode > xNode( xEnumeration->nextElement(), UNO_QUERY_THROW );
358 :
359 10 : Reference< XEnumerationAccess > xEnumerationAccess2( xNode, UNO_QUERY );
360 5 : if ( xEnumerationAccess2.is() )
361 : {
362 5 : Reference< XEnumeration > xEnumeration2( xEnumerationAccess2->createEnumeration(), UNO_QUERY_THROW );
363 10 : while( xEnumeration2->hasMoreElements() )
364 : {
365 0 : Reference< XAnimationNode > xChildNode( xEnumeration2->nextElement(), UNO_QUERY_THROW );
366 :
367 0 : Reference< XEnumerationAccess > xEnumerationAccess3( xChildNode, UNO_QUERY_THROW );
368 0 : Reference< XEnumeration > xEnumeration3( xEnumerationAccess3->createEnumeration(), UNO_QUERY_THROW );
369 0 : while( xEnumeration3->hasMoreElements() )
370 : {
371 0 : Reference< XAnimationNode > xChildNode2( xEnumeration3->nextElement(), UNO_QUERY_THROW );
372 :
373 0 : Reference< XEnumerationAccess > xEnumerationAccess4( xChildNode2, UNO_QUERY_THROW );
374 0 : Reference< XEnumeration > xEnumeration4( xEnumerationAccess4->createEnumeration(), UNO_QUERY_THROW );
375 0 : while( xEnumeration4->hasMoreElements() )
376 : {
377 0 : Reference< XAnimationNode > xChildNode3( xEnumeration4->nextElement(), UNO_QUERY_THROW );
378 :
379 0 : switch( xChildNode3->getType() )
380 : {
381 : // found an after effect
382 : case AnimationNodeType::SET:
383 : case AnimationNodeType::ANIMATECOLOR:
384 : {
385 0 : Reference< XAnimationNode > xMaster;
386 :
387 0 : Sequence< NamedValue > aUserData( xChildNode3->getUserData() );
388 0 : sal_Int32 nLength = aUserData.getLength();
389 0 : const NamedValue* p = aUserData.getConstArray();
390 :
391 0 : while( nLength-- )
392 : {
393 0 : if ( p->Name == "master-element" )
394 : {
395 0 : p->Value >>= xMaster;
396 0 : break;
397 : }
398 0 : p++;
399 : }
400 :
401 0 : AfterEffectNodePtr pAfterEffectNode( new AfterEffectNode( xChildNode3, xMaster ) );
402 0 : maAfterEffectNodes.push_back( pAfterEffectNode );
403 : }
404 0 : break;
405 : }
406 0 : }
407 0 : }
408 5 : }
409 : }
410 10 : }
411 : }
412 0 : catch( Exception& )
413 : {
414 : OSL_FAIL( "(@CL)AnimationExporter::processAfterEffectNodes(), exception caught!" );
415 : }
416 5 : }
417 :
418 0 : bool AnimationExporter::isAfterEffectNode( const Reference< XAnimationNode >& xNode ) const
419 : {
420 0 : const std::list< AfterEffectNodePtr >::const_iterator aEnd( maAfterEffectNodes.end() );
421 0 : for (std::list< AfterEffectNodePtr >::const_iterator aIter( maAfterEffectNodes.begin() );
422 : aIter != aEnd ; ++aIter)
423 : {
424 0 : if( (*aIter)->mxNode == xNode )
425 0 : return true;
426 : }
427 0 : return false;
428 : }
429 :
430 10 : bool AnimationExporter::hasAfterEffectNode( const Reference< XAnimationNode >& xNode, Reference< XAnimationNode >& xAfterEffectNode ) const
431 : {
432 10 : const std::list< AfterEffectNodePtr >::const_iterator aEnd( maAfterEffectNodes.end() );
433 10 : for (std::list< AfterEffectNodePtr >::const_iterator aIter( maAfterEffectNodes.begin() );
434 : aIter != aEnd ; ++aIter)
435 : {
436 0 : if( (*aIter)->mxMaster == xNode )
437 : {
438 0 : xAfterEffectNode = (*aIter)->mxNode;
439 0 : return true;
440 : }
441 : }
442 :
443 10 : return false;
444 : }
445 :
446 : // check if this group only contain empty groups. this may happen when
447 : // after effect nodes are not exported at theire original position
448 0 : bool AnimationExporter::isEmptyNode( const Reference< XAnimationNode >& xNode ) const
449 : {
450 0 : if( xNode.is() ) switch( xNode->getType() )
451 : {
452 : case AnimationNodeType::PAR :
453 : case AnimationNodeType::SEQ :
454 : case AnimationNodeType::ITERATE :
455 : {
456 0 : Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY );
457 0 : if( xEnumerationAccess.is() )
458 : {
459 0 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
460 0 : if( xEnumeration.is() )
461 : {
462 0 : while( xEnumeration->hasMoreElements() )
463 : {
464 0 : Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY );
465 0 : if( xChildNode.is() && !isEmptyNode( xChildNode ) )
466 0 : return false;
467 0 : }
468 0 : }
469 0 : }
470 : }
471 0 : break;
472 :
473 : case AnimationNodeType::SET :
474 : case AnimationNodeType::ANIMATECOLOR :
475 0 : return isAfterEffectNode( xNode );
476 : default:
477 0 : return false;
478 : }
479 :
480 0 : return true;
481 : }
482 :
483 10 : void AnimationExporter::exportNode( SvStream& rStrm, Reference< XAnimationNode > xNode, const Reference< XAnimationNode >* pParent, const sal_uInt16 nContainerRecType,
484 : const sal_uInt16 nInstance, const sal_Int32 nGroupLevel, const bool bTakeBackInteractiveSequenceTiming, const sal_Int16 nFDef )
485 : {
486 10 : if( (nGroupLevel == 4) && isEmptyNode( xNode ) )
487 0 : return;
488 :
489 10 : if ( ( nContainerRecType == DFF_msofbtAnimGroup ) && ( nGroupLevel == 2 ) && isEmptyNode( xNode ) )
490 0 : return;
491 :
492 10 : if( nContainerRecType == DFF_msofbtAnimGroup )
493 10 : mnCurrentGroup++;
494 :
495 10 : bool bTakeBackInteractiveSequenceTimingForChild = false;
496 10 : sal_Int16 nFillDefault = GetFillMode( xNode, nFDef );
497 :
498 10 : bool bSkipChildren = false;
499 :
500 10 : Reference< XAnimationNode > xAudioNode;
501 : static sal_uInt32 nAudioGroup;
502 :
503 : {
504 10 : EscherExContainer aContainer( rStrm, nContainerRecType, nInstance );
505 10 : switch( xNode->getType() )
506 : {
507 : case AnimationNodeType::CUSTOM :
508 : {
509 0 : exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault );
510 0 : exportAnimPropertySet( rStrm, xNode );
511 0 : exportAnimEvent( rStrm, xNode, 0 );
512 0 : exportAnimValue( rStrm, xNode, false );
513 : }
514 0 : break;
515 :
516 : case AnimationNodeType::PAR :
517 : {
518 5 : exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault );
519 5 : exportAnimPropertySet( rStrm, xNode );
520 5 : sal_Int32 nFlags = nGroupLevel == 2 ? 0x10 : 0;
521 5 : if ( bTakeBackInteractiveSequenceTiming )
522 0 : nFlags |= 0x40;
523 5 : exportAnimEvent( rStrm, xNode, nFlags );
524 5 : exportAnimValue( rStrm, xNode, nGroupLevel == 4 );
525 : }
526 5 : break;
527 :
528 : case AnimationNodeType::SEQ :
529 : {
530 5 : exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault );
531 5 : sal_Int16 nNodeType = exportAnimPropertySet( rStrm, xNode );
532 5 : sal_Int32 nFlags = 12;
533 5 : if ( ( nGroupLevel == 1 ) && ( nNodeType == ::com::sun::star::presentation::EffectNodeType::INTERACTIVE_SEQUENCE ) )
534 : {
535 0 : nFlags |= 0x20;
536 0 : bTakeBackInteractiveSequenceTimingForChild = true;
537 : }
538 5 : exportAnimAction( rStrm, xNode );
539 5 : exportAnimEvent( rStrm, xNode, nFlags );
540 5 : exportAnimValue( rStrm, xNode, false );
541 : }
542 5 : break;
543 :
544 : case AnimationNodeType::ITERATE :
545 : {
546 : {
547 0 : EscherExAtom aAnimNodeExAtom( rStrm, DFF_msofbtAnimNode );
548 0 : AnimationNode aAnim;
549 0 : memset( &aAnim, 0, sizeof( aAnim ) );
550 0 : aAnim.mnGroupType = mso_Anim_GroupType_PAR;
551 0 : aAnim.mnNodeType = 1;
552 : // attribute Restart
553 0 : switch( xNode->getRestart() )
554 : {
555 : default:
556 0 : case AnimationRestart::DEFAULT : aAnim.mnRestart = 0; break;
557 0 : case AnimationRestart::ALWAYS : aAnim.mnRestart = 1; break;
558 0 : case AnimationRestart::WHEN_NOT_ACTIVE : aAnim.mnRestart = 2; break;
559 0 : case AnimationRestart::NEVER : aAnim.mnRestart = 3; break;
560 : }
561 : // attribute Fill
562 0 : switch( xNode->getFill() )
563 : {
564 : default:
565 0 : case AnimationFill::DEFAULT : aAnim.mnFill = 0; break;
566 0 : case AnimationFill::REMOVE : aAnim.mnFill = 1; break;
567 0 : case AnimationFill::FREEZE : aAnim.mnFill = 2; break;
568 0 : case AnimationFill::HOLD : aAnim.mnFill = 3; break;
569 0 : case AnimationFill::TRANSITION : aAnim.mnFill = 4; break;
570 : }
571 0 : WriteAnimationNode( rStrm, aAnim );
572 : }
573 0 : exportIterate( rStrm, xNode );
574 0 : exportAnimPropertySet( rStrm, xNode );
575 0 : exportAnimEvent( rStrm, xNode, 0 );
576 0 : exportAnimValue( rStrm, xNode, false );
577 : }
578 0 : break;
579 :
580 : case AnimationNodeType::ANIMATE :
581 : {
582 0 : exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault );
583 0 : exportAnimPropertySet( rStrm, xNode );
584 0 : exportAnimEvent( rStrm, xNode, 0 );
585 0 : exportAnimValue( rStrm, xNode, false );
586 0 : exportAnimate( rStrm, xNode );
587 : }
588 0 : break;
589 :
590 : case AnimationNodeType::SET :
591 : {
592 0 : bool bIsAfterEffectNode( isAfterEffectNode( xNode ) );
593 0 : if( (nGroupLevel != 4) || !bIsAfterEffectNode )
594 : {
595 0 : exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault );
596 0 : exportAnimPropertySet( rStrm, xNode );
597 0 : exportAnimateSet( rStrm, xNode, bIsAfterEffectNode ? AFTEREFFECT_SET : AFTEREFFECT_NONE );
598 0 : exportAnimEvent( rStrm, xNode, 0 );
599 0 : exportAnimValue( rStrm, xNode, false );
600 : }
601 : else
602 : {
603 0 : bSkipChildren = true;
604 : }
605 : }
606 0 : break;
607 :
608 : case AnimationNodeType::ANIMATEMOTION :
609 : {
610 0 : exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault );
611 0 : exportAnimPropertySet( rStrm, xNode );
612 0 : exportAnimateMotion( rStrm, xNode );
613 0 : exportAnimEvent( rStrm, xNode, 0 );
614 0 : exportAnimValue( rStrm, xNode, false );
615 : }
616 0 : break;
617 :
618 : case AnimationNodeType::ANIMATECOLOR :
619 : {
620 0 : bool bIsAfterEffectNode( isAfterEffectNode( xNode ) );
621 0 : if( (nGroupLevel != 4) || !bIsAfterEffectNode )
622 : {
623 0 : if( bIsAfterEffectNode )
624 0 : xNode = createAfterEffectNodeClone( xNode );
625 :
626 0 : exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault );
627 0 : exportAnimPropertySet( rStrm, xNode );
628 0 : exportAnimateColor( rStrm, xNode, bIsAfterEffectNode ? AFTEREFFECT_COLOR : AFTEREFFECT_NONE );
629 0 : exportAnimEvent( rStrm, xNode, 0 );
630 0 : exportAnimValue( rStrm, xNode, false );
631 : }
632 : else
633 : {
634 0 : bSkipChildren = true;
635 : }
636 : }
637 0 : break;
638 :
639 : case AnimationNodeType::ANIMATETRANSFORM :
640 : {
641 0 : exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault );
642 0 : exportAnimPropertySet( rStrm, xNode );
643 0 : exportAnimateTransform( rStrm, xNode );
644 0 : exportAnimEvent( rStrm, xNode, 0 );
645 0 : exportAnimValue( rStrm, xNode, false );
646 : }
647 0 : break;
648 :
649 : case AnimationNodeType::TRANSITIONFILTER :
650 : {
651 0 : exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault );
652 0 : exportAnimPropertySet( rStrm, xNode );
653 0 : exportAnimEvent( rStrm, xNode, 0 );
654 0 : exportAnimValue( rStrm, xNode, false );
655 0 : exportTransitionFilter( rStrm, xNode );
656 : }
657 0 : break;
658 :
659 : case AnimationNodeType::AUDIO : // #i58428#
660 : {
661 0 : exportAnimNode( rStrm, xNode, pParent, nGroupLevel, nFillDefault );
662 0 : exportAnimPropertySet( rStrm, xNode );
663 :
664 0 : Reference< XAudio > xAudio( xNode, UNO_QUERY );
665 0 : if( xAudio.is() )
666 : {
667 0 : Any aAny( xAudio->getSource() );
668 0 : OUString aURL;
669 :
670 0 : if ( ( aAny >>= aURL) && !aURL.isEmpty() )
671 : {
672 0 : sal_Int32 nU1 = 2;
673 0 : sal_Int32 nTrigger = 3;
674 0 : sal_Int32 nU3 = nAudioGroup;
675 0 : sal_Int32 nBegin = 0;
676 : {
677 0 : EscherExContainer aAnimEvent( rStrm, DFF_msofbtAnimEvent, 1 );
678 : {
679 0 : EscherExAtom aAnimTrigger( rStrm, DFF_msofbtAnimTrigger );
680 0 : rStrm.WriteInt32( nU1 ).WriteInt32( nTrigger ).WriteInt32( nU3 ).WriteInt32( nBegin );
681 0 : }
682 : }
683 0 : nU1 = 1;
684 0 : nTrigger = 0xb;
685 0 : nU3 = 0;
686 : {
687 0 : EscherExContainer aAnimEvent( rStrm, DFF_msofbtAnimEvent, 2 );
688 : {
689 0 : EscherExAtom aAnimTrigger( rStrm, DFF_msofbtAnimTrigger );
690 0 : rStrm.WriteInt32( nU1 ).WriteInt32( nTrigger ).WriteInt32( nU3 ).WriteInt32( nBegin );
691 0 : }
692 : }
693 0 : EscherExContainer aAnimateTargetElement( rStrm, DFF_msofbtAnimateTargetElement );
694 : {
695 0 : sal_uInt32 nRefMode = 3;
696 0 : sal_uInt32 nRefType = 2;
697 0 : sal_uInt32 nRefId = mrExSoundCollection.GetId( aURL );
698 0 : sal_Int32 begin = -1;
699 0 : sal_Int32 end = -1;
700 :
701 0 : EscherExAtom aAnimReference( rStrm, DFF_msofbtAnimReference );
702 0 : rStrm.WriteUInt32( nRefMode ).WriteUInt32( nRefType ).WriteUInt32( nRefId ).WriteInt32( begin ).WriteInt32( end );
703 0 : }
704 0 : }
705 : }
706 0 : exportAnimValue( rStrm, xNode, false );
707 : }
708 0 : break;
709 : }
710 10 : if( !bSkipChildren )
711 : {
712 : // export after effect node if one exists for this node
713 10 : Reference< XAnimationNode > xAfterEffectNode;
714 10 : if( hasAfterEffectNode( xNode, xAfterEffectNode ) )
715 : {
716 0 : exportNode( rStrm, xAfterEffectNode, &xNode, DFF_msofbtAnimSubGoup, 1, nGroupLevel + 1, bTakeBackInteractiveSequenceTimingForChild, nFillDefault );
717 : }
718 :
719 20 : Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY );
720 10 : if( xEnumerationAccess.is() )
721 : {
722 10 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
723 10 : if( xEnumeration.is() )
724 : {
725 25 : while( xEnumeration->hasMoreElements() )
726 : {
727 5 : Reference< XAnimationNode > xChildNode( xEnumeration->nextElement(), UNO_QUERY );
728 5 : if( xChildNode.is() )
729 : {
730 5 : if ( xChildNode->getType() == AnimationNodeType::AUDIO )
731 : {
732 0 : xAudioNode = xChildNode;
733 0 : nAudioGroup = mnCurrentGroup;
734 : }
735 : else
736 5 : exportNode( rStrm, xChildNode, &xNode, DFF_msofbtAnimGroup, 1, nGroupLevel + 1, bTakeBackInteractiveSequenceTimingForChild, nFillDefault );
737 : }
738 5 : }
739 10 : }
740 10 : }
741 10 : }
742 : }
743 10 : if ( xAudioNode.is() )
744 0 : exportNode( rStrm, xAudioNode, &xNode, DFF_msofbtAnimGroup, 1, nGroupLevel, bTakeBackInteractiveSequenceTimingForChild, nFillDefault );
745 :
746 10 : if( xNode->getType() == AnimationNodeType::ITERATE )
747 0 : aTarget = Any();
748 : }
749 :
750 0 : Reference< XAnimationNode > AnimationExporter::createAfterEffectNodeClone( const Reference< XAnimationNode >& xNode )
751 : {
752 : try
753 : {
754 0 : Reference< ::com::sun::star::util::XCloneable > xClonable( xNode, UNO_QUERY_THROW );
755 0 : Reference< XAnimationNode > xCloneNode( xClonable->createClone(), UNO_QUERY_THROW );
756 :
757 0 : Any aEmpty;
758 0 : xCloneNode->setBegin( aEmpty );
759 :
760 0 : return xCloneNode;
761 : }
762 0 : catch( Exception& )
763 : {
764 : OSL_FAIL("(@CL)sd::ppt::AnimationExporter::createAfterEffectNodeClone(), could not create clone!" );
765 : }
766 0 : return xNode;
767 : }
768 :
769 10 : bool AnimationExporter::GetNodeType( const Reference< XAnimationNode >& xNode, sal_Int16& nType )
770 : {
771 : // trying to get the nodetype
772 10 : Sequence< NamedValue > aUserData = xNode->getUserData();
773 10 : if ( aUserData.getLength() )
774 : {
775 10 : const NamedValue* p = aUserData.getConstArray();
776 10 : sal_Int32 nLength = aUserData.getLength();
777 10 : while( nLength-- )
778 : {
779 10 : if ( p->Name == "node-type" )
780 : {
781 10 : if ( p->Value >>= nType )
782 10 : return true;
783 : }
784 : }
785 : }
786 :
787 0 : return false;
788 : }
789 :
790 10 : void AnimationExporter::exportAnimNode( SvStream& rStrm, const Reference< XAnimationNode >& xNode,
791 : const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >*, const sal_Int32, const sal_Int16 nFillDefault )
792 : {
793 10 : EscherExAtom aAnimNodeExAtom( rStrm, DFF_msofbtAnimNode );
794 10 : AnimationNode aAnim;
795 10 : memset( &aAnim, 0, sizeof( aAnim ) );
796 :
797 : // attribute Restart
798 10 : switch( xNode->getRestart() )
799 : {
800 : default:
801 10 : case AnimationRestart::DEFAULT : aAnim.mnRestart = 0; break;
802 0 : case AnimationRestart::ALWAYS : aAnim.mnRestart = 1; break;
803 0 : case AnimationRestart::WHEN_NOT_ACTIVE : aAnim.mnRestart = 2; break;
804 0 : case AnimationRestart::NEVER : aAnim.mnRestart = 3; break;
805 : }
806 :
807 10 : switch( nFillDefault )
808 : {
809 : default:
810 0 : case AnimationFill::DEFAULT : aAnim.mnFill = 0; break;
811 0 : case AnimationFill::REMOVE : aAnim.mnFill = 1; break;
812 : case AnimationFill::FREEZE :
813 10 : case AnimationFill::HOLD : aAnim.mnFill = 3; break;
814 0 : case AnimationFill::TRANSITION : aAnim.mnFill = 4; break;
815 : }
816 : // attribute Duration
817 10 : double fDuration = 0.0;
818 : com::sun::star::animations::Timing eTiming;
819 10 : if ( xNode->getDuration() >>= eTiming )
820 : {
821 0 : if ( eTiming == Timing_INDEFINITE )
822 0 : aAnim.mnDuration = -1;
823 : }
824 10 : else if ( xNode->getDuration() >>= fDuration )
825 : {
826 5 : aAnim.mnDuration = (sal_Int32)( fDuration * 1000.0 );
827 : }
828 : else
829 5 : aAnim.mnDuration = -1;
830 :
831 : // NodeType, NodeGroup
832 10 : aAnim.mnNodeType = 1;
833 10 : aAnim.mnGroupType = mso_Anim_GroupType_SEQ;
834 10 : switch( xNode->getType() )
835 : {
836 : case AnimationNodeType::PAR :
837 5 : aAnim.mnGroupType = mso_Anim_GroupType_PAR;
838 : // PASSTROUGH!!! (as it was intended)
839 : case AnimationNodeType::SEQ :
840 : {
841 10 : sal_Int16 nType = 0;
842 10 : if( GetNodeType( xNode, nType ) )
843 10 : switch( nType )
844 : {
845 5 : case ::com::sun::star::presentation::EffectNodeType::TIMING_ROOT : aAnim.mnNodeType = 0x12; break;
846 5 : case ::com::sun::star::presentation::EffectNodeType::MAIN_SEQUENCE : aAnim.mnNodeType = 0x18; break;
847 : }
848 : }
849 10 : break;
850 :
851 : case AnimationNodeType::ANIMATE :
852 : case AnimationNodeType::SET :
853 :
854 : case AnimationNodeType::CUSTOM :
855 : case AnimationNodeType::ITERATE :
856 : case AnimationNodeType::ANIMATEMOTION :
857 : case AnimationNodeType::ANIMATECOLOR :
858 : case AnimationNodeType::ANIMATETRANSFORM :
859 : {
860 0 : aAnim.mnGroupType = mso_Anim_GroupType_NODE;
861 0 : aAnim.mnNodeType = mso_Anim_Behaviour_ANIMATION;
862 : }
863 0 : break;
864 :
865 : case AnimationNodeType::AUDIO :
866 : {
867 0 : aAnim.mnGroupType = mso_Anim_GroupType_MEDIA;
868 0 : aAnim.mnNodeType = mso_Anim_Behaviour_ANIMATION;
869 : }
870 0 : break;
871 :
872 : case AnimationNodeType::TRANSITIONFILTER :
873 : {
874 0 : aAnim.mnGroupType = mso_Anim_GroupType_NODE;
875 0 : aAnim.mnNodeType = mso_Anim_Behaviour_FILTER;
876 : }
877 0 : break;
878 : }
879 :
880 10 : WriteAnimationNode( rStrm, aAnim );
881 10 : }
882 :
883 12 : void AnimationExporter::GetUserData( const Sequence< NamedValue >& rUserData, const Any ** pAny, sal_Size nLen )
884 : {
885 : // storing user data into pAny, to allow direct access later
886 12 : memset( pAny, 0, nLen );
887 12 : if ( rUserData.getLength() )
888 : {
889 12 : const NamedValue* p = rUserData.getConstArray();
890 12 : sal_Int32 nLength = rUserData.getLength();
891 36 : while( nLength-- )
892 : {
893 12 : if ( p->Name == "node-type" )
894 : {
895 12 : pAny[ DFF_ANIM_NODE_TYPE ] = &(p->Value);
896 : }
897 0 : else if ( p->Name == "preset-class" )
898 : {
899 0 : pAny[ DFF_ANIM_PRESET_CLASS ] = &(p->Value);
900 : }
901 0 : else if ( p->Name == "preset-id" )
902 : {
903 0 : pAny[ DFF_ANIM_PRESET_ID ] = &(p->Value);
904 : }
905 0 : else if ( p->Name == "preset-sub-type" )
906 : {
907 0 : pAny[ DFF_ANIM_PRESET_SUB_TYPE ] = &(p->Value);
908 : }
909 0 : else if ( p->Name == "master-element" )
910 : {
911 0 : pAny[ DFF_ANIM_AFTEREFFECT ] = &(p->Value);;
912 : }
913 12 : p++;
914 : }
915 : }
916 12 : }
917 :
918 0 : sal_uInt32 AnimationExporter::GetPresetID( const OUString& rPreset, sal_uInt32 nAPIPresetClass, bool& bPresetId )
919 : {
920 0 : sal_uInt32 nPresetId = 0;
921 0 : bPresetId = false;
922 :
923 0 : if ( rPreset.match( OUString( "ppt_" ), 0 ) )
924 : {
925 0 : sal_Int32 nLast = rPreset.lastIndexOf( '_' );
926 0 : if ( ( nLast != -1 ) && ( ( nLast + 1 ) < rPreset.getLength() ) )
927 : {
928 0 : OUString aNumber( rPreset.copy( nLast + 1 ) );
929 0 : nPresetId = aNumber.toInt32();
930 0 : bPresetId = true;
931 : }
932 : }
933 : else
934 : {
935 0 : const preset_maping* p = gPresetMaping;
936 0 : while( p->mpStrPresetId && ((p->mnPresetClass != (sal_Int32)nAPIPresetClass) || !rPreset.equalsAscii( p->mpStrPresetId )) )
937 0 : p++;
938 :
939 0 : if( p->mpStrPresetId )
940 : {
941 0 : nPresetId = p->mnPresetId;
942 0 : bPresetId = true;
943 : }
944 : }
945 :
946 0 : return nPresetId;
947 : }
948 :
949 10 : sal_Int16 AnimationExporter::exportAnimPropertySet( SvStream& rStrm, const Reference< XAnimationNode >& xNode )
950 : {
951 10 : sal_Int16 nNodeType = ::com::sun::star::presentation::EffectNodeType::DEFAULT;
952 :
953 10 : EscherExContainer aAnimPropertySet( rStrm, DFF_msofbtAnimPropertySet );
954 :
955 20 : Reference< XAnimationNode > xMaster;
956 :
957 20 : Any aMasterRel, aOverride, aRunTimeContext;
958 :
959 : // storing user data into pAny, to allow direct access later
960 20 : const Sequence< NamedValue > aUserData = xNode->getUserData();
961 : const ::com::sun::star::uno::Any* pAny[ DFF_ANIM_PROPERTY_ID_COUNT ];
962 10 : GetUserData( aUserData, pAny, sizeof( pAny ) );
963 :
964 10 : if( pAny[ DFF_ANIM_AFTEREFFECT ] )
965 0 : ( *pAny[ DFF_ANIM_AFTEREFFECT ] ) >>= xMaster;
966 :
967 : // calculate master-rel
968 10 : if( xMaster.is() )
969 : {
970 0 : sal_Int32 nMasterRel = 2;
971 0 : if( xNode.is() && xMaster.is() && (xNode->getParent() == xMaster->getParent() ) )
972 0 : nMasterRel = 0;
973 :
974 0 : aMasterRel <<= nMasterRel;
975 :
976 0 : pAny[ DFF_ANIM_MASTERREL ] = &aMasterRel;
977 :
978 0 : aOverride <<= (sal_Int32)1;
979 0 : pAny[ DFF_ANIM_OVERRIDE ] = &aOverride;
980 :
981 0 : aRunTimeContext <<= (sal_Int32)1;
982 0 : pAny[ DFF_ANIM_RUNTIMECONTEXT ] = &aRunTimeContext;
983 : }
984 :
985 : // the order is important
986 10 : if ( pAny[ DFF_ANIM_NODE_TYPE ] )
987 : {
988 10 : if ( *pAny[ DFF_ANIM_NODE_TYPE ] >>= nNodeType )
989 : {
990 10 : sal_uInt32 nPPTNodeType = DFF_ANIM_NODE_TYPE_ON_CLICK;
991 10 : switch( nNodeType )
992 : {
993 0 : case ::com::sun::star::presentation::EffectNodeType::ON_CLICK : nPPTNodeType = DFF_ANIM_NODE_TYPE_ON_CLICK; break;
994 0 : case ::com::sun::star::presentation::EffectNodeType::WITH_PREVIOUS : nPPTNodeType = DFF_ANIM_NODE_TYPE_WITH_PREVIOUS; break;
995 0 : case ::com::sun::star::presentation::EffectNodeType::AFTER_PREVIOUS : nPPTNodeType = DFF_ANIM_NODE_TYPE_AFTER_PREVIOUS; break;
996 5 : case ::com::sun::star::presentation::EffectNodeType::MAIN_SEQUENCE : nPPTNodeType = DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE; break;
997 5 : case ::com::sun::star::presentation::EffectNodeType::TIMING_ROOT : nPPTNodeType = DFF_ANIM_NODE_TYPE_TIMING_ROOT; break;
998 0 : case ::com::sun::star::presentation::EffectNodeType::INTERACTIVE_SEQUENCE: nPPTNodeType = DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ; break;
999 : }
1000 10 : exportAnimPropertyuInt32( rStrm, DFF_ANIM_NODE_TYPE, nPPTNodeType, TRANSLATE_NONE );
1001 : }
1002 : }
1003 10 : sal_uInt32 nPresetId = 0;
1004 10 : sal_uInt32 nPresetSubType = 0;
1005 10 : sal_uInt32 nAPIPresetClass = EffectPresetClass::CUSTOM;
1006 10 : sal_uInt32 nPresetClass = DFF_ANIM_PRESS_CLASS_USER_DEFINED;
1007 : bool bPresetClass, bPresetId, bPresetSubType;
1008 10 : bPresetId = bPresetClass = bPresetSubType = false;
1009 :
1010 10 : if ( pAny[ DFF_ANIM_PRESET_CLASS ] )
1011 : {
1012 0 : if ( *pAny[ DFF_ANIM_PRESET_CLASS ] >>= nAPIPresetClass )
1013 : {
1014 : sal_uInt8 nPPTPresetClass;
1015 0 : switch( nAPIPresetClass )
1016 : {
1017 0 : case EffectPresetClass::ENTRANCE : nPPTPresetClass = DFF_ANIM_PRESS_CLASS_ENTRANCE; break;
1018 0 : case EffectPresetClass::EXIT : nPPTPresetClass = DFF_ANIM_PRESS_CLASS_EXIT; break;
1019 0 : case EffectPresetClass::EMPHASIS : nPPTPresetClass = DFF_ANIM_PRESS_CLASS_EMPHASIS; break;
1020 0 : case EffectPresetClass::MOTIONPATH : nPPTPresetClass = DFF_ANIM_PRESS_CLASS_MOTIONPATH; break;
1021 0 : case EffectPresetClass::OLEACTION : nPPTPresetClass = DFF_ANIM_PRESS_CLASS_OLE_ACTION; break;
1022 0 : case EffectPresetClass::MEDIACALL : nPPTPresetClass = DFF_ANIM_PRESS_CLASS_MEDIACALL; break;
1023 : default :
1024 0 : nPPTPresetClass = DFF_ANIM_PRESS_CLASS_USER_DEFINED;
1025 : }
1026 0 : nPresetClass = nPPTPresetClass;
1027 0 : bPresetClass = true;
1028 : }
1029 : }
1030 10 : if ( pAny[ DFF_ANIM_PRESET_ID ] )
1031 : {
1032 0 : OUString sPreset;
1033 0 : if ( *pAny[ DFF_ANIM_PRESET_ID ] >>= sPreset )
1034 0 : nPresetId = GetPresetID( sPreset, nAPIPresetClass, bPresetId );
1035 : }
1036 :
1037 10 : if ( pAny[ DFF_ANIM_PRESET_SUB_TYPE ] )
1038 : {
1039 0 : OUString sPresetSubType;
1040 0 : if ( *pAny[ DFF_ANIM_PRESET_SUB_TYPE ] >>= sPresetSubType )
1041 : {
1042 0 : nPresetSubType = TranslatePresetSubType( nPresetClass, nPresetId, sPresetSubType );
1043 0 : bPresetSubType = true;
1044 0 : }
1045 : }
1046 10 : if ( bPresetId )
1047 0 : exportAnimPropertyuInt32( rStrm, DFF_ANIM_PRESET_ID, nPresetId, TRANSLATE_NONE );
1048 10 : if ( bPresetSubType )
1049 0 : exportAnimPropertyuInt32( rStrm, DFF_ANIM_PRESET_SUB_TYPE, nPresetSubType, TRANSLATE_NONE );
1050 10 : if ( bPresetClass )
1051 0 : exportAnimPropertyuInt32( rStrm, DFF_ANIM_PRESET_CLASS, nPresetClass, TRANSLATE_NONE );
1052 :
1053 10 : if ( pAny[ DFF_ANIM_ID ] )
1054 : {
1055 : // TODO DFF_ANIM_ID
1056 : }
1057 :
1058 10 : if ( pAny[ DFF_ANIM_AFTEREFFECT ] )
1059 : {
1060 0 : bool bAfterEffect = false;
1061 0 : if ( *pAny[ DFF_ANIM_AFTEREFFECT ] >>= bAfterEffect )
1062 0 : exportAnimPropertyByte( rStrm, DFF_ANIM_AFTEREFFECT, int(bAfterEffect), TRANSLATE_NONE );
1063 : }
1064 :
1065 10 : if ( pAny[ DFF_ANIM_RUNTIMECONTEXT ] )
1066 : {
1067 0 : sal_Int32 nRunTimeContext = 0;
1068 0 : if ( *pAny[ DFF_ANIM_RUNTIMECONTEXT ] >>= nRunTimeContext )
1069 0 : exportAnimPropertyuInt32( rStrm, DFF_ANIM_RUNTIMECONTEXT, nRunTimeContext, TRANSLATE_NONE );
1070 : }
1071 10 : if ( pAny[ DFF_ANIM_PATH_EDIT_MODE ] )
1072 : {
1073 : // TODO DFF_ANIM_ID
1074 : }
1075 :
1076 10 : if( !xMaster.is() )
1077 : {
1078 10 : Reference< XAnimateColor > xColor( xNode, UNO_QUERY );
1079 10 : if( xColor.is() )
1080 : {
1081 :
1082 0 : bool bDirection = !xColor->getDirection();
1083 0 : exportAnimPropertyuInt32( rStrm, DFF_ANIM_DIRECTION, bDirection ? 1 : 0, TRANSLATE_NONE );
1084 10 : }
1085 : }
1086 :
1087 10 : if ( pAny[ DFF_ANIM_OVERRIDE ] )
1088 : {
1089 0 : sal_Int32 nOverride = 0;
1090 0 : if ( *pAny[ DFF_ANIM_OVERRIDE ] >>= nOverride )
1091 0 : exportAnimPropertyuInt32( rStrm, DFF_ANIM_OVERRIDE, nOverride, TRANSLATE_NONE );
1092 : }
1093 :
1094 10 : if ( pAny[ DFF_ANIM_MASTERREL ] )
1095 : {
1096 0 : sal_Int32 nMasterRel = 0;
1097 0 : if ( *pAny[ DFF_ANIM_MASTERREL ] >>= nMasterRel )
1098 0 : exportAnimPropertyuInt32( rStrm, DFF_ANIM_MASTERREL, nMasterRel, TRANSLATE_NONE );
1099 : }
1100 :
1101 : /* todo
1102 : Reference< XAudio > xAudio( xNode, UNO_QUERY );
1103 : if( xAudio.is() )
1104 : {
1105 : sal_Int16 nEndAfterSlide = 0;
1106 : nEndAfterSlide = xAudio->getEndAfterSlide();
1107 : exportAnimPropertyuInt32( rStrm, DFF_ANIM_ENDAFTERSLIDE, nEndAfterSlide, TRANSLATE_NONE );
1108 : }
1109 : */
1110 10 : Reference< XAnimate > xAnim( xNode, UNO_QUERY );
1111 10 : if( xAnim.is() )
1112 : {
1113 : // TODO: DFF_ANIM_TIMEFILTER
1114 : }
1115 10 : if ( pAny[ DFF_ANIM_EVENT_FILTER ] )
1116 : {
1117 : // TODO DFF_ANIM_EVENT_FILTER
1118 : }
1119 10 : if ( pAny[ DFF_ANIM_VOLUME ] )
1120 : {
1121 : // TODO DFF_ANIM_VOLUME
1122 : }
1123 20 : return nNodeType;
1124 : }
1125 :
1126 0 : bool AnimationExporter::exportAnimProperty( SvStream& rStrm, const sal_uInt16 nPropertyId, const ::com::sun::star::uno::Any& rAny, const TranslateMode eTranslateMode )
1127 : {
1128 0 : bool bRet = false;
1129 0 : if ( rAny.hasValue() )
1130 : {
1131 0 : switch( rAny.getValueType().getTypeClass() )
1132 : {
1133 : case ::com::sun::star::uno::TypeClass_UNSIGNED_SHORT :
1134 : case ::com::sun::star::uno::TypeClass_SHORT :
1135 : case ::com::sun::star::uno::TypeClass_UNSIGNED_LONG :
1136 : case ::com::sun::star::uno::TypeClass_LONG :
1137 : {
1138 0 : sal_Int32 nVal = 0;
1139 0 : if ( rAny >>= nVal )
1140 : {
1141 0 : exportAnimPropertyuInt32( rStrm, nPropertyId, nVal, eTranslateMode );
1142 0 : bRet = true;
1143 : }
1144 : }
1145 0 : break;
1146 :
1147 : case ::com::sun::star::uno::TypeClass_DOUBLE :
1148 : {
1149 0 : double fVal = 0.0;
1150 0 : if ( rAny >>= fVal )
1151 : {
1152 0 : exportAnimPropertyFloat( rStrm, nPropertyId, fVal, eTranslateMode );
1153 0 : bRet = true;
1154 : }
1155 : }
1156 0 : break;
1157 : case ::com::sun::star::uno::TypeClass_FLOAT :
1158 : {
1159 0 : float fVal = 0.0;
1160 0 : if ( rAny >>= fVal )
1161 : {
1162 0 : if ( eTranslateMode & TRANSLATE_NUMBER_TO_STRING )
1163 : {
1164 0 : Any aAny;
1165 0 : OUString aNumber( OUString::number( fVal ) );
1166 0 : aAny <<= aNumber;
1167 0 : exportAnimPropertyString( rStrm, nPropertyId, aNumber, eTranslateMode );
1168 : }
1169 : else
1170 : {
1171 0 : exportAnimPropertyFloat( rStrm, nPropertyId, fVal, eTranslateMode );
1172 0 : bRet = true;
1173 : }
1174 : }
1175 : }
1176 0 : break;
1177 : case ::com::sun::star::uno::TypeClass_STRING :
1178 : {
1179 0 : OUString aStr;
1180 0 : if ( rAny >>= aStr )
1181 : {
1182 0 : exportAnimPropertyString( rStrm, nPropertyId, aStr, eTranslateMode );
1183 0 : bRet = true;
1184 0 : }
1185 : }
1186 0 : break;
1187 : default:
1188 0 : break;
1189 : }
1190 : }
1191 0 : return bRet;
1192 : }
1193 0 : void AnimationExporter::exportAnimPropertyString( SvStream& rStrm, const sal_uInt16 nPropertyId, const OUString& rVal, const TranslateMode eTranslateMode )
1194 : {
1195 0 : EscherExAtom aExAtom( rStrm, DFF_msofbtAnimAttributeValue, nPropertyId );
1196 0 : sal_uInt8 nType = DFF_ANIM_PROP_TYPE_UNISTRING;
1197 0 : rStrm.WriteUChar( nType );
1198 0 : OUString aStr( rVal );
1199 0 : if ( eTranslateMode != TRANSLATE_NONE )
1200 0 : ImplTranslateAttribute( aStr, eTranslateMode );
1201 0 : writeZString( rStrm, aStr );
1202 0 : }
1203 :
1204 0 : void AnimationExporter::exportAnimPropertyFloat( SvStream& rStrm, const sal_uInt16 nPropertyId, const double& rVal, const TranslateMode )
1205 : {
1206 0 : EscherExAtom aExAtom( rStrm, DFF_msofbtAnimAttributeValue, nPropertyId );
1207 0 : sal_uInt8 nType = DFF_ANIM_PROP_TYPE_FLOAT;
1208 0 : float fFloat = (float)rVal;
1209 0 : rStrm.WriteUChar( nType )
1210 0 : .WriteFloat( fFloat );
1211 0 : }
1212 :
1213 10 : void AnimationExporter::exportAnimPropertyuInt32( SvStream& rStrm, const sal_uInt16 nPropertyId, const sal_uInt32 nVal, const TranslateMode )
1214 : {
1215 10 : EscherExAtom aExAtom( rStrm, DFF_msofbtAnimAttributeValue, nPropertyId );
1216 10 : sal_uInt8 nType = DFF_ANIM_PROP_TYPE_INT32 ;
1217 10 : rStrm.WriteUChar( nType )
1218 10 : .WriteUInt32( nVal );
1219 10 : }
1220 :
1221 0 : void AnimationExporter::exportAnimPropertyByte( SvStream& rStrm, const sal_uInt16 nPropertyId, const sal_uInt8 nVal, const TranslateMode )
1222 : {
1223 0 : EscherExAtom aExAtom( rStrm, DFF_msofbtAnimAttributeValue, nPropertyId );
1224 0 : sal_uInt8 nType = DFF_ANIM_PROP_TYPE_BYTE;
1225 0 : rStrm.WriteUChar( nType )
1226 0 : .WriteUChar( nVal );
1227 0 : }
1228 :
1229 0 : void AnimationExporter::writeZString( SvStream& rStrm, const OUString& rVal )
1230 : {
1231 : sal_Int32 i;
1232 0 : for ( i = 0; i < rVal.getLength(); i++ )
1233 0 : rStrm.WriteUInt16( rVal[ i ] );
1234 0 : rStrm.WriteUInt16( 0 );
1235 0 : }
1236 :
1237 5 : void AnimationExporter::exportAnimAction( SvStream& rStrm, const Reference< XAnimationNode >& xNode )
1238 : {
1239 5 : EscherExAtom aExAtom( rStrm, DFF_msofbtAnimAction );
1240 :
1241 5 : sal_Int32 nConcurrent = 1;
1242 5 : sal_Int32 nNextAction = 1;
1243 5 : sal_Int32 nEndSync = 0;
1244 5 : sal_Int32 nU4 = 0;
1245 5 : sal_Int32 nU5 = 3;
1246 :
1247 5 : sal_Int16 nAnimationEndSync = 0;
1248 5 : if ( xNode->getEndSync() >>= nAnimationEndSync )
1249 : {
1250 0 : if ( nAnimationEndSync == AnimationEndSync::ALL )
1251 0 : nEndSync = 1;
1252 : }
1253 5 : rStrm.WriteInt32( nConcurrent )
1254 5 : .WriteInt32( nNextAction )
1255 5 : .WriteInt32( nEndSync )
1256 5 : .WriteInt32( nU4 )
1257 5 : .WriteInt32( nU5 );
1258 :
1259 5 : }
1260 :
1261 : // nFlags Bit 6 = fixInteractiveSequenceTiming (for child)
1262 : // nFlags Bit 5 = fixInteractiveSequenceTiming (for root)
1263 : // nFlags Bit 4 = first node of main sequence -> begin event next has to be replaced to indefinite
1264 10 : void AnimationExporter::exportAnimEvent( SvStream& rStrm, const Reference< XAnimationNode >& xNode, const sal_Int32 nFlags )
1265 : {
1266 : sal_uInt16 i;
1267 50 : for ( i = 0; i < 4; i++ )
1268 : {
1269 40 : sal_Int32 nU1 = 0;
1270 40 : sal_Int32 nTrigger = 0;
1271 40 : sal_Int32 nU3 = 0;
1272 40 : sal_Int32 nBegin = 0;
1273 :
1274 40 : bool bCreateEvent = false;
1275 40 : Any aSource;
1276 :
1277 40 : switch( i )
1278 : {
1279 : case 0 :
1280 : case 1 :
1281 : {
1282 20 : Any aAny;
1283 40 : Event aEvent;
1284 : com::sun::star::animations::Timing eTiming;
1285 20 : if ( i == 0 )
1286 : {
1287 10 : if ( nFlags & 0x20 )
1288 : {
1289 : // taking the first child
1290 0 : Reference< XEnumerationAccess > xEA( xNode, UNO_QUERY_THROW );
1291 0 : Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_QUERY_THROW );
1292 0 : if ( xE.is() && xE->hasMoreElements() )
1293 : {
1294 : {
1295 0 : Reference< XAnimationNode > xClickNode( xE->nextElement(), UNO_QUERY );
1296 0 : aAny = xClickNode->getBegin();
1297 : }
1298 0 : }
1299 : }
1300 10 : else if ( nFlags & 0x40 )
1301 : {
1302 : // begin has to be replaced with void, so don't do anything
1303 : }
1304 : else
1305 : {
1306 10 : aAny = xNode->getBegin();
1307 10 : if ( nFlags & 0x10 ) // replace ON_NEXT with IDEFINITE
1308 : {
1309 0 : if ( ( aAny >>= aEvent ) && ( aEvent.Trigger == EventTrigger::ON_NEXT ) )
1310 : {
1311 0 : eTiming = Timing_INDEFINITE;
1312 0 : aAny <<= eTiming;
1313 : }
1314 : }
1315 : }
1316 : }
1317 : else
1318 10 : aAny = xNode->getEnd();
1319 :
1320 20 : double fTiming = 0.0;
1321 20 : if ( aAny >>= aEvent )
1322 : {
1323 0 : bCreateEvent = true;
1324 0 : switch( aEvent.Trigger )
1325 : {
1326 0 : case EventTrigger::NONE : nTrigger = 0; break;
1327 0 : case EventTrigger::ON_BEGIN : nTrigger = 1; break;
1328 0 : case EventTrigger::ON_END : nTrigger = 2; break;
1329 0 : case EventTrigger::BEGIN_EVENT : nTrigger = 3; break;
1330 0 : case EventTrigger::END_EVENT : nTrigger = 4; nU1 = 2; nU3 = mnCurrentGroup; break;
1331 0 : case EventTrigger::ON_CLICK : nTrigger = 5; break;
1332 0 : case EventTrigger::ON_DBL_CLICK : nTrigger = 6; break;
1333 0 : case EventTrigger::ON_MOUSE_ENTER : nTrigger = 7; break;
1334 0 : case EventTrigger::ON_MOUSE_LEAVE : nTrigger = 8; break;
1335 0 : case EventTrigger::ON_NEXT : nTrigger = 9; break;
1336 0 : case EventTrigger::ON_PREV : nTrigger = 10; break;
1337 0 : case EventTrigger::ON_STOP_AUDIO : nTrigger = 11; break;
1338 : }
1339 0 : if ( aEvent.Offset.hasValue() )
1340 : {
1341 0 : if ( aEvent.Offset >>= eTiming )
1342 : {
1343 0 : if ( eTiming == Timing_INDEFINITE )
1344 0 : nBegin = -1;
1345 : }
1346 0 : else if ( aEvent.Offset >>= fTiming )
1347 0 : nBegin = (sal_Int32)( fTiming * 1000.0 );
1348 : }
1349 0 : aSource = aEvent.Source;
1350 : }
1351 20 : else if ( aAny >>= eTiming )
1352 : {
1353 0 : bCreateEvent = true;
1354 0 : if ( eTiming == Timing_INDEFINITE )
1355 0 : nBegin = -1;
1356 : }
1357 20 : else if ( aAny >>= fTiming )
1358 : {
1359 0 : bCreateEvent = true;
1360 0 : nBegin = (sal_Int32)( fTiming * 1000.0 );
1361 20 : }
1362 : }
1363 20 : break;
1364 :
1365 : case 2 :
1366 : {
1367 10 : if ( nFlags & ( 1 << i ) )
1368 : {
1369 5 : bCreateEvent = true;
1370 5 : nU1 = 1;
1371 5 : nTrigger = 9;
1372 : }
1373 : }
1374 10 : break;
1375 : case 3 :
1376 : {
1377 10 : if ( nFlags & ( 1 << i ) )
1378 : {
1379 5 : bCreateEvent = true;
1380 5 : nU1 = 1;
1381 5 : nTrigger = 10;
1382 : }
1383 : }
1384 10 : break;
1385 : };
1386 40 : if ( bCreateEvent )
1387 : {
1388 10 : EscherExContainer aAnimEvent( rStrm, DFF_msofbtAnimEvent, i + 1 );
1389 : {
1390 10 : EscherExAtom aAnimTrigger( rStrm, DFF_msofbtAnimTrigger );
1391 10 : rStrm.WriteInt32( nU1 )
1392 10 : .WriteInt32( nTrigger )
1393 10 : .WriteInt32( nU3 )
1394 10 : .WriteInt32( nBegin );
1395 : }
1396 10 : exportAnimateTargetElement( rStrm, aSource, ( nFlags & ( 1 << i ) ) != 0 );
1397 : }
1398 40 : }
1399 10 : }
1400 :
1401 0 : Any AnimationExporter::convertAnimateValue( const Any& rSourceValue, const OUString& rAttributeName )
1402 : {
1403 0 : OUString aDest;
1404 0 : if ( rAttributeName == "X"
1405 0 : || rAttributeName == "Y"
1406 0 : || rAttributeName == "Width"
1407 0 : || rAttributeName == "Height"
1408 : )
1409 : {
1410 0 : OUString aStr;
1411 0 : if ( rSourceValue >>= aStr )
1412 : {
1413 0 : ImplTranslateAttribute( aStr, TRANSLATE_MEASURE );
1414 0 : aDest += aStr;
1415 0 : }
1416 : }
1417 0 : else if ( rAttributeName == "Rotate" // "r" or "style.rotation" ?
1418 0 : || rAttributeName == "SkewX"
1419 0 : || rAttributeName == "Opacity"
1420 0 : || rAttributeName == "CharHeight"
1421 : )
1422 : {
1423 0 : double fNumber = 0.0;
1424 0 : if ( rSourceValue >>= fNumber )
1425 0 : aDest += OUString::number( fNumber );
1426 : }
1427 0 : else if ( rAttributeName == "Color"
1428 0 : || rAttributeName == "FillColor" // "Fillcolor" or "FillColor" ?
1429 0 : || rAttributeName == "LineColor"
1430 0 : || rAttributeName == "CharColor"
1431 : )
1432 : {
1433 0 : sal_Int32 nColor = 0;
1434 0 : Sequence< double > aHSL( 3 );
1435 0 : OUString aP( "," );
1436 0 : if ( rSourceValue >>= aHSL )
1437 : {
1438 0 : aDest += "hsl(";
1439 0 : aDest += OUString::number( (sal_Int32)( aHSL[ 0 ] / ( 360.0 / 255 ) ) );
1440 0 : aDest += aP;
1441 0 : aDest += OUString::number( (sal_Int32)( aHSL[ 1 ] * 255.0 ) );
1442 0 : aDest += aP;
1443 0 : aDest += OUString::number( (sal_Int32)( aHSL[ 2 ] * 255.0 ) );
1444 0 : aDest += ")";
1445 : }
1446 0 : else if ( rSourceValue >>= nColor )
1447 : {
1448 0 : aDest += "rgb(";
1449 0 : aDest += OUString::number( ( (sal_Int8)nColor ) );
1450 0 : aDest += aP;
1451 0 : aDest += OUString::number( ( (sal_Int8)( nColor >> 8 ) ) );
1452 0 : aDest += aP;
1453 0 : aDest += OUString::number( ( (sal_Int8)( nColor >> 16 ) ) );
1454 0 : aDest += ")";
1455 0 : }
1456 : }
1457 0 : else if ( rAttributeName == "FillStyle" )
1458 : {
1459 : ::com::sun::star::drawing::FillStyle eFillStyle;
1460 0 : if ( rSourceValue >>= eFillStyle )
1461 : {
1462 0 : if ( eFillStyle == ::com::sun::star::drawing::FillStyle_NONE )
1463 0 : aDest += "none"; // ?
1464 : else
1465 0 : aDest += "solid";
1466 : }
1467 : }
1468 0 : else if ( rAttributeName == "LineStyle" )
1469 : {
1470 : ::com::sun::star::drawing::LineStyle eLineStyle;
1471 0 : if ( rSourceValue >>= eLineStyle )
1472 : {
1473 0 : if ( eLineStyle == ::com::sun::star::drawing::LineStyle_NONE )
1474 0 : aDest += "false";
1475 : else
1476 0 : aDest += "true";
1477 : }
1478 : }
1479 0 : else if ( rAttributeName == "CharWeight" )
1480 : {
1481 0 : float fFontWeight = 0.0;
1482 0 : if ( rSourceValue >>= fFontWeight )
1483 : {
1484 0 : if ( fFontWeight == com::sun::star::awt::FontWeight::BOLD )
1485 0 : aDest += "bold";
1486 : else
1487 0 : aDest += "normal";
1488 : }
1489 : }
1490 0 : else if ( rAttributeName == "CharUnderline" )
1491 : {
1492 0 : sal_Int16 nFontUnderline = 0;
1493 0 : if ( rSourceValue >>= nFontUnderline )
1494 : {
1495 0 : if ( nFontUnderline == com::sun::star::awt::FontUnderline::NONE )
1496 0 : aDest += "false";
1497 : else
1498 0 : aDest += "true";
1499 : }
1500 : }
1501 0 : else if ( rAttributeName == "CharPosture" )
1502 : {
1503 : ::com::sun::star::awt::FontSlant eFontSlant;
1504 0 : if ( rSourceValue >>= eFontSlant )
1505 : {
1506 0 : if ( eFontSlant == com::sun::star::awt::FontSlant_ITALIC )
1507 0 : aDest += "italic";
1508 : else
1509 0 : aDest += "normal"; // ?
1510 : }
1511 : }
1512 0 : else if ( rAttributeName == "Visibility" )
1513 : {
1514 0 : bool bVisible = true;
1515 0 : if ( rSourceValue >>= bVisible )
1516 : {
1517 0 : if ( bVisible )
1518 0 : aDest += "visible";
1519 : else
1520 0 : aDest += "hidden";
1521 : }
1522 : }
1523 0 : Any aRet;
1524 0 : if ( !aDest.isEmpty() )
1525 0 : aRet <<= aDest;
1526 : else
1527 0 : aRet = rSourceValue;
1528 0 : return aRet;
1529 : }
1530 :
1531 0 : void AnimationExporter::exportAnimateSet( SvStream& rStrm, const Reference< XAnimationNode >& xNode, int nAfterEffectType )
1532 : {
1533 0 : Reference< XAnimateSet > xSet( xNode, UNO_QUERY );
1534 0 : if( xSet.is() )
1535 : {
1536 0 : EscherExContainer aAnimateSet( rStrm, DFF_msofbtAnimateSet, 0 );
1537 : {
1538 0 : EscherExAtom aAnimateSetData( rStrm, DFF_msofbtAnimateSetData );
1539 0 : sal_uInt32 nId1 = 1; // ??
1540 0 : sal_uInt32 nId2 = 1; // ??
1541 0 : rStrm.WriteUInt32( nId1 ).WriteUInt32( nId2 );
1542 : }
1543 0 : Any aConvertedValue( convertAnimateValue( xSet->getTo(), xSet->getAttributeName() ) );
1544 0 : if ( aConvertedValue.hasValue() )
1545 0 : exportAnimProperty( rStrm, 1, aConvertedValue, TRANSLATE_NONE );
1546 0 : exportAnimateTarget( rStrm, xNode, 0, nAfterEffectType );
1547 0 : }
1548 0 : }
1549 :
1550 0 : sal_uInt32 AnimationExporter::GetValueTypeForAttributeName( const OUString& rAttributeName )
1551 : {
1552 0 : sal_uInt32 nValueType = 0;
1553 :
1554 : struct Entry
1555 : {
1556 : const sal_Char* pName;
1557 : sal_uInt8 nType;
1558 : };
1559 : static const Entry lcl_attributeMap[] =
1560 : {
1561 : { "charcolor", 2 },
1562 : { "charfontname", 0 },
1563 : { "charheight", 1 },
1564 : { "charposture", 0 },
1565 : // TODO(Q1): This should prolly be changed in PPT import
1566 : // { "charrotation", ATTRIBUTE_CHAR_ROTATION },
1567 : { "charrotation", 1 },
1568 : { "charunderline", 0 },
1569 : { "charweight", 0 },
1570 : { "color", 2 },
1571 : { "dimcolor", 2 },
1572 : { "fillcolor", 2 },
1573 : { "fillstyle", 0 },
1574 : { "height", 1 },
1575 : { "linecolor", 2 },
1576 : { "linestyle", 0 },
1577 : { "opacity", 0 },
1578 : { "rotate", 1 },
1579 : { "skewx", 1 },
1580 : { "skewy", 1 },
1581 : { "visibility", 1 },
1582 : { "width", 1 },
1583 : { "x", 1 },
1584 : { "y", 1 },
1585 : { NULL, 0 }
1586 : };
1587 0 : const Entry* pPtr = &lcl_attributeMap[ 0 ];
1588 0 : while( pPtr->pName )
1589 : {
1590 0 : if ( rAttributeName.equalsIgnoreAsciiCaseAscii( pPtr->pName ) )
1591 : {
1592 0 : nValueType = pPtr->nType;
1593 0 : break;
1594 : }
1595 0 : pPtr++;
1596 : }
1597 : DBG_ASSERT( pPtr->pName, "GetValueTypeForAttributeName, unknown property value!" );
1598 0 : return nValueType;
1599 : }
1600 :
1601 0 : void AnimationExporter::exportAnimate( SvStream& rStrm, const Reference< XAnimationNode >& xNode )
1602 : {
1603 0 : Reference< XAnimate > xAnimate( xNode, UNO_QUERY );
1604 0 : if ( xAnimate.is() )
1605 : {
1606 0 : Any aBy ( xAnimate->getBy() );
1607 0 : Any aFrom( xAnimate->getFrom() );
1608 0 : Any aTo ( xAnimate->getTo() );
1609 :
1610 0 : EscherExContainer aContainer( rStrm, DFF_msofbtAnimate, 0 );
1611 : {
1612 0 : EscherExAtom aAnimateData( rStrm, DFF_msofbtAnimateData );
1613 0 : sal_uInt32 nBits = 0x38;
1614 0 : sal_Int16 nTmp = xAnimate->getCalcMode();
1615 0 : sal_uInt32 nCalcMode = /* (nTmp == AnimationCalcMode::FORMULA) ? 2 : */ (nTmp == AnimationCalcMode::LINEAR) ? 1 : 0;
1616 0 : nTmp = xAnimate->getValueType();
1617 0 : sal_uInt32 nValueType = GetValueTypeForAttributeName( xAnimate->getAttributeName() );
1618 :
1619 0 : if ( aBy.hasValue() )
1620 0 : nBits |= 1;
1621 0 : if ( aFrom.hasValue() )
1622 0 : nBits |= 2;
1623 0 : if ( aTo.hasValue() )
1624 0 : nBits |= 4;
1625 :
1626 0 : rStrm.WriteUInt32( nCalcMode )
1627 0 : .WriteUInt32( nBits )
1628 0 : .WriteUInt32( nValueType );
1629 : }
1630 0 : if ( aBy.hasValue() )
1631 0 : exportAnimProperty( rStrm, 1, aBy, TRANSLATE_NUMBER_TO_STRING | TRANSLATE_MEASURE );
1632 0 : if ( aFrom.hasValue() )
1633 0 : exportAnimProperty( rStrm, 2, aFrom, TRANSLATE_NUMBER_TO_STRING | TRANSLATE_MEASURE );
1634 0 : if ( aTo.hasValue() )
1635 0 : exportAnimProperty( rStrm, 3, aTo, TRANSLATE_NUMBER_TO_STRING | TRANSLATE_MEASURE );
1636 :
1637 0 : exportAnimateKeyPoints( rStrm, xAnimate );
1638 0 : exportAnimateTarget( rStrm, xNode );
1639 0 : }
1640 0 : }
1641 :
1642 0 : void AnimationExporter::exportAnimateTarget( SvStream& rStrm, const Reference< XAnimationNode >& xNode, const sal_uInt32 nForceAttributeNames, int nAfterEffectType )
1643 : {
1644 0 : EscherExContainer aAnimateTarget( rStrm, DFF_msofbtAnimateTarget, 0 );
1645 0 : Reference< XAnimate > xAnimate( xNode, UNO_QUERY );
1646 0 : if ( xAnimate.is() )
1647 : {
1648 : {
1649 0 : EscherExAtom aAnimateTargetSettings( rStrm, DFF_msofbtAnimateTargetSettings, 0 );
1650 : // nBits %0001: additive, %0010: accumulate, %0100: attributeName, %1000: transformtype
1651 : // nAdditive 0 = base, 1 = sum, 2 = replace, 3 = multiply, 4 = none
1652 : // nAccumulate 0 = none, 1 = always
1653 : // nTransformType 0: "property" else "image"
1654 0 : sal_uInt32 nBits = 0;
1655 0 : sal_uInt32 nAdditive = 0;
1656 0 : sal_uInt32 nAccumulate = 0;
1657 0 : sal_uInt32 nTransformType = 0;
1658 0 : if ( xAnimate.is() )
1659 : {
1660 0 : if ( !xAnimate->getAttributeName().isEmpty() )
1661 0 : nBits |= 4; // what is attributeName ?, maybe this is set if a DFF_msofbtAnimateAttributeNames is written
1662 0 : sal_Int16 nAdditiveMode = xAnimate->getAdditive();
1663 0 : if ( nAdditiveMode != AnimationAdditiveMode::BASE )
1664 : {
1665 0 : nBits |= 1;
1666 0 : switch( nAdditiveMode )
1667 : {
1668 0 : case AnimationAdditiveMode::SUM : nAdditive = 1; break;
1669 0 : case AnimationAdditiveMode::REPLACE : nAdditive = 2; break;
1670 0 : case AnimationAdditiveMode::MULTIPLY : nAdditive = 3; break;
1671 0 : case AnimationAdditiveMode::NONE : nAdditive = 4; break;
1672 : }
1673 : }
1674 0 : if ( xAnimate->getAccumulate() )
1675 : {
1676 0 : nBits |= 2;
1677 0 : nAccumulate = 1;
1678 : }
1679 : }
1680 0 : rStrm.WriteUInt32( nBits )
1681 0 : .WriteUInt32( nAdditive )
1682 0 : .WriteUInt32( nAccumulate )
1683 0 : .WriteUInt32( nTransformType );
1684 : }
1685 0 : if ( !xAnimate->getAttributeName().isEmpty() || nForceAttributeNames )
1686 : {
1687 0 : EscherExContainer aAnimateAttributeNames( rStrm, DFF_msofbtAnimateAttributeNames, 1 );
1688 0 : OUString aAttributeName( xAnimate->getAttributeName() );
1689 0 : if ( nForceAttributeNames )
1690 : {
1691 0 : if( nForceAttributeNames == 1 )
1692 : {
1693 0 : aAttributeName = "r";
1694 : }
1695 : }
1696 0 : sal_Int32 nIndex = 0;
1697 0 : do
1698 : {
1699 0 : OUString aToken( aAttributeName.getToken( 0, ';', nIndex ) );
1700 0 : exportAnimPropertyString( rStrm, 0, aToken, TRANSLATE_ATTRIBUTE );
1701 : }
1702 0 : while ( nIndex >= 0 );
1703 : }
1704 :
1705 0 : if( nAfterEffectType != AFTEREFFECT_NONE )
1706 : {
1707 0 : EscherExContainer aAnimPropertySet( rStrm, DFF_msofbtAnimPropertySet );
1708 0 : exportAnimPropertyuInt32( rStrm, 6, 1, TRANSLATE_NONE );
1709 0 : if( nAfterEffectType == AFTEREFFECT_COLOR )
1710 : {
1711 0 : exportAnimPropertyuInt32( rStrm, 4, 0, TRANSLATE_NONE );
1712 0 : exportAnimPropertyuInt32( rStrm, 5, 0, TRANSLATE_NONE );
1713 0 : }
1714 : }
1715 0 : exportAnimateTargetElement( rStrm, aTarget.hasValue() ? aTarget : xAnimate->getTarget(), false );
1716 0 : }
1717 0 : }
1718 :
1719 10 : Reference< XShape > AnimationExporter::getTargetElementShape( const Any& rAny, sal_Int32& rBegin, sal_Int32& rEnd, bool& rParagraphTarget )
1720 : {
1721 10 : Reference< XShape > xShape;
1722 10 : rAny >>= xShape;
1723 :
1724 10 : rParagraphTarget = false;
1725 :
1726 10 : if( !xShape.is() )
1727 : {
1728 10 : ParagraphTarget aParaTarget;
1729 10 : if( rAny >>= aParaTarget )
1730 0 : xShape = aParaTarget.Shape;
1731 10 : if ( xShape.is() )
1732 : {
1733 : // now calculating the character range for the paragraph
1734 0 : sal_Int16 nParagraph = aParaTarget.Paragraph;
1735 0 : Reference< XSimpleText > xText( xShape, UNO_QUERY );
1736 0 : if ( xText.is() )
1737 : {
1738 0 : rParagraphTarget = true;
1739 0 : Reference< XEnumerationAccess > xTextParagraphEnumerationAccess( xText, UNO_QUERY );
1740 0 : if ( xTextParagraphEnumerationAccess.is() )
1741 : {
1742 0 : Reference< XEnumeration > xTextParagraphEnumeration( xTextParagraphEnumerationAccess->createEnumeration() );
1743 0 : if ( xTextParagraphEnumeration.is() )
1744 : {
1745 : sal_Int16 nCurrentParagraph;
1746 0 : rBegin = rEnd = nCurrentParagraph = 0;
1747 0 : while ( xTextParagraphEnumeration->hasMoreElements() )
1748 : {
1749 0 : Reference< XTextRange > xTextRange( xTextParagraphEnumeration->nextElement(), UNO_QUERY );
1750 0 : if ( xTextRange.is() )
1751 : {
1752 0 : OUString aParaText( xTextRange->getString() );
1753 0 : sal_Int32 nLength = aParaText.getLength() + 1;
1754 0 : rEnd += nLength;
1755 0 : if ( nCurrentParagraph == nParagraph )
1756 0 : break;
1757 0 : nCurrentParagraph++;
1758 0 : rBegin += nLength;
1759 : }
1760 0 : }
1761 0 : }
1762 0 : }
1763 0 : }
1764 10 : }
1765 : }
1766 :
1767 10 : return xShape;
1768 : }
1769 :
1770 10 : void AnimationExporter::exportAnimateTargetElement( SvStream& rStrm, const Any& rAny, const bool bCreate2b01Atom )
1771 : {
1772 10 : sal_uInt32 nRefMode = 0; // nRefMode == 2 -> Paragraph
1773 10 : sal_Int32 begin = -1;
1774 10 : sal_Int32 end = -1;
1775 : bool bParagraphTarget;
1776 :
1777 10 : Reference< XShape > xShape = getTargetElementShape(rAny, begin, end, bParagraphTarget);
1778 :
1779 10 : if( bParagraphTarget )
1780 0 : nRefMode = 2;
1781 :
1782 10 : if ( xShape.is() || bCreate2b01Atom )
1783 : {
1784 10 : EscherExContainer aAnimateTargetElement( rStrm, DFF_msofbtAnimateTargetElement );
1785 10 : if ( xShape.is() )
1786 : {
1787 0 : EscherExAtom aAnimReference( rStrm, DFF_msofbtAnimReference );
1788 :
1789 0 : sal_uInt32 nRefType = 1; // TODO: nRefType == 2 -> Sound;
1790 0 : sal_uInt32 nRefId = ((EscherSolverContainer&)mrSolverContainer).GetShapeId( xShape );
1791 :
1792 0 : rStrm.WriteUInt32( nRefMode )
1793 0 : .WriteUInt32( nRefType )
1794 0 : .WriteUInt32( nRefId )
1795 0 : .WriteInt32( begin )
1796 0 : .WriteInt32( end );
1797 : }
1798 10 : if ( bCreate2b01Atom )
1799 : {
1800 10 : EscherExAtom a2b01Atom( rStrm, 0x2b01 );
1801 10 : rStrm.WriteUInt32( 1 ); // ?
1802 10 : }
1803 10 : }
1804 10 : }
1805 :
1806 0 : void AnimationExporter::exportAnimateKeyPoints( SvStream& rStrm, const Reference< XAnimate >& xAnimate )
1807 : {
1808 0 : Sequence< double > aKeyTimes( xAnimate->getKeyTimes() );
1809 0 : Sequence< Any > aValues( xAnimate->getValues() );
1810 0 : OUString aFormula( xAnimate->getFormula() );
1811 0 : if ( aKeyTimes.getLength() )
1812 : {
1813 0 : EscherExContainer aAnimKeyPoints( rStrm, DFF_msofbtAnimKeyPoints );
1814 : sal_Int32 i;
1815 0 : for ( i = 0; i < aKeyTimes.getLength(); i++ )
1816 : {
1817 : {
1818 0 : EscherExAtom aAnimKeyTime( rStrm, DFF_msofbtAnimKeyTime );
1819 0 : sal_Int32 nKeyTime = (sal_Int32)( aKeyTimes[ i ] * 1000.0 );
1820 0 : rStrm.WriteInt32( nKeyTime );
1821 : }
1822 0 : Any aAny[ 2 ];
1823 0 : if ( aValues[ i ].hasValue() )
1824 : {
1825 0 : ValuePair aPair;
1826 0 : if ( aValues[ i ] >>= aPair )
1827 : {
1828 0 : aAny[ 0 ] = convertAnimateValue( aPair.First, xAnimate->getAttributeName() );
1829 0 : aAny[ 1 ] = convertAnimateValue( aPair.Second, xAnimate->getAttributeName() );
1830 : }
1831 : else
1832 : {
1833 0 : aAny[ 0 ] = convertAnimateValue( aValues[ i ], xAnimate->getAttributeName() );
1834 : }
1835 0 : if ( !i && !aFormula.isEmpty() )
1836 : {
1837 0 : ImplTranslateAttribute( aFormula, TRANSLATE_MEASURE );
1838 0 : aAny[ 1 ] <<= aFormula;
1839 : }
1840 0 : exportAnimProperty( rStrm, 0, aAny[ 0 ], TRANSLATE_NONE );
1841 0 : exportAnimProperty( rStrm, 1, aAny[ 1 ], TRANSLATE_NONE );
1842 : }
1843 0 : }
1844 0 : }
1845 0 : }
1846 :
1847 10 : void AnimationExporter::exportAnimValue( SvStream& rStrm, const Reference< XAnimationNode >& xNode, const bool bExportAlways )
1848 : {
1849 10 : Any aAny;
1850 : // repeat count (0)
1851 10 : double fRepeat = 0.0;
1852 10 : float fRepeatCount = 0.0;
1853 : com::sun::star::animations::Timing eTiming;
1854 10 : aAny = xNode->getRepeatCount();
1855 10 : if ( aAny >>= eTiming )
1856 : {
1857 0 : if ( eTiming == Timing_INDEFINITE )
1858 0 : fRepeatCount = ((float)3.40282346638528860e+38);
1859 : }
1860 10 : else if ( aAny >>= fRepeat )
1861 0 : fRepeatCount = (float)fRepeat;
1862 10 : if ( fRepeatCount != 0.0 )
1863 : {
1864 0 : EscherExAtom aExAtom( rStrm, DFF_msofbtAnimValue );
1865 0 : sal_uInt32 nType = 0;
1866 0 : rStrm.WriteUInt32( nType )
1867 0 : .WriteFloat( fRepeatCount );
1868 : }
1869 : // accelerate (3)
1870 10 : float fAccelerate = (float)xNode->getAcceleration();
1871 10 : if ( bExportAlways || ( fAccelerate != 0.0 ) )
1872 : {
1873 0 : EscherExAtom aExAtom( rStrm, DFF_msofbtAnimValue );
1874 0 : sal_uInt32 nType = 3;
1875 0 : rStrm.WriteUInt32( nType )
1876 0 : .WriteFloat( fAccelerate );
1877 : }
1878 :
1879 : // decelerate (4)
1880 10 : float fDecelerate = (float)xNode->getDecelerate();
1881 10 : if ( bExportAlways || ( fDecelerate != 0.0 ) )
1882 : {
1883 0 : EscherExAtom aExAtom( rStrm, DFF_msofbtAnimValue );
1884 0 : sal_uInt32 nType = 4;
1885 0 : rStrm.WriteUInt32( nType )
1886 0 : .WriteFloat( fDecelerate );
1887 : }
1888 :
1889 : // autoreverse (5)
1890 10 : bool bAutoReverse = xNode->getAutoReverse();
1891 10 : if ( bExportAlways || bAutoReverse )
1892 : {
1893 0 : EscherExAtom aExAtom( rStrm, DFF_msofbtAnimValue );
1894 0 : sal_uInt32 nType = 5;
1895 0 : sal_uInt32 nVal = bAutoReverse ? 1 : 0;
1896 0 : rStrm.WriteUInt32( nType )
1897 0 : .WriteUInt32( nVal );
1898 10 : }
1899 10 : }
1900 :
1901 0 : void AnimationExporter::exportTransitionFilter( SvStream& rStrm, const Reference< XAnimationNode >& xNode )
1902 : {
1903 0 : Reference< XTransitionFilter > xFilter( xNode, UNO_QUERY );
1904 0 : if ( xFilter.is() )
1905 : {
1906 0 : EscherExContainer aAnimateFilter( rStrm, DFF_msofbtAnimateFilter );
1907 : {
1908 0 : EscherExAtom aAnimateFilterData( rStrm, DFF_msofbtAnimateFilterData );
1909 0 : sal_uInt32 nBits = 3; // bit 0 -> use AnimAttributeValue
1910 : // bit 1 -> use nTransition
1911 :
1912 0 : sal_uInt32 nTransition = xFilter->getMode() ? 0 : 1;
1913 0 : rStrm.WriteUInt32( nBits )
1914 0 : .WriteUInt32( nTransition );
1915 : }
1916 0 : const sal_Char* pFilter = FindTransitionName( xFilter->getTransition(), xFilter->getSubtype(), xFilter->getDirection() );
1917 0 : if ( pFilter )
1918 : {
1919 0 : const OUString aStr( OUString::createFromAscii( pFilter ) );
1920 0 : exportAnimPropertyString( rStrm, 1, aStr, TRANSLATE_NONE );
1921 : }
1922 0 : exportAnimateTarget( rStrm, xNode );
1923 0 : }
1924 0 : }
1925 :
1926 0 : void AnimationExporter::exportAnimateMotion( SvStream& rStrm, const Reference< XAnimationNode >& xNode )
1927 : {
1928 0 : Reference< XAnimateMotion > xMotion( xNode, UNO_QUERY );
1929 0 : if ( xMotion.is() )
1930 : {
1931 0 : EscherExContainer aAnimateMotion( rStrm, DFF_msofbtAnimateMotion );
1932 : {
1933 : { //SJ: Ignored from import filter
1934 0 : EscherExAtom aAnimateMotionData( rStrm, DFF_msofbtAnimateMotionData );
1935 0 : sal_uInt32 nBits = 0x98;
1936 0 : sal_uInt32 nOrigin = 0x2;
1937 0 : float fByX = 100.0; // nBits&1
1938 0 : float fByY = 100.0; // nBits&1
1939 0 : float fFromX = 0.0; // nBits&2
1940 0 : float fFromY = 0.0; // nBits&2
1941 0 : float fToX = 100.0; // nBits&4
1942 0 : float fToY = 100.0; // nBits&4
1943 0 : rStrm.WriteUInt32( nBits ).WriteFloat( fByX ).WriteFloat( fByY ).WriteFloat( fFromX ).WriteFloat( fFromY ).WriteFloat( fToX ).WriteFloat( fToY ).WriteUInt32( nOrigin );
1944 : }
1945 :
1946 0 : OUString aStr;
1947 0 : if ( xMotion->getPath() >>= aStr )
1948 : {
1949 0 : if ( !aStr.isEmpty() )
1950 0 : exportAnimPropertyString( rStrm, 1, aStr, TRANSLATE_NONE );
1951 : }
1952 0 : exportAnimateTarget( rStrm, xNode );
1953 0 : }
1954 0 : }
1955 0 : }
1956 :
1957 0 : void AnimationExporter::exportAnimateTransform( SvStream& rStrm, const Reference< XAnimationNode >& xNode )
1958 : {
1959 0 : Reference< XAnimateTransform > xTransform( xNode, UNO_QUERY );
1960 0 : if ( xTransform.is() )
1961 : {
1962 0 : if ( xTransform->getTransformType() == AnimationTransformType::SCALE )
1963 : {
1964 0 : EscherExContainer aAnimateScale( rStrm, DFF_msofbtAnimateScale );
1965 : {
1966 0 : EscherExAtom aAnimateScaleData( rStrm, DFF_msofbtAnimateScaleData );
1967 0 : sal_uInt32 nBits = 0;
1968 0 : sal_uInt32 nZoomContents = 1;
1969 0 : float fByX = 100.0;
1970 0 : float fByY = 100.0;
1971 0 : float fFromX = 0.0;
1972 0 : float fFromY = 0.0;
1973 0 : float fToX = 100.0;
1974 0 : float fToY = 100.0;
1975 :
1976 0 : double fX = 0.0, fY = 0.0;
1977 0 : ValuePair aPair;
1978 0 : if ( xTransform->getBy() >>= aPair )
1979 : {
1980 0 : if ( ( aPair.First >>= fX ) && ( aPair.Second >>= fY ) )
1981 : {
1982 0 : nBits |= 1;
1983 0 : fByX = (float)( fX * 100 );
1984 0 : fByY = (float)( fY * 100 );
1985 : }
1986 : }
1987 0 : if ( xTransform->getFrom() >>= aPair )
1988 : {
1989 0 : if ( ( aPair.First >>= fX ) && ( aPair.Second >>= fY ) )
1990 : {
1991 0 : nBits |= 2;
1992 0 : fFromX = (float)( fX * 100 );
1993 0 : fFromY = (float)( fY * 100 );
1994 : }
1995 : }
1996 0 : if( xTransform->getTo() >>= aPair )
1997 : {
1998 0 : if ( ( aPair.First >>= fX ) && ( aPair.Second >>= fY ) )
1999 : {
2000 0 : nBits |= 4;
2001 0 : fToX = (float)( fX * 100 );
2002 0 : fToY = (float)( fY * 100 );
2003 : }
2004 : }
2005 :
2006 : // TODO: ZoomContents:
2007 : //if( nBits & 8 )
2008 : //( fprintf( mpFile, " zoomContents=\"%s\"", nZoomContents ? "true" : "false" );
2009 :
2010 0 : rStrm.WriteUInt32( nBits ).WriteFloat( fByX ).WriteFloat( fByY ).WriteFloat( fFromX ).WriteFloat( fFromY ).WriteFloat( fToX ).WriteFloat( fToY ).WriteUInt32( nZoomContents );
2011 : }
2012 0 : exportAnimateTarget( rStrm, xNode );
2013 : }
2014 0 : else if ( xTransform->getTransformType() == AnimationTransformType::ROTATE )
2015 : {
2016 0 : EscherExContainer aAnimateRotation( rStrm, DFF_msofbtAnimateRotation );
2017 : {
2018 0 : EscherExAtom aAnimateRotationData( rStrm, DFF_msofbtAnimateRotationData );
2019 0 : sal_uInt32 nBits = 0;
2020 0 : sal_uInt32 nU1 = 0;
2021 0 : float fBy = 360.0;
2022 0 : float fFrom = 0.0;
2023 0 : float fTo = 360.0;
2024 :
2025 0 : double fVal = 0.0;
2026 0 : if ( xTransform->getBy() >>= fVal )
2027 : {
2028 0 : nBits |= 1;
2029 0 : fBy = (float)fVal;
2030 : }
2031 0 : if ( xTransform->getFrom() >>= fVal )
2032 : {
2033 0 : nBits |= 2;
2034 0 : fFrom = (float)fVal;
2035 : }
2036 0 : if ( xTransform->getTo() >>= fVal )
2037 : {
2038 0 : nBits |= 4;
2039 0 : fTo = (float)fVal;
2040 : }
2041 0 : rStrm.WriteUInt32( nBits ).WriteFloat( fBy ).WriteFloat( fFrom ).WriteFloat( fTo ).WriteUInt32( nU1 );
2042 : }
2043 0 : exportAnimateTarget( rStrm, xNode, 1 );
2044 : }
2045 0 : }
2046 0 : }
2047 :
2048 0 : bool AnimationExporter::getColorAny( const Any& rAny, const sal_Int16 nColorSpace, sal_Int32& rMode, sal_Int32& rA, sal_Int32& rB, sal_Int32& rC )
2049 : {
2050 0 : bool bIsColor = true;
2051 :
2052 0 : rMode = 0;
2053 0 : if ( nColorSpace == AnimationColorSpace::HSL )
2054 0 : rMode = 1;
2055 :
2056 0 : sal_Int32 nColor = 0;
2057 0 : Sequence< double > aHSL( 3 );
2058 0 : if ( rAny >>= nColor ) // RGB color
2059 : {
2060 0 : rA = (sal_uInt8)( nColor >> 16 );
2061 0 : rB = (sal_uInt8)( nColor >> 8 );
2062 0 : rC = (sal_uInt8)( nColor );
2063 : }
2064 0 : else if ( rAny >>= aHSL ) // HSL
2065 : {
2066 0 : rA = (sal_Int32) ( aHSL[ 0 ] * 255.0 / 360.0 );
2067 0 : rB = (sal_Int32) ( aHSL[ 1 ] * 255.0 );
2068 0 : rC = (sal_Int32) ( aHSL[ 2 ] * 255.0 );
2069 : }
2070 : else
2071 0 : bIsColor = false;
2072 0 : return bIsColor;
2073 : }
2074 :
2075 0 : void AnimationExporter::exportAnimateColor( SvStream& rStrm, const Reference< XAnimationNode >& xNode, int nAfterEffectType )
2076 : {
2077 0 : Reference< XAnimateColor > xColor( xNode, UNO_QUERY );
2078 0 : if ( xColor.is() )
2079 : {
2080 0 : EscherExContainer aAnimateColor( rStrm, DFF_msofbtAnimateColor );
2081 : {
2082 0 : EscherExAtom aAnimateColorData( rStrm, DFF_msofbtAnimateColorData );
2083 0 : sal_uInt32 nBits = 8;
2084 :
2085 : sal_Int32 nByMode, nByA, nByB, nByC;
2086 0 : nByMode = nByA = nByB = nByC = 0;
2087 :
2088 : sal_Int32 nFromMode, nFromA, nFromB, nFromC;
2089 0 : nFromMode = nFromA = nFromB = nFromC = 0;
2090 :
2091 : sal_Int32 nToMode, nToA, nToB, nToC;
2092 0 : nToMode = nToA = nToB = nToC = 0;
2093 :
2094 0 : sal_Int16 nColorSpace = xColor->getColorInterpolation();
2095 :
2096 0 : Any aAny( xColor->getBy() );
2097 0 : if ( aAny.hasValue() )
2098 : {
2099 0 : if ( getColorAny( aAny, nColorSpace, nByMode, nByA, nByB, nByC ) )
2100 0 : nBits |= 0x11;
2101 : }
2102 0 : aAny = xColor->getFrom();
2103 0 : if ( aAny.hasValue() )
2104 : {
2105 0 : if ( getColorAny( aAny, nColorSpace, nFromMode, nFromA, nFromB, nFromC ) )
2106 0 : nBits |= 0x12;
2107 : }
2108 0 : aAny = xColor->getTo();
2109 0 : if ( aAny.hasValue() )
2110 : {
2111 0 : if ( getColorAny( aAny, nColorSpace, nToMode, nToA, nToB, nToC ) )
2112 0 : nBits |= 0x14;
2113 : }
2114 0 : rStrm .WriteUInt32( nBits )
2115 0 : .WriteInt32( nByMode ).WriteInt32( nByA ).WriteInt32( nByB ).WriteInt32( nByC )
2116 0 : .WriteInt32( nFromMode ).WriteInt32( nFromA ).WriteInt32( nFromB ).WriteInt32( nFromC )
2117 0 : .WriteInt32( nToMode ).WriteInt32( nToA ).WriteInt32( nToB ).WriteInt32( nToC );
2118 : }
2119 0 : exportAnimateTarget( rStrm, xNode, 0, nAfterEffectType );
2120 0 : }
2121 0 : }
2122 :
2123 0 : void AnimationExporter::exportIterate( SvStream& rStrm, const Reference< XAnimationNode >& xNode )
2124 : {
2125 0 : Reference< XIterateContainer > xIterate( xNode, UNO_QUERY );
2126 0 : if ( xIterate.is() )
2127 : {
2128 0 : EscherExAtom aAnimIteration( rStrm, DFF_msofbtAnimIteration );
2129 :
2130 0 : float fInterval = 10.0;
2131 0 : sal_Int32 nTextUnitEffect = 0;
2132 0 : sal_Int32 nU1 = 1;
2133 0 : sal_Int32 nU2 = 1;
2134 0 : sal_Int32 nU3 = 0xe;
2135 :
2136 0 : sal_Int16 nIterateType = xIterate->getIterateType();
2137 0 : switch( nIterateType )
2138 : {
2139 0 : case TextAnimationType::BY_WORD : nTextUnitEffect = 1; break;
2140 0 : case TextAnimationType::BY_LETTER : nTextUnitEffect = 2; break;
2141 : }
2142 :
2143 0 : fInterval = (float)xIterate->getIterateInterval();
2144 :
2145 : // convert interval from absolute to percentage
2146 0 : double fDuration = 0.0;
2147 :
2148 0 : Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY );
2149 0 : if( xEnumerationAccess.is() )
2150 : {
2151 0 : Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
2152 0 : if( xEnumeration.is() )
2153 : {
2154 0 : while( xEnumeration->hasMoreElements() )
2155 : {
2156 0 : Reference< XAnimate > xChildNode( xEnumeration->nextElement(), UNO_QUERY );
2157 0 : if( xChildNode.is() )
2158 : {
2159 0 : double fChildBegin = 0.0;
2160 0 : double fChildDuration = 0.0;
2161 0 : xChildNode->getBegin() >>= fChildBegin;
2162 0 : xChildNode->getDuration() >>= fChildDuration;
2163 :
2164 0 : fChildDuration += fChildBegin;
2165 0 : if( fChildDuration > fDuration )
2166 0 : fDuration = fChildDuration;
2167 : }
2168 0 : }
2169 0 : }
2170 : }
2171 :
2172 0 : if( fDuration )
2173 0 : fInterval = (float)(100.0 * fInterval / fDuration);
2174 :
2175 0 : rStrm.WriteFloat( fInterval ).WriteInt32( nTextUnitEffect ).WriteInt32( nU1 ).WriteInt32( nU2 ).WriteInt32( nU3 );
2176 0 : aTarget = xIterate->getTarget();
2177 0 : }
2178 0 : }
2179 :
2180 12 : } // namespace ppt;
2181 :
2182 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|