Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / oox / source / ppt / timenode.cxx
blob030baacec2e3ca8a6498946ef773572721e195f6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/XTransitionFilter.hpp>
35 #include <com/sun/star/animations/AnimationNodeType.hpp>
36 #include <com/sun/star/animations/Event.hpp>
37 #include <com/sun/star/animations/EventTrigger.hpp>
38 #include <com/sun/star/presentation/EffectNodeType.hpp>
39 #include <com/sun/star/uno/XComponentContext.hpp>
41 #include "oox/helper/helper.hxx"
42 #include "oox/core/xmlfilterbase.hxx"
43 #include <oox/ppt/pptfilterhelpers.hxx>
44 #include <oox/token/tokens.hxx>
45 #include "sal/log.hxx"
47 using namespace ::oox::core;
48 using namespace ::com::sun::star::beans;
49 using namespace ::com::sun::star::container;
50 using namespace ::com::sun::star::uno;
51 using namespace ::com::sun::star::lang;
52 using namespace ::com::sun::star::animations;
53 using namespace ::com::sun::star::frame;
54 using namespace ::com::sun::star::presentation;
56 namespace oox { namespace ppt {
58 OUString TimeNode::getServiceName( sal_Int16 nNodeType )
60 OUString sServiceName;
61 switch( nNodeType )
63 case AnimationNodeType::PAR:
64 sServiceName = "com.sun.star.animations.ParallelTimeContainer";
65 break;
66 case AnimationNodeType::SEQ:
67 sServiceName = "com.sun.star.animations.SequenceTimeContainer";
68 break;
69 case AnimationNodeType::ANIMATE:
70 sServiceName = "com.sun.star.animations.Animate";
71 break;
72 case AnimationNodeType::ANIMATECOLOR:
73 sServiceName = "com.sun.star.animations.AnimateColor";
74 break;
75 case AnimationNodeType::TRANSITIONFILTER:
76 sServiceName = "com.sun.star.animations.TransitionFilter";
77 break;
78 case AnimationNodeType::ANIMATEMOTION:
79 sServiceName = "com.sun.star.animations.AnimateMotion";
80 break;
81 case AnimationNodeType::ANIMATETRANSFORM:
82 sServiceName = "com.sun.star.animations.AnimateTransform";
83 break;
84 case AnimationNodeType::COMMAND:
85 sServiceName = "com.sun.star.animations.Command";
86 break;
87 case AnimationNodeType::SET:
88 sServiceName = "com.sun.star.animations.AnimateSet";
89 break;
90 case AnimationNodeType::AUDIO:
91 sServiceName = "com.sun.star.animations.Audio";
92 break;
93 default:
94 SAL_INFO("oox.ppt","OOX: uhandled type " << nNodeType );
95 break;
97 return sServiceName;
100 TimeNode::TimeNode( sal_Int16 nNodeType )
101 : mnNodeType( nNodeType )
102 , mbHasEndSyncValue( false )
106 TimeNode::~TimeNode()
110 void fixMainSequenceTiming( const css::uno::Reference< css::animations::XAnimationNode >& xNode )
114 bool bFirst = true;
115 Reference< XEnumerationAccess > xEA( xNode, UNO_QUERY_THROW );
116 Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_QUERY_THROW );
117 while( xE->hasMoreElements() )
119 // click node
120 Reference< XAnimationNode > xClickNode( xE->nextElement(), UNO_QUERY );
122 Event aEvent;
123 aEvent.Trigger = EventTrigger::ON_NEXT;
124 aEvent.Repeat = 0;
125 xClickNode->setBegin( makeAny( aEvent ) );
127 if( bFirst )
129 bFirst = false;
130 Reference< XEnumerationAccess > xEA2( xClickNode, UNO_QUERY_THROW );
131 Reference< XEnumeration > xE2( xEA2->createEnumeration(), UNO_QUERY_THROW );
132 if( xE2->hasMoreElements() )
134 // with node
135 xE2->nextElement() >>= xEA2;
136 if( xEA2.is() )
137 xE2.set(xEA2->createEnumeration(), css::uno::UNO_QUERY);
138 else
139 xE2.clear();
141 if( xE2.is() && xE2->hasMoreElements() )
143 Reference< XAnimationNode > xEffectNode( xE2->nextElement(), UNO_QUERY_THROW );
144 const Sequence< NamedValue > aUserData( xEffectNode->getUserData() );
145 const NamedValue* p = aUserData.getConstArray();
146 sal_Int32 nLength = aUserData.getLength();
147 while( nLength-- )
149 if ( p->Name == "node-type" )
151 sal_Int16 nNodeType = 0;
152 p->Value >>= nNodeType;
153 if( nNodeType != css::presentation::EffectNodeType::ON_CLICK )
155 // first effect does not start on click, so correct
156 // first click nodes begin to 0s
157 xClickNode->setBegin( makeAny( 0.0 ) );
158 break;
161 p++;
168 catch( Exception& )
170 SAL_INFO("oox.ppt","fixMainSequenceTiming(), exception caught!" );
174 void fixInteractiveSequenceTiming( const css::uno::Reference< css::animations::XAnimationNode >& xNode )
178 Any aBegin( xNode->getBegin() );
179 Any aEmpty;
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() )
186 // click node
187 Reference< XAnimationNode > xClickNode( xE->nextElement(), UNO_QUERY );
188 xClickNode->setBegin( aBegin );
191 catch( Exception& )
193 SAL_INFO("oox.ppt","fixInteractiveSequenceTiming(), exception caught!" );
197 void TimeNode::addNode( const XmlFilterBase& rFilter, const Reference< XAnimationNode >& rxNode, const SlidePersistPtr & pSlide )
199 try {
200 OUString sServiceName = getServiceName( mnNodeType );
201 Reference< XAnimationNode > xNode = createAndInsert( rFilter, sServiceName, rxNode );
202 setNode( rFilter, xNode, pSlide );
204 catch( const Exception& e )
206 SAL_INFO("oox.ppt","OOX: exception raised in TimeNode::addNode() - " << e.Message );
210 void TimeNode::setNode( const XmlFilterBase& rFilter, const Reference< XAnimationNode >& xNode, const SlidePersistPtr & pSlide )
212 SAL_WARN_IF( !xNode.is(), "oox.ppt", "null node passed" );
214 try {
215 if( !msId.isEmpty() )
217 pSlide->getAnimNodesMap()[ msId ] = xNode;
220 if( mpTarget )
222 sal_Int16 nSubType(0);
223 maNodeProperties[ NP_TARGET ] = mpTarget->convert( pSlide, nSubType );
224 if( mpTarget->mnType == XML_spTgt )
226 maNodeProperties[ NP_SUBITEM ] <<= nSubType;
230 if( !maStCondList.empty() )
232 Any aAny = AnimationCondition::convertList( pSlide, maStCondList );
233 if( aAny.hasValue() )
235 xNode->setBegin( aAny );
239 if( !maEndCondList.empty() )
241 Any aAny = AnimationCondition::convertList( pSlide, maEndCondList );
242 if( aAny.hasValue() )
244 xNode->setEnd( aAny );
247 #if 0 // FIXME even the binary filter has this disabled.
248 if( !maNextCondList.empty() )
250 Any aAny = AnimationCondition::convertList( pSlide, maNextCondList );
251 if( aAny.hasValue() )
253 xNode->setNext( aAny );
256 if( !maPrevCondList.empty() )
258 Any aAny = AnimationCondition::convertList( pSlide, maPrevCondList );
259 if( aAny.hasValue() )
261 xNode->setPrev( aAny );
264 #endif
265 if( mbHasEndSyncValue )
267 Any aValue = maEndSyncValue.convert( pSlide );
268 xNode->setEndSync(aValue);
271 if( !maUserData.empty() )
273 Sequence< NamedValue > aUserDataSeq( static_cast< sal_Int32 >( maUserData.size() ) );
274 NamedValue* pValues = aUserDataSeq.getArray();
275 for( UserDataMap::const_iterator aIt = maUserData.begin(), aEnd = maUserData.end(); aIt != aEnd; ++aIt, ++pValues )
277 pValues->Name = aIt->first;
278 pValues->Value = aIt->second;
280 maNodeProperties[ NP_USERDATA ] <<= aUserDataSeq;
283 Reference< XAnimate > xAnimate( xNode, UNO_QUERY );
284 Reference< XAnimateColor > xAnimateColor( xNode, UNO_QUERY );
285 Reference< XAnimateMotion > xAnimateMotion( xNode, UNO_QUERY );
286 Reference< XAnimateTransform > xAnimateTransform( xNode, UNO_QUERY );
287 Reference< XCommand > xCommand( xNode, UNO_QUERY );
288 Reference< XIterateContainer > xIterateContainer( xNode, UNO_QUERY );
289 sal_Int16 nInt16 = 0;
290 bool bBool = false;
291 double fDouble = 0;
292 OUString sString;
293 Sequence< NamedValue > aSeq;
295 for( int i = 0; i < NP_SIZE_; i++)
297 Any & aValue( maNodeProperties[ i ] );
298 if( aValue.hasValue() )
300 switch( i )
302 case NP_TO:
303 if( xAnimate.is() )
304 xAnimate->setTo( aValue );
305 break;
306 case NP_FROM:
307 if( xAnimate.is() )
308 xAnimate->setFrom( aValue );
309 break;
310 case NP_BY:
311 if( xAnimate.is() )
312 xAnimate->setBy( aValue );
313 break;
314 case NP_TARGET:
315 if( xAnimate.is() )
316 xAnimate->setTarget( aValue );
317 break;
318 case NP_SUBITEM:
319 if( xAnimate.is() )
321 if( aValue >>= nInt16 )
322 xAnimate->setSubItem( nInt16 );
323 else
325 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
328 break;
329 case NP_ATTRIBUTENAME:
330 if( xAnimate.is() )
332 if( aValue >>= sString )
333 xAnimate->setAttributeName( sString );
334 else
336 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
339 break;
340 case NP_CALCMODE:
341 if( xAnimate.is() )
343 if( aValue >>= nInt16 )
344 xAnimate->setCalcMode( nInt16 );
345 else
347 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
350 break;
351 case NP_KEYTIMES:
352 if( xAnimate.is() )
354 Sequence<double> aKeyTimes;
355 if( aValue >>= aKeyTimes )
356 xAnimate->setKeyTimes(aKeyTimes);
357 else
359 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
362 break;
363 case NP_VALUES:
364 if( xAnimate.is() )
366 Sequence<Any> aValues;
367 if( aValue >>= aValues )
368 xAnimate->setValues(aValues);
369 else
371 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
374 break;
375 case NP_FORMULA:
376 if( xAnimate.is() )
378 if( aValue >>= sString )
379 xAnimate->setFormula(sString);
380 else
382 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
385 break;
386 case NP_COLORINTERPOLATION:
387 if( xAnimateColor.is() )
389 if( aValue >>= nInt16 )
390 xAnimateColor->setColorInterpolation( nInt16 );
391 else
393 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
396 break;
397 case NP_DIRECTION:
398 if( xAnimateColor.is() )
400 if( aValue >>= bBool )
401 xAnimateColor->setDirection( bBool );
402 else
404 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
407 break;
408 case NP_PATH:
409 if( xAnimateMotion.is() )
410 xAnimateMotion->setPath( aValue );
411 break;
412 case NP_TRANSFORMTYPE:
413 if( xAnimateTransform.is() )
415 if( aValue >>= nInt16 )
416 xAnimateTransform->setTransformType( nInt16 );
417 else
419 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
422 break;
423 case NP_USERDATA:
424 if( aValue >>= aSeq )
425 xNode->setUserData( aSeq );
426 else
428 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
430 break;
431 case NP_ACCELERATION:
432 if( aValue >>= fDouble )
433 xNode->setAcceleration( fDouble );
434 else
436 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
438 break;
439 case NP_DECELERATE:
440 if( aValue >>= fDouble )
441 xNode->setDecelerate( fDouble );
442 else
444 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
446 break;
447 case NP_AUTOREVERSE:
448 if( aValue >>= bBool )
449 xNode->setAutoReverse( bBool );
450 else
452 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
454 break;
455 case NP_DURATION:
456 xNode->setDuration( aValue );
457 break;
458 case NP_FILL:
459 if( aValue >>= nInt16 )
460 xNode->setFill( nInt16 );
461 else
463 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
465 break;
466 case NP_REPEATCOUNT:
467 xNode->setRepeatCount( aValue );
468 break;
469 case NP_REPEATDURATION:
470 xNode->setRepeatDuration( aValue );
471 break;
472 case NP_RESTART:
473 if( aValue >>= nInt16 )
474 xNode->setRestart( nInt16 );
475 else
477 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
479 break;
480 case NP_COMMAND:
481 if( xCommand.is() )
483 if( aValue >>= nInt16 )
484 xCommand->setCommand( nInt16 );
485 else
487 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
490 break;
491 case NP_PARAMETER:
492 if( xCommand.is() )
493 xCommand->setParameter( aValue );
494 break;
495 case NP_ITERATETYPE:
496 if( xIterateContainer.is() )
498 if( aValue >>= nInt16 )
499 xIterateContainer->setIterateType( nInt16 );
500 else
502 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
505 break;
506 case NP_ITERATEINTERVAL:
507 if( xIterateContainer.is() )
509 if( aValue >>= fDouble )
510 xIterateContainer->setIterateInterval( fDouble );
511 else
513 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
516 break;
517 default:
518 SAL_INFO("oox.ppt","ERR-OOX: unknown prop index " << i );
519 break;
524 if( mnNodeType == AnimationNodeType::TRANSITIONFILTER )
527 Reference< XTransitionFilter > xFilter( xNode, UNO_QUERY );
528 maTransitionFilter.setTransitionFilterProperties( xFilter );
531 std::for_each(
532 maChildren.begin(), maChildren.end(),
533 [&rFilter, &xNode, &pSlide] (TimeNodePtr const & child) {
534 child->addNode(rFilter, xNode, pSlide);
535 } );
537 switch( mnNodeType )
539 case AnimationNodeType::SEQ:
541 sal_Int16 nEnum = 0;
542 if( maUserData[ "node-type" ] >>= nEnum )
544 if( nEnum == EffectNodeType::MAIN_SEQUENCE )
546 fixMainSequenceTiming( xNode );
548 else if( nEnum == EffectNodeType::INTERACTIVE_SEQUENCE )
550 fixInteractiveSequenceTiming( xNode );
553 break;
555 case AnimationNodeType::PAR:
556 // some other cut&paste... from AnimationImporter::importAnimationContainer()
557 break;
560 catch( const Exception& e )
562 SAL_INFO("oox.ppt","OOX: exception raised in TimeNode::setNode() - " << e.Message );
566 Reference< XAnimationNode > TimeNode::createAndInsert(
567 const XmlFilterBase& rFilter,
568 const OUString& rServiceName,
569 const Reference< XAnimationNode >& rxNode )
571 try {
572 Reference< XAnimationNode > xNode( Reference<css::lang::XMultiServiceFactory>(rFilter.getComponentContext()->getServiceManager(), UNO_QUERY_THROW)->createInstance( rServiceName ), UNO_QUERY_THROW );
573 Reference< XTimeContainer > xParentContainer( rxNode, UNO_QUERY_THROW );
575 xParentContainer->appendChild( xNode );
576 return xNode;
578 catch( const Exception& e )
580 SAL_INFO("oox.ppt", "OOX: exception raised in TimeNode::createAndInsert() trying to create a service " << rServiceName << " = " << e.Message );
583 return Reference< XAnimationNode >();
586 void TimeNode::setId( sal_Int32 nId )
588 msId = OUString::number(nId);
591 void TimeNode::setTo( const Any & aTo )
593 maNodeProperties[ NP_TO ] = aTo;
596 void TimeNode::setFrom( const Any & aFrom )
598 maNodeProperties[ NP_FROM ] = aFrom;
601 void TimeNode::setBy( const Any & aBy )
603 maNodeProperties[ NP_BY ] = aBy;
608 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */