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
;
72 case AnimationNodeType::PAR
:
73 // sServiceName = CREATE_OUSTRING("com.sun.star.animations.IterateContainer");
74 sServiceName
= CREATE_OUSTRING("com.sun.star.animations.ParallelTimeContainer");
76 case AnimationNodeType::SEQ
:
77 sServiceName
= CREATE_OUSTRING("com.sun.star.animations.SequenceTimeContainer");
79 case AnimationNodeType::ANIMATE
:
80 sServiceName
= CREATE_OUSTRING("com.sun.star.animations.Animate");
82 case AnimationNodeType::ANIMATECOLOR
:
83 sServiceName
= CREATE_OUSTRING("com.sun.star.animations.AnimateColor");
85 case AnimationNodeType::TRANSITIONFILTER
:
86 sServiceName
= CREATE_OUSTRING("com.sun.star.animations.TransitionFilter");
88 case AnimationNodeType::ANIMATEMOTION
:
89 sServiceName
= CREATE_OUSTRING("com.sun.star.animations.AnimateMotion");
91 case AnimationNodeType::ANIMATETRANSFORM
:
92 sServiceName
= CREATE_OUSTRING("com.sun.star.animations.AnimateTransform");
94 case AnimationNodeType::COMMAND
:
95 sServiceName
= CREATE_OUSTRING("com.sun.star.animations.Command");
97 case AnimationNodeType::SET
:
98 sServiceName
= CREATE_OUSTRING("com.sun.star.animations.AnimateSet");
100 case AnimationNodeType::AUDIO
:
101 sServiceName
= CREATE_OUSTRING("com.sun.star.animations.Audio");
104 OSL_TRACE( "OOX: uhandled type %x", nNodeType
);
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
)
130 Reference
< XEnumerationAccess
> xEA( xNode
, UNO_QUERY_THROW
);
131 Reference
< XEnumeration
> xE( xEA
->createEnumeration(), UNO_QUERY_THROW
);
132 while( xE
->hasMoreElements() )
135 Reference
< XAnimationNode
> xClickNode( xE
->nextElement(), UNO_QUERY
);
138 aEvent
.Trigger
= EventTrigger::ON_NEXT
;
140 xClickNode
->setBegin( makeAny( aEvent
) );
145 Reference
< XEnumerationAccess
> xEA2( xClickNode
, UNO_QUERY_THROW
);
146 Reference
< XEnumeration
> xE2( xEA2
->createEnumeration(), UNO_QUERY_THROW
);
147 if( xE2
->hasMoreElements() )
150 xE2
->nextElement() >>= xEA2
;
152 xE2
.query( xEA2
->createEnumeration() );
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();
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 ) );
183 catch( Exception
& 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() );
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() )
205 Reference
< XAnimationNode
> xClickNode( xE
->nextElement(), UNO_QUERY
);
206 xClickNode
->setBegin( aBegin
);
209 catch( Exception
& e
)
212 OSL_TRACE("fixInteractiveSequenceTiming(), exception caught!" );
218 void TimeNode::addNode( const XmlFilterBase
& rFilter
, const Reference
< XAnimationNode
>& rxNode
, const SlidePersistPtr
& pSlide
)
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" );
237 if( msId
.getLength() )
239 pSlide
->getAnimNodesMap()[ msId
] = xNode
;
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
);
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
;
315 Sequence
< NamedValue
> aSeq
;
317 for( int i
= 0; i
< _NP_SIZE
; i
++)
319 Any
& aValue( maNodeProperties
[ i
] );
320 if( aValue
.hasValue() )
326 xAnimate
->setTo( aValue
);
330 xAnimate
->setFrom( aValue
);
334 xAnimate
->setBy( aValue
);
338 xAnimate
->setTarget( aValue
);
343 if( aValue
>>= nInt16
)
344 xAnimate
->setSubItem( nInt16
);
347 OSL_TRACE( "any >>= failed %d", __LINE__
);
351 case NP_ATTRIBUTENAME
:
354 if( aValue
>>= sString
)
355 xAnimate
->setAttributeName( sString
);
358 OSL_TRACE( "any >>= failed %d", __LINE__
);
365 if( aValue
>>= nInt16
)
366 xAnimate
->setCalcMode( nInt16
);
369 OSL_TRACE( "any >>= failed %d", __LINE__
);
376 Sequence
<double> aKeyTimes
;
377 if( aValue
>>= aKeyTimes
)
378 xAnimate
->setKeyTimes(aKeyTimes
);
381 OSL_TRACE( "any >>= failed %d", __LINE__
);
388 Sequence
<Any
> aValues
;
389 if( aValue
>>= aValues
)
390 xAnimate
->setValues(aValues
);
393 OSL_TRACE( "any >>= failed %d", __LINE__
);
400 if( aValue
>>= sString
)
401 xAnimate
->setFormula(sString
);
404 OSL_TRACE( "any >>= failed %d", __LINE__
);
408 case NP_COLORINTERPOLATION
:
409 if( xAnimateColor
.is() )
411 if( aValue
>>= nInt16
)
412 xAnimateColor
->setColorInterpolation( nInt16
);
415 OSL_TRACE( "any >>= failed %d", __LINE__
);
420 if( xAnimateColor
.is() )
422 if( aValue
>>= bBool
)
423 xAnimateColor
->setDirection( bBool
);
426 OSL_TRACE( "any >>= failed %d", __LINE__
);
431 if( xAnimateMotion
.is() )
432 xAnimateMotion
->setPath( aValue
);
434 case NP_TRANSFORMTYPE
:
435 if( xAnimateTransform
.is() )
437 if( aValue
>>= nInt16
)
438 xAnimateTransform
->setTransformType( nInt16
);
441 OSL_TRACE( "any >>= failed %d", __LINE__
);
446 if( aValue
>>= aSeq
)
447 xNode
->setUserData( aSeq
);
450 OSL_TRACE( "any >>= failed %d", __LINE__
);
453 case NP_ACCELERATION
:
454 if( aValue
>>= fDouble
)
455 xNode
->setAcceleration( fDouble
);
458 OSL_TRACE( "any >>= failed %d", __LINE__
);
462 if( aValue
>>= fDouble
)
463 xNode
->setDecelerate( fDouble
);
466 OSL_TRACE( "any >>= failed %d", __LINE__
);
470 if( aValue
>>= bBool
)
471 xNode
->setAutoReverse( bBool
);
474 OSL_TRACE( "any >>= failed %d", __LINE__
);
478 xNode
->setDuration( aValue
);
481 if( aValue
>>= nInt16
)
482 xNode
->setFill( nInt16
);
485 OSL_TRACE( "any >>= failed %d", __LINE__
);
489 xNode
->setRepeatCount( aValue
);
491 case NP_REPEATDURATION
:
492 xNode
->setRepeatDuration( aValue
);
495 if( aValue
>>= nInt16
)
496 xNode
->setRestart( nInt16
);
499 OSL_TRACE( "any >>= failed %d", __LINE__
);
505 if( aValue
>>= nInt16
)
506 xCommand
->setCommand( nInt16
);
509 OSL_TRACE( "any >>= failed %d", __LINE__
);
515 xCommand
->setParameter( aValue
);
518 if( xIterateContainer
.is() )
520 if( aValue
>>= nInt16
)
521 xIterateContainer
->setIterateType( nInt16
);
524 OSL_TRACE( "any >>= failed %d", __LINE__
);
528 case NP_ITERATEINTERVAL
:
529 if( xIterateContainer
.is() )
531 if( aValue
>>= fDouble
)
532 xIterateContainer
->setIterateInterval( fDouble
);
535 OSL_TRACE( "any >>= failed %d", __LINE__
);
540 OSL_TRACE( "ERR-OOX: unknown prop index %d", i
);
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
) ) );
559 case AnimationNodeType::SEQ
:
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
);
575 case AnimationNodeType::PAR
:
576 // some other cut&paste... from AnimationImporter::importAnimationContainer()
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
)
594 Reference
< XAnimationNode
> xNode ( rFilter
.getGlobalFactory()->createInstance(rServiceName
), UNO_QUERY_THROW
);
595 Reference
< XTimeContainer
> xParentContainer( rxNode
, UNO_QUERY_THROW
);
597 xParentContainer
->appendChild( 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
;