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 2de38fd9b0f2a2b7391d9a5394cf767cc0ed47b2
Author:     Miklos Vajna <[email protected]>
AuthorDate: Tue Nov 11 08:23:21 2025 +0100
Commit:     Caolán McNamara <[email protected]>
CommitDate: Tue Nov 11 11:52:25 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/+/193779
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Caolán McNamara <[email protected]>
    Tested-by: Caolán McNamara <[email protected]>

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 d24ee7a8ba9b..e58e85e90313 100644
--- a/sw/qa/filter/md/md.cxx
+++ b/sw/qa/filter/md/md.cxx
@@ -943,6 +943,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 59123bb93ea9..1ca7b97217a2 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