merge the formfield patch from ooo-build
[ooovba.git] / oox / source / ppt / timenode.cxx
blob3667bb63d6ef5c9cedd5a702c20b501ab74b64f9
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: timenode.cxx,v $
10 * $Revision: 1.4.6.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "oox/ppt/timenode.hxx"
33 #include <boost/bind.hpp>
35 #include <com/sun/star/beans/XPropertySet.hpp>
36 #include <com/sun/star/beans/NamedValue.hpp>
37 #include <com/sun/star/container/XEnumerationAccess.hpp>
38 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
39 #include <com/sun/star/frame/XModel.hpp>
40 #include <com/sun/star/animations/XAnimateColor.hpp>
41 #include <com/sun/star/animations/XAnimateMotion.hpp>
42 #include <com/sun/star/animations/XAnimateTransform.hpp>
43 #include <com/sun/star/animations/XCommand.hpp>
44 #include <com/sun/star/animations/XIterateContainer.hpp>
45 #include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
46 #include <com/sun/star/animations/XTimeContainer.hpp>
47 #include <com/sun/star/animations/AnimationNodeType.hpp>
48 #include <com/sun/star/animations/Event.hpp>
49 #include <com/sun/star/animations/EventTrigger.hpp>
50 #include <com/sun/star/presentation/EffectNodeType.hpp>
52 #include "oox/helper/helper.hxx"
53 #include "oox/core/xmlfilterbase.hxx"
55 using ::rtl::OUString;
56 using namespace ::oox::core;
57 using namespace ::com::sun::star::beans;
58 using namespace ::com::sun::star::container;
59 using namespace ::com::sun::star::uno;
60 using namespace ::com::sun::star::lang;
61 using namespace ::com::sun::star::animations;
62 using namespace ::com::sun::star::frame;
63 using namespace ::com::sun::star::presentation;
65 namespace oox { namespace ppt {
67 OUString TimeNode::getServiceName( sal_Int16 nNodeType )
69 OUString sServiceName;
70 switch( nNodeType )
72 case AnimationNodeType::PAR:
73 // sServiceName = CREATE_OUSTRING("com.sun.star.animations.IterateContainer");
74 sServiceName = CREATE_OUSTRING("com.sun.star.animations.ParallelTimeContainer");
75 break;
76 case AnimationNodeType::SEQ:
77 sServiceName = CREATE_OUSTRING("com.sun.star.animations.SequenceTimeContainer");
78 break;
79 case AnimationNodeType::ANIMATE:
80 sServiceName = CREATE_OUSTRING("com.sun.star.animations.Animate");
81 break;
82 case AnimationNodeType::ANIMATECOLOR:
83 sServiceName = CREATE_OUSTRING("com.sun.star.animations.AnimateColor");
84 break;
85 case AnimationNodeType::TRANSITIONFILTER:
86 sServiceName = CREATE_OUSTRING("com.sun.star.animations.TransitionFilter");
87 break;
88 case AnimationNodeType::ANIMATEMOTION:
89 sServiceName = CREATE_OUSTRING("com.sun.star.animations.AnimateMotion");
90 break;
91 case AnimationNodeType::ANIMATETRANSFORM:
92 sServiceName = CREATE_OUSTRING("com.sun.star.animations.AnimateTransform");
93 break;
94 case AnimationNodeType::COMMAND:
95 sServiceName = CREATE_OUSTRING("com.sun.star.animations.Command");
96 break;
97 case AnimationNodeType::SET:
98 sServiceName = CREATE_OUSTRING("com.sun.star.animations.AnimateSet");
99 break;
100 case AnimationNodeType::AUDIO:
101 sServiceName = CREATE_OUSTRING("com.sun.star.animations.Audio");
102 break;
103 default:
104 OSL_TRACE( "OOX: uhandled type %x", nNodeType );
105 break;
107 return sServiceName;
112 TimeNode::TimeNode( sal_Int16 nNodeType )
113 : mnNodeType( nNodeType )
114 , mbHasEndSyncValue( false )
119 TimeNode::~TimeNode()
123 // BEGIN CUT&PASTE from sd/source/filter/ppt/pptinanimations.hxx
124 // --------------------------------------------------------------------
125 static void fixMainSequenceTiming( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode )
129 bool bFirst = true;
130 Reference< XEnumerationAccess > xEA( xNode, UNO_QUERY_THROW );
131 Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_QUERY_THROW );
132 while( xE->hasMoreElements() )
134 // click node
135 Reference< XAnimationNode > xClickNode( xE->nextElement(), UNO_QUERY );
137 Event aEvent;
138 aEvent.Trigger = EventTrigger::ON_NEXT;
139 aEvent.Repeat = 0;
140 xClickNode->setBegin( makeAny( aEvent ) );
142 if( bFirst )
144 bFirst = false;
145 Reference< XEnumerationAccess > xEA2( xClickNode, UNO_QUERY_THROW );
146 Reference< XEnumeration > xE2( xEA2->createEnumeration(), UNO_QUERY_THROW );
147 if( xE2->hasMoreElements() )
149 // with node
150 xE2->nextElement() >>= xEA2;
151 if( xEA2.is() )
152 xE2.query( xEA2->createEnumeration() );
153 else
154 xE2.clear();
156 if( xE2.is() && xE2->hasMoreElements() )
158 Reference< XAnimationNode > xEffectNode( xE2->nextElement(), UNO_QUERY_THROW );
159 const Sequence< NamedValue > aUserData( xEffectNode->getUserData() );
160 const NamedValue* p = aUserData.getConstArray();
161 sal_Int32 nLength = aUserData.getLength();
162 while( nLength-- )
164 if( p->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "node-type" ) ) )
166 sal_Int16 nNodeType = 0;
167 p->Value >>= nNodeType;
168 if( nNodeType != ::com::sun::star::presentation::EffectNodeType::ON_CLICK )
170 // first effect does not start on click, so correct
171 // first click nodes begin to 0s
172 xClickNode->setBegin( makeAny( (double)0.0 ) );
173 break;
176 p++;
183 catch( Exception& e )
185 (void)e;
186 OSL_TRACE("fixMainSequenceTiming(), exception caught!" );
190 // --------------------------------------------------------------------
192 static void fixInteractiveSequenceTiming( const ::com::sun::star::uno::Reference< ::com::sun::star::animations::XAnimationNode >& xNode )
196 Any aBegin( xNode->getBegin() );
197 Any aEmpty;
198 xNode->setBegin( aEmpty );
200 Reference< XEnumerationAccess > xEA( xNode, UNO_QUERY_THROW );
201 Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_QUERY_THROW );
202 while( xE->hasMoreElements() )
204 // click node
205 Reference< XAnimationNode > xClickNode( xE->nextElement(), UNO_QUERY );
206 xClickNode->setBegin( aBegin );
209 catch( Exception& e )
211 (void)e;
212 OSL_TRACE("fixInteractiveSequenceTiming(), exception caught!" );
216 // END CUT&PASTE
218 void TimeNode::addNode( const XmlFilterBase& rFilter, const Reference< XAnimationNode >& rxNode, const SlidePersistPtr & pSlide )
220 try {
221 OUString sServiceName = getServiceName( mnNodeType );
222 Reference< XAnimationNode > xNode = createAndInsert( rFilter, sServiceName, rxNode );
223 setNode( rFilter, xNode, pSlide );
225 catch( const Exception& e )
227 OSL_TRACE( "OOX: exception raised in TimeNode::addNode() - %s",
228 OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
232 void TimeNode::setNode( const XmlFilterBase& rFilter, const Reference< XAnimationNode >& xNode, const SlidePersistPtr & pSlide )
234 OSL_ENSURE( xNode.is(), "null node passed" );
236 try {
237 if( msId.getLength() )
239 pSlide->getAnimNodesMap()[ msId ] = xNode;
242 if( mpTarget )
244 sal_Int16 nSubType;
245 maNodeProperties[ NP_TARGET ] = mpTarget->convert( pSlide, nSubType );
246 if( mpTarget->mnType == XML_spTgt )
248 maNodeProperties[ NP_SUBITEM ] <<= nSubType;
252 if( !maStCondList.empty() )
254 Any aAny = AnimationCondition::convertList( pSlide, maStCondList );
255 if( aAny.hasValue() )
257 xNode->setBegin( aAny );
261 if( !maEndCondList.empty() )
263 Any aAny = AnimationCondition::convertList( pSlide, maEndCondList );
264 if( aAny.hasValue() )
266 xNode->setEnd( aAny );
269 #if 0 // FIXME even the binary filter has this disabled.
270 if( !maNextCondList.empty() )
272 Any aAny = AnimationCondition::convertList( pSlide, maNextCondList );
273 if( aAny.hasValue() )
275 xNode->setNext( aAny );
278 if( !maPrevCondList.empty() )
280 Any aAny = AnimationCondition::convertList( pSlide, maPrevCondList );
281 if( aAny.hasValue() )
283 xNode->setPrev( aAny );
286 #endif
287 if( mbHasEndSyncValue )
289 Any aValue = maEndSyncValue.convert( pSlide );
290 xNode->setEndSync(aValue);
293 if( !maUserData.empty() )
295 Sequence< NamedValue > aUserDataSeq( static_cast< sal_Int32 >( maUserData.size() ) );
296 NamedValue* pValues = aUserDataSeq.getArray();
297 for( UserDataMap::const_iterator aIt = maUserData.begin(), aEnd = maUserData.end(); aIt != aEnd; ++aIt, ++pValues )
299 pValues->Name = aIt->first;
300 pValues->Value = aIt->second;
302 maNodeProperties[ NP_USERDATA ] <<= aUserDataSeq;
305 Reference< XAnimate > xAnimate( xNode, UNO_QUERY );
306 Reference< XAnimateColor > xAnimateColor( xNode, UNO_QUERY );
307 Reference< XAnimateMotion > xAnimateMotion( xNode, UNO_QUERY );
308 Reference< XAnimateTransform > xAnimateTransform( xNode, UNO_QUERY );
309 Reference< XCommand > xCommand( xNode, UNO_QUERY );
310 Reference< XIterateContainer > xIterateContainer( xNode, UNO_QUERY );
311 sal_Int16 nInt16 = 0;
312 sal_Bool bBool = sal_False;
313 double fDouble = 0;
314 OUString sString;
315 Sequence< NamedValue > aSeq;
317 for( int i = 0; i < _NP_SIZE; i++)
319 Any & aValue( maNodeProperties[ i ] );
320 if( aValue.hasValue() )
322 switch( i )
324 case NP_TO:
325 if( xAnimate.is() )
326 xAnimate->setTo( aValue );
327 break;
328 case NP_FROM:
329 if( xAnimate.is() )
330 xAnimate->setFrom( aValue );
331 break;
332 case NP_BY:
333 if( xAnimate.is() )
334 xAnimate->setBy( aValue );
335 break;
336 case NP_TARGET:
337 if( xAnimate.is() )
338 xAnimate->setTarget( aValue );
339 break;
340 case NP_SUBITEM:
341 if( xAnimate.is() )
343 if( aValue >>= nInt16 )
344 xAnimate->setSubItem( nInt16 );
345 else
347 OSL_TRACE( "any >>= failed %d", __LINE__ );
350 break;
351 case NP_ATTRIBUTENAME:
352 if( xAnimate.is() )
354 if( aValue >>= sString )
355 xAnimate->setAttributeName( sString );
356 else
358 OSL_TRACE( "any >>= failed %d", __LINE__ );
361 break;
362 case NP_CALCMODE:
363 if( xAnimate.is() )
365 if( aValue >>= nInt16 )
366 xAnimate->setCalcMode( nInt16 );
367 else
369 OSL_TRACE( "any >>= failed %d", __LINE__ );
372 break;
373 case NP_KEYTIMES:
374 if( xAnimate.is() )
376 Sequence<double> aKeyTimes;
377 if( aValue >>= aKeyTimes )
378 xAnimate->setKeyTimes(aKeyTimes);
379 else
381 OSL_TRACE( "any >>= failed %d", __LINE__ );
384 break;
385 case NP_VALUES:
386 if( xAnimate.is() )
388 Sequence<Any> aValues;
389 if( aValue >>= aValues )
390 xAnimate->setValues(aValues);
391 else
393 OSL_TRACE( "any >>= failed %d", __LINE__ );
396 break;
397 case NP_FORMULA:
398 if( xAnimate.is() )
400 if( aValue >>= sString )
401 xAnimate->setFormula(sString);
402 else
404 OSL_TRACE( "any >>= failed %d", __LINE__ );
407 break;
408 case NP_COLORINTERPOLATION:
409 if( xAnimateColor.is() )
411 if( aValue >>= nInt16 )
412 xAnimateColor->setColorInterpolation( nInt16 );
413 else
415 OSL_TRACE( "any >>= failed %d", __LINE__ );
418 break;
419 case NP_DIRECTION:
420 if( xAnimateColor.is() )
422 if( aValue >>= bBool )
423 xAnimateColor->setDirection( bBool );
424 else
426 OSL_TRACE( "any >>= failed %d", __LINE__ );
429 break;
430 case NP_PATH:
431 if( xAnimateMotion.is() )
432 xAnimateMotion->setPath( aValue );
433 break;
434 case NP_TRANSFORMTYPE:
435 if( xAnimateTransform.is() )
437 if( aValue >>= nInt16 )
438 xAnimateTransform->setTransformType( nInt16 );
439 else
441 OSL_TRACE( "any >>= failed %d", __LINE__ );
444 break;
445 case NP_USERDATA:
446 if( aValue >>= aSeq )
447 xNode->setUserData( aSeq );
448 else
450 OSL_TRACE( "any >>= failed %d", __LINE__ );
452 break;
453 case NP_ACCELERATION:
454 if( aValue >>= fDouble )
455 xNode->setAcceleration( fDouble );
456 else
458 OSL_TRACE( "any >>= failed %d", __LINE__ );
460 break;
461 case NP_DECELERATE:
462 if( aValue >>= fDouble )
463 xNode->setDecelerate( fDouble );
464 else
466 OSL_TRACE( "any >>= failed %d", __LINE__ );
468 break;
469 case NP_AUTOREVERSE:
470 if( aValue >>= bBool )
471 xNode->setAutoReverse( bBool );
472 else
474 OSL_TRACE( "any >>= failed %d", __LINE__ );
476 break;
477 case NP_DURATION:
478 xNode->setDuration( aValue );
479 break;
480 case NP_FILL:
481 if( aValue >>= nInt16 )
482 xNode->setFill( nInt16 );
483 else
485 OSL_TRACE( "any >>= failed %d", __LINE__ );
487 break;
488 case NP_REPEATCOUNT:
489 xNode->setRepeatCount( aValue );
490 break;
491 case NP_REPEATDURATION:
492 xNode->setRepeatDuration( aValue );
493 break;
494 case NP_RESTART:
495 if( aValue >>= nInt16 )
496 xNode->setRestart( nInt16 );
497 else
499 OSL_TRACE( "any >>= failed %d", __LINE__ );
501 break;
502 case NP_COMMAND:
503 if( xCommand.is() )
505 if( aValue >>= nInt16 )
506 xCommand->setCommand( nInt16 );
507 else
509 OSL_TRACE( "any >>= failed %d", __LINE__ );
512 break;
513 case NP_PARAMETER:
514 if( xCommand.is() )
515 xCommand->setParameter( aValue );
516 break;
517 case NP_ITERATETYPE:
518 if( xIterateContainer.is() )
520 if( aValue >>= nInt16 )
521 xIterateContainer->setIterateType( nInt16 );
522 else
524 OSL_TRACE( "any >>= failed %d", __LINE__ );
527 break;
528 case NP_ITERATEINTERVAL:
529 if( xIterateContainer.is() )
531 if( aValue >>= fDouble )
532 xIterateContainer->setIterateInterval( fDouble );
533 else
535 OSL_TRACE( "any >>= failed %d", __LINE__ );
538 break;
539 default:
540 OSL_TRACE( "ERR-OOX: unknown prop index %d", i );
541 break;
546 if( mnNodeType == AnimationNodeType::TRANSITIONFILTER )
549 Reference< XTransitionFilter > xFilter( xNode, UNO_QUERY );
550 maTransitionFilter.setTransitionFilterProperties( xFilter );
553 std::for_each( maChildren.begin(), maChildren.end(),
554 boost::bind(&TimeNode::addNode, _1, boost::cref(rFilter), boost::ref(xNode),
555 boost::ref(pSlide) ) );
557 switch( mnNodeType )
559 case AnimationNodeType::SEQ:
561 sal_Int16 nEnum = 0;
562 if( maUserData[ CREATE_OUSTRING( "node-type" ) ] >>= nEnum )
564 if( nEnum == EffectNodeType::MAIN_SEQUENCE )
566 fixMainSequenceTiming( xNode );
568 else if( nEnum == EffectNodeType::INTERACTIVE_SEQUENCE )
570 fixInteractiveSequenceTiming( xNode );
573 break;
575 case AnimationNodeType::PAR:
576 // some other cut&paste... from AnimationImporter::importAnimationContainer()
577 break;
580 catch( const Exception& e )
582 OSL_TRACE( "OOX: exception raised in TimeNode::setNode() - %s",
583 OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
588 Reference< XAnimationNode > TimeNode::createAndInsert(
589 const XmlFilterBase& rFilter,
590 const OUString& rServiceName,
591 const Reference< XAnimationNode >& rxNode )
593 try {
594 Reference< XAnimationNode > xNode ( rFilter.getGlobalFactory()->createInstance(rServiceName ), UNO_QUERY_THROW );
595 Reference< XTimeContainer > xParentContainer( rxNode, UNO_QUERY_THROW );
597 xParentContainer->appendChild( xNode );
598 return xNode;
600 catch( const Exception& e )
602 OSL_TRACE( "OOX: exception raised in TimeNode::createAndInsert() trying to create a service %s = %s",
603 OUStringToOString( rServiceName, RTL_TEXTENCODING_ASCII_US ).getStr(),
604 OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() );
607 return Reference< XAnimationNode >();
611 void TimeNode::setId( sal_Int32 nId )
613 msId = OUString::valueOf(nId);
616 void TimeNode::setTo( const Any & aTo )
618 maNodeProperties[ NP_TO ] = aTo;
622 void TimeNode::setFrom( const Any & aFrom )
624 maNodeProperties[ NP_FROM ] = aFrom;
627 void TimeNode::setBy( const Any & aBy )
629 maNodeProperties[ NP_BY ] = aBy;