sd/source/filter/eppt/pptx-animations-nodectx.cxx |   13 ++++++++-----
 sd/source/filter/eppt/pptx-animations-nodectx.hxx |    5 ++++-
 sd/source/filter/eppt/pptx-animations.cxx         |   21 ++++++++++++++++++++-
 3 files changed, 32 insertions(+), 7 deletions(-)

New commits:
commit 30d71445d40904fd7c47639575e3f7ffa499dcad
Author:     Karthik Godha <[email protected]>
AuthorDate: Wed Dec 10 21:39:49 2025 +0530
Commit:     Michael Stahl <[email protected]>
CommitDate: Mon Dec 15 13:36:21 2025 +0100

    tdf#169924: ODP -> PPTX export invalid animations
    
    When exporting animations in a slide, animations attached to
    shapes which are not in the slide are also being exported.
    
    Change-Id: I2dbc5cd5755ce6656a9fc2efa453c5837ffeaa6a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195391
    Reviewed-by: Michael Stahl <[email protected]>
    Tested-by: Jenkins CollaboraOffice <[email protected]>

diff --git a/sd/source/filter/eppt/pptx-animations-nodectx.cxx 
b/sd/source/filter/eppt/pptx-animations-nodectx.cxx
index af843d661b69..1fc049b6e42f 100644
--- a/sd/source/filter/eppt/pptx-animations-nodectx.cxx
+++ b/sd/source/filter/eppt/pptx-animations-nodectx.cxx
@@ -83,10 +83,12 @@ bool initCondList(const Any& rAny, std::vector<Cond>& 
rList, bool bIsMainSeqChil
 }
 }
 
-NodeContext::NodeContext(const Reference<XAnimationNode>& xNode, 
PowerPointExport& rExport,
-                         bool bMainSeqChild, bool bIsIterateChild)
+NodeContext::NodeContext(const Reference<XAnimationNode>& xNode,
+                         const std::unordered_set<sal_Int32>& rSlideShapeIDs,
+                         PowerPointExport& rExport, bool bMainSeqChild, bool 
bIsIterateChild)
     : mxNode(xNode)
     , mbValid(true)
+    , mrSlideShapeIDs(rSlideShapeIDs)
     , mrPowerPointExport(rExport)
     , mbOnSubTnLst(false)
     , mnEffectNodeType(-1)
@@ -111,7 +113,7 @@ bool NodeContext::isValidTarget(const Any& rTarget)
     Reference<XShape> xShape;
 
     if ((rTarget >>= xShape) && 
drawingml::ShapeExport::IsShapeTypeKnown(xShape)
-        && (mrPowerPointExport.GetShapeID(xShape) != -1))
+        && (mrSlideShapeIDs.find(mrPowerPointExport.GetShapeID(xShape)) != 
mrSlideShapeIDs.end()))
         return true;
 
     ParagraphTarget aParagraphTarget;
@@ -211,8 +213,9 @@ bool NodeContext::initChildNodes()
                 Reference<XAnimationNode> 
xChildNode(xEnumeration->nextElement(), UNO_QUERY);
                 if (xChildNode.is())
                 {
-                    auto pChildContext = std::make_unique<NodeContext>(
-                        xChildNode, mrPowerPointExport, bIsMainSeq, 
bIsIterateChild);
+                    auto pChildContext = 
std::make_unique<NodeContext>(xChildNode, mrSlideShapeIDs,
+                                                                       
mrPowerPointExport,
+                                                                       
bIsMainSeq, bIsIterateChild);
                     if (pChildContext->isValid())
                         bValid = true;
                     maChildNodes.push_back(std::move(pChildContext));
diff --git a/sd/source/filter/eppt/pptx-animations-nodectx.hxx 
b/sd/source/filter/eppt/pptx-animations-nodectx.hxx
index 1830845ea5da..865c23715b60 100644
--- a/sd/source/filter/eppt/pptx-animations-nodectx.hxx
+++ b/sd/source/filter/eppt/pptx-animations-nodectx.hxx
@@ -10,6 +10,7 @@
 
 #include <com/sun/star/uno/Reference.hxx>
 #include <com/sun/star/animations/XAnimationNode.hpp>
+#include <unordered_set>
 #include <vector>
 #include "epptooxml.hxx"
 #include "pptx-animations-cond.hxx"
@@ -30,6 +31,7 @@ class NodeContext
     // if the node has valid target or contains at least one valid target.
     bool mbValid;
     // Required to check if the associated shape is present in export or not
+    const std::unordered_set<sal_Int32>& mrSlideShapeIDs;
     PowerPointExport& mrPowerPointExport;
 
     // if the node should be on SubTnLst or ChildTnLst
@@ -55,7 +57,8 @@ class NodeContext
 
 public:
     NodeContext(const css::uno::Reference<css::animations::XAnimationNode>& 
xNode,
-                PowerPointExport& rExport, bool bMainSeqChild, bool 
bIsIterateChild);
+                const std::unordered_set<sal_Int32>& rSlideShapeIDs, 
PowerPointExport& rExport,
+                bool bMainSeqChild, bool bIsIterateChild);
     const css::uno::Reference<css::animations::XAnimationNode>& getNode() 
const { return mxNode; }
     sal_Int16 getEffectNodeType() const { return mnEffectNodeType; }
     sal_Int16 getEffectPresetClass() const { return mnEffectPresetClass; }
diff --git a/sd/source/filter/eppt/pptx-animations.cxx 
b/sd/source/filter/eppt/pptx-animations.cxx
index bbae2b29682c..edb068dbc942 100644
--- a/sd/source/filter/eppt/pptx-animations.cxx
+++ b/sd/source/filter/eppt/pptx-animations.cxx
@@ -25,6 +25,7 @@
 #include <sal/log.hxx>
 #include <rtl/math.hxx>
 #include <comphelper/sequenceashashmap.hxx>
+#include <unordered_set>
 
 #include <com/sun/star/animations/AnimationAdditiveMode.hpp>
 #include <com/sun/star/animations/AnimationCalcMode.hpp>
@@ -53,6 +54,7 @@
 #include <com/sun/star/presentation/TextAnimationType.hpp>
 #include <com/sun/star/text/XSimpleText.hpp>
 #include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
 #include <com/sun/star/beans/XPropertySet.hpp>
 #include <oox/export/utils.hxx>
 #include <oox/ppt/pptfilterhelpers.hxx>
@@ -76,6 +78,7 @@ using namespace oox;
 using ::com::sun::star::beans::NamedValue;
 using ::com::sun::star::drawing::XDrawPage;
 using ::com::sun::star::drawing::XShape;
+using ::com::sun::star::drawing::XShapes;
 using ::com::sun::star::text::XSimpleText;
 using ::sax_fastparser::FSHelperPtr;
 
@@ -1244,7 +1247,23 @@ void PPTXAnimationExport::WriteAnimations(const 
Reference<XDrawPage>& rXDrawPage
     if (!(xEnumeration.is() && xEnumeration->hasMoreElements()))
         return;
 
-    auto pNodeContext = std::make_unique<NodeContext>(xNode, 
mrPowerPointExport, false, false);
+    Reference<XShapes> xShapes = rXDrawPage;
+    sal_uInt32 nShapes = xShapes->getCount();
+    std::unordered_set<sal_Int32> aSlideShapeIDs;
+    if (xShapes.is())
+    {
+        for (sal_uInt32 i = 0; i < nShapes; i++)
+        {
+            Reference<XShape> xShape;
+            xShapes->getByIndex(i) >>= xShape;
+            sal_Int32 nId = mrPowerPointExport.GetShapeID(xShape);
+            if (nId != -1)
+                aSlideShapeIDs.insert(nId);
+        }
+    }
+
+    auto pNodeContext
+        = std::make_unique<NodeContext>(xNode, aSlideShapeIDs, 
mrPowerPointExport, false, false);
     if (pNodeContext->isValid())
     {
         mpFS->startElementNS(XML_p, XML_timing);

Reply via email to