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