diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2015-02-22 11:31:16 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2015-02-22 17:40:36 +0100 |
commit | 9ea95a1dbd7e10343a3549c2cbc1b909a873f5f7 (patch) | |
tree | 554186933d86547e756a3c72ec2162eb0b22c8f2 | |
parent | f5ffba36cdf82d7540381e0a0b3200c9c585921d (diff) |
writerfilter: clean up DOCX XFilter implementation
Change-Id: I4524d0a93231f291e074d1eeb10d00efc64e0cc5
-rw-r--r-- | writerfilter/Library_writerfilter.mk | 2 | ||||
-rw-r--r-- | writerfilter/source/filter/ImportFilter.cxx | 354 | ||||
-rw-r--r-- | writerfilter/source/filter/WriterFilter.cxx | 381 | ||||
-rw-r--r-- | writerfilter/source/filter/WriterFilter.hxx | 98 |
4 files changed, 382 insertions, 453 deletions
diff --git a/writerfilter/Library_writerfilter.mk b/writerfilter/Library_writerfilter.mk index f3af37a00252..6149401d284c 100644 --- a/writerfilter/Library_writerfilter.mk +++ b/writerfilter/Library_writerfilter.mk @@ -112,8 +112,8 @@ $(eval $(call gb_Library_add_exception_objects,writerfilter,\ writerfilter/source/dmapper/ThemeTable \ writerfilter/source/dmapper/WrapPolygonHandler \ writerfilter/source/dmapper/util \ - writerfilter/source/filter/ImportFilter \ writerfilter/source/filter/RtfFilter \ + writerfilter/source/filter/WriterFilter \ writerfilter/source/filter/WriterFilterDetection \ writerfilter/source/ooxml/Handler \ writerfilter/source/ooxml/OOXMLBinaryObjectReference \ diff --git a/writerfilter/source/filter/ImportFilter.cxx b/writerfilter/source/filter/ImportFilter.cxx deleted file mode 100644 index 5d43ff5e2ef0..000000000000 --- a/writerfilter/source/filter/ImportFilter.cxx +++ /dev/null @@ -1,354 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#include <osl/diagnose.h> -#include <com/sun/star/uno/XComponentContext.hpp> -#include <com/sun/star/beans/XPropertySet.hpp> -#include <com/sun/star/drawing/XDrawPageSupplier.hpp> -#include <com/sun/star/io/XInputStream.hpp> -#include <com/sun/star/lang/XMultiServiceFactory.hpp> -#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp> -#include <com/sun/star/io/WrongFormatException.hpp> -#include <com/sun/star/xml/sax/SAXParseException.hpp> -#include <unotools/mediadescriptor.hxx> -#include <cppuhelper/exc_hlp.hxx> -#include <cppuhelper/supportsservice.hxx> -#include <oox/core/filterdetect.hxx> -#include <dmapper/DomainMapperFactory.hxx> -#include <WriterFilter.hxx> -#include <ooxml/OOXMLDocument.hxx> -#ifdef DEBUG_WRITERFILTER -#include <iostream> -#include <osl/process.h> -#endif - -#include <oox/ole/olestorage.hxx> -#include <oox/ole/vbaproject.hxx> -#include <oox/helper/graphichelper.hxx> - -using namespace ::com::sun::star; - - -static OUString lcl_GetExceptionMessageRec(xml::sax::SAXException const& e); - -static OUString lcl_GetExceptionMessage(xml::sax::SAXException const& e) -{ - OUString const thisMessage("SAXParseException: " - "\"" + e.Message + "\""); - OUString const restMessage(lcl_GetExceptionMessageRec(e)); - return restMessage + "\n" + thisMessage; -} -static OUString lcl_GetExceptionMessage(xml::sax::SAXParseException const& e) -{ - OUString const thisMessage("SAXParseException: " - "\"" + e.Message + "\" " - "stream \"" + e.SystemId + "\"" - ", Line " + OUString::number(e.LineNumber) - + ", Column " + OUString::number(e.ColumnNumber)); - OUString const restMessage(lcl_GetExceptionMessageRec(e)); - return restMessage + "\n" + thisMessage; -} -static OUString lcl_GetExceptionMessageRec(xml::sax::SAXException const& e) -{ - xml::sax::SAXParseException saxpe; - if (e.WrappedException >>= saxpe) - { - return lcl_GetExceptionMessage(saxpe); - } - xml::sax::SAXException saxe; - if (e.WrappedException >>= saxe) - { - return lcl_GetExceptionMessage(saxe); - } - uno::Exception ue; - if (e.WrappedException >>= ue) - { - return ue.Message; - } - return OUString(); -} - -sal_Bool WriterFilter::filter( const uno::Sequence< beans::PropertyValue >& aDescriptor ) - throw (uno::RuntimeException, std::exception) -{ - if( m_xSrcDoc.is() ) - { - uno::Reference< lang::XMultiServiceFactory > xMSF(m_xContext->getServiceManager(), uno::UNO_QUERY_THROW); - uno::Reference< uno::XInterface > xIfc; - try { - xIfc.set( - xMSF->createInstance("com.sun.star.comp.Writer.DocxExport"), - uno::UNO_QUERY_THROW); - } catch (css::uno::RuntimeException &) { - throw; - } catch (css::uno::Exception & e) { - css::uno::Any a(cppu::getCaughtException()); - throw css::lang::WrappedTargetRuntimeException( - "wrapped " + a.getValueTypeName() + ": " + e.Message, - css::uno::Reference<css::uno::XInterface>(), a); - } - uno::Reference< document::XExporter > xExprtr(xIfc, uno::UNO_QUERY_THROW); - uno::Reference< document::XFilter > xFltr(xIfc, uno::UNO_QUERY_THROW); - if (!xExprtr.is() || !xFltr.is()) - return sal_False; - xExprtr->setSourceDocument(m_xSrcDoc); - return xFltr->filter(aDescriptor); - } - else if (m_xDstDoc.is()) - { - utl::MediaDescriptor aMediaDesc( aDescriptor ); - bool bRepairStorage = aMediaDesc.getUnpackedValueOrDefault( "RepairPackage", false ); - - uno::Reference< io::XInputStream > xInputStream; - try - { - // use the oox.core.FilterDetect implementation to extract the decrypted ZIP package - ::oox::core::FilterDetect aDetector( m_xContext ); - xInputStream = aDetector.extractUnencryptedPackage( aMediaDesc ); - } - catch( uno::Exception& ) - { - } - - if ( !xInputStream.is() ) - return sal_False; - - writerfilter::dmapper::SourceDocumentType eType = writerfilter::dmapper::SourceDocumentType::OOXML; - writerfilter::Stream::Pointer_t pStream( - writerfilter::dmapper::DomainMapperFactory::createMapper(m_xContext, xInputStream, m_xDstDoc, bRepairStorage, eType, uno::Reference<text::XTextRange>(), aMediaDesc)); - //create the tokenizer and domain mapper - writerfilter::ooxml::OOXMLStream::Pointer_t pDocStream = writerfilter::ooxml::OOXMLDocumentFactory::createStream(m_xContext, xInputStream, bRepairStorage); - uno::Reference<task::XStatusIndicator> xStatusIndicator = aMediaDesc.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_STATUSINDICATOR(), uno::Reference<task::XStatusIndicator>()); - writerfilter::ooxml::OOXMLDocument::Pointer_t pDocument(writerfilter::ooxml::OOXMLDocumentFactory::createDocument(pDocStream, xStatusIndicator)); - - uno::Reference<frame::XModel> xModel(m_xDstDoc, uno::UNO_QUERY_THROW); - pDocument->setModel(xModel); - - uno::Reference<drawing::XDrawPageSupplier> xDrawings - (m_xDstDoc, uno::UNO_QUERY_THROW); - uno::Reference<drawing::XDrawPage> xDrawPage - (xDrawings->getDrawPage(), uno::UNO_SET_THROW); - pDocument->setDrawPage(xDrawPage); - - try - { - pDocument->resolve(*pStream); - } - catch (xml::sax::SAXParseException const& e) - { - // note: SfxObjectShell checks for WrongFormatException - io::WrongFormatException wfe(lcl_GetExceptionMessage(e)); - throw lang::WrappedTargetRuntimeException("", - static_cast<OWeakObject*>(this), uno::makeAny(wfe)); - } - catch (xml::sax::SAXException const& e) - { - // note: SfxObjectShell checks for WrongFormatException - io::WrongFormatException wfe(lcl_GetExceptionMessage(e)); - throw lang::WrappedTargetRuntimeException("", - static_cast<OWeakObject*>(this), uno::makeAny(wfe)); - } - catch (uno::RuntimeException const&) - { - throw; - } - catch (uno::Exception const& e) - { - SAL_WARN("writerfilter", "WriterFilter::filter(): " - "failed with exception " << e.Message); - throw lang::WrappedTargetRuntimeException("", - static_cast<OWeakObject*>(this), uno::makeAny(e)); - } - - // Adding some properties to the document's grab bag for interoperability purposes: - comphelper::SequenceAsHashMap aGrabBagProperties; - - // Adding the saved Theme DOM - aGrabBagProperties["OOXTheme"] = uno::makeAny( pDocument->getThemeDom() ); - - // Adding the saved custom xml DOM - aGrabBagProperties["OOXCustomXml"] = uno::makeAny( pDocument->getCustomXmlDomList() ); - aGrabBagProperties["OOXCustomXmlProps"] = uno::makeAny( pDocument->getCustomXmlDomPropsList() ); - - // Adding the saved ActiveX DOM - aGrabBagProperties["OOXActiveX"] = uno::makeAny( pDocument->getActiveXDomList() ); - aGrabBagProperties["OOXActiveXBin"] = uno::makeAny( pDocument->getActiveXBinList() ); - - // Adding the saved Glossary Documnet DOM to the document's grab bag - aGrabBagProperties["OOXGlossary"] = uno::makeAny( pDocument->getGlossaryDocDom() ); - aGrabBagProperties["OOXGlossaryDom"] = uno::makeAny( pDocument->getGlossaryDomList() ); - - // Adding the saved embedding document to document's grab bag - aGrabBagProperties["OOXEmbeddings"] = uno::makeAny( pDocument->getEmbeddingsList() ); - - putPropertiesToDocumentGrabBag( aGrabBagProperties ); - - writerfilter::ooxml::OOXMLStream::Pointer_t pVBAProjectStream(writerfilter::ooxml::OOXMLDocumentFactory::createStream( pDocStream, writerfilter::ooxml::OOXMLStream::VBAPROJECT )); - oox::StorageRef xVbaPrjStrg( new ::oox::ole::OleStorage( m_xContext, pVBAProjectStream->getDocumentStream(), false ) ); - if( xVbaPrjStrg.get() && xVbaPrjStrg->isStorage() ) - { - ::oox::ole::VbaProject aVbaProject( m_xContext, xModel, "Writer" ); - uno::Reference< frame::XFrame > xFrame = aMediaDesc.getUnpackedValueOrDefault( utl::MediaDescriptor::PROP_FRAME(), uno::Reference< frame::XFrame > () ); - - // if no XFrame try fallback to what we can glean from the Model - if ( !xFrame.is() ) - { - uno::Reference< frame::XController > xController = xModel->getCurrentController(); - xFrame = xController.is() ? xController->getFrame() : nullptr; - } - - oox::GraphicHelper gHelper( m_xContext, xFrame, xVbaPrjStrg ); - aVbaProject.importVbaProject( *xVbaPrjStrg, gHelper ); - } - - // Document signature. - writerfilter::ooxml::OOXMLStream::Pointer_t pSignatureStream; - pSignatureStream = writerfilter::ooxml::OOXMLDocumentFactory::createStream(m_xContext, xInputStream, bRepairStorage, writerfilter::ooxml::OOXMLStream::SIGNATURE); - if (pSignatureStream->getDocumentStream().is()) - { - // TODO found, handle it. - } - - pStream.reset(); - - return sal_True; - } - return sal_False; -} - - -void WriterFilter::cancel( ) throw (uno::RuntimeException, std::exception) -{ -} - - - -void WriterFilter::setTargetDocument( const uno::Reference< lang::XComponent >& xDoc ) - throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) -{ - m_xDstDoc = xDoc; - - // Set some compatibility options that are valid for all the formats - uno::Reference< lang::XMultiServiceFactory > xFactory( xDoc, uno::UNO_QUERY ); - uno::Reference< beans::XPropertySet > xSettings( xFactory->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY ); - - xSettings->setPropertyValue( "AddFrameOffsets", uno::makeAny( sal_True ) ); - xSettings->setPropertyValue( "UseOldNumbering", uno::makeAny( sal_False ) ); - xSettings->setPropertyValue( "IgnoreFirstLineIndentInNumbering", uno::makeAny( sal_False ) ); - xSettings->setPropertyValue( "DoNotResetParaAttrsForNumFont", uno::makeAny( sal_False ) ); - xSettings->setPropertyValue( "UseFormerLineSpacing", uno::makeAny( sal_False ) ); - xSettings->setPropertyValue( "AddParaSpacingToTableCells", uno::makeAny( sal_True ) ); - xSettings->setPropertyValue( "UseFormerObjectPositioning", uno::makeAny( sal_False ) ); - xSettings->setPropertyValue( "ConsiderTextWrapOnObjPos", uno::makeAny( sal_True ) ); - xSettings->setPropertyValue( "UseFormerTextWrapping", uno::makeAny( sal_False ) ); - xSettings->setPropertyValue( "TableRowKeep", uno::makeAny( sal_True ) ); - xSettings->setPropertyValue( "IgnoreTabsAndBlanksForLineCalculation", uno::makeAny( sal_True ) ); - xSettings->setPropertyValue( "InvertBorderSpacing", uno::makeAny( sal_True ) ); - xSettings->setPropertyValue( "CollapseEmptyCellPara", uno::makeAny( sal_True ) ); - xSettings->setPropertyValue( "TabOverflow", uno::makeAny( sal_True ) ); - xSettings->setPropertyValue( "UnbreakableNumberings", uno::makeAny( sal_True ) ); - - xSettings->setPropertyValue("FloattableNomargins", uno::makeAny( sal_True )); - xSettings->setPropertyValue( "ClippedPictures", uno::makeAny( sal_True ) ); - xSettings->setPropertyValue( "BackgroundParaOverDrawings", uno::makeAny( sal_True ) ); - xSettings->setPropertyValue( "TabOverMargin", uno::makeAny( sal_True ) ); - xSettings->setPropertyValue("PropLineSpacingShrinksFirstLine", uno::makeAny(sal_True)); -} - -void WriterFilter::setSourceDocument( const uno::Reference< lang::XComponent >& xDoc ) - throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) -{ - m_xSrcDoc = xDoc; -} - - - -void WriterFilter::initialize( const uno::Sequence< uno::Any >& /*aArguments*/ ) throw (uno::Exception, uno::RuntimeException, std::exception) -{ -} - - -OUString WriterFilter_getImplementationName () throw (uno::RuntimeException) -{ - return OUString ( "com.sun.star.comp.Writer.WriterFilter" ); -} - -uno::Sequence< OUString > WriterFilter_getSupportedServiceNames( ) throw (uno::RuntimeException) -{ - uno::Sequence < OUString > aRet(2); - OUString* pArray = aRet.getArray(); - pArray[0] = "com.sun.star.document.ImportFilter"; - pArray[1] = "com.sun.star.document.ExportFilter"; - return aRet; -} - -OUString WriterFilter::getImplementationName( ) throw (uno::RuntimeException, std::exception) -{ - return WriterFilter_getImplementationName(); -} - - -sal_Bool WriterFilter::supportsService( const OUString& rServiceName ) throw (uno::RuntimeException, std::exception) -{ - return cppu::supportsService( this, rServiceName ); -} - - -uno::Sequence< OUString > WriterFilter::getSupportedServiceNames( ) throw (uno::RuntimeException, std::exception) -{ - return WriterFilter_getSupportedServiceNames(); -} - -void WriterFilter::putPropertiesToDocumentGrabBag( const comphelper::SequenceAsHashMap& rProperties ) -{ - try - { - uno::Reference<beans::XPropertySet> xDocProps(m_xDstDoc, uno::UNO_QUERY); - if( xDocProps.is() ) - { - uno::Reference<beans::XPropertySetInfo> xPropsInfo = xDocProps->getPropertySetInfo(); - - const OUString aGrabBagPropName = "InteropGrabBag"; - if( xPropsInfo.is() && xPropsInfo->hasPropertyByName( aGrabBagPropName ) ) - { - // get existing grab bag - comphelper::SequenceAsHashMap aGrabBag(xDocProps->getPropertyValue(aGrabBagPropName)); - - // put the new items - aGrabBag.update(rProperties); - - // put it back to the document - xDocProps->setPropertyValue(aGrabBagPropName, uno::Any(aGrabBag.getAsConstPropertyValueList())); - } - } - } - catch(const uno::Exception&) - { - SAL_WARN("writerfilter","Failed to save documents grab bag"); - } -} - -extern "C" SAL_DLLPUBLIC_EXPORT ::com::sun::star::uno::XInterface* SAL_CALL -com_sun_star_comp_Writer_WriterFilter_get_implementation(::com::sun::star::uno::XComponentContext* component, - ::com::sun::star::uno::Sequence<css::uno::Any> const &) -{ - return cppu::acquire(new WriterFilter(component)); -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/filter/WriterFilter.cxx b/writerfilter/source/filter/WriterFilter.cxx new file mode 100644 index 000000000000..7a5fc1decf28 --- /dev/null +++ b/writerfilter/source/filter/WriterFilter.cxx @@ -0,0 +1,381 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifdef DEBUG_WRITERFILTER +#include <iostream> +#include <osl/process.h> +#endif + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/document/XExporter.hpp> +#include <com/sun/star/document/XFilter.hpp> +#include <com/sun/star/document/XImporter.hpp> +#include <com/sun/star/drawing/XDrawPageSupplier.hpp> +#include <com/sun/star/io/WrongFormatException.hpp> +#include <com/sun/star/io/XInputStream.hpp> +#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/xml/sax/SAXParseException.hpp> +#include <cppuhelper/exc_hlp.hxx> +#include <cppuhelper/implbase.hxx> +#include <cppuhelper/supportsservice.hxx> +#include <dmapper/DomainMapperFactory.hxx> +#include <oox/core/filterdetect.hxx> +#include <oox/helper/graphichelper.hxx> +#include <oox/ole/olestorage.hxx> +#include <oox/ole/vbaproject.hxx> +#include <ooxml/OOXMLDocument.hxx> +#include <osl/diagnose.h> +#include <unotools/mediadescriptor.hxx> + +using namespace ::com::sun::star; + +static OUString lcl_GetExceptionMessageRec(xml::sax::SAXException const& e); + +static OUString lcl_GetExceptionMessage(xml::sax::SAXException const& e) +{ + OUString const thisMessage("SAXParseException: \"" + e.Message + "\""); + OUString const restMessage(lcl_GetExceptionMessageRec(e)); + return restMessage + "\n" + thisMessage; +} +static OUString lcl_GetExceptionMessage(xml::sax::SAXParseException const& e) +{ + OUString const thisMessage("SAXParseException: '" + e.Message + "', Stream '" + e.SystemId + "', Line " + OUString::number(e.LineNumber) + + ", Column " + OUString::number(e.ColumnNumber)); + OUString const restMessage(lcl_GetExceptionMessageRec(e)); + return restMessage + "\n" + thisMessage; +} + +static OUString lcl_GetExceptionMessageRec(xml::sax::SAXException const& e) +{ + xml::sax::SAXParseException saxpe; + if (e.WrappedException >>= saxpe) + { + return lcl_GetExceptionMessage(saxpe); + } + xml::sax::SAXException saxe; + if (e.WrappedException >>= saxe) + { + return lcl_GetExceptionMessage(saxe); + } + uno::Exception ue; + if (e.WrappedException >>= ue) + { + return ue.Message; + } + return OUString(); +} + +/// Common DOCX filter, calls DocxExportFilter via UNO or does the DOCX import. +class WriterFilter : public cppu::WeakImplHelper + < + document::XFilter, + document::XImporter, + document::XExporter, + lang::XInitialization, + lang::XServiceInfo + > +{ + +protected: + uno::Reference<uno::XComponentContext> m_xContext; + uno::Reference<lang::XComponent> m_xSrcDoc, m_xDstDoc; + +public: + WriterFilter(const uno::Reference<uno::XComponentContext>& rxContext) + : m_xContext(rxContext) + {} + virtual ~WriterFilter() {} + + // XFilter + virtual sal_Bool SAL_CALL filter(const uno::Sequence<beans::PropertyValue>& rDescriptor) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE; + virtual void SAL_CALL cancel() throw (uno::RuntimeException, std::exception) SAL_OVERRIDE; + + // XImporter + virtual void SAL_CALL setTargetDocument(const uno::Reference<lang::XComponent>& xDoc) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE; + + // XExporter + virtual void SAL_CALL setSourceDocument(const uno::Reference<lang::XComponent>& xDoc) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE; + + // XInitialization + virtual void SAL_CALL initialize(const uno::Sequence<uno::Any>& rArguments) throw (uno::Exception, uno::RuntimeException, std::exception) SAL_OVERRIDE; + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() throw (uno::RuntimeException, std::exception) SAL_OVERRIDE; + virtual sal_Bool SAL_CALL supportsService(const OUString& rServiceName) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE; + virtual uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() throw (uno::RuntimeException, std::exception) SAL_OVERRIDE; + +private: + void putPropertiesToDocumentGrabBag(const comphelper::SequenceAsHashMap& rProperties); + +}; + +sal_Bool WriterFilter::filter(const uno::Sequence< beans::PropertyValue >& aDescriptor) throw (uno::RuntimeException, std::exception) +{ + if (m_xSrcDoc.is()) + { + uno::Reference< lang::XMultiServiceFactory > xMSF(m_xContext->getServiceManager(), uno::UNO_QUERY_THROW); + uno::Reference< uno::XInterface > xIfc; + try + { + xIfc.set(xMSF->createInstance("com.sun.star.comp.Writer.DocxExport"), uno::UNO_QUERY_THROW); + } + catch (uno::RuntimeException&) + { + throw; + } + catch (uno::Exception& e) + { + uno::Any a(cppu::getCaughtException()); + throw lang::WrappedTargetRuntimeException("wrapped " + a.getValueTypeName() + ": " + e.Message, uno::Reference<uno::XInterface>(), a); + } + uno::Reference< document::XExporter > xExprtr(xIfc, uno::UNO_QUERY_THROW); + uno::Reference< document::XFilter > xFltr(xIfc, uno::UNO_QUERY_THROW); + if (!xExprtr.is() || !xFltr.is()) + return sal_False; + xExprtr->setSourceDocument(m_xSrcDoc); + return xFltr->filter(aDescriptor); + } + else if (m_xDstDoc.is()) + { + utl::MediaDescriptor aMediaDesc(aDescriptor); + bool bRepairStorage = aMediaDesc.getUnpackedValueOrDefault("RepairPackage", false); + + uno::Reference< io::XInputStream > xInputStream; + try + { + // use the oox.core.FilterDetect implementation to extract the decrypted ZIP package + ::oox::core::FilterDetect aDetector(m_xContext); + xInputStream = aDetector.extractUnencryptedPackage(aMediaDesc); + } + catch (uno::Exception&) + { + } + + if (!xInputStream.is()) + return sal_False; + + writerfilter::dmapper::SourceDocumentType eType = writerfilter::dmapper::SourceDocumentType::OOXML; + writerfilter::Stream::Pointer_t pStream( + writerfilter::dmapper::DomainMapperFactory::createMapper(m_xContext, xInputStream, m_xDstDoc, bRepairStorage, eType, uno::Reference<text::XTextRange>(), aMediaDesc)); + //create the tokenizer and domain mapper + writerfilter::ooxml::OOXMLStream::Pointer_t pDocStream = writerfilter::ooxml::OOXMLDocumentFactory::createStream(m_xContext, xInputStream, bRepairStorage); + uno::Reference<task::XStatusIndicator> xStatusIndicator = aMediaDesc.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_STATUSINDICATOR(), uno::Reference<task::XStatusIndicator>()); + writerfilter::ooxml::OOXMLDocument::Pointer_t pDocument(writerfilter::ooxml::OOXMLDocumentFactory::createDocument(pDocStream, xStatusIndicator)); + + uno::Reference<frame::XModel> xModel(m_xDstDoc, uno::UNO_QUERY_THROW); + pDocument->setModel(xModel); + + uno::Reference<drawing::XDrawPageSupplier> xDrawings + (m_xDstDoc, uno::UNO_QUERY_THROW); + uno::Reference<drawing::XDrawPage> xDrawPage + (xDrawings->getDrawPage(), uno::UNO_SET_THROW); + pDocument->setDrawPage(xDrawPage); + + try + { + pDocument->resolve(*pStream); + } + catch (xml::sax::SAXParseException const& e) + { + // note: SfxObjectShell checks for WrongFormatException + io::WrongFormatException wfe(lcl_GetExceptionMessage(e)); + throw lang::WrappedTargetRuntimeException("", + static_cast<OWeakObject*>(this), uno::makeAny(wfe)); + } + catch (xml::sax::SAXException const& e) + { + // note: SfxObjectShell checks for WrongFormatException + io::WrongFormatException wfe(lcl_GetExceptionMessage(e)); + throw lang::WrappedTargetRuntimeException("", + static_cast<OWeakObject*>(this), uno::makeAny(wfe)); + } + catch (uno::RuntimeException const&) + { + throw; + } + catch (uno::Exception const& e) + { + SAL_WARN("writerfilter", "WriterFilter::filter(): " + "failed with exception " << e.Message); + throw lang::WrappedTargetRuntimeException("", + static_cast<OWeakObject*>(this), uno::makeAny(e)); + } + + // Adding some properties to the document's grab bag for interoperability purposes: + comphelper::SequenceAsHashMap aGrabBagProperties; + + // Adding the saved Theme DOM + aGrabBagProperties["OOXTheme"] = uno::makeAny(pDocument->getThemeDom()); + + // Adding the saved custom xml DOM + aGrabBagProperties["OOXCustomXml"] = uno::makeAny(pDocument->getCustomXmlDomList()); + aGrabBagProperties["OOXCustomXmlProps"] = uno::makeAny(pDocument->getCustomXmlDomPropsList()); + + // Adding the saved ActiveX DOM + aGrabBagProperties["OOXActiveX"] = uno::makeAny(pDocument->getActiveXDomList()); + aGrabBagProperties["OOXActiveXBin"] = uno::makeAny(pDocument->getActiveXBinList()); + + // Adding the saved Glossary Documnet DOM to the document's grab bag + aGrabBagProperties["OOXGlossary"] = uno::makeAny(pDocument->getGlossaryDocDom()); + aGrabBagProperties["OOXGlossaryDom"] = uno::makeAny(pDocument->getGlossaryDomList()); + + // Adding the saved embedding document to document's grab bag + aGrabBagProperties["OOXEmbeddings"] = uno::makeAny(pDocument->getEmbeddingsList()); + + putPropertiesToDocumentGrabBag(aGrabBagProperties); + + writerfilter::ooxml::OOXMLStream::Pointer_t pVBAProjectStream(writerfilter::ooxml::OOXMLDocumentFactory::createStream(pDocStream, writerfilter::ooxml::OOXMLStream::VBAPROJECT)); + oox::StorageRef xVbaPrjStrg(new ::oox::ole::OleStorage(m_xContext, pVBAProjectStream->getDocumentStream(), false)); + if (xVbaPrjStrg.get() && xVbaPrjStrg->isStorage()) + { + ::oox::ole::VbaProject aVbaProject(m_xContext, xModel, "Writer"); + uno::Reference< frame::XFrame > xFrame = aMediaDesc.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_FRAME(), uno::Reference< frame::XFrame > ()); + + // if no XFrame try fallback to what we can glean from the Model + if (!xFrame.is()) + { + uno::Reference< frame::XController > xController = xModel->getCurrentController(); + xFrame = xController.is() ? xController->getFrame() : nullptr; + } + + oox::GraphicHelper gHelper(m_xContext, xFrame, xVbaPrjStrg); + aVbaProject.importVbaProject(*xVbaPrjStrg, gHelper); + } + + // Document signature. + writerfilter::ooxml::OOXMLStream::Pointer_t pSignatureStream; + pSignatureStream = writerfilter::ooxml::OOXMLDocumentFactory::createStream(m_xContext, xInputStream, bRepairStorage, writerfilter::ooxml::OOXMLStream::SIGNATURE); + if (pSignatureStream->getDocumentStream().is()) + { + // TODO found, handle it. + } + + pStream.reset(); + + return sal_True; + } + return sal_False; +} + + +void WriterFilter::cancel() throw (uno::RuntimeException, std::exception) +{ +} + +void WriterFilter::setTargetDocument(const uno::Reference< lang::XComponent >& xDoc) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) +{ + m_xDstDoc = xDoc; + + // Set some compatibility options that are valid for all the formats + uno::Reference< lang::XMultiServiceFactory > xFactory(xDoc, uno::UNO_QUERY); + uno::Reference< beans::XPropertySet > xSettings(xFactory->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY); + + xSettings->setPropertyValue("AddFrameOffsets", uno::makeAny(sal_True)); + xSettings->setPropertyValue("UseOldNumbering", uno::makeAny(sal_False)); + xSettings->setPropertyValue("IgnoreFirstLineIndentInNumbering", uno::makeAny(sal_False)); + xSettings->setPropertyValue("DoNotResetParaAttrsForNumFont", uno::makeAny(sal_False)); + xSettings->setPropertyValue("UseFormerLineSpacing", uno::makeAny(sal_False)); + xSettings->setPropertyValue("AddParaSpacingToTableCells", uno::makeAny(sal_True)); + xSettings->setPropertyValue("UseFormerObjectPositioning", uno::makeAny(sal_False)); + xSettings->setPropertyValue("ConsiderTextWrapOnObjPos", uno::makeAny(sal_True)); + xSettings->setPropertyValue("UseFormerTextWrapping", uno::makeAny(sal_False)); + xSettings->setPropertyValue("TableRowKeep", uno::makeAny(sal_True)); + xSettings->setPropertyValue("IgnoreTabsAndBlanksForLineCalculation", uno::makeAny(sal_True)); + xSettings->setPropertyValue("InvertBorderSpacing", uno::makeAny(sal_True)); + xSettings->setPropertyValue("CollapseEmptyCellPara", uno::makeAny(sal_True)); + xSettings->setPropertyValue("TabOverflow", uno::makeAny(sal_True)); + xSettings->setPropertyValue("UnbreakableNumberings", uno::makeAny(sal_True)); + + xSettings->setPropertyValue("FloattableNomargins", uno::makeAny(sal_True)); + xSettings->setPropertyValue("ClippedPictures", uno::makeAny(sal_True)); + xSettings->setPropertyValue("BackgroundParaOverDrawings", uno::makeAny(sal_True)); + xSettings->setPropertyValue("TabOverMargin", uno::makeAny(sal_True)); + xSettings->setPropertyValue("PropLineSpacingShrinksFirstLine", uno::makeAny(sal_True)); +} + +void WriterFilter::setSourceDocument(const uno::Reference< lang::XComponent >& xDoc) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) +{ + m_xSrcDoc = xDoc; +} + +void WriterFilter::initialize(const uno::Sequence< uno::Any >& /*rArguments*/) throw (uno::Exception, uno::RuntimeException, std::exception) +{ +} + +OUString WriterFilter::getImplementationName() throw (uno::RuntimeException, std::exception) +{ + return OUString("com.sun.star.comp.Writer.WriterFilter"); +} + + +sal_Bool WriterFilter::supportsService(const OUString& rServiceName) throw (uno::RuntimeException, std::exception) +{ + return cppu::supportsService(this, rServiceName); +} + + +uno::Sequence<OUString> WriterFilter::getSupportedServiceNames() throw (uno::RuntimeException, std::exception) +{ + uno::Sequence<OUString> aRet = + { + OUString("com.sun.star.document.ImportFilter"), + OUString("com.sun.star.document.ExportFilter") + }; + return aRet; +} + +void WriterFilter::putPropertiesToDocumentGrabBag(const comphelper::SequenceAsHashMap& rProperties) +{ + try + { + uno::Reference<beans::XPropertySet> xDocProps(m_xDstDoc, uno::UNO_QUERY); + if (xDocProps.is()) + { + uno::Reference<beans::XPropertySetInfo> xPropsInfo = xDocProps->getPropertySetInfo(); + + const OUString aGrabBagPropName = "InteropGrabBag"; + if (xPropsInfo.is() && xPropsInfo->hasPropertyByName(aGrabBagPropName)) + { + // get existing grab bag + comphelper::SequenceAsHashMap aGrabBag(xDocProps->getPropertyValue(aGrabBagPropName)); + + // put the new items + aGrabBag.update(rProperties); + + // put it back to the document + xDocProps->setPropertyValue(aGrabBagPropName, uno::Any(aGrabBag.getAsConstPropertyValueList())); + } + } + } + catch (const uno::Exception&) + { + SAL_WARN("writerfilter","Failed to save documents grab bag"); + } +} + +extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface* SAL_CALL com_sun_star_comp_Writer_WriterFilter_get_implementation(uno::XComponentContext* component, uno::Sequence<uno::Any> const&) +{ + return cppu::acquire(new WriterFilter(component)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/filter/WriterFilter.hxx b/writerfilter/source/filter/WriterFilter.hxx deleted file mode 100644 index bb322131c7d9..000000000000 --- a/writerfilter/source/filter/WriterFilter.hxx +++ /dev/null @@ -1,98 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifndef INCLUDED_WRITERFILTER_SOURCE_FILTER_WRITERFILTER_HXX -#define INCLUDED_WRITERFILTER_SOURCE_FILTER_WRITERFILTER_HXX - -#include <com/sun/star/document/XFilter.hpp> -#include <com/sun/star/document/XImporter.hpp> -#include <com/sun/star/document/XExporter.hpp> -#include <com/sun/star/lang/XInitialization.hpp> -#include <com/sun/star/lang/XServiceInfo.hpp> -#include <com/sun/star/xml/sax/XDocumentHandler.hpp> -#include <cppuhelper/implbase5.hxx> -#include <comphelper/sequenceashashmap.hxx> - -/// Common DOC/DOCX filter, calls DocxExportFilter via UNO or does the DOCX import. -class WriterFilter : public cppu::WeakImplHelper5 -< - com::sun::star::document::XFilter, - com::sun::star::document::XImporter, - com::sun::star::document::XExporter, - com::sun::star::lang::XInitialization, - com::sun::star::lang::XServiceInfo -> -{ - -protected: - ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xContext; - ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > m_xSrcDoc, m_xDstDoc; - ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler > m_xHandler; - - -public: - WriterFilter( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& rxContext) - : m_xContext( rxContext ) - {} - virtual ~WriterFilter() {} - - // XFilter - virtual sal_Bool SAL_CALL filter( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor ) - throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; - virtual void SAL_CALL cancel( ) - throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; - - // XImporter - virtual void SAL_CALL setTargetDocument( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& xDoc ) - throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; - - // XExporter - virtual void SAL_CALL setSourceDocument( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >& xDoc ) - throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; - - // XInitialization - virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) - throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; - - // XServiceInfo - virtual OUString SAL_CALL getImplementationName( ) - throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; - virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) - throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; - virtual ::com::sun::star::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() - throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; - -private: - void putPropertiesToDocumentGrabBag(const comphelper::SequenceAsHashMap& rProperties); - -}; - - -OUString WriterFilter_getImplementationName() - throw ( ::com::sun::star::uno::RuntimeException ); - -bool SAL_CALL WriterFilter_supportsService( const OUString& ServiceName ) - throw ( ::com::sun::star::uno::RuntimeException ); - -::com::sun::star::uno::Sequence< OUString > SAL_CALL WriterFilter_getSupportedServiceNames( ) - throw ( ::com::sun::star::uno::RuntimeException ); - -#endif - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |