sd/source/filter/eppt/pptx-animations-nodectx.cxx |   34 +++++++++++-----------
 sd/source/filter/eppt/pptx-animations-nodectx.hxx |    7 +++-
 sd/source/filter/eppt/pptx-animations.cxx         |    2 -
 3 files changed, 25 insertions(+), 18 deletions(-)

New commits:
commit d64f3e812bd6929b62d8c00b60b460aed2bf8e84
Author:     Karthik Godha <[email protected]>
AuthorDate: Tue Dec 9 20:05:53 2025 +0530
Commit:     Michael Stahl <[email protected]>
CommitDate: Fri Jan 2 13:53:50 2026 +0100

    tdf#169911: ODP -> PPTX export invalid animations
    
    Empty/invalid OLE objects are skipped PPTX export, but animations
    attached to these OLE objects are exported.
    
    Add the slide itself as target for these animations
    
    Change-Id: I1e594d607cc37f58c0e56357f8f8d42d9139bec8
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195306
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Michael Stahl <[email protected]>
    (cherry picked from commit 064e42a069c9186919086904ced3100960bafb41)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196156
    Tested-by: Jenkins

diff --git a/sd/source/filter/eppt/pptx-animations-nodectx.cxx 
b/sd/source/filter/eppt/pptx-animations-nodectx.cxx
index 07c8bd618f78..af843d661b69 100644
--- a/sd/source/filter/eppt/pptx-animations-nodectx.cxx
+++ b/sd/source/filter/eppt/pptx-animations-nodectx.cxx
@@ -40,18 +40,6 @@ namespace oox::core
 {
 namespace
 {
-bool isValidTarget(const Any& rTarget)
-{
-    Reference<XShape> xShape;
-
-    if ((rTarget >>= xShape) && 
drawingml::ShapeExport::IsShapeTypeKnown(xShape))
-        return true;
-
-    ParagraphTarget aParagraphTarget;
-
-    return (rTarget >>= aParagraphTarget) && aParagraphTarget.Shape.is();
-}
-
 bool IsAudioURL(std::u16string_view rURL)
 {
     return o3tl::endsWithIgnoreAsciiCase(rURL, ".wav")
@@ -95,10 +83,11 @@ bool initCondList(const Any& rAny, std::vector<Cond>& 
rList, bool bIsMainSeqChil
 }
 }
 
-NodeContext::NodeContext(const Reference<XAnimationNode>& xNode, bool 
bMainSeqChild,
-                         bool bIsIterateChild)
+NodeContext::NodeContext(const Reference<XAnimationNode>& xNode, 
PowerPointExport& rExport,
+                         bool bMainSeqChild, bool bIsIterateChild)
     : mxNode(xNode)
     , mbValid(true)
+    , mrPowerPointExport(rExport)
     , mbOnSubTnLst(false)
     , mnEffectNodeType(-1)
     , mnEffectPresetClass(css::presentation::EffectPresetClass::CUSTOM)
@@ -117,6 +106,19 @@ NodeContext::NodeContext(const Reference<XAnimationNode>& 
xNode, bool bMainSeqCh
     initCondList(getNodeForCondition()->getEnd(), maEndCondList, 
bMainSeqChild);
 }
 
+bool NodeContext::isValidTarget(const Any& rTarget)
+{
+    Reference<XShape> xShape;
+
+    if ((rTarget >>= xShape) && 
drawingml::ShapeExport::IsShapeTypeKnown(xShape)
+        && (mrPowerPointExport.GetShapeID(xShape) != -1))
+        return true;
+
+    ParagraphTarget aParagraphTarget;
+
+    return (rTarget >>= aParagraphTarget) && aParagraphTarget.Shape.is();
+}
+
 void NodeContext::initUserData()
 {
     assert(mxNode.is());
@@ -209,8 +211,8 @@ bool NodeContext::initChildNodes()
                 Reference<XAnimationNode> 
xChildNode(xEnumeration->nextElement(), UNO_QUERY);
                 if (xChildNode.is())
                 {
-                    auto pChildContext
-                        = std::make_unique<NodeContext>(xChildNode, 
bIsMainSeq, bIsIterateChild);
+                    auto pChildContext = std::make_unique<NodeContext>(
+                        xChildNode, 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 c25991a85a23..1830845ea5da 100644
--- a/sd/source/filter/eppt/pptx-animations-nodectx.hxx
+++ b/sd/source/filter/eppt/pptx-animations-nodectx.hxx
@@ -11,6 +11,7 @@
 #include <com/sun/star/uno/Reference.hxx>
 #include <com/sun/star/animations/XAnimationNode.hpp>
 #include <vector>
+#include "epptooxml.hxx"
 #include "pptx-animations-cond.hxx"
 
 namespace oox::core
@@ -28,6 +29,8 @@ class NodeContext
     std::vector<Cond> maEndCondList;
     // 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
+    PowerPointExport& mrPowerPointExport;
 
     // if the node should be on SubTnLst or ChildTnLst
     bool mbOnSubTnLst;
@@ -38,6 +41,8 @@ class NodeContext
     OUString msEffectPresetId;
     OUString msEffectPresetSubType;
 
+    bool isValidTarget(const css::uno::Any& rTarget);
+
     /// constructor helper for initializing user data.
     void initUserData();
 
@@ -50,7 +55,7 @@ class NodeContext
 
 public:
     NodeContext(const css::uno::Reference<css::animations::XAnimationNode>& 
xNode,
-                bool bMainSeqChild, bool bIsIterateChild);
+                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 43f28433465b..bbae2b29682c 100644
--- a/sd/source/filter/eppt/pptx-animations.cxx
+++ b/sd/source/filter/eppt/pptx-animations.cxx
@@ -1244,7 +1244,7 @@ void PPTXAnimationExport::WriteAnimations(const 
Reference<XDrawPage>& rXDrawPage
     if (!(xEnumeration.is() && xEnumeration->hasMoreElements()))
         return;
 
-    auto pNodeContext = std::make_unique<NodeContext>(xNode, false, false);
+    auto pNodeContext = std::make_unique<NodeContext>(xNode, 
mrPowerPointExport, false, false);
     if (pNodeContext->isValid())
     {
         mpFS->startElementNS(XML_p, XML_timing);

Reply via email to