1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "oox/ppt/timenode.hxx"
22 #include <com/sun/star/beans/XPropertySet.hpp>
23 #include <com/sun/star/beans/NamedValue.hpp>
24 #include <com/sun/star/container/XEnumerationAccess.hpp>
25 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
26 #include <com/sun/star/frame/XModel.hpp>
27 #include <com/sun/star/animations/XAnimateColor.hpp>
28 #include <com/sun/star/animations/XAnimateMotion.hpp>
29 #include <com/sun/star/animations/XAnimateTransform.hpp>
30 #include <com/sun/star/animations/XCommand.hpp>
31 #include <com/sun/star/animations/XIterateContainer.hpp>
32 #include <com/sun/star/animations/XAnimationNodeSupplier.hpp>
33 #include <com/sun/star/animations/XTimeContainer.hpp>
34 #include <com/sun/star/animations/AnimationNodeType.hpp>
35 #include <com/sun/star/animations/Event.hpp>
36 #include <com/sun/star/animations/EventTrigger.hpp>
37 #include <com/sun/star/presentation/EffectNodeType.hpp>
38 #include <com/sun/star/uno/XComponentContext.hpp>
40 #include "oox/helper/helper.hxx"
41 #include "oox/core/xmlfilterbase.hxx"
42 #include "sal/log.hxx"
44 using namespace ::oox::core
;
45 using namespace ::com::sun::star::beans
;
46 using namespace ::com::sun::star::container
;
47 using namespace ::com::sun::star::uno
;
48 using namespace ::com::sun::star::lang
;
49 using namespace ::com::sun::star::animations
;
50 using namespace ::com::sun::star::frame
;
51 using namespace ::com::sun::star::presentation
;
53 namespace oox
{ namespace ppt
{
55 OUString
TimeNode::getServiceName( sal_Int16 nNodeType
)
57 OUString sServiceName
;
60 case AnimationNodeType::PAR
:
61 sServiceName
= "com.sun.star.animations.ParallelTimeContainer";
63 case AnimationNodeType::SEQ
:
64 sServiceName
= "com.sun.star.animations.SequenceTimeContainer";
66 case AnimationNodeType::ANIMATE
:
67 sServiceName
= "com.sun.star.animations.Animate";
69 case AnimationNodeType::ANIMATECOLOR
:
70 sServiceName
= "com.sun.star.animations.AnimateColor";
72 case AnimationNodeType::TRANSITIONFILTER
:
73 sServiceName
= "com.sun.star.animations.TransitionFilter";
75 case AnimationNodeType::ANIMATEMOTION
:
76 sServiceName
= "com.sun.star.animations.AnimateMotion";
78 case AnimationNodeType::ANIMATETRANSFORM
:
79 sServiceName
= "com.sun.star.animations.AnimateTransform";
81 case AnimationNodeType::COMMAND
:
82 sServiceName
= "com.sun.star.animations.Command";
84 case AnimationNodeType::SET
:
85 sServiceName
= "com.sun.star.animations.AnimateSet";
87 case AnimationNodeType::AUDIO
:
88 sServiceName
= "com.sun.star.animations.Audio";
91 SAL_INFO("oox.ppt","OOX: uhandled type " << nNodeType
);
97 TimeNode::TimeNode( sal_Int16 nNodeType
)
98 : mnNodeType( nNodeType
)
99 , mbHasEndSyncValue( false )
103 TimeNode::~TimeNode()
107 // BEGIN CUT&PASTE from sd/source/filter/ppt/pptinanimations.hxx
109 static void fixMainSequenceTiming( const ::com::sun::star::uno::Reference
< ::com::sun::star::animations::XAnimationNode
>& xNode
)
114 Reference
< XEnumerationAccess
> xEA( xNode
, UNO_QUERY_THROW
);
115 Reference
< XEnumeration
> xE( xEA
->createEnumeration(), UNO_QUERY_THROW
);
116 while( xE
->hasMoreElements() )
119 Reference
< XAnimationNode
> xClickNode( xE
->nextElement(), UNO_QUERY
);
122 aEvent
.Trigger
= EventTrigger::ON_NEXT
;
124 xClickNode
->setBegin( makeAny( aEvent
) );
129 Reference
< XEnumerationAccess
> xEA2( xClickNode
, UNO_QUERY_THROW
);
130 Reference
< XEnumeration
> xE2( xEA2
->createEnumeration(), UNO_QUERY_THROW
);
131 if( xE2
->hasMoreElements() )
134 xE2
->nextElement() >>= xEA2
;
136 xE2
.set(xEA2
->createEnumeration(), css::uno::UNO_QUERY
);
140 if( xE2
.is() && xE2
->hasMoreElements() )
142 Reference
< XAnimationNode
> xEffectNode( xE2
->nextElement(), UNO_QUERY_THROW
);
143 const Sequence
< NamedValue
> aUserData( xEffectNode
->getUserData() );
144 const NamedValue
* p
= aUserData
.getConstArray();
145 sal_Int32 nLength
= aUserData
.getLength();
148 if ( p
->Name
== "node-type" )
150 sal_Int16 nNodeType
= 0;
151 p
->Value
>>= nNodeType
;
152 if( nNodeType
!= ::com::sun::star::presentation::EffectNodeType::ON_CLICK
)
154 // first effect does not start on click, so correct
155 // first click nodes begin to 0s
156 xClickNode
->setBegin( makeAny( (double)0.0 ) );
167 catch( Exception
& e
)
170 SAL_INFO("oox.ppt","fixMainSequenceTiming(), exception caught!" );
174 static void fixInteractiveSequenceTiming( const ::com::sun::star::uno::Reference
< ::com::sun::star::animations::XAnimationNode
>& xNode
)
178 Any
aBegin( xNode
->getBegin() );
180 xNode
->setBegin( aEmpty
);
182 Reference
< XEnumerationAccess
> xEA( xNode
, UNO_QUERY_THROW
);
183 Reference
< XEnumeration
> xE( xEA
->createEnumeration(), UNO_QUERY_THROW
);
184 while( xE
->hasMoreElements() )
187 Reference
< XAnimationNode
> xClickNode( xE
->nextElement(), UNO_QUERY
);
188 xClickNode
->setBegin( aBegin
);
191 catch( Exception
& e
)
194 SAL_INFO("oox.ppt","fixInteractiveSequenceTiming(), exception caught!" );
200 void TimeNode::addNode( const XmlFilterBase
& rFilter
, const Reference
< XAnimationNode
>& rxNode
, const SlidePersistPtr
& pSlide
)
203 OUString sServiceName
= getServiceName( mnNodeType
);
204 Reference
< XAnimationNode
> xNode
= createAndInsert( rFilter
, sServiceName
, rxNode
);
205 setNode( rFilter
, xNode
, pSlide
);
207 catch( const Exception
& e
)
209 SAL_INFO("oox.ppt","OOX: exception raised in TimeNode::addNode() - " <<
210 OUStringToOString( e
.Message
, RTL_TEXTENCODING_ASCII_US
).getStr() );
214 void TimeNode::setNode( const XmlFilterBase
& rFilter
, const Reference
< XAnimationNode
>& xNode
, const SlidePersistPtr
& pSlide
)
216 SAL_WARN_IF( !xNode
.is(), "oox.ppt", "null node passed" );
219 if( !msId
.isEmpty() )
221 pSlide
->getAnimNodesMap()[ msId
] = xNode
;
226 sal_Int16
nSubType(0);
227 maNodeProperties
[ NP_TARGET
] = mpTarget
->convert( pSlide
, nSubType
);
228 if( mpTarget
->mnType
== XML_spTgt
)
230 maNodeProperties
[ NP_SUBITEM
] <<= nSubType
;
234 if( !maStCondList
.empty() )
236 Any aAny
= AnimationCondition::convertList( pSlide
, maStCondList
);
237 if( aAny
.hasValue() )
239 xNode
->setBegin( aAny
);
243 if( !maEndCondList
.empty() )
245 Any aAny
= AnimationCondition::convertList( pSlide
, maEndCondList
);
246 if( aAny
.hasValue() )
248 xNode
->setEnd( aAny
);
251 #if 0 // FIXME even the binary filter has this disabled.
252 if( !maNextCondList
.empty() )
254 Any aAny
= AnimationCondition::convertList( pSlide
, maNextCondList
);
255 if( aAny
.hasValue() )
257 xNode
->setNext( aAny
);
260 if( !maPrevCondList
.empty() )
262 Any aAny
= AnimationCondition::convertList( pSlide
, maPrevCondList
);
263 if( aAny
.hasValue() )
265 xNode
->setPrev( aAny
);
269 if( mbHasEndSyncValue
)
271 Any aValue
= maEndSyncValue
.convert( pSlide
);
272 xNode
->setEndSync(aValue
);
275 if( !maUserData
.empty() )
277 Sequence
< NamedValue
> aUserDataSeq( static_cast< sal_Int32
>( maUserData
.size() ) );
278 NamedValue
* pValues
= aUserDataSeq
.getArray();
279 for( UserDataMap::const_iterator aIt
= maUserData
.begin(), aEnd
= maUserData
.end(); aIt
!= aEnd
; ++aIt
, ++pValues
)
281 pValues
->Name
= aIt
->first
;
282 pValues
->Value
= aIt
->second
;
284 maNodeProperties
[ NP_USERDATA
] <<= aUserDataSeq
;
287 Reference
< XAnimate
> xAnimate( xNode
, UNO_QUERY
);
288 Reference
< XAnimateColor
> xAnimateColor( xNode
, UNO_QUERY
);
289 Reference
< XAnimateMotion
> xAnimateMotion( xNode
, UNO_QUERY
);
290 Reference
< XAnimateTransform
> xAnimateTransform( xNode
, UNO_QUERY
);
291 Reference
< XCommand
> xCommand( xNode
, UNO_QUERY
);
292 Reference
< XIterateContainer
> xIterateContainer( xNode
, UNO_QUERY
);
293 sal_Int16 nInt16
= 0;
297 Sequence
< NamedValue
> aSeq
;
299 for( int i
= 0; i
< _NP_SIZE
; i
++)
301 Any
& aValue( maNodeProperties
[ i
] );
302 if( aValue
.hasValue() )
308 xAnimate
->setTo( aValue
);
312 xAnimate
->setFrom( aValue
);
316 xAnimate
->setBy( aValue
);
320 xAnimate
->setTarget( aValue
);
325 if( aValue
>>= nInt16
)
326 xAnimate
->setSubItem( nInt16
);
329 SAL_INFO("oox.ppt","any >>= failed " << __LINE__
);
333 case NP_ATTRIBUTENAME
:
336 if( aValue
>>= sString
)
337 xAnimate
->setAttributeName( sString
);
340 SAL_INFO("oox.ppt","any >>= failed " << __LINE__
);
347 if( aValue
>>= nInt16
)
348 xAnimate
->setCalcMode( nInt16
);
351 SAL_INFO("oox.ppt","any >>= failed " << __LINE__
);
358 Sequence
<double> aKeyTimes
;
359 if( aValue
>>= aKeyTimes
)
360 xAnimate
->setKeyTimes(aKeyTimes
);
363 SAL_INFO("oox.ppt","any >>= failed " << __LINE__
);
370 Sequence
<Any
> aValues
;
371 if( aValue
>>= aValues
)
372 xAnimate
->setValues(aValues
);
375 SAL_INFO("oox.ppt","any >>= failed " << __LINE__
);
382 if( aValue
>>= sString
)
383 xAnimate
->setFormula(sString
);
386 SAL_INFO("oox.ppt","any >>= failed " << __LINE__
);
390 case NP_COLORINTERPOLATION
:
391 if( xAnimateColor
.is() )
393 if( aValue
>>= nInt16
)
394 xAnimateColor
->setColorInterpolation( nInt16
);
397 SAL_INFO("oox.ppt","any >>= failed " << __LINE__
);
402 if( xAnimateColor
.is() )
404 if( aValue
>>= bBool
)
405 xAnimateColor
->setDirection( bBool
);
408 SAL_INFO("oox.ppt","any >>= failed " << __LINE__
);
413 if( xAnimateMotion
.is() )
414 xAnimateMotion
->setPath( aValue
);
416 case NP_TRANSFORMTYPE
:
417 if( xAnimateTransform
.is() )
419 if( aValue
>>= nInt16
)
420 xAnimateTransform
->setTransformType( nInt16
);
423 SAL_INFO("oox.ppt","any >>= failed " << __LINE__
);
428 if( aValue
>>= aSeq
)
429 xNode
->setUserData( aSeq
);
432 SAL_INFO("oox.ppt","any >>= failed " << __LINE__
);
435 case NP_ACCELERATION
:
436 if( aValue
>>= fDouble
)
437 xNode
->setAcceleration( fDouble
);
440 SAL_INFO("oox.ppt","any >>= failed " << __LINE__
);
444 if( aValue
>>= fDouble
)
445 xNode
->setDecelerate( fDouble
);
448 SAL_INFO("oox.ppt","any >>= failed " << __LINE__
);
452 if( aValue
>>= bBool
)
453 xNode
->setAutoReverse( bBool
);
456 SAL_INFO("oox.ppt","any >>= failed " << __LINE__
);
460 xNode
->setDuration( aValue
);
463 if( aValue
>>= nInt16
)
464 xNode
->setFill( nInt16
);
467 SAL_INFO("oox.ppt","any >>= failed " << __LINE__
);
471 xNode
->setRepeatCount( aValue
);
473 case NP_REPEATDURATION
:
474 xNode
->setRepeatDuration( aValue
);
477 if( aValue
>>= nInt16
)
478 xNode
->setRestart( nInt16
);
481 SAL_INFO("oox.ppt","any >>= failed " << __LINE__
);
487 if( aValue
>>= nInt16
)
488 xCommand
->setCommand( nInt16
);
491 SAL_INFO("oox.ppt","any >>= failed " << __LINE__
);
497 xCommand
->setParameter( aValue
);
500 if( xIterateContainer
.is() )
502 if( aValue
>>= nInt16
)
503 xIterateContainer
->setIterateType( nInt16
);
506 SAL_INFO("oox.ppt","any >>= failed " << __LINE__
);
510 case NP_ITERATEINTERVAL
:
511 if( xIterateContainer
.is() )
513 if( aValue
>>= fDouble
)
514 xIterateContainer
->setIterateInterval( fDouble
);
517 SAL_INFO("oox.ppt","any >>= failed " << __LINE__
);
522 SAL_INFO("oox.ppt","ERR-OOX: unknown prop index " << i
);
528 if( mnNodeType
== AnimationNodeType::TRANSITIONFILTER
)
531 Reference
< XTransitionFilter
> xFilter( xNode
, UNO_QUERY
);
532 maTransitionFilter
.setTransitionFilterProperties( xFilter
);
536 maChildren
.begin(), maChildren
.end(),
537 [&rFilter
, &xNode
, &pSlide
] (TimeNodePtr
const & child
) {
538 child
->addNode(rFilter
, xNode
, pSlide
);
543 case AnimationNodeType::SEQ
:
546 if( maUserData
[ "node-type" ] >>= nEnum
)
548 if( nEnum
== EffectNodeType::MAIN_SEQUENCE
)
550 fixMainSequenceTiming( xNode
);
552 else if( nEnum
== EffectNodeType::INTERACTIVE_SEQUENCE
)
554 fixInteractiveSequenceTiming( xNode
);
559 case AnimationNodeType::PAR
:
560 // some other cut&paste... from AnimationImporter::importAnimationContainer()
564 catch( const Exception
& e
)
566 SAL_INFO("oox.ppt","OOX: exception raised in TimeNode::setNode() - " << e
.Message
);
570 Reference
< XAnimationNode
> TimeNode::createAndInsert(
571 const XmlFilterBase
& rFilter
,
572 const OUString
& rServiceName
,
573 const Reference
< XAnimationNode
>& rxNode
)
576 Reference
< XAnimationNode
> xNode( Reference
<css::lang::XMultiServiceFactory
>(rFilter
.getComponentContext()->getServiceManager(), UNO_QUERY_THROW
)->createInstance( rServiceName
), UNO_QUERY_THROW
);;
577 Reference
< XTimeContainer
> xParentContainer( rxNode
, UNO_QUERY_THROW
);
579 xParentContainer
->appendChild( xNode
);
582 catch( const Exception
& e
)
584 SAL_INFO("oox.ppt","OOX: exception raised in TimeNode::createAndInsert() trying to create a service " << OUStringToOString( rServiceName
, RTL_TEXTENCODING_ASCII_US
).getStr() << " = " << OUStringToOString( e
.Message
, RTL_TEXTENCODING_ASCII_US
).getStr() );
587 return Reference
< XAnimationNode
>();
590 void TimeNode::setId( sal_Int32 nId
)
592 msId
= OUString::number(nId
);
595 void TimeNode::setTo( const Any
& aTo
)
597 maNodeProperties
[ NP_TO
] = aTo
;
600 void TimeNode::setFrom( const Any
& aFrom
)
602 maNodeProperties
[ NP_FROM
] = aFrom
;
605 void TimeNode::setBy( const Any
& aBy
)
607 maNodeProperties
[ NP_BY
] = aBy
;
612 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */