oox/source/export/shapes.cxx              |   18 +++++++++++-------
 sd/source/filter/eppt/pptx-animations.cxx |    6 ++++--
 sd/source/filter/ppt/pptin.cxx            |   22 ++++++++++++++++++++--
 3 files changed, 35 insertions(+), 11 deletions(-)

New commits:
commit 3a3760e683c5cfefed383299b74e0d68f080c653
Author:     Karthik <[email protected]>
AuthorDate: Fri Oct 10 08:27:38 2025 +0530
Commit:     Xisco Fauli <[email protected]>
CommitDate: Thu Oct 30 16:41:24 2025 +0100

    impress interop: PPT->PPTX invalid time value in <p:tmAbs>
    
    Saving a PPT file as PPTX could sometimes corrupt the output because of
    decimal ST_TLTime value.
    
    ST_TLTime should be unsigned int ([ISO/IEC 29500-1] 19.7.38).
    
    Change-Id: I2bfbec3a4970918e8c58b41c531799796e91668c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192138
    Reviewed-by: Michael Stahl <[email protected]>
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    (cherry picked from commit ec4a63decfe6c6613e3d3b7097359c26fa5b49c7)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193072
    Tested-by: Jenkins
    Signed-off-by: Xisco Fauli <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193193

diff --git a/sd/source/filter/eppt/pptx-animations.cxx 
b/sd/source/filter/eppt/pptx-animations.cxx
index 2bfcc8070a73..90c9da85b038 100644
--- a/sd/source/filter/eppt/pptx-animations.cxx
+++ b/sd/source/filter/eppt/pptx-animations.cxx
@@ -938,9 +938,11 @@ void 
PPTXAnimationExport::WriteAnimationNodeCommonPropsStart()
         {
             const char* sType = 
convertTextAnimationType(xIterate->getIterateType());
 
+            // ST_TLTime should be unsigned int ([ISO/IEC 29500-1] 19.7.38)
+            sal_uInt32 nTime = 
static_cast<sal_uInt32>(xIterate->getIterateInterval() * 1000);
+
             mpFS->startElementNS(XML_p, XML_iterate, XML_type, sType);
-            mpFS->singleElementNS(XML_p, XML_tmAbs, XML_val,
-                                  
OString::number(xIterate->getIterateInterval() * 1000));
+            mpFS->singleElementNS(XML_p, XML_tmAbs, XML_val, 
OString::number(nTime));
             mpFS->endElementNS(XML_p, XML_iterate);
         }
     }
commit b113ba6359384b31025e09288df8a401510fb4a5
Author:     Karthik Godha <[email protected]>
AuthorDate: Tue Oct 21 09:41:13 2025 +0530
Commit:     Xisco Fauli <[email protected]>
CommitDate: Thu Oct 30 16:41:17 2025 +0100

    tdf#168786: Fix PPT->PPTX internal link leading nowhere
    
    When saving PPT files with invalid link targets to PPTX, it results in
    corrupted XML output.
    
    Remove links with empty targets during PPTX export.
    
    Change-Id: I4c0a413c5a9c479094b3f48eead6d3676e6cf804
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192762
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Michael Stahl <[email protected]>
    (cherry picked from commit 0318671fb187941726316442651911a96a80f2f4)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193075
    Tested-by: Jenkins
    Signed-off-by: Xisco Fauli <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193192

diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx
index d8c396382217..febfbcaa9430 100644
--- a/oox/source/export/shapes.cxx
+++ b/oox/source/export/shapes.cxx
@@ -1004,16 +1004,20 @@ ShapeExport& ShapeExport::WriteCustomShape( const 
Reference< XShape >& xShape )
             bool bExtURL = URLTransformer().isExternalURL(sBookmark);
             sBookmark = bExtURL ? sBookmark : 
lcl_GetTarget(GetFB()->getModel(), sBookmark);
 
-            OUString sRelId
-                = mpFB->addRelation(mpFS->getOutputStream(),
-                                    bExtURL ? 
oox::getRelationship(Relationship::HYPERLINK)
-                                            : 
oox::getRelationship(Relationship::SLIDE),
-                                    sBookmark, bExtURL);
+            OUString sRelId;
+            if (!sBookmark.isEmpty())
+            {
+                sRelId = mpFB->addRelation(mpFS->getOutputStream(),
+                                           bExtURL ? 
oox::getRelationship(Relationship::HYPERLINK)
+                                                   : 
oox::getRelationship(Relationship::SLIDE),
+                                           sBookmark, bExtURL);
+            }
             if (bExtURL)
                 mpFS->singleElementNS(XML_a, XML_hlinkClick, FSNS(XML_r, 
XML_id), sRelId);
             else
-                mpFS->singleElementNS(XML_a, XML_hlinkClick, FSNS(XML_r, 
XML_id), sRelId,
-                                      XML_action, "ppaction://hlinksldjump");
+                mpFS->singleElementNS(
+                    XML_a, XML_hlinkClick, FSNS(XML_r, XML_id), sRelId, 
XML_action,
+                    sBookmark.isEmpty() ? "ppaction://noaction" : 
"ppaction://hlinksldjump");
         }
         AddExtLst(pFS, rXPropSet);
         pFS->endElementNS(mnXmlNamespace, XML_cNvPr);
commit c9172d1aec35b9283eb24dc09675f084e5bd9adc
Author:     Karthik <[email protected]>
AuthorDate: Fri Oct 10 18:46:01 2025 +0530
Commit:     Xisco Fauli <[email protected]>
CommitDate: Thu Oct 30 16:41:11 2025 +0100

    tdf#168736: Fix PPT->PPTX internal-link interoperability issue
    
    When PPT files with internal slide links are saved as PPTX, it results
    in corrupted XML output.
    
    Properly importing internal links when loading a PPT file fixes this
    issue. The fix follows PPTX standards for saving internal links.
    
    Change-Id: Ic554dae72e7089a005ed24dc697c3db17187cc83
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/192169
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Michael Stahl <[email protected]>
    (cherry picked from commit 6faf26e5de4aa21980f2ee49253a5e0854d2e62d)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193077
    Tested-by: Jenkins
    Signed-off-by: Xisco Fauli <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193191

diff --git a/sd/source/filter/ppt/pptin.cxx b/sd/source/filter/ppt/pptin.cxx
index 510d25f1bd61..9225566a9f93 100644
--- a/sd/source/filter/ppt/pptin.cxx
+++ b/sd/source/filter/ppt/pptin.cxx
@@ -383,6 +383,14 @@ bool ImplSdPPTImport::Import()
 
                                     nPropCount /= 6;    // 6 properties per 
hyperlink
 
+                                    // if a PPT contains internal links we can 
get the following SubAddresses
+                                    // "-1,-1,NEXT" | "-1,-1,PREV" | 
"-1,-1,FIRST" | "-1,-1,LAST"
+                                    static const std::map<OUString, OUString> 
aInternalLinks
+                                        = { { "NEXT", "nextslide" },
+                                            { "PREV", "previousslide" },
+                                            { "FIRST", "firstslide" },
+                                            { "LAST", "lastslide" } };
+
                                     for ( i = 0; i < nPropCount; i++ )
                                     {
                                         SdHyperlinkEntry aHyperlink;
@@ -492,9 +500,19 @@ bool ImplSdPPTImport::Import()
                                                     aHyperlink.aConvSubString 
= SdResId( STR_PAGE ) + " " + mrDoc.CreatePageNumValue( 
static_cast<sal_uInt16>(nPageNumber) + 1 );
                                                 }
                                             } else {
-                                                // if sub address is given but 
not internal, use it as it is
-                                                if ( 
aHyperlink.aConvSubString.isEmpty() )
+                                                // check for internal slide 
links
+                                                OUString 
aToken(OStringToOUString(
+                                                    aStringAry[2], 
RTL_TEXTENCODING_UTF8));
+
+                                                auto it = 
aInternalLinks.find(aToken);
+                                                if (it != aInternalLinks.end())
+                                                {
+                                                    aHyperlink.aConvSubString
+                                                        = "action?jump=" + 
it->second;
+                                                }
+                                                else if 
(aHyperlink.aConvSubString.isEmpty())
                                                 {
+                                                    // if sub address is given 
but not internal, use it as it is
                                                     aHyperlink.aConvSubString 
= aString;
                                                 }
                                             }

Reply via email to