sd/source/filter/ppt/pptin.cxx | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-)
New commits: commit 6faf26e5de4aa21980f2ee49253a5e0854d2e62d Author: Karthik <[email protected]> AuthorDate: Fri Oct 10 18:46:01 2025 +0530 Commit: Michael Stahl <[email protected]> CommitDate: Tue Oct 14 17:34:53 2025 +0200 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]> diff --git a/sd/source/filter/ppt/pptin.cxx b/sd/source/filter/ppt/pptin.cxx index bcca6cdd624e..4a8ead32f588 100644 --- a/sd/source/filter/ppt/pptin.cxx +++ b/sd/source/filter/ppt/pptin.cxx @@ -386,6 +386,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; @@ -495,9 +503,19 @@ bool ImplSdPPTImport::Import() aHyperlink.aConvSubString = SdResId( STR_PAGE ) + " " + mpDoc->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; } }
