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