1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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>
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>
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
;
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
;
92 void ImplTranslateAttribute( OUString
& rString
, const TranslateMode eTranslateMode
)
94 if ( eTranslateMode
!= TRANSLATE_NONE
)
96 if ( ( eTranslateMode
& TRANSLATE_VALUE
) || ( eTranslateMode
& TRANSLATE_ATTRIBUTE
) )
98 const ImplAttributeNameConversion
* p
= gImplConversionList
;
101 if( rString
.compareToAscii( p
->mpAPIName
) == 0 )
107 if ( eTranslateMode
& TRANSLATE_VALUE
)
109 rString
= OUString( (sal_Unicode
)'#' );
110 rString
+= OUString::createFromAscii( p
->mpMSName
);
113 rString
= OUString::createFromAscii( p
->mpMSName
);
116 else if ( eTranslateMode
& TRANSLATE_MEASURE
)
118 const sal_Char
* pDest
[] = { "#ppt_x", "#ppt_y", "#ppt_w", "#ppt_h", NULL
};
119 const sal_Char
* pSource
[] = { "x", "y", "width", "height", NULL
};
120 sal_Int32 nIndex
= 0;
122 const sal_Char
** ps
= pSource
;
123 const sal_Char
** pd
= pDest
;
127 const OUString
aSearch( OUString::createFromAscii( *ps
) );
128 while( (nIndex
= rString
.indexOf( aSearch
, nIndex
)) != -1 )
130 sal_Int32 nLength
= aSearch
.getLength();
131 if( nIndex
&& (rString
.getStr()[nIndex
-1] == '#' ) )
137 const OUString
aNew( OUString::createFromAscii( *pd
) );
138 rString
= rString
.replaceAt( nIndex
, nLength
, aNew
);
139 nIndex
+= aNew
.getLength();
148 sal_uInt32
AnimationExporter::TranslatePresetSubType( const sal_uInt32 nPresetClass
, const sal_uInt32 nPresetId
, const OUString
& rPresetSubType
)
150 sal_uInt32 nPresetSubType
= 0;
151 sal_Bool bTranslated
= sal_False
;
153 if ( ( nPresetClass
== (sal_uInt32
)EffectPresetClass::ENTRANCE
) || ( nPresetClass
== (sal_uInt32
)EffectPresetClass::EXIT
) )
155 if ( nPresetId
!= 21 )
161 if ( rPresetSubType
== "downward" )
164 bTranslated
= sal_True
;
166 else if ( rPresetSubType
== "across" )
169 bTranslated
= sal_True
;
175 if ( rPresetSubType
== "across" )
178 bTranslated
= sal_True
;
184 if ( rPresetSubType
== "right-to-top" )
187 bTranslated
= sal_True
;
189 else if ( rPresetSubType
== "right-to-bottom" )
192 bTranslated
= sal_True
;
194 else if ( rPresetSubType
== "left-to-top" )
197 bTranslated
= sal_True
;
199 else if ( rPresetSubType
== "left-to-bottom" )
202 bTranslated
= sal_True
;
210 const convert_subtype
* p
= gConvertArray
;
211 while( p
->mpStrSubType
)
213 if ( rPresetSubType
.equalsAscii( p
->mpStrSubType
) )
215 nPresetSubType
= p
->mnID
;
216 bTranslated
= sal_True
;
224 nPresetSubType
= (sal_uInt32
)rPresetSubType
.toInt32();
225 return nPresetSubType
;
228 const sal_Char
* AnimationExporter::FindTransitionName( const sal_Int16 nType
, const sal_Int16 nSubType
, const sal_Bool bDirection
)
230 const sal_Char
* pRet
= NULL
;
233 const transition
* p
= gTransitions
;
237 if ( nType
== p
->mnType
)
239 if ( nSubType
== p
->mnSubType
)
241 if ( bDirection
== p
->mbDirection
)
248 if ( nFit
== 7 ) // maximum
255 SvStream
& operator<<(SvStream
& rOut
, AnimationNode
& rNode
)
258 rOut
<< rNode
.mnRestart
;
259 rOut
<< rNode
.mnGroupType
;
260 rOut
<< rNode
.mnFill
;
263 rOut
<< rNode
.mnDuration
;
264 rOut
<< rNode
.mnNodeType
;
269 AnimationExporter::AnimationExporter( const EscherSolverContainer
& rSolverContainer
, ppt::ExSoundCollection
& rExSoundCollection
) :
270 mrSolverContainer ( rSolverContainer
),
271 mrExSoundCollection ( rExSoundCollection
),
276 // --------------------------------------------------------------------
278 sal_Int16
AnimationExporter::GetFillMode( const Reference
< XAnimationNode
>& xNode
, const sal_Int16 nFillDefault
)
280 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 if ((xNode
->getType() == AnimationNodeType::ANIMATE
)
284 ||(xNode
->getType() == AnimationNodeType::SET
)
285 ||(xNode
->getType() == AnimationNodeType::TRANSITIONFILTER
))
287 if ( nFill
== AnimationFill::DEFAULT
)
291 if ( ( nFill
== AnimationFill::DEFAULT
) ||
292 ( nFill
== AnimationFill::INHERIT
) )
294 if ( nFill
!= AnimationFill::AUTO
)
295 nFill
= nFillDefault
;
297 if( nFill
== AnimationFill::AUTO
)
299 nFill
= AnimationFill::REMOVE
;
300 sal_Bool bIsIndefiniteTiming
= sal_True
;
301 Any aAny
= xNode
->getDuration();
302 if( aAny
.hasValue() )
305 if( aAny
>>= eTiming
)
306 bIsIndefiniteTiming
= eTiming
== Timing_INDEFINITE
;
308 if ( bIsIndefiniteTiming
)
310 aAny
= xNode
->getEnd();
311 if( aAny
.hasValue() )
314 if( aAny
>>= eTiming
)
315 bIsIndefiniteTiming
= eTiming
== Timing_INDEFINITE
;
317 if ( bIsIndefiniteTiming
)
319 if ( !xNode
->getRepeatCount().hasValue() )
321 aAny
= xNode
->getRepeatDuration();
322 if( aAny
.hasValue() )
325 if( aAny
>>= eTiming
)
326 bIsIndefiniteTiming
= eTiming
== Timing_INDEFINITE
;
328 if ( bIsIndefiniteTiming
)
329 nFill
= AnimationFill::FREEZE
;
337 void AnimationExporter::doexport( const Reference
< XDrawPage
>& xPage
, SvStream
& rStrm
)
339 Reference
< XAnimationNodeSupplier
> xNodeSupplier( xPage
, UNO_QUERY
);
340 if( xNodeSupplier
.is() )
342 const Reference
< XAnimationNode
> xRootNode( xNodeSupplier
->getAnimationNode() );
345 processAfterEffectNodes( xRootNode
);
346 exportNode( rStrm
, xRootNode
, NULL
, DFF_msofbtAnimGroup
, 1, 0, sal_False
, AnimationFill::AUTO
);
351 void AnimationExporter::processAfterEffectNodes( const Reference
< XAnimationNode
>& xRootNode
)
355 Reference
< XEnumerationAccess
> xEnumerationAccess( xRootNode
, UNO_QUERY_THROW
);
356 Reference
< XEnumeration
> xEnumeration( xEnumerationAccess
->createEnumeration(), UNO_QUERY_THROW
);
357 while( xEnumeration
->hasMoreElements() )
359 Reference
< XAnimationNode
> xNode( xEnumeration
->nextElement(), UNO_QUERY_THROW
);
361 Reference
< XEnumerationAccess
> xEnumerationAccess2( xNode
, UNO_QUERY
);
362 if ( xEnumerationAccess2
.is() )
364 Reference
< XEnumeration
> xEnumeration2( xEnumerationAccess2
->createEnumeration(), UNO_QUERY_THROW
);
365 while( xEnumeration2
->hasMoreElements() )
367 Reference
< XAnimationNode
> xChildNode( xEnumeration2
->nextElement(), UNO_QUERY_THROW
);
369 Reference
< XEnumerationAccess
> xEnumerationAccess3( xChildNode
, UNO_QUERY_THROW
);
370 Reference
< XEnumeration
> xEnumeration3( xEnumerationAccess3
->createEnumeration(), UNO_QUERY_THROW
);
371 while( xEnumeration3
->hasMoreElements() )
373 Reference
< XAnimationNode
> xChildNode2( xEnumeration3
->nextElement(), UNO_QUERY_THROW
);
375 Reference
< XEnumerationAccess
> xEnumerationAccess4( xChildNode2
, UNO_QUERY_THROW
);
376 Reference
< XEnumeration
> xEnumeration4( xEnumerationAccess4
->createEnumeration(), UNO_QUERY_THROW
);
377 while( xEnumeration4
->hasMoreElements() )
379 Reference
< XAnimationNode
> xChildNode3( xEnumeration4
->nextElement(), UNO_QUERY_THROW
);
381 switch( xChildNode3
->getType() )
383 // found an after effect
384 case AnimationNodeType::SET
:
385 case AnimationNodeType::ANIMATECOLOR
:
387 Reference
< XAnimationNode
> xMaster
;
389 Sequence
< NamedValue
> aUserData( xChildNode3
->getUserData() );
390 sal_Int32 nLength
= aUserData
.getLength();
391 const NamedValue
* p
= aUserData
.getConstArray();
395 if ( p
->Name
== "master-element" )
397 p
->Value
>>= xMaster
;
403 AfterEffectNodePtr
pAfterEffectNode( new AfterEffectNode( xChildNode3
, xMaster
) );
404 maAfterEffectNodes
.push_back( pAfterEffectNode
);
416 OSL_FAIL( "(@CL)AnimationExporter::processAfterEffectNodes(), exception cought!" );
420 bool AnimationExporter::isAfterEffectNode( const Reference
< XAnimationNode
>& xNode
) const
422 const std::list
< AfterEffectNodePtr
>::const_iterator
aEnd( maAfterEffectNodes
.end() );
423 for (std::list
< AfterEffectNodePtr
>::const_iterator
aIter( maAfterEffectNodes
.begin() );
424 aIter
!= aEnd
; ++aIter
)
426 if( (*aIter
)->mxNode
== xNode
)
432 bool AnimationExporter::hasAfterEffectNode( const Reference
< XAnimationNode
>& xNode
, Reference
< XAnimationNode
>& xAfterEffectNode
) const
434 const std::list
< AfterEffectNodePtr
>::const_iterator
aEnd( maAfterEffectNodes
.end() );
435 for (std::list
< AfterEffectNodePtr
>::const_iterator
aIter( maAfterEffectNodes
.begin() );
436 aIter
!= aEnd
; ++aIter
)
438 if( (*aIter
)->mxMaster
== xNode
)
440 xAfterEffectNode
= (*aIter
)->mxNode
;
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 bool AnimationExporter::isEmptyNode( const Reference
< XAnimationNode
>& xNode
) const
452 if( xNode
.is() ) switch( xNode
->getType() )
454 case AnimationNodeType::PAR
:
455 case AnimationNodeType::SEQ
:
456 case AnimationNodeType::ITERATE
:
458 Reference
< XEnumerationAccess
> xEnumerationAccess( xNode
, UNO_QUERY
);
459 if( xEnumerationAccess
.is() )
461 Reference
< XEnumeration
> xEnumeration( xEnumerationAccess
->createEnumeration(), UNO_QUERY
);
462 if( xEnumeration
.is() )
464 while( xEnumeration
->hasMoreElements() )
466 Reference
< XAnimationNode
> xChildNode( xEnumeration
->nextElement(), UNO_QUERY
);
467 if( xChildNode
.is() && !isEmptyNode( xChildNode
) )
475 case AnimationNodeType::SET
:
476 case AnimationNodeType::ANIMATECOLOR
:
477 return isAfterEffectNode( xNode
);
485 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
)
488 if( (nGroupLevel
== 4) && isEmptyNode( xNode
) )
491 if ( ( nContainerRecType
== DFF_msofbtAnimGroup
) && ( nGroupLevel
== 2 ) && isEmptyNode( xNode
) )
494 if( nContainerRecType
== DFF_msofbtAnimGroup
)
497 sal_Bool bTakeBackInteractiveSequenceTimingForChild
= sal_False
;
498 sal_Int16 nFillDefault
= GetFillMode( xNode
, nFDef
);
500 bool bSkipChildren
= false;
502 Reference
< XAnimationNode
> xAudioNode
;
503 static sal_uInt32 nAudioGroup
;
506 EscherExContainer
aContainer( rStrm
, nContainerRecType
, nInstance
);
507 switch( xNode
->getType() )
509 case AnimationNodeType::CUSTOM
:
511 exportAnimNode( rStrm
, xNode
, pParent
, nGroupLevel
, nFillDefault
);
512 exportAnimPropertySet( rStrm
, xNode
);
513 exportAnimEvent( rStrm
, xNode
, 0 );
514 exportAnimValue( rStrm
, xNode
, sal_False
);
518 case AnimationNodeType::PAR
:
520 exportAnimNode( rStrm
, xNode
, pParent
, nGroupLevel
, nFillDefault
);
521 exportAnimPropertySet( rStrm
, xNode
);
522 sal_Int32 nFlags
= nGroupLevel
== 2 ? 0x10 : 0;
523 if ( bTakeBackInteractiveSequenceTiming
)
525 exportAnimEvent( rStrm
, xNode
, nFlags
);
526 exportAnimValue( rStrm
, xNode
, nGroupLevel
== 4 );
530 case AnimationNodeType::SEQ
:
532 exportAnimNode( rStrm
, xNode
, pParent
, nGroupLevel
, nFillDefault
);
533 sal_Int16 nNodeType
= exportAnimPropertySet( rStrm
, xNode
);
534 sal_Int32 nFlags
= 12;
535 if ( ( nGroupLevel
== 1 ) && ( nNodeType
== ::com::sun::star::presentation::EffectNodeType::INTERACTIVE_SEQUENCE
) )
538 bTakeBackInteractiveSequenceTimingForChild
= sal_True
;
540 exportAnimAction( rStrm
, xNode
);
541 exportAnimEvent( rStrm
, xNode
, nFlags
);
542 exportAnimValue( rStrm
, xNode
, sal_False
);
546 case AnimationNodeType::ITERATE
:
549 EscherExAtom
aAnimNodeExAtom( rStrm
, DFF_msofbtAnimNode
);
551 memset( &aAnim
, 0, sizeof( aAnim
) );
552 aAnim
.mnGroupType
= mso_Anim_GroupType_PAR
;
553 aAnim
.mnNodeType
= 1;
555 switch( xNode
->getRestart() )
558 case AnimationRestart::DEFAULT
: aAnim
.mnRestart
= 0; break;
559 case AnimationRestart::ALWAYS
: aAnim
.mnRestart
= 1; break;
560 case AnimationRestart::WHEN_NOT_ACTIVE
: aAnim
.mnRestart
= 2; break;
561 case AnimationRestart::NEVER
: aAnim
.mnRestart
= 3; break;
564 switch( xNode
->getFill() )
567 case AnimationFill::DEFAULT
: aAnim
.mnFill
= 0; break;
568 case AnimationFill::REMOVE
: aAnim
.mnFill
= 1; break;
569 case AnimationFill::FREEZE
: aAnim
.mnFill
= 2; break;
570 case AnimationFill::HOLD
: aAnim
.mnFill
= 3; break;
571 case AnimationFill::TRANSITION
: aAnim
.mnFill
= 4; break;
575 exportIterate( rStrm
, xNode
);
576 exportAnimPropertySet( rStrm
, xNode
);
577 exportAnimEvent( rStrm
, xNode
, 0 );
578 exportAnimValue( rStrm
, xNode
, sal_False
);
582 case AnimationNodeType::ANIMATE
:
584 exportAnimNode( rStrm
, xNode
, pParent
, nGroupLevel
, nFillDefault
);
585 exportAnimPropertySet( rStrm
, xNode
);
586 exportAnimEvent( rStrm
, xNode
, 0 );
587 exportAnimValue( rStrm
, xNode
, sal_False
);
588 exportAnimate( rStrm
, xNode
);
592 case AnimationNodeType::SET
:
594 bool bIsAfterEffectNode( isAfterEffectNode( xNode
) );
595 if( (nGroupLevel
!= 4) || !bIsAfterEffectNode
)
597 exportAnimNode( rStrm
, xNode
, pParent
, nGroupLevel
, nFillDefault
);
598 exportAnimPropertySet( rStrm
, xNode
);
599 exportAnimateSet( rStrm
, xNode
, bIsAfterEffectNode
? AFTEREFFECT_SET
: AFTEREFFECT_NONE
);
600 exportAnimEvent( rStrm
, xNode
, 0 );
601 exportAnimValue( rStrm
, xNode
, sal_False
);
605 bSkipChildren
= true;
610 case AnimationNodeType::ANIMATEMOTION
:
612 exportAnimNode( rStrm
, xNode
, pParent
, nGroupLevel
, nFillDefault
);
613 exportAnimPropertySet( rStrm
, xNode
);
614 exportAnimateMotion( rStrm
, xNode
);
615 exportAnimEvent( rStrm
, xNode
, 0 );
616 exportAnimValue( rStrm
, xNode
, sal_False
);
620 case AnimationNodeType::ANIMATECOLOR
:
622 bool bIsAfterEffectNode( isAfterEffectNode( xNode
) );
623 if( (nGroupLevel
!= 4) || !bIsAfterEffectNode
)
625 if( bIsAfterEffectNode
)
626 xNode
= createAfterEffectNodeClone( xNode
);
628 exportAnimNode( rStrm
, xNode
, pParent
, nGroupLevel
, nFillDefault
);
629 exportAnimPropertySet( rStrm
, xNode
);
630 exportAnimateColor( rStrm
, xNode
, bIsAfterEffectNode
? AFTEREFFECT_COLOR
: AFTEREFFECT_NONE
);
631 exportAnimEvent( rStrm
, xNode
, 0 );
632 exportAnimValue( rStrm
, xNode
, sal_False
);
636 bSkipChildren
= true;
641 case AnimationNodeType::ANIMATETRANSFORM
:
643 exportAnimNode( rStrm
, xNode
, pParent
, nGroupLevel
, nFillDefault
);
644 exportAnimPropertySet( rStrm
, xNode
);
645 exportAnimateTransform( rStrm
, xNode
);
646 exportAnimEvent( rStrm
, xNode
, 0 );
647 exportAnimValue( rStrm
, xNode
, sal_False
);
651 case AnimationNodeType::TRANSITIONFILTER
:
653 exportAnimNode( rStrm
, xNode
, pParent
, nGroupLevel
, nFillDefault
);
654 exportAnimPropertySet( rStrm
, xNode
);
655 exportAnimEvent( rStrm
, xNode
, 0 );
656 exportAnimValue( rStrm
, xNode
, sal_False
);
657 exportTransitionFilter( rStrm
, xNode
);
661 case AnimationNodeType::AUDIO
: // #i58428#
663 exportAnimNode( rStrm
, xNode
, pParent
, nGroupLevel
, nFillDefault
);
664 exportAnimPropertySet( rStrm
, xNode
);
666 Reference
< XAudio
> xAudio( xNode
, UNO_QUERY
);
669 Any
aAny( xAudio
->getSource() );
672 if ( ( aAny
>>= aURL
) && !aURL
.isEmpty() )
675 sal_Int32 nTrigger
= 3;
676 sal_Int32 nU3
= nAudioGroup
;
677 sal_Int32 nBegin
= 0;
679 EscherExContainer
aAnimEvent( rStrm
, DFF_msofbtAnimEvent
, 1 );
681 EscherExAtom
aAnimTrigger( rStrm
, DFF_msofbtAnimTrigger
);
682 rStrm
<< nU1
<< nTrigger
<< nU3
<< nBegin
;
689 EscherExContainer
aAnimEvent( rStrm
, DFF_msofbtAnimEvent
, 2 );
691 EscherExAtom
aAnimTrigger( rStrm
, DFF_msofbtAnimTrigger
);
692 rStrm
<< nU1
<< nTrigger
<< nU3
<< nBegin
;
695 EscherExContainer
aAnimateTargetElement( rStrm
, DFF_msofbtAnimateTargetElement
);
697 sal_uInt32 nRefMode
= 3;
698 sal_uInt32 nRefType
= 2;
699 sal_uInt32 nRefId
= mrExSoundCollection
.GetId( aURL
);
700 sal_Int32 begin
= -1;
703 EscherExAtom
aAnimReference( rStrm
, DFF_msofbtAnimReference
);
704 rStrm
<< nRefMode
<< nRefType
<< nRefId
<< begin
<< end
;
708 exportAnimValue( rStrm
, xNode
, sal_False
);
714 // export after effect node if one exists for this node
715 Reference
< XAnimationNode
> xAfterEffectNode
;
716 if( hasAfterEffectNode( xNode
, xAfterEffectNode
) )
718 exportNode( rStrm
, xAfterEffectNode
, &xNode
, DFF_msofbtAnimSubGoup
, 1, nGroupLevel
+ 1, bTakeBackInteractiveSequenceTimingForChild
, nFillDefault
);
721 Reference
< XEnumerationAccess
> xEnumerationAccess( xNode
, UNO_QUERY
);
722 if( xEnumerationAccess
.is() )
724 Reference
< XEnumeration
> xEnumeration( xEnumerationAccess
->createEnumeration(), UNO_QUERY
);
725 if( xEnumeration
.is() )
727 while( xEnumeration
->hasMoreElements() )
729 Reference
< XAnimationNode
> xChildNode( xEnumeration
->nextElement(), UNO_QUERY
);
730 if( xChildNode
.is() )
732 if ( xChildNode
->getType() == AnimationNodeType::AUDIO
)
734 xAudioNode
= xChildNode
;
735 nAudioGroup
= mnCurrentGroup
;
738 exportNode( rStrm
, xChildNode
, &xNode
, DFF_msofbtAnimGroup
, 1, nGroupLevel
+ 1, bTakeBackInteractiveSequenceTimingForChild
, nFillDefault
);
745 if ( xAudioNode
.is() )
746 exportNode( rStrm
, xAudioNode
, &xNode
, DFF_msofbtAnimGroup
, 1, nGroupLevel
, bTakeBackInteractiveSequenceTimingForChild
, nFillDefault
);
748 if( xNode
->getType() == AnimationNodeType::ITERATE
)
752 Reference
< XAnimationNode
> AnimationExporter::createAfterEffectNodeClone( const Reference
< XAnimationNode
>& xNode
) const
756 Reference
< ::com::sun::star::util::XCloneable
> xClonable( xNode
, UNO_QUERY_THROW
);
757 Reference
< XAnimationNode
> xCloneNode( xClonable
->createClone(), UNO_QUERY_THROW
);
760 xCloneNode
->setBegin( aEmpty
);
766 OSL_FAIL("(@CL)sd::ppt::AnimationExporter::createAfterEffectNodeClone(), could not create clone!" );
771 sal_Bool
AnimationExporter::GetNodeType( const Reference
< XAnimationNode
>& xNode
, sal_Int16
& nType
)
773 // trying to get the nodetype
774 Sequence
< NamedValue
> aUserData
= xNode
->getUserData();
775 if ( aUserData
.getLength() )
777 const NamedValue
* p
= aUserData
.getConstArray();
778 sal_Int32 nLength
= aUserData
.getLength();
781 if ( p
->Name
== "node-type" )
783 if ( p
->Value
>>= nType
)
792 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
)
795 EscherExAtom
aAnimNodeExAtom( rStrm
, DFF_msofbtAnimNode
);
797 memset( &aAnim
, 0, sizeof( aAnim
) );
800 switch( xNode
->getRestart() )
803 case AnimationRestart::DEFAULT
: aAnim
.mnRestart
= 0; break;
804 case AnimationRestart::ALWAYS
: aAnim
.mnRestart
= 1; break;
805 case AnimationRestart::WHEN_NOT_ACTIVE
: aAnim
.mnRestart
= 2; break;
806 case AnimationRestart::NEVER
: aAnim
.mnRestart
= 3; break;
809 switch( nFillDefault
)
812 case AnimationFill::DEFAULT
: aAnim
.mnFill
= 0; break;
813 case AnimationFill::REMOVE
: aAnim
.mnFill
= 1; break;
814 case AnimationFill::FREEZE
:
815 case AnimationFill::HOLD
: aAnim
.mnFill
= 3; break;
816 case AnimationFill::TRANSITION
: aAnim
.mnFill
= 4; break;
818 // attribute Duration
819 double fDuration
= 0.0;
820 com::sun::star::animations::Timing eTiming
;
821 if ( xNode
->getDuration() >>= eTiming
)
823 if ( eTiming
== Timing_INDEFINITE
)
824 aAnim
.mnDuration
= -1;
826 else if ( xNode
->getDuration() >>= fDuration
)
828 aAnim
.mnDuration
= (sal_Int32
)( fDuration
* 1000.0 );
831 aAnim
.mnDuration
= -1;
833 // NodeType, NodeGroup
834 aAnim
.mnNodeType
= 1;
835 aAnim
.mnGroupType
= mso_Anim_GroupType_SEQ
;
836 switch( xNode
->getType() )
838 case AnimationNodeType::PAR
: // PASSTROUGH!!! (as it was intended)
839 aAnim
.mnGroupType
= mso_Anim_GroupType_PAR
;
840 case AnimationNodeType::SEQ
:
843 if( GetNodeType( xNode
, nType
) )
846 case ::com::sun::star::presentation::EffectNodeType::TIMING_ROOT
: aAnim
.mnNodeType
= 0x12; break;
847 case ::com::sun::star::presentation::EffectNodeType::MAIN_SEQUENCE
: aAnim
.mnNodeType
= 0x18; break;
852 case AnimationNodeType::ANIMATE
:
853 case AnimationNodeType::SET
:
855 case AnimationNodeType::CUSTOM
:
856 case AnimationNodeType::ITERATE
:
857 case AnimationNodeType::ANIMATEMOTION
:
858 case AnimationNodeType::ANIMATECOLOR
:
859 case AnimationNodeType::ANIMATETRANSFORM
:
861 aAnim
.mnGroupType
= mso_Anim_GroupType_NODE
;
862 aAnim
.mnNodeType
= mso_Anim_Behaviour_ANIMATION
;
866 case AnimationNodeType::AUDIO
:
868 aAnim
.mnGroupType
= mso_Anim_GroupType_MEDIA
;
869 aAnim
.mnNodeType
= mso_Anim_Behaviour_ANIMATION
;
873 case AnimationNodeType::TRANSITIONFILTER
:
875 aAnim
.mnGroupType
= mso_Anim_GroupType_NODE
;
876 aAnim
.mnNodeType
= mso_Anim_Behaviour_FILTER
;
884 void AnimationExporter::GetUserData( const Sequence
< NamedValue
>& rUserData
, const Any
** pAny
, sal_Size nLen
)
886 // storing user data into pAny, to allow direct access later
887 memset( pAny
, 0, nLen
);
888 if ( rUserData
.getLength() )
890 const NamedValue
* p
= rUserData
.getConstArray();
891 sal_Int32 nLength
= rUserData
.getLength();
894 if ( p
->Name
== "node-type" )
896 pAny
[ DFF_ANIM_NODE_TYPE
] = &(p
->Value
);
898 else if ( p
->Name
== "preset-class" )
900 pAny
[ DFF_ANIM_PRESET_CLASS
] = &(p
->Value
);
902 else if ( p
->Name
== "preset-id" )
904 pAny
[ DFF_ANIM_PRESET_ID
] = &(p
->Value
);
906 else if ( p
->Name
== "preset-sub-type" )
908 pAny
[ DFF_ANIM_PRESET_SUB_TYPE
] = &(p
->Value
);
910 else if ( p
->Name
== "master-element" )
912 pAny
[ DFF_ANIM_AFTEREFFECT
] = &(p
->Value
);;
919 sal_uInt32
AnimationExporter::GetPresetID( const OUString
& rPreset
, sal_uInt32 nAPIPresetClass
, sal_Bool
& bPresetId
)
921 sal_uInt32 nPresetId
= 0;
922 bPresetId
= sal_False
;
924 if ( rPreset
.match( OUString( "ppt_" ), 0 ) )
926 sal_Int32 nLast
= rPreset
.lastIndexOf( '_' );
927 if ( ( nLast
!= -1 ) && ( ( nLast
+ 1 ) < rPreset
.getLength() ) )
929 OUString
aNumber( rPreset
.copy( nLast
+ 1 ) );
930 nPresetId
= aNumber
.toInt32();
931 bPresetId
= sal_True
;
936 const preset_maping
* p
= gPresetMaping
;
937 while( p
->mpStrPresetId
&& ((p
->mnPresetClass
!= (sal_Int32
)nAPIPresetClass
) || !rPreset
.equalsAscii( p
->mpStrPresetId
)) )
940 if( p
->mpStrPresetId
)
942 nPresetId
= p
->mnPresetId
;
943 bPresetId
= sal_True
;
950 sal_Int16
AnimationExporter::exportAnimPropertySet( SvStream
& rStrm
, const Reference
< XAnimationNode
>& xNode
)
952 sal_Int16 nNodeType
= ::com::sun::star::presentation::EffectNodeType::DEFAULT
;
954 EscherExContainer
aAnimPropertySet( rStrm
, DFF_msofbtAnimPropertySet
);
956 Reference
< XAnimationNode
> xMaster
;
958 Any aMasterRel
, aOverride
, aRunTimeContext
;
960 // storing user data into pAny, to allow direct access later
961 const Sequence
< NamedValue
> aUserData
= xNode
->getUserData();
962 const ::com::sun::star::uno::Any
* pAny
[ DFF_ANIM_PROPERTY_ID_COUNT
];
963 GetUserData( aUserData
, pAny
, sizeof( pAny
) );
965 if( pAny
[ DFF_ANIM_AFTEREFFECT
] )
966 ( *pAny
[ DFF_ANIM_AFTEREFFECT
] ) >>= xMaster
;
968 // calculate master-rel
971 sal_Int32 nMasterRel
= 2;
972 Reference
< XChild
> xNodeChild( xNode
, UNO_QUERY
);
973 Reference
< XChild
> xMasterChild( xMaster
, UNO_QUERY
);
974 if( xNodeChild
.is() && xMasterChild
.is() && (xNodeChild
->getParent() == xMasterChild
->getParent() ) )
977 aMasterRel
<<= nMasterRel
;
979 pAny
[ DFF_ANIM_MASTERREL
] = &aMasterRel
;
981 aOverride
<<= (sal_Int32
)1;
982 pAny
[ DFF_ANIM_OVERRIDE
] = &aOverride
;
984 aRunTimeContext
<<= (sal_Int32
)1;
985 pAny
[ DFF_ANIM_RUNTIMECONTEXT
] = &aRunTimeContext
;
988 // the order is important
989 if ( pAny
[ DFF_ANIM_NODE_TYPE
] )
991 if ( *pAny
[ DFF_ANIM_NODE_TYPE
] >>= nNodeType
)
993 sal_uInt32 nPPTNodeType
= DFF_ANIM_NODE_TYPE_ON_CLICK
;
996 case ::com::sun::star::presentation::EffectNodeType::ON_CLICK
: nPPTNodeType
= DFF_ANIM_NODE_TYPE_ON_CLICK
; break;
997 case ::com::sun::star::presentation::EffectNodeType::WITH_PREVIOUS
: nPPTNodeType
= DFF_ANIM_NODE_TYPE_WITH_PREVIOUS
; break;
998 case ::com::sun::star::presentation::EffectNodeType::AFTER_PREVIOUS
: nPPTNodeType
= DFF_ANIM_NODE_TYPE_AFTER_PREVIOUS
; break;
999 case ::com::sun::star::presentation::EffectNodeType::MAIN_SEQUENCE
: nPPTNodeType
= DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE
; break;
1000 case ::com::sun::star::presentation::EffectNodeType::TIMING_ROOT
: nPPTNodeType
= DFF_ANIM_NODE_TYPE_TIMING_ROOT
; break;
1001 case ::com::sun::star::presentation::EffectNodeType::INTERACTIVE_SEQUENCE
: nPPTNodeType
= DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ
; break;
1003 exportAnimPropertyuInt32( rStrm
, DFF_ANIM_NODE_TYPE
, nPPTNodeType
, TRANSLATE_NONE
);
1006 sal_uInt32 nPresetId
= 0;
1007 sal_uInt32 nPresetSubType
= 0;
1008 sal_uInt32 nAPIPresetClass
= EffectPresetClass::CUSTOM
;
1009 sal_uInt32 nPresetClass
= DFF_ANIM_PRESS_CLASS_USER_DEFINED
;
1010 sal_Bool bPresetClass
, bPresetId
, bPresetSubType
;
1011 bPresetId
= bPresetClass
= bPresetSubType
= sal_False
;
1013 if ( pAny
[ DFF_ANIM_PRESET_CLASS
] )
1015 if ( *pAny
[ DFF_ANIM_PRESET_CLASS
] >>= nAPIPresetClass
)
1017 sal_uInt8 nPPTPresetClass
;
1018 switch( nAPIPresetClass
)
1020 case EffectPresetClass::ENTRANCE
: nPPTPresetClass
= DFF_ANIM_PRESS_CLASS_ENTRANCE
; break;
1021 case EffectPresetClass::EXIT
: nPPTPresetClass
= DFF_ANIM_PRESS_CLASS_EXIT
; break;
1022 case EffectPresetClass::EMPHASIS
: nPPTPresetClass
= DFF_ANIM_PRESS_CLASS_EMPHASIS
; break;
1023 case EffectPresetClass::MOTIONPATH
: nPPTPresetClass
= DFF_ANIM_PRESS_CLASS_MOTIONPATH
; break;
1024 case EffectPresetClass::OLEACTION
: nPPTPresetClass
= DFF_ANIM_PRESS_CLASS_OLE_ACTION
; break;
1025 case EffectPresetClass::MEDIACALL
: nPPTPresetClass
= DFF_ANIM_PRESS_CLASS_MEDIACALL
; break;
1027 nPPTPresetClass
= DFF_ANIM_PRESS_CLASS_USER_DEFINED
;
1029 nPresetClass
= nPPTPresetClass
;
1030 bPresetClass
= sal_True
;
1033 if ( pAny
[ DFF_ANIM_PRESET_ID
] )
1036 if ( *pAny
[ DFF_ANIM_PRESET_ID
] >>= sPreset
)
1037 nPresetId
= GetPresetID( sPreset
, nAPIPresetClass
, bPresetId
);
1040 if ( pAny
[ DFF_ANIM_PRESET_SUB_TYPE
] )
1042 OUString sPresetSubType
;
1043 if ( *pAny
[ DFF_ANIM_PRESET_SUB_TYPE
] >>= sPresetSubType
)
1045 nPresetSubType
= TranslatePresetSubType( nPresetClass
, nPresetId
, sPresetSubType
);
1046 bPresetSubType
= sal_True
;
1050 exportAnimPropertyuInt32( rStrm
, DFF_ANIM_PRESET_ID
, nPresetId
, TRANSLATE_NONE
);
1051 if ( bPresetSubType
)
1052 exportAnimPropertyuInt32( rStrm
, DFF_ANIM_PRESET_SUB_TYPE
, nPresetSubType
, TRANSLATE_NONE
);
1054 exportAnimPropertyuInt32( rStrm
, DFF_ANIM_PRESET_CLASS
, nPresetClass
, TRANSLATE_NONE
);
1056 if ( pAny
[ DFF_ANIM_ID
] )
1061 if ( pAny
[ DFF_ANIM_AFTEREFFECT
] )
1063 sal_Bool bAfterEffect
= sal_False
;
1064 if ( *pAny
[ DFF_ANIM_AFTEREFFECT
] >>= bAfterEffect
)
1065 exportAnimPropertyByte( rStrm
, DFF_ANIM_AFTEREFFECT
, bAfterEffect
, TRANSLATE_NONE
);
1068 if ( pAny
[ DFF_ANIM_RUNTIMECONTEXT
] )
1070 sal_Int32 nRunTimeContext
= 0;
1071 if ( *pAny
[ DFF_ANIM_RUNTIMECONTEXT
] >>= nRunTimeContext
)
1072 exportAnimPropertyuInt32( rStrm
, DFF_ANIM_RUNTIMECONTEXT
, nRunTimeContext
, TRANSLATE_NONE
);
1074 if ( pAny
[ DFF_ANIM_PATH_EDIT_MODE
] )
1081 Reference
< XAnimateColor
> xColor( xNode
, UNO_QUERY
);
1085 sal_Bool bDirection
= !xColor
->getDirection();
1086 exportAnimPropertyuInt32( rStrm
, DFF_ANIM_DIRECTION
, bDirection
, TRANSLATE_NONE
);
1090 if ( pAny
[ DFF_ANIM_OVERRIDE
] )
1092 sal_Int32 nOverride
= 0;
1093 if ( *pAny
[ DFF_ANIM_OVERRIDE
] >>= nOverride
)
1094 exportAnimPropertyuInt32( rStrm
, DFF_ANIM_OVERRIDE
, nOverride
, TRANSLATE_NONE
);
1097 if ( pAny
[ DFF_ANIM_MASTERREL
] )
1099 sal_Int32 nMasterRel
= 0;
1100 if ( *pAny
[ DFF_ANIM_MASTERREL
] >>= nMasterRel
)
1101 exportAnimPropertyuInt32( rStrm
, DFF_ANIM_MASTERREL
, nMasterRel
, TRANSLATE_NONE
);
1105 Reference< XAudio > xAudio( xNode, UNO_QUERY );
1108 sal_Int16 nEndAfterSlide = 0;
1109 nEndAfterSlide = xAudio->getEndAfterSlide();
1110 exportAnimPropertyuInt32( rStrm, DFF_ANIM_ENDAFTERSLIDE, nEndAfterSlide, TRANSLATE_NONE );
1113 Reference
< XAnimate
> xAnim( xNode
, UNO_QUERY
);
1116 // TODO: DFF_ANIM_TIMEFILTER
1118 if ( pAny
[ DFF_ANIM_EVENT_FILTER
] )
1120 // TODO DFF_ANIM_EVENT_FILTER
1122 if ( pAny
[ DFF_ANIM_VOLUME
] )
1124 // TODO DFF_ANIM_VOLUME
1129 sal_Bool
AnimationExporter::exportAnimProperty( SvStream
& rStrm
, const sal_uInt16 nPropertyId
, const ::com::sun::star::uno::Any
& rAny
, const TranslateMode eTranslateMode
)
1131 sal_Bool bRet
= sal_False
;
1132 if ( rAny
.hasValue() )
1134 switch( rAny
.getValueType().getTypeClass() )
1136 case ::com::sun::star::uno::TypeClass_UNSIGNED_SHORT
:
1137 case ::com::sun::star::uno::TypeClass_SHORT
:
1138 case ::com::sun::star::uno::TypeClass_UNSIGNED_LONG
:
1139 case ::com::sun::star::uno::TypeClass_LONG
:
1142 if ( rAny
>>= nVal
)
1144 exportAnimPropertyuInt32( rStrm
, nPropertyId
, nVal
, eTranslateMode
);
1150 case ::com::sun::star::uno::TypeClass_DOUBLE
:
1153 if ( rAny
>>= fVal
)
1155 exportAnimPropertyFloat( rStrm
, nPropertyId
, fVal
, eTranslateMode
);
1160 case ::com::sun::star::uno::TypeClass_FLOAT
:
1163 if ( rAny
>>= fVal
)
1165 if ( eTranslateMode
& TRANSLATE_NUMBER_TO_STRING
)
1168 OUString
aNumber( OUString::valueOf( fVal
) );
1170 exportAnimPropertyString( rStrm
, nPropertyId
, aNumber
, eTranslateMode
);
1174 exportAnimPropertyFloat( rStrm
, nPropertyId
, fVal
, eTranslateMode
);
1180 case ::com::sun::star::uno::TypeClass_STRING
:
1183 if ( rAny
>>= aStr
)
1185 exportAnimPropertyString( rStrm
, nPropertyId
, aStr
, eTranslateMode
);
1196 void AnimationExporter::exportAnimPropertyString( SvStream
& rStrm
, const sal_uInt16 nPropertyId
, const OUString
& rVal
, const TranslateMode eTranslateMode
)
1198 EscherExAtom
aExAtom( rStrm
, DFF_msofbtAnimAttributeValue
, nPropertyId
);
1199 sal_uInt8 nType
= DFF_ANIM_PROP_TYPE_UNISTRING
;
1201 OUString
aStr( rVal
);
1202 if ( eTranslateMode
!= TRANSLATE_NONE
)
1203 ImplTranslateAttribute( aStr
, eTranslateMode
);
1204 writeZString( rStrm
, aStr
);
1207 void AnimationExporter::exportAnimPropertyFloat( SvStream
& rStrm
, const sal_uInt16 nPropertyId
, const double& rVal
, const TranslateMode
)
1209 EscherExAtom
aExAtom( rStrm
, DFF_msofbtAnimAttributeValue
, nPropertyId
);
1210 sal_uInt8 nType
= DFF_ANIM_PROP_TYPE_FLOAT
;
1211 float fFloat
= (float)rVal
;
1216 void AnimationExporter::exportAnimPropertyuInt32( SvStream
& rStrm
, const sal_uInt16 nPropertyId
, const sal_uInt32 nVal
, const TranslateMode
)
1218 EscherExAtom
aExAtom( rStrm
, DFF_msofbtAnimAttributeValue
, nPropertyId
);
1219 sal_uInt8 nType
= DFF_ANIM_PROP_TYPE_INT32
;
1224 void AnimationExporter::exportAnimPropertyByte( SvStream
& rStrm
, const sal_uInt16 nPropertyId
, const sal_uInt8 nVal
, const TranslateMode
)
1226 EscherExAtom
aExAtom( rStrm
, DFF_msofbtAnimAttributeValue
, nPropertyId
);
1227 sal_uInt8 nType
= DFF_ANIM_PROP_TYPE_BYTE
;
1232 void AnimationExporter::writeZString( SvStream
& rStrm
, const OUString
& rVal
)
1235 for ( i
= 0; i
< rVal
.getLength(); i
++ )
1237 rStrm
<< (sal_Unicode
)0;
1240 void AnimationExporter::exportAnimAction( SvStream
& rStrm
, const Reference
< XAnimationNode
>& xNode
)
1242 EscherExAtom
aExAtom( rStrm
, DFF_msofbtAnimAction
);
1244 sal_Int32 nConcurrent
= 1;
1245 sal_Int32 nNextAction
= 1;
1246 sal_Int32 nEndSync
= 0;
1250 sal_Int16 nAnimationEndSync
= 0;
1251 if ( xNode
->getEndSync() >>= nAnimationEndSync
)
1253 if ( nAnimationEndSync
== AnimationEndSync::ALL
)
1256 rStrm
<< nConcurrent
1264 // nFlags Bit 6 = fixInteractiveSequenceTiming (for child)
1265 // nFlags Bit 5 = fixInteractiveSequenceTiming (for root)
1266 // nFlags Bit 4 = first node of main sequence -> begin event next has to be replaced to indefinite
1267 void AnimationExporter::exportAnimEvent( SvStream
& rStrm
, const Reference
< XAnimationNode
>& xNode
, const sal_Int32 nFlags
)
1270 for ( i
= 0; i
< 4; i
++ )
1273 sal_Int32 nTrigger
= 0;
1275 sal_Int32 nBegin
= 0;
1277 sal_Bool bCreateEvent
= sal_False
;
1287 com::sun::star::animations::Timing eTiming
;
1290 if ( nFlags
& 0x20 )
1292 // taking the first child
1293 Reference
< XEnumerationAccess
> xEA( xNode
, UNO_QUERY_THROW
);
1294 Reference
< XEnumeration
> xE( xEA
->createEnumeration(), UNO_QUERY_THROW
);
1295 if ( xE
.is() && xE
->hasMoreElements() )
1298 Reference
< XAnimationNode
> xClickNode( xE
->nextElement(), UNO_QUERY
);
1299 aAny
= xClickNode
->getBegin();
1303 else if ( nFlags
& 0x40 )
1305 // begin has to be replaced with void, so don't do anything
1309 aAny
= xNode
->getBegin();
1310 if ( nFlags
& 0x10 ) // replace ON_NEXT with IDEFINITE
1312 if ( ( aAny
>>= aEvent
) && ( aEvent
.Trigger
== EventTrigger::ON_NEXT
) )
1314 eTiming
= Timing_INDEFINITE
;
1321 aAny
= xNode
->getEnd();
1323 double fTiming
= 0.0;
1324 if ( aAny
>>= aEvent
)
1326 bCreateEvent
= sal_True
;
1327 switch( aEvent
.Trigger
)
1329 case EventTrigger::NONE
: nTrigger
= 0; break;
1330 case EventTrigger::ON_BEGIN
: nTrigger
= 1; break;
1331 case EventTrigger::ON_END
: nTrigger
= 2; break;
1332 case EventTrigger::BEGIN_EVENT
: nTrigger
= 3; break;
1333 case EventTrigger::END_EVENT
: nTrigger
= 4; nU1
= 2; nU3
= mnCurrentGroup
; break;
1334 case EventTrigger::ON_CLICK
: nTrigger
= 5; break;
1335 case EventTrigger::ON_DBL_CLICK
: nTrigger
= 6; break;
1336 case EventTrigger::ON_MOUSE_ENTER
: nTrigger
= 7; break;
1337 case EventTrigger::ON_MOUSE_LEAVE
: nTrigger
= 8; break;
1338 case EventTrigger::ON_NEXT
: nTrigger
= 9; break;
1339 case EventTrigger::ON_PREV
: nTrigger
= 10; break;
1340 case EventTrigger::ON_STOP_AUDIO
: nTrigger
= 11; break;
1342 if ( aEvent
.Offset
.hasValue() )
1344 if ( aEvent
.Offset
>>= eTiming
)
1346 if ( eTiming
== Timing_INDEFINITE
)
1349 else if ( aEvent
.Offset
>>= fTiming
)
1350 nBegin
= (sal_Int32
)( fTiming
* 1000.0 );
1352 aSource
= aEvent
.Source
;
1354 else if ( aAny
>>= eTiming
)
1356 bCreateEvent
= sal_True
;
1357 if ( eTiming
== Timing_INDEFINITE
)
1360 else if ( aAny
>>= fTiming
)
1362 bCreateEvent
= sal_True
;
1363 nBegin
= (sal_Int32
)( fTiming
* 1000.0 );
1370 if ( nFlags
& ( 1 << i
) )
1372 bCreateEvent
= sal_True
;
1380 if ( nFlags
& ( 1 << i
) )
1382 bCreateEvent
= sal_True
;
1391 EscherExContainer
aAnimEvent( rStrm
, DFF_msofbtAnimEvent
, i
+ 1 );
1393 EscherExAtom
aAnimTrigger( rStrm
, DFF_msofbtAnimTrigger
);
1399 exportAnimateTargetElement( rStrm
, aSource
, ( nFlags
& ( 1 << i
) ) != 0 );
1404 Any
AnimationExporter::convertAnimateValue( const Any
& rSourceValue
, const OUString
& rAttributeName
)
1407 if ( rAttributeName
== "X"
1408 || rAttributeName
== "Y"
1409 || rAttributeName
== "Width"
1410 || rAttributeName
== "Height"
1414 if ( rSourceValue
>>= aStr
)
1416 ImplTranslateAttribute( aStr
, TRANSLATE_MEASURE
);
1420 else if ( rAttributeName
== "Rotate" // "r" or "style.rotation" ?
1421 || rAttributeName
== "SkewX"
1422 || rAttributeName
== "Opacity"
1423 || rAttributeName
== "CharHeight"
1426 double fNumber
= 0.0;
1427 if ( rSourceValue
>>= fNumber
)
1428 aDest
+= OUString::valueOf( fNumber
);
1430 else if ( rAttributeName
== "Color"
1431 || rAttributeName
== "FillColor" // "Fillcolor" or "FillColor" ?
1432 || rAttributeName
== "LineColor"
1433 || rAttributeName
== "CharColor"
1436 sal_Int32 nColor
= 0;
1437 Sequence
< double > aHSL( 3 );
1439 if ( rSourceValue
>>= aHSL
)
1442 aDest
+= OUString::valueOf( (sal_Int32
)( aHSL
[ 0 ] / ( 360.0 / 255 ) ) );
1444 aDest
+= OUString::valueOf( (sal_Int32
)( aHSL
[ 1 ] * 255.0 ) );
1446 aDest
+= OUString::valueOf( (sal_Int32
)( aHSL
[ 2 ] * 255.0 ) );
1449 else if ( rSourceValue
>>= nColor
)
1452 aDest
+= OUString::valueOf( (sal_Int32
)( (sal_Int8
)nColor
) );
1454 aDest
+= OUString::valueOf( (sal_Int32
)( (sal_Int8
)( nColor
>> 8 ) ) );
1456 aDest
+= OUString::valueOf( (sal_Int32
)( (sal_Int8
)( nColor
>> 16 ) ) );
1460 else if ( rAttributeName
== "FillStyle" )
1462 ::com::sun::star::drawing::FillStyle eFillStyle
;
1463 if ( rSourceValue
>>= eFillStyle
)
1465 if ( eFillStyle
== ::com::sun::star::drawing::FillStyle_NONE
)
1466 aDest
+= "none"; // ?
1471 else if ( rAttributeName
== "LineStyle" )
1473 ::com::sun::star::drawing::LineStyle eLineStyle
;
1474 if ( rSourceValue
>>= eLineStyle
)
1476 if ( eLineStyle
== ::com::sun::star::drawing::LineStyle_NONE
)
1482 else if ( rAttributeName
== "CharWeight" )
1484 float fFontWeight
= 0.0;
1485 if ( rSourceValue
>>= fFontWeight
)
1487 if ( fFontWeight
== com::sun::star::awt::FontWeight::BOLD
)
1493 else if ( rAttributeName
== "CharUnderline" )
1495 sal_Int16 nFontUnderline
= 0;
1496 if ( rSourceValue
>>= nFontUnderline
)
1498 if ( nFontUnderline
== com::sun::star::awt::FontUnderline::NONE
)
1504 else if ( rAttributeName
== "CharPosture" )
1506 ::com::sun::star::awt::FontSlant eFontSlant
;
1507 if ( rSourceValue
>>= eFontSlant
)
1509 if ( eFontSlant
== com::sun::star::awt::FontSlant_ITALIC
)
1512 aDest
+= "normal"; // ?
1515 else if ( rAttributeName
== "Visibility" )
1517 sal_Bool bVisible
= sal_True
;
1518 if ( rSourceValue
>>= bVisible
)
1527 if ( !aDest
.isEmpty() )
1530 aRet
= rSourceValue
;
1534 void AnimationExporter::exportAnimateSet( SvStream
& rStrm
, const Reference
< XAnimationNode
>& xNode
, int nAfterEffectType
)
1536 Reference
< XAnimateSet
> xSet( xNode
, UNO_QUERY
);
1539 EscherExContainer
aAnimateSet( rStrm
, DFF_msofbtAnimateSet
, 0 );
1541 EscherExAtom
aAnimateSetData( rStrm
, DFF_msofbtAnimateSetData
);
1542 sal_uInt32 nId1
= 1; // ??
1543 sal_uInt32 nId2
= 1; // ??
1544 rStrm
<< nId1
<< nId2
;
1546 Any
aConvertedValue( convertAnimateValue( xSet
->getTo(), xSet
->getAttributeName() ) );
1547 if ( aConvertedValue
.hasValue() )
1548 exportAnimProperty( rStrm
, 1, aConvertedValue
, TRANSLATE_NONE
);
1549 exportAnimateTarget( rStrm
, xNode
, 0, nAfterEffectType
);
1553 sal_uInt32
AnimationExporter::GetValueTypeForAttributeName( const OUString
& rAttributeName
)
1555 sal_uInt32 nValueType
= 0;
1559 const sal_Char
* pName
;
1562 static const Entry lcl_attributeMap
[] =
1565 { "charfontname", 0 },
1566 { "charheight", 1 },
1567 { "charposture", 0 },
1568 // TODO(Q1): This should prolly be changed in PPT import
1569 // { "charrotation", ATTRIBUTE_CHAR_ROTATION },
1570 { "charrotation", 1 },
1571 { "charunderline", 0 },
1572 { "charweight", 0 },
1584 { "visibility", 1 },
1590 const Entry
* pPtr
= &lcl_attributeMap
[ 0 ];
1591 while( pPtr
->pName
)
1593 if ( rAttributeName
.equalsIgnoreAsciiCaseAscii( pPtr
->pName
) )
1595 nValueType
= pPtr
->nType
;
1600 DBG_ASSERT( pPtr
->pName
, "GetValueTypeForAttributeName, unknown property value!" );
1604 void AnimationExporter::exportAnimate( SvStream
& rStrm
, const Reference
< XAnimationNode
>& xNode
)
1606 Reference
< XAnimate
> xAnimate( xNode
, UNO_QUERY
);
1607 if ( xAnimate
.is() )
1609 Any
aBy ( xAnimate
->getBy() );
1610 Any
aFrom( xAnimate
->getFrom() );
1611 Any
aTo ( xAnimate
->getTo() );
1613 EscherExContainer
aContainer( rStrm
, DFF_msofbtAnimate
, 0 );
1615 EscherExAtom
aAnimateData( rStrm
, DFF_msofbtAnimateData
);
1616 sal_uInt32 nBits
= 0x38;
1617 sal_Int16 nTmp
= xAnimate
->getCalcMode();
1618 sal_uInt32 nCalcMode
= /* (nTmp == AnimationCalcMode::FORMULA) ? 2 : */ (nTmp
== AnimationCalcMode::LINEAR
) ? 1 : 0;
1619 nTmp
= xAnimate
->getValueType();
1620 sal_uInt32 nValueType
= GetValueTypeForAttributeName( xAnimate
->getAttributeName() );
1622 if ( aBy
.hasValue() )
1624 if ( aFrom
.hasValue() )
1626 if ( aTo
.hasValue() )
1633 if ( aBy
.hasValue() )
1634 exportAnimProperty( rStrm
, 1, aBy
, TRANSLATE_NUMBER_TO_STRING
| TRANSLATE_MEASURE
);
1635 if ( aFrom
.hasValue() )
1636 exportAnimProperty( rStrm
, 2, aFrom
, TRANSLATE_NUMBER_TO_STRING
| TRANSLATE_MEASURE
);
1637 if ( aTo
.hasValue() )
1638 exportAnimProperty( rStrm
, 3, aTo
, TRANSLATE_NUMBER_TO_STRING
| TRANSLATE_MEASURE
);
1640 exportAnimateKeyPoints( rStrm
, xAnimate
);
1641 exportAnimateTarget( rStrm
, xNode
);
1645 void AnimationExporter::exportAnimateTarget( SvStream
& rStrm
, const Reference
< XAnimationNode
>& xNode
, const sal_uInt32 nForceAttributeNames
, int nAfterEffectType
)
1647 EscherExContainer
aAnimateTarget( rStrm
, DFF_msofbtAnimateTarget
, 0 );
1648 Reference
< XAnimate
> xAnimate( xNode
, UNO_QUERY
);
1649 if ( xAnimate
.is() )
1652 EscherExAtom
aAnimateTargetSettings( rStrm
, DFF_msofbtAnimateTargetSettings
, 0 );
1653 // nBits %0001: additive, %0010: accumulate, %0100: attributeName, %1000: transformtype
1654 // nAdditive 0 = base, 1 = sum, 2 = replace, 3 = multiply, 4 = none
1655 // nAccumulate 0 = none, 1 = always
1656 // nTransformType 0: "property" else "image"
1657 sal_uInt32 nBits
= 0;
1658 sal_uInt32 nAdditive
= 0;
1659 sal_uInt32 nAccumulate
= 0;
1660 sal_uInt32 nTransformType
= 0;
1661 if ( xAnimate
.is() )
1663 if ( !xAnimate
->getAttributeName().isEmpty() )
1664 nBits
|= 4; // what is attributeName ?, maybe this is set if a DFF_msofbtAnimateAttributeNames is written
1665 sal_Int16 nAdditiveMode
= xAnimate
->getAdditive();
1666 if ( nAdditiveMode
!= AnimationAdditiveMode::BASE
)
1669 switch( nAdditiveMode
)
1671 case AnimationAdditiveMode::SUM
: nAdditive
= 1; break;
1672 case AnimationAdditiveMode::REPLACE
: nAdditive
= 2; break;
1673 case AnimationAdditiveMode::MULTIPLY
: nAdditive
= 3; break;
1674 case AnimationAdditiveMode::NONE
: nAdditive
= 4; break;
1677 if ( xAnimate
->getAccumulate() )
1688 if ( !xAnimate
->getAttributeName().isEmpty() || nForceAttributeNames
)
1690 EscherExContainer
aAnimateAttributeNames( rStrm
, DFF_msofbtAnimateAttributeNames
, 1 );
1691 OUString
aAttributeName( xAnimate
->getAttributeName() );
1692 if ( nForceAttributeNames
)
1694 if( nForceAttributeNames
== 1 )
1696 aAttributeName
= "r";
1699 sal_Int32 nIndex
= 0;
1702 OUString
aToken( aAttributeName
.getToken( 0, ';', nIndex
) );
1703 exportAnimPropertyString( rStrm
, 0, aToken
, TRANSLATE_ATTRIBUTE
);
1705 while ( nIndex
>= 0 );
1708 if( nAfterEffectType
!= AFTEREFFECT_NONE
)
1710 EscherExContainer
aAnimPropertySet( rStrm
, DFF_msofbtAnimPropertySet
);
1711 exportAnimPropertyuInt32( rStrm
, 6, 1, TRANSLATE_NONE
);
1712 if( nAfterEffectType
== AFTEREFFECT_COLOR
)
1714 exportAnimPropertyuInt32( rStrm
, 4, 0, TRANSLATE_NONE
);
1715 exportAnimPropertyuInt32( rStrm
, 5, 0, TRANSLATE_NONE
);
1718 exportAnimateTargetElement( rStrm
, aTarget
.hasValue() ? aTarget
: xAnimate
->getTarget(), sal_False
);
1722 Reference
< XShape
> AnimationExporter::getTargetElementShape( const Any
& rAny
, sal_Int32
& rBegin
, sal_Int32
& rEnd
, sal_Bool
& rParagraphTarget
)
1724 Reference
< XShape
> xShape
;
1727 rParagraphTarget
= sal_False
;
1731 ParagraphTarget aParaTarget
;
1732 if( rAny
>>= aParaTarget
)
1733 xShape
= aParaTarget
.Shape
;
1736 // now calculating the character range for the paragraph
1737 sal_Int16 nParagraph
= aParaTarget
.Paragraph
;
1738 Reference
< XSimpleText
> xText( xShape
, UNO_QUERY
);
1741 rParagraphTarget
= sal_True
;
1742 Reference
< XEnumerationAccess
> xTextParagraphEnumerationAccess( xText
, UNO_QUERY
);
1743 if ( xTextParagraphEnumerationAccess
.is() )
1745 Reference
< XEnumeration
> xTextParagraphEnumeration( xTextParagraphEnumerationAccess
->createEnumeration() );
1746 if ( xTextParagraphEnumeration
.is() )
1748 sal_Int16 nCurrentParagraph
;
1749 rBegin
= rEnd
= nCurrentParagraph
= 0;
1750 while ( xTextParagraphEnumeration
->hasMoreElements() )
1752 Reference
< XTextRange
> xTextRange( xTextParagraphEnumeration
->nextElement(), UNO_QUERY
);
1753 if ( xTextRange
.is() )
1755 OUString
aParaText( xTextRange
->getString() );
1756 sal_Int32 nLength
= aParaText
.getLength() + 1;
1758 if ( nCurrentParagraph
== nParagraph
)
1760 nCurrentParagraph
++;
1773 void AnimationExporter::exportAnimateTargetElement( SvStream
& rStrm
, const Any aAny
, const sal_Bool bCreate2b01Atom
)
1775 sal_uInt32 nRefMode
= 0; // nRefMode == 2 -> Paragraph
1776 sal_Int32 begin
= -1;
1778 sal_Bool bParagraphTarget
;
1780 Reference
< XShape
> xShape
= getTargetElementShape( aAny
, begin
, end
, bParagraphTarget
);
1782 if( bParagraphTarget
)
1785 if ( xShape
.is() || bCreate2b01Atom
)
1787 EscherExContainer
aAnimateTargetElement( rStrm
, DFF_msofbtAnimateTargetElement
);
1790 EscherExAtom
aAnimReference( rStrm
, DFF_msofbtAnimReference
);
1792 sal_uInt32 nRefType
= 1; // TODO: nRefType == 2 -> Sound;
1793 sal_uInt32 nRefId
= ((EscherSolverContainer
&)mrSolverContainer
).GetShapeId( xShape
);
1801 if ( bCreate2b01Atom
)
1803 EscherExAtom
a2b01Atom( rStrm
, 0x2b01 );
1804 rStrm
<< (sal_uInt32
)1; // ?
1809 void AnimationExporter::exportAnimateKeyPoints( SvStream
& rStrm
, const Reference
< XAnimate
>& xAnimate
)
1811 Sequence
< double > aKeyTimes( xAnimate
->getKeyTimes() );
1812 Sequence
< Any
> aValues( xAnimate
->getValues() );
1813 OUString
aFormula( xAnimate
->getFormula() );
1814 if ( aKeyTimes
.getLength() )
1816 EscherExContainer
aAnimKeyPoints( rStrm
, DFF_msofbtAnimKeyPoints
);
1818 for ( i
= 0; i
< aKeyTimes
.getLength(); i
++ )
1821 EscherExAtom
aAnimKeyTime( rStrm
, DFF_msofbtAnimKeyTime
);
1822 sal_Int32 nKeyTime
= (sal_Int32
)( aKeyTimes
[ i
] * 1000.0 );
1826 if ( aValues
[ i
].hasValue() )
1829 if ( aValues
[ i
] >>= aPair
)
1831 aAny
[ 0 ] = convertAnimateValue( aPair
.First
, xAnimate
->getAttributeName() );
1832 aAny
[ 1 ] = convertAnimateValue( aPair
.Second
, xAnimate
->getAttributeName() );
1836 aAny
[ 0 ] = convertAnimateValue( aValues
[ i
], xAnimate
->getAttributeName() );
1838 if ( !i
&& !aFormula
.isEmpty() )
1840 ImplTranslateAttribute( aFormula
, TRANSLATE_MEASURE
);
1841 aAny
[ 1 ] <<= aFormula
;
1843 exportAnimProperty( rStrm
, 0, aAny
[ 0 ], TRANSLATE_NONE
);
1844 exportAnimProperty( rStrm
, 1, aAny
[ 1 ], TRANSLATE_NONE
);
1850 void AnimationExporter::exportAnimValue( SvStream
& rStrm
, const Reference
< XAnimationNode
>& xNode
, const sal_Bool bExportAlways
)
1854 double fRepeat
= 0.0;
1855 float fRepeatCount
= 0.0;
1856 com::sun::star::animations::Timing eTiming
;
1857 aAny
= xNode
->getRepeatCount();
1858 if ( aAny
>>= eTiming
)
1860 if ( eTiming
== Timing_INDEFINITE
)
1861 fRepeatCount
= ((float)3.40282346638528860e+38);
1863 else if ( aAny
>>= fRepeat
)
1864 fRepeatCount
= (float)fRepeat
;
1865 if ( fRepeatCount
!= 0.0 )
1867 EscherExAtom
aExAtom( rStrm
, DFF_msofbtAnimValue
);
1868 sal_uInt32 nType
= 0;
1873 float fAccelerate
= (float)xNode
->getAcceleration();
1874 if ( bExportAlways
|| ( fAccelerate
!= 0.0 ) )
1876 EscherExAtom
aExAtom( rStrm
, DFF_msofbtAnimValue
);
1877 sal_uInt32 nType
= 3;
1883 float fDecelerate
= (float)xNode
->getDecelerate();
1884 if ( bExportAlways
|| ( fDecelerate
!= 0.0 ) )
1886 EscherExAtom
aExAtom( rStrm
, DFF_msofbtAnimValue
);
1887 sal_uInt32 nType
= 4;
1893 sal_Bool bAutoReverse
= xNode
->getAutoReverse();
1894 if ( bExportAlways
|| bAutoReverse
)
1896 EscherExAtom
aExAtom( rStrm
, DFF_msofbtAnimValue
);
1897 sal_uInt32 nType
= 5;
1898 sal_uInt32 nVal
= bAutoReverse
? 1 : 0;
1904 void AnimationExporter::exportTransitionFilter( SvStream
& rStrm
, const Reference
< XAnimationNode
>& xNode
)
1906 Reference
< XTransitionFilter
> xFilter( xNode
, UNO_QUERY
);
1909 EscherExContainer
aAnimateFilter( rStrm
, DFF_msofbtAnimateFilter
);
1911 EscherExAtom
aAnimateFilterData( rStrm
, DFF_msofbtAnimateFilterData
);
1912 sal_uInt32 nBits
= 3; // bit 0 -> use AnimAttributeValue
1913 // bit 1 -> use nTransition
1915 sal_uInt32 nTransition
= xFilter
->getMode() ? 0 : 1;
1919 const sal_Char
* pFilter
= FindTransitionName( xFilter
->getTransition(), xFilter
->getSubtype(), xFilter
->getDirection() );
1922 const OUString
aStr( OUString::createFromAscii( pFilter
) );
1923 exportAnimPropertyString( rStrm
, 1, aStr
, TRANSLATE_NONE
);
1925 exportAnimateTarget( rStrm
, xNode
);
1929 void AnimationExporter::exportAnimateMotion( SvStream
& rStrm
, const Reference
< XAnimationNode
>& xNode
)
1931 Reference
< XAnimateMotion
> xMotion( xNode
, UNO_QUERY
);
1934 EscherExContainer
aAnimateMotion( rStrm
, DFF_msofbtAnimateMotion
);
1936 { //SJ: Ignored from import filter
1937 EscherExAtom
aAnimateMotionData( rStrm
, DFF_msofbtAnimateMotionData
);
1938 sal_uInt32 nBits
= 0x98;
1939 sal_uInt32 nOrigin
= 0x2;
1940 float fByX
= 100.0; // nBits&1
1941 float fByY
= 100.0; // nBits&1
1942 float fFromX
= 0.0; // nBits&2
1943 float fFromY
= 0.0; // nBits&2
1944 float fToX
= 100.0; // nBits&4
1945 float fToY
= 100.0; // nBits&4
1946 rStrm
<< nBits
<< fByX
<< fByY
<< fFromX
<< fFromY
<< fToX
<< fToY
<< nOrigin
;
1950 if ( xMotion
->getPath() >>= aStr
)
1952 if ( !aStr
.isEmpty() )
1953 exportAnimPropertyString( rStrm
, 1, aStr
, TRANSLATE_NONE
);
1955 exportAnimateTarget( rStrm
, xNode
);
1960 void AnimationExporter::exportAnimateTransform( SvStream
& rStrm
, const Reference
< XAnimationNode
>& xNode
)
1962 Reference
< XAnimateTransform
> xTransform( xNode
, UNO_QUERY
);
1963 if ( xTransform
.is() )
1965 if ( xTransform
->getTransformType() == AnimationTransformType::SCALE
)
1967 EscherExContainer
aAnimateScale( rStrm
, DFF_msofbtAnimateScale
);
1969 EscherExAtom
aAnimateScaleData( rStrm
, DFF_msofbtAnimateScaleData
);
1970 sal_uInt32 nBits
= 0;
1971 sal_uInt32 nZoomContents
= 1;
1979 double fX
= 0.0, fY
= 0.0;
1981 if ( xTransform
->getBy() >>= aPair
)
1983 if ( ( aPair
.First
>>= fX
) && ( aPair
.Second
>>= fY
) )
1986 fByX
= (float)( fX
* 100 );
1987 fByY
= (float)( fY
* 100 );
1990 if ( xTransform
->getFrom() >>= aPair
)
1992 if ( ( aPair
.First
>>= fX
) && ( aPair
.Second
>>= fY
) )
1995 fFromX
= (float)( fX
* 100 );
1996 fFromY
= (float)( fY
* 100 );
1999 if( xTransform
->getTo() >>= aPair
)
2001 if ( ( aPair
.First
>>= fX
) && ( aPair
.Second
>>= fY
) )
2004 fToX
= (float)( fX
* 100 );
2005 fToY
= (float)( fY
* 100 );
2009 // TODO: ZoomContents:
2011 //( fprintf( mpFile, " zoomContents=\"%s\"", nZoomContents ? "true" : "false" );
2013 rStrm
<< nBits
<< fByX
<< fByY
<< fFromX
<< fFromY
<< fToX
<< fToY
<< nZoomContents
;
2015 exportAnimateTarget( rStrm
, xNode
);
2017 else if ( xTransform
->getTransformType() == AnimationTransformType::ROTATE
)
2019 EscherExContainer
aAnimateRotation( rStrm
, DFF_msofbtAnimateRotation
);
2021 EscherExAtom
aAnimateRotationData( rStrm
, DFF_msofbtAnimateRotationData
);
2022 sal_uInt32 nBits
= 0;
2029 if ( xTransform
->getBy() >>= fVal
)
2034 if ( xTransform
->getFrom() >>= fVal
)
2037 fFrom
= (float)fVal
;
2039 if ( xTransform
->getTo() >>= fVal
)
2044 rStrm
<< nBits
<< fBy
<< fFrom
<< fTo
<< nU1
;
2046 exportAnimateTarget( rStrm
, xNode
, 1 );
2051 sal_Bool
AnimationExporter::getColorAny( const Any
& rAny
, const sal_Int16 nColorSpace
, sal_Int32
& rMode
, sal_Int32
& rA
, sal_Int32
& rB
, sal_Int32
& rC
) const
2053 sal_Bool bIsColor
= sal_True
;
2056 if ( nColorSpace
== AnimationColorSpace::HSL
)
2059 sal_Int32 nColor
= 0;
2060 Sequence
< double > aHSL( 3 );
2061 if ( rAny
>>= nColor
) // RGB color
2063 rA
= (sal_uInt8
)( nColor
>> 16 );
2064 rB
= (sal_uInt8
)( nColor
>> 8 );
2065 rC
= (sal_uInt8
)( nColor
);
2067 else if ( rAny
>>= aHSL
) // HSL
2069 rA
= (sal_Int32
) ( aHSL
[ 0 ] * 255.0 / 360.0 );
2070 rB
= (sal_Int32
) ( aHSL
[ 1 ] * 255.0 );
2071 rC
= (sal_Int32
) ( aHSL
[ 2 ] * 255.0 );
2074 bIsColor
= sal_False
;
2078 void AnimationExporter::exportAnimateColor( SvStream
& rStrm
, const Reference
< XAnimationNode
>& xNode
, int nAfterEffectType
)
2080 Reference
< XAnimateColor
> xColor( xNode
, UNO_QUERY
);
2083 EscherExContainer
aAnimateColor( rStrm
, DFF_msofbtAnimateColor
);
2085 EscherExAtom
aAnimateColorData( rStrm
, DFF_msofbtAnimateColorData
);
2086 sal_uInt32 nBits
= 8;
2088 sal_Int32 nByMode
, nByA
, nByB
, nByC
;
2089 nByMode
= nByA
= nByB
= nByC
= 0;
2091 sal_Int32 nFromMode
, nFromA
, nFromB
, nFromC
;
2092 nFromMode
= nFromA
= nFromB
= nFromC
= 0;
2094 sal_Int32 nToMode
, nToA
, nToB
, nToC
;
2095 nToMode
= nToA
= nToB
= nToC
= 0;
2097 sal_Int16 nColorSpace
= xColor
->getColorInterpolation();
2099 Any
aAny( xColor
->getBy() );
2100 if ( aAny
.hasValue() )
2102 if ( getColorAny( aAny
, nColorSpace
, nByMode
, nByA
, nByB
, nByC
) )
2105 aAny
= xColor
->getFrom();
2106 if ( aAny
.hasValue() )
2108 if ( getColorAny( aAny
, nColorSpace
, nFromMode
, nFromA
, nFromB
, nFromC
) )
2111 aAny
= xColor
->getTo();
2112 if ( aAny
.hasValue() )
2114 if ( getColorAny( aAny
, nColorSpace
, nToMode
, nToA
, nToB
, nToC
) )
2118 << nByMode
<< nByA
<< nByB
<< nByC
2119 << nFromMode
<< nFromA
<< nFromB
<< nFromC
2120 << nToMode
<< nToA
<< nToB
<< nToC
;
2122 exportAnimateTarget( rStrm
, xNode
, 0, nAfterEffectType
);
2126 void AnimationExporter::exportIterate( SvStream
& rStrm
, const Reference
< XAnimationNode
>& xNode
)
2128 Reference
< XIterateContainer
> xIterate( xNode
, UNO_QUERY
);
2129 if ( xIterate
.is() )
2131 EscherExAtom
aAnimIteration( rStrm
, DFF_msofbtAnimIteration
);
2133 float fInterval
= 10.0;
2134 sal_Int32 nTextUnitEffect
= 0;
2137 sal_Int32 nU3
= 0xe;
2139 sal_Int16 nIterateType
= xIterate
->getIterateType();
2140 switch( nIterateType
)
2142 case TextAnimationType::BY_WORD
: nTextUnitEffect
= 1; break;
2143 case TextAnimationType::BY_LETTER
: nTextUnitEffect
= 2; break;
2146 fInterval
= (float)xIterate
->getIterateInterval();
2148 // convert interval from absolute to percentage
2149 double fDuration
= 0.0;
2151 Reference
< XEnumerationAccess
> xEnumerationAccess( xNode
, UNO_QUERY
);
2152 if( xEnumerationAccess
.is() )
2154 Reference
< XEnumeration
> xEnumeration( xEnumerationAccess
->createEnumeration(), UNO_QUERY
);
2155 if( xEnumeration
.is() )
2157 while( xEnumeration
->hasMoreElements() )
2159 Reference
< XAnimate
> xChildNode( xEnumeration
->nextElement(), UNO_QUERY
);
2160 if( xChildNode
.is() )
2162 double fChildBegin
= 0.0;
2163 double fChildDuration
= 0.0;
2164 xChildNode
->getBegin() >>= fChildBegin
;
2165 xChildNode
->getDuration() >>= fChildDuration
;
2167 fChildDuration
+= fChildBegin
;
2168 if( fChildDuration
> fDuration
)
2169 fDuration
= fChildDuration
;
2176 fInterval
= (float)(100.0 * fInterval
/ fDuration
);
2178 rStrm
<< fInterval
<< nTextUnitEffect
<< nU1
<< nU2
<< nU3
;
2179 aTarget
= xIterate
->getTarget();
2185 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */