sw/qa/writerfilter/dmapper/DomainMapper_Impl.cxx     |   16 +++++++
 sw/qa/writerfilter/dmapper/data/alt-chunk-html.docx  |binary
 sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx |   40 ++++++++++++-------
 3 files changed, 43 insertions(+), 13 deletions(-)

New commits:
commit c55ae722661d499cb27bc1f2727bc9873248adc5
Author:     ArsalanKhan04 <arsal...@gmail.com>
AuthorDate: Tue Apr 1 01:15:01 2025 +0500
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Fri Apr 4 19:28:52 2025 +0200

    tdf#163164 support altChunk referencing HTML in DOCX
    
    Change-Id: Ib6ff389f66dcc27dd2b2b07d66a1666ecb2c0518
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/183560
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>
    Tested-by: Jenkins

diff --git a/sw/qa/writerfilter/dmapper/DomainMapper_Impl.cxx 
b/sw/qa/writerfilter/dmapper/DomainMapper_Impl.cxx
index 040282e79d62..f9861b0dbe2a 100644
--- a/sw/qa/writerfilter/dmapper/DomainMapper_Impl.cxx
+++ b/sw/qa/writerfilter/dmapper/DomainMapper_Impl.cxx
@@ -144,6 +144,22 @@ CPPUNIT_TEST_FIXTURE(Test, testAltChunk)
     CPPUNIT_ASSERT_EQUAL(u"inner doc, first para"_ustr, xPara->getString());
 }
 
+CPPUNIT_TEST_FIXTURE(Test, testAltChunkHtml)
+{
+    loadFromFile(u"alt-chunk-html.docx");
+    uno::Reference<text::XTextDocument> xTextDocument(mxComponent, 
uno::UNO_QUERY_THROW);
+    uno::Reference<container::XEnumerationAccess> 
xParaEnumAccess(xTextDocument->getText(),
+                                                                  
uno::UNO_QUERY_THROW);
+    uno::Reference<container::XEnumeration> xParaEnum = 
xParaEnumAccess->createEnumeration();
+    uno::Reference<text::XTextRange> xPara;
+    xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY_THROW);
+    CPPUNIT_ASSERT_EQUAL(u"outer para 1"_ustr, xPara->getString());
+    xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY_THROW);
+    CPPUNIT_ASSERT_EQUAL(u"HTML AltChunk"_ustr, xPara->getString());
+    xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY_THROW);
+    CPPUNIT_ASSERT_EQUAL(u"outer para 2"_ustr, xPara->getString());
+}
+
 CPPUNIT_TEST_FIXTURE(Test, testFieldIfInsideIf)
 {
     // Load a document with a field in a table cell: it contains an IF field 
with various nested
diff --git a/sw/qa/writerfilter/dmapper/data/alt-chunk-html.docx 
b/sw/qa/writerfilter/dmapper/data/alt-chunk-html.docx
new file mode 100644
index 000000000000..88a97ffe764e
Binary files /dev/null and 
b/sw/qa/writerfilter/dmapper/data/alt-chunk-html.docx differ
diff --git a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx 
b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
index bd783e03e6c3..fd958abc424b 100644
--- a/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
+++ b/sw/source/writerfilter/dmapper/DomainMapper_Impl.cxx
@@ -33,6 +33,7 @@
 #include <com/sun/star/beans/XPropertyState.hpp>
 #include <com/sun/star/container/XNamed.hpp>
 #include <com/sun/star/document/PrinterIndependentLayout.hpp>
+#include <com/sun/star/document/XTypeDetection.hpp>
 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
 #include <com/sun/star/embed/XEmbeddedObject.hpp>
 #include <com/sun/star/i18n/NumberFormatMapper.hpp>
@@ -103,6 +104,7 @@
 #include <tools/UnitConversion.hxx>
 #include <unotools/ucbstreamhelper.hxx>
 #include <unotools/streamwrap.hxx>
+#include <comphelper/processfactory.hxx>
 #include <comphelper/scopeguard.hxx>
 #include <comphelper/string.hxx>
 
@@ -5302,17 +5304,6 @@ void DomainMapper_Impl::HandleAltChunk(const OUString& 
rStreamName)
 {
     try
     {
-        // Create the import filter.
-        uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(
-            comphelper::getProcessServiceFactory());
-        uno::Reference<uno::XInterface> xDocxFilter
-            = 
xMultiServiceFactory->createInstance(u"com.sun.star.comp.Writer.WriterFilter"_ustr);
-
-        // Set the target document.
-        uno::Reference<document::XImporter> xImporter(xDocxFilter, 
uno::UNO_QUERY);
-        
xImporter->setTargetDocument(static_cast<SfxBaseModel*>(m_xTextDocument.get()));
-
-        // Set the import parameters.
         uno::Reference<embed::XHierarchicalStorageAccess> 
xStorageAccess(m_xDocumentStorage,
                                                                          
uno::UNO_QUERY);
         if (!xStorageAccess.is())
@@ -5342,9 +5333,32 @@ void DomainMapper_Impl::HandleAltChunk(const OUString& 
rStreamName)
             { "AltChunkStartingRange", uno::Any(xSectionStartingRange) },
         }));
 
+        uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(
+            comphelper::getProcessServiceFactory());
+        // Detecting AltChunk type to handle with the appropriate filter
+        uno::Reference<document::XTypeDetection> xTypeDetection(
+            
xMultiServiceFactory->createInstance(u"com.sun.star.document.TypeDetection"_ustr),
 uno::UNO_QUERY);
+        xTypeDetection->queryTypeByDescriptor(aDescriptor, 
/*bAllowDeepDetection*/true);
+        OUString sFilterName = 
comphelper::SequenceAsHashMap(aDescriptor).getUnpackedValueOrDefault(u"FilterName"_ustr,
 OUString());
+
+        uno::Reference<lang::XMultiServiceFactory> 
xFilters(xMultiServiceFactory->createInstance(u"com.sun.star.document.FilterFactory"_ustr),
 uno::UNO_QUERY_THROW);
+        uno::Reference<document::XFilter> 
xFilter(xFilters->createInstance(sFilterName), uno::UNO_QUERY);
+
         // Do the actual import.
-        uno::Reference<document::XFilter> xFilter(xDocxFilter, uno::UNO_QUERY);
-        xFilter->filter(aDescriptor);
+        if (xFilter)
+        {
+            // Set the target document
+            uno::Reference<document::XImporter> xImporter(xFilter, 
uno::UNO_QUERY);
+            
xImporter->setTargetDocument(static_cast<SfxBaseModel*>(m_xTextDocument.get()));
+            xFilter->filter(aDescriptor);
+        }
+        else
+        {
+            // In case no xFilter found, will try insertDocumentFromURL (this 
is needed for HTML altchunks)
+            uno::Reference<text::XTextCursor> 
xCursor(GetCurrentXText()->createTextCursorByRange(xInsertTextRange));
+            uno::Reference<document::XDocumentInsertable> xDocInsert(xCursor, 
uno::UNO_QUERY);
+            xDocInsert->insertDocumentFromURL(u"private:stream"_ustr, 
aDescriptor);
+        }
     }
     catch (const uno::Exception& rException)
     {

Reply via email to