Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / oox / source / ppt / timenode.cxx
blob3c59b54c9cdc19f66f88969bc641632a7e385d5a
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/animations/XAnimateColor.hpp>
27 #include <com/sun/star/animations/XAnimateMotion.hpp>
28 #include <com/sun/star/animations/XAnimateTransform.hpp>
29 #include <com/sun/star/animations/XCommand.hpp>
30 #include <com/sun/star/animations/XAudio.hpp>
31 #include <com/sun/star/animations/XIterateContainer.hpp>
32 #include <com/sun/star/animations/XTimeContainer.hpp>
33 #include <com/sun/star/animations/XTransitionFilter.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 <oox/ppt/pptfilterhelpers.hxx>
43 #include <oox/token/tokens.hxx>
44 #include <sal/log.hxx>
45 #include <tools/diagnose_ex.h>
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::presentation;
55 namespace oox { namespace ppt {
57 OUString TimeNode::getServiceName( sal_Int16 nNodeType )
59 OUString sServiceName;
60 switch( nNodeType )
62 case AnimationNodeType::PAR:
63 sServiceName = "com.sun.star.animations.ParallelTimeContainer";
64 break;
65 case AnimationNodeType::SEQ:
66 sServiceName = "com.sun.star.animations.SequenceTimeContainer";
67 break;
68 case AnimationNodeType::ANIMATE:
69 sServiceName = "com.sun.star.animations.Animate";
70 break;
71 case AnimationNodeType::ITERATE:
72 sServiceName = "com.sun.star.animations.IterateContainer";
73 break;
74 case AnimationNodeType::ANIMATECOLOR:
75 sServiceName = "com.sun.star.animations.AnimateColor";
76 break;
77 case AnimationNodeType::TRANSITIONFILTER:
78 sServiceName = "com.sun.star.animations.TransitionFilter";
79 break;
80 case AnimationNodeType::ANIMATEMOTION:
81 sServiceName = "com.sun.star.animations.AnimateMotion";
82 break;
83 case AnimationNodeType::ANIMATETRANSFORM:
84 sServiceName = "com.sun.star.animations.AnimateTransform";
85 break;
86 case AnimationNodeType::COMMAND:
87 sServiceName = "com.sun.star.animations.Command";
88 break;
89 case AnimationNodeType::SET:
90 sServiceName = "com.sun.star.animations.AnimateSet";
91 break;
92 case AnimationNodeType::AUDIO:
93 sServiceName = "com.sun.star.animations.Audio";
94 break;
95 default:
96 SAL_INFO("oox.ppt","OOX: uhandled type " << nNodeType );
97 break;
99 return sServiceName;
102 TimeNode::TimeNode( sal_Int16 nNodeType )
103 : mnNodeType( nNodeType )
104 , mbHasEndSyncValue( false )
108 TimeNode::~TimeNode()
112 void fixMainSequenceTiming( const css::uno::Reference< css::animations::XAnimationNode >& xNode )
116 bool bFirst = true;
117 Reference< XEnumerationAccess > xEA( xNode, UNO_QUERY_THROW );
118 Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_SET_THROW );
119 while( xE->hasMoreElements() )
121 // click node
122 Reference< XAnimationNode > xClickNode( xE->nextElement(), UNO_QUERY );
124 Event aEvent;
125 aEvent.Trigger = EventTrigger::ON_NEXT;
126 aEvent.Repeat = 0;
127 xClickNode->setBegin( makeAny( aEvent ) );
129 if( bFirst )
131 bFirst = false;
132 Reference< XEnumerationAccess > xEA2( xClickNode, UNO_QUERY_THROW );
133 Reference< XEnumeration > xE2( xEA2->createEnumeration(), UNO_SET_THROW );
134 if( xE2->hasMoreElements() )
136 // with node
137 xE2->nextElement() >>= xEA2;
138 if( xEA2.is() )
139 xE2 = xEA2->createEnumeration();
140 else
141 xE2.clear();
143 if( xE2.is() && xE2->hasMoreElements() )
145 Reference< XAnimationNode > xEffectNode( xE2->nextElement(), UNO_QUERY_THROW );
146 const Sequence< NamedValue > aUserData( xEffectNode->getUserData() );
147 for( const NamedValue& rProp : aUserData )
149 if ( rProp.Name == "node-type" )
151 sal_Int16 nNodeType = 0;
152 rProp.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;
167 catch( Exception& )
169 SAL_INFO("oox.ppt","fixMainSequenceTiming(), exception caught!" );
173 void fixInteractiveSequenceTiming( const css::uno::Reference< css::animations::XAnimationNode >& xNode )
177 Any aBegin( xNode->getBegin() );
178 Any aEmpty;
179 xNode->setBegin( aEmpty );
181 Reference< XEnumerationAccess > xEA( xNode, UNO_QUERY_THROW );
182 Reference< XEnumeration > xE( xEA->createEnumeration(), UNO_SET_THROW );
183 while( xE->hasMoreElements() )
185 // click node
186 Reference< XAnimationNode > xClickNode( xE->nextElement(), UNO_QUERY );
187 xClickNode->setBegin( aBegin );
190 catch( Exception& )
192 SAL_INFO("oox.ppt","fixInteractiveSequenceTiming(), exception caught!" );
196 void TimeNode::addNode( const XmlFilterBase& rFilter, const Reference< XAnimationNode >& rxNode, const SlidePersistPtr & pSlide )
198 try {
199 sal_Int16 nNodeType = mnNodeType;
201 if (mnNodeType == AnimationNodeType::PAR && maNodeProperties[NP_ITERATETYPE].hasValue())
202 nNodeType = AnimationNodeType::ITERATE;
204 OUString sServiceName = getServiceName(nNodeType);
206 Reference< XAnimationNode > xNode = createAndInsert( rFilter, sServiceName, rxNode );
207 if (!xNode)
208 return;
209 setNode(rFilter, xNode, pSlide, rxNode);
211 catch( const Exception& )
213 TOOLS_INFO_EXCEPTION("oox.ppt","OOX: exception raised in TimeNode::addNode()" );
217 void TimeNode::setNode(const XmlFilterBase& rFilter, const Reference< XAnimationNode >& xNode, const SlidePersistPtr & pSlide, const Reference<XAnimationNode>& xParent)
219 SAL_WARN_IF( !xNode.is(), "oox.ppt", "null node passed" );
221 try {
222 if( !msId.isEmpty() )
224 pSlide->getAnimNodesMap()[ msId ] = xNode;
227 if( mpTarget )
229 sal_Int16 nSubType(0);
230 maNodeProperties[ NP_TARGET ] = mpTarget->convert( pSlide, nSubType );
231 if( mpTarget->mnType == XML_spTgt )
233 maNodeProperties[ NP_SUBITEM ] <<= nSubType;
237 if( !maStCondList.empty() )
239 Any aAny = AnimationCondition::convertList( pSlide, maStCondList );
240 if( aAny.hasValue() )
242 xNode->setBegin( aAny );
246 if( !maEndCondList.empty() )
248 Any aAny = AnimationCondition::convertList( pSlide, maEndCondList );
249 if( aAny.hasValue() )
251 xNode->setEnd( aAny );
254 #if 0 // FIXME even the binary filter has this disabled.
255 if( !maNextCondList.empty() )
257 Any aAny = AnimationCondition::convertList( pSlide, maNextCondList );
258 if( aAny.hasValue() )
260 xNode->setNext( aAny );
263 if( !maPrevCondList.empty() )
265 Any aAny = AnimationCondition::convertList( pSlide, maPrevCondList );
266 if( aAny.hasValue() )
268 xNode->setPrev( aAny );
271 #endif
272 if( mbHasEndSyncValue )
274 Any aValue = maEndSyncValue.convert( pSlide );
275 xNode->setEndSync(aValue);
278 if( !maUserData.empty() )
280 Sequence< NamedValue > aUserDataSeq( static_cast< sal_Int32 >( maUserData.size() ) );
281 NamedValue* pValues = aUserDataSeq.getArray();
282 for (auto const& elem : maUserData)
284 pValues->Name = elem.first;
285 pValues->Value = elem.second;
286 ++pValues;
288 maNodeProperties[ NP_USERDATA ] <<= aUserDataSeq;
291 Reference< XAnimate > xAnimate( xNode, UNO_QUERY );
292 Reference< XAnimateColor > xAnimateColor( xNode, UNO_QUERY );
293 Reference< XAnimateMotion > xAnimateMotion( xNode, UNO_QUERY );
294 Reference< XAnimateTransform > xAnimateTransform( xNode, UNO_QUERY );
295 Reference< XCommand > xCommand( xNode, UNO_QUERY );
296 Reference< XAudio > xAudio( xNode, UNO_QUERY );
297 Reference< XIterateContainer > xIterateContainer( xNode, UNO_QUERY );
298 sal_Int16 nInt16 = 0;
299 bool bBool = false;
300 double fDouble = 0;
301 OUString sString;
302 Sequence< NamedValue > aSeq;
304 for( int i = 0; i < NP_SIZE_; i++)
306 Any & aValue( maNodeProperties[ i ] );
307 if( aValue.hasValue() )
309 switch( i )
311 case NP_TO:
312 if( xAnimate.is() )
313 xAnimate->setTo( aValue );
314 break;
315 case NP_FROM:
316 if( xAnimate.is() )
317 xAnimate->setFrom( aValue );
318 break;
319 case NP_BY:
320 if( xAnimate.is() )
321 xAnimate->setBy( aValue );
322 break;
323 case NP_TARGET:
325 if (xParent.is() && xParent->getType() == AnimationNodeType::ITERATE)
327 Reference<XIterateContainer> xParentContainer(xParent, UNO_QUERY);
328 if (xParentContainer.is())
329 xParentContainer->setTarget(aValue);
331 else
333 if (xAnimate.is())
334 xAnimate->setTarget(aValue);
335 if (xCommand.is())
336 xCommand->setTarget(aValue);
337 if (xAudio.is())
338 xAudio->setSource(aValue);
340 break;
341 case NP_SUBITEM:
342 if( xAnimate.is() )
344 if( aValue >>= nInt16 )
345 xAnimate->setSubItem( nInt16 );
346 else
348 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
351 break;
352 case NP_ATTRIBUTENAME:
353 if( xAnimate.is() )
355 if( aValue >>= sString )
356 xAnimate->setAttributeName( sString );
357 else
359 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
362 break;
363 case NP_CALCMODE:
364 if( xAnimate.is() )
366 if( aValue >>= nInt16 )
367 xAnimate->setCalcMode( nInt16 );
368 else
370 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
373 break;
374 case NP_KEYTIMES:
375 if( xAnimate.is() )
377 Sequence<double> aKeyTimes;
378 if( aValue >>= aKeyTimes )
379 xAnimate->setKeyTimes(aKeyTimes);
380 else
382 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
385 break;
386 case NP_VALUES:
387 if( xAnimate.is() )
389 Sequence<Any> aValues;
390 if( aValue >>= aValues )
391 xAnimate->setValues(aValues);
392 else
394 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
397 break;
398 case NP_FORMULA:
399 if( xAnimate.is() )
401 if( aValue >>= sString )
402 xAnimate->setFormula(sString);
403 else
405 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
408 break;
409 case NP_COLORINTERPOLATION:
410 if( xAnimateColor.is() )
412 if( aValue >>= nInt16 )
413 xAnimateColor->setColorInterpolation( nInt16 );
414 else
416 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
419 break;
420 case NP_DIRECTION:
421 if( xAnimateColor.is() )
423 if( aValue >>= bBool )
424 xAnimateColor->setDirection( bBool );
425 else
427 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
430 break;
431 case NP_PATH:
432 if( xAnimateMotion.is() )
433 xAnimateMotion->setPath( aValue );
434 break;
435 case NP_TRANSFORMTYPE:
436 if( xAnimateTransform.is() )
438 if( aValue >>= nInt16 )
439 xAnimateTransform->setTransformType( nInt16 );
440 else
442 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
445 break;
446 case NP_USERDATA:
447 if( aValue >>= aSeq )
448 xNode->setUserData( aSeq );
449 else
451 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
453 break;
454 case NP_ACCELERATION:
455 if( aValue >>= fDouble )
456 xNode->setAcceleration( fDouble );
457 else
459 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
461 break;
462 case NP_DECELERATE:
463 if( aValue >>= fDouble )
464 xNode->setDecelerate( fDouble );
465 else
467 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
469 break;
470 case NP_AUTOREVERSE:
471 if( aValue >>= bBool )
472 xNode->setAutoReverse( bBool );
473 else
475 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
477 break;
478 case NP_DURATION:
479 xNode->setDuration( aValue );
480 break;
481 case NP_FILL:
482 if( aValue >>= nInt16 )
483 xNode->setFill( nInt16 );
484 else
486 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
488 break;
489 case NP_REPEATCOUNT:
490 xNode->setRepeatCount( aValue );
491 break;
492 case NP_REPEATDURATION:
493 xNode->setRepeatDuration( aValue );
494 break;
495 case NP_RESTART:
496 if( aValue >>= nInt16 )
497 xNode->setRestart( nInt16 );
498 else
500 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
502 break;
503 case NP_COMMAND:
504 if( xCommand.is() )
506 if( aValue >>= nInt16 )
507 xCommand->setCommand( nInt16 );
508 else
510 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
513 break;
514 case NP_PARAMETER:
515 if( xCommand.is() )
516 xCommand->setParameter( aValue );
517 break;
518 case NP_ITERATETYPE:
519 if( xIterateContainer.is() )
521 if( aValue >>= nInt16 )
522 xIterateContainer->setIterateType( nInt16 );
523 else
525 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
528 break;
529 case NP_ITERATEINTERVAL:
530 if( xIterateContainer.is() )
532 if( aValue >>= fDouble )
533 xIterateContainer->setIterateInterval( fDouble );
534 else
536 SAL_INFO("oox.ppt","any >>= failed " << __LINE__ );
539 break;
540 default:
541 SAL_INFO("oox.ppt","ERR-OOX: unknown prop index " << i );
542 break;
547 if( mnNodeType == AnimationNodeType::TRANSITIONFILTER )
550 Reference< XTransitionFilter > xFilter( xNode, UNO_QUERY );
551 maTransitionFilter.setTransitionFilterProperties( xFilter );
554 std::for_each(
555 maChildren.begin(), maChildren.end(),
556 [&rFilter, &xNode, &pSlide] (TimeNodePtr const & child) {
557 child->addNode(rFilter, xNode, pSlide);
558 } );
560 switch( mnNodeType )
562 case AnimationNodeType::SEQ:
564 sal_Int16 nEnum = 0;
565 if( maUserData[ "node-type" ] >>= nEnum )
567 if( nEnum == EffectNodeType::MAIN_SEQUENCE )
569 fixMainSequenceTiming( xNode );
571 else if( nEnum == EffectNodeType::INTERACTIVE_SEQUENCE )
573 fixInteractiveSequenceTiming( xNode );
576 break;
578 case AnimationNodeType::PAR:
579 // some other cut&paste... from AnimationImporter::importAnimationContainer()
580 break;
583 catch( const Exception& )
585 TOOLS_INFO_EXCEPTION("oox.ppt","OOX: exception raised in TimeNode::setNode()");
589 Reference< XAnimationNode > TimeNode::createAndInsert(
590 const XmlFilterBase& rFilter,
591 const OUString& rServiceName,
592 const Reference< XAnimationNode >& rxNode )
594 try {
595 Reference< XAnimationNode > xNode( Reference<css::lang::XMultiServiceFactory>(rFilter.getComponentContext()->getServiceManager(), UNO_QUERY_THROW)->createInstance( rServiceName ), UNO_QUERY_THROW );
596 Reference< XTimeContainer > xParentContainer( rxNode, UNO_QUERY_THROW );
598 xParentContainer->appendChild( xNode );
599 return xNode;
601 catch( const Exception& )
603 TOOLS_INFO_EXCEPTION("oox.ppt", "OOX: exception raised in TimeNode::createAndInsert() trying to create a service " << rServiceName);
606 return Reference< XAnimationNode >();
609 void TimeNode::setId( sal_Int32 nId )
611 msId = OUString::number(nId);
614 void TimeNode::setTo( const Any & aTo )
616 maNodeProperties[ NP_TO ] = aTo;
619 void TimeNode::setFrom( const Any & aFrom )
621 maNodeProperties[ NP_FROM ] = aFrom;
624 void TimeNode::setBy( const Any & aBy )
626 maNodeProperties[ NP_BY ] = aBy;
631 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */