sd/Library_sd.mk                                  |    1 
 sd/source/filter/eppt/pptx-animations-nodectx.cxx |  188 ++++++++++++++++++++++
 sd/source/filter/eppt/pptx-animations-nodectx.hxx |   59 ++++++
 sd/source/filter/eppt/pptx-animations.cxx         |  184 ---------------------
 4 files changed, 250 insertions(+), 182 deletions(-)

New commits:
commit 55d4dc3a6b955e54ee73bc81807552a3b4d4a279
Author:     Mark Hung <mark...@gmail.com>
AuthorDate: Fri Jan 27 23:34:49 2023 +0800
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Sat Jan 28 18:57:59 2023 +0000

    sd/pptx-anmiations refactor NodeContext.
    
    Change-Id: I6439882884b3808dec91eaaede50856b0afdd278
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146293
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/sd/Library_sd.mk b/sd/Library_sd.mk
index 297c2bc23654..4ffb86b7d461 100644
--- a/sd/Library_sd.mk
+++ b/sd/Library_sd.mk
@@ -188,6 +188,7 @@ $(eval $(call gb_Library_add_exception_objects,sd,\
     sd/source/filter/eppt/pptx-epptooxml \
     sd/source/filter/eppt/pptx-animations \
     sd/source/filter/eppt/pptx-animations-cond \
+    sd/source/filter/eppt/pptx-animations-nodectx \
     sd/source/filter/eppt/pptx-grouptable \
     sd/source/filter/eppt/pptx-stylesheet \
     sd/source/filter/eppt/pptx-text \
diff --git a/sd/source/filter/eppt/pptx-animations-nodectx.cxx 
b/sd/source/filter/eppt/pptx-animations-nodectx.cxx
new file mode 100644
index 000000000000..0d5cabd49343
--- /dev/null
+++ b/sd/source/filter/eppt/pptx-animations-nodectx.cxx
@@ -0,0 +1,188 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "pptx-animations-nodectx.hxx"
+#include <com/sun/star/animations/AnimationNodeType.hpp>
+#include <com/sun/star/animations/XAnimate.hpp>
+#include <com/sun/star/animations/XAnimationNode.hpp>
+#include <com/sun/star/animations/XCommand.hpp>
+#include <com/sun/star/animations/XAudio.hpp>
+#include <com/sun/star/animations/XIterateContainer.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/presentation/EffectNodeType.hpp>
+#include <com/sun/star/presentation/EffectPresetClass.hpp>
+#include <com/sun/star/presentation/ParagraphTarget.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+#include <o3tl/any.hxx>
+using ::com::sun::star::beans::NamedValue;
+using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::drawing::XShape;
+
+using namespace ::com::sun::star::animations;
+using namespace ::com::sun::star::drawing;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::presentation;
+using namespace ::com::sun::star::uno;
+
+namespace oox::core
+{
+namespace
+{
+bool isValidTarget(const Any& rTarget)
+{
+    Reference<XShape> xShape;
+
+    if ((rTarget >>= xShape) && xShape.is())
+        return true;
+
+    ParagraphTarget aParagraphTarget;
+
+    return (rTarget >>= aParagraphTarget) && aParagraphTarget.Shape.is();
+}
+
+bool IsAudioURL(const OUString& rURL)
+{
+    return rURL.endsWithIgnoreAsciiCase(".wav") || 
rURL.endsWithIgnoreAsciiCase(".m4a");
+}
+
+/// Returns if rURL has an extension which is a video format.
+bool IsVideoURL(const OUString& rURL) { return 
rURL.endsWithIgnoreAsciiCase(".mp4"); }
+}
+
+NodeContext::NodeContext(const Reference<XAnimationNode>& xNode, bool 
bMainSeqChild,
+                         bool bIsIterateChild)
+    : mxNode(xNode)
+    , mbMainSeqChild(bMainSeqChild)
+    , mbValid(true)
+    , mnEffectNodeType(-1)
+    , mnEffectPresetClass(css::presentation::EffectPresetClass::CUSTOM)
+{
+    assert(xNode.is());
+
+    initUserData();
+
+    initValid(initChildNodes(), bIsIterateChild);
+}
+
+void NodeContext::initUserData()
+{
+    assert(mxNode.is());
+
+    Sequence<NamedValue> aUserData = mxNode->getUserData();
+    for (const NamedValue& rProp : aUserData)
+    {
+        if (rProp.Name == "node-type")
+        {
+            rProp.Value >>= mnEffectNodeType;
+        }
+        else if (rProp.Name == "preset-class")
+        {
+            rProp.Value >>= mnEffectPresetClass;
+        }
+        else if (rProp.Name == "preset-id")
+        {
+            rProp.Value >>= msEffectPresetId;
+        }
+        else if (rProp.Name == "preset-sub-type")
+        {
+            rProp.Value >>= 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.empty();
+    }
+    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)
+    {
+        Reference<XAudio> xAudio(mxNode, UNO_QUERY);
+        OUString sURL;
+        Reference<XShape> xShape;
+        mbValid = false;
+        if (xAudio.is())
+        {
+            if (xAudio->getSource() >>= sURL)
+            {
+                mbValid = IsAudioURL(sURL);
+            }
+            else if (xAudio->getSource() >>= xShape)
+            {
+                Reference<XPropertySet> xShapeProps(xShape, UNO_QUERY);
+                bool bHasMediaURL
+                    = 
xShapeProps->getPropertySetInfo()->hasPropertyByName("MediaURL");
+                if (bHasMediaURL && (xShapeProps->getPropertyValue("MediaURL") 
>>= sURL))
+                {
+                    mbValid = IsAudioURL(sURL) || IsVideoURL(sURL);
+                }
+            }
+        }
+    }
+    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();
+        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
+                        = std::make_unique<NodeContext>(xChildNode, 
bIsMainSeq, bIsIterateChild);
+                    if (pChildContext->isValid())
+                        bValid = true;
+                    maChildNodes.push_back(std::move(pChildContext));
+                }
+            }
+        }
+    }
+    return bValid;
+}
+
+const Reference<XAnimationNode>& NodeContext::getNodeForCondition() const
+{
+    const bool bParent
+        = (mnEffectNodeType != EffectNodeType::INTERACTIVE_SEQUENCE || 
maChildNodes.empty());
+    const Reference<XAnimationNode>& rNode = bParent ? mxNode : 
maChildNodes[0]->getNode();
+    return rNode;
+}
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/filter/eppt/pptx-animations-nodectx.hxx 
b/sd/source/filter/eppt/pptx-animations-nodectx.hxx
new file mode 100644
index 000000000000..46a97c5a40cc
--- /dev/null
+++ b/sd/source/filter/eppt/pptx-animations-nodectx.hxx
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#pragma once
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/animations/XAnimationNode.hpp>
+#include <vector>
+
+namespace oox::core
+{
+class NodeContext;
+
+typedef std::unique_ptr<NodeContext> NodeContextPtr;
+
+class NodeContext
+{
+    const css::uno::Reference<css::animations::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;
+    OUString msEffectPresetId;
+    OUString msEffectPresetSubType;
+
+    /// constructor helper for initializing user data.
+    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 css::uno::Reference<css::animations::XAnimationNode>& 
xNode,
+                bool bMainSeqChild, bool bIsIterateChild);
+    const css::uno::Reference<css::animations::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; };
+    const css::uno::Reference<css::animations::XAnimationNode>& 
getNodeForCondition() const;
+};
+}
diff --git a/sd/source/filter/eppt/pptx-animations.cxx 
b/sd/source/filter/eppt/pptx-animations.cxx
index 77b4ea2282a7..bfe1079885e9 100644
--- a/sd/source/filter/eppt/pptx-animations.cxx
+++ b/sd/source/filter/eppt/pptx-animations.cxx
@@ -60,7 +60,7 @@
 #include "pptexanimations.hxx"
 #include "pptx-animations.hxx"
 #include "pptx-animations-cond.hxx"
-#include "../ppt/pptanimations.hxx"
+#include "pptx-animations-nodectx.hxx"
 
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::animations;
@@ -307,18 +307,6 @@ 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;
-
-    return (rTarget >>= aParagraphTarget) && aParagraphTarget.Shape.is();
-}
-
 /// extract ooxml node type from a XAnimationNode.
 sal_Int32 extractNodeType(const Reference<XAnimationNode>& rXNode)
 {
@@ -490,48 +478,6 @@ const char* convertTextAnimationType(sal_Int16 nType)
     return sType;
 }
 
-class NodeContext;
-
-typedef std::unique_ptr<NodeContext> NodeContextPtr;
-
-class NodeContext
-{
-    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;
-    OUString msEffectPresetId;
-    OUString msEffectPresetSubType;
-
-    /// constructor helper for initializing user data.
-    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, 
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; };
-    const Reference<XAnimationNode>& getNodeForCondition() const;
-};
-
 class PPTXAnimationExport
 {
     void WriteAnimationNode(const NodeContextPtr& pContext);
@@ -952,7 +898,7 @@ void 
PPTXAnimationExport::WriteAnimationNodeCommonPropsStart()
         sDuration = OString::number(static_cast<sal_Int32>(fDuration * 
1000.0));
 
     sal_uInt32 nPresetClass = mpContext->getEffectPresetClass();
-    if (nPresetClass != DFF_ANIM_PRESS_CLASS_USER_DEFINED)
+    if (nPresetClass != EffectPresetClass::CUSTOM)
         pPresetClass = convertEffectPresetClass(nPresetClass);
 
     sal_uInt32 nPresetId = 0;
@@ -1317,130 +1263,4 @@ sal_Int32 PPTXAnimationExport::GetAnimationNodeId(const 
Reference<XAnimationNode
     return nId;
 }
 
-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()
-{
-    assert(mxNode.is());
-
-    Sequence<NamedValue> aUserData = mxNode->getUserData();
-    const Any* aIndexedData[DFF_ANIM_PROPERTY_ID_COUNT];
-    AnimationExporter::GetUserData(aUserData, aIndexedData, 
sizeof(aIndexedData));
-
-    const Any* pAny = aIndexedData[DFF_ANIM_NODE_TYPE];
-    if (pAny)
-        *pAny >>= mnEffectNodeType;
-
-    pAny = aIndexedData[DFF_ANIM_PRESET_CLASS];
-    if (pAny)
-        *pAny >>= mnEffectPresetClass;
-
-    pAny = aIndexedData[DFF_ANIM_PRESET_ID];
-    if (pAny)
-        *pAny >>= msEffectPresetId;
-
-    pAny = aIndexedData[DFF_ANIM_PRESET_SUB_TYPE];
-    if (pAny)
-        *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.empty();
-    }
-    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)
-    {
-        Reference<XAudio> xAudio(mxNode, UNO_QUERY);
-        OUString sURL;
-        uno::Reference<drawing::XShape> xShape;
-        mbValid = false;
-        if (xAudio.is())
-        {
-            if (xAudio->getSource() >>= sURL)
-            {
-                mbValid = IsAudioURL(sURL);
-            }
-            else if (xAudio->getSource() >>= xShape)
-            {
-                uno::Reference<beans::XPropertySet> xShapeProps(xShape, 
uno::UNO_QUERY);
-                bool bHasMediaURL
-                    = 
xShapeProps->getPropertySetInfo()->hasPropertyByName("MediaURL");
-                if (bHasMediaURL && (xShapeProps->getPropertyValue("MediaURL") 
>>= sURL))
-                {
-                    mbValid = IsAudioURL(sURL) || IsVideoURL(sURL);
-                }
-            }
-        }
-    }
-    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();
-        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
-                        = std::make_unique<NodeContext>(xChildNode, 
bIsMainSeq, bIsIterateChild);
-                    if (pChildContext->isValid())
-                        bValid = true;
-                    maChildNodes.push_back(std::move(pChildContext));
-                }
-            }
-        }
-    }
-    return bValid;
-}
-
-const Reference<XAnimationNode>& NodeContext::getNodeForCondition() const
-{
-    const bool bParent
-        = (mnEffectNodeType != EffectNodeType::INTERACTIVE_SEQUENCE || 
maChildNodes.empty());
-    const Reference<XAnimationNode>& rNode = bParent ? mxNode : 
maChildNodes[0]->getNode();
-    return rNode;
-}
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Reply via email to