diff options
author | Mark Hung <marklh9@gmail.com> | 2018-09-01 11:11:38 +0800 |
---|---|---|
committer | Mark Hung <marklh9@gmail.com> | 2018-09-07 13:11:41 +0200 |
commit | 612db6877a73e6f9b142b81697291f02c0adb95f (patch) | |
tree | 6f2d79aacd1483c230a7146bddd303dadf15e50f /sd/source | |
parent | c3c43c7966e0f4c7a3b76361559d29c9335487d9 (diff) |
tdf#99213: don't export invalid child nodes.
Create NodeContext for all child nodes at beginning and
check if they are valid, either it has a valid target or
it contains valid nodes, so that we only export valid
node later.
Change-Id: I660d99011eb57ddc79f727455fce0be8876e8b17
Reviewed-on: https://gerrit.libreoffice.org/59892
Tested-by: Jenkins
Reviewed-by: Mark Hung <marklh9@gmail.com>
Diffstat (limited to 'sd/source')
-rw-r--r-- | sd/source/filter/eppt/pptx-animations.cxx | 143 |
1 files changed, 111 insertions, 32 deletions
diff --git a/sd/source/filter/eppt/pptx-animations.cxx b/sd/source/filter/eppt/pptx-animations.cxx index 7a64828ddfd1..b02ccdcc4cb7 100644 --- a/sd/source/filter/eppt/pptx-animations.cxx +++ b/sd/source/filter/eppt/pptx-animations.cxx @@ -410,6 +410,21 @@ void WriteAnimationAttributeName(const FSHelperPtr& pFS, const OUString& rAttrib pFS->endElementNS(XML_p, XML_attrNameLst); } +bool isValidTarget(const Any& rTarget) +{ + Reference<XShape> xShape; + + if ((rTarget >>= xShape) && xShape.is()) + return true; + + ParagraphTarget aParagraphTarget; + + if ((rTarget >>= aParagraphTarget) && aParagraphTarget.Shape.is()) + return true; + + return false; +} + /// convert animation node type to corresponding ooxml element. sal_Int32 convertNodeType(sal_Int16 nType) { @@ -575,9 +590,13 @@ typedef std::unique_ptr<NodeContext> NodeContextPtr; class NodeContext { - const Reference<XAnimationNode>& mxNode; + const Reference<XAnimationNode> mxNode; const bool mbMainSeqChild; + std::vector<NodeContextPtr> maChildNodes; + // if the node has valid target or contains at least one valid target. + bool mbValid; + // Attributes initialized from mxNode->getUserData(). sal_Int16 mnEffectNodeType; sal_Int16 mnEffectPresetClass; @@ -587,14 +606,23 @@ class NodeContext /// constructor helper for initializing user datas. void initUserData(); + /// constructor helper to initialize maChildNodes. + /// return true if at least one childnode is valid. + bool initChildNodes(); + + /// constructor helper to initialize mbValid + void initValid(bool bHasValidChild, bool bIsIterateChild); + public: - NodeContext(const Reference<XAnimationNode>& xNode, bool bMainSeqChild); + NodeContext(const Reference<XAnimationNode>& xNode, bool bMainSeqChild, bool bIsIterateChild); const Reference<XAnimationNode>& getNode() const { return mxNode; } bool isMainSeqChild() const { return mbMainSeqChild; } sal_Int16 getEffectNodeType() const { return mnEffectNodeType; } sal_Int16 getEffectPresetClass() const { return mnEffectPresetClass; } const OUString& getEffectPresetId() const { return msEffectPresetId; } const OUString& getEffectPresetSubType() const { return msEffectPresetSubType; } + bool isValid() const { return mbValid; } + const std::vector<NodeContextPtr>& getChildNodes() const { return maChildNodes; }; }; class PPTXAnimationExport @@ -1014,34 +1042,17 @@ void PPTXAnimationExport::WriteAnimationNodeCommonPropsStart() } } - Reference<XEnumerationAccess> xEnumerationAccess(rXNode, UNO_QUERY); - if (xEnumerationAccess.is()) + const std::vector<NodeContextPtr>& aChildNodes = mpContext->getChildNodes(); + if (!aChildNodes.empty()) { - Reference<XEnumeration> xEnumeration(xEnumerationAccess->createEnumeration(), UNO_QUERY); - if (xEnumeration.is()) + mpFS->startElementNS(XML_p, XML_childTnLst, FSEND); + for (const NodeContextPtr& pChildContext : aChildNodes) { - SAL_INFO("sd.eppt", "-----"); - - if (xEnumeration->hasMoreElements()) - { - mpFS->startElementNS(XML_p, XML_childTnLst, FSEND); - - do - { - Reference<XAnimationNode> xChildNode(xEnumeration->nextElement(), UNO_QUERY); - if (xChildNode.is()) - { - WriteAnimationNode(o3tl::make_unique<NodeContext>( - xChildNode, nType == EffectNodeType::MAIN_SEQUENCE)); - } - } while (xEnumeration->hasMoreElements()); - - mpFS->endElementNS(XML_p, XML_childTnLst); - } - SAL_INFO("sd.eppt", "-----"); + if (pChildContext->isValid()) + WriteAnimationNode(pChildContext); } + mpFS->endElementNS(XML_p, XML_childTnLst); } - mpFS->endElementNS(XML_p, XML_cTn); } @@ -1190,26 +1201,36 @@ void PPTXAnimationExport::WriteAnimations(const Reference<XDrawPage>& rXDrawPage UNO_QUERY); if (xEnumeration.is() && xEnumeration->hasMoreElements()) { - mpFS->startElementNS(XML_p, XML_timing, FSEND); - mpFS->startElementNS(XML_p, XML_tnLst, FSEND); + auto pNodeContext = o3tl::make_unique<NodeContext>(xNode, false, false); + if (pNodeContext->isValid()) + { + mpFS->startElementNS(XML_p, XML_timing, FSEND); + mpFS->startElementNS(XML_p, XML_tnLst, FSEND); - WriteAnimationNode(o3tl::make_unique<NodeContext>(xNode, false)); + WriteAnimationNode(pNodeContext); - mpFS->endElementNS(XML_p, XML_tnLst); - mpFS->endElementNS(XML_p, XML_timing); + mpFS->endElementNS(XML_p, XML_tnLst); + mpFS->endElementNS(XML_p, XML_timing); + } } } } } } -NodeContext::NodeContext(const Reference<XAnimationNode>& xNode, bool bMainSeqChild) +NodeContext::NodeContext(const Reference<XAnimationNode>& xNode, bool bMainSeqChild, + bool bIsIterateChild) : mxNode(xNode) , mbMainSeqChild(bMainSeqChild) + , mbValid(true) , mnEffectNodeType(-1) , mnEffectPresetClass(DFF_ANIM_PRESS_CLASS_USER_DEFINED) { + assert(xNode.is()); + initUserData(); + + initValid(initChildNodes(), bIsIterateChild); } void NodeContext::initUserData() @@ -1237,4 +1258,62 @@ void NodeContext::initUserData() *pAny >>= msEffectPresetSubType; } +void NodeContext::initValid(bool bHasValidChild, bool bIsIterateChild) +{ + sal_Int16 nType = mxNode->getType(); + + if (nType == AnimationNodeType::ITERATE) + { + Reference<XIterateContainer> xIterate(mxNode, UNO_QUERY); + mbValid = xIterate.is() && (bIsIterateChild || isValidTarget(xIterate->getTarget())) + && maChildNodes.size(); + } + else if (nType == AnimationNodeType::COMMAND) + { + Reference<XCommand> xCommand(mxNode, UNO_QUERY); + mbValid = xCommand.is() && (bIsIterateChild || isValidTarget(xCommand->getTarget())); + } + else if (nType == AnimationNodeType::PAR || nType == AnimationNodeType::SEQ) + { + mbValid = bHasValidChild; + } + else if (nType == AnimationNodeType::AUDIO) + { + SAL_WARN("sd.eppt", "Export AUDIO node is not supported yet."); + mbValid = false; + } + else + { + Reference<XAnimate> xAnimate(mxNode, UNO_QUERY); + mbValid = xAnimate.is() && (bIsIterateChild || isValidTarget(xAnimate->getTarget())); + } +} + +bool NodeContext::initChildNodes() +{ + bool bValid = false; + Reference<XEnumerationAccess> xEnumerationAccess(mxNode, UNO_QUERY); + if (xEnumerationAccess.is()) + { + Reference<XEnumeration> xEnumeration(xEnumerationAccess->createEnumeration(), UNO_QUERY); + bool bIsMainSeq = mnEffectNodeType == EffectNodeType::MAIN_SEQUENCE; + bool bIsIterateChild = mxNode->getType() == AnimationNodeType::ITERATE; + if (xEnumeration.is()) + { + while (xEnumeration->hasMoreElements()) + { + Reference<XAnimationNode> xChildNode(xEnumeration->nextElement(), UNO_QUERY); + if (xChildNode.is()) + { + auto pChildContext + = o3tl::make_unique<NodeContext>(xChildNode, bIsMainSeq, bIsIterateChild); + if (pChildContext->isValid()) + bValid = true; + maChildNodes.push_back(std::move(pChildContext)); + } + } + } + } + return bValid; +} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |