avmedia/source/framework/mediaitem.cxx | 4 comphelper/source/misc/graphicmimetype.cxx | 4 include/oox/export/chartexport.hxx | 7 - oox/inc/drawingml/graphicproperties.hxx | 1 oox/source/drawingml/fillproperties.cxx | 5 oox/source/drawingml/graphicshapecontext.cxx | 6 oox/source/drawingml/shape.cxx | 3 oox/source/export/chartexport.cxx | 24 +-- oox/source/export/drawingml.cxx | 147 ++++++++++++++-------- oox/source/export/shapes.cxx | 40 +++++ oox/source/ppt/pptshape.cxx | 10 + oox/source/token/properties.txt | 1 sc/qa/extras/scpdfexport.cxx | 6 sc/source/core/tool/compiler.cxx | 2 sd/qa/unit/data/pptx/tdf169524.pptx |binary sd/qa/unit/export-tests-ooxml4.cxx | 12 + sd/qa/unit/import-tests2.cxx | 6 sd/source/filter/eppt/pptx-animations-nodectx.cxx | 34 ++++- sd/source/filter/eppt/pptx-animations-nodectx.hxx | 5 sd/source/filter/eppt/pptx-animations.cxx | 39 ++++- sd/source/filter/ppt/pptin.cxx | 17 +- svx/source/unodraw/unoshap4.cxx | 7 + sw/qa/extras/htmlexport/htmlexport2.cxx | 3 sw/source/filter/ww8/docxattributeoutput.cxx | 6 24 files changed, 290 insertions(+), 99 deletions(-)
New commits: commit 99c3e6aab88c5592a9d24c16b1ec43fe08be1439 Author: Karthik Godha <[email protected]> AuthorDate: Thu Dec 25 15:16:40 2025 +0530 Commit: Andras Timar <[email protected]> CommitDate: Wed Jan 7 12:41:37 2026 +0100 tdf#170035:Prefix numericals with "val" in guidelist The `fmla` value in `a:gd` XML attribute should be perfixed by "val " for numerical values. Change-Id: I4678a53679d8f2d9e21d6cbe255c922a4cf023c2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196210 Reviewed-by: Michael Stahl <[email protected]> Tested-by: Jenkins CollaboraOffice <[email protected]> diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index ce94129dc991..ad855af5c862 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -4943,6 +4943,11 @@ bool IsValidOOXMLFormula(std::u16string_view sFormula) OUString GetFormula(const OUString& sEquation, const OUString& sReplace, const OUString& sNewStr) { + // If the equation is numerical + sal_Int64 nValue = sEquation.toInt64(); + if (!sEquation.isEmpty() && OUString::number(nValue) == sEquation) + return "val " + sEquation; + OUString sFormula = sEquation; size_t nPos = sFormula.indexOf(sReplace); if (nPos != std::string::npos) commit 0a2c3d0f95f05c7c70c54a63937b6a315fef04f9 Author: Karthik Godha <[email protected]> AuthorDate: Mon Dec 29 19:02:58 2025 +0530 Commit: Andras Timar <[email protected]> CommitDate: Wed Jan 7 12:38:00 2026 +0100 ODP->PPTX: Incorrect MimeType for media files If a media file's name has its file extension in uppercase then the mime type is not handled. Example: audio1.mp3 is handled but audio1.MP3 is not handled bug document: tdf123653-1.odp Change-Id: If220283b1a447cde0a070853192638ee5f30c87b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196302 Reviewed-by: Michael Stahl <[email protected]> Tested-by: Jenkins CollaboraOffice <[email protected]> diff --git a/comphelper/source/misc/graphicmimetype.cxx b/comphelper/source/misc/graphicmimetype.cxx index 78f529f11768..7f061fb373cc 100644 --- a/comphelper/source/misc/graphicmimetype.cxx +++ b/comphelper/source/misc/graphicmimetype.cxx @@ -230,7 +230,8 @@ auto GuessMediaMimeType(::std::u16string_view rFileName) -> OUString { if (auto const i = rFileName.rfind('.'); i != ::std::string_view::npos) { - OString const ext(OUStringToOString(rFileName.substr(i + 1), RTL_TEXTENCODING_UTF8)); + OString const ext( + OUStringToOString(rFileName.substr(i + 1), RTL_TEXTENCODING_UTF8).toAsciiLowerCase()); auto const& rMap(GetMediaMimes()); auto const it(rMap.find(ext)); if (it != rMap.end()) commit 8890d093b14626b7a57b24aba4f6d2dcdba4c1e9 Author: Karthik Godha <[email protected]> AuthorDate: Wed Dec 31 14:58:27 2025 +0530 Commit: Andras Timar <[email protected]> CommitDate: Wed Jan 7 12:37:54 2026 +0100 tdf#170181: PPT placeholder imported as OLE object Placeholder for (table, chart, image) is imported as OLE object instead of placeholder Change-Id: I62d5ac3e48d51944629f0eb82de390db10a59c2c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196352 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 b39dbc73baed..44244f0a6b7b 100644 --- a/sd/source/filter/ppt/pptin.cxx +++ b/sd/source/filter/ppt/pptin.cxx @@ -2411,13 +2411,16 @@ SdrObject* ImplSdPPTImport::ApplyTextObj( PPTTextObj* pTextObj, SdrTextObj* pObj { switch ( nPlaceholderId ) { - case PptPlaceholder::MEDIACLIP : - case PptPlaceholder::OBJECT : ePresObjKind = PresObjKind::Object; break; - case PptPlaceholder::GRAPH : ePresObjKind = PresObjKind::Chart; break; - case PptPlaceholder::TABLE : ePresObjKind = PresObjKind::Table; break; - case PptPlaceholder::CLIPART : ePresObjKind = PresObjKind::Graphic; break; - case PptPlaceholder::ORGANISZATIONCHART : ePresObjKind = PresObjKind::OrgChart; break; - default: break; + case PptPlaceholder::MEDIACLIP: + case PptPlaceholder::OBJECT: + case PptPlaceholder::GRAPH: + case PptPlaceholder::TABLE: + case PptPlaceholder::CLIPART: + case PptPlaceholder::ORGANISZATIONCHART: + ePresObjKind = PresObjKind::Outline; + break; + default: + break; } } }; commit 7f571803cf49dcbdfbdb3e1e75d87db01d60513e Author: Karthik Godha <[email protected]> AuthorDate: Fri Jan 2 17:49:44 2026 +0530 Commit: Andras Timar <[email protected]> CommitDate: Wed Jan 7 12:37:29 2026 +0100 tdf#170201: XLSX - empty values in array formulas LO supports empty values in array formulas but Excel doesn't. Export '0' when an array formula contains an empty value. Change-Id: I5f289c0bf3f98cb75dffa925245afab67641eac2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196421 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Michael Stahl <[email protected]> diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx index 4f86f07913ec..976c225ae5ef 100644 --- a/sc/source/core/tool/compiler.cxx +++ b/sc/source/core/tool/compiler.cxx @@ -5481,7 +5481,7 @@ void ScCompiler::CreateStringFromMatrix( OUStringBuffer& rBuffer, const FormulaT } } else if( pMatrix->IsEmpty( nC, nR ) ) - ; + AppendDouble(rBuffer, 0); else if( pMatrix->IsStringOrEmpty( nC, nR ) ) AppendString( rBuffer, pMatrix->GetString(nC, nR).getString() ); } commit 9afcfdc3c09f25f91a88e3bf7a633ce3849a1d49 Author: Karthik Godha <[email protected]> AuthorDate: Thu Dec 25 17:24:54 2025 +0530 Commit: Andras Timar <[email protected]> CommitDate: Wed Jan 7 12:37:23 2026 +0100 PPTX->PPTX Invalid value in 'h' attribute of hsl 'h' attribute inside XML_hsl (CT_TLByHslColorTransform) can't be a decimal value. Test file: rhbz710556-3.pptx Change-Id: I4ac7af4115c44443ad92c4ca9b9a8be09f806686 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196218 Reviewed-by: Michael Stahl <[email protected]> Tested-by: Jenkins CollaboraOffice <[email protected]> diff --git a/sd/source/filter/eppt/pptx-animations.cxx b/sd/source/filter/eppt/pptx-animations.cxx index 346ad6b01070..a534ca715053 100644 --- a/sd/source/filter/eppt/pptx-animations.cxx +++ b/sd/source/filter/eppt/pptx-animations.cxx @@ -17,6 +17,7 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <cmath> #include <o3tl/any.hxx> #include <o3tl/string_view.hxx> #include <oox/token/tokens.hxx> @@ -182,9 +183,9 @@ void WriteAnimateColorColor(const FSHelperPtr& pFS, const Any& rAny, sal_Int32 n if (nToken == XML_by) { // CT_TLByHslColorTransform - pFS->singleElementNS(XML_p, XML_hsl, XML_h, OString::number(aHSL[0] * 60000), // ST_Angel - XML_s, OString::number(aHSL[1] * 100000), XML_l, - OString::number(aHSL[2] * 100000)); + pFS->singleElementNS( + XML_p, XML_hsl, XML_h, OString::number(std::round(aHSL[0] * 60000)), // ST_Angel + XML_s, OString::number(aHSL[1] * 100000), XML_l, OString::number(aHSL[2] * 100000)); } else { commit e0d50ed50bf7878f38a415af89123b0385d91948 Author: Karthik Godha <[email protected]> AuthorDate: Thu Dec 25 15:11:01 2025 +0530 Commit: Andras Timar <[email protected]> CommitDate: Wed Jan 7 12:37:15 2026 +0100 tdf#170035:Add OOXML formula check for guidelist Add condition check to skip exported of internal names/equations to OOXML. Change-Id: I0c03bbaa7ea61dd4f526fc0476482571df7e7cf7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196209 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Michael Stahl <[email protected]> diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index 5ed18d0f5bf6..ce94129dc991 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -39,6 +39,7 @@ #include <sax/fastattribs.hxx> #include <comphelper/diagnose_ex.hxx> #include <comphelper/processfactory.hxx> +#include <comphelper/string.hxx> #include <i18nlangtag/languagetag.hxx> #include <basegfx/matrix/b2dhommatrixtools.hxx> #include <basegfx/range/b2drange.hxx> @@ -46,6 +47,7 @@ #include <numeric> #include <string_view> +#include <set> #include <com/sun/star/awt/CharSet.hpp> #include <com/sun/star/awt/FontDescriptor.hpp> @@ -4898,12 +4900,49 @@ void prepareTextArea(const EnhancedCustomShape2d& rEnhancedCustomShape2d, return; } -OUString GetFormula(const OUString& sEquation, const OUString& sReplace, const OUString& sNewStr) +bool IsValidOOXMLFormula(std::u16string_view sFormula) { - // 'logheight' and `logwidth` are only used for calculating shape's rectangle - if (sEquation == "logheight" || sEquation == "logwidth") - return OUString(); + // Accepted Formulas + // "val n1" + // "abs n1" + // "sqrt n1" + // "min n1 n2" + // "max n1 n2" + // "*/ n1 n2 n3" + // "+- n1 n2 n3" + // "?: n1 n2 n3" + + // Below vector contains validTokens for the 1st token based on the number of tokens in the formula. The order is: 2, 3, 4 + const std::vector<std::set<OUString>> validTokens + = { { "val", "abs", "sqrt" }, { "min", "max" }, { "*/", "+-", "?:" } }; + const std::set<OUString> builtInVariables = { "w", "h", "t", "b", "l", "r" }; + const std::vector<OUString> strTokens = comphelper::string::split(sFormula, ' '); + sal_uInt16 nSize = strTokens.size(); + + if (nSize > 1 && nSize < 5) + { + auto aTokens = validTokens[nSize - 2]; + + // Check whether the 1st token is valid + if (aTokens.find(strTokens[0]) == aTokens.end()) + return false; + + // Check that the remaining tokens are either numbers or buit-in variables + for (sal_Int16 i = 1; i < nSize; i++) + { + OUString sVal = strTokens[i]; + sal_Int64 nVal = sVal.toInt64(); + if (builtInVariables.find(sVal) == builtInVariables.end() + && OUString::number(nVal) != sVal) + return false; + } + return true; + } + return false; +} +OUString GetFormula(const OUString& sEquation, const OUString& sReplace, const OUString& sNewStr) +{ OUString sFormula = sEquation; size_t nPos = sFormula.indexOf(sReplace); if (nPos != std::string::npos) @@ -4912,7 +4951,10 @@ OUString GetFormula(const OUString& sEquation, const OUString& sReplace, const O sFormula = "*/ " + sModifiedEquation; } - return sFormula; + if (IsValidOOXMLFormula(sFormula)) + return sFormula; + + return OUString(); } void prepareGluePoints(std::vector<Guide>& rGuideList, commit 6a5e08a8e5eab8505968ed76efe7122efb18e695 Author: Karthik Godha <[email protected]> AuthorDate: Sun Dec 28 20:50:43 2025 +0530 Commit: Andras Timar <[email protected]> CommitDate: Wed Jan 7 12:37:07 2026 +0100 tdf#170153: PPTX->PPTX handle ".bin" media file Media files are exported based on file extensions. ".bin" file extension is not handled. Change-Id: Ib7af829e6a5bd042c59edcef9d09b6c5d4fb80a3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196267 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Michael Stahl <[email protected]> diff --git a/avmedia/source/framework/mediaitem.cxx b/avmedia/source/framework/mediaitem.cxx index db3685e14670..59d4c915d3be 100644 --- a/avmedia/source/framework/mediaitem.cxx +++ b/avmedia/source/framework/mediaitem.cxx @@ -244,7 +244,9 @@ bool MediaItem::setURL(const OUString& rURL, const OUString& rTempURL, const OUS m_pImpl->m_URL = rURL; m_pImpl->m_TempFileURL = rTempURL; m_pImpl->m_Referer = rReferer; - setMimeType(::comphelper::GuessMediaMimeType(GetFilename(rURL))); + OUString sMimeType(::comphelper::GuessMediaMimeType(GetFilename(rURL))); + if (!sMimeType.isEmpty()) + setMimeType(sMimeType); } return bChanged; } diff --git a/comphelper/source/misc/graphicmimetype.cxx b/comphelper/source/misc/graphicmimetype.cxx index 9981b33ed386..78f529f11768 100644 --- a/comphelper/source/misc/graphicmimetype.cxx +++ b/comphelper/source/misc/graphicmimetype.cxx @@ -190,6 +190,7 @@ static auto GetMediaMimes() -> std::map<OString, OString> const& { "mov", "video/quicktime" }, { "wmv", "video/x-ms-wmv" }, { "avi", "video/x-msvideo" }, + { "flv", "video/x-flv" }, { "m4a", "audio/mp4" }, { "aac", "audio/aac" }, { "mp3", "audio/mpeg" }, // https://bugs.chromium.org/p/chromium/issues/detail?id=227004 diff --git a/oox/inc/drawingml/graphicproperties.hxx b/oox/inc/drawingml/graphicproperties.hxx index 15ccedb99a2e..cea92cd0e954 100644 --- a/oox/inc/drawingml/graphicproperties.hxx +++ b/oox/inc/drawingml/graphicproperties.hxx @@ -37,6 +37,7 @@ struct GraphicProperties { BlipFillProperties maBlipProps; ///< Properties for the graphic. OUString m_sMediaPackageURL; ///< Audio/Video URL. + OUString m_sMediaMimeType; bool mbIsCustomShape = false; bool mbIsExtruded = false; css::uno::Reference<css::io::XInputStream> m_xMediaStream; ///< Audio/Video input stream. diff --git a/oox/source/drawingml/fillproperties.cxx b/oox/source/drawingml/fillproperties.cxx index 076910558c5e..c2f24160f305 100644 --- a/oox/source/drawingml/fillproperties.cxx +++ b/oox/source/drawingml/fillproperties.cxx @@ -917,6 +917,11 @@ void GraphicProperties::pushToPropMap( PropertyMap& rPropMap, const GraphicHelpe if (m_xMediaStream.is()) rPropMap.setProperty(PROP_PrivateStream, m_xMediaStream); } + // Media Type + if (!m_sMediaMimeType.isEmpty()) + { + rPropMap.setProperty(PROP_MediaMimeType, m_sMediaMimeType); + } } bool ArtisticEffectProperties::isEmpty() const diff --git a/oox/source/drawingml/graphicshapecontext.cxx b/oox/source/drawingml/graphicshapecontext.cxx index 45dbc656e6bb..da7b40603cdf 100644 --- a/oox/source/drawingml/graphicshapecontext.cxx +++ b/oox/source/drawingml/graphicshapecontext.cxx @@ -87,6 +87,7 @@ ContextHandlerRef GraphicShapeContext::onCreateContext( sal_Int32 aElementToken, { mpShapePtr->getGraphicProperties().m_xMediaStream = std::move(xMediaStream); mpShapePtr->getGraphicProperties().m_sMediaPackageURL = lcl_GetMediaReference(path); + mpShapePtr->getGraphicProperties().m_sMediaMimeType = "audio/unknown"; } } break; @@ -113,6 +114,11 @@ ContextHandlerRef GraphicShapeContext::onCreateContext( sal_Int32 aElementToken, mpShapePtr->getGraphicProperties().m_sMediaPackageURL = getFilter().getAbsoluteUrl(rPath); } + + if (getBaseToken(aElementToken) == XML_audioFile) + mpShapePtr->getGraphicProperties().m_sMediaMimeType = "audio/unknown"; + else + mpShapePtr->getGraphicProperties().m_sMediaMimeType = "video/unknown"; } break; } diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index e8603ea7e11b..5ed18d0f5bf6 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -1685,39 +1685,6 @@ void DrawingML::WriteMediaNonVisualProperties(const css::uno::Reference<css::dra { eMediaType = Relationship::AUDIO; } - else - if (aMimeType == "application/vnd.sun.star.media") - { - // try to set something better - // TODO fix the importer to actually set the mimetype on import - if (aExtension.equalsIgnoreAsciiCase(".avi")) - aMimeType = "video/x-msvideo"; - else if (aExtension.equalsIgnoreAsciiCase(".flv")) - aMimeType = "video/x-flv"; - else if (aExtension.equalsIgnoreAsciiCase(".mp4")) - aMimeType = "video/mp4"; - else if (aExtension.equalsIgnoreAsciiCase(".mov")) - aMimeType = "video/quicktime"; - else if (aExtension.equalsIgnoreAsciiCase(".ogv")) - aMimeType = "video/ogg"; - else if (aExtension.equalsIgnoreAsciiCase(".wmv")) - aMimeType = "video/x-ms-wmv"; - else if (aExtension.equalsIgnoreAsciiCase(".wav")) - { - aMimeType = "audio/x-wav"; - eMediaType = Relationship::AUDIO; - } - else if (aExtension.equalsIgnoreAsciiCase(".m4a")) - { - aMimeType = "audio/mp4"; - eMediaType = Relationship::AUDIO; - } - else if (aExtension.equalsIgnoreAsciiCase(".mp3")) - { - aMimeType = "audio/mp3"; - eMediaType = Relationship::AUDIO; - } - } OUString aVideoFileRelId; OUString aMediaRelId; diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt index 36207d8d697e..e674b902f03a 100644 --- a/oox/source/token/properties.txt +++ b/oox/source/token/properties.txt @@ -366,6 +366,7 @@ MarkPosition MaxFieldCount MaxTextLen MediaType +MediaMimeType MediaURL Metal MetalType diff --git a/svx/source/unodraw/unoshap4.cxx b/svx/source/unodraw/unoshap4.cxx index 46c265c64a7c..2c47cd05bb51 100644 --- a/svx/source/unodraw/unoshap4.cxx +++ b/svx/source/unodraw/unoshap4.cxx @@ -33,6 +33,7 @@ #include <comphelper/classids.hxx> #include <comphelper/DirectoryHelper.hxx> #include <comphelper/embeddedobjectcontainer.hxx> +#include <comphelper/mediamimetype.hxx> #include <comphelper/propertysequence.hxx> #include <comphelper/propertyvalue.hxx> #include <cppuhelper/exc_hlp.hxx> @@ -902,6 +903,12 @@ bool SvxMediaShape::setPropertyValueImpl( const OUString& rName, const SfxItemPr if( rValue >>= sMimeType ) { bOk = true; + + if (aItem.getMimeType() != AVMEDIA_MIMETYPE_COMMON + && (sMimeType == "audio/unknown" || sMimeType == "video/unknown")) + { + break; + } aItem.setMimeType( sMimeType ); } } commit 3d7e3f5c8771ce88c5590fe3e9062a0b0e3bba22 Author: Karthik Godha <[email protected]> AuthorDate: Mon Dec 29 14:54:49 2025 +0530 Commit: Andras Timar <[email protected]> CommitDate: Wed Jan 7 12:36:55 2026 +0100 ODP -> PPTX: Skip childTnLst for invalid audio childTnLst element can't be empty in PPTX export. For audio animations we are exporting childTnLst even if the audio is invalid bug document: tdf97809-1.odp Change-Id: I7f4e19cb6541453e36fee8c63d0877ad62896a52 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196279 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Michael Stahl <[email protected]> diff --git a/sd/source/filter/eppt/pptx-animations-nodectx.cxx b/sd/source/filter/eppt/pptx-animations-nodectx.cxx index 11c9d8ed481f..2744cac56480 100644 --- a/sd/source/filter/eppt/pptx-animations-nodectx.cxx +++ b/sd/source/filter/eppt/pptx-animations-nodectx.cxx @@ -23,6 +23,9 @@ #include <com/sun/star/presentation/ParagraphTarget.hpp> #include <com/sun/star/beans/XPropertySet.hpp> +#include <comphelper/storagehelper.hxx> +#include <comphelper/processfactory.hxx> + #include <o3tl/any.hxx> #include <o3tl/string_view.hxx> @@ -35,6 +38,7 @@ using namespace ::com::sun::star::drawing; using namespace ::com::sun::star::container; using namespace ::com::sun::star::presentation; using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::io; namespace oox::core { @@ -177,6 +181,23 @@ void NodeContext::initValid(bool bHasValidChild, bool bIsIterateChild) if (xAudio->getSource() >>= sURL) { mbValid = IsAudioURL(sURL); + + // Check whether URL is accessible + try + { + if (!sURL.startsWith("vnd.sun.star.Package:")) + { + Reference<XInputStream> xAudioStream; + xAudioStream = comphelper::OStorageHelper::GetInputStreamFromURL( + sURL, comphelper::getProcessComponentContext()); + mbValid = mbValid && xAudioStream.is(); + } + } + catch (const Exception&) + { + SAL_WARN("sd", "NodeContext::initValid, invalid audio"); + mbValid = false; + } } else if (xAudio->getSource() >>= xShape) { commit 4ef825a0f53f0a45955bf26e00bd72f386236551 Author: Karthik Godha <[email protected]> AuthorDate: Mon Dec 22 14:47:31 2025 +0530 Commit: Andras Timar <[email protected]> CommitDate: Wed Jan 7 12:36:49 2026 +0100 Skip export of <v:imagedata> for empty graphics This is related to f6b22383258d6ecd93193240b60d6124791d8699, for some Draw OLEs graphic can be empty. Change-Id: I0feac81d8ae33fdbabd426ff2e37c01f911a6f0b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196075 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Michael Stahl <[email protected]> diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 33f009f9a60d..5f2b3d2a0a01 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -6287,9 +6287,9 @@ void DocxAttributeOutput::WriteOLEShape(const SwFlyFrameFormat& rFrameFormat, co } // shape filled with the preview image - m_pSerializer->singleElementNS(XML_v, XML_imagedata, - FSNS(XML_r, XML_id), rImageId, - FSNS(XML_o, XML_title), ""); + if (!rImageId.isEmpty()) + m_pSerializer->singleElementNS(XML_v, XML_imagedata, FSNS(XML_r, XML_id), rImageId, + FSNS(XML_o, XML_title), ""); //export wrap settings if (rFrameFormat.GetAnchor().GetAnchorId() != RndStdIds::FLY_AS_CHAR) //As-char objs does not have surround. commit e14ba6847e3971e50955a587be19b003874b5ba7 Author: Karthik Godha <[email protected]> AuthorDate: Mon Dec 29 16:00:09 2025 +0530 Commit: Andras Timar <[email protected]> CommitDate: Wed Jan 7 12:36:43 2026 +0100 ODP -> PPTX: exporting invalid XML_by (CT_TLPoint) XML_by inside XML_animScale can't contain any child elements. Its schema is defined by CT_TLPoint (ISO-IEC-29500 19.5.21) bug document: tdf112587-1.odp Change-Id: I66169379fb0cf74a46e53f6b4474e0691e9da2f5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196292 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Michael Stahl <[email protected]> diff --git a/sd/source/filter/eppt/pptx-animations.cxx b/sd/source/filter/eppt/pptx-animations.cxx index da05c11dff0a..346ad6b01070 100644 --- a/sd/source/filter/eppt/pptx-animations.cxx +++ b/sd/source/filter/eppt/pptx-animations.cxx @@ -107,6 +107,9 @@ void WriteAnimationProperty(const FSHelperPtr& pFS, const Any& rAny, sal_Int32 n } return; } + // If rAny is not a valid ValuePair and token is XML_by + if (nToken == XML_by) + return; sal_Int32 nRgb = {}; // spurious -Werror=maybe-uninitialized double fDouble = {}; // spurious -Werror=maybe-uninitialized commit fbb7fcb78edcab60c272f1bdf2afd32f0c1bc624 Author: Karthik Godha <[email protected]> AuthorDate: Thu Dec 18 16:45:21 2025 +0530 Commit: Andras Timar <[email protected]> CommitDate: Wed Jan 7 12:36:35 2026 +0100 tdf#170035:PPTX->PPTX invalid values in guide-list During PPTX export internal equation names are exported as guide values in guide-list. Change-Id: I179b47b57057fabf76e85b1c1d4aa62e0e3154d2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195837 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Michael Stahl <[email protected]> diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index 1ccfe0a5fbba..e8603ea7e11b 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -4933,6 +4933,10 @@ void prepareTextArea(const EnhancedCustomShape2d& rEnhancedCustomShape2d, OUString GetFormula(const OUString& sEquation, const OUString& sReplace, const OUString& sNewStr) { + // 'logheight' and `logwidth` are only used for calculating shape's rectangle + if (sEquation == "logheight" || sEquation == "logwidth") + return OUString(); + OUString sFormula = sEquation; size_t nPos = sFormula.indexOf(sReplace); if (nPos != std::string::npos) @@ -4963,18 +4967,24 @@ void prepareGluePoints(std::vector<Guide>& rGuideList, { Guide aGuideX; aGuideX.sName = "GluePoint"_ostr + OString::number(nIndex) + "X"; - aGuideX.sFormula - = (bIsOOXML && nIdx1 >= 0 && nIdx1 < aEquations.getLength()) - ? GetFormula(aEquations[nIdx1], "*logwidth/", " w ").toUtf8() - : "*/ " + OString::number(nIdx1) + " w " + OString::number(nWidth); + + if (bIsOOXML && nIdx1 >= 0 && nIdx1 < aEquations.getLength()) + aGuideX.sFormula = GetFormula(aEquations[nIdx1], "*logwidth/", " w ").toUtf8(); + if (aGuideX.sFormula.isEmpty()) + aGuideX.sFormula + = "*/ " + OString::number(nIdx1) + " w " + OString::number(nWidth); + rGuideList.push_back(aGuideX); Guide aGuideY; aGuideY.sName = "GluePoint"_ostr + OString::number(nIndex) + "Y"; - aGuideY.sFormula - = (bIsOOXML && nIdx2 >= 0 && nIdx2 < aEquations.getLength()) - ? GetFormula(aEquations[nIdx2], "*logheight/", " h ").toUtf8() - : "*/ " + OString::number(nIdx2) + " h " + OString::number(nHeight); + + if (bIsOOXML && nIdx2 >= 0 && nIdx2 < aEquations.getLength()) + aGuideY.sFormula = GetFormula(aEquations[nIdx2], "*logheight/", " h ").toUtf8(); + if (aGuideY.sFormula.isEmpty()) + aGuideY.sFormula + = "*/ " + OString::number(nIdx2) + " h " + OString::number(nHeight); + rGuideList.push_back(aGuideY); } commit 9de3b56526c25ebe03b0ddddf599fdc74ac77e08 Author: Karthik Godha <[email protected]> AuthorDate: Wed Dec 17 10:33:56 2025 +0530 Commit: Andras Timar <[email protected]> CommitDate: Wed Jan 7 12:36:29 2026 +0100 ODP -> PPTX export empty attrName element In OOXML export attrNameLst must contain at least one attrName element. Export of attrName is skipped if it's empty, this results in invalid schema. (ISO-IEC-29500 19.5.8) bug-file: ooo72169-1.odp Change-Id: I8ebf2b9752fc9e90c21339d7d9dd3507e2518fc9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195758 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Michael Stahl <[email protected]> diff --git a/sd/source/filter/eppt/pptx-animations.cxx b/sd/source/filter/eppt/pptx-animations.cxx index 5d6072116420..da05c11dff0a 100644 --- a/sd/source/filter/eppt/pptx-animations.cxx +++ b/sd/source/filter/eppt/pptx-animations.cxx @@ -299,16 +299,12 @@ void WriteAnimationAttributeName(const FSHelperPtr& pFS, const OUString& rAttrib attrConv++; } + pFS->startElementNS(XML_p, XML_attrName); if (pAttribute) - { - pFS->startElementNS(XML_p, XML_attrName); pFS->writeEscaped(pAttribute); - pFS->endElementNS(XML_p, XML_attrName); - } else - { SAL_WARN("sd.eppt", "unhandled animation attribute name: " << rAttributeName); - } + pFS->endElementNS(XML_p, XML_attrName); } pFS->endElementNS(XML_p, XML_attrNameLst); commit 72f82c9383a1c97cb59e0fe5c4a281160b69d15e Author: Karthik Godha <[email protected]> AuthorDate: Mon Dec 15 16:56:58 2025 +0530 Commit: Andras Timar <[email protected]> CommitDate: Wed Jan 7 12:36:24 2026 +0100 tdf#169980: Fix ODP->PPTX export of stock chart In OOXML chart export in `c:stockChart` there are multiple `c:ser` elements with the same `c:idx` value. Change-Id: Id5c5983118214013a3610ae937b9893c479a0ea0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195657 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Michael Stahl <[email protected]> diff --git a/include/oox/export/chartexport.hxx b/include/oox/export/chartexport.hxx index 1fa895d0e9fd..59af37ea0c15 100644 --- a/include/oox/export/chartexport.hxx +++ b/include/oox/export/chartexport.hxx @@ -232,10 +232,9 @@ private: void exportVaryColors(const css::uno::Reference<css::chart2::XChartType>& xChartType); void exportCandleStickSeries( - const css::uno::Sequence< - css::uno::Reference< - css::chart2::XDataSeries > > & aSeriesSeq, - bool& rPrimaryAxes ); + const css::uno::Sequence<css::uno::Reference<css::chart2::XDataSeries>>& aSeriesSeq, + bool& rPrimaryAxes, sal_uInt32& nIdx); + void exportSeriesText( const css::uno::Reference< css::chart2::data::XDataSequence >& xValueSeq, bool bIsChartex ); void exportSeriesCategory( diff --git a/oox/source/export/chartexport.cxx b/oox/source/export/chartexport.cxx index cdf758ce928d..bc3561b0b4c2 100644 --- a/oox/source/export/chartexport.cxx +++ b/oox/source/export/chartexport.cxx @@ -3349,13 +3349,15 @@ void ChartExport::exportStockChart( const Reference< chart2::XChartType >& xChar // Use a dummy data series to output needed basic chart-related XML even in case of empty charts aSplitDataSeries.push_back({}); } + + sal_uInt32 nIdx = 0; for (const auto& splitDataSeries : aSplitDataSeries) { pFS->startElement(FSNS(XML_c, XML_stockChart)); bool bPrimaryAxes = true; if (splitDataSeries.hasElements()) - exportCandleStickSeries(splitDataSeries, bPrimaryAxes); + exportCandleStickSeries(splitDataSeries, bPrimaryAxes, nIdx); // export stock properties Reference< css::chart::XStatisticDisplay > xStockPropProvider(mxDiagram, uno::UNO_QUERY); @@ -3757,8 +3759,7 @@ void ChartExport::exportSeries_chartex( const Reference<chart2::XChartType>& xCh } void ChartExport::exportCandleStickSeries( - const Sequence< Reference< chart2::XDataSeries > > & aSeriesSeq, - bool& rPrimaryAxes) + const Sequence<Reference<chart2::XDataSeries>>& aSeriesSeq, bool& rPrimaryAxes, sal_uInt32& nIdx) { for( const Reference< chart2::XDataSeries >& xSeries : aSeriesSeq ) { @@ -3773,12 +3774,13 @@ void ChartExport::exportCandleStickSeries( Sequence< Reference< chart2::data::XLabeledDataSequence > > aSeqCnt( xSource->getDataSequences()); - const char* sSeries[] = {"values-first","values-max","values-min","values-last",nullptr}; + const char* sSeries[] = {"values-first","values-max","values-min","values-last"}; - for( sal_Int32 idx = 0; sSeries[idx] != nullptr ; idx++ ) + for (const char* series : sSeries) { - Reference< chart2::data::XLabeledDataSequence > xLabeledSeq( lcl_getDataSequenceByRole( aSeqCnt, OUString::createFromAscii(sSeries[idx]) ) ); - if( xLabeledSeq.is()) + Reference<chart2::data::XLabeledDataSequence> xLabeledSeq( + lcl_getDataSequenceByRole(aSeqCnt, OUString::createFromAscii(series))); + if (xLabeledSeq.is()) { Reference< chart2::data::XDataSequence > xLabelSeq( xLabeledSeq->getLabel()); Reference< chart2::data::XDataSequence > xValueSeq( xLabeledSeq->getValues()); @@ -3786,12 +3788,8 @@ void ChartExport::exportCandleStickSeries( FSHelperPtr pFS = GetFS(); pFS->startElement(FSNS(XML_c, XML_ser)); - // TODO: idx and order - // idx attribute should start from 1 and not from 0. - pFS->singleElement( FSNS( XML_c, XML_idx ), - XML_val, OString::number(idx+1) ); - pFS->singleElement( FSNS( XML_c, XML_order ), - XML_val, OString::number(idx+1) ); + pFS->singleElement(FSNS(XML_c, XML_idx), XML_val, OString::number(++nIdx)); + pFS->singleElement(FSNS(XML_c, XML_order), XML_val, OString::number(nIdx)); // export label if( xLabelSeq.is() ) commit 6da61040c96608a94e485750350aaf99fa49e4a0 Author: Karthik Godha <[email protected]> AuthorDate: Mon Dec 15 09:35:58 2025 +0530 Commit: Andras Timar <[email protected]> CommitDate: Wed Jan 7 12:36:17 2026 +0100 tdf#169979: ODP->PPTX export missing p:pic element OLE objects when exported to PPTX should contain p:pic element in the XML. OLEs without graphic content don't export p:pic element, though this is a valid schema, PowerPoint doesn't accept this. Now empty p:pic element is exported for empty graphics Change-Id: Iac6fb988aa20e1bc9ae938d2a02dfc7b8dfae0c1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195623 Reviewed-by: Michael Stahl <[email protected]> Tested-by: Jenkins CollaboraOffice <[email protected]> diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx index 84f616574c5f..e07a72d9dcf5 100644 --- a/oox/source/export/shapes.cxx +++ b/oox/source/export/shapes.cxx @@ -2796,6 +2796,25 @@ void ShapeExport::WriteMathShape(Reference<XShape> const& xShape) mpFS->endElementNS(XML_mc, XML_AlternateContent); } +static void WriteEmptyGraphic(FSHelperPtr const& pFS, sal_Int32 nGraphicId) +{ + pFS->startElementNS(XML_p, XML_pic); + pFS->startElementNS(XML_p, XML_nvPicPr); + pFS->startElementNS(XML_p, XML_cNvPr, XML_id, OUString::number(nGraphicId), XML_name, "", + XML_descr, ""); + pFS->endElementNS(XML_p, XML_cNvPr); + pFS->startElementNS(XML_p, XML_cNvPicPr); + pFS->endElementNS(XML_p, XML_cNvPicPr); + pFS->startElementNS(XML_p, XML_nvPr); + pFS->endElementNS(XML_p, XML_nvPr); + pFS->endElementNS(XML_p, XML_nvPicPr); + pFS->startElementNS(XML_p, XML_blipFill); + pFS->endElementNS(XML_p, XML_blipFill); + pFS->startElementNS(XML_p, XML_spPr); + pFS->endElementNS(XML_p, XML_spPr); + pFS->endElementNS(XML_p, XML_pic); +} + ShapeExport& ShapeExport::WriteOLE2Shape( const Reference< XShape >& xShape ) { Reference< XPropertySet > xPropSet( xShape, UNO_QUERY ); @@ -3020,6 +3039,8 @@ ShapeExport& ShapeExport::WriteOLE2Shape( const Reference< XShape >& xShape ) const Graphic* pGraphic = pOle2Obj->GetGraphic(); if (pGraphic) WriteGraphicObjectShapePart(xShape, pGraphic); + else // Required for MSO + WriteEmptyGraphic(mpFS, GetNewShapeID(xShape)); } mpFS->endElementNS( mnXmlNamespace, XML_oleObj ); commit 525acf311c4d4258d12495a0f00096a97dd3ec4b Author: Karthik Godha <[email protected]> AuthorDate: Wed Dec 10 21:39:49 2025 +0530 Commit: Andras Timar <[email protected]> CommitDate: Wed Jan 7 12:36:11 2026 +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 0e3c2ee3d4d5..11c9d8ed481f 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; @@ -216,8 +218,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 3890e392d2aa..5d6072116420 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; @@ -1234,7 +1237,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); commit 4b99110f55bc1b49bc31c7aa9ce633f749fb5e92 Author: Karthik Godha <[email protected]> AuthorDate: Thu Dec 11 18:27:12 2025 +0530 Commit: Andras Timar <[email protected]> CommitDate: Wed Jan 7 12:36:05 2026 +0100 tdf#169941: ODP->PPTX exporting shape hyperlinks LO supports hyperlinks to shapes within the document. PowerPoint doesn't have this feature. Export of these shape hyperlinks is not handled. Now hyperlinks to shapes are converted to slides in which thy are present. Change-Id: I53f971c35a4f0f58532048b4041b0f35814b2715 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195465 Reviewed-by: Michael Stahl <[email protected]> Tested-by: Jenkins CollaboraOffice <[email protected]> diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index 226c2bc1e866..1ccfe0a5fbba 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -2482,6 +2482,25 @@ static OUString lcl_GetTarget(const css::uno::Reference<css::frame::XModel>& xMo sTarget = "slide" + OUString::number(i + 1) + ".xml"; break; } + else // If URL is linked to a shape, assign it's slide as target + { + Reference<XShapes> xShapes = xDrawPage; + sal_uInt32 nShapes = xShapes->getCount(); + for (sal_uInt32 j = 0; j < nShapes; j++) + { + Reference<XShape> xShape; + xShapes->getByIndex(j) >>= xShape; + Reference<container::XNamed> xName(xShape, UNO_QUERY); + if (!xName) + continue; + OUString sShapeName = "#" + xName->getName(); + if (rURL == sShapeName) + { + sTarget = "slide" + OUString::number(i + 1) + ".xml"; + break; + } + } + } } if (sTarget.isEmpty()) { @@ -2894,17 +2913,21 @@ void DrawingML::WriteRunProperties(const Reference<XPropertySet>& rRun, sal_Int3 bool bExtURL = URLTransformer().isExternalURL(sURL); sURL = bExtURL ? sURL : lcl_GetTarget(GetFB()->getModel(), sURL); - OUString sRelId - = mpFB->addRelation(mpFS->getOutputStream(), - bExtURL ? oox::getRelationship(Relationship::HYPERLINK) - : oox::getRelationship(Relationship::SLIDE), - sURL, bExtURL); - + OUString sRelId; + if (!sURL.isEmpty()) + { + sRelId + = mpFB->addRelation(mpFS->getOutputStream(), + bExtURL ? oox::getRelationship(Relationship::HYPERLINK) + : oox::getRelationship(Relationship::SLIDE), + sURL, 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, + sURL.isEmpty() ? "ppaction://noaction" : "ppaction://hlinksldjump"); } else { diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx index 3b20157f2988..84f616574c5f 100644 --- a/oox/source/export/shapes.cxx +++ b/oox/source/export/shapes.cxx @@ -751,6 +751,25 @@ static OUString lcl_GetTarget(const css::uno::Reference<css::frame::XModel>& xMo sTarget = "slide" + OUString::number(i + 1) + ".xml"; break; } + else // If URL is linked to a shape, assign it's slide as target + { + Reference<XShapes> xShapes = xDrawPage; + sal_uInt32 nShapes = xShapes->getCount(); + for (sal_uInt32 j = 0; j < nShapes; j++) + { + Reference<XShape> xShape; + xShapes->getByIndex(j) >>= xShape; + Reference<container::XNamed> xName(xShape, UNO_QUERY); + if (!xName) + continue; + OUString sShapeName = "#" + xName->getName(); + if (rURL == sShapeName) + { + sTarget = "slide" + OUString::number(i + 1) + ".xml"; + break; + } + } + } } return sTarget; commit 1c69a2e6143a4430ec11d73cf238baabb2561ad4 Author: Karthik Godha <[email protected]> AuthorDate: Mon Dec 8 18:54:06 2025 +0530 Commit: Andras Timar <[email protected]> CommitDate: Wed Jan 7 12:35:59 2026 +0100 tdf#169559: PPTX import master placeholder styles Master Slide placeholder styles are skipped during import of PPTX Change-Id: I33fdf4e66cd5c2ab461e125c302bcbd2ca2cf14b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195229 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Michael Stahl <[email protected]> diff --git a/oox/source/ppt/pptshape.cxx b/oox/source/ppt/pptshape.cxx index 98385c78e115..10ae157ee1fb 100644 --- a/oox/source/ppt/pptshape.cxx +++ b/oox/source/ppt/pptshape.cxx @@ -238,9 +238,6 @@ void PPTShape::addShape( ::oox::drawingml::ShapeIdMap* pShapeMap ) { SAL_INFO("oox.ppt","add shape id: " << msId << " location: " << ((meShapeLocation == Master) ? "master" : ((meShapeLocation == Slide) ? "slide" : ((meShapeLocation == Layout) ? "layout" : "other"))) << " subtype: " << mnSubType << " service: " << msServiceName); - // only placeholder from layout are being inserted - if ( mnSubType && ( meShapeLocation == Master ) ) - return; OUString sServiceName( msServiceName ); if (sServiceName.isEmpty()) @@ -522,6 +519,13 @@ void PPTShape::addShape( } else setMasterTextListStyle( aMasterTextListStyle ); + if (mnSubType && meShapeLocation == Master) + { + if (getTextBody() && !getTextBody()->isEmpty()) + setTextMasterStyles(rSlidePersist, rFilterBase, sServiceName); + return; + } + Reference< XShape > xShape( createAndInsert( rFilterBase, sServiceName, pTheme, rxShapes, bClearText, mpPlaceholder, aTransformation, getFillProperties() ) ); // Apply text properties on placeholder text inside this placeholder shape diff --git a/sd/qa/unit/data/pptx/tdf169524.pptx b/sd/qa/unit/data/pptx/tdf169524.pptx index f1e93c55ca3a..96361fffbef8 100644 Binary files a/sd/qa/unit/data/pptx/tdf169524.pptx and b/sd/qa/unit/data/pptx/tdf169524.pptx differ diff --git a/sd/qa/unit/export-tests-ooxml4.cxx b/sd/qa/unit/export-tests-ooxml4.cxx index 359119749dff..c851c99d5ceb 100644 --- a/sd/qa/unit/export-tests-ooxml4.cxx +++ b/sd/qa/unit/export-tests-ooxml4.cxx @@ -1859,6 +1859,18 @@ CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest4, testFooterIdxConsistency) // - In <>, attribute 'idx' of '//p:sp/p:nvSpPr/p:nvPr/p:ph' incorrect value. } +CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest4, testTdf169559) +{ + createSdImpressDoc("pptx/tdf169524.pptx"); + save(u"Impress Office Open XML"_ustr); + + xmlDocUniquePtr pXmlDoc = parseExport(u"ppt/slideMasters/slideMaster1.xml"_ustr); + assertXPath( + pXmlDoc, + "/p:sldMaster/p:cSld/p:spTree/p:sp[2]/p:txBody/a:lstStyle/a:lvl1pPr/a:spcAft/a:spcPts", + "val", u"1701"); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ commit 7be2769f115e8e45e7d13af69a5dab52482bdabc Author: Karthik Godha <[email protected]> AuthorDate: Thu Dec 4 20:38:04 2025 +0530 Commit: Andras Timar <[email protected]> CommitDate: Wed Jan 7 12:35:52 2026 +0100 tdf#169548: PPTX import of autoresize shapes If there is a mismatch b/w manually calculated and auto-generated sizes always use the larger one. Change-Id: I41e3b98d55990d2fa3f210e44af14ae8ccfc1d30 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195011 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Michael Stahl <[email protected]> diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index 659282c93d52..679f4a7d85a8 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -2383,6 +2383,9 @@ Reference< XShape > const & Shape::createAndInsert( if (!aOrigSize.IsEmpty() && (std::abs(aOrigSize.GetHeight() - aAutoSize.GetHeight()) > 1 || std::abs(aOrigSize.GetWidth() - aAutoSize.GetWidth()) > 1)) { + if (aAutoSize.GetHeight() > aOrigSize.GetHeight()) + aOrigSize.setHeight(aAutoSize.GetHeight()); + pShape->NbcSetLogicRect(aOrigSize, false); } } diff --git a/sd/qa/unit/import-tests2.cxx b/sd/qa/unit/import-tests2.cxx index cdae01a52184..27bcae8e651c 100644 --- a/sd/qa/unit/import-tests2.cxx +++ b/sd/qa/unit/import-tests2.cxx @@ -2296,6 +2296,12 @@ CPPUNIT_TEST_FIXTURE(SdImportTest2, testTdf169524) sal_Int32 nLeftMargin; xParagraph->getPropertyValue(u"ParaLeftMargin"_ustr) >>= nLeftMargin; CPPUNIT_ASSERT_EQUAL(sal_Int32(0), nLeftMargin); + + // Test tdf#169548 (uses the same test file) + uno::Reference<drawing::XShape> xRect(getShapeFromPage(0, 0), uno::UNO_QUERY); + CPPUNIT_ASSERT(xRect.is()); + sal_Int32 nHeight = xRect->getSize().Height; + CPPUNIT_ASSERT_EQUAL(sal_Int32(18073), nHeight); } CPPUNIT_PLUGIN_IMPLEMENT(); commit 92f6ec0835baca3b9f0be785c90bb46aad75bc38 Author: Tor Lillqvist <[email protected]> AuthorDate: Mon Mar 17 14:15:27 2025 +0200 Commit: Andras Timar <[email protected]> CommitDate: Wed Jan 7 12:33:55 2026 +0100 Avoid test failures with --disable-pdfimport Change-Id: I05b0af5dfff2fa4b12ec1216ca4e9667c0388b72 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183040 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> diff --git a/sc/qa/extras/scpdfexport.cxx b/sc/qa/extras/scpdfexport.cxx index 6ef9267e4ee5..533ce520af3e 100644 --- a/sc/qa/extras/scpdfexport.cxx +++ b/sc/qa/extras/scpdfexport.cxx @@ -235,6 +235,12 @@ void ScPDFExportTest::testPopupRectangleSize_Tdf162955() ScRange aRange(0, 0, 0, 0, 0, 0); exportToPDF(xModel, aRange); + std::shared_ptr<vcl::pdf::PDFium> pPDFium = vcl::pdf::PDFiumLibrary::get(); + if (!pPDFium) + { + return; + } + // Parse the export result with pdfium. std::unique_ptr<vcl::pdf::PDFiumDocument> pPdfDocument = parsePDFExport(); CPPUNIT_ASSERT_EQUAL(1, pPdfDocument->getPageCount()); diff --git a/sw/qa/extras/htmlexport/htmlexport2.cxx b/sw/qa/extras/htmlexport/htmlexport2.cxx index c1fe12df2435..81461fba24c8 100644 --- a/sw/qa/extras/htmlexport/htmlexport2.cxx +++ b/sw/qa/extras/htmlexport/htmlexport2.cxx @@ -7,6 +7,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include <config_features.h> + #include "htmlmodeltestbase.hxx" #include <config_poppler.h> #include <memory> @@ -1171,6 +1173,7 @@ CPPUNIT_TEST_FIXTURE(SwHtmlDomExportTest, testReqIF_ExportFormulasAsPDF) }; saveWithParams(aStoreProperties); +#if HAVE_FEATURE_PDFIMPORT // Make sure that the formula is exported as PDF: xmlDocUniquePtr pXmlDoc = WrapReqifFromTempFile(); assertXPath(pXmlDoc, "/reqif-xhtml:html/reqif-xhtml:div/reqif-xhtml:p[2]/reqif-xhtml:object",
