bump product version to 4.1.6.2
[LibreOffice.git] / sd / source / filter / ppt / pptinanimations.cxx
blob90112513def103f18763c1774e5c58cde2dc7c3b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
21 #include <com/sun/star/animations/AnimationFill.hpp>
22 #include <com/sun/star/animations/AnimationRestart.hpp>
23 #include <com/sun/star/animations/Timing.hpp>
24 #include <com/sun/star/animations/Event.hpp>
25 #include <com/sun/star/animations/AnimationEndSync.hpp>
26 #include <com/sun/star/animations/Command.hpp>
27 #include <com/sun/star/animations/EventTrigger.hpp>
28 #include <com/sun/star/animations/AnimationNodeType.hpp>
29 #include <com/sun/star/animations/AnimationTransformType.hpp>
30 #include <com/sun/star/animations/AnimationCalcMode.hpp>
31 #include <com/sun/star/animations/AnimationValueType.hpp>
32 #include <com/sun/star/animations/AnimationAdditiveMode.hpp>
33 #include <com/sun/star/animations/XIterateContainer.hpp>
34 #include <com/sun/star/animations/XAnimateSet.hpp>
35 #include <com/sun/star/animations/XAudio.hpp>
36 #include <com/sun/star/animations/XCommand.hpp>
37 #include <com/sun/star/animations/XTransitionFilter.hpp>
38 #include <com/sun/star/animations/XAnimateColor.hpp>
39 #include <com/sun/star/animations/XAnimateMotion.hpp>
40 #include <com/sun/star/animations/XAnimateTransform.hpp>
41 #include <com/sun/star/animations/ValuePair.hpp>
42 #include <com/sun/star/animations/AnimationColorSpace.hpp>
43 #include <com/sun/star/presentation/EffectNodeType.hpp>
44 #include <com/sun/star/presentation/EffectPresetClass.hpp>
45 #include <com/sun/star/presentation/ShapeAnimationSubType.hpp>
46 #include <com/sun/star/presentation/EffectCommands.hpp>
47 #include <com/sun/star/beans/NamedValue.hpp>
48 #include <com/sun/star/drawing/FillStyle.hpp>
49 #include <com/sun/star/drawing/LineStyle.hpp>
50 #include <com/sun/star/awt/FontWeight.hpp>
51 #include <com/sun/star/awt/FontUnderline.hpp>
52 #include <com/sun/star/awt/FontSlant.hpp>
53 #include <com/sun/star/container/XEnumerationAccess.hpp>
54 #include <com/sun/star/presentation/ParagraphTarget.hpp>
55 #include <com/sun/star/presentation/TextAnimationType.hpp>
56 #include <comphelper/processfactory.hxx>
57 #include <rtl/ustrbuf.hxx>
58 #include <rtl/math.hxx>
60 #include <vcl/vclenum.hxx>
61 #include <svx/svdotext.hxx>
62 #include <editeng/outlobj.hxx>
63 #include <editeng/editobj.hxx>
64 #include <pptinanimations.hxx>
65 #include <pptatom.hxx>
66 #include "pptin.hxx"
67 #include <algorithm>
69 using ::std::map;
70 using ::com::sun::star::beans::NamedValue;
71 using ::com::sun::star::container::XEnumerationAccess;
72 using ::com::sun::star::container::XEnumeration;
73 using ::com::sun::star::lang::XMultiServiceFactory;
75 using namespace ::com::sun::star::uno;
76 using namespace ::com::sun::star::drawing;
77 using namespace ::com::sun::star::animations;
78 using namespace ::com::sun::star::presentation;
80 namespace sd
82 extern Reference< XInterface > RandomAnimationNode_createInstance( sal_Int16 nPresetClass );
85 namespace ppt
88 const transition* transition::find( const OUString& rName )
90 const transition* p = gTransitions;
92 while( p->mpName )
94 if( rName.compareToAscii( p->mpName ) == 0 )
95 return p;
97 p++;
100 return NULL;
103 // ====================================================================
107 // ====================================================================
109 SvStream& operator>>(SvStream& rIn, AnimationNode& rNode )
111 rIn >> rNode.mnU1;
112 rIn >> rNode.mnRestart;
113 rIn >> rNode.mnGroupType;
114 rIn >> rNode.mnFill;
115 rIn >> rNode.mnU3;
116 rIn >> rNode.mnU4;
117 rIn >> rNode.mnDuration;
118 rIn >> rNode.mnNodeType;
120 return rIn;
123 // ====================================================================
125 static bool convertMeasure( OUString& rString )
127 bool bRet = false;
129 const sal_Char* pSource[] = { "ppt_x", "ppt_y", "ppt_w", "ppt_h", NULL };
130 const sal_Char* pDest[] = { "x", "y", "width", "height", NULL };
131 sal_Int32 nIndex = 0;
133 const sal_Char** ps = pSource;
134 const sal_Char** pd = pDest;
136 while( *ps )
138 const OUString aSearch( OUString::createFromAscii( *ps ) );
139 while( (nIndex = rString.indexOf( aSearch, nIndex )) != -1 )
141 sal_Int32 nLength = aSearch.getLength();
142 if( nIndex && (rString.getStr()[nIndex-1] == '#' ) )
144 nIndex--;
145 nLength++;
148 const OUString aNew( OUString::createFromAscii( *pd ) );
149 rString = rString.replaceAt( nIndex, nLength, aNew );
150 nIndex += aNew.getLength();
151 bRet = true;
153 ps++;
154 pd++;
157 return bRet;
161 // ====================================================================
163 bool PropertySet::hasProperty( sal_Int32 nProperty ) const
165 return maProperties.find( nProperty ) != maProperties.end();
168 // --------------------------------------------------------------------
170 Any PropertySet::getProperty( sal_Int32 nProperty ) const
172 PropertySetMap_t::const_iterator aIter( maProperties.find( nProperty ) );
173 if( aIter != maProperties.end() )
174 return (*aIter).second;
175 else
176 return Any();
179 // ====================================================================
181 /** this adds an any to another any.
182 if rNewValue is empty, rOldValue is returned.
183 if rOldValue is empty, rNewValue is returned.
184 if rOldValue contains a value, a sequence with rOldValue and rNewValue is returned.
185 if rOldValue contains a sequence, a new sequence with the old sequence and rNewValue is returned.
187 static Any addToSequence( const Any& rOldValue, const Any& rNewValue )
189 if( !rNewValue.hasValue() )
191 return rOldValue;
193 else if( !rOldValue.hasValue() )
195 return rNewValue;
197 else
199 Sequence< Any > aNewSeq;
200 if( rOldValue >>= aNewSeq )
202 sal_Int32 nSize = aNewSeq.getLength();
203 aNewSeq.realloc(nSize+1);
204 aNewSeq[nSize] = rNewValue;
206 else
208 aNewSeq.realloc(2);
209 aNewSeq[0] = rOldValue;
210 aNewSeq[1] = rNewValue;
212 return makeAny( aNewSeq );
216 // ====================================================================
218 AnimationImporter::AnimationImporter( ImplSdPPTImport* pPPTImport, SvStream& rStCtrl )
219 : mpPPTImport( pPPTImport ), mrStCtrl( rStCtrl )
223 // --------------------------------------------------------------------
225 int AnimationImporter::import( const Reference< XDrawPage >& xPage, const DffRecordHeader& rProgTagContentHd )
227 int nNodes = 0;
229 #ifdef DBG_ANIM_LOG
230 static int ppt_anim_debug_stream_number = 1;
231 OUString ppt_anim_debug_filename("ppt-animation-import-debug-output-");
232 ppt_anim_debug_filename += OUString::valueOf(ppt_anim_debug_stream_number++);
233 ppt_anim_debug_filename += OUString(".xml");
234 mpFile = fopen( OUStringToOString( ppt_anim_debug_filename, RTL_TEXTENCODING_UTF8).getStr() , "w+" );
235 #endif
236 dump("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
238 Reference< XAnimationNodeSupplier > xNodeSupplier( xPage, UNO_QUERY );
239 if( xNodeSupplier.is() )
241 mxRootNode = xNodeSupplier->getAnimationNode();
242 if( mxRootNode.is() )
244 Reference< XAnimationNode > xParent;
246 boost::scoped_ptr<Atom> pAtom(Atom::import( rProgTagContentHd, mrStCtrl ));
247 if( pAtom )
249 nNodes = importAnimationContainer( pAtom.get(), xParent );
252 processAfterEffectNodes();
256 #ifdef DBG_ANIM_LOG
257 fclose( mpFile );
258 #endif
260 return nNodes;
263 // --------------------------------------------------------------------
265 void AnimationImporter::processAfterEffectNodes()
267 std::for_each( maAfterEffectNodes.begin(), maAfterEffectNodes.end(), sd::stl_process_after_effect_node_func );
270 // --------------------------------------------------------------------
272 Reference< XAnimationNode > AnimationImporter::createNode( const Atom* pAtom, const AnimationNode& rNode )
274 const char* pServiceName = NULL;
276 switch( rNode.mnGroupType )
278 case mso_Anim_GroupType_PAR:
279 if( pAtom->hasChildAtom( DFF_msofbtAnimIteration ) )
280 pServiceName = "com.sun.star.animations.IterateContainer";
281 else
282 pServiceName = "com.sun.star.animations.ParallelTimeContainer";
283 break;
284 case mso_Anim_GroupType_SEQ:
285 pServiceName = "com.sun.star.animations.SequenceTimeContainer";
286 break;
287 case mso_Anim_GroupType_NODE:
289 switch( rNode.mnNodeType )
291 case mso_Anim_Behaviour_FILTER:
292 case mso_Anim_Behaviour_ANIMATION:
293 if( pAtom->hasChildAtom( DFF_msofbtAnimateSet ) )
294 pServiceName = "com.sun.star.animations.AnimateSet";
295 else if( pAtom->hasChildAtom( DFF_msofbtAnimateColor ) )
296 pServiceName = "com.sun.star.animations.AnimateColor";
297 else if( pAtom->hasChildAtom( DFF_msofbtAnimateScale ) )
298 pServiceName = "com.sun.star.animations.AnimateTransform";
299 else if( pAtom->hasChildAtom( DFF_msofbtAnimateRotation ) )
300 pServiceName = "com.sun.star.animations.AnimateTransform";
301 else if( pAtom->hasChildAtom( DFF_msofbtAnimateMotion ) )
302 pServiceName = "com.sun.star.animations.AnimateMotion";
303 else if( pAtom->hasChildAtom( DFF_msofbtAnimateFilter ) )
304 pServiceName = "com.sun.star.animations.TransitionFilter";
305 else if( pAtom->hasChildAtom( DFF_msofbtAnimCommand ) )
306 pServiceName = "com.sun.star.animations.Command";
307 else
308 pServiceName = "com.sun.star.animations.Animate";
309 break;
311 break;
313 case mso_Anim_GroupType_MEDIA:
314 pServiceName = "com.sun.star.animations.Audio";
315 break;
317 default:
318 pServiceName = "com.sun.star.animations.Animate";
319 break;
322 Reference< XAnimationNode > xNode;
323 if( pServiceName )
325 Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
326 const OUString aServiceName( OUString::createFromAscii(pServiceName) );
327 Reference< XInterface > xFac( xContext->getServiceManager()->createInstanceWithContext(aServiceName, xContext) );
328 xNode.set(xFac , UNO_QUERY );
331 DBG_ASSERT( xNode.is(), "sd::AnimationImporter::createNode(), node creation failed!" );
332 return xNode;
335 // --------------------------------------------------------------------
337 static bool is_random( const AnimationNode& rNode, const PropertySet& rSet, sal_Int32& rPresetClass )
339 if( rNode.mnGroupType != mso_Anim_GroupType_PAR )
340 return false;
342 if( !rSet.hasProperty( DFF_ANIM_PRESET_ID ) || !rSet.hasProperty( DFF_ANIM_PRESET_CLASS ) )
343 return false;
345 sal_Int32 nPresetId = 0;
346 if( !(rSet.getProperty( DFF_ANIM_PRESET_ID ) >>= nPresetId) || (nPresetId != 24) )
347 return false;
349 sal_Int32 nPresetClass = 0;
350 if( !(rSet.getProperty( DFF_ANIM_PRESET_CLASS ) >>= nPresetClass) )
351 return false;
353 switch( nPresetClass )
355 case DFF_ANIM_PRESS_CLASS_ENTRANCE: rPresetClass = EffectPresetClass::ENTRANCE; return true;
356 case DFF_ANIM_PRESS_CLASS_EXIT: rPresetClass = EffectPresetClass::EXIT; return true;
358 return false;
362 int AnimationImporter::importAnimationContainer( const Atom* pAtom, const Reference< XAnimationNode >& xParent )
364 int nNodes = 0;
365 if( pAtom->seekToContent() )
367 AnimationNode aNode;
368 const Atom* pAnimationNodeAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimNode );
369 if( pAnimationNodeAtom && pAnimationNodeAtom->seekToContent() )
370 mrStCtrl >> aNode;
372 PropertySet aSet;
373 const Atom* pAnimationPropertySetAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimPropertySet );
374 if( pAnimationPropertySetAtom )
375 importPropertySetContainer( pAnimationPropertySetAtom, aSet );
377 Reference< XAnimationNode > xNode;
379 if( xParent.is() )
381 sal_Int32 nPresetClass;
382 if( is_random( aNode, aSet, nPresetClass ) )
384 // create a random animation node with the given preset class
385 xNode.set( sd::RandomAnimationNode_createInstance( (sal_Int16)nPresetClass ), UNO_QUERY );
388 if( !xNode.is() )
390 // create a node for the given atom
391 xNode = createNode( pAtom, aNode );
394 else
396 // if we have no parent we fill the root node
397 xNode = mxRootNode;
400 // import if we have a node and its not random
401 if( xNode.is() )
403 fillNode( xNode, aNode, aSet );
405 switch( aNode.mnGroupType )
407 case mso_Anim_GroupType_PAR:
409 dump( "<par" );
410 dump( aNode );
411 dump( aSet );
412 nNodes += importTimeContainer( pAtom, xNode );
413 dump( "</par>\n" );
415 // for iteration containers, map target from children to iteration
416 Reference< XIterateContainer > xIter( xNode, UNO_QUERY );
417 if( xIter.is() )
419 double fDuration = 0.0;
420 Any aTarget, aEmpty;
421 Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY );
422 if( xEnumerationAccess.is() )
424 Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
425 if( xEnumeration.is() )
427 while( xEnumeration->hasMoreElements() )
429 Reference< XAnimate > xChildNode( xEnumeration->nextElement(), UNO_QUERY );
430 if( xChildNode.is() )
432 double fChildBegin = 0.0;
433 double fChildDuration = 0.0;
434 xChildNode->getBegin() >>= fChildBegin;
435 xChildNode->getDuration() >>= fChildDuration;
437 fChildDuration += fChildBegin;
438 if( fChildDuration > fDuration )
439 fDuration = fChildDuration;
441 if( !aTarget.hasValue() )
442 aTarget = xChildNode->getTarget();
444 xChildNode->setTarget( aEmpty );
450 xIter->setTarget( aTarget );
452 double fIterateInterval = xIter->getIterateInterval() * fDuration / 100;
453 xIter->setIterateInterval( fIterateInterval );
456 break;
458 case mso_Anim_GroupType_SEQ:
460 dump( "<seq" );
461 dump( aNode );
462 dump( aSet );
463 nNodes += importTimeContainer( pAtom, xNode );
464 dump( "</seq>\n" );
466 if( aSet.hasProperty( DFF_ANIM_NODE_TYPE ) )
468 sal_Int32 nPPTNodeType = 0;
469 if( aSet.getProperty( DFF_ANIM_NODE_TYPE ) >>= nPPTNodeType )
471 switch(nPPTNodeType)
473 case DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE:
474 fixMainSequenceTiming( xNode );
475 break;
476 case DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ:
477 fixInteractiveSequenceTiming( xNode );
478 break;
483 break;
485 case mso_Anim_GroupType_NODE:
487 #ifdef DBG_ANIM_LOG
488 if( pAtom->hasChildAtom( DFF_msofbtAnimateSet ) )
490 dump( "<set" );
492 else if( pAtom->hasChildAtom( DFF_msofbtAnimateColor ) )
494 dump( "<animateColor" );
496 else if( pAtom->hasChildAtom( DFF_msofbtAnimateScale ) )
498 dump( "<animateScale" );
500 else if( pAtom->hasChildAtom( DFF_msofbtAnimateRotation ) )
502 dump( "<animateRotation" );
504 else if( pAtom->hasChildAtom( DFF_msofbtAnimateMotion ) )
506 dump( "<animateMotion" );
508 else if( pAtom->hasChildAtom( DFF_msofbtAnimate ) )
510 dump( "<animate" );
512 else if( pAtom->hasChildAtom( DFF_msofbtAnimateFilter ) )
514 dump( "<animateFilter" );
516 else if( pAtom->hasChildAtom( DFF_msofbtAnimCommand ) )
518 dump( "<command" );
520 else
522 OSL_FAIL( "unknown node atom!" );
523 dump_atom_header( pAtom, true, false );
524 dump_atom( pAtom );
525 dump_atom_header( pAtom, false, false );
526 break;
528 dump( aNode );
529 dump( aSet );
530 #endif
531 int nANCNodes = importAnimationNodeContainer( pAtom, xNode );
532 if( !convertAnimationNode( xNode, xParent ) )
533 xNode = 0;
534 else
535 nNodes += nANCNodes;
536 dump( "/>\n");
539 break;
541 case mso_Anim_GroupType_MEDIA:
543 dump( "<audio" );
544 dump( aNode );
545 dump( aSet );
546 nNodes += importAudioContainer( pAtom, xNode );
547 dump( "</audio>\n" );
549 break;
551 default:
552 OSL_FAIL( "unknown group atom!" );
554 dump_atom_header( pAtom, true, false );
555 dump_atom( pAtom );
556 dump_atom_header( pAtom, false, false );
557 break;
562 if( xParent.is() && xNode.is() )
564 Reference< XTimeContainer > xParentContainer( xParent, UNO_QUERY );
565 DBG_ASSERT( xParentContainer.is(), "parent is no container, then why do I have a child here?" );
566 if( xParentContainer.is() )
568 xParentContainer->appendChild( xNode );
573 return nNodes;
576 // --------------------------------------------------------------------
577 void AnimationImporter::fixMainSequenceTiming( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode )
581 bool bFirst = true;
582 Reference< XEnumerationAccess > xEA( xNode, UNO_QUERY_THROW );
583 Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_QUERY_THROW );
584 while( xE->hasMoreElements() )
586 // click node
587 Reference< XAnimationNode > xClickNode( xE->nextElement(), UNO_QUERY );
589 Event aEvent;
590 aEvent.Trigger = EventTrigger::ON_NEXT;
591 aEvent.Repeat = 0;
592 xClickNode->setBegin( makeAny( aEvent ) );
594 if( bFirst )
596 bFirst = false;
597 Reference< XEnumerationAccess > xEA2( xClickNode, UNO_QUERY_THROW );
598 Reference< XEnumeration > xE2( xEA2->createEnumeration(), UNO_QUERY_THROW );
599 if( xE2->hasMoreElements() )
601 // with node
602 xE2->nextElement() >>= xEA2;
603 if( xEA2.is() )
604 xE2.query( xEA2->createEnumeration() );
605 else
606 xE2.clear();
608 if( xE2.is() && xE2->hasMoreElements() )
610 Reference< XAnimationNode > xEffectNode( xE2->nextElement(), UNO_QUERY_THROW );
611 const Sequence< NamedValue > aUserData( xEffectNode->getUserData() );
612 const NamedValue* p = aUserData.getConstArray();
613 sal_Int32 nLength = aUserData.getLength();
614 while( nLength-- )
616 if ( p->Name == "node-type" )
618 sal_Int16 nNodeType = 0;
619 p->Value >>= nNodeType;
620 if( nNodeType != ::com::sun::star::presentation::EffectNodeType::ON_CLICK )
622 // first effect does not start on click, so correct
623 // first click nodes begin to 0s
624 xClickNode->setBegin( makeAny( (double)0.0 ) );
625 break;
628 p++;
635 catch( Exception& )
637 OSL_FAIL("sd::AnimationImporter::fixMainSequenceTiming(), exception caught!" );
641 // --------------------------------------------------------------------
643 void AnimationImporter::fixInteractiveSequenceTiming( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode )
647 Any aBegin( xNode->getBegin() );
648 Any aEmpty;
649 xNode->setBegin( aEmpty );
651 Reference< XEnumerationAccess > xEA( xNode, UNO_QUERY_THROW );
652 Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_QUERY_THROW );
653 while( xE->hasMoreElements() )
655 // click node
656 Reference< XAnimationNode > xClickNode( xE->nextElement(), UNO_QUERY );
657 xClickNode->setBegin( aBegin );
660 catch( Exception& )
662 OSL_FAIL("sd::AnimationImporter::fixInteractiveSequenceTiming(), exception caught!" );
666 // --------------------------------------------------------------------
668 bool AnimationImporter::convertAnimationNode( const Reference< XAnimationNode >& xNode, const Reference< XAnimationNode >& xParent )
670 Reference< XAnimate > xAnimate( xNode, UNO_QUERY );
671 if( !xAnimate.is() )
672 return true;
674 if( !xAnimate->getTarget().hasValue() )
675 return false;
677 const sal_Int16 nNodeType = xNode->getType();
679 if( nNodeType == AnimationNodeType::TRANSITIONFILTER )
680 return true;
682 OUString aAttributeName( xAnimate->getAttributeName() );
684 if( (nNodeType == AnimationNodeType::SET) && aAttributeName == "fill.on" )
685 return false;
687 const ImplAttributeNameConversion* p = gImplConversionList;
689 MS_AttributeNames eAttribute = MS_UNKNOWN;
691 if( (nNodeType == AnimationNodeType::ANIMATEMOTION) ||
692 (nNodeType == AnimationNodeType::ANIMATETRANSFORM) )
694 OUString aEmpty;
695 aAttributeName = aEmpty;
697 else
699 while( p->mpMSName )
701 if( aAttributeName.compareToAscii( p->mpMSName ) == 0 )
702 break;
704 p++;
707 DBG_ASSERT( p->mpMSName || aAttributeName.isEmpty(), "sd::AnimationImporter::convertAnimationNode(), unknown attribute!" );
708 #ifdef DBG_ANIM_LOG
709 if( p->mpMSName == 0 ) dump( "<error text=\"sd::AnimationImporter::convertAnimationNode(), unknown attribute!\"/>\n" );
710 #endif
712 eAttribute = p->meAttribute;
714 if( p->mpAPIName )
715 aAttributeName = OUString::createFromAscii( p->mpAPIName );
718 xAnimate->setAttributeName( aAttributeName );
720 if( eAttribute != MS_UNKNOWN )
722 Any aAny( xAnimate->getFrom() );
723 if( aAny.hasValue() )
725 if( convertAnimationValue( eAttribute, aAny ) )
726 xAnimate->setFrom( aAny );
729 aAny = xAnimate->getBy();
730 if( aAny.hasValue() )
732 if( convertAnimationValue( eAttribute, aAny ) )
733 xAnimate->setBy( aAny );
736 aAny = xAnimate->getTo();
737 if( aAny.hasValue() )
739 if( convertAnimationValue( eAttribute, aAny ) )
740 xAnimate->setTo( aAny );
743 Sequence< Any > aValues( xAnimate->getValues() );
744 sal_Int32 nValues = aValues.getLength();
745 if( nValues )
747 Any* p2 = aValues.getArray();
748 while( nValues-- )
749 convertAnimationValue( eAttribute, *p2++ );
751 xAnimate->setValues( aValues );
754 OUString aFormula( xAnimate->getFormula() );
755 if( !aFormula.isEmpty() )
757 if( convertMeasure( aFormula ) )
758 xAnimate->setFormula( aFormula );
762 // check for after-affect
763 Sequence< NamedValue > aUserData( xNode->getUserData() );
764 NamedValue* pValue = aUserData.getArray();
765 NamedValue* pLastValue = pValue;
766 sal_Int32 nLength = aUserData.getLength(), nRemoved = 0;
768 sal_Bool bAfterEffect = false;
769 sal_Int32 nMasterRel = 0;
770 for( ; nLength--; pValue++ )
772 if ( pValue->Name == "after-effect" )
774 pValue->Value >>= bAfterEffect;
775 nRemoved++;
777 else if ( pValue->Name == "master-rel" )
779 pValue->Value >>= nMasterRel;
780 nRemoved++;
782 else
784 if( nRemoved )
785 *pLastValue = *pValue;
786 pLastValue++;
790 if( nRemoved )
792 aUserData.realloc( aUserData.getLength() - nRemoved );
793 xNode->setUserData( aUserData );
796 // if its an after effect node, add it to the list for
797 // later processing
798 // after effect nodes are not inserted at their import
799 // position, so return false in this case
800 if( bAfterEffect )
802 if( nMasterRel != 2 )
804 Event aEvent;
806 aEvent.Source <<= xParent;
807 aEvent.Trigger = EventTrigger::END_EVENT;
808 aEvent.Repeat = 0;
810 xNode->setBegin( makeAny( aEvent ) );
813 // add to after effect nodes for later processing
814 sd::AfterEffectNode aNode( xNode, xParent, nMasterRel == 2 );
815 maAfterEffectNodes.push_back( aNode );
816 return false;
819 return true;
822 static int lcl_gethex( int nChar )
824 if( nChar >= '0' && nChar <= '9' )
825 return nChar - '0';
826 else if( nChar >= 'a' && nChar <= 'f' )
827 return nChar - 'a' + 10;
828 else if( nChar >= 'A' && nChar <= 'F' )
829 return nChar - 'A' + 10;
830 else
831 return 0;
834 bool AnimationImporter::convertAnimationValue( MS_AttributeNames eAttribute, Any& rValue )
836 bool bRet = false;
837 switch( eAttribute )
839 case MS_PPT_X:
840 case MS_PPT_Y:
841 case MS_PPT_W:
842 case MS_PPT_H:
844 OUString aString;
846 if( rValue.getValueType() == ::getCppuType((const ValuePair*)0) )
848 ValuePair aValuePair;
849 if( rValue >>= aValuePair )
851 if( aValuePair.First >>= aString )
853 if( convertMeasure( aString ) )
855 aValuePair.First <<= aString;
856 bRet = true;
860 if( aValuePair.Second >>= aString )
862 if( convertMeasure( aString ) )
864 aValuePair.Second <<= aString;
865 bRet = true;
870 else if( rValue.getValueType() == ::getCppuType((const OUString*)0) )
872 if( rValue >>= aString )
874 bRet = convertMeasure( aString );
876 if( bRet )
877 rValue <<= aString;
881 break;
883 case MS_XSHEAR:
884 case MS_R:
886 OUString aString;
887 if( rValue >>= aString )
889 rValue <<= aString.toDouble();
890 bRet = true;
893 break;
895 case MS_STYLEROTATION:
897 if( rValue.getValueType() == ::getCppuType((const OUString*)0) )
899 OUString aString;
900 rValue >>= aString;
901 rValue <<= (sal_Int16)aString.toDouble();
902 bRet = true;
904 else if( rValue.getValueType() == ::getCppuType((const double*)0) )
906 double fValue = 0.0;
907 rValue >>= fValue;
908 rValue <<= (sal_Int16)fValue;
909 bRet = true;
912 break;
914 case MS_FILLCOLOR:
915 case MS_STROKECOLOR:
916 case MS_STYLECOLOR:
917 case MS_PPT_C:
919 OUString aString;
920 if( rValue >>= aString )
922 if( aString.getLength() >= 7 && aString[0] == '#' )
924 Color aColor;
925 aColor.SetRed( (sal_uInt8)(lcl_gethex( aString[1] ) * 16 + lcl_gethex( aString[2] )) );
926 aColor.SetGreen( (sal_uInt8)(lcl_gethex( aString[3] ) * 16 + lcl_gethex( aString[4] )) );
927 aColor.SetBlue( (sal_uInt8)(lcl_gethex( aString[5] ) * 16 + lcl_gethex( aString[6] )) );
928 rValue <<= (sal_Int32)aColor.GetColor();
929 bRet = true;
931 else if( aString.matchAsciiL( "rgb(", 4, 0 ) )
933 aString = aString.copy( 4, aString.getLength() - 5 );
934 Color aColor;
935 sal_Int32 index = 0;
936 aColor.SetRed( (sal_uInt8)aString.getToken( 0, (sal_Unicode)',', index ).toInt32() );
937 aColor.SetGreen( (sal_uInt8)aString.getToken( 0, (sal_Unicode)',', index ).toInt32() );
938 aColor.SetRed( (sal_uInt8)aString.getToken( 0, (sal_Unicode)',', index ).toInt32() );
939 rValue <<= (sal_Int32)aColor.GetColor();
940 bRet = true;
942 else if( aString.matchAsciiL( "hsl(", 4, 0 ) )
944 sal_Int32 index = 0;
945 sal_Int32 nA = aString.getToken( 0, (sal_Unicode)',', index ).toInt32();
946 sal_Int32 nB = aString.getToken( 0, (sal_Unicode)',', index ).toInt32();
947 sal_Int32 nC = aString.getToken( 0, (sal_Unicode)',', index ).toInt32();
948 dump( "hsl(%ld", nA );
949 dump( ",%ld", nB );
950 dump( ",%ld)", nC );
951 Sequence< double > aHSL( 3 );
952 aHSL[0] = nA * 360.0/255.0;
953 aHSL[1] = nB / 255.0;
954 aHSL[2] = nC / 255.0;
955 rValue <<= aHSL;
956 bRet = true;
960 break;
962 case MS_FILLTYPE:
964 OUString aString;
965 if( rValue >>= aString )
967 rValue <<= aString == "solid" ? FillStyle_SOLID : FillStyle_NONE;
968 bRet = true;
971 break;
973 case MS_STROKEON:
975 OUString aString;
976 if( rValue >>= aString )
978 rValue <<= aString == "true" ? ::com::sun::star::drawing::LineStyle_SOLID : ::com::sun::star::drawing::LineStyle_NONE;
979 bRet = true;
982 break;
984 case MS_FONTWEIGHT:
986 OUString aString;
987 if( rValue >>= aString )
989 rValue <<= aString == "bold" ? com::sun::star::awt::FontWeight::BOLD : com::sun::star::awt::FontWeight::NORMAL;
990 bRet = true;
993 break;
995 case MS_STYLEFONTSTYLE:
997 OUString aString;
998 if( rValue >>= aString )
1000 rValue <<= aString == "italic" ? com::sun::star::awt::FontSlant_ITALIC : com::sun::star::awt::FontSlant_NONE;
1001 bRet = true;
1004 break;
1006 case MS_STYLEUNDERLINE:
1008 OUString aString;
1009 if( rValue >>= aString )
1011 rValue <<= aString == "true" ? com::sun::star::awt::FontUnderline::SINGLE : com::sun::star::awt::FontUnderline::NONE;
1012 bRet = true;
1015 break;
1017 case MS_STYLEOPACITY:
1018 case MS_STYLEFONTSIZE:
1020 OUString aString;
1021 if( rValue >>= aString )
1023 rValue <<= (float)aString.toDouble();
1024 bRet = true;
1027 break;
1029 case MS_STYLEVISIBILITY:
1031 OUString aString;
1032 if( rValue >>= aString )
1034 rValue <<= aString == "visible" ? sal_True : sal_False;
1035 bRet = true;
1038 break;
1039 default:
1040 break;
1043 return bRet;
1046 // --------------------------------------------------------------------
1048 static OUString getConvertedSubType( sal_Int16 nPresetClass, sal_Int32 nPresetId, sal_Int32 nPresetSubType )
1050 const sal_Char* pStr = 0;
1052 if( (nPresetClass == EffectPresetClass::ENTRANCE) || (nPresetClass == EffectPresetClass::EXIT) )
1054 // skip wheel effect
1055 if( nPresetId != 21 )
1057 if( nPresetId == 5 )
1059 // checkerboard
1060 switch( nPresetSubType )
1062 case 5: pStr = "downward"; break;
1063 case 10: pStr = "across"; break;
1066 else if( nPresetId == 17 )
1068 // stretch
1069 if( nPresetSubType == 10 )
1070 pStr = "across";
1072 else if( nPresetId == 18 )
1074 // strips
1075 switch( nPresetSubType )
1077 case 3: pStr = "right-to-top"; break;
1078 case 6: pStr = "right-to-bottom"; break;
1079 case 9: pStr = "left-to-top"; break;
1080 case 12: pStr = "left-to-bottom"; break;
1084 if( pStr == 0 )
1086 const convert_subtype* p = gConvertArray;
1088 while( p->mpStrSubType )
1090 if( p->mnID == nPresetSubType )
1092 pStr = p->mpStrSubType;
1093 break;
1095 p++;
1101 if( pStr )
1102 return OUString::createFromAscii( pStr );
1103 else
1104 return OUString::valueOf( nPresetSubType );
1107 // --------------------------------------------------------------------
1109 void AnimationImporter::fillNode( Reference< XAnimationNode >& xNode, const AnimationNode& rNode, const PropertySet& rSet )
1111 sal_Bool bAfterEffect = false;
1113 // attribute Restart
1114 if( rNode.mnRestart )
1116 sal_Int16 nRestart = AnimationRestart::DEFAULT;
1117 switch( rNode.mnRestart )
1119 case 1: nRestart = AnimationRestart::ALWAYS; break;
1120 case 2: nRestart = AnimationRestart::WHEN_NOT_ACTIVE; break;
1121 case 3: nRestart = AnimationRestart::NEVER; break;
1123 xNode->setRestart( nRestart );
1126 // attribute Fill
1127 if( rNode.mnFill )
1129 sal_Int16 nFill = AnimationFill::DEFAULT;
1130 switch( rNode.mnFill )
1132 case 1: nFill = AnimationFill::REMOVE; break;
1133 case 2: nFill = AnimationFill::FREEZE; break;
1134 case 3: nFill = AnimationFill::HOLD; break;
1135 case 4: nFill = AnimationFill::TRANSITION; break;
1137 xNode->setFill( nFill );
1140 // attribute Duration
1141 if( rNode.mnDuration )
1143 Any aDuration;
1144 if( rNode.mnDuration > 0 )
1146 aDuration <<= (double)(rNode.mnDuration / 1000.0);
1148 else if( rNode.mnDuration < 0 )
1150 aDuration <<= Timing_INDEFINITE;
1152 xNode->setDuration( aDuration );
1155 // TODO: DFF_ANIM_PATH_EDIT_MODE
1156 if( rSet.hasProperty( DFF_ANIM_PATH_EDIT_MODE ) )
1158 sal_Int32 nPathEditMode ;
1159 if( rSet.getProperty( DFF_ANIM_PATH_EDIT_MODE ) >>= nPathEditMode )
1164 // set user data
1165 Sequence< NamedValue > aUserData;
1167 // attribute Type
1168 if( rSet.hasProperty( DFF_ANIM_NODE_TYPE ) )
1170 sal_Int32 nPPTNodeType = 0;
1171 if( rSet.getProperty( DFF_ANIM_NODE_TYPE ) >>= nPPTNodeType )
1173 sal_Int16 nNodeType = ::com::sun::star::presentation::EffectNodeType::DEFAULT;
1174 switch( nPPTNodeType )
1176 case DFF_ANIM_NODE_TYPE_ON_CLICK: nNodeType = ::com::sun::star::presentation::EffectNodeType::ON_CLICK; break;
1177 case DFF_ANIM_NODE_TYPE_WITH_PREVIOUS: nNodeType = ::com::sun::star::presentation::EffectNodeType::WITH_PREVIOUS; break;
1178 case DFF_ANIM_NODE_TYPE_AFTER_PREVIOUS: nNodeType = ::com::sun::star::presentation::EffectNodeType::AFTER_PREVIOUS; break;
1179 case DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE: nNodeType = ::com::sun::star::presentation::EffectNodeType::MAIN_SEQUENCE; break;
1180 case DFF_ANIM_NODE_TYPE_TIMING_ROOT: nNodeType = ::com::sun::star::presentation::EffectNodeType::TIMING_ROOT; break;
1181 case DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ:nNodeType = ::com::sun::star::presentation::EffectNodeType::INTERACTIVE_SEQUENCE; break;
1184 sal_Int32 nSize = aUserData.getLength();
1185 aUserData.realloc(nSize+1);
1186 aUserData[nSize].Name = "node-type";
1187 aUserData[nSize].Value <<= nNodeType;
1191 if( rSet.hasProperty( DFF_ANIM_GROUP_ID ) )
1193 sal_Int32 nGroupId;
1194 if( rSet.getProperty( DFF_ANIM_GROUP_ID ) >>= nGroupId )
1196 sal_Int32 nSize = aUserData.getLength();
1197 aUserData.realloc(nSize+1);
1198 aUserData[nSize].Name = "group-id";
1199 aUserData[nSize].Value <<= nGroupId;
1203 sal_Int16 nEffectPresetClass = EffectPresetClass::CUSTOM;
1204 sal_Int32 nPresetId = 0;
1206 if( rSet.hasProperty( DFF_ANIM_PRESET_CLASS ) )
1208 sal_Int32 nPresetClass = 0;
1209 if ( rSet.getProperty( DFF_ANIM_PRESET_CLASS ) >>= nPresetClass )
1211 switch( nPresetClass )
1213 case DFF_ANIM_PRESS_CLASS_ENTRANCE: nEffectPresetClass = EffectPresetClass::ENTRANCE; break;
1214 case DFF_ANIM_PRESS_CLASS_EXIT: nEffectPresetClass = EffectPresetClass::EXIT; break;
1215 case DFF_ANIM_PRESS_CLASS_EMPHASIS: nEffectPresetClass = EffectPresetClass::EMPHASIS; break;
1216 case DFF_ANIM_PRESS_CLASS_MOTIONPATH: nEffectPresetClass = EffectPresetClass::MOTIONPATH; break;
1217 case DFF_ANIM_PRESS_CLASS_OLE_ACTION: nEffectPresetClass = EffectPresetClass::OLEACTION; break;
1218 case DFF_ANIM_PRESS_CLASS_MEDIACALL: nEffectPresetClass = EffectPresetClass::MEDIACALL; break;
1220 sal_Int32 nSize = aUserData.getLength();
1221 aUserData.realloc(nSize+1);
1222 aUserData[nSize].Name = "preset-class";
1223 aUserData[nSize].Value <<= nEffectPresetClass;
1227 if( rSet.hasProperty( DFF_ANIM_PRESET_ID ) )
1229 if( rSet.getProperty( DFF_ANIM_PRESET_ID ) >>= nPresetId )
1231 sal_Int32 nSize = aUserData.getLength();
1232 aUserData.realloc(nSize+1);
1233 aUserData[nSize].Name = "preset-id";
1235 const preset_maping* p = gPresetMaping;
1236 while( p->mpStrPresetId && ((p->mnPresetClass != nEffectPresetClass) || (p->mnPresetId != nPresetId )) )
1237 p++;
1239 if( p->mpStrPresetId )
1241 aUserData[nSize].Value <<= OUString::createFromAscii( p->mpStrPresetId );
1243 else
1245 OUStringBuffer sBuffer;
1246 sBuffer.appendAscii( "ppt_" );
1247 switch( nEffectPresetClass )
1249 case EffectPresetClass::ENTRANCE: sBuffer.appendAscii( "entrance_" ); break;
1250 case EffectPresetClass::EXIT: sBuffer.appendAscii( "exit_" ); break;
1251 case EffectPresetClass::EMPHASIS: sBuffer.appendAscii( "emphasis_" ); break;
1252 case EffectPresetClass::MOTIONPATH: sBuffer.appendAscii( "motionpath_" ); break;
1253 case EffectPresetClass::OLEACTION: sBuffer.appendAscii( "oleaction_" ); break;
1254 case EffectPresetClass::MEDIACALL: sBuffer.appendAscii( "mediacall_" ); break;
1256 sBuffer.append( nPresetId );
1258 aUserData[nSize].Value <<= sBuffer.makeStringAndClear();
1263 if( rSet.hasProperty( DFF_ANIM_PRESET_SUB_TYPE ) )
1265 sal_Int32 nPresetSubType = 0;
1266 if( (rSet.getProperty( DFF_ANIM_PRESET_SUB_TYPE ) >>= nPresetSubType) )
1268 if( nPresetSubType )
1270 sal_Int32 nSize = aUserData.getLength();
1271 aUserData.realloc(nSize+1);
1272 aUserData[nSize].Name = "preset-sub-type";
1273 aUserData[nSize].Value <<= getConvertedSubType( nEffectPresetClass, nPresetId, nPresetSubType );
1278 if( rSet.hasProperty( DFF_ANIM_AFTEREFFECT ) )
1280 if( rSet.getProperty( DFF_ANIM_AFTEREFFECT ) >>= bAfterEffect )
1282 sal_Int32 nSize = aUserData.getLength();
1283 aUserData.realloc(nSize+1);
1284 aUserData[nSize].Name = "after-effect";
1285 aUserData[nSize].Value <<= bAfterEffect;
1289 if( bAfterEffect && rSet.hasProperty( DFF_ANIM_MASTERREL ) )
1291 sal_Int32 nMasterRel = 2;
1292 if( rSet.getProperty( DFF_ANIM_MASTERREL ) >>= nMasterRel )
1294 sal_Int32 nSize = aUserData.getLength();
1295 aUserData.realloc(nSize+1);
1296 aUserData[nSize].Name = "master-rel";
1297 aUserData[nSize].Value <<= nMasterRel;
1301 xNode->setUserData( aUserData );
1303 // TODO: DFF_ANIM_ID
1304 if( rSet.hasProperty( DFF_ANIM_ID ) )
1306 OUString aString;
1307 rSet.getProperty( DFF_ANIM_ID ) >>= aString;
1308 //if( !aString.isEmpty() )
1313 // TODO: DFF_ANIM_EVENT_FILTER
1314 if( rSet.hasProperty( DFF_ANIM_EVENT_FILTER ) )
1316 OUString aString;
1317 rSet.getProperty( DFF_ANIM_EVENT_FILTER ) >>= aString;
1318 //if( !aString.isEmpty() )
1323 // DFF_ANIM_TIMEFILTER
1324 if( rSet.hasProperty( DFF_ANIM_TIMEFILTER ) )
1326 Reference< XAnimate > xAnim( xNode, UNO_QUERY );
1327 if( xAnim.is() )
1329 OUString aString;
1330 rSet.getProperty( DFF_ANIM_TIMEFILTER ) >>= aString;
1331 if( !aString.isEmpty() )
1333 sal_Int32 nElements = 1; // a non empty string has at least one value
1335 sal_Int32 fromIndex = 0;
1336 while(true)
1338 fromIndex = aString.indexOf( (sal_Unicode)';', fromIndex );
1339 if( fromIndex == -1 )
1340 break;
1342 fromIndex++;
1343 nElements++;
1346 Sequence< TimeFilterPair > aTimeFilter( nElements );
1348 TimeFilterPair* pValues = aTimeFilter.getArray();
1349 sal_Int32 nIndex = 0;
1350 while( (nElements--) && (nIndex >= 0) )
1352 const OUString aToken( aString.getToken( 0, ';', nIndex ) );
1354 sal_Int32 nPos = aToken.indexOf( ',' );
1355 if( nPos >= 0 )
1357 pValues->Time = aToken.copy( 0, nPos ).toDouble();
1358 pValues->Progress = aToken.copy( nPos+1, aToken.getLength() - nPos - 1 ).toDouble();
1360 pValues++;
1363 xAnim->setTimeFilter( aTimeFilter );
1369 // TODO: DFF_ANIM_ENDAFTERSLIDE / DFF_ANIM_VOLUME handling. git history has sample code
1370 Reference< XAnimateColor > xColor( xNode, UNO_QUERY );
1371 if( xColor.is() )
1373 if( rSet.hasProperty( DFF_ANIM_DIRECTION ) )
1375 sal_Bool bDirection = sal_False;
1376 if( rSet.getProperty( DFF_ANIM_DIRECTION ) >>= bDirection )
1377 xColor->setDirection( (sal_Bool)!bDirection );
1380 if( rSet.hasProperty( DFF_ANIM_COLORSPACE ) )
1382 sal_Int32 nColorSpace = 0;
1383 rSet.getProperty( DFF_ANIM_COLORSPACE ) >>= nColorSpace;
1384 xColor->setColorInterpolation( (nColorSpace == 0) ? AnimationColorSpace::RGB : AnimationColorSpace::HSL );
1389 // --------------------------------------------------------------------
1391 int AnimationImporter::importTimeContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1393 int nNodes = 0;
1395 DBG_ASSERT( pAtom && xNode.is(), "invalid call to ppt::AnimationImporter::importTimeContainer()!");
1396 if( pAtom && xNode.is() )
1398 importAnimationEvents( pAtom, xNode );
1399 importAnimationValues( pAtom, xNode );
1400 importAnimationActions( pAtom, xNode );
1402 dump(">\n");
1404 // import sub containers
1405 const Atom* pChildAtom = pAtom->findFirstChildAtom();
1407 while( pChildAtom )
1409 switch( pChildAtom->getType() )
1411 case DFF_msofbtAnimNode:
1412 case DFF_msofbtAnimEvent:
1413 case DFF_msofbtAnimValue:
1414 case DFF_msofbtAnimAction:
1415 case DFF_msofbtAnimPropertySet:
1416 break;
1418 case DFF_msofbtAnimSubGoup :
1420 if( pChildAtom->hasChildAtom( DFF_msofbtAnimCommand ) )
1422 Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
1423 Reference< XAnimationNode > xChildNode( Command::create(xContext), UNO_QUERY_THROW );
1424 nNodes += importAnimationNodeContainer( pChildAtom, xChildNode );
1425 Reference< XTimeContainer > xParentContainer( xNode, UNO_QUERY );
1426 if( xParentContainer.is() && xChildNode.is() )
1427 xParentContainer->appendChild( xChildNode );
1429 else
1431 nNodes += importAnimationContainer( pChildAtom, xNode );
1434 break;
1435 case DFF_msofbtAnimGroup :
1437 nNodes += importAnimationContainer( pChildAtom, xNode );
1439 break;
1440 case DFF_msofbtAnimIteration:
1442 if( pChildAtom->seekToContent() )
1444 float fInterval;
1445 sal_Int32 nTextUnitEffect, nU1, nU2, nU3;
1447 mrStCtrl >> fInterval >> nTextUnitEffect >> nU1 >> nU2 >> nU3;
1449 Reference< XIterateContainer > xIter( xNode, UNO_QUERY );
1450 if( xIter.is() )
1452 sal_Int16 nIterateType = TextAnimationType::BY_PARAGRAPH;
1453 switch( nTextUnitEffect )
1455 case 1: nIterateType = TextAnimationType::BY_WORD; break;
1456 case 2: nIterateType = TextAnimationType::BY_LETTER; break;
1458 xIter->setIterateType( nIterateType );
1459 xIter->setIterateInterval( (double)fInterval );
1462 nNodes++;
1464 dump( "<iterate" );
1465 dump( " iterateType=\"%s\"", (nTextUnitEffect == 0) ? "byElement" : (nTextUnitEffect == 1) ? "byWord" : "byLetter" );
1466 dump( " iterateInterval=\"%g\"", fInterval );
1467 dump( " u1=\"%ld\"", nU1 );
1468 dump( " u2=\"%ld\"", nU2 );
1469 dump( " u3=\"%ld\"/>\n", nU3 );
1472 break;
1474 case 0xf136:
1476 #ifdef DBG_ANIM_LOG
1477 sal_uInt32 nU1, nU2;
1478 mrStCtrl >> nU1 >> nU2;
1480 fprintf( mpFile, "<unknown_0xf136 nU1=\"%ld\" nU2=\"%ld\"/>\n", nU1, nU2 );
1481 #endif
1483 break;
1485 default:
1487 dump_atom_header( pChildAtom, true, false );
1488 dump_atom( pChildAtom );
1489 dump_atom_header( pChildAtom, false, false );
1491 break;
1494 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
1498 return nNodes;
1501 // --------------------------------------------------------------------
1503 int AnimationImporter::importAnimationNodeContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1505 int nNodes = 0;
1507 DBG_ASSERT( pAtom && xNode.is(), "invalid call to ppt::AnimationImporter::importAnimationNodeContainer()!");
1508 if( pAtom && xNode.is() )
1510 importAnimationEvents( pAtom, xNode );
1511 importAnimationValues( pAtom, xNode );
1512 importAnimationActions( pAtom, xNode );
1514 const Atom* pChildAtom = pAtom->findFirstChildAtom();
1516 while( pChildAtom )
1518 nNodes ++;
1519 switch( pChildAtom->getType() )
1521 case DFF_msofbtAnimNode:
1522 case DFF_msofbtAnimEvent:
1523 case DFF_msofbtAnimValue:
1524 case DFF_msofbtAnimAction:
1525 case DFF_msofbtAnimPropertySet:
1526 break;
1528 case DFF_msofbtAnimateFilter:
1529 importAnimateFilterContainer( pChildAtom, xNode );
1530 break;
1532 case DFF_msofbtAnimateSet:
1533 importAnimateSetContainer( pChildAtom, xNode );
1534 break;
1536 case DFF_msofbtAnimate:
1537 importAnimateContainer( pChildAtom, xNode );
1538 break;
1540 case DFF_msofbtAnimateScale:
1541 importAnimateScaleContainer( pChildAtom, xNode );
1542 break;
1544 case DFF_msofbtAnimateColor:
1545 importAnimateColorContainer( pChildAtom, xNode );
1546 break;
1548 case DFF_msofbtAnimateRotation:
1549 importAnimateRotationContainer( pChildAtom, xNode );
1550 break;
1552 case DFF_msofbtAnimateMotion:
1553 importAnimateMotionContainer( pChildAtom, xNode );
1554 break;
1556 case DFF_msofbtAnimCommand:
1557 importCommandContainer( pChildAtom, xNode );
1558 break;
1560 default:
1562 nNodes --;
1563 dump_atom_header( pChildAtom, true, false );
1564 dump_atom( pChildAtom );
1565 dump_atom_header( pChildAtom, false, false );
1567 break;
1570 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
1574 return nNodes;
1577 // --------------------------------------------------------------------
1579 void AnimationImporter::importAnimateFilterContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1581 Reference< XTransitionFilter > xFilter( xNode, UNO_QUERY );
1583 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateFilter && xFilter.is(), "invalid call to ppt::AnimationImporter::importAnimateFilterContainer()!");
1584 if( pAtom && xFilter.is() )
1586 sal_uInt32 nBits = 0;
1588 const Atom* pChildAtom = pAtom->findFirstChildAtom();
1590 while( pChildAtom )
1592 if( !pChildAtom->isContainer() )
1594 if( !pChildAtom->seekToContent() )
1595 break;
1598 switch( pChildAtom->getType() )
1600 case DFF_msofbtAnimateFilterData:
1602 sal_uInt32 transition;
1603 mrStCtrl >> nBits;
1604 mrStCtrl >> transition;
1606 if( nBits & 1 )
1607 xFilter->setMode( transition == 0 );
1609 dump( " transition=\"%s\"", (transition == 0) ? "in" : "out" );
1611 break;
1613 case DFF_msofbtAnimAttributeValue:
1615 if( (nBits & 2 ) && ( pChildAtom->getInstance() == 1 ) )
1617 Any aAny;
1618 if ( importAttributeValue( pChildAtom, aAny ) )
1620 OUString filter;
1621 aAny >>= filter;
1623 dump( " filter=\"%s\"", filter );
1625 const transition* pTransition = transition::find( filter );
1626 if( pTransition )
1628 xFilter->setTransition( pTransition->mnType );
1629 xFilter->setSubtype( pTransition->mnSubType );
1630 xFilter->setDirection( pTransition->mbDirection );
1632 else
1634 OSL_FAIL( "unknown transition!" );
1639 break;
1641 case DFF_msofbtAnimateTarget:
1642 importAnimateAttributeTargetContainer( pChildAtom, xNode );
1643 break;
1645 default:
1646 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
1647 break;
1651 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
1656 // --------------------------------------------------------------------
1658 void AnimationImporter::importAnimateAttributeTargetContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1660 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateTarget, "invalid call to ppt::AnimationImporter::importAnimateAttributeTargetContainer()!");
1662 Any aTarget;
1664 Reference< XAnimate > xAnimate( xNode, UNO_QUERY );
1666 bool bWrongContext = false;
1668 if( pAtom )
1670 const Atom* pChildAtom = pAtom->findFirstChildAtom();
1672 while( pChildAtom )
1674 if( !pChildAtom->isContainer() )
1676 if( !pChildAtom->seekToContent() )
1677 break;
1680 switch( pChildAtom->getType() )
1682 case DFF_msofbtAnimPropertySet:
1684 PropertySet aSet;
1685 importPropertySetContainer( pChildAtom, aSet );
1686 if( aSet.hasProperty( DFF_ANIM_RUNTIMECONTEXT ) )
1688 OUString aContext;
1689 if( aSet.getProperty( DFF_ANIM_RUNTIMECONTEXT ) >>= aContext )
1691 if( aContext != "PPT" )
1692 bWrongContext = true;
1696 dump( aSet );
1698 break;
1700 case DFF_msofbtAnimateTargetSettings:
1702 if( xAnimate.is() )
1704 sal_uInt32 nBits;
1705 sal_uInt32 nAdditive;
1706 sal_uInt32 nAccumulate;
1707 sal_uInt32 nTransformType;
1709 mrStCtrl >> nBits >> nAdditive >> nAccumulate >> nTransformType;
1711 // nBits %0001: additive, %0010: accumulate, %0100: attributeName, %1000: transformtype
1712 // nAdditive 0 = base, 1 = sum, 2 = replace, 3 = multiply, 4 = none
1713 // nAccumulate 0 = none, 1 = always
1714 // nTransformType 0: "property" else "image"
1716 if( nBits & 3 )
1718 if( xAnimate.is() )
1720 if( nBits & 1 )
1722 sal_Int16 nTemp = AnimationAdditiveMode::BASE;
1723 switch( nAdditive )
1725 case 1: nTemp = AnimationAdditiveMode::SUM; break;
1726 case 2: nTemp = AnimationAdditiveMode::REPLACE; break;
1727 case 3: nTemp = AnimationAdditiveMode::MULTIPLY; break;
1728 case 4: nTemp = AnimationAdditiveMode::NONE; break;
1730 xAnimate->setAdditive( nTemp );
1733 if( nBits & 2 )
1735 xAnimate->setAccumulate( (nAccumulate == 0) ? sal_True : sal_False );
1739 #ifdef DBG_ANIM_LOG
1740 if( nBits & 1 )
1741 fprintf( mpFile, " additive=\"%s\"", (nAdditive == 0) ? "base" : (nAdditive == 2) ? "replace" : (nAdditive == 1) ? "sum" : (nAdditive == 3 ) ? "multiply" : (nAdditive == 4) ? "none" : "unknown" );
1743 if( nBits & 2 )
1744 fprintf( mpFile, " accumulate=\"%s\"", (nAccumulate == 0) ? "none" : "always" );
1746 if( nBits & 8 )
1747 fprintf( mpFile, " transformType=\"%s\"", (nTransformType == 0) ? "property" : "image" );
1748 #endif
1751 break;
1753 case DFF_msofbtAnimateAttributeNames:
1755 if( xAnimate.is() )
1757 OUString aAttributeName;
1758 importAttributeNamesContainer( pChildAtom, aAttributeName );
1759 if( xAnimate.is() )
1760 xAnimate->setAttributeName( aAttributeName );
1761 dump( " attributeName=\"%s\"", aAttributeName );
1764 break;
1766 case DFF_msofbtAnimateTargetElement:
1768 sal_Int16 nSubType;
1769 importTargetElementContainer( pChildAtom, aTarget, nSubType );
1770 if( xAnimate.is() )
1771 xAnimate->setSubItem( nSubType );
1773 dump( " target=\"" );
1774 dump_target( aTarget );
1775 dump( "\"" );
1777 break;
1779 default:
1780 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
1781 break;
1784 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
1788 if( bWrongContext )
1789 aTarget.clear();
1791 if( xAnimate.is() )
1792 xAnimate->setTarget( aTarget );
1793 else
1795 Reference< XCommand > xCommand( xNode, UNO_QUERY );
1796 if( xCommand.is() )
1797 xCommand->setTarget( aTarget );
1801 // --------------------------------------------------------------------
1803 sal_Int16 AnimationImporter::implGetColorSpace( sal_Int32 nMode, sal_Int32 /*nA*/, sal_Int32 /*nB*/, sal_Int32 /*nC*/ )
1805 switch( nMode )
1807 case 2: // index
1808 // FALLTHROUGH intended
1809 default:
1810 // FALLTHROUGH intended
1811 case 0: // rgb
1812 return AnimationColorSpace::RGB;
1814 case 1: // hsl
1815 return AnimationColorSpace::HSL;
1819 // --------------------------------------------------------------------
1821 Any AnimationImporter::implGetColorAny( sal_Int32 nMode, sal_Int32 nA, sal_Int32 nB, sal_Int32 nC )
1823 switch( nMode )
1825 case 0: // rgb
1827 dump( "rgb(%ld", nA );
1828 dump( ",%ld", nB );
1829 dump( ",%ld)", nC );
1830 Color aColor( (sal_uInt8)nA, (sal_uInt8)nB, (sal_uInt8)nC );
1831 return makeAny( (sal_Int32)aColor.GetRGBColor() );
1833 case 1: // hsl
1835 dump( "hsl(%ld", nA );
1836 dump( ",%ld", nB );
1837 dump( ",%ld)", nC );
1838 Sequence< double > aHSL( 3 );
1839 aHSL[0] = nA * 360.0/255.0;
1840 aHSL[1] = nB / 255.0;
1841 aHSL[2] = nC / 255.0;
1842 return makeAny( aHSL );
1845 case 2: // index
1847 Color aColor;
1848 mpPPTImport->GetColorFromPalette((sal_uInt16)nA, aColor );
1849 dump( "index(%ld", nA );
1850 dump( " [%ld", (sal_Int32)aColor.GetRed() );
1851 dump( ",%ld", (sal_Int32)aColor.GetGreen() );
1852 dump( ",%ld])", (sal_Int32)aColor.GetBlue() );
1853 return makeAny( (sal_Int32)aColor.GetRGBColor() );
1856 default:
1858 dump( "unknown_%ld(", nMode );
1859 dump( "%ld", nA );
1860 dump( ",%ld", nB );
1861 dump( ",%ld)", nC );
1862 OSL_FAIL( "ppt::implGetColorAny(), unhandled color type" );
1864 Any aAny;
1865 return aAny;
1870 void AnimationImporter::importAnimateColorContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1872 Reference< XAnimateColor > xColor( xNode, UNO_QUERY );
1874 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateColor && xColor.is(), "invalid call to ppt::AnimationImporter::importAnimateColorContainer()!");
1875 if( pAtom && xColor.is() )
1877 const Atom* pChildAtom = pAtom->findFirstChildAtom();
1879 while( pChildAtom )
1881 if( !pChildAtom->isContainer() )
1883 if( !pChildAtom->seekToContent() )
1884 break;
1887 switch( pChildAtom->getType() )
1889 case DFF_msofbtAnimateColorData:
1891 sal_uInt32 nBits;
1892 sal_Int32 nByMode, nByA, nByB, nByC;
1893 sal_Int32 nFromMode, nFromA, nFromB, nFromC;
1894 sal_Int32 nToMode, nToA, nToB, nToC;
1895 mrStCtrl >> nBits;
1896 mrStCtrl >> nByMode >> nByA >> nByB >> nByC;
1897 mrStCtrl >> nFromMode >> nFromA >> nFromB >> nFromC;
1898 mrStCtrl >> nToMode >> nToA >> nToB >> nToC;
1900 if( nBits & 1 )
1902 dump( " by=\"" );
1903 xColor->setBy( implGetColorAny( nByMode, nByA, nByB, nByC ) );
1904 xColor->setColorInterpolation( implGetColorSpace( nByMode, nByA, nByB, nByC ) );
1905 dump( "\"");
1908 if( nBits & 2 )
1910 dump( " from=\"" );
1911 xColor->setFrom( implGetColorAny( nFromMode, nFromA, nFromB, nFromC ) );
1912 xColor->setColorInterpolation( implGetColorSpace( nFromMode, nFromA, nFromB, nFromC ) );
1913 dump( "\"");
1916 if( nBits & 4 )
1918 dump( " to=\"" );
1919 xColor->setTo( implGetColorAny( nToMode, nToA, nToB, nToC ) );
1920 xColor->setColorInterpolation( implGetColorSpace( nToMode, nToA, nToB, nToC ) );
1921 dump( "\"");
1924 break;
1926 case DFF_msofbtAnimateTarget:
1927 importAnimateAttributeTargetContainer( pChildAtom, xNode );
1928 break;
1930 default:
1931 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
1932 break;
1935 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
1940 // --------------------------------------------------------------------
1942 void AnimationImporter::importAnimateSetContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1944 Reference< XAnimateSet > xSet( xNode, UNO_QUERY );
1946 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateSet && xSet.is(), "invalid call to ppt::AnimationImporter::importAnimateSetContainer()!");
1947 if( pAtom && xSet.is() )
1949 const Atom* pChildAtom = pAtom->findFirstChildAtom();
1951 while( pChildAtom )
1953 if( !pChildAtom->isContainer() )
1955 if( !pChildAtom->seekToContent() )
1956 break;
1959 switch( pChildAtom->getType() )
1961 case DFF_msofbtAnimateSetData:
1963 sal_Int32 nU1, nU2;
1964 mrStCtrl >> nU1 >> nU2;
1966 dump( " set_1=\"%ld\"", nU1 ),
1967 dump( " set_2=\"%ld\"", nU2 );
1969 break;
1971 case DFF_msofbtAnimAttributeValue:
1973 Any aTo;
1974 if ( importAttributeValue( pChildAtom, aTo ) )
1976 xSet->setTo( aTo );
1978 dump( " value=\"" );
1979 dump( aTo );
1980 dump( "\"" );
1983 break;
1985 case DFF_msofbtAnimateTarget:
1986 importAnimateAttributeTargetContainer( pChildAtom, xNode );
1987 break;
1989 default:
1990 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
1991 break;
1994 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
1999 // --------------------------------------------------------------------
2001 void AnimationImporter::importAnimateContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2003 Reference< XAnimate > xAnim( xNode, UNO_QUERY );
2005 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimate && xAnim.is(), "invalid call to ppt::AnimationImporter::importAnimateContainer()!");
2006 if( pAtom && xAnim.is() )
2008 const Atom* pChildAtom = pAtom->findFirstChildAtom();
2010 while( pChildAtom )
2012 if( !pChildAtom->isContainer() )
2014 if( !pChildAtom->seekToContent() )
2015 break;
2018 switch( pChildAtom->getType() )
2020 case DFF_msofbtAnimateData:
2022 sal_uInt32 nCalcmode, nBits, nValueType;
2023 mrStCtrl >> nCalcmode >> nBits >> nValueType;
2025 if( nBits & 0x08 )
2027 sal_Int16 n = (nCalcmode == 1) ? AnimationCalcMode::LINEAR : /* (nCalcmode == 2) ? AnimationCalcMode::FORMULA : */ AnimationCalcMode::DISCRETE;
2028 xAnim->setCalcMode( n );
2029 dump( " calcmode=\"%s\"", (nCalcmode == 0) ? "discrete" : (nCalcmode == 1) ? "linear" : (nCalcmode == 2) ? "formula" : "unknown" );
2032 if( nBits & 0x30 )
2034 sal_Int16 n = (nValueType == 1) ? AnimationValueType::NUMBER : (nValueType == 2 ) ? AnimationValueType::COLOR : AnimationValueType::STRING;
2035 xAnim->setValueType( n );
2036 dump( " valueType=\"%s\"", (nValueType == 0) ? "string" : (nValueType == 1) ? "number" : (nValueType == 2) ? "color" : "unknown" );
2039 break;
2041 case DFF_msofbtAnimateTarget:
2042 importAnimateAttributeTargetContainer( pChildAtom, xNode );
2043 break;
2045 case DFF_msofbtAnimKeyPoints:
2046 importAnimateKeyPoints( pChildAtom, xNode );
2047 break;
2049 case DFF_msofbtAnimAttributeValue:
2051 Any a;
2052 if ( importAttributeValue( pChildAtom, a ) )
2054 switch( pChildAtom->getInstance() )
2056 case 1: xAnim->setBy( a ); dump( " by=\"" ); break;
2057 case 2: xAnim->setFrom( a ); dump( " from=\"" ); break;
2058 case 3: xAnim->setTo( a ); dump( " to=\"" ); break;
2059 default:
2060 dump( " unknown_value=\"" );
2063 dump( a );
2064 dump( "\"" );
2067 break;
2068 default:
2069 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
2070 break;
2073 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
2078 // --------------------------------------------------------------------
2080 void AnimationImporter::importAnimateMotionContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2082 Reference< XAnimateMotion > xMotion( xNode, UNO_QUERY );
2084 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateMotion && xMotion.is(), "invalid call to ppt::AnimationImporter::importAnimateMotionContainer()!");
2085 if( pAtom && xMotion.is() )
2087 const Atom* pChildAtom = pAtom->findFirstChildAtom();
2089 while( pChildAtom )
2091 if( !pChildAtom->isContainer() )
2093 if( !pChildAtom->seekToContent() )
2094 break;
2097 switch( pChildAtom->getType() )
2099 case DFF_msofbtAnimateMotionData:
2101 sal_uInt32 nBits, nOrigin;
2102 float fByX, fByY, fFromX, fFromY, fToX, fToY;
2104 mrStCtrl >> nBits >> fByX >> fByY >> fFromX >> fFromY >> fToX >> fToY >> nOrigin;
2106 #ifdef DBG_ANIM_LOG
2107 if( nBits & 1 )
2108 fprintf( mpFile, " by=\"%g,%g\"", (double)fByX, (double)fByY );
2110 if( nBits & 2 )
2111 fprintf( mpFile, " from=\"%g,%g\"", (double)fFromX, (double)fFromY );
2113 if( nBits & 4 )
2114 fprintf( mpFile, " to=\"%g,%g\"", (double)fToX, (double)fToY );
2116 if( nBits & 8 )
2117 fprintf( mpFile, " origin=\"%s\"", (nOrigin == 1) ? "parent" : (nOrigin == 2) ? "layout" : "unknown" );
2119 #endif
2121 break;
2123 case DFF_msofbtAnimAttributeValue:
2125 Any aPath;
2126 if ( importAttributeValue( pChildAtom, aPath ) )
2128 OUString aStr;
2129 if ( aPath >>= aStr )
2131 // E can appear inside a number, so we only check for its presence at the end
2132 aStr = aStr.trim();
2133 if (aStr.endsWith("E"))
2134 aStr = aStr.copy(0, aStr.getLength() - 1);
2135 aStr = aStr.trim();
2136 aPath <<= aStr;
2137 xMotion->setPath( aPath );
2138 dump( " path=\"" );
2139 dump( aPath );
2140 dump( "\"" );
2144 break;
2146 case DFF_msofbtAnimateTarget:
2147 importAnimateAttributeTargetContainer( pChildAtom, xNode );
2148 break;
2150 default:
2151 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
2152 break;
2155 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
2160 // --------------------------------------------------------------------
2162 void AnimationImporter::importCommandContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2164 Reference< XCommand > xCommand( xNode, UNO_QUERY );
2165 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimCommand && xCommand.is(), "invalid call to ppt::AnimationImporter::importCommandContainer()!");
2166 if( pAtom && xCommand.is() )
2168 sal_Int32 nBits = 0, nType = 0;
2169 Any aValue;
2171 const Atom* pChildAtom = pAtom->findFirstChildAtom();
2173 while( pChildAtom )
2175 if( !pChildAtom->isContainer() )
2177 if( !pChildAtom->seekToContent() )
2178 break;
2181 switch( pChildAtom->getType() )
2183 case DFF_msofbtCommandData:
2185 sal_Int32 nCommandType;
2186 // looks like U1 is a bitset, bit 1 enables the type and bit 2 enables
2187 // a propertyvalue that follows
2188 mrStCtrl >> nBits;
2189 mrStCtrl >> nCommandType;
2191 if( nBits & 1 )
2193 dump( " type=\"%s\"", (nCommandType == 0) ? "event" : ( nCommandType == 1) ? "call" : "verb" );
2196 break;
2198 case DFF_msofbtAnimAttributeValue:
2200 if ( importAttributeValue( pChildAtom, aValue ) )
2202 if( nBits & 2 )
2204 dump( " cmd=\"" );
2205 dump( aValue );
2206 dump( "\"" );
2210 break;
2212 case DFF_msofbtAnimateTarget:
2213 importAnimateAttributeTargetContainer( pChildAtom, xNode );
2214 break;
2216 default:
2217 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
2218 break;
2221 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
2224 if( nBits & 3 )
2226 OUString aParam;
2227 aValue >>= aParam;
2229 sal_Int16 nCommand = EffectCommands::CUSTOM;
2231 NamedValue aParamValue;
2233 switch( nType )
2235 case 0: // event
2236 case 1: // call
2237 if ( aParam == "onstopaudio" )
2239 nCommand = EffectCommands::STOPAUDIO;
2241 else if ( aParam == "play" )
2243 nCommand = EffectCommands::PLAY;
2245 else if( aParam.startsWith( "playFrom" ) )
2247 const OUString aMediaTime( aParam.copy( 9, aParam.getLength() - 10 ) );
2248 rtl_math_ConversionStatus eStatus;
2249 double fMediaTime = ::rtl::math::stringToDouble( aMediaTime, (sal_Unicode)('.'), (sal_Unicode)(','), &eStatus, NULL );
2250 if( eStatus == rtl_math_ConversionStatus_Ok )
2252 aParamValue.Name = "MediaTime";
2253 aParamValue.Value <<= fMediaTime;
2255 nCommand = EffectCommands::PLAY;
2257 else if ( aParam == "togglePause" )
2259 nCommand = EffectCommands::TOGGLEPAUSE;
2261 else if ( aParam == "stop" )
2263 nCommand = EffectCommands::STOP;
2265 break;
2266 case 2: // verb
2268 aParamValue.Name = "Verb";
2269 aParamValue.Value <<= aParam.toInt32();
2271 nCommand = EffectCommands::VERB;
2273 break;
2276 xCommand->setCommand( nCommand );
2277 if( nCommand == EffectCommands::CUSTOM )
2279 OSL_FAIL("sd::AnimationImporter::importCommandContainer(), unknown command!");
2280 aParamValue.Name = "UserDefined";
2281 aParamValue.Value <<= aParam;
2284 if( aParamValue.Value.hasValue() )
2286 Sequence< NamedValue > aParamSeq( &aParamValue, 1 );
2287 xCommand->setParameter( makeAny( aParamSeq ) );
2293 // --------------------------------------------------------------------
2295 int AnimationImporter::importAudioContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2297 int nNodes = 0;
2299 Reference< XAudio > xAudio( xNode, UNO_QUERY );
2300 DBG_ASSERT( pAtom && xAudio.is() &&
2301 ( (pAtom->getType() == DFF_msofbtAnimGroup) ||
2302 (pAtom->getType() == DFF_msofbtAnimSubGoup) ), "invalid call to ppt::AnimationImporter::importAudioContainer()!");
2303 if( pAtom && xAudio.is() )
2305 importAnimationEvents( pAtom, xNode );
2306 importAnimationValues( pAtom, xNode );
2307 importAnimationActions( pAtom, xNode );
2309 dump(">\n");
2311 const Atom* pChildAtom = pAtom->findFirstChildAtom();
2313 while( pChildAtom )
2315 if( !pChildAtom->isContainer() )
2317 if( !pChildAtom->seekToContent() )
2318 break;
2321 switch( pChildAtom->getType() )
2323 case DFF_msofbtAnimNode:
2324 case DFF_msofbtAnimEvent:
2325 case DFF_msofbtAnimValue:
2326 case DFF_msofbtAnimAction:
2327 case DFF_msofbtAnimPropertySet:
2328 break;
2330 case DFF_msofbtAnimAttributeValue:
2332 Any aValue;
2333 if ( importAttributeValue( pChildAtom, aValue ) )
2335 nNodes ++;
2336 dump( " value=\"" );
2337 dump( aValue );
2338 dump( "\"" );
2341 break;
2343 case DFF_msofbtAnimateTargetElement:
2345 sal_Int16 nSubType;
2346 Any aSource;
2347 importTargetElementContainer( pChildAtom, aSource, nSubType );
2348 if( xAudio.is() ) {
2349 xAudio->setSource( aSource );
2350 nNodes ++;
2353 break;
2355 default:
2356 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
2357 break;
2360 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
2363 // TODO: What to do with them?
2364 Any aEmpty;
2365 xAudio->setBegin( aEmpty );
2366 xAudio->setEnd( aEmpty );
2369 return nNodes;
2372 // --------------------------------------------------------------------
2374 void AnimationImporter::importAnimateScaleContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2376 Reference< XAnimateTransform > xTransform( xNode, UNO_QUERY );
2378 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateScale && xTransform.is(), "invalid call to ppt::AnimationImporter::importAnimateScaleContainer()!");
2379 if( pAtom && xTransform.is() )
2381 xTransform->setTransformType( AnimationTransformType::SCALE );
2383 const Atom* pChildAtom = pAtom->findFirstChildAtom();
2385 while( pChildAtom )
2387 if( !pChildAtom->isContainer() )
2389 if( !pChildAtom->seekToContent() )
2390 break;
2393 switch( pChildAtom->getType() )
2395 case DFF_msofbtAnimateScaleData:
2397 sal_uInt32 nBits, nZoomContents;
2398 float fByX, fByY, fFromX, fFromY, fToX, fToY;
2400 // nBits %001: by, %010: from, %100: to, %1000: zoomContents(bool)
2401 mrStCtrl >> nBits >> fByX >> fByY >> fFromX >> fFromY >> fToX >> fToY >> nZoomContents;
2403 ValuePair aPair;
2404 // 'from' value
2405 if( nBits & 2 )
2407 aPair.First <<= (double)fFromX / 100.0;
2408 aPair.Second <<= (double)fFromY / 100.0;
2409 xTransform->setFrom( makeAny( aPair ) );
2412 // 'to' value
2413 if( nBits & 4 )
2415 aPair.First <<= (double)fToX / 100.0;
2416 aPair.Second <<= (double)fToY / 100.0;
2417 xTransform->setTo( makeAny( aPair ) );
2420 // 'by' value
2421 if( nBits & 1 )
2423 aPair.First <<= (double)fByX / 100.0;
2424 aPair.Second <<= (double)fByY / 100.0;
2426 if( nBits & 2 )
2428 // 'from' value given, import normally
2429 xTransform->setBy( makeAny( aPair ) );
2431 else
2433 // mapping 'by' to 'to', if no 'from' is
2434 // given. This is due to a non-conformity in
2435 // PPT, which exports animateScale effects
2436 // with a sole 'by' value, but with the
2437 // semantics of a sole 'to' animation
2438 xTransform->setTo( makeAny( aPair ) );
2443 #ifdef DBG_ANIM_LOG
2444 if( nBits & 1 )
2445 fprintf( mpFile, " by=\"%g,%g\"", (double)fByX, (double)fByY );
2447 if( nBits & 2 )
2448 fprintf( mpFile, " from=\"%g,%g\"", (double)fFromX, (double)fFromY );
2450 if( nBits & 4 )
2451 fprintf( mpFile, " to=\"%g,%g\"", (double)fToX, (double)fToY );
2453 if( nBits & 8 )
2454 fprintf( mpFile, " zoomContents=\"%s\"", nZoomContents ? "true" : "false" );
2455 #endif
2457 break;
2459 case DFF_msofbtAnimateTarget:
2460 importAnimateAttributeTargetContainer( pChildAtom, xNode );
2461 break;
2463 default:
2464 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
2465 break;
2468 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
2473 // --------------------------------------------------------------------
2475 void AnimationImporter::importAnimateRotationContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2477 Reference< XAnimateTransform > xTransform( xNode, UNO_QUERY );
2479 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateRotation && xTransform.is(), "invalid call to ppt::AnimationImporter::importAnimateRotationContainer()!");
2480 if( pAtom && xTransform.is() )
2482 xTransform->setTransformType( AnimationTransformType::ROTATE );
2484 const Atom* pChildAtom = pAtom->findFirstChildAtom();
2486 while( pChildAtom )
2488 if( !pChildAtom->isContainer() )
2490 if( !pChildAtom->seekToContent() )
2491 break;
2494 switch( pChildAtom->getType() )
2496 case DFF_msofbtAnimateRotationData:
2498 sal_uInt32 nBits, nU1;
2499 float fBy, fFrom, fTo;
2501 // nBits %001: by, %010: from, %100: to, %1000: zoomContents(bool)
2502 mrStCtrl >> nBits >> fBy >> fFrom >> fTo >> nU1;
2504 if( nBits & 1 )
2505 xTransform->setBy( makeAny( (double) fBy ) );
2507 if( nBits & 2 )
2508 xTransform->setFrom( makeAny( (double) fFrom ) );
2510 if( nBits & 4 )
2511 xTransform->setTo( makeAny( (double) fTo ) );
2513 #ifdef DBG_ANIM_LOG
2514 if( nBits & 1 )
2515 fprintf( mpFile, " by=\"%g\"", (double)fBy );
2517 if( nBits & 2 )
2518 fprintf( mpFile, " from=\"%g\"", (double)fFrom );
2520 if( nBits & 4 )
2521 fprintf( mpFile, " to=\"%g\"", (double)fTo );
2523 if( nU1 )
2524 fprintf( mpFile, " rotation_1=\"%ld\"", nU1 );
2525 #endif
2527 break;
2529 case DFF_msofbtAnimateTarget:
2530 importAnimateAttributeTargetContainer( pChildAtom, xNode );
2531 break;
2533 default:
2534 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
2535 break;
2538 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
2542 // --------------------------------------------------------------------
2544 bool AnimationImporter::importAttributeNamesContainer( const Atom* pAtom, OUString& rAttributeNames )
2546 OUStringBuffer aNames;
2548 DBG_ASSERT( pAtom && (pAtom->getType() == DFF_msofbtAnimateAttributeNames), "invalid call to ppt::AnimationImporter::importAttributeName()!" );
2549 if( pAtom )
2551 const Atom* pAttributeValueAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimAttributeValue );
2553 while( pAttributeValueAtom )
2555 Any aAny;
2556 if ( importAttributeValue( pAttributeValueAtom, aAny ) )
2558 OUString aName;
2559 if( aAny >>= aName )
2561 if( aNames.getLength() )
2562 aNames.append( (sal_Unicode)';' );
2564 aNames.append( aName );
2567 else
2569 OSL_FAIL( "error during ppt::AnimationImporter::importAttributeName()!" );
2572 pAttributeValueAtom = pAtom->findNextChildAtom( DFF_msofbtAnimAttributeValue, pAttributeValueAtom );
2576 rAttributeNames = aNames.makeStringAndClear();
2577 return true;
2580 // --------------------------------------------------------------------
2582 void AnimationImporter::importAnimationValues( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2584 DBG_ASSERT( pAtom, "invalid call to ppt::AnimationImporter::importAnimationValues()!" );
2586 if( pAtom )
2588 const Atom* pValueAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimValue );
2590 while( pValueAtom && pValueAtom->seekToContent() )
2592 sal_uInt32 nType;
2593 mrStCtrl >> nType;
2594 switch( nType )
2596 case 0:
2598 float fRepeat;
2599 mrStCtrl >> fRepeat;
2600 xNode->setRepeatCount( (fRepeat < ((float)3.40282346638528860e+38)) ? makeAny( (double)fRepeat ) : makeAny( Timing_INDEFINITE ) );
2602 #ifdef DBG_ANIM_LOG
2603 if( (fRepeat < ((float)3.40282346638528860e+38)) )
2605 dump( " repeat=\"%g\"", (double)fRepeat );
2607 else
2609 dump( " repeat=\"indefinite\"" );
2611 #endif
2613 break;
2615 case 3:
2617 float faccelerate;
2618 mrStCtrl >> faccelerate;
2619 xNode->setAcceleration( faccelerate );
2620 dump( " accelerate=\"%g\"", (double)faccelerate );
2622 break;
2624 case 4:
2626 float fdecelerate;
2627 mrStCtrl >> fdecelerate;
2628 xNode->setDecelerate( fdecelerate );
2629 dump( " decelerate=\"%g\"", (double)fdecelerate );
2631 break;
2633 case 5:
2635 sal_Int32 nAutoreverse;
2636 mrStCtrl >> nAutoreverse;
2637 xNode->setAutoReverse( nAutoreverse != 0 );
2638 dump( " autoreverse=\"%#lx\"", nAutoreverse );
2640 break;
2642 default:
2644 sal_uInt32 nUnknown;
2645 mrStCtrl >> nUnknown;
2646 #ifdef DBG_ANIM_LOG
2647 fprintf(mpFile, " attribute_%d=\"%#lx\"", nType, nUnknown );
2648 #endif
2650 break;
2653 pValueAtom = pAtom->findNextChildAtom( DFF_msofbtAnimValue, pValueAtom );
2658 // --------------------------------------------------------------------
2660 void AnimationImporter::importAnimateKeyPoints( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2662 Reference< XAnimate > xAnim( xNode, UNO_QUERY );
2664 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimKeyPoints && xAnim.is(), "invalid call to ppt::AnimationImporter::importAnimateKeyPoints()!" );
2666 if( pAtom && xAnim.is() )
2668 // first count keytimes
2669 const Atom* pIter = NULL;
2670 int nKeyTimes = 0;
2672 while( (pIter = pAtom->findNextChildAtom( DFF_msofbtAnimKeyTime, pIter )) != 0 )
2673 nKeyTimes++;
2675 Sequence< double > aKeyTimes( nKeyTimes );
2676 Sequence< Any > aValues( nKeyTimes );
2677 OUString aFormula;
2679 pIter = pAtom->findFirstChildAtom(DFF_msofbtAnimKeyTime);
2680 int nKeyTime;
2681 sal_Int32 nTemp;
2682 for( nKeyTime = 0; (nKeyTime < nKeyTimes) && pIter; nKeyTime++ )
2684 if( pIter->seekToContent() )
2686 mrStCtrl >> nTemp;
2687 double fTemp = (double)nTemp / 1000.0;
2688 aKeyTimes[nKeyTime] = fTemp;
2690 const Atom* pValue = pAtom->findNextChildAtom(pIter);
2691 if( pValue && pValue->getType() == DFF_msofbtAnimAttributeValue )
2693 Any aValue1, aValue2;
2694 if( importAttributeValue( pValue, aValue1 ) )
2696 pValue = pAtom->findNextChildAtom(pValue);
2697 if( pValue && pValue->getType() == DFF_msofbtAnimAttributeValue )
2698 importAttributeValue( pValue, aValue2 );
2700 bool bCouldBeFormula = false;
2701 bool bHasValue = aValue2.hasValue();
2702 if( bHasValue )
2704 if( aValue2.getValueType() == ::getCppuType((const OUString*)0) )
2706 OUString aTest;
2707 aValue2 >>= aTest;
2708 bHasValue = !aTest.isEmpty();
2709 bCouldBeFormula = true;
2713 if( bHasValue && bCouldBeFormula && (aValue1.getValueType() == ::getCppuType((const double*)0)) )
2715 aValue2 >>= aFormula;
2716 bHasValue = false;
2719 if( bHasValue )
2721 aValues[nKeyTime] = makeAny( ValuePair( aValue1, aValue2 ) );
2723 else
2725 aValues[nKeyTime] = aValue1;
2730 pIter = pAtom->findNextChildAtom(DFF_msofbtAnimKeyTime, pIter);
2733 #ifdef DBG_ANIM_LOG
2734 dump( " keyTimes=\"" );
2735 for( int i=0; i<nKeyTimes; ++i )
2736 dump( "%f;", aKeyTimes[i] );
2738 if( !aFormula.isEmpty() )
2740 dump( "formula=\"%s", aFormula );
2743 dump( "\" values=\"" );
2744 double nVal;
2745 OUString aStr;
2746 for( int i=0; i<nKeyTimes; ++i )
2748 if( i != 0 )
2749 dump( ";" );
2751 if( aValues[i] >>= aStr )
2752 dump( "%s",
2753 OUStringToOString( aStr,
2754 RTL_TEXTENCODING_ASCII_US ).getStr() );
2755 else if( aValues[i] >>= nVal )
2756 dump( "%f", nVal );
2757 else
2759 ValuePair aValuePair;
2761 if( aValues[i] >>= aValuePair )
2763 if( aValuePair.First >>= aStr )
2764 dump( "%s",
2765 OUStringToOString( aStr,
2766 RTL_TEXTENCODING_ASCII_US ).getStr() );
2767 else if( aValuePair.First >>= nVal )
2768 dump( "%f", nVal );
2769 else
2770 dump( "%X", (sal_Int64)&aValuePair.First );
2772 if( aValuePair.Second >>= aStr )
2773 dump( ",%s",
2774 OUStringToOString( aStr,
2775 RTL_TEXTENCODING_ASCII_US ).getStr() );
2776 else if( aValuePair.Second >>= nVal )
2777 dump( ",%f", nVal );
2778 else
2779 dump( ",%X", (sal_Int64)&aValuePair.Second );
2783 dump( "\"" );
2784 #endif
2786 xAnim->setKeyTimes( aKeyTimes );
2787 xAnim->setValues( aValues );
2788 xAnim->setFormula( aFormula );
2792 // --------------------------------------------------------------------
2794 bool AnimationImporter::importAttributeValue( const Atom* pAtom, Any& rAny )
2796 DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimAttributeValue, "invalid call to ppt::AnimationImporter::importAttributeValue()!" );
2798 bool bOk = false;
2800 if( pAtom && pAtom->seekToContent() )
2802 sal_uInt32 nRecLen = pAtom->getLength();
2803 if ( nRecLen >= 1 )
2805 sal_Int8 nType;
2806 mrStCtrl >> nType;
2807 switch( nType )
2809 case DFF_ANIM_PROP_TYPE_BYTE :
2811 if ( nRecLen == 2 )
2813 sal_uInt8 nByte;
2814 mrStCtrl >> nByte;
2815 rAny <<= nByte;
2817 bOk = true;
2820 break;
2822 case DFF_ANIM_PROP_TYPE_INT32 :
2824 if ( nRecLen == 5 )
2826 sal_uInt32 nInt32;
2827 mrStCtrl >> nInt32;
2828 rAny <<= nInt32;
2830 bOk = true;
2833 break;
2835 case DFF_ANIM_PROP_TYPE_FLOAT:
2837 if( nRecLen == 5 )
2839 float fFloat;
2840 mrStCtrl >> fFloat;
2841 rAny <<= (double)fFloat;
2843 bOk = true;
2846 break;
2848 case DFF_ANIM_PROP_TYPE_UNISTRING :
2850 if ( ( nRecLen & 1 ) && ( nRecLen > 1 ) )
2852 OUString aOUString = mpPPTImport->MSDFFReadZString( mrStCtrl, nRecLen - 1, sal_True );
2853 rAny <<= aOUString;
2855 bOk = true;
2858 break;
2863 DBG_ASSERT( bOk, "invalid value inside ppt::AnimationImporter::importAttributeValue()!" );
2864 return bOk;
2867 // --------------------------------------------------------------------
2869 void AnimationImporter::importAnimationEvents( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2871 DBG_ASSERT( xNode.is() && pAtom, "invalid call to ppt::AnimationImporter::importAnimationEvents()!" );
2873 Any aBegin, aEnd, aNext, aPrev;
2875 const Atom* pEventAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimEvent );
2876 while( pEventAtom )
2878 Any* pEvents = NULL;
2880 switch( pEventAtom->getInstance() )
2882 case 1: pEvents = &aBegin; break;
2883 case 2: pEvents = &aEnd; break;
2884 case 3: pEvents = &aNext; break;
2885 case 4: pEvents = &aPrev; break;
2888 if( pEvents )
2890 Event aEvent;
2891 aEvent.Trigger = EventTrigger::NONE;
2892 aEvent.Repeat = 0;
2894 const Atom* pChildAtom = pEventAtom->findFirstChildAtom();
2896 while( pChildAtom && pChildAtom->seekToContent() )
2898 switch( pChildAtom->getType() )
2900 case DFF_msofbtAnimTrigger:
2902 sal_Int32 nU1, nTrigger, nU3, nBegin;
2903 mrStCtrl >> nU1;
2904 mrStCtrl >> nTrigger;
2905 mrStCtrl >> nU3;
2906 mrStCtrl >> nBegin;
2908 switch( nTrigger )
2910 case 0: aEvent.Trigger = EventTrigger::NONE; break;
2911 case 1: aEvent.Trigger = EventTrigger::ON_BEGIN; break;
2912 case 2: aEvent.Trigger = EventTrigger::ON_END; break;
2913 case 3: aEvent.Trigger = EventTrigger::BEGIN_EVENT; break;
2914 case 4: aEvent.Trigger = EventTrigger::END_EVENT; break;
2915 case 5: aEvent.Trigger = EventTrigger::ON_CLICK; break;
2916 case 6: aEvent.Trigger = EventTrigger::ON_DBL_CLICK; break;
2917 case 7: aEvent.Trigger = EventTrigger::ON_MOUSE_ENTER; break;
2918 case 8: aEvent.Trigger = EventTrigger::ON_MOUSE_LEAVE; break;
2919 case 9: aEvent.Trigger = EventTrigger::ON_NEXT; break;
2920 case 10: aEvent.Trigger = EventTrigger::ON_PREV; break;
2921 case 11: aEvent.Trigger = EventTrigger::ON_STOP_AUDIO; break;
2924 if( (nBegin != 0) || (aEvent.Trigger == EventTrigger::NONE) )
2925 aEvent.Offset = (nBegin == -1) ? makeAny( Timing_INDEFINITE ) : makeAny( (double)(nBegin / 1000.0) );
2927 break;
2928 case DFF_msofbtAnimateTargetElement:
2930 sal_Int16 nSubType;
2931 importTargetElementContainer( pChildAtom, aEvent.Source, nSubType );
2933 break;
2934 default:
2936 OSL_FAIL("unknown atom inside ppt::AnimationImporter::importAnimationEvents()!");
2940 pChildAtom = pEventAtom->findNextChildAtom( pChildAtom );
2943 *pEvents = addToSequence( *pEvents, (aEvent.Trigger == EventTrigger::NONE) ? aEvent.Offset : makeAny( aEvent ) );
2946 pEventAtom = pAtom->findNextChildAtom( DFF_msofbtAnimEvent, pEventAtom );
2949 xNode->setBegin( aBegin );
2950 xNode->setEnd( aEnd );
2951 // TODO: xNode->setNext( aNext );
2952 // TODO: xNode->setPrev( aNext );
2954 #ifdef DBG_ANIM_LOG
2955 if( aBegin.hasValue() )
2957 dump( " begin=\"" );
2958 dump( aBegin );
2959 dump( "\"" );
2962 if( aEnd.hasValue() )
2964 dump( " end=\"" );
2965 dump( aEnd );
2966 dump( "\"" );
2969 if( aNext.hasValue() )
2971 dump( " next=\"" );
2972 dump( aNext );
2973 dump( "\"" );
2976 if( aPrev.hasValue() )
2978 dump( " prev=\"" );
2979 dump( aPrev );
2980 dump( "\"" );
2982 #endif
2985 // --------------------------------------------------------------------
2987 void AnimationImporter::importAnimationActions( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2989 DBG_ASSERT( pAtom && xNode.is(), "invalid call to ppt::AnimationImporter::importAnimationActions()!");
2991 if( pAtom )
2993 const Atom* pActionAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimAction );
2995 if( pActionAtom && pActionAtom->seekToContent() )
2997 sal_Int32 nConcurrent, nNextAction, nEndSync, nU4, nU5;
2998 mrStCtrl >> nConcurrent;
2999 mrStCtrl >> nNextAction;
3000 mrStCtrl >> nEndSync;
3001 mrStCtrl >> nU4;
3002 mrStCtrl >> nU5;
3004 if( nEndSync == 1 )
3005 xNode->setEndSync( makeAny( AnimationEndSync::ALL ) );
3007 #ifdef DBG_ANIM_LOG
3008 dump( " concurrent=\"%s\"", nConcurrent == 0 ? "disabled" : (nConcurrent == 1 ? "enabled" : "unknown") );
3010 dump( " nextAction=\"%s\"", nNextAction == 0 ? "none" : (nNextAction == 1 ? "seek" : "unknown") );
3012 if( nEndSync != 0 )
3014 dump( " endSync=\"%s\"", nEndSync == 1 ? "all" : "unknown" );
3017 dump( " action_4=\"%#lx\"", nU4 );
3018 dump( " action_5=\"%#lx\"", nU5 );
3019 #endif
3024 // --------------------------------------------------------------------
3026 sal_Int32 AnimationImporter::importTargetElementContainer( const Atom* pAtom, Any& rTarget, sal_Int16& rSubType )
3028 rSubType = ShapeAnimationSubType::AS_WHOLE;
3029 sal_Int32 nRefMode = -1;
3031 DBG_ASSERT( pAtom && (pAtom->getType() == DFF_msofbtAnimateTargetElement), "invalid call to ppt::AnimationImporter::importTargetElementContainer()!" );
3032 if( pAtom )
3034 const Atom* pChildAtom = pAtom->findFirstChildAtom();
3035 while( pChildAtom && pChildAtom->seekToContent() )
3037 switch( pChildAtom->getType() )
3039 case DFF_msofbtAnimReference:
3041 sal_Int32 nRefType,nRefId;
3042 sal_Int32 begin,end;
3043 mrStCtrl >> nRefMode;
3044 mrStCtrl >> nRefType;
3045 mrStCtrl >> nRefId;
3046 mrStCtrl >> begin;
3047 mrStCtrl >> end;
3049 switch( nRefType )
3051 case 1: // shape
3053 SdrObject* pSdrObject = mpPPTImport->getShapeForId( nRefId );
3054 if( pSdrObject == NULL )
3055 break;
3057 rTarget <<= pSdrObject->getUnoShape();
3059 switch( nRefMode )
3061 case 6: rSubType = ShapeAnimationSubType::ONLY_BACKGROUND; break;
3062 case 8: rSubType = ShapeAnimationSubType::ONLY_TEXT; break;
3063 case 2: // one paragraph
3065 if( ((begin == -1) && (end == -1)) || !pSdrObject->ISA( SdrTextObj ) )
3066 break;
3068 SdrTextObj* pTextObj = static_cast< SdrTextObj* >( pSdrObject );
3070 const OutlinerParaObject* pOPO = pTextObj->GetOutlinerParaObject();
3071 if( pOPO == NULL )
3072 break;
3074 const EditTextObject& rEditTextObject = pOPO->GetTextObject();
3076 const sal_Int32 nParaCount = rEditTextObject.GetParagraphCount();
3078 sal_Int32 nPara = 0;
3080 while( (nPara < nParaCount) && (begin > 0) )
3082 sal_Int32 nParaLength = rEditTextObject.GetText( nPara ).Len() + 1;
3083 begin -= nParaLength;
3084 end -= nParaLength;
3085 nPara++;
3088 if( nPara < nParaCount )
3090 ParagraphTarget aParaTarget;
3091 rTarget >>= aParaTarget.Shape;
3092 /* FIXME: Paragraph should be sal_Int32 as well */
3093 aParaTarget.Paragraph = static_cast<sal_Int16>(nPara);
3094 rTarget = makeAny( aParaTarget );
3096 rSubType = ShapeAnimationSubType::ONLY_TEXT;
3097 dump( " paragraph %d,", (sal_Int32)nPara);
3098 dump( " %d characters", (sal_Int32)end );
3103 break;
3105 case 2: // sound
3107 OUString aSoundURL( ((ImplSdPPTImport*)mpPPTImport)->ReadSound( nRefId ) );
3108 rTarget <<= aSoundURL;
3109 dump( " srcRef=\"%s\"", aSoundURL );
3111 break;
3112 case 3: // audio object
3113 case 4: // video object
3115 SdrObject* pSdrObject = mpPPTImport->getShapeForId( nRefId );
3116 if( pSdrObject == NULL )
3117 break;
3119 rTarget <<= pSdrObject->getUnoShape();
3121 break;
3122 default:
3123 OSL_FAIL("unknown reference type");
3127 break;
3128 case 0x2b01:
3130 sal_Int32 nU1;
3131 mrStCtrl >> nU1;
3133 break;
3134 default:
3135 OSL_FAIL("unknown atom inside ppt::AnimationImporter::importTargetElementContainer()!");
3136 break;
3139 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
3144 return nRefMode;
3147 // --------------------------------------------------------------------
3149 void AnimationImporter::importPropertySetContainer( const Atom* pAtom, PropertySet& rSet )
3151 DBG_ASSERT( pAtom && (pAtom->getType() == DFF_msofbtAnimPropertySet), "invalid call to ppt::AnimationImporter::importPropertySetContainer()!" );
3153 if( pAtom )
3155 const Atom* pChildAtom = pAtom->findFirstChildAtom();
3156 while( pChildAtom )
3158 if( pChildAtom->getType() == DFF_msofbtAnimAttributeValue )
3160 Any aAny;
3161 importAttributeValue( pChildAtom, aAny );
3162 rSet.maProperties[ pChildAtom->getInstance() ] = aAny;
3164 else
3166 OSL_FAIL("unknown atom inside ppt::AnimationImporter::importPropertySetContainer()!");
3169 pChildAtom = pAtom->findNextChildAtom( pChildAtom );
3174 // ====================================================================
3176 #ifdef DBG_ANIM_LOG
3177 void AnimationImporter::dump_atom_header( const Atom* pAtom, bool bOpen, bool bAppend )
3179 if( pAtom )
3181 const char* pTitle;
3183 switch( pAtom->getType() )
3185 case DFF_msofbtAnimEvent: pTitle = "AnimEvent"; break;
3186 case DFF_msofbtAnimTrigger: pTitle = "AnimTrigger"; break;
3187 case DFF_msofbtAnimateMotion: pTitle = "AnimateMotion"; break;
3188 case DFF_msofbtAnimPropertySet: pTitle = "AnimPropertySet"; break;
3189 case DFF_msofbtAnimateAttributeNames: pTitle = "AnimAttributeName"; break;
3190 case DFF_msofbtAnimAttributeValue: pTitle = "AnimAttributeValue"; break;
3191 case DFF_msofbtAnimGroup: pTitle = "AnimGroup"; break;
3192 case DFF_msofbtAnimNode: pTitle = "AnimNode"; break;
3193 case DFF_msofbtAnimValue: pTitle = "AnimValue"; break;
3194 case DFF_msofbtAnimateFilter: pTitle = "animateFilter"; break;
3195 case DFF_msofbtAnimate: pTitle = "animate"; break;
3196 case DFF_msofbtAnimateSet: pTitle = "set"; break;
3197 case DFF_msofbtAnimKeyTime: pTitle = "AnimKeyTime"; break;
3198 case DFF_msofbtAnimKeyPoints: pTitle = "AnimKeyPoints"; break;
3199 case DFF_msofbtAnimReference: pTitle = "AnimReference"; break;
3200 case DFF_msofbtAnimateTargetElement: pTitle = "AnimTargetElementContainer"; break;
3201 case DFF_msofbtAnimAction: pTitle = "AnimAction"; break;
3202 case DFF_msofbtAnimCommand: pTitle = "AnimCommand"; break;
3203 case DFF_msofbtAnimateTarget: pTitle = "TransformationTarget"; break;
3204 case DFF_msofbtAnimateTargetSettings: pTitle = "TransformationTargetSettings"; break;
3205 case DFF_msofbtAnimIteration: pTitle = "iterate"; break;
3206 case DFF_msofbtAnimateColorData: pTitle = "colorData"; break;
3207 case DFF_msofbtAnimateScaleData: pTitle = "scaleData"; break;
3208 case DFF_msofbtAnimateSetData: pTitle = "setData"; break;
3210 default:
3212 static char buffer[128];
3213 sprintf( buffer, "unknown_%#x", pAtom->getType() );
3214 pTitle = buffer;
3218 if( bOpen )
3220 fprintf(mpFile, "<%s", pTitle );
3222 fprintf(mpFile, " instance=\"%hu\"%s",
3223 pAtom->getInstance(),
3224 bAppend ? "" : ">\n");
3226 else
3228 if( bAppend )
3229 fprintf(mpFile,"/>\n");
3230 else
3231 fprintf(mpFile, "</%s>\n", pTitle );
3236 // --------------------------------------------------------------------
3238 void AnimationImporter::dump( sal_uInt32 nLen, bool bNewLine )
3240 char * faul = "0123456789abcdef";
3242 sal_uInt32 i = 0;
3243 int b = 0;
3244 sal_Int8 nData;
3246 for( i = 0; i < nLen; i++ )
3248 mrStCtrl >> nData;
3250 fprintf( mpFile, "%c%c ", faul[ (nData >> 4) & 0x0f ], faul[ nData & 0x0f ] );
3252 b++;
3253 if( bNewLine && (b == 32) )
3255 fprintf(mpFile,"\n");
3256 b = 0;
3259 if( (b != 0) && bNewLine )
3260 fprintf(mpFile,"\n");
3263 // --------------------------------------------------------------------
3265 void AnimationImporter::dump_atom( const Atom* pAtom, bool bNewLine )
3267 if( pAtom )
3269 if( pAtom->isContainer() )
3271 const Atom* pChildAtom = pAtom->findFirstChildAtom();
3272 while( pChildAtom )
3274 if( pChildAtom->getType() == DFF_msofbtAnimAttributeValue )
3276 fprintf(mpFile, "<attributeValue instance=\"%hu\"", pChildAtom->getInstance() );
3278 Any aValue;
3279 if( importAttributeValue( pChildAtom, aValue ) )
3281 sal_Int32 nInt;
3282 OUString aString;
3283 double fDouble;
3285 if( aValue >>= nInt )
3287 fprintf(mpFile, " value=\"%ld\"", nInt );
3289 else if( aValue >>= aString )
3291 fprintf(mpFile, " value=\"%s\"",
3292 OUStringToOString(aString,
3293 RTL_TEXTENCODING_UTF8).getStr());
3295 else if( aValue >>= fDouble )
3297 fprintf(mpFile, " value=\"%g\"", fDouble );
3300 else
3302 if( pChildAtom->seekToContent() )
3304 fprintf(mpFile, " value=\"" );
3305 dump_atom( pChildAtom, false );
3306 fprintf(mpFile, "\"");
3310 fprintf(mpFile, "/>\n" );
3312 else
3314 dump_atom_header( pChildAtom, true, pChildAtom->getType() == DFF_msofbtAnimAttributeValue );
3315 dump_atom( pChildAtom );
3316 dump_atom_header( pChildAtom, false, pChildAtom->getType() == DFF_msofbtAnimAttributeValue );
3319 pChildAtom = pAtom->findNextChildAtom(pChildAtom);
3322 else if( pAtom->seekToContent() )
3324 dump( pAtom->getLength(), bNewLine );
3329 // --------------------------------------------------------------------
3331 void AnimationImporter::dump_anim_group( const Atom* pAtom, const AnimationNode& rNode, const PropertySet& rSet, bool bOpen )
3333 fprintf( mpFile, bOpen ? "<" : "</" );
3335 switch( rNode.mnGroupType )
3337 case mso_Anim_GroupType_PAR:
3338 fprintf( mpFile, "par" );
3339 break;
3340 case mso_Anim_GroupType_SEQ:
3341 fprintf( mpFile, "seq" );
3342 break;
3343 case mso_Anim_GroupType_NODE:
3344 switch( rNode.mnNodeType )
3346 case mso_Anim_Behaviour_FILTER:
3347 fprintf( mpFile, "animateFilter" );
3348 break;
3349 case mso_Anim_Behaviour_ANIMATION:
3350 if( pAtom->hasChildAtom( DFF_msofbtAnimateSet ) )
3351 fprintf( mpFile, "set" );
3352 else if( pAtom->hasChildAtom( DFF_msofbtAnimateColor ) )
3353 fprintf( mpFile, "animateColor" );
3354 else if( pAtom->hasChildAtom( DFF_msofbtAnimateScale ) )
3355 fprintf( mpFile, "animateScale" );
3356 else if( pAtom->hasChildAtom( DFF_msofbtAnimateRotation ) )
3357 fprintf( mpFile, "animateRotation" );
3358 else if( pAtom->hasChildAtom( DFF_msofbtAnimateMotion ) )
3359 fprintf( mpFile, "animateMotion" );
3360 else if( pAtom->hasChildAtom( DFF_msofbtAnimCommand ) )
3361 fprintf( mpFile, "command" );
3362 else
3363 fprintf( mpFile, "animation" );
3364 break;
3365 default:
3367 fprintf( mpFile, "unknown_node_%#lx", rNode.mnNodeType );
3369 break;
3371 break;
3372 case mso_Anim_GroupType_MEDIA:
3373 fprintf( mpFile, "media" );
3374 break;
3375 default:
3376 fprintf( mpFile, "unknown_group_%#lx", rNode.mnGroupType );
3377 break;
3380 if( bOpen )
3382 dump( rNode );
3383 dump( rSet );
3386 fprintf(mpFile,">\n");
3389 void AnimationImporter::dump( const AnimationNode& rNode )
3391 // dump animation node
3392 if( rNode.mnRestart != 0 )
3394 fprintf(mpFile," restart=\"%s\"",
3395 rNode.mnRestart == 1 ? "always" : (rNode.mnRestart == 2 ? "whenOff" : (rNode.mnRestart == 3 ? "never" : "unknown")) );
3398 if( rNode.mnFill )
3400 fprintf(mpFile," fill=\"%s\"",
3401 rNode.mnFill == 1 ? "remove" : (rNode.mnFill == 3 ? "hold" : (rNode.mnFill == 2 ? "freeze" : "unknown")) );
3404 if( rNode.mnDuration > 0 )
3406 double fSeconds = rNode.mnDuration;
3407 fSeconds /= 1000.0;
3408 fprintf(mpFile, " dur=\"%g\"", fSeconds);
3410 else if( rNode.mnDuration < 0 )
3412 fprintf(mpFile, " dur=\"indefinite\"" );
3415 if( rNode.mnU1 ) fprintf(mpFile," u1=\"%#lx\"", rNode.mnU1);
3416 if( rNode.mnU3 ) fprintf(mpFile," u3=\"%#lx\"", rNode.mnU3);
3417 if( rNode.mnU4 ) fprintf(mpFile," u4=\"%#lx\"", rNode.mnU4);
3420 void AnimationImporter::dump( Any& rAny )
3422 Sequence< Any > aSeq;
3423 sal_Int32 nInt;
3424 double fDouble;
3425 OUString aString;
3426 sal_Bool bBool;
3427 Event aEvent;
3428 Timing aTiming;
3430 if( rAny >>= aSeq )
3432 const sal_Int32 nSize = aSeq.getLength();
3433 sal_Int32 nIndex = 0;
3434 while( nIndex < nSize )
3436 dump( aSeq[nIndex++] );
3437 if(nIndex < nSize)
3438 fprintf( mpFile, "," );
3441 else if( rAny >>= aString )
3443 fprintf( mpFile, "%s", OUStringToOString(aString,
3444 RTL_TEXTENCODING_UTF8).getStr() );
3446 else if( rAny >>= nInt )
3448 fprintf( mpFile, "%ld", nInt );
3450 else if( rAny >>= bBool )
3452 fprintf( mpFile, "%s", bBool ? "true" : "false" );
3454 else if( rAny >>= fDouble )
3456 fprintf( mpFile, "%g", fDouble );
3458 else if( rAny >>= aTiming )
3460 fprintf( mpFile, "%s", aTiming == (Timing_INDEFINITE) ? "indefinite" : "media" );
3462 else if( rAny >>= aEvent )
3464 static const char* triggers[] =
3466 "none","onbegin","onend","begin",
3467 "end","onclick","ondoubleclick","onmouseenter",
3468 "onmouseleave","onpptnext","onpptprev","onstopaudio"
3471 if( aEvent.Trigger != EventTrigger::NONE )
3473 if( aEvent.Source.hasValue() )
3475 dump_target( aEvent.Source );
3476 dump( "." );
3479 dump( triggers[ aEvent.Trigger ] );
3482 if( aEvent.Offset.hasValue() )
3484 double fOffset;
3485 if( aEvent.Offset >>= fOffset )
3486 fprintf( mpFile, "%g", fOffset );
3487 else
3488 dump( "indefinite" );
3493 void AnimationImporter::dump( const PropertySet& rSet )
3495 // dump property set
3497 map< sal_Int32, Any >::const_iterator aIter( rSet.maProperties.begin() );
3498 const map< sal_Int32, Any >::const_iterator aEnd( rSet.maProperties.end() );
3499 while( aIter != aEnd )
3501 bool bKnown = false;
3503 const sal_Int32 nInstance = (*aIter).first;
3504 Any aAny( (*aIter).second );
3506 switch ( nInstance )
3508 case DFF_ANIM_COLORSPACE:
3510 sal_Int32 nColorSpace;
3511 if( aAny >>= nColorSpace )
3513 fprintf( mpFile, " colorSpace=\"%s\"", (nColorSpace == 0) ? "rgb" : (nColorSpace == 1) ? "hsl" : "unknown" );
3514 bKnown = true;
3517 break;
3519 case DFF_ANIM_DIRECTION:
3521 sal_Bool bDirection;
3522 if( aAny >>= bDirection )
3524 fprintf( mpFile, " direction=\"%s\"", bDirection ? "cclockwise" : "clockwise" );
3525 bKnown = true;
3527 else
3529 sal_Int32 nMasterRel;
3530 if( aAny >>= nMasterRel )
3532 fprintf( mpFile, " direction=\"%s\"", nMasterRel == 0 ? "sameClick" : ( nMasterRel == 2 ? "nextClick" : "lastClick" ) );
3533 bKnown = true;
3537 break;
3539 case DFF_ANIM_OVERRIDE: // TODO
3541 sal_Int32 nOverride;
3542 if( aAny >>= nOverride )
3544 fprintf( mpFile, " override=\"%s\"", (nOverride == 1) ? "childStyle" : (nOverride == 0) ? "normal" : "unknown" );
3545 bKnown = true;
3548 break;
3550 case DFF_ANIM_PATH_EDIT_MODE:
3552 sal_Bool bPathEditMode;
3553 if( aAny >>= bPathEditMode )
3555 fprintf( mpFile, " pptPathEditMode=\"%s\"", bPathEditMode ? "relative" : "fixed" );
3556 bKnown = true;
3559 break;
3561 case DFF_ANIM_PRESET_ID :
3563 sal_Int32 nPresetId ;
3564 if( aAny >>= nPresetId )
3566 fprintf(mpFile, " presetid=\"%ld\"", nPresetId );
3567 bKnown = true;
3570 break;
3572 case DFF_ANIM_PRESET_SUB_TYPE :
3574 sal_Int32 nPointsType ;
3575 if( aAny >>= nPointsType )
3577 fprintf(mpFile, " presetSubType=\"%ld\"", nPointsType );
3578 bKnown = true;
3581 break;
3583 case DFF_ANIM_PRESET_CLASS :
3585 sal_Int32 nPresetClass;
3586 if ( aAny >>= nPresetClass )
3588 const char* pMode;
3589 switch( nPresetClass )
3591 case DFF_ANIM_PRESS_CLASS_USER_DEFINED: pMode = "userdefined"; break;
3592 case DFF_ANIM_PRESS_CLASS_ENTRANCE: pMode = "entrance"; break;
3593 case DFF_ANIM_PRESS_CLASS_EXIT: pMode = "exit"; break;
3594 case DFF_ANIM_PRESS_CLASS_EMPHASIS: pMode = "emphasis"; break;
3595 case DFF_ANIM_PRESS_CLASS_MOTIONPATH: pMode = "motionpath"; break;
3596 case DFF_ANIM_PRESS_CLASS_OLE_ACTION: pMode = "oleaction"; break;
3597 case DFF_ANIM_PRESS_CLASS_MEDIACALL: pMode = "mediacall"; break;
3598 default:
3600 static char buffer[128];
3601 sprintf( buffer, "%ld", nPresetClass );
3602 pMode = buffer;
3604 break;
3607 fprintf(mpFile, " class=\"%s\"", pMode);
3608 bKnown = true;
3611 break;
3613 case DFF_ANIM_NODE_TYPE :
3615 sal_Int32 nNodeType;
3616 if ( aAny >>= nNodeType )
3618 const char* pNode;
3619 switch( nNodeType )
3621 case DFF_ANIM_NODE_TYPE_ON_CLICK: pNode = "onclick"; break;
3622 case DFF_ANIM_NODE_TYPE_WITH_PREVIOUS: pNode = "withprevious"; break;
3623 case DFF_ANIM_NODE_TYPE_AFTER_PREVIOUS: pNode = "afterprevious"; break;
3624 case DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE: pNode = "mainsequence"; break;
3625 case DFF_ANIM_NODE_TYPE_TIMING_ROOT: pNode = "timingroot"; break;
3626 case DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ:pNode = "interactivesequence"; break;
3627 default :
3629 static char buffer[128];
3630 sprintf( buffer, "%ld", nNodeType );
3631 pNode = buffer;
3633 break;
3636 fprintf(mpFile, " nodeType=\"%s\"", pNode);
3637 bKnown = true;
3640 break;
3642 case DFF_ANIM_GROUP_ID:
3644 sal_Int32 nGroupId;
3645 if ( aAny >>= nGroupId )
3647 fprintf( mpFile, " groupId=\"%ld\"", nGroupId );
3648 bKnown = true;
3651 break;
3653 case DFF_ANIM_ID:
3655 OUString aString;
3656 if( aAny >>= aString )
3658 fprintf( mpFile, " id=\"%s\"",
3659 OUStringToOString(aString,
3660 RTL_TEXTENCODING_UTF8).getStr() );
3661 bKnown = true;
3664 break;
3666 case DFF_ANIM_EVENT_FILTER:
3668 OUString aString;
3669 if( aAny >>= aString )
3671 fprintf( mpFile, " eventFilter=\"%s\"",
3672 OUStringToOString(aString,
3673 RTL_TEXTENCODING_UTF8).getStr() );
3674 bKnown = true;
3677 break;
3679 case DFF_ANIM_ENDAFTERSLIDE:
3681 sal_Int32 nEndAfterSlide;
3682 if( aAny >>= nEndAfterSlide )
3684 fprintf(mpFile, " endAfterSlide=\"%ld\"", nEndAfterSlide );
3685 bKnown = true;
3689 case DFF_ANIM_TIMEFILTER:
3691 OUString aString;
3692 if( aAny >>= aString )
3694 fprintf( mpFile, " timeFilter=\"%s\"",
3695 OUStringToOString(aString,
3696 RTL_TEXTENCODING_UTF8).getStr() );
3697 bKnown = true;
3700 break;
3702 case DFF_ANIM_RUNTIMECONTEXT:
3704 OUString aString;
3705 if( aAny >>= aString )
3707 fprintf( mpFile, " runtimeContext=\"%s\"",
3708 OUStringToOString(aString,
3709 RTL_TEXTENCODING_UTF8).getStr() );
3710 bKnown = true;
3713 break;
3715 case DFF_ANIM_VOLUME:
3717 double fVolume(0.0);
3718 if( aAny >>= fVolume )
3720 fprintf( mpFile, " volume=\"%g%%\"", (double)(fVolume * 100.0) );
3721 bKnown = true;
3724 break;
3726 case DFF_ANIM_AFTEREFFECT:
3728 sal_Bool bAfterEffect;
3729 if( aAny >>= bAfterEffect )
3731 fprintf( mpFile, "afterEffect=\"%s\"", bAfterEffect ? "true" : "false" );
3732 bKnown = true;
3735 break;
3740 if( !bKnown )
3742 fprintf( mpFile, " unknown_%lu=\"", nInstance );
3743 dump( aAny );
3744 fprintf( mpFile, "\"" );
3747 ++aIter;
3751 void AnimationImporter::dump_target( Any& rAny )
3753 Any aSource, aSourceData;
3754 Sequence< Any > aSeq;
3755 if( rAny >>= aSeq )
3757 if( aSeq.getLength() >= 1 ) aSource = aSeq[0];
3758 if( aSeq.getLength() >= 2 ) aSourceData = aSeq[1];
3760 else
3762 aSource = rAny;
3765 Reference< XShape > xShape;
3766 aSource >>= xShape;
3767 if( xShape.is() )
3769 OUString aStr( xShape->getShapeType() );
3770 dump( aStr );
3772 if( aSourceData.hasValue() )
3774 dump( "(" );
3775 dump( aSourceData );
3776 dump( ")" );
3781 void AnimationImporter::dump( const char * pText )
3783 fprintf( mpFile, "%s", pText );
3786 void AnimationImporter::dump( const OUString& rString )
3788 fprintf( mpFile, OUStringToOString(rString,
3789 RTL_TEXTENCODING_UTF8).getStr() );
3792 void AnimationImporter::dump( const char * pText, sal_Int64 nInt )
3794 fprintf( mpFile, pText, nInt );
3797 void AnimationImporter::dump( const char * pText, sal_Int32 nInt )
3799 fprintf( mpFile, pText, nInt );
3802 void AnimationImporter::dump( const char * pText, double fDouble )
3804 fprintf( mpFile, pText, fDouble );
3807 void AnimationImporter::dump( const char * pText, const char * pText2 )
3809 fprintf( mpFile, pText, pText2 );
3812 void AnimationImporter::dump( const char * pText, const OUString& rString )
3814 fprintf( mpFile, pText, OUStringToOString(rString,
3815 RTL_TEXTENCODING_UTF8).getStr() );
3818 #else
3820 void AnimationImporter::dump_atom_header( const Atom* , bool , bool )
3824 void AnimationImporter::dump_atom( const Atom* , bool )
3828 void AnimationImporter::dump_target( ::com::sun::star::uno::Any& )
3832 void AnimationImporter::dump( ::com::sun::star::uno::Any& )
3836 void AnimationImporter::dump( const PropertySet& )
3840 void AnimationImporter::dump( const AnimationNode& )
3844 void AnimationImporter::dump( const char * )
3848 void AnimationImporter::dump( const char * , sal_Int32 )
3852 void AnimationImporter::dump( const char * , double )
3856 void AnimationImporter::dump( const char * , const char * )
3860 void AnimationImporter::dump( const char * , const OUString& )
3864 #endif
3866 } // namespace ppt;
3868 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */