sw/qa/extras/ooxmlexport/data/tdf169274.docx |binary sw/qa/extras/ooxmlexport/ooxmlexport25.cxx | 13 +++++++++ sw/source/writerfilter/dmapper/DomainMapper.cxx | 34 +++++++++++++----------- 3 files changed, 32 insertions(+), 15 deletions(-)
New commits: commit e30ba5582ff40c016978b40318ed861d075f7b6f Author: Karthik Godha <[email protected]> AuthorDate: Wed Nov 5 20:45:26 2025 +0530 Commit: Michael Stahl <[email protected]> CommitDate: Mon Dec 15 14:29:05 2025 +0100 tdf#169274: Fix export of SDTs with DataBindings Run-level SDTs containing DataBinding properties are exported twice which results in corrupted XML Change-Id: I24bcdf76a5cac850257b36f5a042d5b61a74118d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193467 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Michael Stahl <[email protected]> (cherry picked from commit d2b7ec90d4d8a85091dc985092ba000b0acad540) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195635 Tested-by: Michael Stahl <[email protected]> diff --git a/sw/qa/extras/ooxmlexport/data/tdf169274.docx b/sw/qa/extras/ooxmlexport/data/tdf169274.docx new file mode 100644 index 000000000000..f9ce604adf58 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf169274.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport25.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport25.cxx index 1b0f0d794b09..c49120ac2834 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport25.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport25.cxx @@ -196,6 +196,19 @@ CPPUNIT_TEST_FIXTURE(Test, testWNumDuplication) CPPUNIT_ASSERT_EQUAL(10, countXPathNodes(pXmlNum, "//w:numbering/w:num")); } +CPPUNIT_TEST_FIXTURE(Test, testTdf169274) +{ + loadAndSave("tdf169274.docx"); + + xmlDocUniquePtr pXmlDoc = parseExport(u"word/document.xml"_ustr); + const OString sPath = "//w:body/w:tbl/w:tr/w:tc/w:p/w:sdt/"_ostr; + + // Verify SDT exists with dataBinding property + assertXPath(pXmlDoc, sPath + "w:sdtPr/w:dataBinding", 1); + // Verify there are no nested SDTs + assertXPath(pXmlDoc, sPath + "w:sdtContent/w:sdt", 0); +} + } // end of anonymous namespace CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/writerfilter/dmapper/DomainMapper.cxx b/sw/source/writerfilter/dmapper/DomainMapper.cxx index e85eaa77ac96..721a7b6a0a55 100644 --- a/sw/source/writerfilter/dmapper/DomainMapper.cxx +++ b/sw/source/writerfilter/dmapper/DomainMapper.cxx @@ -4463,12 +4463,21 @@ void DomainMapper::lcl_utext(const sal_Unicode *const data_, size_t len) m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear(); return; } - if((m_pImpl->m_pSdtHelper->containedInInteropGrabBag(u"ooxml:CT_SdtPr_checkbox"_ustr) || - m_pImpl->m_pSdtHelper->containedInInteropGrabBag(u"ooxml:CT_SdtPr_text"_ustr) || - m_pImpl->m_pSdtHelper->containedInInteropGrabBag(u"ooxml:CT_SdtPr_dataBinding"_ustr) || - m_pImpl->m_pSdtHelper->containedInInteropGrabBag(u"ooxml:CT_SdtPr_citation"_ustr) || - (m_pImpl->m_pSdtHelper->containedInInteropGrabBag(u"ooxml:CT_SdtPr_id"_ustr) && - m_pImpl->m_pSdtHelper->getInteropGrabBagSize() == 1)) && !m_pImpl->m_pSdtHelper->isOutsideAParagraph()) + const SdtControlType aControlType = m_pImpl->m_pSdtHelper->getControlType(); + if (aControlType != SdtControlType::unsupported && aControlType != SdtControlType::unknown + && m_pImpl->m_pSdtHelper->GetSdtType() == NS_ooxml::LN_CT_SdtRun_sdtContent) + { + m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear(); + } + else if ((m_pImpl->m_pSdtHelper->containedInInteropGrabBag(u"ooxml:CT_SdtPr_checkbox"_ustr) + || m_pImpl->m_pSdtHelper->containedInInteropGrabBag(u"ooxml:CT_SdtPr_text"_ustr) + || m_pImpl->m_pSdtHelper->containedInInteropGrabBag( + u"ooxml:CT_SdtPr_dataBinding"_ustr) + || m_pImpl->m_pSdtHelper->containedInInteropGrabBag( + u"ooxml:CT_SdtPr_citation"_ustr) + || (m_pImpl->m_pSdtHelper->containedInInteropGrabBag(u"ooxml:CT_SdtPr_id"_ustr) + && m_pImpl->m_pSdtHelper->getInteropGrabBagSize() == 1)) + && !m_pImpl->m_pSdtHelper->isOutsideAParagraph()) { PropertyMapPtr pContext = m_pImpl->GetTopContextOfType(CONTEXT_CHARACTER); @@ -4477,20 +4486,15 @@ void DomainMapper::lcl_utext(const sal_Unicode *const data_, size_t len) pContext = m_pImpl->GetTopFieldContext()->getProperties(); uno::Sequence<beans::PropertyValue> aGrabBag = m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear(); - if (m_pImpl->GetSdtStarts().empty() - || (m_pImpl->m_pSdtHelper->getControlType() != SdtControlType::dropDown - && m_pImpl->m_pSdtHelper->getControlType() != SdtControlType::comboBox)) - { - pContext->Insert(PROP_SDTPR, uno::Any(aGrabBag), true, CHAR_GRAB_BAG); - } + pContext->Insert(PROP_SDTPR, uno::Any(aGrabBag), true, CHAR_GRAB_BAG); } else { uno::Sequence<beans::PropertyValue> aGrabBag = m_pImpl->m_pSdtHelper->getInteropGrabBagAndClear(); if (m_pImpl->GetSdtStarts().empty() - || (m_pImpl->m_pSdtHelper->getControlType() != SdtControlType::dropDown - && m_pImpl->m_pSdtHelper->getControlType() != SdtControlType::comboBox - && m_pImpl->m_pSdtHelper->getControlType() != SdtControlType::richText)) + || (aControlType != SdtControlType::dropDown + && aControlType != SdtControlType::comboBox + && aControlType != SdtControlType::richText)) { m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)->Insert(PROP_SDTPR, uno::Any(aGrabBag), true, PARA_GRAB_BAG);
