xref: /AOO41X/main/sd/source/filter/ppt/pptinanimations.cxx (revision ca62e2c2083b5d0995f1245bad6c2edfb455fbec)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sd.hxx"
26 #include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
27 #include <com/sun/star/animations/AnimationFill.hpp>
28 #include <com/sun/star/animations/AnimationRestart.hpp>
29 #include <com/sun/star/animations/Timing.hpp>
30 #include <com/sun/star/animations/Event.hpp>
31 #include <com/sun/star/animations/AnimationEndSync.hpp>
32 #include <com/sun/star/animations/EventTrigger.hpp>
33 #include <com/sun/star/presentation/EffectNodeType.hpp>
34 #include <com/sun/star/presentation/EffectPresetClass.hpp>
35 #include <com/sun/star/animations/AnimationNodeType.hpp>
36 #include <com/sun/star/animations/AnimationTransformType.hpp>
37 #include <com/sun/star/animations/AnimationCalcMode.hpp>
38 #include <com/sun/star/animations/AnimationValueType.hpp>
39 #include <com/sun/star/animations/AnimationAdditiveMode.hpp>
40 #include <com/sun/star/animations/XIterateContainer.hpp>
41 #include <com/sun/star/animations/XAnimateSet.hpp>
42 #include <com/sun/star/animations/XAudio.hpp>
43 #include <com/sun/star/animations/XCommand.hpp>
44 #include <com/sun/star/animations/XTransitionFilter.hpp>
45 #include <com/sun/star/animations/XAnimateColor.hpp>
46 #include <com/sun/star/animations/XAnimateMotion.hpp>
47 #include <com/sun/star/animations/XAnimateTransform.hpp>
48 #include <com/sun/star/animations/ValuePair.hpp>
49 #include <com/sun/star/animations/AnimationColorSpace.hpp>
50 #include <com/sun/star/presentation/ShapeAnimationSubType.hpp>
51 #include <com/sun/star/presentation/EffectCommands.hpp>
52 #include <com/sun/star/beans/NamedValue.hpp>
53 #include <com/sun/star/drawing/FillStyle.hpp>
54 #include <com/sun/star/drawing/LineStyle.hpp>
55 #include <com/sun/star/awt/FontWeight.hpp>
56 #include <com/sun/star/awt/FontUnderline.hpp>
57 #include <com/sun/star/awt/FontSlant.hpp>
58 #include <com/sun/star/container/XEnumerationAccess.hpp>
59 #include <com/sun/star/presentation/ParagraphTarget.hpp>
60 #include <com/sun/star/presentation/TextAnimationType.hpp>
61 #include <comphelper/processfactory.hxx>
62 #include <rtl/ustrbuf.hxx>
63 #include <rtl/math.hxx>
64 
65 #include <vcl/vclenum.hxx>
66 #include <svx/svdotext.hxx>
67 #include <editeng/outlobj.hxx>
68 #include <editeng/editobj.hxx>
69 #include <pptinanimations.hxx>
70 #include <pptatom.hxx>
71 #include "pptin.hxx"
72 #include <algorithm>
73 
74 using ::std::map;
75 using ::rtl::OUString;
76 using ::rtl::OUStringBuffer;
77 using ::com::sun::star::uno::Any;
78 using ::com::sun::star::uno::Reference;
79 using ::com::sun::star::uno::UNO_QUERY;
80 using ::com::sun::star::uno::UNO_QUERY_THROW;
81 using ::com::sun::star::uno::Sequence;
82 using ::com::sun::star::uno::makeAny;
83 using ::com::sun::star::uno::Exception;
84 using ::com::sun::star::uno::XInterface;
85 using ::com::sun::star::beans::NamedValue;
86 using ::com::sun::star::container::XEnumerationAccess;
87 using ::com::sun::star::container::XEnumeration;
88 using ::com::sun::star::lang::XMultiServiceFactory;
89 
90 using namespace ::com::sun::star::drawing;
91 using namespace ::com::sun::star::animations;
92 using namespace ::com::sun::star::presentation;
93 
94 namespace sd
95 {
96 extern Reference< XInterface > RandomAnimationNode_createInstance( sal_Int16 nPresetClass );
97 }
98 
99 namespace ppt
100 {
101 
find(const OUString & rName)102 const transition* transition::find( const OUString& rName )
103 {
104     const transition* p = gTransitions;
105 
106     while( p->mpName )
107     {
108         if( rName.compareToAscii( p->mpName ) == 0 )
109             return p;
110 
111         p++;
112     }
113 
114     return NULL;
115 }
116 
117 // ====================================================================
118 
119 
120 
121 // ====================================================================
122 
operator >>(SvStream & rIn,AnimationNode & rNode)123 SvStream& operator>>(SvStream& rIn, AnimationNode& rNode )
124 {
125     rIn >> rNode.mnU1;
126     rIn >> rNode.mnRestart;
127     rIn >> rNode.mnGroupType;
128     rIn >> rNode.mnFill;
129     rIn >> rNode.mnU3;
130     rIn >> rNode.mnU4;
131     rIn >> rNode.mnDuration;
132     rIn >> rNode.mnNodeType;
133 
134     return rIn;
135 }
136 
137 // ====================================================================
138 
convertMeasure(OUString & rString)139 static bool convertMeasure( OUString& rString )
140 {
141     bool bRet = false;
142 
143     const sal_Char* pSource[] = { "ppt_x", "ppt_y", "ppt_w", "ppt_h", NULL };
144     const sal_Char* pDest[] = { "x", "y", "width", "height", NULL };
145     sal_Int32 nIndex = 0;
146 
147     const sal_Char** ps = pSource;
148     const sal_Char** pd = pDest;
149 
150     while( *ps )
151     {
152         const OUString aSearch( OUString::createFromAscii( *ps ) );
153         while( (nIndex = rString.indexOf( aSearch, nIndex )) != -1  )
154         {
155             sal_Int32 nLength = aSearch.getLength();
156             if( nIndex && (rString.getStr()[nIndex-1] == '#' ) )
157             {
158                 nIndex--;
159                 nLength++;
160             }
161 
162             const OUString aNew( OUString::createFromAscii( *pd ) );
163             rString = rString.replaceAt( nIndex, nLength, aNew );
164             nIndex += aNew.getLength();
165             bRet = true;
166         }
167         ps++;
168         pd++;
169     }
170 
171     return bRet;
172 }
173 
174 
175 // ====================================================================
176 
hasProperty(sal_Int32 nProperty) const177 bool PropertySet::hasProperty( sal_Int32 nProperty ) const
178 {
179     return maProperties.find( nProperty ) != maProperties.end();
180 }
181 
182 // --------------------------------------------------------------------
183 
getProperty(sal_Int32 nProperty) const184 Any PropertySet::getProperty( sal_Int32 nProperty ) const
185 {
186     PropertySetMap_t::const_iterator aIter( maProperties.find( nProperty ) );
187     if( aIter != maProperties.end() )
188         return (*aIter).second;
189     else
190         return Any();
191 }
192 
193 // ====================================================================
194 
195 /** this adds an any to another any.
196     if rNewValue is empty, rOldValue is returned.
197     if rOldValue is empty, rNewValue is returned.
198     if rOldValue contains a value, a sequence with rOldValue and rNewValue is returned.
199     if rOldValue contains a sequence, a new sequence with the old sequence and rNewValue is returned.
200 */
addToSequence(const Any & rOldValue,const Any & rNewValue)201 static Any addToSequence( const Any& rOldValue, const Any& rNewValue )
202 {
203     if( !rNewValue.hasValue() )
204     {
205         return rOldValue;
206     }
207     else if( !rOldValue.hasValue() )
208     {
209         return rNewValue;
210     }
211     else
212     {
213         Sequence< Any > aNewSeq;
214         if( rOldValue >>= aNewSeq )
215         {
216             sal_Int32 nSize = aNewSeq.getLength();
217             aNewSeq.realloc(nSize+1);
218             aNewSeq[nSize] = rNewValue;
219         }
220         else
221         {
222             aNewSeq.realloc(2);
223             aNewSeq[0] = rOldValue;
224             aNewSeq[1] = rNewValue;
225         }
226         return makeAny( aNewSeq );
227     }
228 }
229 
230 // ====================================================================
231 
AnimationImporter(ImplSdPPTImport * pPPTImport,SvStream & rStCtrl)232 AnimationImporter::AnimationImporter( ImplSdPPTImport* pPPTImport, SvStream& rStCtrl )
233 : mpPPTImport( pPPTImport ), mrStCtrl( rStCtrl )
234 {
235 }
236 
237 // --------------------------------------------------------------------
238 
import(const Reference<XDrawPage> & xPage,const DffRecordHeader & rProgTagContentHd)239 void AnimationImporter::import( const Reference< XDrawPage >& xPage, const DffRecordHeader& rProgTagContentHd )
240 {
241 #ifdef DBG_ANIM_LOG
242     mpFile = fopen( "c:\\output.xml", "w+" );
243     //mpFile = stdout;
244 #endif
245     dump("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
246 
247     Reference< XAnimationNodeSupplier > xNodeSupplier( xPage, UNO_QUERY );
248     if( xNodeSupplier.is() )
249     {
250         mxRootNode = xNodeSupplier->getAnimationNode();
251         if( mxRootNode.is() )
252         {
253             Reference< XAnimationNode > xParent;
254 
255             const Atom* pAtom = Atom::import( rProgTagContentHd, mrStCtrl );
256             if( pAtom )
257             {
258                 importAnimationContainer( pAtom, xParent );
259             }
260 
261             processAfterEffectNodes();
262         }
263     }
264 
265 #ifdef DBG_ANIM_LOG
266     fclose( mpFile );
267 #endif
268 }
269 
270 // --------------------------------------------------------------------
271 
processAfterEffectNodes()272 void AnimationImporter::processAfterEffectNodes()
273 {
274     std::for_each( maAfterEffectNodes.begin(), maAfterEffectNodes.end(), sd::stl_process_after_effect_node_func );
275 }
276 
277 // --------------------------------------------------------------------
278 
createNode(const Atom * pAtom,const AnimationNode & rNode)279 Reference< XAnimationNode > AnimationImporter::createNode( const Atom* pAtom, const AnimationNode& rNode )
280 {
281     const char* pServiceName = NULL;
282 
283     switch( rNode.mnGroupType )
284     {
285     case mso_Anim_GroupType_PAR:
286         if( pAtom->hasChildAtom( DFF_msofbtAnimIteration ) )
287             pServiceName = "com.sun.star.animations.IterateContainer";
288         else
289             pServiceName = "com.sun.star.animations.ParallelTimeContainer";
290         break;
291     case mso_Anim_GroupType_SEQ:
292         pServiceName = "com.sun.star.animations.SequenceTimeContainer";
293         break;
294     case mso_Anim_GroupType_NODE:
295     {
296         switch( rNode.mnNodeType )
297         {
298         case mso_Anim_Behaviour_FILTER:
299 /*
300             pServiceName = "com.sun.star.animations.TransitionFilter";
301             break;
302 */
303         case mso_Anim_Behaviour_ANIMATION:
304             if( pAtom->hasChildAtom( DFF_msofbtAnimateSet ) )
305                 pServiceName = "com.sun.star.animations.AnimateSet";
306             else if( pAtom->hasChildAtom( DFF_msofbtAnimateColor ) )
307                 pServiceName = "com.sun.star.animations.AnimateColor";
308             else if( pAtom->hasChildAtom( DFF_msofbtAnimateScale ) )
309                 pServiceName = "com.sun.star.animations.AnimateTransform";
310             else if( pAtom->hasChildAtom( DFF_msofbtAnimateRotation ) )
311                 pServiceName = "com.sun.star.animations.AnimateTransform";
312             else if( pAtom->hasChildAtom( DFF_msofbtAnimateMotion ) )
313                 pServiceName = "com.sun.star.animations.AnimateMotion";
314             else if( pAtom->hasChildAtom( DFF_msofbtAnimateFilter ) )
315                 pServiceName = "com.sun.star.animations.TransitionFilter";
316             else if( pAtom->hasChildAtom( DFF_msofbtAnimCommand ) )
317                 pServiceName = "com.sun.star.animations.Command";
318             else
319                 pServiceName = "com.sun.star.animations.Animate";
320             break;
321         }
322         break;
323     }
324     case mso_Anim_GroupType_MEDIA:
325         pServiceName = "com.sun.star.animations.Audio";
326         break;
327 
328     default:
329         pServiceName = "com.sun.star.animations.Animate";
330         break;
331     }
332 
333     Reference< XAnimationNode > xNode;
334     if( pServiceName )
335     {
336         const OUString aServiceName( OUString::createFromAscii(pServiceName) );
337         Reference< XInterface > xFac( ::comphelper::getProcessServiceFactory()->createInstance(aServiceName) );
338         xNode.set(xFac , UNO_QUERY );
339     }
340 
341     DBG_ASSERT( xNode.is(), "sd::AnimationImporter::createNode(), node creation failed!" );
342     return xNode;
343 }
344 
345 // --------------------------------------------------------------------
346 
is_random(const AnimationNode & rNode,const PropertySet & rSet,sal_Int32 & rPresetClass)347 static bool is_random( const AnimationNode& rNode, const PropertySet& rSet, sal_Int32& rPresetClass )
348 {
349     if( rNode.mnGroupType != mso_Anim_GroupType_PAR )
350         return false;
351 
352     if( !rSet.hasProperty( DFF_ANIM_PRESET_ID ) || !rSet.hasProperty( DFF_ANIM_PRESET_CLASS ) )
353         return false;
354 
355     sal_Int32 nPresetId = 0;
356     if( !(rSet.getProperty( DFF_ANIM_PRESET_ID ) >>= nPresetId) || (nPresetId != 24) )
357         return false;
358 
359     sal_Int32 nPresetClass = 0;
360     if( !(rSet.getProperty( DFF_ANIM_PRESET_CLASS ) >>= nPresetClass) )
361         return false;
362 
363     switch( nPresetClass )
364     {
365     case DFF_ANIM_PRESS_CLASS_ENTRANCE: rPresetClass = EffectPresetClass::ENTRANCE; return true;
366     case DFF_ANIM_PRESS_CLASS_EXIT: rPresetClass = EffectPresetClass::EXIT; return true;
367     }
368     return false;
369 }
370 
371 
importAnimationContainer(const Atom * pAtom,const Reference<XAnimationNode> & xParent)372 void AnimationImporter::importAnimationContainer( const Atom* pAtom, const Reference< XAnimationNode >& xParent )
373 {
374     if( pAtom->seekToContent() )
375     {
376         AnimationNode aNode;
377         const Atom* pAnimationNodeAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimNode );
378         if( pAnimationNodeAtom && pAnimationNodeAtom->seekToContent() )
379             mrStCtrl >> aNode;
380 
381         PropertySet aSet;
382         const Atom* pAnimationPropertySetAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimPropertySet );
383         if( pAnimationPropertySetAtom )
384             importPropertySetContainer( pAnimationPropertySetAtom, aSet );
385 
386         Reference< XAnimationNode > xNode;
387 
388         if( xParent.is() )
389         {
390             sal_Int32 nPresetClass;
391             if( is_random( aNode, aSet, nPresetClass ) )
392             {
393                 // create a random animation node with the given preset class
394                 xNode.set( sd::RandomAnimationNode_createInstance( (sal_Int16)nPresetClass ), UNO_QUERY );
395             }
396 
397             if( !xNode.is() )
398             {
399                 // create a node for the given atom
400                 xNode = createNode( pAtom, aNode );
401             }
402         }
403         else
404         {
405             // if we have no parent we fill the root node
406             xNode = mxRootNode;
407         }
408 
409         // import if we have a node and its not random
410         if( xNode.is() )
411         {
412             fillNode( xNode, aNode, aSet );
413 
414             switch( aNode.mnGroupType )
415             {
416             case mso_Anim_GroupType_PAR:
417             {
418                 dump( "<par" );
419                 dump( aNode );
420                 dump( aSet );
421                 importTimeContainer( pAtom, xNode );
422                 dump( "</par>\n" );
423 
424                 // for iteration containers, map target from childs to iteration
425                 Reference< XIterateContainer > xIter( xNode, UNO_QUERY );
426                 if( xIter.is() )
427                 {
428                     double fDuration = 0.0;
429                     Any aTarget, aEmpty;
430                     Reference< XEnumerationAccess > xEnumerationAccess( xNode, UNO_QUERY );
431                     if( xEnumerationAccess.is() )
432                     {
433                         Reference< XEnumeration > xEnumeration( xEnumerationAccess->createEnumeration(), UNO_QUERY );
434                         if( xEnumeration.is() )
435                         {
436                             while( xEnumeration->hasMoreElements() )
437                             {
438                                 Reference< XAnimate > xChildNode( xEnumeration->nextElement(), UNO_QUERY );
439                                 if( xChildNode.is() )
440                                 {
441                                     double fChildBegin = 0.0;
442                                     double fChildDuration = 0.0;
443                                     xChildNode->getBegin() >>= fChildBegin;
444                                     xChildNode->getDuration() >>= fChildDuration;
445 
446                                     fChildDuration += fChildBegin;
447                                     if( fChildDuration > fDuration )
448                                         fDuration = fChildDuration;
449 
450                                     if( !aTarget.hasValue() )
451                                         aTarget = xChildNode->getTarget();
452 
453                                     xChildNode->setTarget( aEmpty );
454                                 }
455                             }
456                         }
457                     }
458 
459                     xIter->setTarget( aTarget );
460 
461                     double fIterateInterval = xIter->getIterateInterval() * fDuration / 100;
462                     xIter->setIterateInterval( fIterateInterval );
463                 }
464             }
465             break;
466 
467             case mso_Anim_GroupType_SEQ:
468             {
469                 dump( "<seq" );
470                 dump( aNode );
471                 dump( aSet );
472                 importTimeContainer( pAtom, xNode );
473                 dump( "</seq>\n" );
474 
475                 if( aSet.hasProperty( DFF_ANIM_NODE_TYPE ) )
476                 {
477                     sal_Int32 nPPTNodeType = 0;
478                     if( aSet.getProperty( DFF_ANIM_NODE_TYPE ) >>= nPPTNodeType )
479                     {
480                         switch(nPPTNodeType)
481                         {
482                         case DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE:
483                             fixMainSequenceTiming( xNode );
484                             break;
485                         case DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ:
486                             fixInteractiveSequenceTiming( xNode );
487                             break;
488                         }
489                     }
490                 }
491             }
492             break;
493 
494             case mso_Anim_GroupType_NODE:
495             {
496 #ifdef DBG_ANIM_LOG
497                 if( pAtom->hasChildAtom( DFF_msofbtAnimateSet ) )
498                 {
499                     dump( "<set" );
500                 }
501                 else if( pAtom->hasChildAtom( DFF_msofbtAnimateColor ) )
502                 {
503                     dump( "<animateColor" );
504                 }
505                 else if( pAtom->hasChildAtom( DFF_msofbtAnimateScale ) )
506                 {
507                     dump( "<animateScale" );
508                 }
509                 else if( pAtom->hasChildAtom( DFF_msofbtAnimateRotation ) )
510                 {
511                     dump( "<animateRotation" );
512                 }
513                 else if( pAtom->hasChildAtom( DFF_msofbtAnimateMotion ) )
514                 {
515                     dump( "<animateMotion" );
516                 }
517                 else if( pAtom->hasChildAtom( DFF_msofbtAnimate ) )
518                 {
519                     dump( "<animate" );
520                 }
521                 else if( pAtom->hasChildAtom( DFF_msofbtAnimateFilter ) )
522                 {
523                     dump( "<animateFilter" );
524                 }
525                 else if( pAtom->hasChildAtom( DFF_msofbtAnimCommand ) )
526                 {
527                     dump( "<command" );
528                 }
529                 else
530                 {
531                     DBG_ERROR( "unknown node atom!" );
532                     dump_atom_header( pAtom, true, false );
533                     dump_atom( pAtom );
534                     dump_atom_header( pAtom, false, false );
535                     break;
536                 }
537                 dump( aNode );
538                 dump( aSet );
539 #endif
540                 importAnimationNodeContainer( pAtom, xNode );
541                 if( !convertAnimationNode( xNode, xParent ) )
542                     xNode = 0;
543                 dump( "/>\n");
544 
545             }
546             break;
547 
548             case mso_Anim_GroupType_MEDIA:
549             {
550                 dump( "<audio" );
551                 dump( aNode );
552                 dump( aSet );
553                 importAudioContainer( pAtom, xNode );
554                 dump( "</audio>\n" );
555             }
556             break;
557 
558             default:
559                 DBG_ERROR( "unknown group atom!" );
560 
561                 dump_atom_header( pAtom, true, false );
562                 dump_atom( pAtom );
563                 dump_atom_header( pAtom, false, false );
564                 break;
565 
566             }
567         }
568 
569         if( xParent.is() && xNode.is() )
570         {
571             Reference< XTimeContainer > xParentContainer( xParent, UNO_QUERY );
572             DBG_ASSERT( xParentContainer.is(), "parent is no container, then why do I have a child here?" );
573             if( xParentContainer.is() )
574             {
575                 xParentContainer->appendChild( xNode );
576             }
577         }
578     }
579 }
580 
581 // --------------------------------------------------------------------
fixMainSequenceTiming(const::com::sun::star::uno::Reference<::com::sun::star::animations::XAnimationNode> & xNode)582 void AnimationImporter::fixMainSequenceTiming( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode )
583 {
584     try
585     {
586         bool bFirst = true;
587         Reference< XEnumerationAccess > xEA( xNode, UNO_QUERY_THROW );
588         Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_QUERY_THROW );
589         while( xE->hasMoreElements() )
590         {
591             // click node
592             Reference< XAnimationNode > xClickNode( xE->nextElement(), UNO_QUERY );
593 
594             Event aEvent;
595             aEvent.Trigger = EventTrigger::ON_NEXT;
596             aEvent.Repeat = 0;
597             xClickNode->setBegin( makeAny( aEvent ) );
598 
599             if( bFirst )
600             {
601                 bFirst = false;
602                 Reference< XEnumerationAccess > xEA2( xClickNode, UNO_QUERY_THROW );
603                 Reference< XEnumeration > xE2( xEA2->createEnumeration(), UNO_QUERY_THROW );
604                 if( xE2->hasMoreElements() )
605                 {
606                     // with node
607                     xE2->nextElement() >>= xEA2;
608                     if( xEA2.is() )
609                         xE2.query( xEA2->createEnumeration() );
610                     else
611                         xE2.clear();
612 
613                     if( xE2.is() && xE2->hasMoreElements() )
614                     {
615                         Reference< XAnimationNode > xEffectNode( xE2->nextElement(), UNO_QUERY_THROW );
616                         const Sequence< NamedValue > aUserData( xEffectNode->getUserData() );
617                         const NamedValue* p = aUserData.getConstArray();
618                         sal_Int32 nLength = aUserData.getLength();
619                         while( nLength-- )
620                         {
621                             if( p->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "node-type" ) ) )
622                             {
623                                 sal_Int16 nNodeType = 0;
624                                 p->Value >>= nNodeType;
625                                 if( nNodeType != ::com::sun::star::presentation::EffectNodeType::ON_CLICK )
626                                 {
627                                     // first effect does not start on click, so correct
628                                     // first click nodes begin to 0s
629                                     xClickNode->setBegin( makeAny( (double)0.0 ) );
630                                     break;
631                                 }
632                             }
633                             p++;
634                         }
635                     }
636                 }
637             }
638         }
639     }
640     catch( Exception& e )
641     {
642         (void)e;
643         DBG_ERROR("sd::AnimationImporter::fixMainSequenceTiming(), exception caught!" );
644     }
645 }
646 
647 // --------------------------------------------------------------------
648 
fixInteractiveSequenceTiming(const::com::sun::star::uno::Reference<::com::sun::star::animations::XAnimationNode> & xNode)649 void AnimationImporter::fixInteractiveSequenceTiming( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode )
650 {
651     try
652     {
653         Any aBegin( xNode->getBegin() );
654         Any aEmpty;
655         xNode->setBegin( aEmpty );
656 
657         Reference< XEnumerationAccess > xEA( xNode, UNO_QUERY_THROW );
658         Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_QUERY_THROW );
659         while( xE->hasMoreElements() )
660         {
661             // click node
662             Reference< XAnimationNode > xClickNode( xE->nextElement(), UNO_QUERY );
663             xClickNode->setBegin( aBegin );
664         }
665     }
666     catch( Exception& e )
667     {
668         (void)e;
669         DBG_ERROR("sd::AnimationImporter::fixInteractiveSequenceTiming(), exception caught!" );
670     }
671 }
672 
673 // --------------------------------------------------------------------
674 
convertAnimationNode(const Reference<XAnimationNode> & xNode,const Reference<XAnimationNode> & xParent)675 bool AnimationImporter::convertAnimationNode( const Reference< XAnimationNode >& xNode, const Reference< XAnimationNode >& xParent )
676 {
677     Reference< XAnimate > xAnimate( xNode, UNO_QUERY );
678     if( !xAnimate.is() )
679         return true;
680 
681     if( !xAnimate->getTarget().hasValue() )
682         return false;
683 
684     const sal_Int16 nNodeType = xNode->getType();
685 
686     if( nNodeType == AnimationNodeType::TRANSITIONFILTER )
687         return true;
688 
689     OUString aAttributeName( xAnimate->getAttributeName() );
690 
691     if( (nNodeType == AnimationNodeType::SET) && aAttributeName.equalsAscii( "fill.on" ) )
692         return false;
693 
694     const ImplAttributeNameConversion* p = gImplConversionList;
695 
696     MS_AttributeNames eAttribute = MS_UNKNOWN;
697 
698     if( (nNodeType == AnimationNodeType::ANIMATEMOTION) ||
699         (nNodeType == AnimationNodeType::ANIMATETRANSFORM) )
700     {
701         OUString aEmpty;
702         aAttributeName = aEmpty;
703     }
704     else
705     {
706         while( p->mpMSName )
707         {
708             if( aAttributeName.compareToAscii( p->mpMSName ) == 0 )
709                 break;
710 
711             p++;
712         }
713 
714         DBG_ASSERT( p->mpMSName || (aAttributeName.getLength() == 0), "sd::AnimationImporter::convertAnimationNode(), unknown attribute!" );
715 #ifdef DBG_ANIM_LOG
716         if( p->mpMSName == 0 ) dump( "<error text=\"sd::AnimationImporter::convertAnimationNode(), unknown attribute!\"/>\n" );
717 #endif
718 
719         eAttribute = p->meAttribute;
720 
721         if( p->mpAPIName )
722             aAttributeName = OUString::createFromAscii( p->mpAPIName );
723     }
724 
725     xAnimate->setAttributeName( aAttributeName );
726 
727     if( eAttribute != MS_UNKNOWN )
728     {
729         Any aAny( xAnimate->getFrom() );
730         if( aAny.hasValue() )
731         {
732             if( convertAnimationValue( eAttribute, aAny ) )
733                 xAnimate->setFrom( aAny );
734         }
735 
736         aAny = xAnimate->getBy();
737         if( aAny.hasValue() )
738         {
739             if( convertAnimationValue( eAttribute, aAny ) )
740                 xAnimate->setBy( aAny );
741         }
742 
743         aAny = xAnimate->getTo();
744         if( aAny.hasValue() )
745         {
746             if( convertAnimationValue( eAttribute, aAny ) )
747                 xAnimate->setTo( aAny );
748         }
749 
750         Sequence< Any > aValues( xAnimate->getValues() );
751         sal_Int32 nValues = aValues.getLength();
752         if( nValues )
753         {
754             Any* p2 = aValues.getArray();
755             while( nValues-- )
756                 convertAnimationValue( eAttribute, *p2++ );
757 
758             xAnimate->setValues( aValues );
759         }
760 
761         OUString aFormula( xAnimate->getFormula() );
762         if( aFormula.getLength() )
763         {
764             if( convertMeasure( aFormula ) )
765                 xAnimate->setFormula( aFormula );
766         }
767     }
768 
769     // check for after-affect
770     Sequence< NamedValue > aUserData( xNode->getUserData() );
771     NamedValue* pValue = aUserData.getArray();
772     NamedValue* pLastValue = pValue;
773     sal_Int32 nLength = aUserData.getLength(), nRemoved = 0;
774 
775     sal_Bool bAfterEffect = false;
776     sal_Int32 nMasterRel = 0;
777     for( ; nLength--; pValue++ )
778     {
779         if( pValue->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("after-effect") ) )
780         {
781             pValue->Value >>= bAfterEffect;
782             nRemoved++;
783         }
784         else if( pValue->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("master-rel") ) )
785         {
786             pValue->Value >>= nMasterRel;
787             nRemoved++;
788         }
789         else
790         {
791             if( nRemoved )
792                 *pLastValue = *pValue;
793             pLastValue++;
794         }
795     }
796 
797     if( nRemoved )
798     {
799         aUserData.realloc( aUserData.getLength() - nRemoved );
800         xNode->setUserData( aUserData );
801     }
802 
803     // if its an after effect node, add it to the list for
804     // later processing
805     // after effect nodes are not inserted at their import
806     // position, so return false in this case
807     if( bAfterEffect )
808     {
809         if( nMasterRel != 2 )
810         {
811             Event aEvent;
812 
813             aEvent.Source <<= xParent;
814             aEvent.Trigger = EventTrigger::END_EVENT;
815             aEvent.Repeat = 0;
816 
817             xNode->setBegin( makeAny( aEvent ) );
818         }
819 
820         // add to after effect nodes for later processing
821         sd::AfterEffectNode aNode( xNode, xParent, nMasterRel == 2 );
822         maAfterEffectNodes.push_back( aNode );
823         return false;
824     }
825 
826     return true;
827 }
828 
lcl_gethex(int nChar)829 static int lcl_gethex( int nChar )
830 {
831     if( nChar >= '0' && nChar <= '9' )
832         return nChar - '0';
833     else if( nChar >= 'a' && nChar <= 'f' )
834         return nChar - 'a' + 10;
835     else if( nChar >= 'A' && nChar <= 'F' )
836         return nChar - 'A' + 10;
837     else
838         return 0;
839 }
840 
convertAnimationValue(MS_AttributeNames eAttribute,Any & rValue)841 bool AnimationImporter::convertAnimationValue( MS_AttributeNames eAttribute, Any& rValue )
842 {
843     bool bRet = false;
844     switch( eAttribute )
845     {
846     case MS_PPT_X:
847     case MS_PPT_Y:
848     case MS_PPT_W:
849     case MS_PPT_H:
850     {
851         OUString aString;
852 
853         if( rValue.getValueType() == ::getCppuType((const ValuePair*)0) )
854         {
855             ValuePair aValuePair;
856             if( rValue >>= aValuePair )
857             {
858                 if( aValuePair.First >>= aString )
859                 {
860                     if( convertMeasure( aString ) )
861                     {
862                         aValuePair.First <<= aString;
863                         bRet = true;
864                     }
865                 }
866 
867                 if( aValuePair.Second >>= aString )
868                 {
869                     if( convertMeasure( aString ) )
870                     {
871                         aValuePair.Second <<= aString;
872                         bRet = true;
873                     }
874                 }
875             }
876         }
877         else if( rValue.getValueType() == ::getCppuType((const OUString*)0) )
878         {
879             if( rValue >>= aString )
880             {
881                 bRet = convertMeasure( aString );
882 
883                 if( bRet )
884                     rValue <<= aString;
885             }
886         }
887     }
888     break;
889 
890     case MS_XSHEAR:
891     case MS_R:
892     {
893         OUString aString;
894         if( rValue >>= aString )
895         {
896             rValue <<= aString.toDouble();
897             bRet = true;
898         }
899     }
900     break;
901 
902     case MS_STYLEROTATION:
903     {
904         if( rValue.getValueType() == ::getCppuType((const OUString*)0) )
905         {
906             OUString aString;
907             rValue >>= aString;
908             rValue <<= (sal_Int16)aString.toDouble();
909             bRet = true;
910         }
911         else if( rValue.getValueType() == ::getCppuType((const double*)0) )
912         {
913             double fValue = 0.0;
914             rValue >>= fValue;
915             rValue <<= (sal_Int16)fValue;
916             bRet = true;
917         }
918     }
919     break;
920 
921     case MS_FILLCOLOR:
922     case MS_STROKECOLOR:
923     case MS_STYLECOLOR:
924     case MS_PPT_C:
925     {
926         OUString aString;
927         if( rValue >>= aString )
928         {
929             if( aString.getLength() >= 7 && aString[0] == '#' )
930             {
931                 Color aColor;
932                 aColor.SetRed( (sal_uInt8)(lcl_gethex( aString[1] ) * 16 + lcl_gethex( aString[2] )) );
933                 aColor.SetGreen( (sal_uInt8)(lcl_gethex( aString[3] ) * 16 + lcl_gethex( aString[4] )) );
934                 aColor.SetBlue( (sal_uInt8)(lcl_gethex( aString[5] ) * 16 + lcl_gethex( aString[6] )) );
935                 rValue <<= (sal_Int32)aColor.GetColor();
936                 bRet = true;
937             }
938             else if( aString.matchAsciiL( "rgb(", 4, 0 ) )
939             {
940                 aString = aString.copy( 4, aString.getLength() - 5 );
941                 Color aColor;
942                 sal_Int32 index = 0;
943                 aColor.SetRed( (sal_uInt8)aString.getToken( 0, (sal_Unicode)',', index ).toInt32() );
944                 aColor.SetGreen( (sal_uInt8)aString.getToken( 0, (sal_Unicode)',', index ).toInt32() );
945                 aColor.SetRed( (sal_uInt8)aString.getToken( 0, (sal_Unicode)',', index ).toInt32() );
946                 rValue <<= (sal_Int32)aColor.GetColor();
947                 bRet = true;
948             }
949             else if( aString.matchAsciiL( "hsl(", 4, 0 ) )
950             {
951                 sal_Int32 index = 0;
952                 sal_Int32 nA = aString.getToken( 0, (sal_Unicode)',', index ).toInt32();
953                 sal_Int32 nB = aString.getToken( 0, (sal_Unicode)',', index ).toInt32();
954                 sal_Int32 nC = aString.getToken( 0, (sal_Unicode)',', index ).toInt32();
955                 dump( "hsl(%ld", nA );
956                 dump( ",%ld", nB );
957                 dump( ",%ld)", nC );
958                 Sequence< double > aHSL( 3 );
959                 aHSL[0] = nA * 360.0/255.0;
960                 aHSL[1] = nB / 255.0;
961                 aHSL[2] = nC / 255.0;
962                 rValue <<= aHSL;
963                 bRet = true;
964             }
965         }
966     }
967     break;
968 
969     case MS_FILLTYPE:
970     {
971         OUString aString;
972         if( rValue >>= aString )
973         {
974             rValue <<= aString.equalsAscii( "solid" ) ? FillStyle_SOLID : FillStyle_NONE;
975             bRet = true;
976         }
977     }
978     break;
979 
980     case MS_STROKEON:
981     {
982         OUString aString;
983         if( rValue >>= aString )
984         {
985             rValue <<= aString.equalsAscii( "true" ) ? ::com::sun::star::drawing::LineStyle_SOLID : ::com::sun::star::drawing::LineStyle_NONE;
986             bRet = true;
987         }
988     }
989     break;
990 
991     case MS_FONTWEIGHT:
992     {
993         OUString aString;
994         if( rValue >>= aString )
995         {
996             rValue <<= aString.equalsAscii( "bold" ) ? com::sun::star::awt::FontWeight::BOLD : com::sun::star::awt::FontWeight::NORMAL;
997             bRet = true;
998         }
999     }
1000     break;
1001 
1002     case MS_STYLEFONTSTYLE:
1003     {
1004         OUString aString;
1005         if( rValue >>= aString )
1006         {
1007             rValue <<= aString.equalsAscii( "italic" ) ? com::sun::star::awt::FontSlant_ITALIC : com::sun::star::awt::FontSlant_NONE;
1008             bRet = true;
1009         }
1010     }
1011     break;
1012 
1013     case MS_STYLEUNDERLINE:
1014     {
1015         OUString aString;
1016         if( rValue >>= aString )
1017         {
1018             rValue <<= aString.equalsAscii( "true" ) ? com::sun::star::awt::FontUnderline::SINGLE : com::sun::star::awt::FontUnderline::NONE;
1019             bRet = true;
1020         }
1021     }
1022     break;
1023 
1024     case MS_STYLEOPACITY:
1025     case MS_STYLEFONTSIZE:
1026     {
1027         OUString aString;
1028         if( rValue >>= aString )
1029         {
1030             rValue <<= (float)aString.toDouble();
1031             bRet = true;
1032         }
1033     }
1034     break;
1035 
1036     case MS_STYLEVISIBILITY:
1037     {
1038         OUString aString;
1039         if( rValue >>= aString )
1040         {
1041             rValue <<= aString.equalsAscii( "visible" ) ? sal_True : sal_False;
1042             bRet = true;
1043         }
1044     }
1045     break;
1046     default:
1047         break;
1048     }
1049 
1050     return bRet;
1051 }
1052 
1053 // --------------------------------------------------------------------
1054 
getConvertedSubType(sal_Int16 nPresetClass,sal_Int32 nPresetId,sal_Int32 nPresetSubType)1055 static OUString getConvertedSubType( sal_Int16 nPresetClass, sal_Int32 nPresetId, sal_Int32 nPresetSubType )
1056 {
1057     const sal_Char* pStr = 0;
1058 
1059     if( (nPresetClass == EffectPresetClass::ENTRANCE) || (nPresetClass == EffectPresetClass::EXIT) )
1060     {
1061         // skip wheel effect
1062         if( nPresetId != 21 )
1063         {
1064             if( nPresetId == 5 )
1065             {
1066                 // checkerboard
1067                 switch( nPresetSubType )
1068                 {
1069                 case  5: pStr = "downward"; break;
1070                 case 10: pStr = "across"; break;
1071                 }
1072             }
1073             else if( nPresetId == 17 )
1074             {
1075                 // stretch
1076                 if( nPresetSubType == 10 )
1077                     pStr = "across";
1078             }
1079             else if( nPresetId == 18 )
1080             {
1081                 // strips
1082                 switch( nPresetSubType )
1083                 {
1084                 case 3: pStr = "right-to-top"; break;
1085                 case 6: pStr = "right-to-bottom"; break;
1086                 case 9: pStr = "left-to-top"; break;
1087                 case 12: pStr = "left-to-bottom"; break;
1088                 }
1089             }
1090 
1091             if( pStr == 0 )
1092             {
1093                 const convert_subtype* p = gConvertArray;
1094 
1095                 while( p->mpStrSubType )
1096                 {
1097                     if( p->mnID == nPresetSubType )
1098                     {
1099                         pStr = p->mpStrSubType;
1100                         break;
1101                     }
1102                     p++;
1103                 }
1104             }
1105         }
1106     }
1107 
1108     if( pStr )
1109         return OUString::createFromAscii( pStr );
1110     else
1111         return OUString::valueOf( nPresetSubType );
1112 }
1113 
1114 // --------------------------------------------------------------------
1115 
fillNode(Reference<XAnimationNode> & xNode,const AnimationNode & rNode,const PropertySet & rSet)1116 void AnimationImporter::fillNode( Reference< XAnimationNode >& xNode, const AnimationNode& rNode, const PropertySet& rSet )
1117 {
1118     sal_Bool bAfterEffect = false;
1119 
1120     // attribute Restart
1121     if( rNode.mnRestart )
1122     {
1123         sal_Int16 nRestart = AnimationRestart::DEFAULT;
1124         switch( rNode.mnRestart )
1125         {
1126         case 1: nRestart = AnimationRestart::ALWAYS; break;
1127         case 2: nRestart = AnimationRestart::WHEN_NOT_ACTIVE; break;
1128         case 3: nRestart = AnimationRestart::NEVER; break;
1129         }
1130         xNode->setRestart( nRestart );
1131     }
1132 
1133     // attribute Fill
1134     if( rNode.mnFill )
1135     {
1136         sal_Int16 nFill = AnimationFill::DEFAULT;
1137         switch( rNode.mnFill )
1138         {
1139         case 1: nFill = AnimationFill::REMOVE; break;
1140         case 2: nFill = AnimationFill::FREEZE; break;
1141         case 3: nFill = AnimationFill::HOLD; break;
1142         case 4: nFill = AnimationFill::TRANSITION; break;
1143         }
1144         xNode->setFill( nFill );
1145     }
1146 
1147     // attribute Duration
1148     if( rNode.mnDuration )
1149     {
1150         Any aDuration;
1151         if( rNode.mnDuration > 0 )
1152         {
1153             aDuration <<= (double)(rNode.mnDuration / 1000.0);
1154         }
1155         else if( rNode.mnDuration < 0 )
1156         {
1157             aDuration <<= Timing_INDEFINITE;
1158         }
1159         xNode->setDuration( aDuration );
1160     }
1161 
1162     // TODO: DFF_ANIM_PATH_EDIT_MODE
1163     if( rSet.hasProperty( DFF_ANIM_PATH_EDIT_MODE ) )
1164     {
1165         sal_Int32 nPathEditMode ;
1166         if( rSet.getProperty( DFF_ANIM_PATH_EDIT_MODE ) >>= nPathEditMode )
1167         {
1168         }
1169     }
1170 
1171     // set user data
1172     Sequence< NamedValue > aUserData;
1173 
1174     // attribute Type
1175     if( rSet.hasProperty( DFF_ANIM_NODE_TYPE ) )
1176     {
1177         sal_Int32 nPPTNodeType = 0;
1178         if( rSet.getProperty( DFF_ANIM_NODE_TYPE ) >>= nPPTNodeType )
1179         {
1180             sal_Int16 nNodeType = ::com::sun::star::presentation::EffectNodeType::DEFAULT;
1181             switch( nPPTNodeType )
1182             {
1183                 case DFF_ANIM_NODE_TYPE_ON_CLICK:       nNodeType = ::com::sun::star::presentation::EffectNodeType::ON_CLICK;   break;
1184                 case DFF_ANIM_NODE_TYPE_WITH_PREVIOUS:  nNodeType = ::com::sun::star::presentation::EffectNodeType::WITH_PREVIOUS; break;
1185                 case DFF_ANIM_NODE_TYPE_AFTER_PREVIOUS: nNodeType = ::com::sun::star::presentation::EffectNodeType::AFTER_PREVIOUS; break;
1186                 case DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE:  nNodeType = ::com::sun::star::presentation::EffectNodeType::MAIN_SEQUENCE; break;
1187                 case DFF_ANIM_NODE_TYPE_TIMING_ROOT:    nNodeType = ::com::sun::star::presentation::EffectNodeType::TIMING_ROOT; break;
1188                 case DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ:nNodeType = ::com::sun::star::presentation::EffectNodeType::INTERACTIVE_SEQUENCE; break;
1189             }
1190 
1191             sal_Int32 nSize = aUserData.getLength();
1192             aUserData.realloc(nSize+1);
1193             aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "node-type" ) );
1194             aUserData[nSize].Value <<= nNodeType;
1195         }
1196     }
1197 
1198     if( rSet.hasProperty( DFF_ANIM_GROUP_ID ) )
1199     {
1200         sal_Int32 nGroupId;
1201         if( rSet.getProperty( DFF_ANIM_GROUP_ID ) >>= nGroupId )
1202         {
1203             sal_Int32 nSize = aUserData.getLength();
1204             aUserData.realloc(nSize+1);
1205             aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "group-id" ) );
1206             aUserData[nSize].Value <<= nGroupId;
1207         }
1208     }
1209 
1210     sal_Int16 nEffectPresetClass = EffectPresetClass::CUSTOM;
1211     sal_Int32 nPresetId = 0;
1212 
1213     if( rSet.hasProperty( DFF_ANIM_PRESET_CLASS ) )
1214     {
1215         sal_Int32 nPresetClass = 0;
1216         if ( rSet.getProperty( DFF_ANIM_PRESET_CLASS ) >>= nPresetClass )
1217         {
1218             switch( nPresetClass )
1219             {
1220             case DFF_ANIM_PRESS_CLASS_ENTRANCE:     nEffectPresetClass = EffectPresetClass::ENTRANCE; break;
1221             case DFF_ANIM_PRESS_CLASS_EXIT:         nEffectPresetClass = EffectPresetClass::EXIT; break;
1222             case DFF_ANIM_PRESS_CLASS_EMPHASIS:     nEffectPresetClass = EffectPresetClass::EMPHASIS; break;
1223             case DFF_ANIM_PRESS_CLASS_MOTIONPATH:   nEffectPresetClass = EffectPresetClass::MOTIONPATH; break;
1224             case DFF_ANIM_PRESS_CLASS_OLE_ACTION:   nEffectPresetClass = EffectPresetClass::OLEACTION; break;
1225             case DFF_ANIM_PRESS_CLASS_MEDIACALL:    nEffectPresetClass = EffectPresetClass::MEDIACALL; break;
1226             }
1227             sal_Int32 nSize = aUserData.getLength();
1228             aUserData.realloc(nSize+1);
1229             aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "preset-class" ) );
1230             aUserData[nSize].Value <<= nEffectPresetClass;
1231         }
1232     }
1233 
1234     if( rSet.hasProperty( DFF_ANIM_PRESET_ID ) )
1235     {
1236         if( rSet.getProperty( DFF_ANIM_PRESET_ID ) >>= nPresetId )
1237         {
1238             sal_Int32 nSize = aUserData.getLength();
1239             aUserData.realloc(nSize+1);
1240             aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "preset-id" ) );
1241 
1242             const preset_maping* p = gPresetMaping;
1243             while( p->mpStrPresetId && ((p->mnPresetClass != nEffectPresetClass) || (p->mnPresetId != nPresetId )) )
1244                 p++;
1245 
1246             if( p->mpStrPresetId )
1247             {
1248                 aUserData[nSize].Value <<= OUString::createFromAscii( p->mpStrPresetId );
1249             }
1250             else
1251             {
1252                 OUStringBuffer sBuffer;
1253                 sBuffer.appendAscii( "ppt_" );
1254                 switch( nEffectPresetClass )
1255                 {
1256                 case EffectPresetClass::ENTRANCE: sBuffer.appendAscii( "entrance_" ); break;
1257                 case EffectPresetClass::EXIT: sBuffer.appendAscii( "exit_" ); break;
1258                 case EffectPresetClass::EMPHASIS: sBuffer.appendAscii( "emphasis_" ); break;
1259                 case EffectPresetClass::MOTIONPATH: sBuffer.appendAscii( "motionpath_" ); break;
1260                 case EffectPresetClass::OLEACTION: sBuffer.appendAscii( "oleaction_" ); break;
1261                 case EffectPresetClass::MEDIACALL: sBuffer.appendAscii( "mediacall_" ); break;
1262                 }
1263                 sBuffer.append( nPresetId );
1264 
1265                 aUserData[nSize].Value <<= sBuffer.makeStringAndClear();
1266             }
1267         }
1268     }
1269 
1270     if( rSet.hasProperty( DFF_ANIM_PRESET_SUB_TYPE ) )
1271     {
1272         sal_Int32 nPresetSubType = 0;
1273         if( (rSet.getProperty( DFF_ANIM_PRESET_SUB_TYPE ) >>= nPresetSubType) )
1274         {
1275             if( nPresetSubType )
1276             {
1277                 sal_Int32 nSize = aUserData.getLength();
1278                 aUserData.realloc(nSize+1);
1279                 aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "preset-sub-type" ) );
1280                 aUserData[nSize].Value <<= getConvertedSubType( nEffectPresetClass, nPresetId, nPresetSubType );
1281             }
1282         }
1283     }
1284 
1285     if( rSet.hasProperty( DFF_ANIM_AFTEREFFECT ) )
1286     {
1287         if( rSet.getProperty( DFF_ANIM_AFTEREFFECT ) >>= bAfterEffect )
1288         {
1289             sal_Int32 nSize = aUserData.getLength();
1290             aUserData.realloc(nSize+1);
1291             aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "after-effect" ) );
1292             aUserData[nSize].Value <<= bAfterEffect;
1293         }
1294     }
1295 
1296     if( bAfterEffect && rSet.hasProperty( DFF_ANIM_MASTERREL ) )
1297     {
1298         sal_Int32 nMasterRel = 2;
1299         if( rSet.getProperty( DFF_ANIM_MASTERREL ) >>= nMasterRel )
1300         {
1301             sal_Int32 nSize = aUserData.getLength();
1302             aUserData.realloc(nSize+1);
1303             aUserData[nSize].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "master-rel" ) );
1304             aUserData[nSize].Value <<= nMasterRel;
1305         }
1306     }
1307 
1308     xNode->setUserData( aUserData );
1309 
1310     // TODO: DFF_ANIM_ID
1311     if( rSet.hasProperty( DFF_ANIM_ID ) )
1312     {
1313         rtl::OUString aString;
1314         rSet.getProperty( DFF_ANIM_ID ) >>= aString;
1315         if( aString.getLength() )
1316         {
1317         }
1318     }
1319 
1320     // TODO: DFF_ANIM_EVENT_FILTER
1321     if( rSet.hasProperty( DFF_ANIM_EVENT_FILTER ) )
1322     {
1323         rtl::OUString aString;
1324         rSet.getProperty( DFF_ANIM_EVENT_FILTER ) >>= aString;
1325         if( aString.getLength() )
1326         {
1327         }
1328     }
1329 
1330     // DFF_ANIM_TIMEFILTER
1331     if( rSet.hasProperty( DFF_ANIM_TIMEFILTER ) )
1332     {
1333         Reference< XAnimate > xAnim( xNode, UNO_QUERY );
1334         if( xAnim.is() )
1335         {
1336             rtl::OUString aString;
1337             rSet.getProperty( DFF_ANIM_TIMEFILTER ) >>= aString;
1338             if( aString.getLength() )
1339             {
1340                 sal_Int32 nElements = 1; // a non empty string has at least one value
1341 
1342                 sal_Int32 fromIndex = 0;
1343                 while(true)
1344                 {
1345                     fromIndex = aString.indexOf( (sal_Unicode)';', fromIndex );
1346                     if( fromIndex == -1 )
1347                         break;
1348 
1349                     fromIndex++;
1350                     nElements++;
1351                 }
1352 
1353                 Sequence< TimeFilterPair > aTimeFilter( nElements );
1354 
1355                 TimeFilterPair* pValues = aTimeFilter.getArray();
1356                 sal_Int32 nIndex = 0;
1357                 while( (nElements--) && (nIndex >= 0) )
1358                 {
1359                     const OUString aToken( aString.getToken( 0, ';', nIndex ) );
1360 
1361                     sal_Int32 nPos = aToken.indexOf( ',' );
1362                     if( nPos >= 0 )
1363                     {
1364                         pValues->Time = aToken.copy( 0, nPos ).toDouble();
1365                         pValues->Progress = aToken.copy( nPos+1, aToken.getLength() - nPos - 1 ).toDouble();
1366                     }
1367                     pValues++;
1368                 }
1369 
1370                 xAnim->setTimeFilter( aTimeFilter );
1371             }
1372         }
1373     }
1374 
1375 /* todo
1376     Reference< XAudio > xAudio( xNode, UNO_QUERY );
1377     if( xAudio.is() )
1378     {
1379         if( rSet.hasProperty( DFF_ANIM_ENDAFTERSLIDE ) )
1380         {
1381             sal_Int16 nEndAfterSlide = 0;
1382             if( rSet.getProperty( DFF_ANIM_ENDAFTERSLIDE ) >>= nEndAfterSlide )
1383                 xAudio->setEndAfterSlide( nEndAfterSlide );
1384         }
1385 
1386         if( rSet.hasProperty( DFF_ANIM_VOLUME ) )
1387         {
1388             double fVolume = 1.0;
1389             rSet.getProperty( DFF_ANIM_VOLUME ) >>= fVolume;
1390             xAudio->setVolume( fVolume );
1391         }
1392     }
1393 */
1394     Reference< XAnimateColor > xColor( xNode, UNO_QUERY );
1395     if( xColor.is() )
1396     {
1397         if( rSet.hasProperty( DFF_ANIM_DIRECTION ) )
1398         {
1399             sal_Bool bDirection = sal_False;
1400             if( rSet.getProperty( DFF_ANIM_DIRECTION ) >>= bDirection )
1401                 xColor->setDirection( (sal_Bool)!bDirection );
1402         }
1403 
1404         if( rSet.hasProperty( DFF_ANIM_COLORSPACE ) )
1405         {
1406             sal_Int32 nColorSpace = 0;
1407             rSet.getProperty( DFF_ANIM_COLORSPACE ) >>= nColorSpace;
1408             xColor->setColorInterpolation( (nColorSpace == 0) ? AnimationColorSpace::RGB : AnimationColorSpace::HSL );
1409         }
1410     }
1411 }
1412 
1413 // --------------------------------------------------------------------
1414 
importTimeContainer(const Atom * pAtom,const Reference<XAnimationNode> & xNode)1415 void AnimationImporter::importTimeContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1416 {
1417     DBG_ASSERT( pAtom && xNode.is(), "invalid call to ppt::AnimationImporter::importTimeContainer()!");
1418     if( pAtom && xNode.is() )
1419     {
1420         importAnimationEvents( pAtom, xNode );
1421         importAnimationValues( pAtom, xNode );
1422         importAnimationActions( pAtom, xNode );
1423 
1424         dump(">\n");
1425 
1426         // import sub containers
1427         const Atom* pChildAtom = pAtom->findFirstChildAtom();
1428 
1429         while( pChildAtom )
1430         {
1431             switch( pChildAtom->getType() )
1432             {
1433                 case DFF_msofbtAnimNode:
1434                 case DFF_msofbtAnimEvent:
1435                 case DFF_msofbtAnimValue:
1436                 case DFF_msofbtAnimAction:
1437                 case DFF_msofbtAnimPropertySet:
1438                     break;
1439 
1440                 case DFF_msofbtAnimSubGoup :
1441                 {
1442                     if( pChildAtom->hasChildAtom( DFF_msofbtAnimCommand ) )
1443                     {
1444                         const OUString aServiceName( OUString::createFromAscii("com.sun.star.animations.Command") );
1445                         Reference< XAnimationNode > xChildNode( ::comphelper::getProcessServiceFactory()->createInstance(aServiceName), UNO_QUERY );
1446                         importAnimationNodeContainer( pChildAtom, xChildNode );
1447                         Reference< XTimeContainer > xParentContainer( xNode, UNO_QUERY );
1448                         if( xParentContainer.is() && xChildNode.is() )
1449                             xParentContainer->appendChild( xChildNode );
1450                     }
1451                     else
1452                     {
1453                         importAnimationContainer( pChildAtom, xNode );
1454                     }
1455                 }
1456                 break;
1457                 case DFF_msofbtAnimGroup :
1458                 {
1459                     importAnimationContainer( pChildAtom, xNode );
1460                 }
1461                 break;
1462                 case DFF_msofbtAnimIteration:
1463                 {
1464                     if( pChildAtom->seekToContent() )
1465                     {
1466                         float fInterval;
1467                         sal_Int32 nTextUnitEffect, nU1, nU2, nU3;
1468 
1469                         mrStCtrl >> fInterval >> nTextUnitEffect >> nU1 >> nU2 >> nU3;
1470 
1471                         Reference< XIterateContainer > xIter( xNode, UNO_QUERY );
1472                         if( xIter.is() )
1473                         {
1474                             sal_Int16 nIterateType = TextAnimationType::BY_PARAGRAPH;
1475                             switch( nTextUnitEffect )
1476                             {
1477                             case 1: nIterateType = TextAnimationType::BY_WORD; break;
1478                             case 2: nIterateType = TextAnimationType::BY_LETTER; break;
1479                             }
1480                             xIter->setIterateType( nIterateType );
1481                             xIter->setIterateInterval( (double)fInterval );
1482                         }
1483 
1484                         dump( "<iterate" );
1485                         dump( " iterateType=\"%s\"", (nTextUnitEffect == 0) ? "byElement" : (nTextUnitEffect == 1) ? "byWord" : "byLetter" );
1486                         dump( " iterateInterval=\"%g\"", fInterval );
1487                         dump( " u1=\"%ld\"", nU1 );
1488                         dump( " u2=\"%ld\"", nU2 );
1489                         dump( " u3=\"%ld\"/>\n", nU3 );
1490                     }
1491                 }
1492                 break;
1493 
1494                 case 0xf136:
1495                 {
1496 #ifdef DBG_ANIM_LOG
1497                     sal_uInt32 nU1, nU2;
1498                     mrStCtrl >> nU1 >> nU2;
1499 
1500                     fprintf( mpFile, "<unknown_0xf136 nU1=\"%ld\" nU2=\"%ld\"/>\n", nU1, nU2 );
1501 #endif
1502                 }
1503                 break;
1504 
1505                 default:
1506                 {
1507                     dump_atom_header( pChildAtom, true, false );
1508                     dump_atom( pChildAtom );
1509                     dump_atom_header( pChildAtom, false, false );
1510                 }
1511                 break;
1512             }
1513 
1514             pChildAtom = pAtom->findNextChildAtom( pChildAtom );
1515         }
1516     }
1517 }
1518 
1519 // --------------------------------------------------------------------
1520 
importAnimationNodeContainer(const Atom * pAtom,const Reference<XAnimationNode> & xNode)1521 void AnimationImporter::importAnimationNodeContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1522 {
1523     DBG_ASSERT( pAtom && xNode.is(), "invalid call to ppt::AnimationImporter::importAnimationNodeContainer()!");
1524     if( pAtom && xNode.is() )
1525     {
1526         importAnimationEvents( pAtom, xNode );
1527         importAnimationValues( pAtom, xNode );
1528         importAnimationActions( pAtom, xNode );
1529 
1530         const Atom* pChildAtom = pAtom->findFirstChildAtom();
1531 
1532         while( pChildAtom )
1533         {
1534             switch( pChildAtom->getType() )
1535             {
1536                 case DFF_msofbtAnimNode:
1537                 case DFF_msofbtAnimEvent:
1538                 case DFF_msofbtAnimValue:
1539                 case DFF_msofbtAnimAction:
1540                 case DFF_msofbtAnimPropertySet:
1541                     break;
1542 
1543                 case DFF_msofbtAnimateFilter:
1544                     importAnimateFilterContainer( pChildAtom, xNode );
1545                     break;
1546 
1547                 case DFF_msofbtAnimateSet:
1548                     importAnimateSetContainer( pChildAtom, xNode );
1549                     break;
1550 
1551                 case DFF_msofbtAnimate:
1552                     importAnimateContainer( pChildAtom, xNode );
1553                     break;
1554 
1555                 case DFF_msofbtAnimateScale:
1556                     importAnimateScaleContainer( pChildAtom, xNode );
1557                     break;
1558 
1559                 case DFF_msofbtAnimateColor:
1560                     importAnimateColorContainer( pChildAtom, xNode );
1561                     break;
1562 
1563                 case DFF_msofbtAnimateRotation:
1564                     importAnimateRotationContainer( pChildAtom, xNode );
1565                     break;
1566 
1567                 case DFF_msofbtAnimateMotion:
1568                     importAnimateMotionContainer( pChildAtom, xNode );
1569                     break;
1570 
1571                 case DFF_msofbtAnimCommand:
1572                     importCommandContainer( pChildAtom, xNode );
1573                     break;
1574 
1575                 default:
1576                 {
1577                     dump_atom_header( pChildAtom, true, false );
1578                     dump_atom( pChildAtom );
1579                     dump_atom_header( pChildAtom, false, false );
1580                 }
1581                 break;
1582             }
1583 
1584             pChildAtom = pAtom->findNextChildAtom( pChildAtom );
1585         }
1586     }
1587 }
1588 
1589 // --------------------------------------------------------------------
1590 
importAnimateFilterContainer(const Atom * pAtom,const Reference<XAnimationNode> & xNode)1591 void AnimationImporter::importAnimateFilterContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1592 {
1593     Reference< XTransitionFilter > xFilter( xNode, UNO_QUERY );
1594 
1595     DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateFilter && xFilter.is(), "invalid call to ppt::AnimationImporter::importAnimateFilterContainer()!");
1596     if( pAtom && xFilter.is() )
1597     {
1598         sal_uInt32 nBits = 0;
1599 
1600         const Atom* pChildAtom = pAtom->findFirstChildAtom();
1601 
1602         while( pChildAtom )
1603         {
1604             if( !pChildAtom->isContainer() )
1605             {
1606                 if( !pChildAtom->seekToContent() )
1607                     break;
1608             }
1609 
1610             switch( pChildAtom->getType() )
1611             {
1612             case DFF_msofbtAnimateFilterData:
1613             {
1614                 sal_uInt32 transition;
1615                 mrStCtrl >> nBits;
1616                 mrStCtrl >> transition;
1617 
1618                 if( nBits & 1 )
1619                     xFilter->setMode( transition == 0 );
1620 
1621                 dump( " transition=\"%s\"", (transition == 0) ? "in" : "out" );
1622             }
1623             break;
1624 
1625             case DFF_msofbtAnimAttributeValue:
1626             {
1627                 if( (nBits & 2 ) && ( pChildAtom->getInstance() == 1 )  )
1628                 {
1629                     Any aAny;
1630                     if ( importAttributeValue( pChildAtom, aAny ) )
1631                     {
1632                         rtl::OUString filter;
1633                         aAny >>= filter;
1634 
1635                         dump( " filter=\"%s\"", filter );
1636 
1637                         const transition* pTransition = transition::find( filter );
1638                         if( pTransition )
1639                         {
1640                             xFilter->setTransition( pTransition->mnType );
1641                             xFilter->setSubtype( pTransition->mnSubType );
1642                             xFilter->setDirection( pTransition->mbDirection );
1643                         }
1644                         else
1645                         {
1646                             DBG_ERROR( "unknown transition!" );
1647                         }
1648                     }
1649                 }
1650             }
1651             break;
1652 
1653             case DFF_msofbtAnimateTarget:
1654                 importAnimateAttributeTargetContainer( pChildAtom, xNode );
1655                 break;
1656 
1657             default:
1658                 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
1659                 break;
1660 
1661             }
1662 
1663             pChildAtom = pAtom->findNextChildAtom( pChildAtom );
1664         }
1665     }
1666 }
1667 
1668 // --------------------------------------------------------------------
1669 
importAnimateAttributeTargetContainer(const Atom * pAtom,const Reference<XAnimationNode> & xNode)1670 void AnimationImporter::importAnimateAttributeTargetContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1671 {
1672     DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateTarget, "invalid call to ppt::AnimationImporter::importAnimateAttributeTargetContainer()!");
1673 
1674     Any aTarget;
1675 
1676     Reference< XAnimate > xAnimate( xNode, UNO_QUERY );
1677 
1678     bool bWrongContext = false;
1679 
1680     if( pAtom )
1681     {
1682         const Atom* pChildAtom = pAtom->findFirstChildAtom();
1683 
1684         while( pChildAtom )
1685         {
1686             if( !pChildAtom->isContainer() )
1687             {
1688                 if( !pChildAtom->seekToContent() )
1689                     break;
1690             }
1691 
1692             switch( pChildAtom->getType() )
1693             {
1694             case DFF_msofbtAnimPropertySet:
1695             {
1696                 PropertySet aSet;
1697                 importPropertySetContainer( pChildAtom, aSet );
1698                 if( aSet.hasProperty( DFF_ANIM_RUNTIMECONTEXT ) )
1699                 {
1700                     OUString aContext;
1701                     if( aSet.getProperty( DFF_ANIM_RUNTIMECONTEXT ) >>= aContext )
1702                     {
1703                         if( !aContext.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("PPT") ) )
1704                             bWrongContext = true;
1705                     }
1706                 }
1707 
1708                 dump( aSet );
1709             }
1710             break;
1711 
1712             case DFF_msofbtAnimateTargetSettings:
1713             {
1714                 if( xAnimate.is() )
1715                 {
1716                     sal_uInt32 nBits;
1717                     sal_uInt32 nAdditive;
1718                     sal_uInt32 nAccumulate;
1719                     sal_uInt32 nTransformType;
1720 
1721                     mrStCtrl >> nBits >> nAdditive >> nAccumulate >> nTransformType;
1722 
1723                     // nBits %0001: additive, %0010: accumulate, %0100: attributeName, %1000: transformtype
1724                     // nAdditive 0 = base, 1 = sum, 2 = replace, 3 = multiply, 4 = none
1725                     // nAccumulate 0 = none, 1 = always
1726                     // nTransformType 0: "property" else "image"
1727 
1728                     if( nBits & 3 )
1729                     {
1730                         if( xAnimate.is() )
1731                         {
1732                             if( nBits & 1 )
1733                             {
1734                                 sal_Int16 nTemp = AnimationAdditiveMode::BASE;
1735                                 switch( nAdditive )
1736                                 {
1737                                 case 1: nTemp = AnimationAdditiveMode::SUM; break;
1738                                 case 2: nTemp = AnimationAdditiveMode::REPLACE; break;
1739                                 case 3: nTemp = AnimationAdditiveMode::MULTIPLY; break;
1740                                 case 4: nTemp = AnimationAdditiveMode::NONE; break;
1741                                 }
1742                                 xAnimate->setAdditive( nTemp );
1743                             }
1744 
1745                             if( nBits & 2 )
1746                             {
1747                                 xAnimate->setAccumulate( (nAccumulate == 0) ? sal_True : sal_False );
1748                             }
1749                         }
1750                     }
1751 #ifdef DBG_ANIM_LOG
1752                     if( nBits & 1 )
1753                         fprintf( mpFile, " additive=\"%s\"", (nAdditive == 0) ? "base" : (nAdditive == 2) ? "replace" : (nAdditive == 1) ? "sum" : (nAdditive == 3 ) ? "multiply" : (nAdditive == 4) ? "none" : "unknown" );
1754 
1755                     if( nBits & 2 )
1756                         fprintf( mpFile, " accumulate=\"%s\"", (nAccumulate == 0) ? "none" : "always" );
1757 
1758                     if( nBits & 8 )
1759                         fprintf( mpFile, " transformType=\"%s\"", (nTransformType == 0) ? "property" : "image" );
1760 #endif
1761                 }
1762             }
1763             break;
1764 
1765             case DFF_msofbtAnimateAttributeNames:
1766             {
1767                 if( xAnimate.is() )
1768                 {
1769                     OUString aAttributeName;
1770                     importAttributeNamesContainer( pChildAtom, aAttributeName );
1771                     if( xAnimate.is() )
1772                         xAnimate->setAttributeName( aAttributeName );
1773                     dump( " attributeName=\"%s\"", aAttributeName );
1774                 }
1775             }
1776             break;
1777 
1778             case DFF_msofbtAnimateTargetElement:
1779             {
1780                 sal_Int16 nSubType;
1781                 importTargetElementContainer( pChildAtom, aTarget, nSubType );
1782                 if( xAnimate.is() )
1783                     xAnimate->setSubItem( nSubType );
1784 
1785                 dump( " target=\"" );
1786                 dump_target( aTarget );
1787                 dump( "\"" );
1788             }
1789             break;
1790 
1791             default:
1792                 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
1793                 break;
1794             }
1795 
1796             pChildAtom = pAtom->findNextChildAtom( pChildAtom );
1797         }
1798     }
1799 
1800     if( bWrongContext )
1801         aTarget.clear();
1802 
1803     if( xAnimate.is() )
1804         xAnimate->setTarget( aTarget );
1805     else
1806     {
1807         Reference< XCommand > xCommand( xNode, UNO_QUERY );
1808         if( xCommand.is() )
1809             xCommand->setTarget( aTarget );
1810     }
1811 }
1812 
1813 // --------------------------------------------------------------------
1814 
implGetColorSpace(sal_Int32 nMode,sal_Int32,sal_Int32,sal_Int32)1815 sal_Int16 AnimationImporter::implGetColorSpace( sal_Int32 nMode, sal_Int32 /*nA*/, sal_Int32 /*nB*/, sal_Int32 /*nC*/ )
1816 {
1817     switch( nMode )
1818     {
1819     case 2: // index
1820         // FALLTHROUGH intended
1821     default:
1822         // FALLTHROUGH intended
1823     case 0: // rgb
1824         return AnimationColorSpace::RGB;
1825 
1826     case 1: // hsl
1827         return AnimationColorSpace::HSL;
1828     }
1829 }
1830 
1831 // --------------------------------------------------------------------
1832 
implGetColorAny(sal_Int32 nMode,sal_Int32 nA,sal_Int32 nB,sal_Int32 nC)1833 Any AnimationImporter::implGetColorAny( sal_Int32 nMode, sal_Int32  nA, sal_Int32 nB, sal_Int32 nC )
1834 {
1835     switch( nMode )
1836     {
1837     case 0: // rgb
1838         {
1839             dump( "rgb(%ld", nA );
1840             dump( ",%ld", nB );
1841             dump( ",%ld)", nC );
1842             Color aColor( (sal_uInt8)nA, (sal_uInt8)nB, (sal_uInt8)nC );
1843             return makeAny( (sal_Int32)aColor.GetRGBColor() );
1844         }
1845     case 1: // hsl
1846         {
1847             dump( "hsl(%ld", nA );
1848             dump( ",%ld", nB );
1849             dump( ",%ld)", nC );
1850             Sequence< double > aHSL( 3 );
1851             aHSL[0] = nA * 360.0/255.0;
1852             aHSL[1] = nB / 255.0;
1853             aHSL[2] = nC / 255.0;
1854             return makeAny( aHSL );
1855         }
1856 
1857     case 2: // index
1858         {
1859             Color aColor;
1860             mpPPTImport->GetColorFromPalette((sal_uInt16)nA, aColor );
1861             dump( "index(%ld", nA );
1862             dump( " [%ld", (sal_Int32)aColor.GetRed() );
1863             dump( ",%ld", (sal_Int32)aColor.GetGreen() );
1864             dump( ",%ld])", (sal_Int32)aColor.GetBlue() );
1865             return makeAny( (sal_Int32)aColor.GetRGBColor() );
1866         }
1867 
1868     default:
1869         {
1870             dump( "unknown_%ld(", nMode );
1871             dump( "%ld", nA );
1872             dump( ",%ld", nB );
1873             dump( ",%ld)", nC );
1874             DBG_ERROR( "ppt::implGetColorAny(), unhandled color type" );
1875 
1876             Any aAny;
1877             return aAny;
1878         }
1879     }
1880 }
1881 
importAnimateColorContainer(const Atom * pAtom,const Reference<XAnimationNode> & xNode)1882 void AnimationImporter::importAnimateColorContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1883 {
1884     Reference< XAnimateColor > xColor( xNode, UNO_QUERY );
1885 
1886     DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateColor && xColor.is(), "invalid call to ppt::AnimationImporter::importAnimateColorContainer()!");
1887     if( pAtom && xColor.is() )
1888     {
1889         const Atom* pChildAtom = pAtom->findFirstChildAtom();
1890 
1891         while( pChildAtom )
1892         {
1893             if( !pChildAtom->isContainer() )
1894             {
1895                 if( !pChildAtom->seekToContent() )
1896                     break;
1897             }
1898 
1899             switch( pChildAtom->getType() )
1900             {
1901             case DFF_msofbtAnimateColorData:
1902             {
1903                 sal_uInt32 nBits;
1904                 sal_Int32 nByMode, nByA, nByB, nByC;
1905                 sal_Int32 nFromMode, nFromA, nFromB, nFromC;
1906                 sal_Int32 nToMode, nToA, nToB, nToC;
1907                 mrStCtrl >> nBits;
1908                 mrStCtrl >> nByMode >> nByA >> nByB >> nByC;
1909                 mrStCtrl >> nFromMode >> nFromA >> nFromB >> nFromC;
1910                 mrStCtrl >> nToMode >> nToA >> nToB >> nToC;
1911 
1912                 if( nBits & 1 )
1913                 {
1914                     dump( " by=\"" );
1915                     xColor->setBy( implGetColorAny( nByMode, nByA, nByB, nByC ) );
1916                     xColor->setColorInterpolation( implGetColorSpace( nByMode, nByA, nByB, nByC ) );
1917                     dump( "\"");
1918                 }
1919 
1920                 if( nBits & 2 )
1921                 {
1922                     dump( " from=\"" );
1923                     xColor->setFrom( implGetColorAny( nFromMode, nFromA, nFromB, nFromC ) );
1924                     xColor->setColorInterpolation( implGetColorSpace( nFromMode, nFromA, nFromB, nFromC ) );
1925                     dump( "\"");
1926                 }
1927 
1928                 if( nBits & 4 )
1929                 {
1930                     dump( " to=\"" );
1931                     xColor->setTo( implGetColorAny( nToMode, nToA, nToB, nToC ) );
1932                     xColor->setColorInterpolation( implGetColorSpace( nToMode, nToA, nToB, nToC ) );
1933                     dump( "\"");
1934                 }
1935             }
1936             break;
1937 
1938             case DFF_msofbtAnimateTarget:
1939                 importAnimateAttributeTargetContainer( pChildAtom, xNode );
1940                 break;
1941 
1942             default:
1943                 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
1944                 break;
1945             }
1946 
1947             pChildAtom = pAtom->findNextChildAtom( pChildAtom );
1948         }
1949     }
1950 }
1951 
1952 // --------------------------------------------------------------------
1953 
importAnimateSetContainer(const Atom * pAtom,const Reference<XAnimationNode> & xNode)1954 void AnimationImporter::importAnimateSetContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
1955 {
1956     Reference< XAnimateSet > xSet( xNode, UNO_QUERY );
1957 
1958     DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateSet && xSet.is(), "invalid call to ppt::AnimationImporter::importAnimateSetContainer()!");
1959     if( pAtom && xSet.is() )
1960     {
1961         const Atom* pChildAtom = pAtom->findFirstChildAtom();
1962 
1963         while( pChildAtom )
1964         {
1965             if( !pChildAtom->isContainer() )
1966             {
1967                 if( !pChildAtom->seekToContent() )
1968                     break;
1969             }
1970 
1971             switch( pChildAtom->getType() )
1972             {
1973             case DFF_msofbtAnimateSetData:
1974             {
1975                 sal_Int32 nU1, nU2;
1976                 mrStCtrl >> nU1 >> nU2;
1977 
1978                 dump( " set_1=\"%ld\"", nU1 ),
1979                 dump( " set_2=\"%ld\"", nU2 );
1980             }
1981             break;
1982 
1983             case DFF_msofbtAnimAttributeValue:
1984             {
1985                 Any aTo;
1986                 if ( importAttributeValue( pChildAtom, aTo ) )
1987                 {
1988                     xSet->setTo( aTo );
1989 
1990                     dump( " value=\"" );
1991                     dump( aTo );
1992                     dump( "\"" );
1993                 }
1994             }
1995             break;
1996 
1997             case DFF_msofbtAnimateTarget:
1998                 importAnimateAttributeTargetContainer( pChildAtom, xNode );
1999                 break;
2000 
2001             default:
2002                 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
2003                 break;
2004             }
2005 
2006             pChildAtom = pAtom->findNextChildAtom( pChildAtom );
2007         }
2008     }
2009 }
2010 
2011 // --------------------------------------------------------------------
2012 
importAnimateContainer(const Atom * pAtom,const Reference<XAnimationNode> & xNode)2013 void AnimationImporter::importAnimateContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2014 {
2015     Reference< XAnimate > xAnim( xNode, UNO_QUERY );
2016 
2017     DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimate && xAnim.is(), "invalid call to ppt::AnimationImporter::importAnimateContainer()!");
2018     if( pAtom && xAnim.is() )
2019     {
2020         const Atom* pChildAtom = pAtom->findFirstChildAtom();
2021 
2022         while( pChildAtom )
2023         {
2024             if( !pChildAtom->isContainer() )
2025             {
2026                 if( !pChildAtom->seekToContent() )
2027                     break;
2028             }
2029 
2030             switch( pChildAtom->getType() )
2031             {
2032             case DFF_msofbtAnimateData:
2033             {
2034                 sal_uInt32 nCalcmode, nBits, nValueType;
2035                 mrStCtrl >> nCalcmode >> nBits >> nValueType;
2036 
2037                 if( nBits & 0x08 )
2038                 {
2039                     sal_Int16 n = (nCalcmode == 1) ? AnimationCalcMode::LINEAR : /* (nCalcmode == 2) ? AnimationCalcMode::FORMULA : */ AnimationCalcMode::DISCRETE;
2040                     xAnim->setCalcMode( n );
2041                     dump( " calcmode=\"%s\"", (nCalcmode == 0) ? "discrete" : (nCalcmode == 1) ? "linear" : (nCalcmode == 2) ? "formula" : "unknown" );
2042                 }
2043 
2044                 if( nBits & 0x30 )
2045                 {
2046                     sal_Int16 n = (nValueType == 1) ? AnimationValueType::NUMBER : (nValueType == 2 ) ? AnimationValueType::COLOR : AnimationValueType::STRING;
2047                     xAnim->setValueType( n );
2048                     dump( " valueType=\"%s\"", (nValueType == 0) ? "string" : (nValueType == 1) ? "number" : (nValueType == 2) ? "color" : "unknown" );
2049                 }
2050             }
2051             break;
2052 
2053             case DFF_msofbtAnimateTarget:
2054                 importAnimateAttributeTargetContainer( pChildAtom, xNode );
2055                 break;
2056 
2057             case DFF_msofbtAnimKeyPoints:
2058                 importAnimateKeyPoints( pChildAtom, xNode );
2059                 break;
2060 
2061             case DFF_msofbtAnimAttributeValue:
2062                 {
2063                     Any a;
2064                     if ( importAttributeValue( pChildAtom, a ) )
2065                     {
2066                         switch( pChildAtom->getInstance() )
2067                         {
2068                         case 1: xAnim->setBy( a ); dump( " by=\"" ); break;
2069                         case 2: xAnim->setFrom( a ); dump( " from=\"" ); break;
2070                         case 3: xAnim->setTo( a ); dump( " to=\"" ); break;
2071                         default:
2072                             dump( " unknown_value=\"" );
2073                         }
2074 
2075                         dump( a );
2076                         dump( "\"" );
2077                     }
2078                 }
2079                 break;
2080             default:
2081                 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
2082                 break;
2083             }
2084 
2085             pChildAtom = pAtom->findNextChildAtom( pChildAtom );
2086         }
2087     }
2088 }
2089 
2090 // --------------------------------------------------------------------
2091 
importAnimateMotionContainer(const Atom * pAtom,const Reference<XAnimationNode> & xNode)2092 void AnimationImporter::importAnimateMotionContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2093 {
2094     Reference< XAnimateMotion > xMotion( xNode, UNO_QUERY );
2095 
2096     DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateMotion && xMotion.is(), "invalid call to ppt::AnimationImporter::importAnimateMotionContainer()!");
2097     if( pAtom && xMotion.is() )
2098     {
2099         const Atom* pChildAtom = pAtom->findFirstChildAtom();
2100 
2101         while( pChildAtom )
2102         {
2103             if( !pChildAtom->isContainer() )
2104             {
2105                 if( !pChildAtom->seekToContent() )
2106                     break;
2107             }
2108 
2109             switch( pChildAtom->getType() )
2110             {
2111             case DFF_msofbtAnimateMotionData:
2112             {
2113                 sal_uInt32 nBits, nOrigin;
2114                 float fByX, fByY, fFromX, fFromY, fToX, fToY;
2115 
2116                 mrStCtrl >> nBits >> fByX >> fByY >> fFromX >> fFromY >> fToX >> fToY >> nOrigin;
2117 
2118 #ifdef DBG_ANIM_LOG
2119                 if( nBits & 1 )
2120                     fprintf( mpFile, " by=\"%g,%g\"", (double)fByX, (double)fByY );
2121 
2122                 if( nBits & 2 )
2123                     fprintf( mpFile, " from=\"%g,%g\"", (double)fFromX, (double)fFromY );
2124 
2125                 if( nBits & 4 )
2126                     fprintf( mpFile, " to=\"%g,%g\"", (double)fToX, (double)fToY );
2127 
2128                 if( nBits & 8 )
2129                     fprintf( mpFile, " origin=\"%s\"", (nOrigin == 1) ? "parent" : (nOrigin == 2) ? "layout" : "unknown" );
2130 
2131 #endif
2132             }
2133             break;
2134 
2135             case DFF_msofbtAnimAttributeValue:
2136             {
2137                 Any aPath;
2138                 if ( importAttributeValue( pChildAtom, aPath ) )
2139                 {
2140                     rtl::OUString aStr;
2141                     if ( aPath >>= aStr )
2142                     {
2143                         aStr = aStr.replace( 'E', ' ' );
2144                         aStr = aStr.trim();
2145                         aPath <<= aStr;
2146                         xMotion->setPath( aPath );
2147                         dump( " path=\"" );
2148                         dump( aPath );
2149                         dump( "\"" );
2150                     }
2151                 }
2152             }
2153             break;
2154 
2155             case DFF_msofbtAnimateTarget:
2156                 importAnimateAttributeTargetContainer( pChildAtom, xNode );
2157                 break;
2158 
2159             default:
2160                 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
2161                 break;
2162             }
2163 
2164             pChildAtom = pAtom->findNextChildAtom( pChildAtom );
2165         }
2166     }
2167 }
2168 
2169 // --------------------------------------------------------------------
2170 
importCommandContainer(const Atom * pAtom,const Reference<XAnimationNode> & xNode)2171 void AnimationImporter::importCommandContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2172 {
2173     Reference< XCommand > xCommand( xNode, UNO_QUERY );
2174     DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimCommand && xCommand.is(), "invalid call to ppt::AnimationImporter::importCommandContainer()!");
2175     if( pAtom && xCommand.is() )
2176     {
2177         sal_Int32 nBits = 0, nType = 0;
2178         Any aValue;
2179 
2180         const Atom* pChildAtom = pAtom->findFirstChildAtom();
2181 
2182         while( pChildAtom )
2183         {
2184             if( !pChildAtom->isContainer() )
2185             {
2186                 if( !pChildAtom->seekToContent() )
2187                     break;
2188             }
2189 
2190             switch( pChildAtom->getType() )
2191             {
2192             case DFF_msofbtCommandData:
2193             {
2194                 sal_Int32 nCommandType;
2195                 // looks like U1 is a bitset, bit 1 enables the type and bit 2 enables
2196                 // a propertyvalue that follows
2197                 mrStCtrl >> nBits;
2198                 mrStCtrl >> nCommandType;
2199 
2200                 if( nBits & 1 )
2201                 {
2202                     dump( " type=\"%s\"", (nCommandType == 0) ? "event" : ( nCommandType == 1) ? "call" : "verb" );
2203                 }
2204             }
2205             break;
2206 
2207             case DFF_msofbtAnimAttributeValue:
2208             {
2209                 if ( importAttributeValue( pChildAtom, aValue ) )
2210                 {
2211                     if( nBits & 2 )
2212                     {
2213                         dump( " cmd=\"" );
2214                         dump( aValue );
2215                         dump( "\"" );
2216                     }
2217                 }
2218             }
2219             break;
2220 
2221             case DFF_msofbtAnimateTarget:
2222                 importAnimateAttributeTargetContainer( pChildAtom, xNode );
2223                 break;
2224 
2225             default:
2226                 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
2227                 break;
2228             }
2229 
2230             pChildAtom = pAtom->findNextChildAtom( pChildAtom );
2231         }
2232 
2233         if( nBits & 3 )
2234         {
2235             OUString aParam;
2236             aValue >>= aParam;
2237 
2238             sal_Int16 nCommand = EffectCommands::CUSTOM;
2239 
2240             NamedValue aParamValue;
2241 
2242             switch( nType )
2243             {
2244             case 0: // event
2245             case 1: // call
2246                 if( aParam.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "onstopaudio" ) ) )
2247                 {
2248                     nCommand = EffectCommands::STOPAUDIO;
2249                 }
2250                 else if( aParam.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("play") ) )
2251                 {
2252                     nCommand = EffectCommands::PLAY;
2253                 }
2254                 else if( aParam.compareToAscii( RTL_CONSTASCII_STRINGPARAM("playFrom") ) == 0 )
2255                 {
2256                     const OUString aMediaTime( aParam.copy( 9, aParam.getLength() - 10 ) );
2257                     rtl_math_ConversionStatus eStatus;
2258                     double fMediaTime = ::rtl::math::stringToDouble( aMediaTime, (sal_Unicode)('.'), (sal_Unicode)(','), &eStatus, NULL );
2259                     if( eStatus == rtl_math_ConversionStatus_Ok )
2260                     {
2261                         aParamValue.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("MediaTime"));
2262                         aParamValue.Value <<= fMediaTime;
2263                     }
2264                     nCommand = EffectCommands::PLAY;
2265                 }
2266                 else if( aParam.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("togglePause") ) )
2267                 {
2268                     nCommand = EffectCommands::TOGGLEPAUSE;
2269                 }
2270                 else if( aParam.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("stop") ) )
2271                 {
2272                     nCommand = EffectCommands::STOP;
2273                 }
2274                 break;
2275             case 2: // verb
2276                 {
2277                     aParamValue.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("Verb"));
2278                     aParamValue.Value <<= aParam.toInt32();
2279 
2280                     nCommand = EffectCommands::VERB;
2281                 }
2282                 break;
2283             }
2284 
2285             xCommand->setCommand( nCommand );
2286             if( nCommand == EffectCommands::CUSTOM )
2287             {
2288                 DBG_ERROR("sd::AnimationImporter::importCommandContainer(), unknown command!");
2289                 aParamValue.Name = OUString(RTL_CONSTASCII_USTRINGPARAM("UserDefined"));
2290                 aParamValue.Value <<= aParam;
2291             }
2292 
2293             if( aParamValue.Value.hasValue() )
2294             {
2295                 Sequence< NamedValue > aParamSeq( &aParamValue, 1 );
2296                 xCommand->setParameter( makeAny( aParamSeq ) );
2297             }
2298         }
2299     }
2300 }
2301 
2302 // --------------------------------------------------------------------
2303 
importAudioContainer(const Atom * pAtom,const Reference<XAnimationNode> & xNode)2304 void AnimationImporter::importAudioContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2305 {
2306     Reference< XAudio > xAudio( xNode, UNO_QUERY );
2307     DBG_ASSERT( pAtom && xAudio.is() &&
2308                  ( (pAtom->getType() == DFF_msofbtAnimGroup) ||
2309                    (pAtom->getType() == DFF_msofbtAnimSubGoup) ), "invalid call to ppt::AnimationImporter::importAudioContainer()!");
2310     if( pAtom && xAudio.is() )
2311     {
2312         importAnimationEvents( pAtom, xNode );
2313         importAnimationValues( pAtom, xNode );
2314         importAnimationActions( pAtom, xNode );
2315 
2316         dump(">\n");
2317 
2318         const Atom* pChildAtom = pAtom->findFirstChildAtom();
2319 
2320         while( pChildAtom )
2321         {
2322             if( !pChildAtom->isContainer() )
2323             {
2324                 if( !pChildAtom->seekToContent() )
2325                     break;
2326             }
2327 
2328             switch( pChildAtom->getType() )
2329             {
2330             case DFF_msofbtAnimNode:
2331             case DFF_msofbtAnimEvent:
2332             case DFF_msofbtAnimValue:
2333             case DFF_msofbtAnimAction:
2334             case DFF_msofbtAnimPropertySet:
2335                 break;
2336 
2337             case DFF_msofbtAnimAttributeValue:
2338             {
2339                 Any aValue;
2340                 if ( importAttributeValue( pChildAtom, aValue ) )
2341                 {
2342                     dump( " value=\"" );
2343                     dump( aValue );
2344                     dump( "\"" );
2345                 }
2346             }
2347             break;
2348 
2349             case DFF_msofbtAnimateTargetElement:
2350             {
2351                 sal_Int16 nSubType;
2352                 Any aSource;
2353                 importTargetElementContainer( pChildAtom, aSource, nSubType );
2354                 if( xAudio.is() )
2355                     xAudio->setSource( aSource );
2356             }
2357             break;
2358 
2359             default:
2360                 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
2361                 break;
2362             }
2363 
2364             pChildAtom = pAtom->findNextChildAtom( pChildAtom );
2365         }
2366 
2367         // TODO: What to do with them?
2368         Any aEmpty;
2369         xAudio->setBegin( aEmpty );
2370         xAudio->setEnd( aEmpty );
2371     }
2372 }
2373 
2374 // --------------------------------------------------------------------
2375 
importAnimateScaleContainer(const Atom * pAtom,const Reference<XAnimationNode> & xNode)2376 void AnimationImporter::importAnimateScaleContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2377 {
2378     Reference< XAnimateTransform > xTransform( xNode, UNO_QUERY );
2379 
2380     DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateScale && xTransform.is(), "invalid call to ppt::AnimationImporter::importAnimateScaleContainer()!");
2381     if( pAtom && xTransform.is() )
2382     {
2383         xTransform->setTransformType( AnimationTransformType::SCALE );
2384 
2385         const Atom* pChildAtom = pAtom->findFirstChildAtom();
2386 
2387         while( pChildAtom )
2388         {
2389             if( !pChildAtom->isContainer() )
2390             {
2391                 if( !pChildAtom->seekToContent() )
2392                     break;
2393             }
2394 
2395             switch( pChildAtom->getType() )
2396             {
2397             case DFF_msofbtAnimateScaleData:
2398             {
2399                 sal_uInt32 nBits, nZoomContents;
2400                 float fByX, fByY, fFromX, fFromY, fToX, fToY;
2401 
2402                 // nBits %001: by, %010: from, %100: to, %1000: zoomContents(bool)
2403                 mrStCtrl >> nBits >> fByX >> fByY >> fFromX >> fFromY >> fToX >> fToY >> nZoomContents;
2404 
2405                 ValuePair aPair;
2406                 // 'from' value
2407                 if( nBits & 2 )
2408                 {
2409                     aPair.First <<= (double)fFromX / 100.0;
2410                     aPair.Second <<= (double)fFromY / 100.0;
2411                     xTransform->setFrom( makeAny( aPair ) );
2412                 }
2413 
2414                 // 'to' value
2415                 if( nBits & 4 )
2416                 {
2417                     aPair.First <<= (double)fToX / 100.0;
2418                     aPair.Second <<= (double)fToY / 100.0;
2419                     xTransform->setTo( makeAny( aPair ) );
2420                 }
2421 
2422                 // 'by' value
2423                 if( nBits & 1 )
2424                 {
2425                     aPair.First <<= (double)fByX / 100.0;
2426                     aPair.Second <<= (double)fByY / 100.0;
2427 
2428                     if( nBits & 2 )
2429                     {
2430                         // 'from' value given, import normally
2431                         xTransform->setBy( makeAny( aPair ) );
2432                     }
2433                     else
2434                     {
2435                         // mapping 'by' to 'to', if no 'from' is
2436                         // given. This is due to a non-conformity in
2437                         // PPT, which exports animateScale effects
2438                         // with a sole 'by' value, but with the
2439                         // semantics of a sole 'to' animation
2440                         xTransform->setTo( makeAny( aPair ) );
2441                     }
2442                 }
2443 
2444 
2445 #ifdef DBG_ANIM_LOG
2446                 if( nBits & 1 )
2447                     fprintf( mpFile, " by=\"%g,%g\"", (double)fByX, (double)fByY );
2448 
2449                 if( nBits & 2 )
2450                     fprintf( mpFile, " from=\"%g,%g\"", (double)fFromX, (double)fFromY );
2451 
2452                 if( nBits & 4 )
2453                     fprintf( mpFile, " to=\"%g,%g\"", (double)fToX, (double)fToY );
2454 
2455                 if( nBits & 8 )
2456                     fprintf( mpFile, " zoomContents=\"%s\"", nZoomContents ? "true" : "false" );
2457 #endif
2458             }
2459             break;
2460 
2461             case DFF_msofbtAnimateTarget:
2462                 importAnimateAttributeTargetContainer( pChildAtom, xNode );
2463                 break;
2464 
2465             default:
2466                 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
2467                 break;
2468             }
2469 
2470             pChildAtom = pAtom->findNextChildAtom( pChildAtom );
2471         }
2472     }
2473 }
2474 
2475 // --------------------------------------------------------------------
2476 
importAnimateRotationContainer(const Atom * pAtom,const Reference<XAnimationNode> & xNode)2477 void AnimationImporter::importAnimateRotationContainer( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2478 {
2479     Reference< XAnimateTransform > xTransform( xNode, UNO_QUERY );
2480 
2481     DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimateRotation && xTransform.is(), "invalid call to ppt::AnimationImporter::importAnimateRotationContainer()!");
2482     if( pAtom && xTransform.is() )
2483     {
2484         xTransform->setTransformType( AnimationTransformType::ROTATE );
2485 
2486         const Atom* pChildAtom = pAtom->findFirstChildAtom();
2487 
2488         while( pChildAtom )
2489         {
2490             if( !pChildAtom->isContainer() )
2491             {
2492                 if( !pChildAtom->seekToContent() )
2493                     break;
2494             }
2495 
2496             switch( pChildAtom->getType() )
2497             {
2498             case DFF_msofbtAnimateRotationData:
2499             {
2500                 sal_uInt32 nBits, nU1;
2501                 float fBy, fFrom, fTo;
2502 
2503                 // nBits %001: by, %010: from, %100: to, %1000: zoomContents(bool)
2504                 mrStCtrl >> nBits >> fBy >> fFrom >> fTo >> nU1;
2505 
2506                 if( nBits & 1 )
2507                     xTransform->setBy( makeAny( (double) fBy ) );
2508 
2509                 if( nBits & 2 )
2510                     xTransform->setFrom( makeAny( (double) fFrom ) );
2511 
2512                 if( nBits & 4 )
2513                     xTransform->setTo( makeAny( (double) fTo ) );
2514 
2515 #ifdef DBG_ANIM_LOG
2516                 if( nBits & 1 )
2517                     fprintf( mpFile, " by=\"%g\"", (double)fBy );
2518 
2519                 if( nBits & 2 )
2520                     fprintf( mpFile, " from=\"%g\"", (double)fFrom );
2521 
2522                 if( nBits & 4 )
2523                     fprintf( mpFile, " to=\"%g\"", (double)fTo );
2524 
2525                 if( nU1 )
2526                     fprintf( mpFile, " rotation_1=\"%ld\"", nU1 );
2527 #endif
2528             }
2529             break;
2530 
2531             case DFF_msofbtAnimateTarget:
2532                 importAnimateAttributeTargetContainer( pChildAtom, xNode );
2533                 break;
2534 
2535             default:
2536                 dump( " unknown_atom=\"%ld\"", (sal_Int32)pChildAtom->getType() );
2537                 break;
2538             }
2539 
2540             pChildAtom = pAtom->findNextChildAtom( pChildAtom );
2541         }
2542     }
2543 }
2544 // --------------------------------------------------------------------
2545 
importAttributeNamesContainer(const Atom * pAtom,OUString & rAttributeNames)2546 bool AnimationImporter::importAttributeNamesContainer( const Atom* pAtom, OUString& rAttributeNames )
2547 {
2548     OUStringBuffer aNames;
2549 
2550     DBG_ASSERT( pAtom && (pAtom->getType() == DFF_msofbtAnimateAttributeNames), "invalid call to ppt::AnimationImporter::importAttributeName()!" );
2551     if( pAtom )
2552     {
2553         const Atom* pAttributeValueAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimAttributeValue );
2554 
2555         while( pAttributeValueAtom )
2556         {
2557             Any aAny;
2558             if ( importAttributeValue( pAttributeValueAtom, aAny ) )
2559             {
2560                 OUString aName;
2561                 if( aAny >>= aName )
2562                 {
2563                     if( aNames.getLength() )
2564                         aNames.append( (sal_Unicode)';' );
2565 
2566                     aNames.append( aName );
2567                 }
2568             }
2569             else
2570             {
2571                 DBG_ERROR( "error during ppt::AnimationImporter::importAttributeName()!" );
2572             }
2573 
2574             pAttributeValueAtom = pAtom->findNextChildAtom( DFF_msofbtAnimAttributeValue, pAttributeValueAtom );
2575         }
2576     }
2577 
2578     rAttributeNames = aNames.makeStringAndClear();
2579     return true;
2580 }
2581 
2582 // --------------------------------------------------------------------
2583 
importAnimationValues(const Atom * pAtom,const Reference<XAnimationNode> & xNode)2584 void AnimationImporter::importAnimationValues( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2585 {
2586     DBG_ASSERT( pAtom, "invalid call to ppt::AnimationImporter::importAnimationValues()!" );
2587 
2588     if( pAtom )
2589     {
2590         const Atom* pValueAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimValue );
2591 
2592         while( pValueAtom && pValueAtom->seekToContent() )
2593         {
2594             sal_uInt32 nType;
2595             mrStCtrl >> nType;
2596             switch( nType )
2597             {
2598             case 0:
2599             {
2600                 float fRepeat;
2601                 mrStCtrl >> fRepeat;
2602                 xNode->setRepeatCount( (fRepeat < ((float)3.40282346638528860e+38)) ? makeAny( (double)fRepeat ) : makeAny( Timing_INDEFINITE ) );
2603 
2604 #ifdef DBG_ANIM_LOG
2605                 if( (fRepeat < ((float)3.40282346638528860e+38)) )
2606                 {
2607                     dump( " repeat=\"%g\"", (double)fRepeat );
2608                 }
2609                 else
2610                 {
2611                     dump( " repeat=\"indefinite\"" );
2612                 }
2613 #endif
2614             }
2615             break;
2616 
2617             case 3:
2618             {
2619                 float faccelerate;
2620                 mrStCtrl >> faccelerate;
2621                 xNode->setAcceleration( faccelerate );
2622                 dump( " accelerate=\"%g\"", (double)faccelerate );
2623             }
2624             break;
2625 
2626             case 4:
2627             {
2628                 float fdecelerate;
2629                 mrStCtrl >> fdecelerate;
2630                 xNode->setDecelerate( fdecelerate );
2631                 dump( " decelerate=\"%g\"", (double)fdecelerate );
2632             }
2633             break;
2634 
2635             case 5:
2636             {
2637                 sal_Int32 nAutoreverse;
2638                 mrStCtrl >> nAutoreverse;
2639                 xNode->setAutoReverse( nAutoreverse != 0 );
2640                 dump( " autoreverse=\"%#lx\"", nAutoreverse );
2641             }
2642             break;
2643 
2644             default:
2645             {
2646                 sal_uInt32 nUnknown;
2647                 mrStCtrl >> nUnknown;
2648 #ifdef DBG_ANIM_LOG
2649                 fprintf(mpFile, " attribute_%d=\"%#lx\"", nType, nUnknown );
2650 #endif
2651             }
2652             break;
2653             }
2654 
2655             pValueAtom = pAtom->findNextChildAtom( DFF_msofbtAnimValue, pValueAtom );
2656         }
2657     }
2658 }
2659 
2660 // --------------------------------------------------------------------
2661 
importAnimateKeyPoints(const Atom * pAtom,const Reference<XAnimationNode> & xNode)2662 void AnimationImporter::importAnimateKeyPoints( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2663 {
2664     Reference< XAnimate > xAnim( xNode, UNO_QUERY );
2665 
2666     DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimKeyPoints && xAnim.is(), "invalid call to ppt::AnimationImporter::importAnimateKeyPoints()!" );
2667 
2668     if( pAtom && xAnim.is() )
2669     {
2670         // first count keytimes
2671         const Atom* pIter = NULL;
2672         int nKeyTimes = 0;
2673 
2674         while( (pIter = pAtom->findNextChildAtom( DFF_msofbtAnimKeyTime,  pIter )) != 0 )
2675             nKeyTimes++;
2676 
2677         Sequence< double > aKeyTimes( nKeyTimes );
2678         Sequence< Any > aValues( nKeyTimes );
2679         OUString aFormula;
2680 
2681         pIter = pAtom->findFirstChildAtom(DFF_msofbtAnimKeyTime);
2682         int nKeyTime;
2683         sal_Int32 nTemp;
2684         for( nKeyTime = 0; (nKeyTime < nKeyTimes) && pIter; nKeyTime++ )
2685         {
2686             if( pIter->seekToContent() )
2687             {
2688                 mrStCtrl >> nTemp;
2689                 double fTemp = (double)nTemp / 1000.0;
2690                 aKeyTimes[nKeyTime] = fTemp;
2691 
2692                 const Atom* pValue = pAtom->findNextChildAtom(pIter);
2693                 if( pValue && pValue->getType() == DFF_msofbtAnimAttributeValue )
2694                 {
2695                     Any aValue1, aValue2;
2696                     if( importAttributeValue( pValue, aValue1 ) )
2697                     {
2698                         pValue = pAtom->findNextChildAtom(pValue);
2699                         if( pValue && pValue->getType() == DFF_msofbtAnimAttributeValue )
2700                             importAttributeValue( pValue, aValue2 );
2701 
2702                         bool bCouldBeFormula = false;
2703                         bool bHasValue = aValue2.hasValue();
2704                         if( bHasValue )
2705                         {
2706                             if( aValue2.getValueType() == ::getCppuType((const OUString*)0) )
2707                             {
2708                                 OUString aTest;
2709                                 aValue2 >>= aTest;
2710                                 bHasValue = aTest.getLength() != 0;
2711                                 bCouldBeFormula = true;
2712                             }
2713                         }
2714 
2715                         if( bHasValue && bCouldBeFormula && (aValue1.getValueType() == ::getCppuType((const double*)0)) )
2716                         {
2717                             aValue2 >>= aFormula;
2718                             bHasValue = false;
2719                         }
2720 
2721                         if( bHasValue )
2722                         {
2723                             aValues[nKeyTime] = makeAny( ValuePair( aValue1, aValue2 ) );
2724                         }
2725                         else
2726                         {
2727                             aValues[nKeyTime] = aValue1;
2728                         }
2729                     }
2730                 }
2731             }
2732             pIter = pAtom->findNextChildAtom(DFF_msofbtAnimKeyTime, pIter);
2733         }
2734 
2735 #ifdef DBG_ANIM_LOG
2736         dump( " keyTimes=\"" );
2737         for( int i=0; i<nKeyTimes; ++i )
2738             dump( "%f;", aKeyTimes[i] );
2739 
2740         if( aFormula.getLength() )
2741         {
2742             dump( "formula=\"%s", aFormula );
2743         }
2744 
2745         dump( "\" values=\"" );
2746         double nVal;
2747         OUString aStr;
2748         for( int i=0; i<nKeyTimes; ++i )
2749         {
2750             if( i != 0 )
2751                 dump( ";" );
2752 
2753             if( aValues[i] >>= aStr )
2754                 dump( "%s",
2755                       ::rtl::OUStringToOString( aStr,
2756                                                 RTL_TEXTENCODING_ASCII_US ).getStr() );
2757             else if( aValues[i] >>= nVal )
2758                 dump( "%f", nVal );
2759             else
2760             {
2761                 ValuePair aValuePair;
2762 
2763                 if( aValues[i] >>= aValuePair )
2764                 {
2765                     if( aValuePair.First >>= aStr )
2766                         dump( "%s",
2767                               ::rtl::OUStringToOString( aStr,
2768                                                         RTL_TEXTENCODING_ASCII_US ).getStr() );
2769                     else if( aValuePair.First >>= nVal )
2770                         dump( "%f", nVal );
2771                     else
2772                         dump( "%X", (sal_Int32)&aValuePair.First );
2773 
2774                     if( aValuePair.Second >>= aStr )
2775                         dump( ",%s",
2776                               ::rtl::OUStringToOString( aStr,
2777                                                         RTL_TEXTENCODING_ASCII_US ).getStr() );
2778                     else if( aValuePair.Second >>= nVal )
2779                         dump( ",%f", nVal );
2780                     else
2781                         dump( ",%X", (sal_Int32)&aValuePair.Second );
2782                 }
2783             }
2784         }
2785         dump( "\"" );
2786 #endif
2787 
2788         xAnim->setKeyTimes( aKeyTimes );
2789         xAnim->setValues( aValues );
2790         xAnim->setFormula( aFormula );
2791     }
2792 }
2793 
2794 // --------------------------------------------------------------------
2795 
importAttributeValue(const Atom * pAtom,Any & rAny)2796 bool AnimationImporter::importAttributeValue( const Atom* pAtom, Any& rAny )
2797 {
2798     DBG_ASSERT( pAtom && pAtom->getType() == DFF_msofbtAnimAttributeValue, "invalid call to ppt::AnimationImporter::importAttributeValue()!" );
2799 
2800     bool bOk = false;
2801 
2802     if( pAtom && pAtom->seekToContent() )
2803     {
2804         sal_uInt32 nRecLen = pAtom->getLength();
2805         if ( nRecLen >= 1 )
2806         {
2807             sal_Int8 nType;
2808             mrStCtrl >> nType;
2809             switch( nType )
2810             {
2811                 case DFF_ANIM_PROP_TYPE_BYTE :
2812                 {
2813                     if ( nRecLen == 2 )
2814                     {
2815                         sal_uInt8 nByte;
2816                         mrStCtrl >> nByte;
2817                         rAny <<= nByte;
2818 
2819                         bOk = true;
2820                     }
2821                 }
2822                 break;
2823 
2824                 case DFF_ANIM_PROP_TYPE_INT32 :
2825                 {
2826                     if ( nRecLen == 5 )
2827                     {
2828                         sal_uInt32 nInt32;
2829                         mrStCtrl >> nInt32;
2830                         rAny <<= nInt32;
2831 
2832                         bOk = true;
2833                     }
2834                 }
2835                 break;
2836 
2837                 case DFF_ANIM_PROP_TYPE_FLOAT:
2838                 {
2839                     if( nRecLen == 5 )
2840                     {
2841                         float fFloat;
2842                         mrStCtrl >> fFloat;
2843                         rAny <<= (double)fFloat;
2844 
2845                         bOk = true;
2846                     }
2847                 }
2848                 break;
2849 
2850                 case DFF_ANIM_PROP_TYPE_UNISTRING :
2851                 {
2852                     if ( ( nRecLen & 1 ) && ( nRecLen > 1 ) )
2853                     {
2854                         String aString;
2855                         mpPPTImport->MSDFFReadZString( mrStCtrl, aString, nRecLen - 1, sal_True );
2856                         rtl::OUString aOUString( aString );
2857                         rAny <<= aOUString;
2858 
2859                         bOk = true;
2860                     }
2861                 }
2862                 break;
2863             }
2864         }
2865     }
2866 
2867     DBG_ASSERT( bOk, "invalid value inside ppt::AnimationImporter::importAttributeValue()!" );
2868     return bOk;
2869 }
2870 
2871 // --------------------------------------------------------------------
2872 
importAnimationEvents(const Atom * pAtom,const Reference<XAnimationNode> & xNode)2873 void AnimationImporter::importAnimationEvents( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2874 {
2875     DBG_ASSERT( xNode.is() && pAtom, "invalid call to ppt::AnimationImporter::importAnimationEvents()!" );
2876 
2877     Any aBegin, aEnd, aNext, aPrev;
2878 
2879     const Atom* pEventAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimEvent );
2880     while( pEventAtom )
2881     {
2882         Any* pEvents = NULL;
2883 
2884         switch( pEventAtom->getInstance() )
2885         {
2886         case 1: pEvents = &aBegin; break;
2887         case 2: pEvents = &aEnd; break;
2888         case 3: pEvents = &aNext; break;
2889         case 4: pEvents = &aPrev; break;
2890         }
2891 
2892         if( pEvents )
2893         {
2894             Event aEvent;
2895             aEvent.Trigger = EventTrigger::NONE;
2896             aEvent.Repeat = 0;
2897 
2898             const Atom* pChildAtom = pEventAtom->findFirstChildAtom();
2899 
2900             while( pChildAtom && pChildAtom->seekToContent() )
2901             {
2902                 switch( pChildAtom->getType() )
2903                 {
2904                 case DFF_msofbtAnimTrigger:
2905                 {
2906                     sal_Int32 nU1, nTrigger, nU3, nBegin;
2907                     mrStCtrl >> nU1;
2908                     mrStCtrl >> nTrigger;
2909                     mrStCtrl >> nU3;
2910                     mrStCtrl >> nBegin;
2911 
2912                     switch( nTrigger )
2913                     {
2914                     case 0: aEvent.Trigger = EventTrigger::NONE; break;
2915                     case 1: aEvent.Trigger = EventTrigger::ON_BEGIN; break;
2916                     case 2: aEvent.Trigger = EventTrigger::ON_END; break;
2917                     case 3: aEvent.Trigger = EventTrigger::BEGIN_EVENT; break;
2918                     case 4: aEvent.Trigger = EventTrigger::END_EVENT; break;
2919                     case 5: aEvent.Trigger = EventTrigger::ON_CLICK; break;
2920                     case 6: aEvent.Trigger = EventTrigger::ON_DBL_CLICK; break;
2921                     case 7: aEvent.Trigger = EventTrigger::ON_MOUSE_ENTER; break;
2922                     case 8: aEvent.Trigger = EventTrigger::ON_MOUSE_LEAVE; break;
2923                     case 9: aEvent.Trigger = EventTrigger::ON_NEXT; break;
2924                     case 10: aEvent.Trigger = EventTrigger::ON_PREV; break;
2925                     case 11: aEvent.Trigger = EventTrigger::ON_STOP_AUDIO; break;
2926                     }
2927 
2928                     if( (nBegin != 0) || (aEvent.Trigger == EventTrigger::NONE) )
2929                         aEvent.Offset = (nBegin == -1) ? makeAny( Timing_INDEFINITE ) : makeAny( (double)(nBegin / 1000.0) );
2930                 }
2931                 break;
2932                 case DFF_msofbtAnimateTargetElement:
2933                 {
2934                     sal_Int16 nSubType;
2935                     importTargetElementContainer( pChildAtom, aEvent.Source, nSubType );
2936                 }
2937                 break;
2938                 default:
2939                 {
2940                     DBG_ERROR("unknown atom inside ppt::AnimationImporter::importAnimationEvents()!");
2941                 }
2942                 }
2943 
2944                 pChildAtom = pEventAtom->findNextChildAtom( pChildAtom );
2945             }
2946 
2947             *pEvents = addToSequence( *pEvents, (aEvent.Trigger == EventTrigger::NONE) ? aEvent.Offset : makeAny( aEvent ) );
2948         }
2949 
2950         pEventAtom = pAtom->findNextChildAtom( DFF_msofbtAnimEvent, pEventAtom );
2951     }
2952 
2953     xNode->setBegin( aBegin );
2954     xNode->setEnd( aEnd );
2955     // TODO: xNode->setNext( aNext );
2956     // TODO: xNode->setPrev( aNext );
2957 
2958 #ifdef DBG_ANIM_LOG
2959     if( aBegin.hasValue() )
2960     {
2961         dump( " begin=\"" );
2962         dump( aBegin );
2963         dump( "\"" );
2964     }
2965 
2966     if( aEnd.hasValue() )
2967     {
2968         dump( " end=\"" );
2969         dump( aEnd );
2970         dump( "\"" );
2971     }
2972 
2973     if( aNext.hasValue() )
2974     {
2975         dump( " next=\"" );
2976         dump( aNext );
2977         dump( "\"" );
2978     }
2979 
2980     if( aPrev.hasValue() )
2981     {
2982         dump( " prev=\"" );
2983         dump( aPrev );
2984         dump( "\"" );
2985     }
2986 #endif
2987 }
2988 
2989 // --------------------------------------------------------------------
2990 
importAnimationActions(const Atom * pAtom,const Reference<XAnimationNode> & xNode)2991 void AnimationImporter::importAnimationActions( const Atom* pAtom, const Reference< XAnimationNode >& xNode )
2992 {
2993     DBG_ASSERT( pAtom && xNode.is(), "invalid call to ppt::AnimationImporter::importAnimationActions()!");
2994 
2995     if( pAtom )
2996     {
2997         const Atom* pActionAtom = pAtom->findFirstChildAtom( DFF_msofbtAnimAction );
2998 
2999         if( pActionAtom && pActionAtom->seekToContent() )
3000         {
3001             sal_Int32 nConcurrent, nNextAction, nEndSync, nU4, nU5;
3002             mrStCtrl >> nConcurrent;
3003             mrStCtrl >> nNextAction;
3004             mrStCtrl >> nEndSync;
3005             mrStCtrl >> nU4;
3006             mrStCtrl >> nU5;
3007 
3008             if( nEndSync == 1 )
3009                 xNode->setEndSync( makeAny( AnimationEndSync::ALL ) );
3010 
3011     #ifdef DBG_ANIM_LOG
3012             dump( " concurrent=\"%s\"", nConcurrent == 0 ? "disabled" : (nConcurrent == 1 ? "enabled" : "unknown") );
3013 
3014             dump( " nextAction=\"%s\"", nNextAction == 0 ? "none" : (nNextAction == 1 ? "seek" : "unknown") );
3015 
3016             if( nEndSync != 0 )
3017             {
3018                 dump( " endSync=\"%s\"", nEndSync == 1 ? "all" : "unknown" );
3019             }
3020 
3021             dump( " action_4=\"%#lx\"", nU4 );
3022             dump( " action_5=\"%#lx\"", nU5 );
3023     #endif
3024         }
3025     }
3026 }
3027 
3028 // --------------------------------------------------------------------
3029 
importTargetElementContainer(const Atom * pAtom,Any & rTarget,sal_Int16 & rSubType)3030 sal_Int32 AnimationImporter::importTargetElementContainer( const Atom* pAtom, Any& rTarget, sal_Int16& rSubType )
3031 {
3032     rSubType = ShapeAnimationSubType::AS_WHOLE;
3033     sal_Int32 nRefMode = -1;
3034 
3035     DBG_ASSERT( pAtom && (pAtom->getType() == DFF_msofbtAnimateTargetElement), "invalid call to ppt::AnimationImporter::importTargetElementContainer()!" );
3036     if( pAtom )
3037     {
3038         const Atom* pChildAtom = pAtom->findFirstChildAtom();
3039         while( pChildAtom && pChildAtom->seekToContent() )
3040         {
3041             switch( pChildAtom->getType() )
3042             {
3043             case DFF_msofbtAnimReference:
3044             {
3045                 sal_Int32 nRefType,nRefId;
3046                 sal_Int32 begin,end;
3047                 mrStCtrl >> nRefMode;
3048                 mrStCtrl >> nRefType;
3049                 mrStCtrl >> nRefId;
3050                 mrStCtrl >> begin;
3051                 mrStCtrl >> end;
3052 
3053                 switch( nRefType )
3054                 {
3055                 case 1: // shape
3056                 {
3057                     SdrObject* pSdrObject = mpPPTImport->getShapeForId( nRefId );
3058                     if( pSdrObject == NULL )
3059                         break;
3060 
3061                     rTarget <<= pSdrObject->getUnoShape();
3062 
3063                     switch( nRefMode )
3064                     {
3065 // default          case 0: rSubType = ShapeAnimationSubType::AS_WHOLE; break;
3066                     case 6: rSubType = ShapeAnimationSubType::ONLY_BACKGROUND; break;
3067                     case 8: rSubType = ShapeAnimationSubType::ONLY_TEXT; break;
3068                     case 2: // one paragraph
3069                     {
3070                         if( ((begin == -1) && (end == -1)) || !pSdrObject->ISA( SdrTextObj )  )
3071                             break;
3072 
3073                         SdrTextObj* pTextObj = static_cast< SdrTextObj* >( pSdrObject );
3074 
3075                         const OutlinerParaObject* pOPO = pTextObj->GetOutlinerParaObject();
3076                         if( pOPO == NULL )
3077                             break;
3078 
3079                         const EditTextObject& rEditTextObject = pOPO->GetTextObject();
3080 
3081                         const sal_uInt16 nParaCount = rEditTextObject.GetParagraphCount();
3082 
3083                         sal_uInt16 nPara = 0;
3084 
3085                         while( (nPara < nParaCount) && (begin > 0) )
3086                         {
3087                             sal_Int32 nParaLength = rEditTextObject.GetText( nPara ).Len() + 1;
3088                             begin -= nParaLength;
3089                             end -= nParaLength;
3090                             nPara++;
3091                         }
3092 
3093                         if( nPara < nParaCount )
3094                         {
3095                             ParagraphTarget aParaTarget;
3096                             rTarget >>= aParaTarget.Shape;
3097                             aParaTarget.Paragraph = nPara;
3098                             rTarget = makeAny( aParaTarget );
3099 
3100                             rSubType = ShapeAnimationSubType::ONLY_TEXT;
3101                             dump( " paragraph %d,", (sal_Int32)nPara);
3102                             dump( " %d characters", (sal_Int32)end );
3103                         }
3104                     }
3105                     }
3106                 }
3107                 break;
3108 
3109                 case 2: // sound
3110                     {
3111                         OUString aSoundURL( ((ImplSdPPTImport*)mpPPTImport)->ReadSound( nRefId ) );
3112                         rTarget <<= aSoundURL;
3113                         dump( " srcRef=\"%s\"", aSoundURL );
3114                     }
3115                     break;
3116                 case 3: // audio object
3117                 case 4: // video object
3118                     {
3119                         SdrObject* pSdrObject = mpPPTImport->getShapeForId( nRefId );
3120                         if( pSdrObject == NULL )
3121                             break;
3122 
3123                         rTarget <<= pSdrObject->getUnoShape();
3124                     }
3125                     break;
3126                 default:
3127                     DBG_ERROR("unknown reference type");
3128                 }
3129 
3130 
3131 //              dump( " ref=\"%s\"", nRefMode == 3 ? "source" : ( nRefMode == 0 ? "target" : "unknown" ) );
3132 //              dump( " type=\"%s\"", nRefType == 1 ? "shape" : ( nRefType == 2 ? "sound": "unknown" ) );
3133 //              dump( " id=\"%lu\"", (sal_Int32)nRefId );
3134 #ifdef DBG_ANIM_LOG
3135                 if((begin != -1) || (end != -1) )
3136                 {
3137 //                  dump( " text_begin=\"%ld\"", begin );
3138 //                  dump( " text_end=\"%ld\"", end );
3139                 }
3140 #endif
3141             }
3142             break;
3143             case 0x2b01:
3144             {
3145                 sal_Int32 nU1;
3146                 mrStCtrl >> nU1;
3147 
3148                 // HINT: nU1 == 1 : target document. ?
3149 //              dump( " unknown_0x2b01=\"%#lx\"", nU1 );
3150             }
3151             break;
3152             default:
3153                 DBG_ERROR("unknwon atom inside ppt::AnimationImporter::importTargetElementContainer()!");
3154                 break;
3155             }
3156 
3157         pChildAtom = pAtom->findNextChildAtom( pChildAtom );
3158 
3159         }
3160     }
3161 
3162     return nRefMode;
3163 }
3164 
3165 // --------------------------------------------------------------------
3166 
importPropertySetContainer(const Atom * pAtom,PropertySet & rSet)3167 void AnimationImporter::importPropertySetContainer( const Atom* pAtom, PropertySet& rSet )
3168 {
3169     DBG_ASSERT( pAtom && (pAtom->getType() == DFF_msofbtAnimPropertySet), "invalid call to ppt::AnimationImporter::importPropertySetContainer()!" );
3170 
3171     if( pAtom )
3172     {
3173         const Atom* pChildAtom = pAtom->findFirstChildAtom();
3174         while( pChildAtom )
3175         {
3176             if( pChildAtom->getType() == DFF_msofbtAnimAttributeValue )
3177             {
3178                 Any aAny;
3179                 importAttributeValue( pChildAtom, aAny );
3180                 rSet.maProperties[ pChildAtom->getInstance() ] = aAny;
3181             }
3182             else
3183             {
3184                 DBG_ERROR("unknwon atom inside ppt::AnimationImporter::importPropertySetContainer()!");
3185             }
3186 
3187             pChildAtom = pAtom->findNextChildAtom( pChildAtom );
3188         }
3189     }
3190 }
3191 
3192 // ====================================================================
3193 
3194 #ifdef DBG_ANIM_LOG
dump_atom_header(const Atom * pAtom,bool bOpen,bool bAppend)3195 void AnimationImporter::dump_atom_header( const Atom* pAtom, bool bOpen, bool bAppend )
3196 {
3197     if( pAtom )
3198     {
3199         const char* pTitle;
3200 
3201         bool bUnknown = false;
3202 
3203         switch( pAtom->getType() )
3204         {
3205         case DFF_msofbtAnimEvent: pTitle = "AnimEvent"; break;
3206         case DFF_msofbtAnimTrigger: pTitle = "AnimTrigger"; break;
3207         case DFF_msofbtAnimateMotion:   pTitle = "AnimateMotion"; break;
3208         case DFF_msofbtAnimPropertySet: pTitle = "AnimPropertySet"; break;
3209         case DFF_msofbtAnimateAttributeNames: pTitle = "AnimAttributeName"; break;
3210         case DFF_msofbtAnimAttributeValue: pTitle = "AnimAttributeValue"; break;
3211         case DFF_msofbtAnimGroup: pTitle = "AnimGroup"; break;
3212         case DFF_msofbtAnimNode: pTitle = "AnimNode"; break;
3213         case DFF_msofbtAnimValue: pTitle = "AnimValue"; break;
3214         case DFF_msofbtAnimateFilter: pTitle = "animateFilter"; break;
3215         case DFF_msofbtAnimate: pTitle = "animate"; break;
3216         case DFF_msofbtAnimateSet: pTitle = "set"; break;
3217         case DFF_msofbtAnimKeyTime: pTitle = "AnimKeyTime"; break;
3218         case DFF_msofbtAnimKeyPoints: pTitle = "AnimKeyPoints"; break;
3219         case DFF_msofbtAnimReference: pTitle = "AnimReference"; break;
3220         case DFF_msofbtAnimateTargetElement: pTitle = "AnimTargetElementContainer"; break;
3221         case DFF_msofbtAnimAction: pTitle = "AnimAction"; break;
3222         case DFF_msofbtAnimCommand: pTitle = "AnimCommand"; break;
3223         case DFF_msofbtAnimateTarget: pTitle = "TransformationTarget"; break;
3224         case DFF_msofbtAnimateTargetSettings: pTitle = "TransformationTargetSettings"; break;
3225         case DFF_msofbtAnimIteration: pTitle = "iterate"; break;
3226         case DFF_msofbtAnimateColorData: pTitle = "colorData"; break;
3227         case DFF_msofbtAnimateScaleData: pTitle = "scaleData"; break;
3228         case DFF_msofbtAnimateSetData: pTitle = "setData"; break;
3229 
3230         default:
3231             {
3232                 static char buffer[128];
3233                 sprintf( buffer, "unknown_%#x", pAtom->getType() );
3234                 pTitle = buffer;
3235             }
3236         }
3237 
3238         if( bOpen )
3239         {
3240             fprintf(mpFile, "<%s", pTitle );
3241 
3242             fprintf(mpFile, " instance=\"%hu\"%s",
3243                         pAtom->getInstance(),
3244                         bAppend ? "" : ">\n");
3245         }
3246         else
3247         {
3248             if( bAppend )
3249                 fprintf(mpFile,"/>\n");
3250             else
3251                 fprintf(mpFile, "</%s>\n", pTitle );
3252         }
3253     }
3254 }
3255 
3256 // --------------------------------------------------------------------
3257 
dump(sal_uInt32 nLen,bool bNewLine)3258 void AnimationImporter::dump( sal_uInt32 nLen, bool bNewLine )
3259 {
3260     char * faul = "0123456789abcdef";
3261 
3262     sal_uInt32 i = 0;
3263     int b = 0;
3264     sal_Int8 nData;
3265 
3266     for( i = 0; i < nLen; i++ )
3267     {
3268         mrStCtrl >> nData;
3269 
3270         fprintf( mpFile, "%c%c ", faul[ (nData >> 4) & 0x0f ], faul[ nData & 0x0f ] );
3271 
3272         b++;
3273         if( bNewLine && (b == 32) )
3274         {
3275             fprintf(mpFile,"\n");
3276             b = 0;
3277         }
3278     }
3279     if( (b != 0) && bNewLine )
3280         fprintf(mpFile,"\n");
3281 }
3282 
3283 // --------------------------------------------------------------------
3284 
dump_atom(const Atom * pAtom,bool bNewLine)3285 void AnimationImporter::dump_atom( const Atom* pAtom, bool bNewLine )
3286 {
3287     if( pAtom )
3288     {
3289         if( pAtom->isContainer() )
3290         {
3291             const Atom* pChildAtom = pAtom->findFirstChildAtom();
3292             while( pChildAtom )
3293             {
3294                 if( pChildAtom->getType() == DFF_msofbtAnimAttributeValue )
3295                 {
3296                     fprintf(mpFile, "<attributeValue instance=\"%hu\"", pChildAtom->getInstance() );
3297 
3298                     Any aValue;
3299                     if( importAttributeValue( pChildAtom, aValue ) )
3300                     {
3301                         sal_Int32 nInt;
3302                         rtl::OUString aString;
3303                         double fDouble;
3304 
3305                         if( aValue >>= nInt )
3306                         {
3307                             fprintf(mpFile, " value=\"%ld\"", nInt );
3308                         }
3309                         else if( aValue >>= aString )
3310                         {
3311                             UniString aTmp( aString );
3312                             ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 );
3313                             fprintf(mpFile, " value=\"%s\"", aStr.GetBuffer() );
3314                         }
3315                         else if( aValue >>= fDouble )
3316                         {
3317                             fprintf(mpFile, " value=\"%g\"", fDouble );
3318                         }
3319                     }
3320                     else
3321                     {
3322                         if( pChildAtom->seekToContent() )
3323                         {
3324                             fprintf(mpFile, " value=\""  );
3325                             dump_atom( pChildAtom, false );
3326                             fprintf(mpFile, "\"");
3327                         }
3328                     }
3329 
3330                     fprintf(mpFile, "/>\n" );
3331                 }
3332                 else
3333                 {
3334                     dump_atom_header( pChildAtom, true, pChildAtom->getType() == DFF_msofbtAnimAttributeValue );
3335                     dump_atom( pChildAtom );
3336                     dump_atom_header( pChildAtom, false, pChildAtom->getType() == DFF_msofbtAnimAttributeValue );
3337                 }
3338 
3339                 pChildAtom = pAtom->findNextChildAtom(pChildAtom);
3340             }
3341         }
3342         else if( pAtom->seekToContent() )
3343         {
3344             dump( pAtom->getLength(), bNewLine );
3345         }
3346     }
3347 }
3348 
3349 // --------------------------------------------------------------------
3350 
dump_anim_group(const Atom * pAtom,const AnimationNode & rNode,const PropertySet & rSet,bool bOpen)3351 void AnimationImporter::dump_anim_group( const Atom* pAtom, const AnimationNode& rNode, const PropertySet& rSet, bool bOpen )
3352 {
3353     fprintf( mpFile, bOpen ? "<" : "</" );
3354 
3355     switch( rNode.mnGroupType )
3356     {
3357     case mso_Anim_GroupType_PAR:
3358         fprintf( mpFile, "par" );
3359         break;
3360     case mso_Anim_GroupType_SEQ:
3361         fprintf( mpFile, "seq" );
3362         break;
3363     case mso_Anim_GroupType_NODE:
3364         switch( rNode.mnNodeType )
3365         {
3366         case mso_Anim_Behaviour_FILTER:
3367             fprintf( mpFile, "animateFilter" );
3368             break;
3369         case mso_Anim_Behaviour_ANIMATION:
3370             if( pAtom->hasChildAtom( DFF_msofbtAnimateSet ) )
3371                 fprintf( mpFile, "set" );
3372             else if( pAtom->hasChildAtom( DFF_msofbtAnimateColor ) )
3373                 fprintf( mpFile, "animateColor" );
3374             else if( pAtom->hasChildAtom( DFF_msofbtAnimateScale ) )
3375                 fprintf( mpFile, "animateScale" );
3376             else if( pAtom->hasChildAtom( DFF_msofbtAnimateRotation ) )
3377                 fprintf( mpFile, "animateRotation" );
3378             else if( pAtom->hasChildAtom( DFF_msofbtAnimateMotion ) )
3379                 fprintf( mpFile, "animateMotion" );
3380             else if( pAtom->hasChildAtom( DFF_msofbtAnimCommand ) )
3381                 fprintf( mpFile, "command" );
3382             else
3383                 fprintf( mpFile, "animation" );
3384             break;
3385         default:
3386             {
3387                 fprintf( mpFile, "unknown_node_%#lx", rNode.mnNodeType );
3388             }
3389             break;
3390         }
3391         break;
3392     case mso_Anim_GroupType_MEDIA:
3393         fprintf( mpFile, "media" );
3394         break;
3395     default:
3396         fprintf( mpFile, "unknown_group_%#lx", rNode.mnGroupType );
3397         break;
3398     }
3399 
3400     if( bOpen )
3401     {
3402         dump( rNode );
3403         dump( rSet );
3404     }
3405 
3406     fprintf(mpFile,">\n");
3407 }
3408 
dump(const AnimationNode & rNode)3409 void AnimationImporter::dump( const AnimationNode& rNode )
3410 {
3411     // dump animation node
3412     if( rNode.mnRestart != 0 )
3413     {
3414         fprintf(mpFile," restart=\"%s\"",
3415             rNode.mnRestart == 1 ? "always" : (rNode.mnRestart == 2 ? "whenOff" : (rNode.mnRestart == 3 ? "never" : "unknown")) );
3416     }
3417 
3418     if( rNode.mnFill )
3419     {
3420         fprintf(mpFile," fill=\"%s\"",
3421             rNode.mnFill == 1 ? "remove" : (rNode.mnFill == 3 ? "hold" : (rNode.mnFill == 2 ? "freeze" : "unknown")) );
3422     }
3423 
3424     if( rNode.mnDuration > 0 )
3425     {
3426         double fSeconds = rNode.mnDuration;
3427         fSeconds /= 1000.0;
3428         fprintf(mpFile, " dur=\"%g\"", fSeconds);
3429     }
3430     else if( rNode.mnDuration < 0 )
3431     {
3432         fprintf(mpFile, " dur=\"indefinite\"" );
3433     }
3434 
3435     if( rNode.mnU1 ) fprintf(mpFile," u1=\"%#lx\"", rNode.mnU1);
3436     if( rNode.mnU3 ) fprintf(mpFile," u3=\"%#lx\"", rNode.mnU3);
3437     if( rNode.mnU4 ) fprintf(mpFile," u4=\"%#lx\"", rNode.mnU4);
3438 }
3439 
dump(Any & rAny)3440 void AnimationImporter::dump( Any& rAny )
3441 {
3442     Sequence< Any > aSeq;
3443     sal_Int32 nInt;
3444     double fDouble;
3445     OUString aString;
3446     sal_Bool bBool;
3447     Event aEvent;
3448     Timing aTiming;
3449 
3450     if( rAny >>= aSeq )
3451     {
3452         const sal_Int32 nSize = aSeq.getLength();
3453         sal_Int32 nIndex = 0;
3454         while( nIndex < nSize )
3455         {
3456             dump( aSeq[nIndex++] );
3457             if(nIndex < nSize)
3458                 fprintf( mpFile, "," );
3459         }
3460     }
3461     else if( rAny >>= aString )
3462     {
3463         UniString aTmp(aString);
3464         ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 );
3465         fprintf( mpFile, "%s", aStr.GetBuffer() );
3466     }
3467     else if( rAny >>= nInt )
3468     {
3469         fprintf( mpFile, "%ld", nInt );
3470     }
3471     else if( rAny >>= bBool )
3472     {
3473         fprintf( mpFile, "%s", bBool ? "true" : "false" );
3474     }
3475     else if( rAny >>= fDouble )
3476     {
3477         fprintf( mpFile, "%g", fDouble );
3478     }
3479     else if( rAny >>= aTiming )
3480     {
3481         fprintf( mpFile, "%s", aTiming == (Timing_INDEFINITE) ? "indefinite" : "media" );
3482     }
3483     else if( rAny >>= aEvent )
3484     {
3485         static const char* triggers[] =
3486         {
3487             "none","onbegin","onend","begin",
3488             "end","onclick","ondoubleclick","onmouseenter",
3489             "onmouseleave","onpptnext","onpptprev","onstopaudio"
3490         };
3491 
3492         if( aEvent.Trigger != EventTrigger::NONE )
3493         {
3494             if( aEvent.Source.hasValue() )
3495             {
3496                 dump_target( aEvent.Source );
3497                 dump( "." );
3498             }
3499 
3500             dump( triggers[ aEvent.Trigger ] );
3501         }
3502 
3503         if( aEvent.Offset.hasValue() )
3504         {
3505             double fOffset;
3506             if( aEvent.Offset >>= fOffset )
3507                 fprintf( mpFile, "%g", fOffset );
3508             else
3509                 dump( "indefinite" );
3510         }
3511     }
3512 }
3513 
dump(const PropertySet & rSet)3514 void AnimationImporter::dump( const PropertySet& rSet )
3515 {
3516     // dump property set
3517 
3518     map< sal_Int32, Any >::const_iterator aIter( rSet.maProperties.begin() );
3519     const map< sal_Int32, Any >::const_iterator aEnd( rSet.maProperties.end() );
3520     while( aIter != aEnd )
3521     {
3522         bool bKnown = false;
3523 
3524         const sal_Int32 nInstance = (*aIter).first;
3525         Any aAny( (*aIter).second );
3526 
3527         switch ( nInstance )
3528         {
3529         case DFF_ANIM_COLORSPACE:
3530         {
3531             sal_Int32 nColorSpace;
3532             if( aAny >>= nColorSpace )
3533             {
3534                 fprintf( mpFile, " colorSpace=\"%s\"", (nColorSpace == 0) ? "rgb" : (nColorSpace == 1) ? "hsl" : "unknown" );
3535                 bKnown = true;
3536             }
3537         }
3538         break;
3539 
3540         case DFF_ANIM_DIRECTION:
3541 //      case DFF_ANIM_MASTERREL:
3542         {
3543             sal_Bool bDirection;
3544             if( aAny >>= bDirection )
3545             {
3546                 fprintf( mpFile, " direction=\"%s\"", bDirection ? "cclockwise" : "clockwise"  );
3547                 bKnown = true;
3548             }
3549             else
3550             {
3551                 sal_Int32 nMasterRel;
3552                 if( aAny >>= nMasterRel )
3553                 {
3554                     fprintf( mpFile, " direction=\"%s\"", nMasterRel == 0 ? "sameClick" : ( nMasterRel == 2 ? "nextClick" : "lastClick" )  );
3555                     bKnown = true;
3556                 }
3557             }
3558         }
3559         break;
3560 
3561         case DFF_ANIM_OVERRIDE:     // TODO
3562         {
3563             sal_Int32 nOverride;
3564             if( aAny >>= nOverride )
3565             {
3566                 fprintf( mpFile, " override=\"%s\"", (nOverride == 1) ? "childStyle" : (nOverride == 0) ? "normal" : "unknown" );
3567                 bKnown = true;
3568             }
3569         }
3570         break;
3571 
3572         case DFF_ANIM_PATH_EDIT_MODE:
3573         {
3574             sal_Bool bPathEditMode;
3575             if( aAny >>= bPathEditMode )
3576             {
3577                 fprintf( mpFile, " pptPathEditMode=\"%s\"", bPathEditMode ? "relative" : "fixed" );
3578                 bKnown = true;
3579             }
3580         }
3581         break;
3582 
3583         case DFF_ANIM_PRESET_ID :
3584         {
3585             sal_Int32 nPresetId ;
3586             if( aAny >>= nPresetId )
3587             {
3588                 fprintf(mpFile, " presetid=\"%ld\"", nPresetId );
3589                 bKnown = true;
3590             }
3591         }
3592         break;
3593 
3594         case DFF_ANIM_PRESET_SUB_TYPE :
3595         {
3596             sal_Int32 nPointsType ;
3597             if( aAny >>= nPointsType )
3598             {
3599                 fprintf(mpFile, " presetSubType=\"%ld\"", nPointsType );
3600                 bKnown = true;
3601             }
3602         }
3603         break;
3604 
3605         case DFF_ANIM_PRESET_CLASS :
3606         {
3607             sal_Int32 nPresetClass;
3608             if ( aAny >>= nPresetClass )
3609             {
3610                 const char* pMode;
3611                 switch( nPresetClass )
3612                 {
3613                 case DFF_ANIM_PRESS_CLASS_USER_DEFINED:     pMode = "userdefined"; break;
3614                 case DFF_ANIM_PRESS_CLASS_ENTRANCE:         pMode = "entrance"; break;
3615                 case DFF_ANIM_PRESS_CLASS_EXIT:             pMode = "exit"; break;
3616                 case DFF_ANIM_PRESS_CLASS_EMPHASIS:         pMode = "emphasis"; break;
3617                 case DFF_ANIM_PRESS_CLASS_MOTIONPATH:       pMode = "motionpath"; break;
3618                 case DFF_ANIM_PRESS_CLASS_OLE_ACTION:       pMode = "oleaction"; break;
3619                 case DFF_ANIM_PRESS_CLASS_MEDIACALL:        pMode = "mediacall"; break;
3620                 default:
3621                 {
3622                     static char buffer[128];
3623                     sprintf( buffer, "%ld", nPresetClass );
3624                     pMode = buffer;
3625                 }
3626                 break;
3627                 }
3628 
3629                 fprintf(mpFile, " class=\"%s\"", pMode);
3630                 bKnown = true;
3631             }
3632         }
3633         break;
3634 
3635         case DFF_ANIM_NODE_TYPE :
3636         {
3637             sal_Int32 nNodeType;
3638             if ( aAny >>= nNodeType )
3639             {
3640                 const char* pNode;
3641                 switch( nNodeType )
3642                 {
3643                     case DFF_ANIM_NODE_TYPE_ON_CLICK:       pNode = "onclick";  break;
3644                     case DFF_ANIM_NODE_TYPE_WITH_PREVIOUS:  pNode = "withprevious"; break;
3645                     case DFF_ANIM_NODE_TYPE_AFTER_PREVIOUS: pNode = "afterprevious"; break;
3646                     case DFF_ANIM_NODE_TYPE_MAIN_SEQUENCE:  pNode = "mainsequence"; break;
3647                     case DFF_ANIM_NODE_TYPE_TIMING_ROOT:    pNode = "timingroot"; break;
3648                     case DFF_ANIM_NODE_TYPE_INTERACTIVE_SEQ:pNode = "interactivesequence"; break;
3649                     default :
3650                     {
3651                         static char buffer[128];
3652                         sprintf( buffer, "%ld", nNodeType );
3653                         pNode = buffer;
3654                     }
3655                     break;
3656                 }
3657 
3658                 fprintf(mpFile, " nodeType=\"%s\"", pNode);
3659                 bKnown = true;
3660             }
3661         }
3662         break;
3663 
3664         case DFF_ANIM_GROUP_ID:
3665         {
3666             sal_Int32 nGroupId;
3667             if ( aAny >>= nGroupId )
3668             {
3669                 fprintf( mpFile, " groupId=\"%ld\"", nGroupId );
3670                 bKnown = true;
3671             }
3672         }
3673         break;
3674 
3675         case DFF_ANIM_ID:
3676         {
3677             rtl::OUString aString;
3678             if( aAny >>= aString )
3679             {
3680                 UniString aTmp(aString);
3681                 ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 );
3682                 fprintf( mpFile, " id=\"%s\"", aStr.GetBuffer() );
3683                 bKnown = true;
3684             }
3685         }
3686         break;
3687 
3688         case DFF_ANIM_EVENT_FILTER:
3689         {
3690             rtl::OUString aString;
3691             if( aAny >>= aString )
3692             {
3693                 UniString aTmp(aString);
3694                 ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 );
3695                 fprintf( mpFile, " eventFilter=\"%s\"", aStr.GetBuffer() );
3696                 bKnown = true;
3697             }
3698         }
3699         break;
3700 
3701         case DFF_ANIM_ENDAFTERSLIDE:
3702         {
3703             sal_Int32 nEndAfterSlide;
3704             if( aAny >>= nEndAfterSlide )
3705             {
3706                 fprintf(mpFile, " endAfterSlide=\"%ld\"", nEndAfterSlide );
3707             bKnown = true;
3708             }
3709         }
3710 
3711         case DFF_ANIM_TIMEFILTER:
3712         {
3713             rtl::OUString aString;
3714             if( aAny >>= aString )
3715             {
3716                 UniString aTmp(aString);
3717                 ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 );
3718                 fprintf( mpFile, " timeFilter=\"%s\"", aStr.GetBuffer() );
3719                 bKnown = true;
3720             }
3721         }
3722         break;
3723 
3724         case DFF_ANIM_RUNTIMECONTEXT:
3725         {
3726             rtl::OUString aString;
3727             if( aAny >>= aString )
3728             {
3729                 UniString aTmp(aString);
3730                 ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 );
3731                 fprintf( mpFile, " runtimeContext=\"%s\"", aStr.GetBuffer() );
3732                 bKnown = true;
3733             }
3734         }
3735         break;
3736 
3737         case DFF_ANIM_VOLUME:
3738         {
3739             double fVolume;
3740             if( aAny >>= fVolume )
3741             {
3742                 fprintf( mpFile, " volume=\"%g%%\"", (double)(fVolume * 100.0) );
3743                 bKnown = true;
3744             }
3745         }
3746         break;
3747 
3748         case DFF_ANIM_AFTEREFFECT:
3749         {
3750             sal_Bool bAfterEffect;
3751             if( aAny >>= bAfterEffect )
3752             {
3753                 fprintf( mpFile, "afterEffect=\"%s\"", bAfterEffect ? "true" : "false" );
3754                 bKnown = true;
3755             }
3756         }
3757         break;
3758 
3759         }
3760 
3761 
3762         if( !bKnown )
3763         {
3764             fprintf( mpFile, " unknown_%lu=\"", nInstance );
3765             dump( aAny );
3766             fprintf( mpFile, "\"" );
3767         }
3768 
3769         aIter++;
3770     }
3771 }
3772 
dump_target(Any & rAny)3773 void AnimationImporter::dump_target( Any& rAny )
3774 {
3775     Any aSource, aSourceData;
3776     Sequence< Any > aSeq;
3777     if( rAny >>= aSeq )
3778     {
3779         if( aSeq.getLength() >= 1 ) aSource = aSeq[0];
3780         if( aSeq.getLength() >= 2 ) aSourceData = aSeq[1];
3781     }
3782     else
3783     {
3784         aSource = rAny;
3785     }
3786 
3787     Reference< XShape > xShape;
3788     aSource >>= xShape;
3789     if( xShape.is() )
3790     {
3791         OUString aStr( xShape->getShapeType() );
3792         dump( aStr );
3793 
3794         if( aSourceData.hasValue() )
3795         {
3796             dump( "(" );
3797             dump( aSourceData );
3798             dump( ")" );
3799         }
3800     }
3801 }
3802 
dump(const char * pText)3803 void AnimationImporter::dump( const char * pText )
3804 {
3805     fprintf( mpFile, "%s", pText );
3806 }
3807 
dump(const rtl::OUString & rString)3808 void AnimationImporter::dump( const rtl::OUString& rString )
3809 {
3810     UniString aTmp( rString );
3811     ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 );
3812     fprintf( mpFile, aStr.GetBuffer() );
3813 }
3814 
dump(const char * pText,sal_Int32 nInt)3815 void AnimationImporter::dump( const char * pText, sal_Int32 nInt )
3816 {
3817     fprintf( mpFile, pText, nInt );
3818 }
3819 
dump(const char * pText,double fDouble)3820 void AnimationImporter::dump( const char * pText, double fDouble )
3821 {
3822     fprintf( mpFile, pText, fDouble );
3823 }
3824 
dump(const char * pText,const char * pText2)3825 void AnimationImporter::dump( const char * pText, const char * pText2 )
3826 {
3827     fprintf( mpFile, pText, pText2 );
3828 }
3829 
dump(const char * pText,const OUString & rString)3830 void AnimationImporter::dump( const char * pText, const OUString& rString )
3831 {
3832     UniString aTmp( rString );
3833     ByteString aStr( aTmp, RTL_TEXTENCODING_UTF8 );
3834     fprintf( mpFile, pText, aStr.GetBuffer() );
3835 }
3836 
3837 #else
3838 
dump_atom_header(const Atom *,bool,bool)3839 void AnimationImporter::dump_atom_header( const Atom* , bool , bool  )
3840 {
3841 }
3842 
dump_atom(const Atom *,bool)3843 void AnimationImporter::dump_atom( const Atom* , bool  )
3844 {
3845 }
3846 
dump_target(::com::sun::star::uno::Any &)3847 void AnimationImporter::dump_target( ::com::sun::star::uno::Any&  )
3848 {
3849 }
3850 
dump(::com::sun::star::uno::Any &)3851 void AnimationImporter::dump( ::com::sun::star::uno::Any&  )
3852 {
3853 }
3854 
dump(const PropertySet &)3855 void AnimationImporter::dump( const PropertySet&  )
3856 {
3857 }
3858 
dump(const AnimationNode &)3859 void AnimationImporter::dump( const AnimationNode&  )
3860 {
3861 }
3862 
dump(const char *)3863 void AnimationImporter::dump( const char *  )
3864 {
3865 }
3866 
dump(const char *,sal_Int32)3867 void AnimationImporter::dump( const char * , sal_Int32  )
3868 {
3869 }
3870 
dump(const char *,double)3871 void AnimationImporter::dump( const char * , double  )
3872 {
3873 }
3874 
dump(const char *,const char *)3875 void AnimationImporter::dump( const char * , const char *  )
3876 {
3877 }
3878 
dump(const char *,const rtl::OUString &)3879 void AnimationImporter::dump( const char * , const rtl::OUString&  )
3880 {
3881 }
3882 
3883 #endif
3884 
3885 } // namespace ppt;
3886 
3887