merge the formfield patch from ooo-build
[ooovba.git] / sd / source / filter / ppt / pptinanimations.cxx
blobc5e7eadc30a9980c63f78068b6a4796aa8059704
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: pptinanimations.cxx,v $
10 * $Revision: 1.14 $
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/animations/AnimationAdditiveMode.hpp>
47 #include <com/sun/star/animations/XIterateContainer.hpp>
48 #include <com/sun/star/animations/XAnimateSet.hpp>
49 #include <com/sun/star/animations/XAudio.hpp>
50 #include <com/sun/star/animations/XCommand.hpp>
51 #include <com/sun/star/animations/XTransitionFilter.hpp>
52 #include <com/sun/star/animations/XAnimateColor.hpp>
53 #include <com/sun/star/animations/XAnimateMotion.hpp>
54 #include <com/sun/star/animations/XAnimateTransform.hpp>
55 #include <com/sun/star/animations/ValuePair.hpp>
56 #include <com/sun/star/animations/AnimationColorSpace.hpp>
57 #include <com/sun/star/presentation/ShapeAnimationSubType.hpp>
58 #include <com/sun/star/presentation/EffectCommands.hpp>
59 #include <com/sun/star/beans/NamedValue.hpp>
60 #include <com/sun/star/drawing/FillStyle.hpp>
61 #include <com/sun/star/drawing/LineStyle.hpp>
62 #include <com/sun/star/awt/FontWeight.hpp>
63 #include <com/sun/star/awt/FontUnderline.hpp>
64 #include <com/sun/star/awt/FontSlant.hpp>
65 #include <com/sun/star/container/XEnumerationAccess.hpp>
66 #include <com/sun/star/presentation/ParagraphTarget.hpp>
67 #include <com/sun/star/presentation/TextAnimationType.hpp>
68 #include <comphelper/processfactory.hxx>
69 #include <rtl/ustrbuf.hxx>
70 #include <rtl/math.hxx>
72 #include <vcl/vclenum.hxx>
73 #include <svx/svdotext.hxx>
74 #include <svx/outlobj.hxx>
75 #include <svx/editobj.hxx>
76 #include <pptinanimations.hxx>
77 #include <pptatom.hxx>
78 #include "pptin.hxx"
79 #include <algorithm>
81 using ::std::map;
82 using ::rtl::OUString;
83 using ::rtl::OUStringBuffer;
84 using ::com::sun::star::uno::Any;
85 using ::com::sun::star::uno::Reference;
86 using ::com::sun::star::uno::UNO_QUERY;
87 using ::com::sun::star::uno::UNO_QUERY_THROW;
88 using ::com::sun::star::uno::Sequence;
89 using ::com::sun::star::uno::makeAny;
90 using ::com::sun::star::uno::Exception;
91 using ::com::sun::star::uno::XInterface;
92 using ::com::sun::star::beans::NamedValue;
93 using ::com::sun::star::container::XEnumerationAccess;
94 using ::com::sun::star::container::XEnumeration;
95 using ::com::sun::star::lang::XMultiServiceFactory;
97 using namespace ::com::sun::star::drawing;
98 using namespace ::com::sun::star::animations;
99 using namespace ::com::sun::star::presentation;
101 namespace sd
103 extern Reference< XInterface > RandomAnimationNode_createInstance( sal_Int16 nPresetClass );
106 namespace ppt
109 const transition* transition::find( const OUString& rName )
111 const transition* p = gTransitions;
113 while( p->mpName )
115 if( rName.compareToAscii( p->mpName ) == 0 )
116 return p;
118 p++;
121 return NULL;
124 // ====================================================================
128 // ====================================================================
130 SvStream& operator>>(SvStream& rIn, AnimationNode& rNode )
132 rIn >> rNode.mnU1;
133 rIn >> rNode.mnRestart;
134 rIn >> rNode.mnGroupType;
135 rIn >> rNode.mnFill;
136 rIn >> rNode.mnU3;
137 rIn >> rNode.mnU4;
138 rIn >> rNode.mnDuration;
139 rIn >> rNode.mnNodeType;
141 return rIn;
144 // ====================================================================
146 static bool convertMeasure( OUString& rString )
148 bool bRet = false;
150 const sal_Char* pSource[] = { "ppt_x", "ppt_y", "ppt_w", "ppt_h", NULL };
151 const sal_Char* pDest[] = { "x", "y", "width", "height", NULL };
152 sal_Int32 nIndex = 0;
154 const sal_Char** ps = pSource;
155 const sal_Char** pd = pDest;
157 while( *ps )
159 const OUString aSearch( OUString::createFromAscii( *ps ) );
160 while( (nIndex = rString.indexOf( aSearch, nIndex )) != -1 )
162 sal_Int32 nLength = aSearch.getLength();
163 if( nIndex && (rString.getStr()[nIndex-1] == '#' ) )
165 nIndex--;
166 nLength++;
169 const OUString aNew( OUString::createFromAscii( *pd ) );
170 rString = rString.replaceAt( nIndex, nLength, aNew );
171 nIndex += aNew.getLength();
172 bRet = true;
174 ps++;
175 pd++;
178 return bRet;
182 // ====================================================================
184 bool PropertySet::hasProperty( sal_Int32 nProperty ) const
186 return maProperties.find( nProperty ) != maProperties.end();
189 // --------------------------------------------------------------------
191 Any PropertySet::getProperty( sal_Int32 nProperty ) const
193 PropertySetMap_t::const_iterator aIter( maProperties.find( nProperty ) );
194 if( aIter != maProperties.end() )
195 return (*aIter).second;
196 else
197 return Any();
200 // ====================================================================
202 /** this adds an any to another any.
203 if rNewValue is empty, rOldValue is returned.
204 if rOldValue is empty, rNewValue is returned.
205 if rOldValue contains a value, a sequence with rOldValue and rNewValue is returned.
206 if rOldValue contains a sequence, a new sequence with the old sequence and rNewValue is returned.
208 static Any addToSequence( const Any& rOldValue, const Any& rNewValue )
210 if( !rNewValue.hasValue() )
212 return rOldValue;
214 else if( !rOldValue.hasValue() )
216 return rNewValue;
218 else
220 Sequence< Any > aNewSeq;
221 if( rOldValue >>= aNewSeq )
223 sal_Int32 nSize = aNewSeq.getLength();
224 aNewSeq.realloc(nSize+1);
225 aNewSeq[nSize] = rNewValue;
227 else
229 aNewSeq.realloc(2);
230 aNewSeq[0] = rOldValue;
231 aNewSeq[1] = rNewValue;
233 return makeAny( aNewSeq );
237 // ====================================================================
239 AnimationImporter::AnimationImporter( ImplSdPPTImport* pPPTImport, SvStream& rStCtrl )
240 : mpPPTImport( pPPTImport ), mrStCtrl( rStCtrl )
244 // --------------------------------------------------------------------
246 void AnimationImporter::import( const Reference< XDrawPage >& xPage, const DffRecordHeader& rProgTagContentHd )
248 #ifdef DBG_ANIM_LOG
249 mpFile = fopen( "c:\\output.xml", "w+" );
250 //mpFile = stdout;
251 #endif
252 dump("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
254 Reference< XAnimationNodeSupplier > xNodeSupplier( xPage, UNO_QUERY );
255 if( xNodeSupplier.is() )
257 mxRootNode = xNodeSupplier->getAnimationNode();
258 if( mxRootNode.is() )
260 Reference< XAnimationNode > xParent;
262 const Atom* pAtom = Atom::import( rProgTagContentHd, mrStCtrl );
263 if( pAtom )
265 importAnimationContainer( pAtom, xParent );
268 processAfterEffectNodes();
272 #ifdef DBG_ANIM_LOG
273 fclose( mpFile );
274 #endif
277 // --------------------------------------------------------------------
279 void AnimationImporter::processAfterEffectNodes()
281 std::for_each( maAfterEffectNodes.begin(), maAfterEffectNodes.end(), sd::stl_process_after_effect_node_func );
284 // --------------------------------------------------------------------
286 Reference< XAnimationNode > AnimationImporter::createNode( const Atom* pAtom, const AnimationNode& rNode )
288 const char* pServiceName = NULL;
290 switch( rNode.mnGroupType )
292 case mso_Anim_GroupType_PAR:
293 if( pAtom->hasChildAtom( DFF_msofbtAnimIteration ) )
294 pServiceName = "com.sun.star.animations.IterateContainer";
295 else
296 pServiceName = "com.sun.star.animations.ParallelTimeContainer";
297 break;
298 case mso_Anim_GroupType_SEQ:
299 pServiceName = "com.sun.star.animations.SequenceTimeContainer";
300 break;
301 case mso_Anim_GroupType_NODE:
303 switch( rNode.mnNodeType )
305 case mso_Anim_Behaviour_FILTER:
307 pServiceName = "com.sun.star.animations.TransitionFilter";
308 break;
310 case mso_Anim_Behaviour_ANIMATION:
311 if( pAtom->hasChildAtom( DFF_msofbtAnimateSet ) )
312 pServiceName = "com.sun.star.animations.AnimateSet";
313 else if( pAtom->hasChildAtom( DFF_msofbtAnimateColor ) )
314 pServiceName = "com.sun.star.animations.AnimateColor";
315 else if( pAtom->hasChildAtom( DFF_msofbtAnimateScale ) )
316 pServiceName = "com.sun.star.animations.AnimateTransform";
317 else if( pAtom->hasChildAtom( DFF_msofbtAnimateRotation ) )
318 pServiceName = "com.sun.star.animations.AnimateTransform";
319 else if( pAtom->hasChildAtom( DFF_msofbtAnimateMotion ) )
320 pServiceName = "com.sun.star.animations.AnimateMotion";
321 else if( pAtom->hasChildAtom( DFF_msofbtAnimateFilter ) )
322 pServiceName = "com.sun.star.animations.TransitionFilter";
323 else if( pAtom->hasChildAtom( DFF_msofbtAnimCommand ) )
324 pServiceName = "com.sun.star.animations.Command";
325 else
326 pServiceName = "com.sun.star.animations.Animate";
327 break;
329 break;
331 case mso_Anim_GroupType_MEDIA:
332 pServiceName = "com.sun.star.animations.Audio";
333 break;
335 default:
336 pServiceName = "com.sun.star.animations.Animate";
337 break;
340 Reference< XAnimationNode > xNode;
341 if( pServiceName )
343 const OUString aServiceName( OUString::createFromAscii(pServiceName) );
344 Reference< XInterface > xFac( ::comphelper::getProcessServiceFactory()->createInstance(aServiceName) );
345 xNode.set(xFac , UNO_QUERY );
348 DBG_ASSERT( xNode.is(), "sd::AnimationImporter::createNode(), node creation failed!" );
349 return xNode;
352 // --------------------------------------------------------------------
354 static bool is_random( const AnimationNode& rNode, const PropertySet& rSet, sal_Int32& rPresetClass )
356 if( rNode.mnGroupType != mso_Anim_GroupType_PAR )
357 return false;
359 if( !rSet.hasProperty( DFF_ANIM_PRESET_ID ) || !rSet.hasProperty( DFF_ANIM_PRESET_CLASS ) )
360 return false;
362 sal_Int32 nPresetId = 0;
363 if( !(rSet.getProperty( DFF_ANIM_PRESET_ID ) >>= nPresetId) || (nPresetId != 24) )
364 return false;
366 sal_Int32 nPresetClass = 0;
367 if( !(rSet.getProperty( DFF_ANIM_PRESET_CLASS ) >>= nPresetClass) )
368 return false;
370 switch( nPresetClass )
372 case DFF_ANIM_PRESS_CLASS_ENTRANCE: rPresetClass = EffectPresetClass::ENTRANCE; return true;
373 case DFF_ANIM_PRESS_CLASS_EXIT: rPresetClass = EffectPresetClass::EXIT; return true;
375 return false;
379 void AnimationImporter::importAnimationContainer( const Atom* pAtom, const Reference< XAnimationNode >& xParent )
381 if( pAtom->seekToContent() )
383 AnimationNode aNode;
384 const Atom* pAnimationNodeAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimNode );
385 if( pAnimationNodeAtom && pAnimationNodeAtom->seekToContent() )
386 mrStCtrl >> aNode;
388 PropertySet aSet;
389 const Atom* pAnimationPropertySetAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimPropertySet );
390 if( pAnimationPropertySetAtom )
391 importPropertySetContainer( pAnimationPropertySetAtom, aSet );
393 Reference< XAnimationNode > xNode;
395 if( xParent.is() )
397 sal_Int32 nPresetClass;
398 if( is_random( aNode, aSet, nPresetClass ) )
400 // create a random animation node with the given preset class
401 xNode.set( sd::RandomAnimationNode_createInstance( (sal_Int16)nPresetClass ), UNO_QUERY );
404 if( !xNode.is() )
406 // create a node for the given atom
407 xNode = createNode( pAtom, aNode );
410 else
412 // if we have no parent we fill the root node
413 xNode = mxRootNode;
416 // import if we have a node and its not random
417 if( xNode.is() )
419 fillNode( xNode, aNode, aSet );
421 switch( aNode.mnGroupType )
423 case mso_Anim_GroupType_PAR:
425 dump( "<par" );
426 dump( aNode );
427 dump( aSet );
428 importTimeContainer( pAtom, xNode );
429 dump( "</par>\n" );
431 // for iteration containers, map target from childs to iteration
432 Reference< XIterateContainer > xIter( xNode, UNO_QUERY );
433 if( xIter.is() )
435 double fDuration = 0.0;
436 Any aTarget, aEmpty;
437 Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY );
438 if( xEnumerationAccess.is() )
440 Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
441 if( xEnumeration.is() )
443 while( xEnumeration->hasMoreElements() )
445 Reference< XAnimate > xChildNode( xEnumeration->nextElement(), UNO_QUERY );
446 if( xChildNode.is() )
448 double fChildBegin = 0.0;
449 double fChildDuration = 0.0;
450 xChildNode->getBegin() >>= fChildBegin;
451 xChildNode->getDuration() >>= fChildDuration;
453 fChildDuration += fChildBegin;
454 if( fChildDuration > fDuration )
455 fDuration = fChildDuration;
457 if( !aTarget.hasValue() )
458 aTarget = xChildNode->getTarget();
460 xChildNode->setTarget( aEmpty );
466 xIter->setTarget( aTarget );
468 double fIterateInterval = xIter->getIterateInterval() * fDuration / 100;
469 xIter->setIterateInterval( fIterateInterval );
472 break;
474 case mso_Anim_GroupType_SEQ:
476 dump( "<seq" );
477 dump( aNode );
478 dump( aSet );
479 importTimeContainer( pAtom, xNode );
480 dump( "</seq>\n" );
482 if( aSet.hasProperty( DFF_ANIM_NODE_TYPE ) )
484 sal_Int32 nPPTNodeType = 0;
485 if( aSet.getProperty( DFF_ANIM_NODE_TYPE ) >>= nPPTNodeType )
487 switch(nPPTNodeType)
489 case DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE:
490 fixMainSequenceTiming( xNode );
491 break;
492 case DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ:
493 fixInteractiveSequenceTiming( xNode );
494 break;
499 break;
501 case mso_Anim_GroupType_NODE:
503 #ifdef DBG_ANIM_LOG
504 if( pAtom->hasChildAtom( DFF_msofbtAnimateSet ) )
506 dump( "<set" );
508 else if( pAtom->hasChildAtom( DFF_msofbtAnimateColor ) )
510 dump( "<animateColor" );
512 else if( pAtom->hasChildAtom( DFF_msofbtAnimateScale ) )
514 dump( "<animateScale" );
516 else if( pAtom->hasChildAtom( DFF_msofbtAnimateRotation ) )
518 dump( "<animateRotation" );
520 else if( pAtom->hasChildAtom( DFF_msofbtAnimateMotion ) )
522 dump( "<animateMotion" );
524 else if( pAtom->hasChildAtom( DFF_msofbtAnimate ) )
526 dump( "<animate" );
528 else if( pAtom->hasChildAtom( DFF_msofbtAnimateFilter ) )
530 dump( "<animateFilter" );
532 else if( pAtom->hasChildAtom( DFF_msofbtAnimCommand ) )
534 dump( "<command" );
536 else
538 DBG_ERROR( "unknown node atom!" );
539 dump_atom_header( pAtom, true, false );
540 dump_atom( pAtom );
541 dump_atom_header( pAtom, false, false );
542 break;
544 dump( aNode );
545 dump( aSet );
546 #endif
547 importAnimationNodeContainer( pAtom, xNode );
548 if( !convertAnimationNode( xNode, xParent ) )
549 xNode = 0;
550 dump( "/>\n");
553 break;
555 case mso_Anim_GroupType_MEDIA:
557 dump( "<audio" );
558 dump( aNode );
559 dump( aSet );
560 importAudioContainer( pAtom, xNode );
561 dump( "</audio>\n" );
563 break;
565 default:
566 DBG_ERROR( "unknown group atom!" );
568 dump_atom_header( pAtom, true, false );
569 dump_atom( pAtom );
570 dump_atom_header( pAtom, false, false );
571 break;
576 if( xParent.is() && xNode.is() )
578 Reference< XTimeContainer > xParentContainer( xParent, UNO_QUERY );
579 DBG_ASSERT( xParentContainer.is(), "parent is no container, then why do I have a child here?" );
580 if( xParentContainer.is() )
582 xParentContainer->appendChild( xNode );
588 // --------------------------------------------------------------------
589 void AnimationImporter::fixMainSequenceTiming( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode )
593 bool bFirst = true;
594 Reference< XEnumerationAccess > xEA( xNode, UNO_QUERY_THROW );
595 Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_QUERY_THROW );
596 while( xE->hasMoreElements() )
598 // click node
599 Reference< XAnimationNode > xClickNode( xE->nextElement(), UNO_QUERY );
601 Event aEvent;
602 aEvent.Trigger = EventTrigger::ON_NEXT;
603 aEvent.Repeat = 0;
604 xClickNode->setBegin( makeAny( aEvent ) );
606 if( bFirst )
608 bFirst = false;
609 Reference< XEnumerationAccess > xEA2( xClickNode, UNO_QUERY_THROW );
610 Reference< XEnumeration > xE2( xEA2->createEnumeration(), UNO_QUERY_THROW );
611 if( xE2->hasMoreElements() )
613 // with node
614 xE2->nextElement() >>= xEA2;
615 if( xEA2.is() )
616 xE2.query( xEA2->createEnumeration() );
617 else
618 xE2.clear();
620 if( xE2.is() && xE2->hasMoreElements() )
622 Reference< XAnimationNode > xEffectNode( xE2->nextElement(), UNO_QUERY_THROW );
623 const Sequence< NamedValue > aUserData( xEffectNode->getUserData() );
624 const NamedValue* p = aUserData.getConstArray();
625 sal_Int32 nLength = aUserData.getLength();
626 while( nLength-- )
628 if( p->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "node-type" ) ) )
630 sal_Int16 nNodeType = 0;
631 p->Value >>= nNodeType;
632 if( nNodeType != ::com::sun::star::presentation::EffectNodeType::ON_CLICK )
634 // first effect does not start on click, so correct
635 // first click nodes begin to 0s
636 xClickNode->setBegin( makeAny( (double)0.0 ) );
637 break;
640 p++;
647 catch( Exception& e )
649 (void)e;
650 DBG_ERROR("sd::AnimationImporter::fixMainSequenceTiming(), exception caught!" );
654 // --------------------------------------------------------------------
656 void AnimationImporter::fixInteractiveSequenceTiming( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode )
660 Any aBegin( xNode->getBegin() );
661 Any aEmpty;
662 xNode->setBegin( aEmpty );
664 Reference< XEnumerationAccess > xEA( xNode, UNO_QUERY_THROW );
665 Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_QUERY_THROW );
666 while( xE->hasMoreElements() )
668 // click node
669 Reference< XAnimationNode > xClickNode( xE->nextElement(), UNO_QUERY );
670 xClickNode->setBegin( aBegin );
673 catch( Exception& e )
675 (void)e;
676 DBG_ERROR("sd::AnimationImporter::fixInteractiveSequenceTiming(), exception caught!" );
680 // --------------------------------------------------------------------
682 bool AnimationImporter::convertAnimationNode( const Reference< XAnimationNode >& xNode, const Reference< XAnimationNode >& xParent )
684 Reference< XAnimate > xAnimate( xNode, UNO_QUERY );
685 if( !xAnimate.is() )
686 return true;
688 if( !xAnimate->getTarget().hasValue() )
689 return false;
691 const sal_Int16 nNodeType = xNode->getType();
693 if( nNodeType == AnimationNodeType::TRANSITIONFILTER )
694 return true;
696 OUString aAttributeName( xAnimate->getAttributeName() );
698 if( (nNodeType == AnimationNodeType::SET) && aAttributeName.equalsAscii( "fill.on" ) )
699 return false;
701 const ImplAttributeNameConversion* p = gImplConversionList;
703 MS_AttributeNames eAttribute = MS_UNKNOWN;
705 if( (nNodeType == AnimationNodeType::ANIMATEMOTION) ||
706 (nNodeType == AnimationNodeType::ANIMATETRANSFORM) )
708 OUString aEmpty;
709 aAttributeName = aEmpty;
711 else
713 while( p->mpMSName )
715 if( aAttributeName.compareToAscii( p->mpMSName ) == 0 )
716 break;
718 p++;
721 DBG_ASSERT( p->mpMSName || (aAttributeName.getLength() == 0), "sd::AnimationImporter::convertAnimationNode(), unknown attribute!" );
722 #ifdef DBG_ANIM_LOG
723 if( p->mpMSName == 0 ) dump( "<error text=\"sd::AnimationImporter::convertAnimationNode(), unknown attribute!\"/>\n" );
724 #endif
726 eAttribute = p->meAttribute;
728 if( p->mpAPIName )
729 aAttributeName = OUString::createFromAscii( p->mpAPIName );
732 xAnimate->setAttributeName( aAttributeName );
734 if( eAttribute != MS_UNKNOWN )
736 Any aAny( xAnimate->getFrom() );
737 if( aAny.hasValue() )
739 if( convertAnimationValue( eAttribute, aAny ) )
740 xAnimate->setFrom( aAny );
743 aAny = xAnimate->getBy();
744 if( aAny.hasValue() )
746 if( convertAnimationValue( eAttribute, aAny ) )
747 xAnimate->setBy( aAny );
750 aAny = xAnimate->getTo();
751 if( aAny.hasValue() )
753 if( convertAnimationValue( eAttribute, aAny ) )
754 xAnimate->setTo( aAny );
757 Sequence< Any > aValues( xAnimate->getValues() );
758 sal_Int32 nValues = aValues.getLength();
759 if( nValues )
761 Any* p2 = aValues.getArray();
762 while( nValues-- )
763 convertAnimationValue( eAttribute, *p2++ );
765 xAnimate->setValues( aValues );
768 OUString aFormula( xAnimate->getFormula() );
769 if( aFormula.getLength() )
771 if( convertMeasure( aFormula ) )
772 xAnimate->setFormula( aFormula );
776 // check for after-affect
777 Sequence< NamedValue > aUserData( xNode->getUserData() );
778 NamedValue* pValue = aUserData.getArray();
779 NamedValue* pLastValue = pValue;
780 sal_Int32 nLength = aUserData.getLength(), nRemoved = 0;
782 sal_Bool bAfterEffect = false;
783 sal_Int32 nMasterRel = 0;
784 for( ; nLength--; pValue++ )
786 if( pValue->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("after-effect") ) )
788 pValue->Value >>= bAfterEffect;
789 nRemoved++;
791 else if( pValue->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("master-rel") ) )
793 pValue->Value >>= nMasterRel;
794 nRemoved++;
796 else
798 if( nRemoved )
799 *pLastValue = *pValue;
800 pLastValue++;
804 if( nRemoved )
806 aUserData.realloc( aUserData.getLength() - nRemoved );
807 xNode->setUserData( aUserData );
810 // if its an after effect node, add it to the list for
811 // later processing
812 // after effect nodes are not inserted at their import
813 // position, so return false in this case
814 if( bAfterEffect )
816 if( nMasterRel != 2 )
818 Event aEvent;
820 aEvent.Source <<= xParent;
821 aEvent.Trigger = EventTrigger::END_EVENT;
822 aEvent.Repeat = 0;
824 xNode->setBegin( makeAny( aEvent ) );
827 // add to after effect nodes for later processing
828 sd::AfterEffectNode aNode( xNode, xParent, nMasterRel == 2 );
829 maAfterEffectNodes.push_back( aNode );
830 return false;
833 return true;
836 static int lcl_gethex( int nChar )
838 if( nChar >= '0' && nChar <= '9' )
839 return nChar - '0';
840 else if( nChar >= 'a' && nChar <= 'f' )
841 return nChar - 'a' + 10;
842 else if( nChar >= 'A' && nChar <= 'F' )
843 return nChar - 'A' + 10;
844 else
845 return 0;
848 bool AnimationImporter::convertAnimationValue( MS_AttributeNames eAttribute, Any& rValue )
850 bool bRet = false;
851 switch( eAttribute )
853 case MS_PPT_X:
854 case MS_PPT_Y:
855 case MS_PPT_W:
856 case MS_PPT_H:
858 OUString aString;
860 if( rValue.getValueType() == ::getCppuType((const ValuePair*)0) )
862 ValuePair aValuePair;
863 if( rValue >>= aValuePair )
865 if( aValuePair.First >>= aString )
867 if( convertMeasure( aString ) )
869 aValuePair.First <<= aString;
870 bRet = true;
874 if( aValuePair.Second >>= aString )
876 if( convertMeasure( aString ) )
878 aValuePair.Second <<= aString;
879 bRet = true;
884 else if( rValue.getValueType() == ::getCppuType((const OUString*)0) )
886 if( rValue >>= aString )
888 bRet = convertMeasure( aString );
890 if( bRet )
891 rValue <<= aString;
895 break;
897 case MS_XSHEAR:
898 case MS_R:
900 OUString aString;
901 if( rValue >>= aString )
903 rValue <<= aString.toDouble();
904 bRet = true;
907 break;
909 case MS_STYLEROTATION:
911 if( rValue.getValueType() == ::getCppuType((const OUString*)0) )
913 OUString aString;
914 rValue >>= aString;
915 rValue <<= (sal_Int16)aString.toDouble();
916 bRet = true;
918 else if( rValue.getValueType() == ::getCppuType((const double*)0) )
920 double fValue = 0.0;
921 rValue >>= fValue;
922 rValue <<= (sal_Int16)fValue;
923 bRet = true;
926 break;
928 case MS_FILLCOLOR:
929 case MS_STROKECOLOR:
930 case MS_STYLECOLOR:
931 case MS_PPT_C:
933 OUString aString;
934 if( rValue >>= aString )
936 if( aString.getLength() >= 7 && aString[0] == '#' )
938 Color aColor;
939 aColor.SetRed( (UINT8)(lcl_gethex( aString[1] ) * 16 + lcl_gethex( aString[2] )) );
940 aColor.SetGreen( (UINT8)(lcl_gethex( aString[3] ) * 16 + lcl_gethex( aString[4] )) );
941 aColor.SetBlue( (UINT8)(lcl_gethex( aString[5] ) * 16 + lcl_gethex( aString[6] )) );
942 rValue <<= (sal_Int32)aColor.GetColor();
943 bRet = true;
945 else if( aString.matchAsciiL( "rgb(", 4, 0 ) )
947 aString = aString.copy( 4, aString.getLength() - 5 );
948 Color aColor;
949 sal_Int32 index = 0;
950 aColor.SetRed( (UINT8)aString.getToken( 0, (sal_Unicode)',', index ).toInt32() );
951 aColor.SetGreen( (UINT8)aString.getToken( 0, (sal_Unicode)',', index ).toInt32() );
952 aColor.SetRed( (UINT8)aString.getToken( 0, (sal_Unicode)',', index ).toInt32() );
953 rValue <<= (sal_Int32)aColor.GetColor();
954 bRet = true;
956 else if( aString.matchAsciiL( "hsl(", 4, 0 ) )
958 sal_Int32 index = 0;
959 sal_Int32 nA = aString.getToken( 0, (sal_Unicode)',', index ).toInt32();
960 sal_Int32 nB = aString.getToken( 0, (sal_Unicode)',', index ).toInt32();
961 sal_Int32 nC = aString.getToken( 0, (sal_Unicode)',', index ).toInt32();
962 dump( "hsl(%ld", nA );
963 dump( ",%ld", nB );
964 dump( ",%ld)", nC );
965 Sequence< double > aHSL( 3 );
966 aHSL[0] = nA * 360.0/255.0;
967 aHSL[1] = nB / 255.0;
968 aHSL[2] = nC / 255.0;
969 rValue <<= aHSL;
970 bRet = true;
974 break;
976 case MS_FILLTYPE:
978 OUString aString;
979 if( rValue >>= aString )
981 rValue <<= aString.equalsAscii( "solid" ) ? FillStyle_SOLID : FillStyle_NONE;
982 bRet = true;
985 break;
987 case MS_STROKEON:
989 OUString aString;
990 if( rValue >>= aString )
992 rValue <<= aString.equalsAscii( "true" ) ? ::com::sun::star::drawing::LineStyle_SOLID : ::com::sun::star::drawing::LineStyle_NONE;
993 bRet = true;
996 break;
998 case MS_FONTWEIGHT:
1000 OUString aString;
1001 if( rValue >>= aString )
1003 rValue <<= aString.equalsAscii( "bold" ) ? com::sun::star::awt::FontWeight::BOLD : com::sun::star::awt::FontWeight::NORMAL;
1004 bRet = true;
1007 break;
1009 case MS_STYLEFONTSTYLE:
1011 OUString aString;
1012 if( rValue >>= aString )
1014 rValue <<= aString.equalsAscii( "italic" ) ? com::sun::star::awt::FontSlant_ITALIC : com::sun::star::awt::FontSlant_NONE;
1015 bRet = true;
1018 break;
1020 case MS_STYLEUNDERLINE:
1022 OUString aString;
1023 if( rValue >>= aString )
1025 rValue <<= aString.equalsAscii( "true" ) ? com::sun::star::awt::FontUnderline::SINGLE : com::sun::star::awt::FontUnderline::NONE;
1026 bRet = true;
1029 break;
1031 case MS_STYLEOPACITY:
1032 case MS_STYLEFONTSIZE:
1034 OUString aString;
1035 if( rValue >>= aString )
1037 rValue <<= (float)aString.toDouble();
1038 bRet = true;
1041 break;
1043 case MS_STYLEVISIBILITY:
1045 OUString aString;
1046 if( rValue >>= aString )
1048 rValue <<= aString.equalsAscii( "visible" ) ? sal_True : sal_False;
1049 bRet = true;
1052 break;
1053 default:
1054 break;
1057 return bRet;
1060 // --------------------------------------------------------------------
1062 static OUString getConvertedSubType( sal_Int16 nPresetClass, sal_Int32 nPresetId, sal_Int32 nPresetSubType )
1064 const sal_Char* pStr = 0;
1066 if( (nPresetClass == EffectPresetClass::ENTRANCE) || (nPresetClass == EffectPresetClass::EXIT) )
1068 // skip wheel effect
1069 if( nPresetId != 21 )
1071 if( nPresetId == 5 )
1073 // checkerboard
1074 switch( nPresetSubType )
1076 case 5: pStr = "downward"; break;
1077 case 10: pStr = "across"; break;
1080 else if( nPresetId == 17 )
1082 // stretch
1083 if( nPresetSubType == 10 )
1084 pStr = "across";
1086 else if( nPresetId == 18 )
1088 // strips
1089 switch( nPresetSubType )
1091 case 3: pStr = "right-to-top"; break;
1092 case 6: pStr = "right-to-bottom"; break;
1093 case 9: pStr = "left-to-top"; break;
1094 case 12: pStr = "left-to-bottom"; break;
1098 if( pStr == 0 )
1100 const convert_subtype* p = gConvertArray;
1102 while( p->mpStrSubType )
1104 if( p->mnID == nPresetSubType )
1106 pStr = p->mpStrSubType;
1107 break;
1109 p++;
1115 if( pStr )
1116 return OUString::createFromAscii( pStr );
1117 else
1118 return OUString::valueOf( nPresetSubType );
1121 // --------------------------------------------------------------------
1123 void AnimationImporter::fillNode( Reference< XAnimationNode >& xNode, const AnimationNode& rNode, const PropertySet& rSet )
1125 sal_Bool bAfterEffect = false;
1127 // attribute Restart
1128 if( rNode.mnRestart )
1130 sal_Int16 nRestart = AnimationRestart::DEFAULT;
1131 switch( rNode.mnRestart )
1133 case 1: nRestart = AnimationRestart::ALWAYS; break;
1134 case 2: nRestart = AnimationRestart::WHEN_NOT_ACTIVE; break;
1135 case 3: nRestart = AnimationRestart::NEVER; break;
1137 xNode->setRestart( nRestart );
1140 // attribute Fill
1141 if( rNode.mnFill )
1143 sal_Int16 nFill = AnimationFill::DEFAULT;
1144 switch( rNode.mnFill )
1146 case 1: nFill = AnimationFill::REMOVE; break;
1147 case 2: nFill = AnimationFill::FREEZE; break;
1148 case 3: nFill = AnimationFill::HOLD; break;
1149 case 4: nFill = AnimationFill::TRANSITION; break;
1151 xNode->setFill( nFill );
1154 // attribute Duration
1155 if( rNode.mnDuration )
1157 Any aDuration;
1158 if( rNode.mnDuration > 0 )
1160 aDuration <<= (double)(rNode.mnDuration / 1000.0);
1162 else if( rNode.mnDuration < 0 )
1164 aDuration <<= Timing_INDEFINITE;
1166 xNode->setDuration( aDuration );
1169 // TODO: DFF_ANIM_PATH_EDIT_MODE
1170 if( rSet.hasProperty( DFF_ANIM_PATH_EDIT_MODE ) )
1172 sal_Int32 nPathEditMode ;
1173 if( rSet.getProperty( DFF_ANIM_PATH_EDIT_MODE ) >>= nPathEditMode )
1178 // set user data
1179 Sequence< NamedValue > aUserData;
1181 // attribute Type
1182 if( rSet.hasProperty( DFF_ANIM_NODE_TYPE ) )
1184 sal_Int32 nPPTNodeType = 0;
1185 if( rSet.getProperty( DFF_ANIM_NODE_TYPE ) >>= nPPTNodeType )
1187 sal_Int16 nNodeType = ::com::sun::star::presentation::EffectNodeType::DEFAULT;
1188 switch( nPPTNodeType )
1190 case DFF_ANIM_NODE_TYPE_ON_CLICK: nNodeType = ::com::sun::star::presentation::EffectNodeType::ON_CLICK; break;
1191 case DFF_ANIM_NODE_TYPE_WITH_PREVIOUS: nNodeType = ::com::sun::star::presentation::EffectNodeType::WITH_PREVIOUS; break;
1192 case DFF_ANIM_NODE_TYPE_AFTER_PREVIOUS: nNodeType = ::com::sun::star::presentation::EffectNodeType::AFTER_PREVIOUS; break;
1193 case DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE: nNodeType = ::com::sun::star::presentation::EffectNodeType::MAIN_SEQUENCE; break;
1194 case DFF_ANIM_NODE_TYPE_TIMING_ROOT: nNodeType = ::com::sun::star::presentation::EffectNodeType::TIMING_ROOT; break;
1195 case DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ:nNodeType = ::com::sun::star::presentation::EffectNodeType::INTERACTIVE_SEQUENCE; break;
1198 sal_Int32 nSize = aUserData.getLength();
1199 aUserData.realloc(nSize+1);
1200 aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "node-type" ) );
1201 aUserData[nSize].Value <<= nNodeType;
1205 if( rSet.hasProperty( DFF_ANIM_GROUP_ID ) )
1207 sal_Int32 nGroupId;
1208 if( rSet.getProperty( DFF_ANIM_GROUP_ID ) >>= nGroupId )
1210 sal_Int32 nSize = aUserData.getLength();
1211 aUserData.realloc(nSize+1);
1212 aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "group-id" ) );
1213 aUserData[nSize].Value <<= nGroupId;
1217 sal_Int16 nEffectPresetClass = EffectPresetClass::CUSTOM;
1218 sal_Int32 nPresetId = 0;
1220 if( rSet.hasProperty( DFF_ANIM_PRESET_CLASS ) )
1222 sal_Int32 nPresetClass = 0;
1223 if ( rSet.getProperty( DFF_ANIM_PRESET_CLASS ) >>= nPresetClass )
1225 switch( nPresetClass )
1227 case DFF_ANIM_PRESS_CLASS_ENTRANCE: nEffectPresetClass = EffectPresetClass::ENTRANCE; break;
1228 case DFF_ANIM_PRESS_CLASS_EXIT: nEffectPresetClass = EffectPresetClass::EXIT; break;
1229 case DFF_ANIM_PRESS_CLASS_EMPHASIS: nEffectPresetClass = EffectPresetClass::EMPHASIS; break;
1230 case DFF_ANIM_PRESS_CLASS_MOTIONPATH: nEffectPresetClass = EffectPresetClass::MOTIONPATH; break;
1231 case DFF_ANIM_PRESS_CLASS_OLE_ACTION: nEffectPresetClass = EffectPresetClass::OLEACTION; break;
1232 case DFF_ANIM_PRESS_CLASS_MEDIACALL: nEffectPresetClass = EffectPresetClass::MEDIACALL; break;
1234 sal_Int32 nSize = aUserData.getLength();
1235 aUserData.realloc(nSize+1);
1236 aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "preset-class" ) );
1237 aUserData[nSize].Value <<= nEffectPresetClass;
1241 if( rSet.hasProperty( DFF_ANIM_PRESET_ID ) )
1243 if( rSet.getProperty( DFF_ANIM_PRESET_ID ) >>= nPresetId )
1245 sal_Int32 nSize = aUserData.getLength();
1246 aUserData.realloc(nSize+1);
1247 aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "preset-id" ) );
1249 const preset_maping* p = gPresetMaping;
1250 while( p->mpStrPresetId && ((p->mnPresetClass != nEffectPresetClass) || (p->mnPresetId != nPresetId )) )
1251 p++;
1253 if( p->mpStrPresetId )
1255 aUserData[nSize].Value <<= OUString::createFromAscii( p->mpStrPresetId );
1257 else
1259 OUStringBuffer sBuffer;
1260 sBuffer.appendAscii( "ppt_" );
1261 switch( nEffectPresetClass )
1263 case EffectPresetClass::ENTRANCE: sBuffer.appendAscii( "entrance_" ); break;
1264 case EffectPresetClass::EXIT: sBuffer.appendAscii( "exit_" ); break;
1265 case EffectPresetClass::EMPHASIS: sBuffer.appendAscii( "emphasis_" ); break;
1266 case EffectPresetClass::MOTIONPATH: sBuffer.appendAscii( "motionpath_" ); break;
1267 case EffectPresetClass::OLEACTION: sBuffer.appendAscii( "oleaction_" ); break;
1268 case EffectPresetClass::MEDIACALL: sBuffer.appendAscii( "mediacall_" ); break;
1270 sBuffer.append( nPresetId );
1272 aUserData[nSize].Value <<= sBuffer.makeStringAndClear();
1277 if( rSet.hasProperty( DFF_ANIM_PRESET_SUB_TYPE ) )
1279 sal_Int32 nPresetSubType = 0;
1280 if( (rSet.getProperty( DFF_ANIM_PRESET_SUB_TYPE ) >>= nPresetSubType) )
1282 if( nPresetSubType )
1284 sal_Int32 nSize = aUserData.getLength();
1285 aUserData.realloc(nSize+1);
1286 aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "preset-sub-type" ) );
1287 aUserData[nSize].Value <<= getConvertedSubType( nEffectPresetClass, nPresetId, nPresetSubType );
1292 if( rSet.hasProperty( DFF_ANIM_AFTEREFFECT ) )
1294 if( rSet.getProperty( DFF_ANIM_AFTEREFFECT ) >>= bAfterEffect )
1296 sal_Int32 nSize = aUserData.getLength();
1297 aUserData.realloc(nSize+1);
1298 aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "after-effect" ) );
1299 aUserData[nSize].Value <<= bAfterEffect;
1303 if( bAfterEffect && rSet.hasProperty( DFF_ANIM_MASTERREL ) )
1305 sal_Int32 nMasterRel = 2;
1306 if( rSet.getProperty( DFF_ANIM_MASTERREL ) >>= nMasterRel )
1308 sal_Int32 nSize = aUserData.getLength();
1309 aUserData.realloc(nSize+1);
1310 aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "master-rel" ) );
1311 aUserData[nSize].Value <<= nMasterRel;
1315 xNode->setUserData( aUserData );
1317 // TODO: DFF_ANIM_ID
1318 if( rSet.hasProperty( DFF_ANIM_ID ) )
1320 rtl::OUString aString;
1321 rSet.getProperty( DFF_ANIM_ID ) >>= aString;
1322 if( aString.getLength() )
1327 // TODO: DFF_ANIM_EVENT_FILTER
1328 if( rSet.hasProperty( DFF_ANIM_EVENT_FILTER ) )
1330 rtl::OUString aString;
1331 rSet.getProperty( DFF_ANIM_EVENT_FILTER ) >>= aString;
1332 if( aString.getLength() )
1337 // DFF_ANIM_TIMEFILTER
1338 if( rSet.hasProperty( DFF_ANIM_TIMEFILTER ) )
1340 Reference< XAnimate > xAnim( xNode, UNO_QUERY );
1341 if( xAnim.is() )
1343 rtl::OUString aString;
1344 rSet.getProperty( DFF_ANIM_TIMEFILTER ) >>= aString;
1345 if( aString.getLength() )
1347 sal_Int32 nElements = 1; // a non empty string has at least one value
1349 sal_Int32 fromIndex = 0;
1350 while(true)
1352 fromIndex = aString.indexOf( (sal_Unicode)';', fromIndex );
1353 if( fromIndex == -1 )
1354 break;
1356 fromIndex++;
1357 nElements++;
1360 Sequence< TimeFilterPair > aTimeFilter( nElements );
1362 TimeFilterPair* pValues = aTimeFilter.getArray();
1363 sal_Int32 nIndex = 0;
1364 while( (nElements--) && (nIndex >= 0) )
1366 const OUString aToken( aString.getToken( 0, ';', nIndex ) );
1368 sal_Int32 nPos = aToken.indexOf( ',' );
1369 if( nPos >= 0 )
1371 pValues->Time = aToken.copy( 0, nPos ).toDouble();
1372 pValues->Progress = aToken.copy( nPos+1, aToken.getLength() - nPos - 1 ).toDouble();
1374 pValues++;
1377 xAnim->setTimeFilter( aTimeFilter );
1382 /* todo
1383 Reference< XAudio > xAudio( xNode, UNO_QUERY );
1384 if( xAudio.is() )
1386 if( rSet.hasProperty( DFF_ANIM_ENDAFTERSLIDE ) )
1388 sal_Int16 nEndAfterSlide = 0;
1389 if( rSet.getProperty( DFF_ANIM_ENDAFTERSLIDE ) >>= nEndAfterSlide )
1390 xAudio->setEndAfterSlide( nEndAfterSlide );
1393 if( rSet.hasProperty( DFF_ANIM_VOLUME ) )
1395 double fVolume = 1.0;
1396 rSet.getProperty( DFF_ANIM_VOLUME ) >>= fVolume;
1397 xAudio->setVolume( fVolume );
1401 Reference< XAnimateColor > xColor( xNode, UNO_QUERY );
1402 if( xColor.is() )
1404 if( rSet.hasProperty( DFF_ANIM_DIRECTION ) )
1406 sal_Bool bDirection = sal_False;
1407 if( rSet.getProperty( DFF_ANIM_DIRECTION ) >>= bDirection )
1408 xColor->setDirection( (sal_Bool)!bDirection );
1411 if( rSet.hasProperty( DFF_ANIM_COLORSPACE ) )
1413 sal_Int32 nColorSpace = 0;
1414 rSet.getProperty( DFF_ANIM_COLORSPACE ) >>= nColorSpace;
1415 xColor->setColorInterpolation( (nColorSpace == 0) ? AnimationColorSpace::RGB : AnimationColorSpace::HSL );
1420 // --------------------------------------------------------------------
1422 void AnimationImporter::importTimeContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1424 DBG_ASSERT( pAtom && xNode.is(), "invalid call to ppt::AnimationImporter::importTimeContainer()!");
1425 if( pAtom && xNode.is() )
1427 importAnimationEvents( pAtom, xNode );
1428 importAnimationValues( pAtom, xNode );
1429 importAnimationActions( pAtom, xNode );
1431 dump(">\n");
1433 // import sub containers
1434 const Atom* pChildAtom = pAtom->findFirstChildAtom();
1436 while( pChildAtom )
1438 switch( pChildAtom->getType() )
1440 case DFF_msofbtAnimNode:
1441 case DFF_msofbtAnimEvent:
1442 case DFF_msofbtAnimValue:
1443 case DFF_msofbtAnimAction:
1444 case DFF_msofbtAnimPropertySet:
1445 break;
1447 case DFF_msofbtAnimSubGoup :
1449 if( pChildAtom->hasChildAtom( DFF_msofbtAnimCommand ) )
1451 const OUString aServiceName( OUString::createFromAscii("com.sun.star.animations.Command") );
1452 Reference< XAnimationNode > xChildNode( ::comphelper::getProcessServiceFactory()->createInstance(aServiceName), UNO_QUERY );
1453 importAnimationNodeContainer( pChildAtom, xChildNode );
1454 Reference< XTimeContainer > xParentContainer( xNode, UNO_QUERY );
1455 if( xParentContainer.is() && xChildNode.is() )
1456 xParentContainer->appendChild( xChildNode );
1458 else
1460 importAnimationContainer( pChildAtom, xNode );
1463 break;
1464 case DFF_msofbtAnimGroup :
1466 importAnimationContainer( pChildAtom, xNode );
1468 break;
1469 case DFF_msofbtAnimIteration:
1471 if( pChildAtom->seekToContent() )
1473 float fInterval;
1474 sal_Int32 nTextUnitEffect, nU1, nU2, nU3;
1476 mrStCtrl >> fInterval >> nTextUnitEffect >> nU1 >> nU2 >> nU3;
1478 Reference< XIterateContainer > xIter( xNode, UNO_QUERY );
1479 if( xIter.is() )
1481 sal_Int16 nIterateType = TextAnimationType::BY_PARAGRAPH;
1482 switch( nTextUnitEffect )
1484 case 1: nIterateType = TextAnimationType::BY_WORD; break;
1485 case 2: nIterateType = TextAnimationType::BY_LETTER; break;
1487 xIter->setIterateType( nIterateType );
1488 xIter->setIterateInterval( (double)fInterval );
1491 dump( "<iterate" );
1492 dump( " iterateType=\"%s\"", (nTextUnitEffect == 0) ? "byElement" : (nTextUnitEffect == 1) ? "byWord" : "byLetter" );
1493 dump( " iterateInterval=\"%g\"", fInterval );
1494 dump( " u1=\"%ld\"", nU1 );
1495 dump( " u2=\"%ld\"", nU2 );
1496 dump( " u3=\"%ld\"/>\n", nU3 );
1499 break;
1501 case 0xf136:
1503 #ifdef DBG_ANIM_LOG
1504 sal_uInt32 nU1, nU2;
1505 mrStCtrl >> nU1 >> nU2;
1507 fprintf( mpFile, "<unknown_0xf136 nU1=\"%ld\" nU2=\"%ld\"/>\n", nU1, nU2 );
1508 #endif
1510 break;
1512 default:
1514 dump_atom_header( pChildAtom, true, false );
1515 dump_atom( pChildAtom );
1516 dump_atom_header( pChildAtom, false, false );
1518 break;
1521 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
1526 // --------------------------------------------------------------------
1528 /* todo: for now we dump sub containers into its parent container, what else to do with it? */
1529 void AnimationImporter::importAnimationSubContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1531 DBG_ASSERT( pAtom && xNode.is(), "invalid call to ppt::AnimationImporter::importTimeContainer()!");
1532 if( pAtom && xNode.is() )
1534 // import sub containers
1535 const Atom* pChildAtom = pAtom->findFirstChildAtom();
1537 while( pChildAtom )
1539 switch( pChildAtom->getType() )
1541 case DFF_msofbtAnimNode:
1542 case DFF_msofbtAnimEvent:
1543 case DFF_msofbtAnimValue:
1544 case DFF_msofbtAnimAction:
1545 case DFF_msofbtAnimPropertySet:
1546 break;
1547 case DFF_msofbtAnimCommand:
1549 const OUString aServiceName( OUString::createFromAscii("com.sun.star.animations.Command") );
1550 Reference< XAnimationNode > xChildNode( ::comphelper::getProcessServiceFactory()->createInstance(aServiceName), UNO_QUERY );
1551 importAnimationNodeContainer( pChildAtom, xChildNode );
1552 Reference< XTimeContainer > xParentContainer( xNode, UNO_QUERY );
1553 if( xParentContainer.is() && xChildNode.is() )
1554 xParentContainer->appendChild( xChildNode );
1556 break;
1558 default:
1560 dump_atom_header( pChildAtom, true, false );
1561 dump_atom( pChildAtom );
1562 dump_atom_header( pChildAtom, false, false );
1564 break;
1567 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
1572 // --------------------------------------------------------------------
1574 void AnimationImporter::importAnimationNodeContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1576 DBG_ASSERT( pAtom && xNode.is(), "invalid call to ppt::AnimationImporter::importAnimationNodeContainer()!");
1577 if( pAtom && xNode.is() )
1579 importAnimationEvents( pAtom, xNode );
1580 importAnimationValues( pAtom, xNode );
1581 importAnimationActions( pAtom, xNode );
1583 const Atom* pChildAtom = pAtom->findFirstChildAtom();
1585 while( pChildAtom )
1587 switch( pChildAtom->getType() )
1589 case DFF_msofbtAnimNode:
1590 case DFF_msofbtAnimEvent:
1591 case DFF_msofbtAnimValue:
1592 case DFF_msofbtAnimAction:
1593 case DFF_msofbtAnimPropertySet:
1594 break;
1596 case DFF_msofbtAnimateFilter:
1597 importAnimateFilterContainer( pChildAtom, xNode );
1598 break;
1600 case DFF_msofbtAnimateSet:
1601 importAnimateSetContainer( pChildAtom, xNode );
1602 break;
1604 case DFF_msofbtAnimate:
1605 importAnimateContainer( pChildAtom, xNode );
1606 break;
1608 case DFF_msofbtAnimateScale:
1609 importAnimateScaleContainer( pChildAtom, xNode );
1610 break;
1612 case DFF_msofbtAnimateColor:
1613 importAnimateColorContainer( pChildAtom, xNode );
1614 break;
1616 case DFF_msofbtAnimateRotation:
1617 importAnimateRotationContainer( pChildAtom, xNode );
1618 break;
1620 case DFF_msofbtAnimateMotion:
1621 importAnimateMotionContainer( pChildAtom, xNode );
1622 break;
1624 case DFF_msofbtAnimCommand:
1625 importCommandContainer( pChildAtom, xNode );
1626 break;
1628 default:
1630 dump_atom_header( pChildAtom, true, false );
1631 dump_atom( pChildAtom );
1632 dump_atom_header( pChildAtom, false, false );
1634 break;
1637 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
1642 // --------------------------------------------------------------------
1644 void AnimationImporter::importAnimateFilterContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1646 Reference< XTransitionFilter > xFilter( xNode, UNO_QUERY );
1648 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateFilter && xFilter.is(), "invalid call to ppt::AnimationImporter::importAnimateFilterContainer()!");
1649 if( pAtom && xFilter.is() )
1651 sal_uInt32 nBits = 0;
1653 const Atom* pChildAtom = pAtom->findFirstChildAtom();
1655 while( pChildAtom )
1657 if( !pChildAtom->isContainer() )
1659 if( !pChildAtom->seekToContent() )
1660 break;
1663 switch( pChildAtom->getType() )
1665 case DFF_msofbtAnimateFilterData:
1667 sal_uInt32 transition;
1668 mrStCtrl >> nBits;
1669 mrStCtrl >> transition;
1671 if( nBits & 1 )
1672 xFilter->setMode( transition == 0 );
1674 dump( " transition=\"%s\"", (transition == 0) ? "in" : "out" );
1676 break;
1678 case DFF_msofbtAnimAttributeValue:
1680 if( (nBits & 2 ) && ( pChildAtom->getInstance() == 1 ) )
1682 Any aAny;
1683 if ( importAttributeValue( pChildAtom, aAny ) )
1685 rtl::OUString filter;
1686 aAny >>= filter;
1688 dump( " filter=\"%s\"", filter );
1690 const transition* pTransition = transition::find( filter );
1691 if( pTransition )
1693 xFilter->setTransition( pTransition->mnType );
1694 xFilter->setSubtype( pTransition->mnSubType );
1695 xFilter->setDirection( pTransition->mbDirection );
1697 else
1699 DBG_ERROR( "unknown transition!" );
1704 break;
1706 case DFF_msofbtAnimateTarget:
1707 importAnimateAttributeTargetContainer( pChildAtom, xNode );
1708 break;
1710 default:
1711 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
1712 break;
1716 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
1721 // --------------------------------------------------------------------
1723 void AnimationImporter::importAnimateAttributeTargetContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1725 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateTarget, "invalid call to ppt::AnimationImporter::importAnimateAttributeTargetContainer()!");
1727 Any aTarget;
1729 Reference< XAnimate > xAnimate( xNode, UNO_QUERY );
1731 bool bWrongContext = false;
1733 if( pAtom )
1735 const Atom* pChildAtom = pAtom->findFirstChildAtom();
1737 while( pChildAtom )
1739 if( !pChildAtom->isContainer() )
1741 if( !pChildAtom->seekToContent() )
1742 break;
1745 switch( pChildAtom->getType() )
1747 case DFF_msofbtAnimPropertySet:
1749 PropertySet aSet;
1750 importPropertySetContainer( pChildAtom, aSet );
1751 if( aSet.hasProperty( DFF_ANIM_RUNTIMECONTEXT ) )
1753 OUString aContext;
1754 if( aSet.getProperty( DFF_ANIM_RUNTIMECONTEXT ) >>= aContext )
1756 if( !aContext.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("PPT") ) )
1757 bWrongContext = true;
1761 dump( aSet );
1763 break;
1765 case DFF_msofbtAnimateTargetSettings:
1767 if( xAnimate.is() )
1769 sal_uInt32 nBits;
1770 sal_uInt32 nAdditive;
1771 sal_uInt32 nAccumulate;
1772 sal_uInt32 nTransformType;
1774 mrStCtrl >> nBits >> nAdditive >> nAccumulate >> nTransformType;
1776 // nBits %0001: additive, %0010: accumulate, %0100: attributeName, %1000: transformtype
1777 // nAdditive 0 = base, 1 = sum, 2 = replace, 3 = multiply, 4 = none
1778 // nAccumulate 0 = none, 1 = always
1779 // nTransformType 0: "property" else "image"
1781 if( nBits & 3 )
1783 if( xAnimate.is() )
1785 if( nBits & 1 )
1787 sal_Int16 nTemp = AnimationAdditiveMode::BASE;
1788 switch( nAdditive )
1790 case 1: nTemp = AnimationAdditiveMode::SUM; break;
1791 case 2: nTemp = AnimationAdditiveMode::REPLACE; break;
1792 case 3: nTemp = AnimationAdditiveMode::MULTIPLY; break;
1793 case 4: nTemp = AnimationAdditiveMode::NONE; break;
1795 xAnimate->setAdditive( nTemp );
1798 if( nBits & 2 )
1800 xAnimate->setAccumulate( (nAccumulate == 0) ? sal_True : sal_False );
1804 #ifdef DBG_ANIM_LOG
1805 if( nBits & 1 )
1806 fprintf( mpFile, " additive=\"%s\"", (nAdditive == 0) ? "base" : (nAdditive == 2) ? "replace" : (nAdditive == 1) ? "sum" : (nAdditive == 3 ) ? "multiply" : (nAdditive == 4) ? "none" : "unknown" );
1808 if( nBits & 2 )
1809 fprintf( mpFile, " accumulate=\"%s\"", (nAccumulate == 0) ? "none" : "always" );
1811 if( nBits & 8 )
1812 fprintf( mpFile, " transformType=\"%s\"", (nTransformType == 0) ? "property" : "image" );
1813 #endif
1816 break;
1818 case DFF_msofbtAnimateAttributeNames:
1820 if( xAnimate.is() )
1822 OUString aAttributeName;
1823 importAttributeNamesContainer( pChildAtom, aAttributeName );
1824 if( xAnimate.is() )
1825 xAnimate->setAttributeName( aAttributeName );
1826 dump( " attributeName=\"%s\"", aAttributeName );
1829 break;
1831 case DFF_msofbtAnimateTargetElement:
1833 sal_Int16 nSubType;
1834 importTargetElementContainer( pChildAtom, aTarget, nSubType );
1835 if( xAnimate.is() )
1836 xAnimate->setSubItem( nSubType );
1838 dump( " target=\"" );
1839 dump_target( aTarget );
1840 dump( "\"" );
1842 break;
1844 default:
1845 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
1846 break;
1849 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
1853 if( bWrongContext )
1854 aTarget.clear();
1856 if( xAnimate.is() )
1857 xAnimate->setTarget( aTarget );
1858 else
1860 Reference< XCommand > xCommand( xNode, UNO_QUERY );
1861 if( xCommand.is() )
1862 xCommand->setTarget( aTarget );
1866 // --------------------------------------------------------------------
1868 sal_Int16 AnimationImporter::implGetColorSpace( sal_Int32 nMode, sal_Int32 /*nA*/, sal_Int32 /*nB*/, sal_Int32 /*nC*/ )
1870 switch( nMode )
1872 case 2: // index
1873 // FALLTHROUGH intended
1874 default:
1875 // FALLTHROUGH intended
1876 case 0: // rgb
1877 return AnimationColorSpace::RGB;
1879 case 1: // hsl
1880 return AnimationColorSpace::HSL;
1884 // --------------------------------------------------------------------
1886 Any AnimationImporter::implGetColorAny( sal_Int32 nMode, sal_Int32 nA, sal_Int32 nB, sal_Int32 nC )
1888 switch( nMode )
1890 case 0: // rgb
1892 dump( "rgb(%ld", nA );
1893 dump( ",%ld", nB );
1894 dump( ",%ld)", nC );
1895 Color aColor( (UINT8)nA, (UINT8)nB, (UINT8)nC );
1896 return makeAny( (sal_Int32)aColor.GetRGBColor() );
1898 case 1: // hsl
1900 dump( "hsl(%ld", nA );
1901 dump( ",%ld", nB );
1902 dump( ",%ld)", nC );
1903 Sequence< double > aHSL( 3 );
1904 aHSL[0] = nA * 360.0/255.0;
1905 aHSL[1] = nB / 255.0;
1906 aHSL[2] = nC / 255.0;
1907 return makeAny( aHSL );
1910 case 2: // index
1912 Color aColor;
1913 mpPPTImport->GetColorFromPalette((USHORT)nA, aColor );
1914 dump( "index(%ld", nA );
1915 dump( " [%ld", (sal_Int32)aColor.GetRed() );
1916 dump( ",%ld", (sal_Int32)aColor.GetGreen() );
1917 dump( ",%ld])", (sal_Int32)aColor.GetBlue() );
1918 return makeAny( (sal_Int32)aColor.GetRGBColor() );
1921 default:
1923 dump( "unknown_%ld(", nMode );
1924 dump( "%ld", nA );
1925 dump( ",%ld", nB );
1926 dump( ",%ld)", nC );
1927 DBG_ERROR( "ppt::implGetColorAny(), unhandled color type" );
1929 Any aAny;
1930 return aAny;
1935 void AnimationImporter::importAnimateColorContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1937 Reference< XAnimateColor > xColor( xNode, UNO_QUERY );
1939 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateColor && xColor.is(), "invalid call to ppt::AnimationImporter::importAnimateColorContainer()!");
1940 if( pAtom && xColor.is() )
1942 const Atom* pChildAtom = pAtom->findFirstChildAtom();
1944 while( pChildAtom )
1946 if( !pChildAtom->isContainer() )
1948 if( !pChildAtom->seekToContent() )
1949 break;
1952 switch( pChildAtom->getType() )
1954 case DFF_msofbtAnimateColorData:
1956 sal_uInt32 nBits;
1957 sal_Int32 nByMode, nByA, nByB, nByC;
1958 sal_Int32 nFromMode, nFromA, nFromB, nFromC;
1959 sal_Int32 nToMode, nToA, nToB, nToC;
1960 mrStCtrl >> nBits;
1961 mrStCtrl >> nByMode >> nByA >> nByB >> nByC;
1962 mrStCtrl >> nFromMode >> nFromA >> nFromB >> nFromC;
1963 mrStCtrl >> nToMode >> nToA >> nToB >> nToC;
1965 if( nBits & 1 )
1967 dump( " by=\"" );
1968 xColor->setBy( implGetColorAny( nByMode, nByA, nByB, nByC ) );
1969 xColor->setColorInterpolation( implGetColorSpace( nByMode, nByA, nByB, nByC ) );
1970 dump( "\"");
1973 if( nBits & 2 )
1975 dump( " from=\"" );
1976 xColor->setFrom( implGetColorAny( nFromMode, nFromA, nFromB, nFromC ) );
1977 xColor->setColorInterpolation( implGetColorSpace( nFromMode, nFromA, nFromB, nFromC ) );
1978 dump( "\"");
1981 if( nBits & 4 )
1983 dump( " to=\"" );
1984 xColor->setTo( implGetColorAny( nToMode, nToA, nToB, nToC ) );
1985 xColor->setColorInterpolation( implGetColorSpace( nToMode, nToA, nToB, nToC ) );
1986 dump( "\"");
1989 break;
1991 case DFF_msofbtAnimateTarget:
1992 importAnimateAttributeTargetContainer( pChildAtom, xNode );
1993 break;
1995 default:
1996 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
1997 break;
2000 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
2005 // --------------------------------------------------------------------
2007 void AnimationImporter::importAnimateSetContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2009 Reference< XAnimateSet > xSet( xNode, UNO_QUERY );
2011 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateSet && xSet.is(), "invalid call to ppt::AnimationImporter::importAnimateSetContainer()!");
2012 if( pAtom && xSet.is() )
2014 const Atom* pChildAtom = pAtom->findFirstChildAtom();
2016 while( pChildAtom )
2018 if( !pChildAtom->isContainer() )
2020 if( !pChildAtom->seekToContent() )
2021 break;
2024 switch( pChildAtom->getType() )
2026 case DFF_msofbtAnimateSetData:
2028 sal_Int32 nU1, nU2;
2029 mrStCtrl >> nU1 >> nU2;
2031 dump( " set_1=\"%ld\"", nU1 ),
2032 dump( " set_2=\"%ld\"", nU2 );
2034 break;
2036 case DFF_msofbtAnimAttributeValue:
2038 Any aTo;
2039 if ( importAttributeValue( pChildAtom, aTo ) )
2041 xSet->setTo( aTo );
2043 dump( " value=\"" );
2044 dump( aTo );
2045 dump( "\"" );
2048 break;
2050 case DFF_msofbtAnimateTarget:
2051 importAnimateAttributeTargetContainer( pChildAtom, xNode );
2052 break;
2054 default:
2055 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
2056 break;
2059 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
2064 // --------------------------------------------------------------------
2066 void AnimationImporter::importAnimateContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2068 Reference< XAnimate > xAnim( xNode, UNO_QUERY );
2070 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimate && xAnim.is(), "invalid call to ppt::AnimationImporter::importAnimateContainer()!");
2071 if( pAtom && xAnim.is() )
2073 const Atom* pChildAtom = pAtom->findFirstChildAtom();
2075 while( pChildAtom )
2077 if( !pChildAtom->isContainer() )
2079 if( !pChildAtom->seekToContent() )
2080 break;
2083 switch( pChildAtom->getType() )
2085 case DFF_msofbtAnimateData:
2087 sal_uInt32 nCalcmode, nBits, nValueType;
2088 mrStCtrl >> nCalcmode >> nBits >> nValueType;
2090 if( nBits & 0x08 )
2092 sal_Int16 n = (nCalcmode == 1) ? AnimationCalcMode::LINEAR : /* (nCalcmode == 2) ? AnimationCalcMode::FORMULA : */ AnimationCalcMode::DISCRETE;
2093 xAnim->setCalcMode( n );
2094 dump( " calcmode=\"%s\"", (nCalcmode == 0) ? "discrete" : (nCalcmode == 1) ? "linear" : (nCalcmode == 2) ? "formula" : "unknown" );
2097 if( nBits & 0x30 )
2099 sal_Int16 n = (nValueType == 1) ? AnimationValueType::NUMBER : (nValueType == 2 ) ? AnimationValueType::COLOR : AnimationValueType::STRING;
2100 xAnim->setValueType( n );
2101 dump( " valueType=\"%s\"", (nValueType == 0) ? "string" : (nValueType == 1) ? "number" : (nValueType == 2) ? "color" : "unknown" );
2104 break;
2106 case DFF_msofbtAnimateTarget:
2107 importAnimateAttributeTargetContainer( pChildAtom, xNode );
2108 break;
2110 case DFF_msofbtAnimKeyPoints:
2111 importAnimateKeyPoints( pChildAtom, xNode );
2112 break;
2114 case DFF_msofbtAnimAttributeValue:
2116 Any a;
2117 if ( importAttributeValue( pChildAtom, a ) )
2119 switch( pChildAtom->getInstance() )
2121 case 1: xAnim->setBy( a ); dump( " by=\"" ); break;
2122 case 2: xAnim->setFrom( a ); dump( " from=\"" ); break;
2123 case 3: xAnim->setTo( a ); dump( " to=\"" ); break;
2124 default:
2125 dump( " unknown_value=\"" );
2128 dump( a );
2129 dump( "\"" );
2132 break;
2133 default:
2134 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
2135 break;
2138 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
2143 // --------------------------------------------------------------------
2145 void AnimationImporter::importAnimateMotionContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2147 Reference< XAnimateMotion > xMotion( xNode, UNO_QUERY );
2149 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateMotion && xMotion.is(), "invalid call to ppt::AnimationImporter::importAnimateMotionContainer()!");
2150 if( pAtom && xMotion.is() )
2152 const Atom* pChildAtom = pAtom->findFirstChildAtom();
2154 while( pChildAtom )
2156 if( !pChildAtom->isContainer() )
2158 if( !pChildAtom->seekToContent() )
2159 break;
2162 switch( pChildAtom->getType() )
2164 case DFF_msofbtAnimateMotionData:
2166 sal_uInt32 nBits, nOrigin;
2167 float fByX, fByY, fFromX, fFromY, fToX, fToY;
2169 mrStCtrl >> nBits >> fByX >> fByY >> fFromX >> fFromY >> fToX >> fToY >> nOrigin;
2171 #ifdef DBG_ANIM_LOG
2172 if( nBits & 1 )
2173 fprintf( mpFile, " by=\"%g,%g\"", (double)fByX, (double)fByY );
2175 if( nBits & 2 )
2176 fprintf( mpFile, " from=\"%g,%g\"", (double)fFromX, (double)fFromY );
2178 if( nBits & 4 )
2179 fprintf( mpFile, " to=\"%g,%g\"", (double)fToX, (double)fToY );
2181 if( nBits & 8 )
2182 fprintf( mpFile, " origin=\"%s\"", (nOrigin == 1) ? "parent" : (nOrigin == 2) ? "layout" : "unknown" );
2184 #endif
2186 break;
2188 case DFF_msofbtAnimAttributeValue:
2190 Any aPath;
2191 if ( importAttributeValue( pChildAtom, aPath ) )
2193 rtl::OUString aStr;
2194 if ( aPath >>= aStr )
2196 aStr = aStr.replace( 'E', ' ' );
2197 aStr = aStr.trim();
2198 aPath <<= aStr;
2199 xMotion->setPath( aPath );
2200 dump( " path=\"" );
2201 dump( aPath );
2202 dump( "\"" );
2206 break;
2208 case DFF_msofbtAnimateTarget:
2209 importAnimateAttributeTargetContainer( pChildAtom, xNode );
2210 break;
2212 default:
2213 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
2214 break;
2217 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
2222 // --------------------------------------------------------------------
2224 void AnimationImporter::importCommandContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2226 Reference< XCommand > xCommand( xNode, UNO_QUERY );
2227 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimCommand && xCommand.is(), "invalid call to ppt::AnimationImporter::importCommandContainer()!");
2228 if( pAtom && xCommand.is() )
2230 sal_Int32 nBits = 0, nType = 0;
2231 Any aValue;
2233 const Atom* pChildAtom = pAtom->findFirstChildAtom();
2235 while( pChildAtom )
2237 if( !pChildAtom->isContainer() )
2239 if( !pChildAtom->seekToContent() )
2240 break;
2243 switch( pChildAtom->getType() )
2245 case DFF_msofbtCommandData:
2247 sal_Int32 nCommandType;
2248 // looks like U1 is a bitset, bit 1 enables the type and bit 2 enables
2249 // a propertyvalue that follows
2250 mrStCtrl >> nBits;
2251 mrStCtrl >> nCommandType;
2253 if( nBits && 1 )
2255 dump( " type=\"%s\"", (nCommandType == 0) ? "event" : ( nCommandType == 1) ? "call" : "verb" );
2258 break;
2260 case DFF_msofbtAnimAttributeValue:
2262 if ( importAttributeValue( pChildAtom, aValue ) )
2264 if( nBits && 2 )
2266 dump( " cmd=\"" );
2267 dump( aValue );
2268 dump( "\"" );
2272 break;
2274 case DFF_msofbtAnimateTarget:
2275 importAnimateAttributeTargetContainer( pChildAtom, xNode );
2276 break;
2278 default:
2279 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
2280 break;
2283 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
2286 if( nBits & 3 )
2288 OUString aParam;
2289 aValue >>= aParam;
2291 sal_Int16 nCommand = EffectCommands::CUSTOM;
2293 NamedValue aParamValue;
2295 switch( nType )
2297 case 0: // event
2298 case 1: // call
2299 if( aParam.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "onstopaudio" ) ) )
2301 nCommand = EffectCommands::STOPAUDIO;
2303 else if( aParam.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("play") ) )
2305 nCommand = EffectCommands::PLAY;
2307 else if( aParam.compareToAscii( RTL_CONSTASCII_STRINGPARAM("playFrom") ) == 0 )
2309 const OUString aMediaTime( aParam.copy( 9, aParam.getLength() - 10 ) );
2310 rtl_math_ConversionStatus eStatus;
2311 double fMediaTime = ::rtl::math::stringToDouble( aMediaTime, (sal_Unicode)('.'), (sal_Unicode)(','), &eStatus, NULL );
2312 if( eStatus == rtl_math_ConversionStatus_Ok )
2314 aParamValue.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("MediaTime"));
2315 aParamValue.Value <<= fMediaTime;
2317 nCommand = EffectCommands::PLAY;
2319 else if( aParam.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("togglePause") ) )
2321 nCommand = EffectCommands::TOGGLEPAUSE;
2323 else if( aParam.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("stop") ) )
2325 nCommand = EffectCommands::STOP;
2327 break;
2328 case 2: // verb
2330 aParamValue.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("Verb"));
2331 aParamValue.Value <<= aParam.toInt32();
2333 nCommand = EffectCommands::VERB;
2335 break;
2338 xCommand->setCommand( nCommand );
2339 if( nCommand == EffectCommands::CUSTOM )
2341 DBG_ERROR("sd::AnimationImporter::importCommandContainer(), unknown command!");
2342 aParamValue.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("UserDefined"));
2343 aParamValue.Value <<= aParam;
2346 if( aParamValue.Value.hasValue() )
2348 Sequence< NamedValue > aParamSeq( &aParamValue, 1 );
2349 xCommand->setParameter( makeAny( aParamSeq ) );
2355 // --------------------------------------------------------------------
2357 void AnimationImporter::importAudioContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2359 Reference< XAudio > xAudio( xNode, UNO_QUERY );
2360 DBG_ASSERT( pAtom && xAudio.is() &&
2361 ( (pAtom->getType() == DFF_msofbtAnimGroup) ||
2362 (pAtom->getType() == DFF_msofbtAnimSubGoup) ), "invalid call to ppt::AnimationImporter::importAudioContainer()!");
2363 if( pAtom && xAudio.is() )
2365 importAnimationEvents( pAtom, xNode );
2366 importAnimationValues( pAtom, xNode );
2367 importAnimationActions( pAtom, xNode );
2369 dump(">\n");
2371 const Atom* pChildAtom = pAtom->findFirstChildAtom();
2373 while( pChildAtom )
2375 if( !pChildAtom->isContainer() )
2377 if( !pChildAtom->seekToContent() )
2378 break;
2381 switch( pChildAtom->getType() )
2383 case DFF_msofbtAnimNode:
2384 case DFF_msofbtAnimEvent:
2385 case DFF_msofbtAnimValue:
2386 case DFF_msofbtAnimAction:
2387 case DFF_msofbtAnimPropertySet:
2388 break;
2390 case DFF_msofbtAnimAttributeValue:
2392 Any aValue;
2393 if ( importAttributeValue( pChildAtom, aValue ) )
2395 dump( " value=\"" );
2396 dump( aValue );
2397 dump( "\"" );
2400 break;
2402 case DFF_msofbtAnimateTargetElement:
2404 sal_Int16 nSubType;
2405 Any aSource;
2406 importTargetElementContainer( pChildAtom, aSource, nSubType );
2407 if( xAudio.is() )
2408 xAudio->setSource( aSource );
2410 break;
2412 default:
2413 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
2414 break;
2417 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
2420 // TODO: What to do with them?
2421 Any aEmpty;
2422 xAudio->setBegin( aEmpty );
2423 xAudio->setEnd( aEmpty );
2427 // --------------------------------------------------------------------
2429 void AnimationImporter::importAnimateScaleContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2431 Reference< XAnimateTransform > xTransform( xNode, UNO_QUERY );
2433 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateScale && xTransform.is(), "invalid call to ppt::AnimationImporter::importAnimateScaleContainer()!");
2434 if( pAtom && xTransform.is() )
2436 xTransform->setTransformType( AnimationTransformType::SCALE );
2438 const Atom* pChildAtom = pAtom->findFirstChildAtom();
2440 while( pChildAtom )
2442 if( !pChildAtom->isContainer() )
2444 if( !pChildAtom->seekToContent() )
2445 break;
2448 switch( pChildAtom->getType() )
2450 case DFF_msofbtAnimateScaleData:
2452 sal_uInt32 nBits, nZoomContents;
2453 float fByX, fByY, fFromX, fFromY, fToX, fToY;
2455 // nBits %001: by, %010: from, %100: to, %1000: zoomContents(bool)
2456 mrStCtrl >> nBits >> fByX >> fByY >> fFromX >> fFromY >> fToX >> fToY >> nZoomContents;
2458 ValuePair aPair;
2459 // 'from' value
2460 if( nBits & 2 )
2462 aPair.First <<= (double)fFromX / 100.0;
2463 aPair.Second <<= (double)fFromY / 100.0;
2464 xTransform->setFrom( makeAny( aPair ) );
2467 // 'to' value
2468 if( nBits & 4 )
2470 aPair.First <<= (double)fToX / 100.0;
2471 aPair.Second <<= (double)fToY / 100.0;
2472 xTransform->setTo( makeAny( aPair ) );
2475 // 'by' value
2476 if( nBits & 1 )
2478 aPair.First <<= (double)fByX / 100.0;
2479 aPair.Second <<= (double)fByY / 100.0;
2481 if( nBits & 2 )
2483 // 'from' value given, import normally
2484 xTransform->setBy( makeAny( aPair ) );
2486 else
2488 // mapping 'by' to 'to', if no 'from' is
2489 // given. This is due to a non-conformity in
2490 // PPT, which exports animateScale effects
2491 // with a sole 'by' value, but with the
2492 // semantics of a sole 'to' animation
2493 xTransform->setTo( makeAny( aPair ) );
2498 #ifdef DBG_ANIM_LOG
2499 if( nBits & 1 )
2500 fprintf( mpFile, " by=\"%g,%g\"", (double)fByX, (double)fByY );
2502 if( nBits & 2 )
2503 fprintf( mpFile, " from=\"%g,%g\"", (double)fFromX, (double)fFromY );
2505 if( nBits & 4 )
2506 fprintf( mpFile, " to=\"%g,%g\"", (double)fToX, (double)fToY );
2508 if( nBits & 8 )
2509 fprintf( mpFile, " zoomContents=\"%s\"", nZoomContents ? "true" : "false" );
2510 #endif
2512 break;
2514 case DFF_msofbtAnimateTarget:
2515 importAnimateAttributeTargetContainer( pChildAtom, xNode );
2516 break;
2518 default:
2519 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
2520 break;
2523 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
2528 // --------------------------------------------------------------------
2530 void AnimationImporter::importAnimateRotationContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2532 Reference< XAnimateTransform > xTransform( xNode, UNO_QUERY );
2534 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateRotation && xTransform.is(), "invalid call to ppt::AnimationImporter::importAnimateRotationContainer()!");
2535 if( pAtom && xTransform.is() )
2537 xTransform->setTransformType( AnimationTransformType::ROTATE );
2539 const Atom* pChildAtom = pAtom->findFirstChildAtom();
2541 while( pChildAtom )
2543 if( !pChildAtom->isContainer() )
2545 if( !pChildAtom->seekToContent() )
2546 break;
2549 switch( pChildAtom->getType() )
2551 case DFF_msofbtAnimateRotationData:
2553 sal_uInt32 nBits, nU1;
2554 float fBy, fFrom, fTo;
2556 // nBits %001: by, %010: from, %100: to, %1000: zoomContents(bool)
2557 mrStCtrl >> nBits >> fBy >> fFrom >> fTo >> nU1;
2559 if( nBits & 1 )
2560 xTransform->setBy( makeAny( (double) fBy ) );
2562 if( nBits & 2 )
2563 xTransform->setFrom( makeAny( (double) fFrom ) );
2565 if( nBits & 4 )
2566 xTransform->setTo( makeAny( (double) fTo ) );
2568 #ifdef DBG_ANIM_LOG
2569 if( nBits & 1 )
2570 fprintf( mpFile, " by=\"%g\"", (double)fBy );
2572 if( nBits & 2 )
2573 fprintf( mpFile, " from=\"%g\"", (double)fFrom );
2575 if( nBits & 4 )
2576 fprintf( mpFile, " to=\"%g\"", (double)fTo );
2578 if( nU1 )
2579 fprintf( mpFile, " rotation_1=\"%ld\"", nU1 );
2580 #endif
2582 break;
2584 case DFF_msofbtAnimateTarget:
2585 importAnimateAttributeTargetContainer( pChildAtom, xNode );
2586 break;
2588 default:
2589 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
2590 break;
2593 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
2597 // --------------------------------------------------------------------
2599 bool AnimationImporter::importAttributeNamesContainer( const Atom* pAtom, OUString& rAttributeNames )
2601 OUStringBuffer aNames;
2603 DBG_ASSERT( pAtom && (pAtom->getType() == DFF_msofbtAnimateAttributeNames), "invalid call to ppt::AnimationImporter::importAttributeName()!" );
2604 if( pAtom )
2606 const Atom* pAttributeValueAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimAttributeValue );
2608 while( pAttributeValueAtom )
2610 Any aAny;
2611 if ( importAttributeValue( pAttributeValueAtom, aAny ) )
2613 OUString aName;
2614 if( aAny >>= aName )
2616 if( aNames.getLength() )
2617 aNames.append( (sal_Unicode)';' );
2619 aNames.append( aName );
2622 else
2624 DBG_ERROR( "error during ppt::AnimationImporter::importAttributeName()!" );
2627 pAttributeValueAtom = pAtom->findNextChildAtom( DFF_msofbtAnimAttributeValue, pAttributeValueAtom );
2631 rAttributeNames = aNames.makeStringAndClear();
2632 return true;
2635 // --------------------------------------------------------------------
2637 void AnimationImporter::importAnimationValues( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2639 DBG_ASSERT( pAtom, "invalid call to ppt::AnimationImporter::importAnimationValues()!" );
2641 if( pAtom )
2643 const Atom* pValueAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimValue );
2645 while( pValueAtom && pValueAtom->seekToContent() )
2647 sal_uInt32 nType;
2648 mrStCtrl >> nType;
2649 switch( nType )
2651 case 0:
2653 float fRepeat;
2654 mrStCtrl >> fRepeat;
2655 xNode->setRepeatCount( (fRepeat < ((float)3.40282346638528860e+38)) ? makeAny( (double)fRepeat ) : makeAny( Timing_INDEFINITE ) );
2657 #ifdef DBG_ANIM_LOG
2658 if( (fRepeat < ((float)3.40282346638528860e+38)) )
2660 dump( " repeat=\"%g\"", (double)fRepeat );
2662 else
2664 dump( " repeat=\"indefinite\"" );
2666 #endif
2668 break;
2670 case 3:
2672 float faccelerate;
2673 mrStCtrl >> faccelerate;
2674 xNode->setAcceleration( faccelerate );
2675 dump( " accelerate=\"%g\"", (double)faccelerate );
2677 break;
2679 case 4:
2681 float fdecelerate;
2682 mrStCtrl >> fdecelerate;
2683 xNode->setDecelerate( fdecelerate );
2684 dump( " decelerate=\"%g\"", (double)fdecelerate );
2686 break;
2688 case 5:
2690 sal_Int32 nAutoreverse;
2691 mrStCtrl >> nAutoreverse;
2692 xNode->setAutoReverse( nAutoreverse != 0 );
2693 dump( " autoreverse=\"%#lx\"", nAutoreverse );
2695 break;
2697 default:
2699 sal_uInt32 nUnknown;
2700 mrStCtrl >> nUnknown;
2701 #ifdef DBG_ANIM_LOG
2702 fprintf(mpFile, " attribute_%d=\"%#lx\"", nType, nUnknown );
2703 #endif
2705 break;
2708 pValueAtom = pAtom->findNextChildAtom( DFF_msofbtAnimValue, pValueAtom );
2713 // --------------------------------------------------------------------
2715 void AnimationImporter::importAnimateKeyPoints( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2717 Reference< XAnimate > xAnim( xNode, UNO_QUERY );
2719 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimKeyPoints && xAnim.is(), "invalid call to ppt::AnimationImporter::importAnimateKeyPoints()!" );
2721 if( pAtom && xAnim.is() )
2723 // first count keytimes
2724 const Atom* pIter = NULL;
2725 int nKeyTimes = 0;
2727 while( (pIter = pAtom->findNextChildAtom( DFF_msofbtAnimKeyTime, pIter )) != 0 )
2728 nKeyTimes++;
2730 Sequence< double > aKeyTimes( nKeyTimes );
2731 Sequence< Any > aValues( nKeyTimes );
2732 OUString aFormula;
2734 pIter = pAtom->findFirstChildAtom(DFF_msofbtAnimKeyTime);
2735 int nKeyTime;
2736 sal_Int32 nTemp;
2737 for( nKeyTime = 0; (nKeyTime < nKeyTimes) && pIter; nKeyTime++ )
2739 if( pIter->seekToContent() )
2741 mrStCtrl >> nTemp;
2742 double fTemp = (double)nTemp / 1000.0;
2743 aKeyTimes[nKeyTime] = fTemp;
2745 const Atom* pValue = pAtom->findNextChildAtom(pIter);
2746 if( pValue && pValue->getType() == DFF_msofbtAnimAttributeValue )
2748 Any aValue1, aValue2;
2749 if( importAttributeValue( pValue, aValue1 ) )
2751 pValue = pAtom->findNextChildAtom(pValue);
2752 if( pValue && pValue->getType() == DFF_msofbtAnimAttributeValue )
2753 importAttributeValue( pValue, aValue2 );
2755 bool bCouldBeFormula = false;
2756 bool bHasValue = aValue2.hasValue();
2757 if( bHasValue )
2759 if( aValue2.getValueType() == ::getCppuType((const OUString*)0) )
2761 OUString aTest;
2762 aValue2 >>= aTest;
2763 bHasValue = aTest.getLength() != 0;
2764 bCouldBeFormula = true;
2768 if( bHasValue && bCouldBeFormula && (aValue1.getValueType() == ::getCppuType((const double*)0)) )
2770 aValue2 >>= aFormula;
2771 bHasValue = false;
2774 if( bHasValue )
2776 aValues[nKeyTime] = makeAny( ValuePair( aValue1, aValue2 ) );
2778 else
2780 aValues[nKeyTime] = aValue1;
2785 pIter = pAtom->findNextChildAtom(DFF_msofbtAnimKeyTime, pIter);
2788 #ifdef DBG_ANIM_LOG
2789 dump( " keyTimes=\"" );
2790 for( int i=0; i<nKeyTimes; ++i )
2791 dump( "%f;", aKeyTimes[i] );
2793 if( aFormula.getLength() )
2795 dump( "formula=\"%s", aFormula );
2798 dump( "\" values=\"" );
2799 double nVal;
2800 OUString aStr;
2801 for( int i=0; i<nKeyTimes; ++i )
2803 if( i != 0 )
2804 dump( ";" );
2806 if( aValues[i] >>= aStr )
2807 dump( "%s",
2808 ::rtl::OUStringToOString( aStr,
2809 RTL_TEXTENCODING_ASCII_US ).getStr() );
2810 else if( aValues[i] >>= nVal )
2811 dump( "%f", nVal );
2812 else
2814 ValuePair aValuePair;
2816 if( aValues[i] >>= aValuePair )
2818 if( aValuePair.First >>= aStr )
2819 dump( "%s",
2820 ::rtl::OUStringToOString( aStr,
2821 RTL_TEXTENCODING_ASCII_US ).getStr() );
2822 else if( aValuePair.First >>= nVal )
2823 dump( "%f", nVal );
2824 else
2825 dump( "%X", (sal_Int32)&aValuePair.First );
2827 if( aValuePair.Second >>= aStr )
2828 dump( ",%s",
2829 ::rtl::OUStringToOString( aStr,
2830 RTL_TEXTENCODING_ASCII_US ).getStr() );
2831 else if( aValuePair.Second >>= nVal )
2832 dump( ",%f", nVal );
2833 else
2834 dump( ",%X", (sal_Int32)&aValuePair.Second );
2838 dump( "\"" );
2839 #endif
2841 xAnim->setKeyTimes( aKeyTimes );
2842 xAnim->setValues( aValues );
2843 xAnim->setFormula( aFormula );
2847 // --------------------------------------------------------------------
2849 bool AnimationImporter::importAttributeValue( const Atom* pAtom, Any& rAny )
2851 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimAttributeValue, "invalid call to ppt::AnimationImporter::importAttributeValue()!" );
2853 bool bOk = false;
2855 if( pAtom && pAtom->seekToContent() )
2857 sal_uInt32 nRecLen = pAtom->getLength();
2858 if ( nRecLen >= 1 )
2860 sal_Int8 nType;
2861 mrStCtrl >> nType;
2862 switch( nType )
2864 case DFF_ANIM_PROP_TYPE_BYTE :
2866 if ( nRecLen == 2 )
2868 sal_uInt8 nByte;
2869 mrStCtrl >> nByte;
2870 rAny <<= nByte;
2872 bOk = true;
2875 break;
2877 case DFF_ANIM_PROP_TYPE_INT32 :
2879 if ( nRecLen == 5 )
2881 sal_uInt32 nInt32;
2882 mrStCtrl >> nInt32;
2883 rAny <<= nInt32;
2885 bOk = true;
2888 break;
2890 case DFF_ANIM_PROP_TYPE_FLOAT:
2892 if( nRecLen == 5 )
2894 float fFloat;
2895 mrStCtrl >> fFloat;
2896 rAny <<= (double)fFloat;
2898 bOk = true;
2901 break;
2903 case DFF_ANIM_PROP_TYPE_UNISTRING :
2905 if ( ( nRecLen & 1 ) && ( nRecLen > 1 ) )
2907 String aString;
2908 mpPPTImport->MSDFFReadZString( mrStCtrl, aString, nRecLen - 1, sal_True );
2909 rtl::OUString aOUString( aString );
2910 rAny <<= aOUString;
2912 bOk = true;
2915 break;
2920 DBG_ASSERT( bOk, "invalid value inside ppt::AnimationImporter::importAttributeValue()!" );
2921 return bOk;
2924 // --------------------------------------------------------------------
2926 void AnimationImporter::importAnimationEvents( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2928 DBG_ASSERT( xNode.is() && pAtom, "invalid call to ppt::AnimationImporter::importAnimationEvents()!" );
2930 Any aBegin, aEnd, aNext, aPrev;
2932 const Atom* pEventAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimEvent );
2933 while( pEventAtom )
2935 Any* pEvents = NULL;
2937 switch( pEventAtom->getInstance() )
2939 case 1: pEvents = &aBegin; break;
2940 case 2: pEvents = &aEnd; break;
2941 case 3: pEvents = &aNext; break;
2942 case 4: pEvents = &aPrev; break;
2945 if( pEvents )
2947 Event aEvent;
2948 aEvent.Trigger = EventTrigger::NONE;
2949 aEvent.Repeat = 0;
2951 const Atom* pChildAtom = pEventAtom->findFirstChildAtom();
2953 while( pChildAtom && pChildAtom->seekToContent() )
2955 switch( pChildAtom->getType() )
2957 case DFF_msofbtAnimTrigger:
2959 sal_Int32 nU1, nTrigger, nU3, nBegin;
2960 mrStCtrl >> nU1;
2961 mrStCtrl >> nTrigger;
2962 mrStCtrl >> nU3;
2963 mrStCtrl >> nBegin;
2965 switch( nTrigger )
2967 case 0: aEvent.Trigger = EventTrigger::NONE; break;
2968 case 1: aEvent.Trigger = EventTrigger::ON_BEGIN; break;
2969 case 2: aEvent.Trigger = EventTrigger::ON_END; break;
2970 case 3: aEvent.Trigger = EventTrigger::BEGIN_EVENT; break;
2971 case 4: aEvent.Trigger = EventTrigger::END_EVENT; break;
2972 case 5: aEvent.Trigger = EventTrigger::ON_CLICK; break;
2973 case 6: aEvent.Trigger = EventTrigger::ON_DBL_CLICK; break;
2974 case 7: aEvent.Trigger = EventTrigger::ON_MOUSE_ENTER; break;
2975 case 8: aEvent.Trigger = EventTrigger::ON_MOUSE_LEAVE; break;
2976 case 9: aEvent.Trigger = EventTrigger::ON_NEXT; break;
2977 case 10: aEvent.Trigger = EventTrigger::ON_PREV; break;
2978 case 11: aEvent.Trigger = EventTrigger::ON_STOP_AUDIO; break;
2981 if( (nBegin != 0) || (aEvent.Trigger == EventTrigger::NONE) )
2982 aEvent.Offset = (nBegin == -1) ? makeAny( Timing_INDEFINITE ) : makeAny( (double)(nBegin / 1000.0) );
2984 break;
2985 case DFF_msofbtAnimateTargetElement:
2987 sal_Int16 nSubType;
2988 importTargetElementContainer( pChildAtom, aEvent.Source, nSubType );
2990 break;
2991 default:
2993 DBG_ERROR("unknown atom inside ppt::AnimationImporter::importAnimationEvents()!");
2997 pChildAtom = pEventAtom->findNextChildAtom( pChildAtom );
3000 *pEvents = addToSequence( *pEvents, (aEvent.Trigger == EventTrigger::NONE) ? aEvent.Offset : makeAny( aEvent ) );
3003 pEventAtom = pAtom->findNextChildAtom( DFF_msofbtAnimEvent, pEventAtom );
3006 xNode->setBegin( aBegin );
3007 xNode->setEnd( aEnd );
3008 // TODO: xNode->setNext( aNext );
3009 // TODO: xNode->setPrev( aNext );
3011 #ifdef DBG_ANIM_LOG
3012 if( aBegin.hasValue() )
3014 dump( " begin=\"" );
3015 dump( aBegin );
3016 dump( "\"" );
3019 if( aEnd.hasValue() )
3021 dump( " end=\"" );
3022 dump( aEnd );
3023 dump( "\"" );
3026 if( aNext.hasValue() )
3028 dump( " next=\"" );
3029 dump( aNext );
3030 dump( "\"" );
3033 if( aPrev.hasValue() )
3035 dump( " prev=\"" );
3036 dump( aPrev );
3037 dump( "\"" );
3039 #endif
3042 // --------------------------------------------------------------------
3044 void AnimationImporter::importAnimationActions( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
3046 DBG_ASSERT( pAtom && xNode.is(), "invalid call to ppt::AnimationImporter::importAnimationActions()!");
3048 if( pAtom )
3050 const Atom* pActionAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimAction );
3052 if( pActionAtom && pActionAtom->seekToContent() )
3054 sal_Int32 nConcurrent, nNextAction, nEndSync, nU4, nU5;
3055 mrStCtrl >> nConcurrent;
3056 mrStCtrl >> nNextAction;
3057 mrStCtrl >> nEndSync;
3058 mrStCtrl >> nU4;
3059 mrStCtrl >> nU5;
3061 if( nEndSync == 1 )
3062 xNode->setEndSync( makeAny( AnimationEndSync::ALL ) );
3064 #ifdef DBG_ANIM_LOG
3065 dump( " concurrent=\"%s\"", nConcurrent == 0 ? "disabled" : (nConcurrent == 1 ? "enabled" : "unknown") );
3067 dump( " nextAction=\"%s\"", nNextAction == 0 ? "none" : (nNextAction == 1 ? "seek" : "unknown") );
3069 if( nEndSync != 0 )
3071 dump( " endSync=\"%s\"", nEndSync == 1 ? "all" : "unknown" );
3074 dump( " action_4=\"%#lx\"", nU4 );
3075 dump( " action_5=\"%#lx\"", nU5 );
3076 #endif
3081 // --------------------------------------------------------------------
3083 sal_Int32 AnimationImporter::importTargetElementContainer( const Atom* pAtom, Any& rTarget, sal_Int16& rSubType )
3085 rSubType = ShapeAnimationSubType::AS_WHOLE;
3086 sal_Int32 nRefMode = -1;
3088 DBG_ASSERT( pAtom && (pAtom->getType() == DFF_msofbtAnimateTargetElement), "invalid call to ppt::AnimationImporter::importTargetElementContainer()!" );
3089 if( pAtom )
3091 const Atom* pChildAtom = pAtom->findFirstChildAtom();
3092 while( pChildAtom && pChildAtom->seekToContent() )
3094 switch( pChildAtom->getType() )
3096 case DFF_msofbtAnimReference:
3098 sal_Int32 nRefType,nRefId;
3099 sal_Int32 begin,end;
3100 mrStCtrl >> nRefMode;
3101 mrStCtrl >> nRefType;
3102 mrStCtrl >> nRefId;
3103 mrStCtrl >> begin;
3104 mrStCtrl >> end;
3106 switch( nRefType )
3108 case 1: // shape
3110 SdrObject* pSdrObject = mpPPTImport->getShapeForId( nRefId );
3111 if( pSdrObject == NULL )
3112 break;
3114 rTarget <<= pSdrObject->getUnoShape();
3116 switch( nRefMode )
3118 // default case 0: rSubType = ShapeAnimationSubType::AS_WHOLE; break;
3119 case 6: rSubType = ShapeAnimationSubType::ONLY_BACKGROUND; break;
3120 case 8: rSubType = ShapeAnimationSubType::ONLY_TEXT; break;
3121 case 2: // one paragraph
3123 if( ((begin == -1) && (end == -1)) || !pSdrObject->ISA( SdrTextObj ) )
3124 break;
3126 SdrTextObj* pTextObj = static_cast< SdrTextObj* >( pSdrObject );
3128 const OutlinerParaObject* pOPO = pTextObj->GetOutlinerParaObject();
3129 if( pOPO == NULL )
3130 break;
3132 const EditTextObject& rEditTextObject = pOPO->GetTextObject();
3134 const USHORT nParaCount = rEditTextObject.GetParagraphCount();
3136 USHORT nPara = 0;
3138 while( (nPara < nParaCount) && (begin > 0) )
3140 sal_Int32 nParaLength = rEditTextObject.GetText( nPara ).Len() + 1;
3141 begin -= nParaLength;
3142 end -= nParaLength;
3143 nPara++;
3146 if( nPara < nParaCount )
3148 ParagraphTarget aParaTarget;
3149 rTarget >>= aParaTarget.Shape;
3150 aParaTarget.Paragraph = nPara;
3151 rTarget = makeAny( aParaTarget );
3153 rSubType = ShapeAnimationSubType::ONLY_TEXT;
3154 dump( " paragraph %d,", (sal_Int32)nPara);
3155 dump( " %d characters", (sal_Int32)end );
3160 break;
3162 case 2: // sound
3164 OUString aSoundURL( ((ImplSdPPTImport*)mpPPTImport)->ReadSound( nRefId ) );
3165 rTarget <<= aSoundURL;
3166 dump( " srcRef=\"%s\"", aSoundURL );
3168 break;
3169 case 3: // audio object
3170 case 4: // video object
3172 SdrObject* pSdrObject = mpPPTImport->getShapeForId( nRefId );
3173 if( pSdrObject == NULL )
3174 break;
3176 rTarget <<= pSdrObject->getUnoShape();
3178 break;
3179 default:
3180 DBG_ERROR("unknown reference type");
3184 // dump( " ref=\"%s\"", nRefMode == 3 ? "source" : ( nRefMode == 0 ? "target" : "unknown" ) );
3185 // dump( " type=\"%s\"", nRefType == 1 ? "shape" : ( nRefType == 2 ? "sound": "unknown" ) );
3186 // dump( " id=\"%lu\"", (sal_Int32)nRefId );
3187 #ifdef DBG_ANIM_LOG
3188 if((begin != -1) || (end != -1) )
3190 // dump( " text_begin=\"%ld\"", begin );
3191 // dump( " text_end=\"%ld\"", end );
3193 #endif
3195 break;
3196 case 0x2b01:
3198 sal_Int32 nU1;
3199 mrStCtrl >> nU1;
3201 // HINT: nU1 == 1 : target document. ?
3202 // dump( " unknown_0x2b01=\"%#lx\"", nU1 );
3204 break;
3205 default:
3206 DBG_ERROR("unknwon atom inside ppt::AnimationImporter::importTargetElementContainer()!");
3207 break;
3210 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
3215 return nRefMode;
3218 // --------------------------------------------------------------------
3220 void AnimationImporter::importPropertySetContainer( const Atom* pAtom, PropertySet& rSet )
3222 DBG_ASSERT( pAtom && (pAtom->getType() == DFF_msofbtAnimPropertySet), "invalid call to ppt::AnimationImporter::importPropertySetContainer()!" );
3224 if( pAtom )
3226 const Atom* pChildAtom = pAtom->findFirstChildAtom();
3227 while( pChildAtom )
3229 if( pChildAtom->getType() == DFF_msofbtAnimAttributeValue )
3231 Any aAny;
3232 importAttributeValue( pChildAtom, aAny );
3233 rSet.maProperties[ pChildAtom->getInstance() ] = aAny;
3235 else
3237 DBG_ERROR("unknwon atom inside ppt::AnimationImporter::importPropertySetContainer()!");
3240 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
3245 // ====================================================================
3247 #ifdef DBG_ANIM_LOG
3248 void AnimationImporter::dump_atom_header( const Atom* pAtom, bool bOpen, bool bAppend )
3250 if( pAtom )
3252 const char* pTitle;
3254 bool bUnknown = false;
3256 switch( pAtom->getType() )
3258 case DFF_msofbtAnimEvent: pTitle = "AnimEvent"; break;
3259 case DFF_msofbtAnimTrigger: pTitle = "AnimTrigger"; break;
3260 case DFF_msofbtAnimateMotion: pTitle = "AnimateMotion"; break;
3261 case DFF_msofbtAnimPropertySet: pTitle = "AnimPropertySet"; break;
3262 case DFF_msofbtAnimateAttributeNames: pTitle = "AnimAttributeName"; break;
3263 case DFF_msofbtAnimAttributeValue: pTitle = "AnimAttributeValue"; break;
3264 case DFF_msofbtAnimGroup: pTitle = "AnimGroup"; break;
3265 case DFF_msofbtAnimNode: pTitle = "AnimNode"; break;
3266 case DFF_msofbtAnimValue: pTitle = "AnimValue"; break;
3267 case DFF_msofbtAnimateFilter: pTitle = "animateFilter"; break;
3268 case DFF_msofbtAnimate: pTitle = "animate"; break;
3269 case DFF_msofbtAnimateSet: pTitle = "set"; break;
3270 case DFF_msofbtAnimKeyTime: pTitle = "AnimKeyTime"; break;
3271 case DFF_msofbtAnimKeyPoints: pTitle = "AnimKeyPoints"; break;
3272 case DFF_msofbtAnimReference: pTitle = "AnimReference"; break;
3273 case DFF_msofbtAnimateTargetElement: pTitle = "AnimTargetElementContainer"; break;
3274 case DFF_msofbtAnimAction: pTitle = "AnimAction"; break;
3275 case DFF_msofbtAnimCommand: pTitle = "AnimCommand"; break;
3276 case DFF_msofbtAnimateTarget: pTitle = "TransformationTarget"; break;
3277 case DFF_msofbtAnimateTargetSettings: pTitle = "TransformationTargetSettings"; break;
3278 case DFF_msofbtAnimIteration: pTitle = "iterate"; break;
3279 case DFF_msofbtAnimateColorData: pTitle = "colorData"; break;
3280 case DFF_msofbtAnimateScaleData: pTitle = "scaleData"; break;
3281 case DFF_msofbtAnimateSetData: pTitle = "setData"; break;
3283 default:
3285 static char buffer[128];
3286 sprintf( buffer, "unknown_%#x", pAtom->getType() );
3287 pTitle = buffer;
3291 if( bOpen )
3293 fprintf(mpFile, "<%s", pTitle );
3295 fprintf(mpFile, " instance=\"%hu\"%s",
3296 pAtom->getInstance(),
3297 bAppend ? "" : ">\n");
3299 else
3301 if( bAppend )
3302 fprintf(mpFile,"/>\n");
3303 else
3304 fprintf(mpFile, "</%s>\n", pTitle );
3309 // --------------------------------------------------------------------
3311 void AnimationImporter::dump( UINT32 nLen, bool bNewLine )
3313 char * faul = "0123456789abcdef";
3315 UINT32 i = 0;
3316 int b = 0;
3317 sal_Int8 nData;
3319 for( i = 0; i < nLen; i++ )
3321 mrStCtrl >> nData;
3323 fprintf( mpFile, "%c%c ", faul[ (nData >> 4) & 0x0f ], faul[ nData & 0x0f ] );
3325 b++;
3326 if( bNewLine && (b == 32) )
3328 fprintf(mpFile,"\n");
3329 b = 0;
3332 if( (b != 0) && bNewLine )
3333 fprintf(mpFile,"\n");
3336 // --------------------------------------------------------------------
3338 void AnimationImporter::dump_atom( const Atom* pAtom, bool bNewLine )
3340 if( pAtom )
3342 if( pAtom->isContainer() )
3344 const Atom* pChildAtom = pAtom->findFirstChildAtom();
3345 while( pChildAtom )
3347 if( pChildAtom->getType() == DFF_msofbtAnimAttributeValue )
3349 fprintf(mpFile, "<attributeValue instance=\"%hu\"", pChildAtom->getInstance() );
3351 Any aValue;
3352 if( importAttributeValue( pChildAtom, aValue ) )
3354 sal_Int32 nInt;
3355 rtl::OUString aString;
3356 double fDouble;
3358 if( aValue >>= nInt )
3360 fprintf(mpFile, " value=\"%ld\"", nInt );
3362 else if( aValue >>= aString )
3364 UniString aTmp( aString );
3365 ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 );
3366 fprintf(mpFile, " value=\"%s\"", aStr.GetBuffer() );
3368 else if( aValue >>= fDouble )
3370 fprintf(mpFile, " value=\"%g\"", fDouble );
3373 else
3375 if( pChildAtom->seekToContent() )
3377 fprintf(mpFile, " value=\"" );
3378 dump_atom( pChildAtom, false );
3379 fprintf(mpFile, "\"");
3383 fprintf(mpFile, "/>\n" );
3385 else
3387 dump_atom_header( pChildAtom, true, pChildAtom->getType() == DFF_msofbtAnimAttributeValue );
3388 dump_atom( pChildAtom );
3389 dump_atom_header( pChildAtom, false, pChildAtom->getType() == DFF_msofbtAnimAttributeValue );
3392 pChildAtom = pAtom->findNextChildAtom(pChildAtom);
3395 else if( pAtom->seekToContent() )
3397 dump( pAtom->getLength(), bNewLine );
3402 // --------------------------------------------------------------------
3404 void AnimationImporter::dump_anim_group( const Atom* pAtom, const AnimationNode& rNode, const PropertySet& rSet, bool bOpen )
3406 fprintf( mpFile, bOpen ? "<" : "</" );
3408 switch( rNode.mnGroupType )
3410 case mso_Anim_GroupType_PAR:
3411 fprintf( mpFile, "par" );
3412 break;
3413 case mso_Anim_GroupType_SEQ:
3414 fprintf( mpFile, "seq" );
3415 break;
3416 case mso_Anim_GroupType_NODE:
3417 switch( rNode.mnNodeType )
3419 case mso_Anim_Behaviour_FILTER:
3420 fprintf( mpFile, "animateFilter" );
3421 break;
3422 case mso_Anim_Behaviour_ANIMATION:
3423 if( pAtom->hasChildAtom( DFF_msofbtAnimateSet ) )
3424 fprintf( mpFile, "set" );
3425 else if( pAtom->hasChildAtom( DFF_msofbtAnimateColor ) )
3426 fprintf( mpFile, "animateColor" );
3427 else if( pAtom->hasChildAtom( DFF_msofbtAnimateScale ) )
3428 fprintf( mpFile, "animateScale" );
3429 else if( pAtom->hasChildAtom( DFF_msofbtAnimateRotation ) )
3430 fprintf( mpFile, "animateRotation" );
3431 else if( pAtom->hasChildAtom( DFF_msofbtAnimateMotion ) )
3432 fprintf( mpFile, "animateMotion" );
3433 else if( pAtom->hasChildAtom( DFF_msofbtAnimCommand ) )
3434 fprintf( mpFile, "command" );
3435 else
3436 fprintf( mpFile, "animation" );
3437 break;
3438 default:
3440 fprintf( mpFile, "unknown_node_%#lx", rNode.mnNodeType );
3442 break;
3444 break;
3445 case mso_Anim_GroupType_MEDIA:
3446 fprintf( mpFile, "media" );
3447 break;
3448 default:
3449 fprintf( mpFile, "unknown_group_%#lx", rNode.mnGroupType );
3450 break;
3453 if( bOpen )
3455 dump( rNode );
3456 dump( rSet );
3459 fprintf(mpFile,">\n");
3462 void AnimationImporter::dump( const AnimationNode& rNode )
3464 // dump animation node
3465 if( rNode.mnRestart != 0 )
3467 fprintf(mpFile," restart=\"%s\"",
3468 rNode.mnRestart == 1 ? "always" : (rNode.mnRestart == 2 ? "whenOff" : (rNode.mnRestart == 3 ? "never" : "unknown")) );
3471 if( rNode.mnFill )
3473 fprintf(mpFile," fill=\"%s\"",
3474 rNode.mnFill == 1 ? "remove" : (rNode.mnFill == 3 ? "hold" : (rNode.mnFill == 2 ? "freeze" : "unknown")) );
3477 if( rNode.mnDuration > 0 )
3479 double fSeconds = rNode.mnDuration;
3480 fSeconds /= 1000.0;
3481 fprintf(mpFile, " dur=\"%g\"", fSeconds);
3483 else if( rNode.mnDuration < 0 )
3485 fprintf(mpFile, " dur=\"indefinite\"" );
3488 if( rNode.mnU1 ) fprintf(mpFile," u1=\"%#lx\"", rNode.mnU1);
3489 if( rNode.mnU3 ) fprintf(mpFile," u3=\"%#lx\"", rNode.mnU3);
3490 if( rNode.mnU4 ) fprintf(mpFile," u4=\"%#lx\"", rNode.mnU4);
3493 void AnimationImporter::dump( Any& rAny )
3495 Sequence< Any > aSeq;
3496 sal_Int32 nInt;
3497 double fDouble;
3498 OUString aString;
3499 sal_Bool bBool;
3500 Event aEvent;
3501 Timing aTiming;
3503 if( rAny >>= aSeq )
3505 const sal_Int32 nSize = aSeq.getLength();
3506 sal_Int32 nIndex = 0;
3507 while( nIndex < nSize )
3509 dump( aSeq[nIndex++] );
3510 if(nIndex < nSize)
3511 fprintf( mpFile, "," );
3514 else if( rAny >>= aString )
3516 UniString aTmp(aString);
3517 ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 );
3518 fprintf( mpFile, "%s", aStr.GetBuffer() );
3520 else if( rAny >>= nInt )
3522 fprintf( mpFile, "%ld", nInt );
3524 else if( rAny >>= bBool )
3526 fprintf( mpFile, "%s", bBool ? "true" : "false" );
3528 else if( rAny >>= fDouble )
3530 fprintf( mpFile, "%g", fDouble );
3532 else if( rAny >>= aTiming )
3534 fprintf( mpFile, "%s", aTiming == (Timing_INDEFINITE) ? "indefinite" : "media" );
3536 else if( rAny >>= aEvent )
3538 static const char* triggers[] =
3540 "none","onbegin","onend","begin",
3541 "end","onclick","ondoubleclick","onmouseenter",
3542 "onmouseleave","onpptnext","onpptprev","onstopaudio"
3545 if( aEvent.Trigger != EventTrigger::NONE )
3547 if( aEvent.Source.hasValue() )
3549 dump_target( aEvent.Source );
3550 dump( "." );
3553 dump( triggers[ aEvent.Trigger ] );
3556 if( aEvent.Offset.hasValue() )
3558 double fOffset;
3559 if( aEvent.Offset >>= fOffset )
3560 fprintf( mpFile, "%g", fOffset );
3561 else
3562 dump( "indefinite" );
3567 void AnimationImporter::dump( const PropertySet& rSet )
3569 // dump property set
3571 map< sal_Int32, Any >::const_iterator aIter( rSet.maProperties.begin() );
3572 const map< sal_Int32, Any >::const_iterator aEnd( rSet.maProperties.end() );
3573 while( aIter != aEnd )
3575 bool bKnown = false;
3577 const sal_Int32 nInstance = (*aIter).first;
3578 Any aAny( (*aIter).second );
3580 switch ( nInstance )
3582 case DFF_ANIM_COLORSPACE:
3584 sal_Int32 nColorSpace;
3585 if( aAny >>= nColorSpace )
3587 fprintf( mpFile, " colorSpace=\"%s\"", (nColorSpace == 0) ? "rgb" : (nColorSpace == 1) ? "hsl" : "unknown" );
3588 bKnown = true;
3591 break;
3593 case DFF_ANIM_DIRECTION:
3594 // case DFF_ANIM_MASTERREL:
3596 sal_Bool bDirection;
3597 if( aAny >>= bDirection )
3599 fprintf( mpFile, " direction=\"%s\"", bDirection ? "cclockwise" : "clockwise" );
3600 bKnown = true;
3602 else
3604 sal_Int32 nMasterRel;
3605 if( aAny >>= nMasterRel )
3607 fprintf( mpFile, " direction=\"%s\"", nMasterRel == 0 ? "sameClick" : ( nMasterRel == 2 ? "nextClick" : "lastClick" ) );
3608 bKnown = true;
3612 break;
3614 case DFF_ANIM_OVERRIDE: // TODO
3616 sal_Int32 nOverride;
3617 if( aAny >>= nOverride )
3619 fprintf( mpFile, " override=\"%s\"", (nOverride == 1) ? "childStyle" : (nOverride == 0) ? "normal" : "unknown" );
3620 bKnown = true;
3623 break;
3625 case DFF_ANIM_PATH_EDIT_MODE:
3627 sal_Bool bPathEditMode;
3628 if( aAny >>= bPathEditMode )
3630 fprintf( mpFile, " pptPathEditMode=\"%s\"", bPathEditMode ? "relative" : "fixed" );
3631 bKnown = true;
3634 break;
3636 case DFF_ANIM_PRESET_ID :
3638 sal_Int32 nPresetId ;
3639 if( aAny >>= nPresetId )
3641 fprintf(mpFile, " presetid=\"%ld\"", nPresetId );
3642 bKnown = true;
3645 break;
3647 case DFF_ANIM_PRESET_SUB_TYPE :
3649 sal_Int32 nPointsType ;
3650 if( aAny >>= nPointsType )
3652 fprintf(mpFile, " presetSubType=\"%ld\"", nPointsType );
3653 bKnown = true;
3656 break;
3658 case DFF_ANIM_PRESET_CLASS :
3660 sal_Int32 nPresetClass;
3661 if ( aAny >>= nPresetClass )
3663 const char* pMode;
3664 switch( nPresetClass )
3666 case DFF_ANIM_PRESS_CLASS_USER_DEFINED: pMode = "userdefined"; break;
3667 case DFF_ANIM_PRESS_CLASS_ENTRANCE: pMode = "entrance"; break;
3668 case DFF_ANIM_PRESS_CLASS_EXIT: pMode = "exit"; break;
3669 case DFF_ANIM_PRESS_CLASS_EMPHASIS: pMode = "emphasis"; break;
3670 case DFF_ANIM_PRESS_CLASS_MOTIONPATH: pMode = "motionpath"; break;
3671 case DFF_ANIM_PRESS_CLASS_OLE_ACTION: pMode = "oleaction"; break;
3672 case DFF_ANIM_PRESS_CLASS_MEDIACALL: pMode = "mediacall"; break;
3673 default:
3675 static char buffer[128];
3676 sprintf( buffer, "%ld", nPresetClass );
3677 pMode = buffer;
3679 break;
3682 fprintf(mpFile, " class=\"%s\"", pMode);
3683 bKnown = true;
3686 break;
3688 case DFF_ANIM_NODE_TYPE :
3690 sal_Int32 nNodeType;
3691 if ( aAny >>= nNodeType )
3693 const char* pNode;
3694 switch( nNodeType )
3696 case DFF_ANIM_NODE_TYPE_ON_CLICK: pNode = "onclick"; break;
3697 case DFF_ANIM_NODE_TYPE_WITH_PREVIOUS: pNode = "withprevious"; break;
3698 case DFF_ANIM_NODE_TYPE_AFTER_PREVIOUS: pNode = "afterprevious"; break;
3699 case DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE: pNode = "mainsequence"; break;
3700 case DFF_ANIM_NODE_TYPE_TIMING_ROOT: pNode = "timingroot"; break;
3701 case DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ:pNode = "interactivesequence"; break;
3702 default :
3704 static char buffer[128];
3705 sprintf( buffer, "%ld", nNodeType );
3706 pNode = buffer;
3708 break;
3711 fprintf(mpFile, " nodeType=\"%s\"", pNode);
3712 bKnown = true;
3715 break;
3717 case DFF_ANIM_GROUP_ID:
3719 sal_Int32 nGroupId;
3720 if ( aAny >>= nGroupId )
3722 fprintf( mpFile, " groupId=\"%ld\"", nGroupId );
3723 bKnown = true;
3726 break;
3728 case DFF_ANIM_ID:
3730 rtl::OUString aString;
3731 if( aAny >>= aString )
3733 UniString aTmp(aString);
3734 ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 );
3735 fprintf( mpFile, " id=\"%s\"", aStr.GetBuffer() );
3736 bKnown = true;
3739 break;
3741 case DFF_ANIM_EVENT_FILTER:
3743 rtl::OUString aString;
3744 if( aAny >>= aString )
3746 UniString aTmp(aString);
3747 ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 );
3748 fprintf( mpFile, " eventFilter=\"%s\"", aStr.GetBuffer() );
3749 bKnown = true;
3752 break;
3754 case DFF_ANIM_ENDAFTERSLIDE:
3756 sal_Int32 nEndAfterSlide;
3757 if( aAny >>= nEndAfterSlide )
3759 fprintf(mpFile, " endAfterSlide=\"%ld\"", nEndAfterSlide );
3760 bKnown = true;
3764 case DFF_ANIM_TIMEFILTER:
3766 rtl::OUString aString;
3767 if( aAny >>= aString )
3769 UniString aTmp(aString);
3770 ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 );
3771 fprintf( mpFile, " timeFilter=\"%s\"", aStr.GetBuffer() );
3772 bKnown = true;
3775 break;
3777 case DFF_ANIM_RUNTIMECONTEXT:
3779 rtl::OUString aString;
3780 if( aAny >>= aString )
3782 UniString aTmp(aString);
3783 ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 );
3784 fprintf( mpFile, " runtimeContext=\"%s\"", aStr.GetBuffer() );
3785 bKnown = true;
3788 break;
3790 case DFF_ANIM_VOLUME:
3792 double fVolume;
3793 if( aAny >>= fVolume )
3795 fprintf( mpFile, " volume=\"%g%%\"", (double)(fVolume * 100.0) );
3796 bKnown = true;
3799 break;
3801 case DFF_ANIM_AFTEREFFECT:
3803 sal_Bool bAfterEffect;
3804 if( aAny >>= bAfterEffect )
3806 fprintf( mpFile, "afterEffect=\"%s\"", bAfterEffect ? "true" : "false" );
3807 bKnown = true;
3810 break;
3815 if( !bKnown )
3817 fprintf( mpFile, " unknown_%lu=\"", nInstance );
3818 dump( aAny );
3819 fprintf( mpFile, "\"" );
3822 aIter++;
3826 void AnimationImporter::dump_target( Any& rAny )
3828 Any aSource, aSourceData;
3829 Sequence< Any > aSeq;
3830 if( rAny >>= aSeq )
3832 if( aSeq.getLength() >= 1 ) aSource = aSeq[0];
3833 if( aSeq.getLength() >= 2 ) aSourceData = aSeq[1];
3835 else
3837 aSource = rAny;
3840 Reference< XShape > xShape;
3841 aSource >>= xShape;
3842 if( xShape.is() )
3844 OUString aStr( xShape->getShapeType() );
3845 dump( aStr );
3847 if( aSourceData.hasValue() )
3849 dump( "(" );
3850 dump( aSourceData );
3851 dump( ")" );
3856 void AnimationImporter::dump( const char * pText )
3858 fprintf( mpFile, "%s", pText );
3861 void AnimationImporter::dump( const rtl::OUString& rString )
3863 UniString aTmp( rString );
3864 ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 );
3865 fprintf( mpFile, aStr.GetBuffer() );
3868 void AnimationImporter::dump( const char * pText, sal_Int32 nInt )
3870 fprintf( mpFile, pText, nInt );
3873 void AnimationImporter::dump( const char * pText, double fDouble )
3875 fprintf( mpFile, pText, fDouble );
3878 void AnimationImporter::dump( const char * pText, const char * pText2 )
3880 fprintf( mpFile, pText, pText2 );
3883 void AnimationImporter::dump( const char * pText, const OUString& rString )
3885 UniString aTmp( rString );
3886 ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 );
3887 fprintf( mpFile, pText, aStr.GetBuffer() );
3890 #else
3892 void AnimationImporter::dump_atom_header( const Atom* , bool , bool )
3896 void AnimationImporter::dump_atom( const Atom* , bool )
3900 void AnimationImporter::dump( sal_uInt32 , bool )
3904 void AnimationImporter::dump_anim_group( const Atom* , const AnimationNode& , const PropertySet& , bool )
3908 void AnimationImporter::dump_target( ::com::sun::star::uno::Any& )
3912 void AnimationImporter::dump( ::com::sun::star::uno::Any& )
3916 void AnimationImporter::dump( const PropertySet& )
3920 void AnimationImporter::dump( const AnimationNode& )
3924 void AnimationImporter::dump( const char * )
3928 void AnimationImporter::dump( const rtl::OUString& )
3932 void AnimationImporter::dump( const char * , sal_Int32 )
3936 void AnimationImporter::dump( const char * , double )
3940 void AnimationImporter::dump( const char * , const char * )
3944 void AnimationImporter::dump( const char * , const rtl::OUString& )
3948 #endif
3950 } // namespace ppt;