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_uInt32 nParaCount = rEditTextObject.GetParagraphCount();
3082 
3083 						sal_uInt32 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("unknown 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("unknown 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