summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Hung <marklh9@gmail.com>2018-08-03 23:59:54 +0800
committerMark Hung <marklh9@gmail.com>2018-08-06 15:15:30 +0200
commita472d3352a61b51624aea480410789e3f547a9ca (patch)
tree0dce2c14ba914d0422e2a61f4b0e726c48d181cb
parentdf1d4bd528027c60bcab2f2e0a87303610fad326 (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.hxx3
-rw-r--r--oox/source/ppt/slidepersist.cxx3
-rw-r--r--oox/source/ppt/timenode.cxx33
-rw-r--r--sd/qa/unit/export-tests.cxx9
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();
}