1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: pptexanimations.cxx,v $
10 * $Revision: 1.15.108.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sd.hxx"
33 #include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
34 #include <com/sun/star/animations/AnimationFill.hpp>
35 #include <com/sun/star/animations/AnimationRestart.hpp>
36 #include <com/sun/star/animations/Timing.hpp>
37 #include <com/sun/star/animations/Event.hpp>
38 #include <com/sun/star/animations/AnimationEndSync.hpp>
39 #include <com/sun/star/animations/EventTrigger.hpp>
40 #include <com/sun/star/presentation/EffectNodeType.hpp>
41 #include <com/sun/star/presentation/EffectPresetClass.hpp>
42 #include <com/sun/star/animations/AnimationNodeType.hpp>
43 #include <com/sun/star/animations/AnimationTransformType.hpp>
44 #include <com/sun/star/animations/AnimationCalcMode.hpp>
45 #include <com/sun/star/animations/AnimationValueType.hpp>
46 #include <com/sun/star/util/XCloneable.hpp>
47 #include <com/sun/star/animations/AnimationAdditiveMode.hpp>
48 #include <com/sun/star/animations/XAnimateSet.hpp>
49 #include <com/sun/star/animations/XAudio.hpp>
50 #include <com/sun/star/animations/XTransitionFilter.hpp>
51 #include <com/sun/star/animations/XAnimateColor.hpp>
52 #include <com/sun/star/animations/XAnimateMotion.hpp>
53 #include <com/sun/star/animations/XAnimateTransform.hpp>
54 #include <com/sun/star/animations/TransitionType.hpp>
55 #include <com/sun/star/animations/TransitionSubType.hpp>
56 #include <com/sun/star/animations/ValuePair.hpp>
57 #include <com/sun/star/animations/AnimationColorSpace.hpp>
58 #include <com/sun/star/beans/NamedValue.hpp>
59 #include <com/sun/star/drawing/FillStyle.hpp>
60 #include <com/sun/star/drawing/LineStyle.hpp>
61 #include <com/sun/star/awt/FontWeight.hpp>
62 #include <com/sun/star/awt/FontUnderline.hpp>
63 #include <com/sun/star/awt/FontSlant.hpp>
64 #include <com/sun/star/container/XEnumerationAccess.hpp>
65 #include <com/sun/star/presentation/ParagraphTarget.hpp>
66 #include <com/sun/star/text/XSimpleText.hpp>
67 #include <com/sun/star/animations/XIterateContainer.hpp>
68 #include <com/sun/star/presentation/TextAnimationType.hpp>
69 #include <com/sun/star/container/XChild.hpp>
70 #include <comphelper/processfactory.hxx>
71 #include <rtl/ustrbuf.hxx>
72 #ifndef _RTL_MEMORY_H_
73 #include <rtl/memory.hxx>
76 #include <vcl/vclenum.hxx>
77 #include <svx/svdotext.hxx>
78 #include <svx/outlobj.hxx>
79 #include <svx/editobj.hxx>
80 #include <pptexanimations.hxx>
81 #include <osl/endian.h>
86 using ::rtl::OUString
;
87 using ::rtl::OUStringBuffer
;
88 using ::com::sun::star::uno::Any
;
89 using ::com::sun::star::container::XChild
;
90 using ::com::sun::star::util::XCloneable
;
91 using ::com::sun::star::uno::Reference
;
92 using ::com::sun::star::uno::UNO_QUERY
;
93 using ::com::sun::star::uno::UNO_QUERY_THROW
;
94 using ::com::sun::star::uno::Sequence
;
95 using ::com::sun::star::uno::makeAny
;
96 using ::com::sun::star::uno::Exception
;
97 using ::com::sun::star::uno::XInterface
;
98 using ::com::sun::star::beans::NamedValue
;
99 using ::com::sun::star::container::XEnumerationAccess
;
100 using ::com::sun::star::container::XEnumeration
;
101 using ::com::sun::star::lang::XMultiServiceFactory
;
103 using namespace ::com::sun::star::text
;
104 using namespace ::com::sun::star::drawing
;
105 using namespace ::com::sun::star::animations
;
106 using namespace ::com::sun::star::presentation
;
111 void ImplTranslateAttribute( rtl::OUString
& rString
, const TranslateMode eTranslateMode
)
113 if ( eTranslateMode
!= TRANSLATE_NONE
)
115 if ( ( eTranslateMode
& TRANSLATE_VALUE
) || ( eTranslateMode
& TRANSLATE_ATTRIBUTE
) )
117 const ImplAttributeNameConversion
* p
= gImplConversionList
;
118 while( p
->mpAPIName
)
120 if( rString
.compareToAscii( p
->mpAPIName
) == 0 )
126 if ( eTranslateMode
& TRANSLATE_VALUE
)
128 rString
= rtl::OUString( (sal_Unicode
)'#' );
129 rString
+= OUString::createFromAscii( p
->mpMSName
);
132 rString
= OUString::createFromAscii( p
->mpMSName
);
135 else if ( eTranslateMode
& TRANSLATE_MEASURE
)
137 const sal_Char
* pDest
[] = { "#ppt_x", "#ppt_y", "#ppt_w", "#ppt_h", NULL
};
138 const sal_Char
* pSource
[] = { "x", "y", "width", "height", NULL
};
139 sal_Int32 nIndex
= 0;
141 const sal_Char
** ps
= pSource
;
142 const sal_Char
** pd
= pDest
;
146 const OUString
aSearch( OUString::createFromAscii( *ps
) );
147 while( (nIndex
= rString
.indexOf( aSearch
, nIndex
)) != -1 )
149 sal_Int32 nLength
= aSearch
.getLength();
150 if( nIndex
&& (rString
.getStr()[nIndex
-1] == '#' ) )
156 const OUString
aNew( OUString::createFromAscii( *pd
) );
157 rString
= rString
.replaceAt( nIndex
, nLength
, aNew
);
158 nIndex
+= aNew
.getLength();
167 sal_uInt32
ImplTranslatePresetSubType( const sal_uInt32 nPresetClass
, const sal_uInt32 nPresetId
, const rtl::OUString
& rPresetSubType
)
169 sal_uInt32 nPresetSubType
= 0;
170 sal_Bool bTranslated
= sal_False
;
172 if ( ( nPresetClass
== (sal_uInt32
)EffectPresetClass::ENTRANCE
) || ( nPresetClass
== (sal_uInt32
)EffectPresetClass::EXIT
) )
174 if ( nPresetId
!= 21 )
180 if ( rPresetSubType
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "downward" ) ) )
183 bTranslated
= sal_True
;
185 else if ( rPresetSubType
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "across" ) ) )
188 bTranslated
= sal_True
;
194 if ( rPresetSubType
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "across" ) ) )
197 bTranslated
= sal_True
;
203 if ( rPresetSubType
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "right-to-top" ) ) )
206 bTranslated
= sal_True
;
208 else if ( rPresetSubType
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "right-to-bottom" ) ) )
211 bTranslated
= sal_True
;
213 else if ( rPresetSubType
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "left-to-top" ) ) )
216 bTranslated
= sal_True
;
218 else if ( rPresetSubType
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "left-to-bottom" ) ) )
221 bTranslated
= sal_True
;
229 const convert_subtype
* p
= gConvertArray
;
230 while( p
->mpStrSubType
)
232 if ( rPresetSubType
.equalsAscii( p
->mpStrSubType
) )
234 nPresetSubType
= p
->mnID
;
235 bTranslated
= sal_True
;
243 nPresetSubType
= (sal_uInt32
)rPresetSubType
.toInt32();
244 return nPresetSubType
;
247 const sal_Char
* transition::find( const sal_Int16 nType
, const sal_Int16 nSubType
, const sal_Bool bDirection
)
249 const sal_Char
* pRet
= NULL
;
252 const transition
* p
= gTransitions
;
256 if ( nType
== p
->mnType
)
258 if ( nSubType
== p
->mnSubType
)
260 if ( bDirection
== p
->mbDirection
)
267 if ( nFit
== 7 ) // maximum
274 SvStream
& operator<<(SvStream
& rOut
, AnimationNode
& rNode
)
277 rOut
<< rNode
.mnRestart
;
278 rOut
<< rNode
.mnGroupType
;
279 rOut
<< rNode
.mnFill
;
282 rOut
<< rNode
.mnDuration
;
283 rOut
<< rNode
.mnNodeType
;
288 AnimationExporter::AnimationExporter( const EscherSolverContainer
& rSolverContainer
, ppt::ExSoundCollection
& rExSoundCollection
) :
289 mrSolverContainer ( rSolverContainer
),
290 mrExSoundCollection ( rExSoundCollection
),
295 // --------------------------------------------------------------------
297 static sal_Int16
GetFillMode( const Reference
< XAnimationNode
>& xNode
, const sal_Int16 nFillDefault
)
299 sal_Int16 nFill
= xNode
->getFill();
300 if ( ( nFill
== AnimationFill::DEFAULT
) ||
301 ( nFill
== AnimationFill::INHERIT
) )
303 if ( nFill
!= AnimationFill::AUTO
)
304 nFill
= nFillDefault
;
306 if( nFill
== AnimationFill::AUTO
)
308 nFill
= AnimationFill::REMOVE
;
309 sal_Bool bIsIndefiniteTiming
= sal_True
;
310 Any aAny
= xNode
->getDuration();
311 if( aAny
.hasValue() )
314 if( aAny
>>= eTiming
)
315 bIsIndefiniteTiming
= eTiming
== Timing_INDEFINITE
;
317 if ( bIsIndefiniteTiming
)
319 aAny
= xNode
->getEnd();
320 if( aAny
.hasValue() )
323 if( aAny
>>= eTiming
)
324 bIsIndefiniteTiming
= eTiming
== Timing_INDEFINITE
;
326 if ( bIsIndefiniteTiming
)
328 if ( !xNode
->getRepeatCount().hasValue() )
330 aAny
= xNode
->getRepeatDuration();
331 if( aAny
.hasValue() )
334 if( aAny
>>= eTiming
)
335 bIsIndefiniteTiming
= eTiming
== Timing_INDEFINITE
;
337 if ( bIsIndefiniteTiming
)
338 nFill
= AnimationFill::FREEZE
;
346 void AnimationExporter::doexport( const Reference
< XDrawPage
>& xPage
, SvStream
& rStrm
)
348 Reference
< XAnimationNodeSupplier
> xNodeSupplier( xPage
, UNO_QUERY
);
349 if( xNodeSupplier
.is() )
351 const Reference
< XAnimationNode
> xRootNode( xNodeSupplier
->getAnimationNode() );
354 processAfterEffectNodes( xRootNode
);
355 exportNode( rStrm
, xRootNode
, NULL
, DFF_msofbtAnimGroup
, 1, 0, sal_False
, AnimationFill::AUTO
);
360 void AnimationExporter::processAfterEffectNodes( const Reference
< XAnimationNode
>& xRootNode
)
364 Reference
< XEnumerationAccess
> xEnumerationAccess( xRootNode
, UNO_QUERY_THROW
);
365 Reference
< XEnumeration
> xEnumeration( xEnumerationAccess
->createEnumeration(), UNO_QUERY_THROW
);
366 while( xEnumeration
->hasMoreElements() )
368 Reference
< XAnimationNode
> xNode( xEnumeration
->nextElement(), UNO_QUERY_THROW
);
370 Reference
< XEnumerationAccess
> xEnumerationAccess2( xNode
, UNO_QUERY
);
371 if ( xEnumerationAccess2
.is() )
373 Reference
< XEnumeration
> xEnumeration2( xEnumerationAccess2
->createEnumeration(), UNO_QUERY_THROW
);
374 while( xEnumeration2
->hasMoreElements() )
376 Reference
< XAnimationNode
> xChildNode( xEnumeration2
->nextElement(), UNO_QUERY_THROW
);
378 Reference
< XEnumerationAccess
> xEnumerationAccess3( xChildNode
, UNO_QUERY_THROW
);
379 Reference
< XEnumeration
> xEnumeration3( xEnumerationAccess3
->createEnumeration(), UNO_QUERY_THROW
);
380 while( xEnumeration3
->hasMoreElements() )
382 Reference
< XAnimationNode
> xChildNode2( xEnumeration3
->nextElement(), UNO_QUERY_THROW
);
384 Reference
< XEnumerationAccess
> xEnumerationAccess4( xChildNode2
, UNO_QUERY_THROW
);
385 Reference
< XEnumeration
> xEnumeration4( xEnumerationAccess4
->createEnumeration(), UNO_QUERY_THROW
);
386 while( xEnumeration4
->hasMoreElements() )
388 Reference
< XAnimationNode
> xChildNode3( xEnumeration4
->nextElement(), UNO_QUERY_THROW
);
390 switch( xChildNode3
->getType() )
392 // found an after effect
393 case AnimationNodeType::SET
:
394 case AnimationNodeType::ANIMATECOLOR
:
396 Reference
< XAnimationNode
> xMaster
;
398 Sequence
< NamedValue
> aUserData( xChildNode3
->getUserData() );
399 sal_Int32 nLength
= aUserData
.getLength();
400 const NamedValue
* p
= aUserData
.getConstArray();
404 if( p
->Name
.equalsAscii( "master-element" ) )
406 p
->Value
>>= xMaster
;
412 AfterEffectNodePtr
pAfterEffectNode( new AfterEffectNode( xChildNode3
, xMaster
) );
413 maAfterEffectNodes
.push_back( pAfterEffectNode
);
423 catch( Exception
& e
)
426 DBG_ERROR( "(@CL)AnimationExporter::processAfterEffectNodes(), exception cought!" );
430 bool AnimationExporter::isAfterEffectNode( const Reference
< XAnimationNode
>& xNode
) const
432 std::list
< AfterEffectNodePtr
>::const_iterator
aIter( maAfterEffectNodes
.begin() );
433 const std::list
< AfterEffectNodePtr
>::const_iterator
aEnd( maAfterEffectNodes
.end() );
434 while( aIter
!= aEnd
)
436 if( (*aIter
)->mxNode
== xNode
)
444 bool AnimationExporter::hasAfterEffectNode( const Reference
< XAnimationNode
>& xNode
, Reference
< XAnimationNode
>& xAfterEffectNode
) const
446 std::list
< AfterEffectNodePtr
>::const_iterator
aIter( maAfterEffectNodes
.begin() );
447 const std::list
< AfterEffectNodePtr
>::const_iterator
aEnd( maAfterEffectNodes
.end() );
448 while( aIter
!= aEnd
)
450 if( (*aIter
)->mxMaster
== xNode
)
452 xAfterEffectNode
= (*aIter
)->mxNode
;
461 // check if this group only contain empty groups. this may happen when
462 // after effect nodes are not exported at theire original position
463 bool AnimationExporter::isEmptyNode( const Reference
< XAnimationNode
>& xNode
) const
465 if( xNode
.is() ) switch( xNode
->getType() )
467 case AnimationNodeType::PAR
:
468 case AnimationNodeType::SEQ
:
469 case AnimationNodeType::ITERATE
:
471 Reference
< XEnumerationAccess
> xEnumerationAccess( xNode
, UNO_QUERY
);
472 if( xEnumerationAccess
.is() )
474 Reference
< XEnumeration
> xEnumeration( xEnumerationAccess
->createEnumeration(), UNO_QUERY
);
475 if( xEnumeration
.is() )
477 while( xEnumeration
->hasMoreElements() )
479 Reference
< XAnimationNode
> xChildNode( xEnumeration
->nextElement(), UNO_QUERY
);
480 if( xChildNode
.is() && !isEmptyNode( xChildNode
) )
488 case AnimationNodeType::SET
:
489 case AnimationNodeType::ANIMATECOLOR
:
490 return isAfterEffectNode( xNode
);
498 void AnimationExporter::exportNode( SvStream
& rStrm
, Reference
< XAnimationNode
> xNode
, const Reference
< XAnimationNode
>* pParent
, const sal_uInt16 nContainerRecType
,
499 const sal_uInt16 nInstance
, const sal_Int32 nGroupLevel
, const sal_Bool bTakeBackInteractiveSequenceTiming
, const sal_Int16 nFDef
)
501 if( (nGroupLevel
== 4) && isEmptyNode( xNode
) )
504 if ( ( nContainerRecType
== DFF_msofbtAnimGroup
) && ( nGroupLevel
== 2 ) && isEmptyNode( xNode
) )
507 if( nContainerRecType
== DFF_msofbtAnimGroup
)
510 sal_Bool bTakeBackInteractiveSequenceTimingForChild
= sal_False
;
511 sal_Int16 nFillDefault
= GetFillMode( xNode
, nFDef
);
513 bool bSkipChildren
= false;
515 Reference
< XAnimationNode
> xAudioNode
;
516 static sal_uInt32 nAudioGroup
;
519 EscherExContainer
aContainer( rStrm
, nContainerRecType
, nInstance
);
520 switch( xNode
->getType() )
522 case AnimationNodeType::CUSTOM
:
524 exportAnimNode( rStrm
, xNode
, pParent
, nGroupLevel
, nFillDefault
);
525 exportAnimPropertySet( rStrm
, xNode
);
526 exportAnimEvent( rStrm
, xNode
, 0 );
527 exportAnimValue( rStrm
, xNode
, sal_False
);
531 case AnimationNodeType::PAR
:
533 exportAnimNode( rStrm
, xNode
, pParent
, nGroupLevel
, nFillDefault
);
534 exportAnimPropertySet( rStrm
, xNode
);
535 sal_Int32 nFlags
= nGroupLevel
== 2 ? 0x10 : 0;
536 if ( bTakeBackInteractiveSequenceTiming
)
538 exportAnimEvent( rStrm
, xNode
, nFlags
);
539 exportAnimValue( rStrm
, xNode
, nGroupLevel
== 4 );
543 case AnimationNodeType::SEQ
:
545 exportAnimNode( rStrm
, xNode
, pParent
, nGroupLevel
, nFillDefault
);
546 sal_Int16 nNodeType
= exportAnimPropertySet( rStrm
, xNode
);
547 sal_Int32 nFlags
= 12;
548 if ( ( nGroupLevel
== 1 ) && ( nNodeType
== ::com::sun::star::presentation::EffectNodeType::INTERACTIVE_SEQUENCE
) )
551 bTakeBackInteractiveSequenceTimingForChild
= sal_True
;
553 exportAnimAction( rStrm
, xNode
);
554 exportAnimEvent( rStrm
, xNode
, nFlags
);
555 exportAnimValue( rStrm
, xNode
, sal_False
);
559 case AnimationNodeType::ITERATE
:
562 EscherExAtom
aAnimNodeExAtom( rStrm
, DFF_msofbtAnimNode
);
564 rtl_zeroMemory( &aAnim
, sizeof( aAnim
) );
565 aAnim
.mnGroupType
= mso_Anim_GroupType_PAR
;
566 aAnim
.mnNodeType
= 1;
568 switch( xNode
->getRestart() )
571 case AnimationRestart::DEFAULT
: aAnim
.mnRestart
= 0; break;
572 case AnimationRestart::ALWAYS
: aAnim
.mnRestart
= 1; break;
573 case AnimationRestart::WHEN_NOT_ACTIVE
: aAnim
.mnRestart
= 2; break;
574 case AnimationRestart::NEVER
: aAnim
.mnRestart
= 3; break;
577 switch( xNode
->getFill() )
580 case AnimationFill::DEFAULT
: aAnim
.mnFill
= 0; break;
581 case AnimationFill::REMOVE
: aAnim
.mnFill
= 1; break;
582 case AnimationFill::FREEZE
: aAnim
.mnFill
= 2; break;
583 case AnimationFill::HOLD
: aAnim
.mnFill
= 3; break;
584 case AnimationFill::TRANSITION
: aAnim
.mnFill
= 4; break;
588 exportIterate( rStrm
, xNode
);
589 exportAnimPropertySet( rStrm
, xNode
);
590 exportAnimEvent( rStrm
, xNode
, 0 );
591 exportAnimValue( rStrm
, xNode
, sal_False
);
594 EscherExContainer aContainer( rStrm, DFF_msofbtAnimGroup, 1 );
595 exportAnimNode( rStrm, xNode, pParent, nGroupLevel + 1, nFillDefault );
596 exportAnimPropertySet( rStrm, xNode );
597 exportAnimEvent( rStrm, xNode, 0 );
598 exportAnimValue( rStrm, xNode, sal_False );
603 case AnimationNodeType::ANIMATE
:
605 exportAnimNode( rStrm
, xNode
, pParent
, nGroupLevel
, nFillDefault
);
606 exportAnimPropertySet( rStrm
, xNode
);
607 exportAnimEvent( rStrm
, xNode
, 0 );
608 exportAnimValue( rStrm
, xNode
, sal_False
);
609 exportAnimate( rStrm
, xNode
);
613 case AnimationNodeType::SET
:
615 bool bIsAfterEffectNode( isAfterEffectNode( xNode
) );
616 if( (nGroupLevel
!= 4) || !bIsAfterEffectNode
)
618 exportAnimNode( rStrm
, xNode
, pParent
, nGroupLevel
, nFillDefault
);
619 exportAnimPropertySet( rStrm
, xNode
);
620 exportAnimateSet( rStrm
, xNode
, bIsAfterEffectNode
? AFTEREFFECT_SET
: AFTEREFFECT_NONE
);
621 exportAnimEvent( rStrm
, xNode
, 0 );
622 exportAnimValue( rStrm
, xNode
, sal_False
);
626 bSkipChildren
= true;
631 case AnimationNodeType::ANIMATEMOTION
:
633 exportAnimNode( rStrm
, xNode
, pParent
, nGroupLevel
, nFillDefault
);
634 exportAnimPropertySet( rStrm
, xNode
);
635 exportAnimateMotion( rStrm
, xNode
);
636 exportAnimEvent( rStrm
, xNode
, 0 );
637 exportAnimValue( rStrm
, xNode
, sal_False
);
641 case AnimationNodeType::ANIMATECOLOR
:
643 bool bIsAfterEffectNode( isAfterEffectNode( xNode
) );
644 if( (nGroupLevel
!= 4) || !bIsAfterEffectNode
)
646 if( bIsAfterEffectNode
)
647 xNode
= createAfterEffectNodeClone( xNode
);
649 exportAnimNode( rStrm
, xNode
, pParent
, nGroupLevel
, nFillDefault
);
650 exportAnimPropertySet( rStrm
, xNode
);
651 exportAnimateColor( rStrm
, xNode
, bIsAfterEffectNode
? AFTEREFFECT_COLOR
: AFTEREFFECT_NONE
);
652 exportAnimEvent( rStrm
, xNode
, 0 );
653 exportAnimValue( rStrm
, xNode
, sal_False
);
657 bSkipChildren
= true;
662 case AnimationNodeType::ANIMATETRANSFORM
:
664 exportAnimNode( rStrm
, xNode
, pParent
, nGroupLevel
, nFillDefault
);
665 exportAnimPropertySet( rStrm
, xNode
);
666 exportAnimateTransform( rStrm
, xNode
);
667 exportAnimEvent( rStrm
, xNode
, 0 );
668 exportAnimValue( rStrm
, xNode
, sal_False
);
672 case AnimationNodeType::TRANSITIONFILTER
:
674 exportAnimNode( rStrm
, xNode
, pParent
, nGroupLevel
, nFillDefault
);
675 exportAnimPropertySet( rStrm
, xNode
);
676 exportAnimEvent( rStrm
, xNode
, 0 );
677 exportAnimValue( rStrm
, xNode
, sal_False
);
678 exportTransitionFilter( rStrm
, xNode
);
682 case AnimationNodeType::AUDIO
: // #i58428#
684 exportAnimNode( rStrm
, xNode
, pParent
, nGroupLevel
, nFillDefault
);
685 exportAnimPropertySet( rStrm
, xNode
);
687 Reference
< XAudio
> xAudio( xNode
, UNO_QUERY
);
690 Any
aAny( xAudio
->getSource() );
693 if ( ( aAny
>>= aURL
) && ( aURL
.getLength() ) )
696 sal_Int32 nTrigger
= 3;
697 sal_Int32 nU3
= nAudioGroup
;
698 sal_Int32 nBegin
= 0;
700 EscherExContainer
aAnimEvent( rStrm
, DFF_msofbtAnimEvent
, 1 );
702 EscherExAtom
aAnimTrigger( rStrm
, DFF_msofbtAnimTrigger
);
703 rStrm
<< nU1
<< nTrigger
<< nU3
<< nBegin
;
710 EscherExContainer
aAnimEvent( rStrm
, DFF_msofbtAnimEvent
, 2 );
712 EscherExAtom
aAnimTrigger( rStrm
, DFF_msofbtAnimTrigger
);
713 rStrm
<< nU1
<< nTrigger
<< nU3
<< nBegin
;
716 EscherExContainer
aAnimateTargetElement( rStrm
, DFF_msofbtAnimateTargetElement
);
718 sal_uInt32 nRefMode
= 3;
719 sal_uInt32 nRefType
= 2;
720 sal_uInt32 nRefId
= mrExSoundCollection
.GetId( aURL
);
721 sal_Int32 begin
= -1;
724 EscherExAtom
aAnimReference( rStrm
, DFF_msofbtAnimReference
);
725 rStrm
<< nRefMode
<< nRefType
<< nRefId
<< begin
<< end
;
729 exportAnimValue( rStrm
, xNode
, sal_False
);
735 // export after effect node if one exists for this node
736 Reference
< XAnimationNode
> xAfterEffectNode
;
737 if( hasAfterEffectNode( xNode
, xAfterEffectNode
) )
739 exportNode( rStrm
, xAfterEffectNode
, &xNode
, DFF_msofbtAnimSubGoup
, 1, nGroupLevel
+ 1, bTakeBackInteractiveSequenceTimingForChild
, nFillDefault
);
742 Reference
< XEnumerationAccess
> xEnumerationAccess( xNode
, UNO_QUERY
);
743 if( xEnumerationAccess
.is() )
745 Reference
< XEnumeration
> xEnumeration( xEnumerationAccess
->createEnumeration(), UNO_QUERY
);
746 if( xEnumeration
.is() )
748 while( xEnumeration
->hasMoreElements() )
750 Reference
< XAnimationNode
> xChildNode( xEnumeration
->nextElement(), UNO_QUERY
);
751 if( xChildNode
.is() )
753 if ( xChildNode
->getType() == AnimationNodeType::AUDIO
)
755 xAudioNode
= xChildNode
;
756 nAudioGroup
= mnCurrentGroup
;
759 exportNode( rStrm
, xChildNode
, &xNode
, DFF_msofbtAnimGroup
, 1, nGroupLevel
+ 1, bTakeBackInteractiveSequenceTimingForChild
, nFillDefault
);
766 if ( xAudioNode
.is() )
767 exportNode( rStrm
, xAudioNode
, &xNode
, DFF_msofbtAnimGroup
, 1, nGroupLevel
, bTakeBackInteractiveSequenceTimingForChild
, nFillDefault
);
769 if( xNode
->getType() == AnimationNodeType::ITERATE
)
773 Reference
< XAnimationNode
> AnimationExporter::createAfterEffectNodeClone( const Reference
< XAnimationNode
>& xNode
) const
777 Reference
< ::com::sun::star::util::XCloneable
> xClonable( xNode
, UNO_QUERY_THROW
);
778 Reference
< XAnimationNode
> xCloneNode( xClonable
->createClone(), UNO_QUERY_THROW
);
781 xCloneNode
->setBegin( aEmpty
);
786 catch( Exception
& e
)
789 DBG_ERROR("(@CL)sd::ppt::AnimationExporter::createAfterEffectNodeClone(), could not create clone!" );
794 void AnimationExporter::exportAnimNode( SvStream
& rStrm
, const Reference
< XAnimationNode
>& xNode
,
795 const ::com::sun::star::uno::Reference
< ::com::sun::star::animations::XAnimationNode
>*, const sal_Int32
, const sal_Int16 nFillDefault
)
797 EscherExAtom
aAnimNodeExAtom( rStrm
, DFF_msofbtAnimNode
);
799 rtl_zeroMemory( &aAnim
, sizeof( aAnim
) );
802 switch( xNode
->getRestart() )
805 case AnimationRestart::DEFAULT
: aAnim
.mnRestart
= 0; break;
806 case AnimationRestart::ALWAYS
: aAnim
.mnRestart
= 1; break;
807 case AnimationRestart::WHEN_NOT_ACTIVE
: aAnim
.mnRestart
= 2; break;
808 case AnimationRestart::NEVER
: aAnim
.mnRestart
= 3; break;
812 // aAnim.mnFill = GetFillMode( xNode, pParent );
813 switch( nFillDefault
)
816 case AnimationFill::DEFAULT
: aAnim
.mnFill
= 0; break;
817 case AnimationFill::REMOVE
: aAnim
.mnFill
= 1; break;
818 case AnimationFill::FREEZE
: // aAnim.mnFill = 2; break;
819 case AnimationFill::HOLD
: aAnim
.mnFill
= 3; break;
820 case AnimationFill::TRANSITION
: aAnim
.mnFill
= 4; break;
822 // attribute Duration
823 double fDuration
= 0.0;
824 com::sun::star::animations::Timing eTiming
;
825 if ( xNode
->getDuration() >>= eTiming
)
827 if ( eTiming
== Timing_INDEFINITE
)
828 aAnim
.mnDuration
= -1;
830 else if ( xNode
->getDuration() >>= fDuration
)
832 aAnim
.mnDuration
= (sal_Int32
)( fDuration
* 1000.0 );
835 aAnim
.mnDuration
= -1;
837 // NodeType, NodeGroup
838 aAnim
.mnNodeType
= 1;
839 aAnim
.mnGroupType
= mso_Anim_GroupType_SEQ
;
840 switch( xNode
->getType() )
842 case AnimationNodeType::PAR
: // PASSTROUGH!!! (as it was intended)
843 aAnim
.mnGroupType
= mso_Anim_GroupType_PAR
;
844 case AnimationNodeType::SEQ
:
846 // trying to get the nodetype
847 Sequence
< NamedValue
> aUserData
= xNode
->getUserData();
848 if ( aUserData
.getLength() )
850 const NamedValue
* p
= aUserData
.getConstArray();
851 sal_Int32 nLength
= aUserData
.getLength();
854 if( p
->Name
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "node-type" ) ) )
857 if ( p
->Value
>>= nType
)
861 case ::com::sun::star::presentation::EffectNodeType::TIMING_ROOT
: aAnim
.mnNodeType
= 0x12; break;
862 case ::com::sun::star::presentation::EffectNodeType::MAIN_SEQUENCE
: aAnim
.mnNodeType
= 0x18; break;
864 case ::com::sun::star::presentation::EffectNodeType::ON_CLICK :
865 case ::com::sun::star::presentation::EffectNodeType::WITH_PREVIOUS :
866 case ::com::sun::star::presentation::EffectNodeType::AFTER_PREVIOUS :
867 case ::com::sun::star::presentation::EffectNodeType::INTERACTIVE_SEQUENCE :
879 case AnimationNodeType::ANIMATE
:
880 case AnimationNodeType::SET
:
882 case AnimationNodeType::CUSTOM
:
883 case AnimationNodeType::ITERATE
:
884 case AnimationNodeType::ANIMATEMOTION
:
885 case AnimationNodeType::ANIMATECOLOR
:
886 case AnimationNodeType::ANIMATETRANSFORM
:
888 aAnim
.mnGroupType
= mso_Anim_GroupType_NODE
;
889 aAnim
.mnNodeType
= mso_Anim_Behaviour_ANIMATION
;
893 case AnimationNodeType::AUDIO
:
895 aAnim
.mnGroupType
= mso_Anim_GroupType_MEDIA
;
896 aAnim
.mnNodeType
= mso_Anim_Behaviour_ANIMATION
;
900 case AnimationNodeType::TRANSITIONFILTER
:
902 aAnim
.mnGroupType
= mso_Anim_GroupType_NODE
;
903 aAnim
.mnNodeType
= mso_Anim_Behaviour_FILTER
;
910 sal_Int16
AnimationExporter::exportAnimPropertySet( SvStream
& rStrm
, const Reference
< XAnimationNode
>& xNode
)
912 sal_Int16 nNodeType
= ::com::sun::star::presentation::EffectNodeType::DEFAULT
;
914 EscherExContainer
aAnimPropertySet( rStrm
, DFF_msofbtAnimPropertySet
);
915 const ::com::sun::star::uno::Any
* pAny
[ DFF_ANIM_PROPERTY_ID_COUNT
];
916 rtl_zeroMemory( pAny
, sizeof( pAny
) );
918 Reference
< XAnimationNode
> xMaster
;
920 const Any
aTrue( makeAny( (sal_Bool
)sal_True
) );
921 Any aMasterRel
, aOverride
, aRunTimeContext
;
923 // storing user data into pAny, to allow direct access later
924 Sequence
< NamedValue
> aUserData
= xNode
->getUserData();
925 if ( aUserData
.getLength() )
927 const NamedValue
* p
= aUserData
.getConstArray();
928 sal_Int32 nLength
= aUserData
.getLength();
931 if( p
->Name
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "node-type" ) ) )
933 pAny
[ DFF_ANIM_NODE_TYPE
] = &(p
->Value
);
935 else if ( p
->Name
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "preset-class" ) ) )
937 pAny
[ DFF_ANIM_PRESET_CLASS
] = &(p
->Value
);
939 else if ( p
->Name
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "preset-id" ) ) )
941 pAny
[ DFF_ANIM_PRESET_ID
] = &(p
->Value
);
943 else if ( p
->Name
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "preset-sub-type" ) ) )
945 pAny
[ DFF_ANIM_PRESET_SUB_TYPE
] = &(p
->Value
);
947 else if ( p
->Name
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "master-element" ) ) )
949 pAny
[ DFF_ANIM_AFTEREFFECT
] = &aTrue
;
950 p
->Value
>>= xMaster
;
956 // calculate master-rel
959 sal_Int32 nMasterRel
= 2;
960 Reference
< XChild
> xNodeChild( xNode
, UNO_QUERY
);
961 Reference
< XChild
> xMasterChild( xMaster
, UNO_QUERY
);
962 if( xNodeChild
.is() && xMasterChild
.is() && (xNodeChild
->getParent() == xMasterChild
->getParent() ) )
965 aMasterRel
<<= nMasterRel
;
967 pAny
[ DFF_ANIM_MASTERREL
] = &aMasterRel
;
969 aOverride
<<= (sal_Int32
)1;
970 pAny
[ DFF_ANIM_OVERRIDE
] = &aOverride
;
972 aRunTimeContext
<<= (sal_Int32
)1;
973 pAny
[ DFF_ANIM_RUNTIMECONTEXT
] = &aRunTimeContext
;
976 // the order is important
977 if ( pAny
[ DFF_ANIM_NODE_TYPE
] )
979 if ( *pAny
[ DFF_ANIM_NODE_TYPE
] >>= nNodeType
)
981 sal_uInt32 nPPTNodeType
= DFF_ANIM_NODE_TYPE_ON_CLICK
;
984 case ::com::sun::star::presentation::EffectNodeType::ON_CLICK
: nPPTNodeType
= DFF_ANIM_NODE_TYPE_ON_CLICK
; break;
985 case ::com::sun::star::presentation::EffectNodeType::WITH_PREVIOUS
: nPPTNodeType
= DFF_ANIM_NODE_TYPE_WITH_PREVIOUS
; break;
986 case ::com::sun::star::presentation::EffectNodeType::AFTER_PREVIOUS
: nPPTNodeType
= DFF_ANIM_NODE_TYPE_AFTER_PREVIOUS
; break;
987 case ::com::sun::star::presentation::EffectNodeType::MAIN_SEQUENCE
: nPPTNodeType
= DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE
; break;
988 case ::com::sun::star::presentation::EffectNodeType::TIMING_ROOT
: nPPTNodeType
= DFF_ANIM_NODE_TYPE_TIMING_ROOT
; break;
989 case ::com::sun::star::presentation::EffectNodeType::INTERACTIVE_SEQUENCE
: nPPTNodeType
= DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ
; break;
991 exportAnimPropertyuInt32( rStrm
, DFF_ANIM_NODE_TYPE
, nPPTNodeType
, TRANSLATE_NONE
);
994 sal_uInt32 nPresetId
= 0;
995 sal_uInt32 nPresetSubType
= 0;
996 sal_uInt32 nAPIPresetClass
= EffectPresetClass::CUSTOM
;
997 sal_uInt32 nPresetClass
= DFF_ANIM_PRESS_CLASS_USER_DEFINED
;
998 sal_Bool bPresetClass
, bPresetId
, bPresetSubType
;
999 bPresetClass
= bPresetId
= bPresetSubType
= sal_False
;
1001 if ( pAny
[ DFF_ANIM_PRESET_CLASS
] )
1003 if ( *pAny
[ DFF_ANIM_PRESET_CLASS
] >>= nAPIPresetClass
)
1005 sal_uInt8 nPPTPresetClass
;
1006 switch( nAPIPresetClass
)
1008 case EffectPresetClass::ENTRANCE
: nPPTPresetClass
= DFF_ANIM_PRESS_CLASS_ENTRANCE
; break;
1009 case EffectPresetClass::EXIT
: nPPTPresetClass
= DFF_ANIM_PRESS_CLASS_EXIT
; break;
1010 case EffectPresetClass::EMPHASIS
: nPPTPresetClass
= DFF_ANIM_PRESS_CLASS_EMPHASIS
; break;
1011 case EffectPresetClass::MOTIONPATH
: nPPTPresetClass
= DFF_ANIM_PRESS_CLASS_MOTIONPATH
; break;
1012 case EffectPresetClass::OLEACTION
: nPPTPresetClass
= DFF_ANIM_PRESS_CLASS_OLE_ACTION
; break;
1013 case EffectPresetClass::MEDIACALL
: nPPTPresetClass
= DFF_ANIM_PRESS_CLASS_MEDIACALL
; break;
1015 nPPTPresetClass
= DFF_ANIM_PRESS_CLASS_USER_DEFINED
;
1017 nPresetClass
= nPPTPresetClass
;
1018 bPresetClass
= sal_True
;
1021 if ( pAny
[ DFF_ANIM_PRESET_ID
] )
1023 rtl::OUString sPreset
;
1024 if ( *pAny
[ DFF_ANIM_PRESET_ID
] >>= sPreset
)
1026 if ( sPreset
.match( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ppt_" ) ), 0 ) )
1028 sal_Int32 nLast
= sPreset
.lastIndexOf( '_' );
1029 if ( ( nLast
!= -1 ) && ( ( nLast
+ 1 ) < sPreset
.getLength() ) )
1031 rtl::OUString
aNumber( sPreset
.copy( nLast
+ 1 ) );
1032 nPresetId
= aNumber
.toInt32();
1033 bPresetId
= sal_True
;
1038 const preset_maping
* p
= gPresetMaping
;
1039 while( p
->mpStrPresetId
&& ((p
->mnPresetClass
!= (sal_Int32
)nAPIPresetClass
) || !sPreset
.equalsAscii( p
->mpStrPresetId
)) )
1042 if( p
->mpStrPresetId
)
1044 nPresetId
= p
->mnPresetId
;
1045 bPresetId
= sal_True
;
1051 if ( pAny
[ DFF_ANIM_PRESET_SUB_TYPE
] )
1053 rtl::OUString sPresetSubType
;
1054 if ( *pAny
[ DFF_ANIM_PRESET_SUB_TYPE
] >>= sPresetSubType
)
1056 nPresetSubType
= ImplTranslatePresetSubType( nPresetClass
, nPresetId
, sPresetSubType
);
1057 bPresetSubType
= sal_True
;
1061 exportAnimPropertyuInt32( rStrm
, DFF_ANIM_PRESET_ID
, nPresetId
, TRANSLATE_NONE
);
1062 if ( bPresetSubType
)
1063 exportAnimPropertyuInt32( rStrm
, DFF_ANIM_PRESET_SUB_TYPE
, nPresetSubType
, TRANSLATE_NONE
);
1065 exportAnimPropertyuInt32( rStrm
, DFF_ANIM_PRESET_CLASS
, nPresetClass
, TRANSLATE_NONE
);
1067 if ( pAny
[ DFF_ANIM_ID
] )
1072 if ( pAny
[ DFF_ANIM_AFTEREFFECT
] )
1074 sal_Bool bAfterEffect
= sal_False
;
1075 if ( *pAny
[ DFF_ANIM_AFTEREFFECT
] >>= bAfterEffect
)
1076 exportAnimPropertyByte( rStrm
, DFF_ANIM_AFTEREFFECT
, bAfterEffect
, TRANSLATE_NONE
);
1079 if ( pAny
[ DFF_ANIM_RUNTIMECONTEXT
] )
1081 sal_Int32 nRunTimeContext
= 0;
1082 if ( *pAny
[ DFF_ANIM_RUNTIMECONTEXT
] >>= nRunTimeContext
)
1083 exportAnimPropertyuInt32( rStrm
, DFF_ANIM_RUNTIMECONTEXT
, nRunTimeContext
, TRANSLATE_NONE
);
1085 if ( pAny
[ DFF_ANIM_PATH_EDIT_MODE
] )
1092 Reference
< XAnimateColor
> xColor( xNode
, UNO_QUERY
);
1095 // sal_uInt32 nColorSpace = xColor->getColorSpace() == AnimationColorSpace::RGB ? 0 : 1;
1096 // exportAnimPropertyuInt32( rStrm, DFF_ANIM_COLORSPACE, nColorSpace, TRANSLATE_NONE );
1098 sal_Bool bDirection
= !xColor
->getDirection();
1099 exportAnimPropertyuInt32( rStrm
, DFF_ANIM_DIRECTION
, bDirection
, TRANSLATE_NONE
);
1103 if ( pAny
[ DFF_ANIM_OVERRIDE
] )
1105 sal_Int32 nOverride
= 0;
1106 if ( *pAny
[ DFF_ANIM_OVERRIDE
] >>= nOverride
)
1107 exportAnimPropertyuInt32( rStrm
, DFF_ANIM_OVERRIDE
, nOverride
, TRANSLATE_NONE
);
1110 if ( pAny
[ DFF_ANIM_MASTERREL
] )
1112 sal_Int32 nMasterRel
= 0;
1113 if ( *pAny
[ DFF_ANIM_MASTERREL
] >>= nMasterRel
)
1114 exportAnimPropertyuInt32( rStrm
, DFF_ANIM_MASTERREL
, nMasterRel
, TRANSLATE_NONE
);
1118 Reference< XAudio > xAudio( xNode, UNO_QUERY );
1121 sal_Int16 nEndAfterSlide = 0;
1122 nEndAfterSlide = xAudio->getEndAfterSlide();
1123 exportAnimPropertyuInt32( rStrm, DFF_ANIM_ENDAFTERSLIDE, nEndAfterSlide, TRANSLATE_NONE );
1126 Reference
< XAnimate
> xAnim( xNode
, UNO_QUERY
);
1129 // TODO: DFF_ANIM_TIMEFILTER
1131 if ( pAny
[ DFF_ANIM_EVENT_FILTER
] )
1133 // TODO DFF_ANIM_EVENT_FILTER
1135 if ( pAny
[ DFF_ANIM_VOLUME
] )
1137 // TODO DFF_ANIM_VOLUME
1142 sal_Bool
AnimationExporter::exportAnimProperty( SvStream
& rStrm
, const sal_uInt16 nPropertyId
, const ::com::sun::star::uno::Any
& rAny
, const TranslateMode eTranslateMode
)
1144 sal_Bool bRet
= sal_False
;
1145 if ( rAny
.hasValue() )
1147 switch( rAny
.getValueType().getTypeClass() )
1149 case ::com::sun::star::uno::TypeClass_UNSIGNED_SHORT
:
1150 case ::com::sun::star::uno::TypeClass_SHORT
:
1151 case ::com::sun::star::uno::TypeClass_UNSIGNED_LONG
:
1152 case ::com::sun::star::uno::TypeClass_LONG
:
1155 if ( rAny
>>= nVal
)
1157 exportAnimPropertyuInt32( rStrm
, nPropertyId
, nVal
, eTranslateMode
);
1163 case ::com::sun::star::uno::TypeClass_DOUBLE
:
1166 if ( rAny
>>= fVal
)
1168 exportAnimPropertyFloat( rStrm
, nPropertyId
, fVal
, eTranslateMode
);
1173 case ::com::sun::star::uno::TypeClass_FLOAT
:
1176 if ( rAny
>>= fVal
)
1178 if ( eTranslateMode
& TRANSLATE_NUMBER_TO_STRING
)
1181 rtl::OUString
aNumber( rtl::OUString::valueOf( fVal
) );
1183 exportAnimPropertyString( rStrm
, nPropertyId
, aNumber
, eTranslateMode
);
1187 exportAnimPropertyFloat( rStrm
, nPropertyId
, fVal
, eTranslateMode
);
1193 case ::com::sun::star::uno::TypeClass_STRING
:
1196 if ( rAny
>>= aStr
)
1198 exportAnimPropertyString( rStrm
, nPropertyId
, aStr
, eTranslateMode
);
1209 void AnimationExporter::exportAnimPropertyString( SvStream
& rStrm
, const sal_uInt16 nPropertyId
, const rtl::OUString
& rVal
, const TranslateMode eTranslateMode
)
1211 EscherExAtom
aExAtom( rStrm
, DFF_msofbtAnimAttributeValue
, nPropertyId
);
1212 sal_uInt8 nType
= DFF_ANIM_PROP_TYPE_UNISTRING
;
1214 rtl::OUString
aStr( rVal
);
1215 if ( eTranslateMode
!= TRANSLATE_NONE
)
1216 ImplTranslateAttribute( aStr
, eTranslateMode
);
1217 writeZString( rStrm
, aStr
);
1220 void AnimationExporter::exportAnimPropertyFloat( SvStream
& rStrm
, const sal_uInt16 nPropertyId
, const double& rVal
, const TranslateMode
)
1222 EscherExAtom
aExAtom( rStrm
, DFF_msofbtAnimAttributeValue
, nPropertyId
);
1223 sal_uInt8 nType
= DFF_ANIM_PROP_TYPE_FLOAT
;
1224 float fFloat
= (float)rVal
;
1229 void AnimationExporter::exportAnimPropertyuInt32( SvStream
& rStrm
, const sal_uInt16 nPropertyId
, const sal_uInt32 nVal
, const TranslateMode
)
1231 EscherExAtom
aExAtom( rStrm
, DFF_msofbtAnimAttributeValue
, nPropertyId
);
1232 sal_uInt8 nType
= DFF_ANIM_PROP_TYPE_INT32
;
1237 void AnimationExporter::exportAnimPropertyByte( SvStream
& rStrm
, const sal_uInt16 nPropertyId
, const sal_uInt8 nVal
, const TranslateMode
)
1239 EscherExAtom
aExAtom( rStrm
, DFF_msofbtAnimAttributeValue
, nPropertyId
);
1240 sal_uInt8 nType
= DFF_ANIM_PROP_TYPE_BYTE
;
1245 void AnimationExporter::writeZString( SvStream
& rStrm
, const rtl::OUString
& rVal
)
1248 for ( i
= 0; i
< rVal
.getLength(); i
++ )
1250 rStrm
<< (sal_Unicode
)0;
1253 void AnimationExporter::exportAnimAction( SvStream
& rStrm
, const Reference
< XAnimationNode
>& xNode
)
1255 EscherExAtom
aExAtom( rStrm
, DFF_msofbtAnimAction
);
1257 sal_Int32 nConcurrent
= 1;
1258 sal_Int32 nNextAction
= 1;
1259 sal_Int32 nEndSync
= 0;
1263 sal_Int16 nAnimationEndSync
= 0;
1264 if ( xNode
->getEndSync() >>= nAnimationEndSync
)
1266 if ( nAnimationEndSync
== AnimationEndSync::ALL
)
1269 rStrm
<< nConcurrent
1277 // nFlags Bit 6 = fixInteractiveSequenceTiming (for child)
1278 // nFlags Bit 5 = fixInteractiveSequenceTiming (for root)
1279 // nFlags Bit 4 = first node of main sequence -> begin event next has to be replaced to indefinite
1280 void AnimationExporter::exportAnimEvent( SvStream
& rStrm
, const Reference
< XAnimationNode
>& xNode
, const sal_Int32 nFlags
)
1283 for ( i
= 0; i
< 4; i
++ )
1286 sal_Int32 nTrigger
= 0;
1288 sal_Int32 nBegin
= 0;
1290 sal_Bool bCreateEvent
= sal_False
;
1300 com::sun::star::animations::Timing eTiming
;
1303 if ( nFlags
& 0x20 )
1305 // taking the first child
1306 Reference
< XEnumerationAccess
> xEA( xNode
, UNO_QUERY_THROW
);
1307 Reference
< XEnumeration
> xE( xEA
->createEnumeration(), UNO_QUERY_THROW
);
1308 if ( xE
.is() && xE
->hasMoreElements() )
1310 // while( xE->hasMoreElements() )
1312 Reference
< XAnimationNode
> xClickNode( xE
->nextElement(), UNO_QUERY
);
1313 aAny
= xClickNode
->getBegin();
1317 else if ( nFlags
& 0x40 )
1319 // begin has to be replaced with void, so don't do anything
1323 aAny
= xNode
->getBegin();
1324 if ( nFlags
& 0x10 ) // replace ON_NEXT with IDEFINITE
1326 if ( ( aAny
>>= aEvent
) && ( aEvent
.Trigger
== EventTrigger::ON_NEXT
) )
1328 eTiming
= Timing_INDEFINITE
;
1335 aAny
= xNode
->getEnd();
1337 double fTiming
= 0.0;
1338 if ( aAny
>>= aEvent
)
1340 bCreateEvent
= sal_True
;
1341 switch( aEvent
.Trigger
)
1343 case EventTrigger::NONE
: nTrigger
= 0; break;
1344 case EventTrigger::ON_BEGIN
: nTrigger
= 1; break;
1345 case EventTrigger::ON_END
: nTrigger
= 2; break;
1346 case EventTrigger::BEGIN_EVENT
: nTrigger
= 3; break;
1347 case EventTrigger::END_EVENT
: nTrigger
= 4; nU1
= 2; nU3
= mnCurrentGroup
; break;
1348 case EventTrigger::ON_CLICK
: nTrigger
= 5; break;
1349 case EventTrigger::ON_DBL_CLICK
: nTrigger
= 6; break;
1350 case EventTrigger::ON_MOUSE_ENTER
: nTrigger
= 7; break;
1351 case EventTrigger::ON_MOUSE_LEAVE
: nTrigger
= 8; break;
1352 case EventTrigger::ON_NEXT
: nTrigger
= 9; break;
1353 case EventTrigger::ON_PREV
: nTrigger
= 10; break;
1354 case EventTrigger::ON_STOP_AUDIO
: nTrigger
= 11; break;
1356 if ( aEvent
.Offset
.hasValue() )
1358 if ( aEvent
.Offset
>>= eTiming
)
1360 if ( eTiming
== Timing_INDEFINITE
)
1363 else if ( aEvent
.Offset
>>= fTiming
)
1364 nBegin
= (sal_Int32
)( fTiming
* 1000.0 );
1366 aSource
= aEvent
.Source
;
1368 else if ( aAny
>>= eTiming
)
1370 bCreateEvent
= sal_True
;
1371 if ( eTiming
== Timing_INDEFINITE
)
1374 else if ( aAny
>>= fTiming
)
1376 bCreateEvent
= sal_True
;
1377 if ( eTiming
== Timing_INDEFINITE
)
1378 nBegin
= (sal_Int32
)( fTiming
* 1000.0 );
1385 if ( nFlags
& ( 1 << i
) )
1387 bCreateEvent
= sal_True
;
1395 if ( nFlags
& ( 1 << i
) )
1397 bCreateEvent
= sal_True
;
1406 EscherExContainer
aAnimEvent( rStrm
, DFF_msofbtAnimEvent
, i
+ 1 );
1408 EscherExAtom
aAnimTrigger( rStrm
, DFF_msofbtAnimTrigger
);
1414 exportAnimateTargetElement( rStrm
, aSource
, ( nFlags
& ( 1 << i
) ) != 0 );
1419 Any
AnimationExporter::convertAnimateValue( const Any
& rSourceValue
, const rtl::OUString
& rAttributeName
) const
1421 rtl::OUString aDest
;
1422 if ( rAttributeName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "X" ) )
1423 || rAttributeName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Y" ) )
1424 || rAttributeName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Width" ) )
1425 || rAttributeName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Height" ) )
1429 if ( rSourceValue
>>= aStr
)
1431 ImplTranslateAttribute( aStr
, TRANSLATE_MEASURE
);
1435 else if ( rAttributeName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Rotate" ) ) // "r" or "style.rotation" ?
1436 || rAttributeName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "SkewX" ) )
1437 || rAttributeName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Opacity" ) )
1438 || rAttributeName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CharHeight" ) )
1441 double fNumber
= 0.0;
1442 if ( rSourceValue
>>= fNumber
)
1443 aDest
+= rtl::OUString::valueOf( fNumber
);
1445 else if ( rAttributeName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Color" ) )
1446 || rAttributeName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "FillColor" ) ) // "Fillcolor" or "FillColor" ?
1447 || rAttributeName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "LineColor" ) )
1448 || rAttributeName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CharColor" ) )
1451 sal_Int32 nColor
= 0;
1452 Sequence
< double > aHSL( 3 );
1453 rtl::OUString
aP( RTL_CONSTASCII_USTRINGPARAM( "," ) );
1454 if ( rSourceValue
>>= aHSL
)
1456 aDest
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "hsl(" ) );
1457 aDest
+= rtl::OUString::valueOf( (sal_Int32
)( aHSL
[ 0 ] / ( 360.0 / 255 ) ) );
1459 aDest
+= rtl::OUString::valueOf( (sal_Int32
)( aHSL
[ 1 ] * 255.0 ) );
1461 aDest
+= rtl::OUString::valueOf( (sal_Int32
)( aHSL
[ 2 ] * 255.0 ) );
1462 aDest
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ")" ) );
1464 else if ( rSourceValue
>>= nColor
)
1466 aDest
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "rgb(" ) );
1467 aDest
+= rtl::OUString::valueOf( (sal_Int32
)( (sal_Int8
)nColor
) );
1469 aDest
+= rtl::OUString::valueOf( (sal_Int32
)( (sal_Int8
)( nColor
>> 8 ) ) );
1471 aDest
+= rtl::OUString::valueOf( (sal_Int32
)( (sal_Int8
)( nColor
>> 16 ) ) );
1472 aDest
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ")" ) );
1475 else if ( rAttributeName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "FillStyle" ) ) )
1477 ::com::sun::star::drawing::FillStyle eFillStyle
;
1478 if ( rSourceValue
>>= eFillStyle
)
1480 if ( eFillStyle
== ::com::sun::star::drawing::FillStyle_NONE
)
1481 aDest
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "none" ) ); // ?
1483 aDest
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "solid" ) );
1486 else if ( rAttributeName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "LineStyle" ) ) )
1488 ::com::sun::star::drawing::LineStyle eLineStyle
;
1489 if ( rSourceValue
>>= eLineStyle
)
1491 if ( eLineStyle
== ::com::sun::star::drawing::LineStyle_NONE
)
1492 aDest
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "false" ) );
1494 aDest
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "true" ) );
1497 else if ( rAttributeName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CharWeight" ) ) )
1499 float fFontWeight
= 0.0;
1500 if ( rSourceValue
>>= fFontWeight
)
1502 if ( fFontWeight
== com::sun::star::awt::FontWeight::BOLD
)
1503 aDest
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "bold" ) );
1505 aDest
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "normal" ) );
1508 else if ( rAttributeName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CharUnderline" ) ) )
1510 sal_Int16 nFontUnderline
= 0;
1511 if ( rSourceValue
>>= nFontUnderline
)
1513 if ( nFontUnderline
== com::sun::star::awt::FontUnderline::NONE
)
1514 aDest
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "false" ) );
1516 aDest
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "true" ) );
1519 else if ( rAttributeName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CharPosture" ) ) )
1521 ::com::sun::star::awt::FontSlant eFontSlant
;
1522 if ( rSourceValue
>>= eFontSlant
)
1524 if ( eFontSlant
== com::sun::star::awt::FontSlant_ITALIC
)
1525 aDest
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "italic" ) );
1527 aDest
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "normal" ) ); // ?
1530 else if ( rAttributeName
.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Visibility" ) ) )
1532 sal_Bool bVisible
= sal_True
;
1533 if ( rSourceValue
>>= bVisible
)
1536 aDest
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "visible" ) );
1538 aDest
+= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "hidden" ) );
1542 if ( aDest
.getLength() )
1545 aRet
= rSourceValue
;
1549 void AnimationExporter::exportAnimateSet( SvStream
& rStrm
, const Reference
< XAnimationNode
>& xNode
, int nAfterEffectType
)
1551 Reference
< XAnimateSet
> xSet( xNode
, UNO_QUERY
);
1554 EscherExContainer
aAnimateSet( rStrm
, DFF_msofbtAnimateSet
, 0 );
1556 EscherExAtom
aAnimateSetData( rStrm
, DFF_msofbtAnimateSetData
);
1557 sal_uInt32 nId1
= 1; // ??
1558 sal_uInt32 nId2
= 1; // ??
1559 rStrm
<< nId1
<< nId2
;
1561 Any
aConvertedValue( convertAnimateValue( xSet
->getTo(), xSet
->getAttributeName() ) );
1562 if ( aConvertedValue
.hasValue() )
1563 exportAnimProperty( rStrm
, 1, aConvertedValue
, TRANSLATE_NONE
);
1564 exportAnimateTarget( rStrm
, xNode
, 0, nAfterEffectType
);
1568 sal_uInt32
GetValueTypeForAttributeName( const rtl::OUString
& rAttributeName
)
1570 sal_uInt32 nValueType
= 0;
1573 AnimationValueType::STRING == 0;
1574 AnimationValueType::NUMBER == 1;
1575 AnimationValueType::COLOR == 2;
1580 const sal_Char
* pName
;
1583 static const Entry lcl_attributeMap
[] =
1586 { "charfontname", 0 },
1587 { "charheight", 1 },
1588 { "charposture", 0 },
1589 // TODO(Q1): This should prolly be changed in PPT import
1590 // { "charrotation", ATTRIBUTE_CHAR_ROTATION },
1591 { "charrotation", 1 },
1592 { "charunderline", 0 },
1593 { "charweight", 0 },
1605 { "visibility", 1 },
1611 const Entry
* pPtr
= &lcl_attributeMap
[ 0 ];
1612 while( pPtr
->pName
)
1614 if ( rAttributeName
.equalsIgnoreAsciiCaseAscii( pPtr
->pName
) )
1616 nValueType
= pPtr
->nType
;
1621 DBG_ASSERT( pPtr
->pName
, "GetValueTypeForAttributeName, unknown property value!" );
1625 void AnimationExporter::exportAnimate( SvStream
& rStrm
, const Reference
< XAnimationNode
>& xNode
)
1627 Reference
< XAnimate
> xAnimate( xNode
, UNO_QUERY
);
1628 if ( xAnimate
.is() )
1630 Any
aBy ( xAnimate
->getBy() );
1631 Any
aFrom( xAnimate
->getFrom() );
1632 Any
aTo ( xAnimate
->getTo() );
1634 EscherExContainer
aContainer( rStrm
, DFF_msofbtAnimate
, 0 );
1636 EscherExAtom
aAnimateData( rStrm
, DFF_msofbtAnimateData
);
1637 sal_uInt32 nBits
= 0x38;
1638 sal_Int16 nTmp
= xAnimate
->getCalcMode();
1639 sal_uInt32 nCalcMode
= /* (nTmp == AnimationCalcMode::FORMULA) ? 2 : */ (nTmp
== AnimationCalcMode::LINEAR
) ? 1 : 0;
1640 nTmp
= xAnimate
->getValueType();
1641 sal_uInt32 nValueType
= GetValueTypeForAttributeName( xAnimate
->getAttributeName() );
1643 if ( aBy
.hasValue() )
1645 if ( aFrom
.hasValue() )
1647 if ( aTo
.hasValue() )
1654 if ( aBy
.hasValue() )
1655 exportAnimProperty( rStrm
, 1, aBy
, TRANSLATE_NUMBER_TO_STRING
| TRANSLATE_MEASURE
);
1656 if ( aFrom
.hasValue() )
1657 exportAnimProperty( rStrm
, 2, aFrom
, TRANSLATE_NUMBER_TO_STRING
| TRANSLATE_MEASURE
);
1658 if ( aTo
.hasValue() )
1659 exportAnimProperty( rStrm
, 3, aTo
, TRANSLATE_NUMBER_TO_STRING
| TRANSLATE_MEASURE
);
1661 exportAnimateKeyPoints( rStrm
, xAnimate
);
1662 exportAnimateTarget( rStrm
, xNode
);
1666 void AnimationExporter::exportAnimateTarget( SvStream
& rStrm
, const Reference
< XAnimationNode
>& xNode
, const sal_uInt32 nForceAttributeNames
, int nAfterEffectType
)
1668 EscherExContainer
aAnimateTarget( rStrm
, DFF_msofbtAnimateTarget
, 0 );
1669 Reference
< XAnimate
> xAnimate( xNode
, UNO_QUERY
);
1670 if ( xAnimate
.is() )
1673 EscherExAtom
aAnimateTargetSettings( rStrm
, DFF_msofbtAnimateTargetSettings
, 0 );
1674 // nBits %0001: additive, %0010: accumulate, %0100: attributeName, %1000: transformtype
1675 // nAdditive 0 = base, 1 = sum, 2 = replace, 3 = multiply, 4 = none
1676 // nAccumulate 0 = none, 1 = always
1677 // nTransformType 0: "property" else "image"
1678 sal_uInt32 nBits
= 0;
1679 sal_uInt32 nAdditive
= 0;
1680 sal_uInt32 nAccumulate
= 0;
1681 sal_uInt32 nTransformType
= 0;
1682 if ( xAnimate
.is() )
1684 if ( xAnimate
->getAttributeName().getLength() )
1685 nBits
|= 4; // what is attributeName ?, maybe this is set if a DFF_msofbtAnimateAttributeNames is written
1686 sal_Int16 nAdditiveMode
= xAnimate
->getAdditive();
1687 if ( nAdditiveMode
!= AnimationAdditiveMode::BASE
)
1690 switch( nAdditiveMode
)
1692 case AnimationAdditiveMode::SUM
: nAdditive
= 1; break;
1693 case AnimationAdditiveMode::REPLACE
: nAdditive
= 2; break;
1694 case AnimationAdditiveMode::MULTIPLY
: nAdditive
= 3; break;
1695 case AnimationAdditiveMode::NONE
: nAdditive
= 4; break;
1698 if ( xAnimate
->getAccumulate() )
1709 if ( xAnimate
->getAttributeName().getLength() || nForceAttributeNames
)
1711 EscherExContainer
aAnimateAttributeNames( rStrm
, DFF_msofbtAnimateAttributeNames
, 1 );
1712 rtl::OUString
aAttributeName( xAnimate
->getAttributeName() );
1713 if ( nForceAttributeNames
)
1715 switch( nForceAttributeNames
)
1717 case 1 : aAttributeName
= rtl::OUString::createFromAscii( "r" ); break;
1720 sal_Int32 nIndex
= 0;
1723 OUString
aToken( aAttributeName
.getToken( 0, ';', nIndex
) );
1724 exportAnimPropertyString( rStrm
, 0, aToken
, TRANSLATE_ATTRIBUTE
);
1726 while ( nIndex
>= 0 );
1729 if( nAfterEffectType
!= AFTEREFFECT_NONE
)
1731 EscherExContainer
aAnimPropertySet( rStrm
, DFF_msofbtAnimPropertySet
);
1732 exportAnimPropertyuInt32( rStrm
, 6, 1, TRANSLATE_NONE
);
1733 if( nAfterEffectType
== AFTEREFFECT_COLOR
)
1735 exportAnimPropertyuInt32( rStrm
, 4, 0, TRANSLATE_NONE
);
1736 exportAnimPropertyuInt32( rStrm
, 5, 0, TRANSLATE_NONE
);
1739 exportAnimateTargetElement( rStrm
, aTarget
.hasValue() ? aTarget
: xAnimate
->getTarget(), sal_False
);
1743 void AnimationExporter::exportAnimateTargetElement( SvStream
& rStrm
, const Any aAny
, const sal_Bool bCreate2b01Atom
)
1745 Reference
< XShape
> xShape
;
1747 sal_uInt32 nRefMode
= 0; // nRefMode == 2 -> Paragraph
1748 sal_Int32 begin
= -1;
1753 ParagraphTarget aParaTarget
;
1754 if( aAny
>>= aParaTarget
)
1755 xShape
= aParaTarget
.Shape
;
1758 // now calculating the character range for the paragraph
1759 sal_Int16 nParagraph
= aParaTarget
.Paragraph
;
1760 Reference
< XSimpleText
> xText( xShape
, UNO_QUERY
);
1764 Reference
< XEnumerationAccess
> xTextParagraphEnumerationAccess( xText
, UNO_QUERY
);
1765 if ( xTextParagraphEnumerationAccess
.is() )
1767 Reference
< XEnumeration
> xTextParagraphEnumeration( xTextParagraphEnumerationAccess
->createEnumeration() );
1768 if ( xTextParagraphEnumeration
.is() )
1770 sal_Int16 nCurrentParagraph
;
1771 begin
= end
= nCurrentParagraph
= 0;
1772 while ( xTextParagraphEnumeration
->hasMoreElements() )
1774 Reference
< XTextRange
> xTextRange( xTextParagraphEnumeration
->nextElement(), UNO_QUERY
);
1775 if ( xTextRange
.is() )
1777 rtl::OUString
aParaText( xTextRange
->getString() );
1778 sal_Int32 nLength
= aParaText
.getLength() + 1;
1780 if ( nCurrentParagraph
== nParagraph
)
1782 nCurrentParagraph
++;
1791 if ( xShape
.is() || bCreate2b01Atom
)
1793 EscherExContainer
aAnimateTargetElement( rStrm
, DFF_msofbtAnimateTargetElement
);
1796 EscherExAtom
aAnimReference( rStrm
, DFF_msofbtAnimReference
);
1798 sal_uInt32 nRefType
= 1; // TODO: nRefType == 2 -> Sound;
1799 sal_uInt32 nRefId
= ((EscherSolverContainer
&)mrSolverContainer
).GetShapeId( xShape
);
1807 if ( bCreate2b01Atom
)
1809 EscherExAtom
a2b01Atom( rStrm
, 0x2b01 );
1810 rStrm
<< (sal_uInt32
)1; // ?
1815 void AnimationExporter::exportAnimateKeyPoints( SvStream
& rStrm
, const Reference
< XAnimate
>& xAnimate
)
1817 Sequence
< double > aKeyTimes( xAnimate
->getKeyTimes() );
1818 Sequence
< Any
> aValues( xAnimate
->getValues() );
1819 OUString
aFormula( xAnimate
->getFormula() );
1820 if ( aKeyTimes
.getLength() )
1822 EscherExContainer
aAnimKeyPoints( rStrm
, DFF_msofbtAnimKeyPoints
);
1824 for ( i
= 0; i
< aKeyTimes
.getLength(); i
++ )
1827 EscherExAtom
aAnimKeyTime( rStrm
, DFF_msofbtAnimKeyTime
);
1828 sal_Int32 nKeyTime
= (sal_Int32
)( aKeyTimes
[ i
] * 1000.0 );
1832 if ( aValues
[ i
].hasValue() )
1835 if ( aValues
[ i
] >>= aPair
)
1837 aAny
[ 0 ] = convertAnimateValue( aPair
.First
, xAnimate
->getAttributeName() );
1838 aAny
[ 1 ] = convertAnimateValue( aPair
.Second
, xAnimate
->getAttributeName() );
1842 aAny
[ 0 ] = convertAnimateValue( aValues
[ i
], xAnimate
->getAttributeName() );
1844 if ( !i
&& aFormula
.getLength() )
1846 ImplTranslateAttribute( aFormula
, TRANSLATE_MEASURE
);
1847 aAny
[ 1 ] <<= aFormula
;
1849 exportAnimProperty( rStrm
, 0, aAny
[ 0 ], TRANSLATE_NONE
);
1850 exportAnimProperty( rStrm
, 1, aAny
[ 1 ], TRANSLATE_NONE
);
1856 void AnimationExporter::exportAnimValue( SvStream
& rStrm
, const Reference
< XAnimationNode
>& xNode
, const sal_Bool bExportAlways
)
1860 double fRepeat
= 0.0;
1861 float fRepeatCount
= 0.0;
1862 com::sun::star::animations::Timing eTiming
;
1863 aAny
= xNode
->getRepeatCount();
1864 if ( aAny
>>= eTiming
)
1866 if ( eTiming
== Timing_INDEFINITE
)
1867 fRepeatCount
= ((float)3.40282346638528860e+38);
1869 else if ( aAny
>>= fRepeat
)
1870 fRepeatCount
= (float)fRepeat
;
1871 if ( fRepeatCount
!= 0.0 )
1873 EscherExAtom
aExAtom( rStrm
, DFF_msofbtAnimValue
);
1874 sal_uInt32 nType
= 0;
1879 float fAccelerate
= (float)xNode
->getAcceleration();
1880 if ( bExportAlways
|| ( fAccelerate
!= 0.0 ) )
1882 EscherExAtom
aExAtom( rStrm
, DFF_msofbtAnimValue
);
1883 sal_uInt32 nType
= 3;
1889 float fDecelerate
= (float)xNode
->getDecelerate();
1890 if ( bExportAlways
|| ( fDecelerate
!= 0.0 ) )
1892 EscherExAtom
aExAtom( rStrm
, DFF_msofbtAnimValue
);
1893 sal_uInt32 nType
= 4;
1899 sal_Bool bAutoReverse
= xNode
->getAutoReverse();
1900 if ( bExportAlways
|| bAutoReverse
)
1902 EscherExAtom
aExAtom( rStrm
, DFF_msofbtAnimValue
);
1903 sal_uInt32 nType
= 5;
1904 sal_uInt32 nVal
= bAutoReverse
? 1 : 0;
1910 void AnimationExporter::exportTransitionFilter( SvStream
& rStrm
, const Reference
< XAnimationNode
>& xNode
)
1912 Reference
< XTransitionFilter
> xFilter( xNode
, UNO_QUERY
);
1915 EscherExContainer
aAnimateFilter( rStrm
, DFF_msofbtAnimateFilter
);
1917 EscherExAtom
aAnimateFilterData( rStrm
, DFF_msofbtAnimateFilterData
);
1918 sal_uInt32 nBits
= 3; // bit 0 -> use AnimAttributeValue
1919 // bit 1 -> use nTransition
1921 sal_uInt32 nTransition
= xFilter
->getMode() ? 0 : 1;
1925 const sal_Char
* pFilter
= transition::find( xFilter
->getTransition(), xFilter
->getSubtype(), xFilter
->getDirection() );
1928 const OUString
aStr( OUString::createFromAscii( pFilter
) );
1929 exportAnimPropertyString( rStrm
, 1, aStr
, TRANSLATE_NONE
);
1931 exportAnimateTarget( rStrm
, xNode
);
1935 void AnimationExporter::exportAnimateMotion( SvStream
& rStrm
, const Reference
< XAnimationNode
>& xNode
)
1937 Reference
< XAnimateMotion
> xMotion( xNode
, UNO_QUERY
);
1940 EscherExContainer
aAnimateMotion( rStrm
, DFF_msofbtAnimateMotion
);
1942 { //SJ: Ignored from import filter
1943 EscherExAtom
aAnimateMotionData( rStrm
, DFF_msofbtAnimateMotionData
);
1944 sal_uInt32 nBits
= 0x98;
1945 sal_uInt32 nOrigin
= 0x2;
1946 float fByX
= 100.0; // nBits&1
1947 float fByY
= 100.0; // nBits&1
1948 float fFromX
= 0.0; // nBits&2
1949 float fFromY
= 0.0; // nBits&2
1950 float fToX
= 100.0; // nBits&4
1951 float fToY
= 100.0; // nBits&4
1952 rStrm
<< nBits
<< fByX
<< fByY
<< fFromX
<< fFromY
<< fToX
<< fToY
<< nOrigin
;
1956 EscherExAtom aF137( rStrm, 0xf137 );
1960 if ( xMotion
->getPath() >>= aStr
)
1962 if ( aStr
.getLength() )
1963 exportAnimPropertyString( rStrm
, 1, aStr
, TRANSLATE_NONE
);
1965 exportAnimateTarget( rStrm
, xNode
);
1970 void AnimationExporter::exportAnimateTransform( SvStream
& rStrm
, const Reference
< XAnimationNode
>& xNode
)
1972 Reference
< XAnimateTransform
> xTransform( xNode
, UNO_QUERY
);
1973 if ( xTransform
.is() )
1975 if ( xTransform
->getTransformType() == AnimationTransformType::SCALE
)
1977 EscherExContainer
aAnimateScale( rStrm
, DFF_msofbtAnimateScale
);
1979 EscherExAtom
aAnimateScaleData( rStrm
, DFF_msofbtAnimateScaleData
);
1980 sal_uInt32 nBits
= 0;
1981 sal_uInt32 nZoomContents
= 1;
1989 double fX
= 0.0, fY
= 0.0;
1991 if ( xTransform
->getBy() >>= aPair
)
1993 if ( ( aPair
.First
>>= fX
) && ( aPair
.Second
>>= fY
) )
1996 fByX
= (float)( fX
* 100 );
1997 fByY
= (float)( fY
* 100 );
2000 if ( xTransform
->getFrom() >>= aPair
)
2002 if ( ( aPair
.First
>>= fX
) && ( aPair
.Second
>>= fY
) )
2005 fFromX
= (float)( fX
* 100 );
2006 fFromY
= (float)( fY
* 100 );
2009 if( xTransform
->getTo() >>= aPair
)
2011 if ( ( aPair
.First
>>= fX
) && ( aPair
.Second
>>= fY
) )
2014 fToX
= (float)( fX
* 100 );
2015 fToY
= (float)( fY
* 100 );
2019 // TODO: ZoomContents:
2021 //( fprintf( mpFile, " zoomContents=\"%s\"", nZoomContents ? "true" : "false" );
2023 rStrm
<< nBits
<< fByX
<< fByY
<< fFromX
<< fFromY
<< fToX
<< fToY
<< nZoomContents
;
2025 exportAnimateTarget( rStrm
, xNode
);
2027 else if ( xTransform
->getTransformType() == AnimationTransformType::ROTATE
)
2029 EscherExContainer
aAnimateRotation( rStrm
, DFF_msofbtAnimateRotation
);
2031 EscherExAtom
aAnimateRotationData( rStrm
, DFF_msofbtAnimateRotationData
);
2032 sal_uInt32 nBits
= 0;
2039 if ( xTransform
->getBy() >>= fVal
)
2044 if ( xTransform
->getFrom() >>= fVal
)
2047 fFrom
= (float)fVal
;
2049 if ( xTransform
->getTo() >>= fVal
)
2054 rStrm
<< nBits
<< fBy
<< fFrom
<< fTo
<< nU1
;
2056 exportAnimateTarget( rStrm
, xNode
, 1 );
2061 sal_Bool
AnimationExporter::getColorAny( const Any
& rAny
, const sal_Int16 nColorSpace
, sal_Int32
& rMode
, sal_Int32
& rA
, sal_Int32
& rB
, sal_Int32
& rC
) const
2063 sal_Bool bIsColor
= sal_True
;
2066 if ( nColorSpace
== AnimationColorSpace::HSL
)
2069 sal_Int32 nColor
= 0;
2070 Sequence
< double > aHSL( 3 );
2071 if ( rAny
>>= nColor
) // RGB color
2073 rA
= (sal_uInt8
)( nColor
>> 24 );
2074 rB
= (sal_uInt8
)( nColor
>> 8 );
2075 rC
= (sal_uInt8
)( nColor
);
2077 else if ( rAny
>>= aHSL
) // HSL
2079 rA
= (sal_Int32
) ( aHSL
[ 0 ] * 255.0 / 360.0 );
2080 rB
= (sal_Int32
) ( aHSL
[ 1 ] * 255.0 );
2081 rC
= (sal_Int32
) ( aHSL
[ 2 ] * 255.0 );
2084 bIsColor
= sal_False
;
2088 void AnimationExporter::exportAnimateColor( SvStream
& rStrm
, const Reference
< XAnimationNode
>& xNode
, int nAfterEffectType
)
2090 Reference
< XAnimateColor
> xColor( xNode
, UNO_QUERY
);
2093 EscherExContainer
aAnimateColor( rStrm
, DFF_msofbtAnimateColor
);
2095 EscherExAtom
aAnimateColorData( rStrm
, DFF_msofbtAnimateColorData
);
2096 sal_uInt32 nBits
= 8;
2098 sal_Int32 nByMode
, nByA
, nByB
, nByC
;
2099 nByMode
= nByA
= nByB
= nByC
= 0;
2101 sal_Int32 nFromMode
, nFromA
, nFromB
, nFromC
;
2102 nFromMode
= nFromA
= nFromB
= nFromC
= 0;
2104 sal_Int32 nToMode
, nToA
, nToB
, nToC
;
2105 nToMode
= nToA
= nToB
= nToC
= 0;
2107 sal_Int16 nColorSpace
= xColor
->getColorInterpolation();
2109 Any
aAny( xColor
->getBy() );
2110 if ( aAny
.hasValue() )
2112 if ( getColorAny( aAny
, nColorSpace
, nByMode
, nByA
, nByB
, nByC
) )
2115 aAny
= xColor
->getFrom();
2116 if ( aAny
.hasValue() )
2118 if ( getColorAny( aAny
, nColorSpace
, nFromMode
, nFromA
, nFromB
, nFromC
) )
2121 aAny
= xColor
->getTo();
2122 if ( aAny
.hasValue() )
2124 if ( getColorAny( aAny
, nColorSpace
, nToMode
, nToA
, nToB
, nToC
) )
2128 << nByMode
<< nByA
<< nByB
<< nByC
2129 << nFromMode
<< nFromA
<< nFromB
<< nFromC
2130 << nToMode
<< nToA
<< nToB
<< nToC
;
2132 exportAnimateTarget( rStrm
, xNode
, 0, nAfterEffectType
);
2136 void AnimationExporter::exportIterate( SvStream
& rStrm
, const Reference
< XAnimationNode
>& xNode
)
2138 Reference
< XIterateContainer
> xIterate( xNode
, UNO_QUERY
);
2139 if ( xIterate
.is() )
2141 EscherExAtom
aAnimIteration( rStrm
, DFF_msofbtAnimIteration
);
2143 float fInterval
= 10.0;
2144 sal_Int32 nTextUnitEffect
= 0;
2147 sal_Int32 nU3
= 0xe;
2149 sal_Int16 nIterateType
= xIterate
->getIterateType();
2150 switch( nIterateType
)
2152 case TextAnimationType::BY_WORD
: nTextUnitEffect
= 1; break;
2153 case TextAnimationType::BY_LETTER
: nTextUnitEffect
= 2; break;
2156 fInterval
= (float)xIterate
->getIterateInterval();
2158 // convert interval from absolute to percentage
2159 double fDuration
= 0.0;
2161 Reference
< XEnumerationAccess
> xEnumerationAccess( xNode
, UNO_QUERY
);
2162 if( xEnumerationAccess
.is() )
2164 Reference
< XEnumeration
> xEnumeration( xEnumerationAccess
->createEnumeration(), UNO_QUERY
);
2165 if( xEnumeration
.is() )
2167 while( xEnumeration
->hasMoreElements() )
2169 Reference
< XAnimate
> xChildNode( xEnumeration
->nextElement(), UNO_QUERY
);
2170 if( xChildNode
.is() )
2172 double fChildBegin
= 0.0;
2173 double fChildDuration
= 0.0;
2174 xChildNode
->getBegin() >>= fChildBegin
;
2175 xChildNode
->getDuration() >>= fChildDuration
;
2177 fChildDuration
+= fChildBegin
;
2178 if( fChildDuration
> fDuration
)
2179 fDuration
= fChildDuration
;
2186 fInterval
= (float)(100.0 * fInterval
/ fDuration
);
2188 rStrm
<< fInterval
<< nTextUnitEffect
<< nU1
<< nU2
<< nU3
;
2189 aTarget
= xIterate
->getTarget();