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&)

Reply via email to