From 4347d505e7d1c90809dd356334fcdc7936c84f73 Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Thu, 22 Oct 2020 17:21:33 +0200 Subject: DOCX import: handle This refers to a self-contained full DOCX file inside a DOCX file. Change-Id: Ic9451833db30231f08ff2e2493da678edbc9a4c6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104654 Reviewed-by: Miklos Vajna Tested-by: Jenkins --- writerfilter/source/dmapper/DomainMapper.cxx | 12 +++-- writerfilter/source/dmapper/DomainMapper_Impl.cxx | 54 +++++++++++++++++++++++ writerfilter/source/dmapper/DomainMapper_Impl.hxx | 6 +++ 3 files changed, 69 insertions(+), 3 deletions(-) (limited to 'writerfilter/source/dmapper') diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index ca118c0f9c9b..938b1f41a106 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -169,8 +169,8 @@ DomainMapper::DomainMapper( const uno::Reference< uno::XComponentContext >& xCon //import document properties try { - uno::Reference< embed::XStorage > xDocumentStorage = - comphelper::OStorageHelper::GetStorageOfFormatFromInputStream(OFOPXML_STORAGE_FORMAT_STRING, xInputStream, xContext, bRepairStorage ); + m_pImpl->m_xDocumentStorage = comphelper::OStorageHelper::GetStorageOfFormatFromInputStream( + OFOPXML_STORAGE_FORMAT_STRING, xInputStream, xContext, bRepairStorage); uno::Reference< uno::XInterface > xTemp = xContext->getServiceManager()->createInstanceWithContext( "com.sun.star.document.OOXMLDocumentPropertiesImporter", @@ -178,7 +178,8 @@ DomainMapper::DomainMapper( const uno::Reference< uno::XComponentContext >& xCon uno::Reference< document::XOOXMLDocumentPropertiesImporter > xImporter( xTemp, uno::UNO_QUERY_THROW ); uno::Reference< document::XDocumentPropertiesSupplier > xPropSupplier( xModel, uno::UNO_QUERY_THROW); - xImporter->importProperties( xDocumentStorage, xPropSupplier->getDocumentProperties() ); + xImporter->importProperties(m_pImpl->m_xDocumentStorage, + xPropSupplier->getDocumentProperties()); } catch( const uno::Exception& ) {} } @@ -1230,6 +1231,11 @@ void DomainMapper::lcl_attribute(Id nName, Value & val) } } break; + case NS_ooxml::LN_CT_AltChunk: + { + m_pImpl->HandleAltChunk(sStringValue); + } + break; default: SAL_WARN("writerfilter", "DomainMapper::lcl_attribute: unhandled token: " << nName); } diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index f6ede7c143b4..fe1ab5c99b91 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -73,12 +73,19 @@ #include #include #include +#include +#include +#include +#include #include #include #include #include #include #include +#include +#include + #include #include @@ -3239,6 +3246,53 @@ void DomainMapper_Impl::ClearPreviousParagraph() m_bFirstParagraphInCell = true; } +void DomainMapper_Impl::HandleAltChunk(const OUString& rStreamName) +{ + try + { + // Create the import filter. + uno::Reference xMultiServiceFactory( + comphelper::getProcessServiceFactory()); + uno::Reference xDocxFilter + = xMultiServiceFactory->createInstance("com.sun.star.comp.Writer.WriterFilter"); + + // Set the target document. + uno::Reference xImporter(xDocxFilter, uno::UNO_QUERY); + xImporter->setTargetDocument(m_xTextDocument); + + // Set the import parameters. + uno::Reference xStorageAccess(m_xDocumentStorage, + uno::UNO_QUERY); + if (!xStorageAccess.is()) + { + return; + } + // Turn the ZIP stream into a seekable one, as the importer only works with such streams. + uno::Reference xStream = xStorageAccess->openStreamElementByHierarchicalName( + rStreamName, embed::ElementModes::READ); + std::unique_ptr pStream = utl::UcbStreamHelper::CreateStream(xStream, true); + SvMemoryStream aMemory; + aMemory.WriteStream(*pStream); + uno::Reference xInputStream = new utl::OStreamWrapper(aMemory); + // Not handling AltChunk during paste for now. + uno::Reference xInsertTextRange = GetCurrentXText()->getEnd(); + uno::Sequence aDescriptor(comphelper::InitPropertySequence({ + { "InputStream", uno::Any(xInputStream) }, + { "InsertMode", uno::Any(true) }, + { "TextInsertModeRange", uno::Any(xInsertTextRange) }, + })); + + // Do the actual import. + uno::Reference xFilter(xDocxFilter, uno::UNO_QUERY); + xFilter->filter(aDescriptor); + } + catch (const uno::Exception& rException) + { + SAL_WARN("writerfilter", "DomainMapper_Impl::HandleAltChunk: failed to handle alt chunk: " + << rException.Message); + } +} + static sal_Int16 lcl_ParseNumberingType( const OUString& rCommand ) { sal_Int16 nRet = style::NumberingType::PAGE_DESCRIPTOR; diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx index 4a45bc3f1fd2..50b5561076ef 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -1087,6 +1088,11 @@ public: bool IsParaWithInlineObject() const { return m_bParaWithInlineObject; } + css::uno::Reference< css::embed::XStorage > m_xDocumentStorage; + + /// Handles . + void HandleAltChunk(const OUString& rStreamName); + private: void PushPageHeaderFooter(bool bHeader, SectionPropertyMap::PageType eType); // Start a new index section; if needed, finish current paragraph -- cgit v1.2.3