sw/qa/filter/md/data/template.docx |binary sw/qa/filter/md/md.cxx | 26 ++++++++++++++++++++++++++ sw/source/filter/md/swmd.cxx | 36 +++++++++++++++++++++++++----------- 3 files changed, 51 insertions(+), 11 deletions(-)
New commits: commit 6d1312e160ee8c2c0f65b6e0a86333bf3c9c60ce Author: Miklos Vajna <[email protected]> AuthorDate: Tue Nov 11 08:23:21 2025 +0100 Commit: Miklos Vajna <[email protected]> CommitDate: Tue Nov 11 15:25:34 2025 +0100 tdf#169316 sw markdown import, template: handle non-ODF formats as well Load a markdown file, specify a DOCX template using soffice --infilter='Markdown:{"TemplateURL":{"type":"string","value":"./template.docx"}}' test.md and the load fails. This happens because SfxObjectShell::LoadFrom() is affectively pure-virtual and SwDocShell::LoadFrom() calls ReadXML, expects a styles.xml -- not designed to be called with non-ODF input. Fix the problem by loading the template using loadComponentFromURL() in hidden mode, then LoadStyles() can still take the styles from the template to the markdown document. This way we get type detection for free, too. Change-Id: I71325f810c9065281f3b1ad0dcdb01ba96c32476 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193797 Reviewed-by: Miklos Vajna <[email protected]> Tested-by: Jenkins diff --git a/sw/qa/filter/md/data/template.docx b/sw/qa/filter/md/data/template.docx new file mode 100644 index 000000000000..d7d13d5f559e Binary files /dev/null and b/sw/qa/filter/md/data/template.docx differ diff --git a/sw/qa/filter/md/md.cxx b/sw/qa/filter/md/md.cxx index 147759ed4214..8134ff09939a 100644 --- a/sw/qa/filter/md/md.cxx +++ b/sw/qa/filter/md/md.cxx @@ -953,6 +953,32 @@ CPPUNIT_TEST_FIXTURE(Test, testTemplateMdImport) CPPUNIT_ASSERT_EQUAL(Color(0x156082), pXFillColorItem->GetColorValue()); } +CPPUNIT_TEST_FIXTURE(Test, testDocxTemplateMdImport) +{ + // Given a document with a DOCX template: + setImportFilterOptions(uR"json({ + "TemplateURL": { + "type": "string", + "value": "./template.docx" + } +})json"_ustr); + + // When importing that markdown: + // Without the accompanying fix in place, this crashed. + createSwDoc("template.md"); + + // Then make sure the styles are taken from the template: + SwDocShell* pDocShell = getSwDocShell(); + SwWrtShell* pWrtShell = pDocShell->GetWrtShell(); + SwCursor* pCursor = pWrtShell->GetCursor(); + SwTextNode* pTextNode = pCursor->GetPointNode().GetTextNode(); + SwFormatColl* pStyle = pTextNode->GetFormatColl(); + auto pXFillStyleItem = pStyle->GetAttrSet().GetItem<XFillStyleItem>(XATTR_FILLSTYLE); + CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_SOLID, pXFillStyleItem->GetValue()); + auto pXFillColorItem = pStyle->GetAttrSet().GetItem<XFillColorItem>(XATTR_FILLCOLOR); + CPPUNIT_ASSERT_EQUAL(Color(0x156082), pXFillColorItem->GetColorValue()); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sw/source/filter/md/swmd.cxx b/sw/source/filter/md/swmd.cxx index f96114b7319a..08d8fa39abe4 100644 --- a/sw/source/filter/md/swmd.cxx +++ b/sw/source/filter/md/swmd.cxx @@ -19,14 +19,14 @@ #include <boost/property_tree/json_parser/error.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/frame/Desktop.hpp> + #include <osl/diagnose.h> -#include <list.hxx> #include <numrule.hxx> #include <node.hxx> #include <ndtxt.hxx> -#include <fmthdft.hxx> #include <fltini.hxx> -#include <itabenum.hxx> #include <fchrfmt.hxx> #include <swerror.h> #include <strings.hrc> @@ -36,7 +36,6 @@ #include <hintids.hxx> #include <sfx2/docfile.hxx> #include <sfx2/sfxsids.hrc> -#include <svl/itemiter.hxx> #include <IDocumentStylePoolAccess.hxx> #include <fmtinfmt.hxx> #include <frmatr.hxx> @@ -49,9 +48,11 @@ #include <comphelper/propertysequence.hxx> #include <comphelper/sequence.hxx> #include <comphelper/sequenceashashmap.hxx> +#include <comphelper/processfactory.hxx> +#include <comphelper/propertyvalue.hxx> +#include <sfx2/sfxbasemodel.hxx> #include <rtl/uri.hxx> #include <ndgrf.hxx> -#include <fmtcntnt.hxx> #include <swtypes.hxx> #include <fmturl.hxx> #include <formatcontentcontrol.hxx> @@ -799,17 +800,30 @@ void MarkdownReader::SetupFilterOptions(SwDoc& rDoc) return; } - SfxObjectShellLock xTemplateDoc = SfxObjectShell::CreateObjectByFactoryName( - pDocShell->GetFactory().GetFactoryName(), SfxObjectCreateMode::ORGANIZER); - xTemplateDoc->DoInitNew(); - SfxMedium aTemplateMedium(aTemplateURL, StreamMode::STD_READ); - if (!xTemplateDoc->LoadFrom(aTemplateMedium)) + // Go via filter detection so non-ODF templates work, too. + uno::Reference<uno::XComponentContext> xContext = comphelper::getProcessComponentContext(); + uno::Reference<frame::XDesktop2> xComponentLoader = frame::Desktop::create(xContext); + uno::Sequence<css::beans::PropertyValue> aTemplateArgs = { + comphelper::makePropertyValue("Hidden", true), + }; + uno::Reference<lang::XComponent> xTemplateComponent + = xComponentLoader->loadComponentFromURL(aTemplateURL, u"_blank"_ustr, 0, aTemplateArgs); + auto pTemplateModel = dynamic_cast<SfxBaseModel*>(xTemplateComponent.get()); + if (!pTemplateModel) + { + return; + } + + SfxObjectShell* pTemplateShell = pTemplateModel->GetObjectShell(); + if (!pTemplateShell) { return; } // Copy the styles from the template doc to our document. - pDocShell->LoadStyles(*xTemplateDoc); + pDocShell->LoadStyles(*pTemplateShell); + + xTemplateComponent->dispose(); } ErrCodeMsg MarkdownReader::Read(SwDoc& rDoc, const OUString& rBaseURL, SwPaM& rPam, const OUString&)
