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