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