diff options
author | Mark Hung <marklh9@gmail.com> | 2018-08-03 23:59:54 +0800 |
---|---|---|
committer | Mark Hung <marklh9@gmail.com> | 2018-08-06 15:15:30 +0200 |
commit | a472d3352a61b51624aea480410789e3f547a9ca (patch) | |
tree | 0dce2c14ba914d0422e2a61f4b0e726c48d181cb | |
parent | df1d4bd528027c60bcab2f2e0a87303610fad326 (diff) |
tdf#113822 handle letter-by-letter animations in pptx documents.
Unlike odp that has anim:iterate (IterateContainer) node,
both parallel time container and interate container appear
as p:par in ooxml so that we have to alter the node type
in the end. We also have to set the target of the iterate
container to make animation work.
Change-Id: Ic50b5f1d85716a67712ed1e812bcb0e7f25fb5a8
Reviewed-on: https://gerrit.libreoffice.org/58576
Tested-by: Jenkins
Reviewed-by: Mark Hung <marklh9@gmail.com>
-rw-r--r-- | include/oox/ppt/timenode.hxx | 3 | ||||
-rw-r--r-- | oox/source/ppt/slidepersist.cxx | 3 | ||||
-rw-r--r-- | oox/source/ppt/timenode.cxx | 33 | ||||
-rw-r--r-- | sd/qa/unit/export-tests.cxx | 9 |
4 files changed, 38 insertions, 10 deletions
diff --git a/include/oox/ppt/timenode.hxx b/include/oox/ppt/timenode.hxx index 1aee1a893ed3..d4794ae96dee 100644 --- a/include/oox/ppt/timenode.hxx +++ b/include/oox/ppt/timenode.hxx @@ -75,7 +75,8 @@ namespace oox { namespace ppt { void setNode( const ::oox::core::XmlFilterBase& rFilter, const css::uno::Reference< css::animations::XAnimationNode >& xNode, - const SlidePersistPtr & pSlide ); + const SlidePersistPtr & pSlide, + const css::uno::Reference< css::animations::XAnimationNode >& xParent); AnimTargetElementPtr const & getTarget() { diff --git a/oox/source/ppt/slidepersist.cxx b/oox/source/ppt/slidepersist.cxx index 4f337500761c..f56bee7469a1 100644 --- a/oox/source/ppt/slidepersist.cxx +++ b/oox/source/ppt/slidepersist.cxx @@ -157,7 +157,8 @@ void SlidePersist::createXShapes( XmlFilterBase& rFilterBase ) TimeNodePtr pNode(maTimeNodeList.front()); OSL_ENSURE( pNode, "pNode" ); - pNode->setNode( rFilterBase, xNode, pSlidePtr ); + Reference<XAnimationNode> xDummy; + pNode->setNode(rFilterBase, xNode, pSlidePtr, xDummy); } } } diff --git a/oox/source/ppt/timenode.cxx b/oox/source/ppt/timenode.cxx index f695d7918b96..854797a9649c 100644 --- a/oox/source/ppt/timenode.cxx +++ b/oox/source/ppt/timenode.cxx @@ -66,6 +66,9 @@ namespace oox { namespace ppt { case AnimationNodeType::ANIMATE: sServiceName = "com.sun.star.animations.Animate"; break; + case AnimationNodeType::ITERATE: + sServiceName = "com.sun.star.animations.IterateContainer"; + break; case AnimationNodeType::ANIMATECOLOR: sServiceName = "com.sun.star.animations.AnimateColor"; break; @@ -194,9 +197,15 @@ namespace oox { namespace ppt { void TimeNode::addNode( const XmlFilterBase& rFilter, const Reference< XAnimationNode >& rxNode, const SlidePersistPtr & pSlide ) { try { - OUString sServiceName = getServiceName( mnNodeType ); + sal_Int16 nNodeType = mnNodeType; + + if (mnNodeType == AnimationNodeType::PAR && maNodeProperties[NP_ITERATETYPE].hasValue()) + nNodeType = AnimationNodeType::ITERATE; + + OUString sServiceName = getServiceName(nNodeType); + Reference< XAnimationNode > xNode = createAndInsert( rFilter, sServiceName, rxNode ); - setNode( rFilter, xNode, pSlide ); + setNode(rFilter, xNode, pSlide, rxNode); } catch( const Exception& e ) { @@ -204,7 +213,7 @@ namespace oox { namespace ppt { } } - void TimeNode::setNode( const XmlFilterBase& rFilter, const Reference< XAnimationNode >& xNode, const SlidePersistPtr & pSlide ) + void TimeNode::setNode(const XmlFilterBase& rFilter, const Reference< XAnimationNode >& xNode, const SlidePersistPtr & pSlide, const Reference<XAnimationNode>& xParent) { SAL_WARN_IF( !xNode.is(), "oox.ppt", "null node passed" ); @@ -310,10 +319,20 @@ namespace oox { namespace ppt { xAnimate->setBy( aValue ); break; case NP_TARGET: - if (xAnimate.is()) - xAnimate->setTarget(aValue); - if (xCommand.is()) - xCommand->setTarget(aValue); + + if (xParent.is() && xParent->getType() == AnimationNodeType::ITERATE) + { + Reference<XIterateContainer> xParentContainer(xParent, UNO_QUERY); + if (xParentContainer.is()) + xParentContainer->setTarget(aValue); + } + else + { + if (xAnimate.is()) + xAnimate->setTarget(aValue); + if (xCommand.is()) + xCommand->setTarget(aValue); + } break; case NP_SUBITEM: if( xAnimate.is() ) diff --git a/sd/qa/unit/export-tests.cxx b/sd/qa/unit/export-tests.cxx index e92d95f934c8..0e5b8f563df9 100644 --- a/sd/qa/unit/export-tests.cxx +++ b/sd/qa/unit/export-tests.cxx @@ -1108,7 +1108,14 @@ void SdExportTest::testTdf113822() xDocShRef = saveAndReload(xDocShRef.get(), ODP, &tempFile); xmlDocPtr pXmlDoc = parseExport(tempFile, "content.xml"); - assertXPath(pXmlDoc, "//anim:set[1]", "to", "solid"); + + // IterateContainer was created as ParallelTimeContainer before, so + // the iterate type is not set too. + assertXPath(pXmlDoc, "//anim:iterate", "iterate-type", "by-letter"); + // The target of the child animation nodes need to be in the iterate container. + assertXPath(pXmlDoc, "//anim:iterate", "targetElement", "id1"); + assertXPath(pXmlDoc, "//anim:iterate/anim:set", "attributeName", "text-underline"); + assertXPath(pXmlDoc, "//anim:iterate/anim:set", "to", "solid"); xDocShRef->DoClose(); } |