Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <osl/diagnose.h>
21 : #include <com/sun/star/uno/XComponentContext.hpp>
22 : #include <com/sun/star/beans/XPropertySet.hpp>
23 : #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
24 : #include <com/sun/star/io/XInputStream.hpp>
25 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
26 : #include <unotools/mediadescriptor.hxx>
27 : #include <cppuhelper/supportsservice.hxx>
28 : #include <oox/core/filterdetect.hxx>
29 : #include <dmapper/DomainMapper.hxx>
30 : #include <WriterFilter.hxx>
31 : #include <ooxml/OOXMLDocument.hxx>
32 : #ifdef DEBUG_WRITERFILTER
33 : #include <iostream>
34 : #include <osl/process.h>
35 : #endif
36 :
37 : #include <resourcemodel/TagLogger.hxx>
38 : #include <oox/ole/olestorage.hxx>
39 : #include <oox/ole/vbaproject.hxx>
40 : #include <oox/helper/graphichelper.hxx>
41 : using namespace ::com::sun::star;
42 :
43 :
44 :
45 3658 : sal_Bool WriterFilter::filter( const uno::Sequence< beans::PropertyValue >& aDescriptor )
46 : throw (uno::RuntimeException, std::exception)
47 : {
48 3658 : if( m_xSrcDoc.is() )
49 : {
50 860 : uno::Reference< lang::XMultiServiceFactory > xMSF(m_xContext->getServiceManager(), uno::UNO_QUERY_THROW);
51 1720 : uno::Reference< uno::XInterface > xIfc( xMSF->createInstance("com.sun.star.comp.Writer.DocxExport"), uno::UNO_QUERY_THROW);
52 860 : if (!xIfc.is())
53 0 : return sal_False;
54 1720 : uno::Reference< document::XExporter > xExprtr(xIfc, uno::UNO_QUERY_THROW);
55 1720 : uno::Reference< document::XFilter > xFltr(xIfc, uno::UNO_QUERY_THROW);
56 860 : if (!xExprtr.is() || !xFltr.is())
57 0 : return sal_False;
58 860 : xExprtr->setSourceDocument(m_xSrcDoc);
59 1720 : return xFltr->filter(aDescriptor);
60 : }
61 2798 : else if (m_xDstDoc.is())
62 : {
63 2798 : utl::MediaDescriptor aMediaDesc( aDescriptor );
64 2798 : bool bRepairStorage = aMediaDesc.getUnpackedValueOrDefault( "RepairPackage", false );
65 :
66 5596 : uno::Reference< io::XInputStream > xInputStream;
67 : try
68 : {
69 : // use the oox.core.FilterDetect implementation to extract the decrypted ZIP package
70 2798 : ::oox::core::FilterDetect aDetector( m_xContext );
71 2798 : xInputStream = aDetector.extractUnencryptedPackage( aMediaDesc );
72 : }
73 0 : catch( uno::Exception& )
74 : {
75 : }
76 :
77 2798 : if ( !xInputStream.is() )
78 0 : return sal_False;
79 :
80 : #ifdef DEBUG_WRITERFILTER
81 : OUString sURL = aMediaDesc.getUnpackedValueOrDefault( utl::MediaDescriptor::PROP_URL(), OUString() );
82 : ::std::string sURLc = OUStringToOString(sURL, RTL_TEXTENCODING_ASCII_US).getStr();
83 :
84 : writerfilter::TagLogger::Pointer_t dmapper_logger
85 : (writerfilter::TagLogger::getInstance("DOMAINMAPPER"));
86 : if (getenv("SW_DEBUG_WRITERFILTER"))
87 : dmapper_logger->setFileName(sURLc);
88 : dmapper_logger->startDocument();
89 : #endif
90 :
91 2798 : writerfilter::dmapper::SourceDocumentType eType = writerfilter::dmapper::DOCUMENT_OOXML;
92 2798 : writerfilter::dmapper::DomainMapper* aDomainMapper = new writerfilter::dmapper::DomainMapper(m_xContext, xInputStream, m_xDstDoc, bRepairStorage, eType, uno::Reference<text::XTextRange>());
93 5596 : writerfilter::Stream::Pointer_t pStream(aDomainMapper);
94 : //create the tokenizer and domain mapper
95 5596 : writerfilter::ooxml::OOXMLStream::Pointer_t pDocStream = writerfilter::ooxml::OOXMLDocumentFactory::createStream(m_xContext, xInputStream, bRepairStorage);
96 5596 : uno::Reference<task::XStatusIndicator> xStatusIndicator = aMediaDesc.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_STATUSINDICATOR(), uno::Reference<task::XStatusIndicator>());
97 5596 : writerfilter::ooxml::OOXMLDocument::Pointer_t pDocument(writerfilter::ooxml::OOXMLDocumentFactory::createDocument(pDocStream, xStatusIndicator));
98 :
99 5596 : uno::Reference<frame::XModel> xModel(m_xDstDoc, uno::UNO_QUERY_THROW);
100 2798 : pDocument->setModel(xModel);
101 :
102 : uno::Reference<drawing::XDrawPageSupplier> xDrawings
103 5596 : (m_xDstDoc, uno::UNO_QUERY_THROW);
104 : uno::Reference<drawing::XDrawPage> xDrawPage
105 5596 : (xDrawings->getDrawPage(), uno::UNO_SET_THROW);
106 2798 : pDocument->setDrawPage(xDrawPage);
107 :
108 2798 : pDocument->resolve(*pStream);
109 :
110 : // Adding some properties to the document's grab bag for interoperability purposes:
111 5596 : comphelper::SequenceAsHashMap aGrabBagProperties;
112 :
113 : // Adding the saved Theme DOM
114 2798 : aGrabBagProperties["OOXTheme"] = uno::makeAny( pDocument->getThemeDom() );
115 :
116 : // Adding the saved custom xml DOM
117 2798 : aGrabBagProperties["OOXCustomXml"] = uno::makeAny( pDocument->getCustomXmlDomList() );
118 2798 : aGrabBagProperties["OOXCustomXmlProps"] = uno::makeAny( pDocument->getCustomXmlDomPropsList() );
119 :
120 : // Adding the saved ActiveX DOM
121 2798 : aGrabBagProperties["OOXActiveX"] = uno::makeAny( pDocument->getActiveXDomList() );
122 2798 : aGrabBagProperties["OOXActiveXBin"] = uno::makeAny( pDocument->getActiveXBinList() );
123 :
124 : // Adding the saved w:themeFontLang setting
125 2798 : aGrabBagProperties["ThemeFontLangProps"] = uno::makeAny( aDomainMapper->GetThemeFontLangProperties() );
126 :
127 : // Adding the saved Glossary Documnet DOM to the document's grab bag
128 2798 : aGrabBagProperties["OOXGlossary"] = uno::makeAny( pDocument->getGlossaryDocDom() );
129 2798 : aGrabBagProperties["OOXGlossaryDom"] = uno::makeAny( pDocument->getGlossaryDomList() );
130 :
131 : // Adding the saved embedding document to document's grab bag
132 2798 : aGrabBagProperties["OOXEmbeddings"] = uno::makeAny( pDocument->getEmbeddingsList() );
133 :
134 : // Adding the saved compat settings
135 2798 : aGrabBagProperties["CompatSettings"] = uno::makeAny( aDomainMapper->GetCompatSettings() );
136 :
137 2798 : putPropertiesToDocumentGrabBag( aGrabBagProperties );
138 :
139 5596 : writerfilter::ooxml::OOXMLStream::Pointer_t pVBAProjectStream(writerfilter::ooxml::OOXMLDocumentFactory::createStream( pDocStream, writerfilter::ooxml::OOXMLStream::VBAPROJECT ));
140 5596 : oox::StorageRef xVbaPrjStrg( new ::oox::ole::OleStorage( m_xContext, pVBAProjectStream->getDocumentStream(), false ) );
141 2798 : if( xVbaPrjStrg.get() && xVbaPrjStrg->isStorage() )
142 : {
143 0 : ::oox::ole::VbaProject aVbaProject( m_xContext, xModel, "Writer" );
144 0 : uno::Reference< frame::XFrame > xFrame = aMediaDesc.getUnpackedValueOrDefault( utl::MediaDescriptor::PROP_FRAME(), uno::Reference< frame::XFrame > () );
145 :
146 : // if no XFrame try fallback to what we can glean from the Model
147 0 : if ( !xFrame.is() )
148 : {
149 0 : uno::Reference< frame::XController > xController = xModel->getCurrentController();
150 0 : xFrame = xController.is() ? xController->getFrame() : nullptr;
151 : }
152 :
153 0 : oox::GraphicHelper gHelper( m_xContext, xFrame, xVbaPrjStrg );
154 0 : aVbaProject.importVbaProject( *xVbaPrjStrg, gHelper );
155 : }
156 :
157 : // Document signature.
158 5596 : writerfilter::ooxml::OOXMLStream::Pointer_t pSignatureStream;
159 2798 : pSignatureStream = writerfilter::ooxml::OOXMLDocumentFactory::createStream(m_xContext, xInputStream, bRepairStorage, writerfilter::ooxml::OOXMLStream::SIGNATURE);
160 2798 : if (pSignatureStream->getDocumentStream().is())
161 : {
162 : // TODO found, handle it.
163 : }
164 :
165 2798 : pStream.reset();
166 :
167 : #ifdef DEBUG_WRITERFILTER
168 : dmapper_logger->endDocument();
169 : #endif
170 :
171 5596 : return sal_True;
172 : }
173 0 : return sal_False;
174 : }
175 :
176 :
177 0 : void WriterFilter::cancel( ) throw (uno::RuntimeException, std::exception)
178 : {
179 0 : }
180 :
181 :
182 :
183 2798 : void WriterFilter::setTargetDocument( const uno::Reference< lang::XComponent >& xDoc )
184 : throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception)
185 : {
186 2798 : m_xDstDoc = xDoc;
187 :
188 : // Set some compatibility options that are valid for all the formats
189 2798 : uno::Reference< lang::XMultiServiceFactory > xFactory( xDoc, uno::UNO_QUERY );
190 5596 : uno::Reference< beans::XPropertySet > xSettings( xFactory->createInstance("com.sun.star.document.Settings"), uno::UNO_QUERY );
191 :
192 2798 : xSettings->setPropertyValue( "AddFrameOffsets", uno::makeAny( sal_True ) );
193 2798 : xSettings->setPropertyValue( "UseOldNumbering", uno::makeAny( sal_False ) );
194 2798 : xSettings->setPropertyValue( "IgnoreFirstLineIndentInNumbering", uno::makeAny( sal_False ) );
195 2798 : xSettings->setPropertyValue( "DoNotResetParaAttrsForNumFont", uno::makeAny( sal_False ) );
196 2798 : xSettings->setPropertyValue( "UseFormerLineSpacing", uno::makeAny( sal_False ) );
197 2798 : xSettings->setPropertyValue( "AddParaSpacingToTableCells", uno::makeAny( sal_True ) );
198 2798 : xSettings->setPropertyValue( "UseFormerObjectPositioning", uno::makeAny( sal_False ) );
199 2798 : xSettings->setPropertyValue( "ConsiderTextWrapOnObjPos", uno::makeAny( sal_True ) );
200 2798 : xSettings->setPropertyValue( "UseFormerTextWrapping", uno::makeAny( sal_False ) );
201 2798 : xSettings->setPropertyValue( "TableRowKeep", uno::makeAny( sal_True ) );
202 2798 : xSettings->setPropertyValue( "IgnoreTabsAndBlanksForLineCalculation", uno::makeAny( sal_True ) );
203 2798 : xSettings->setPropertyValue( "InvertBorderSpacing", uno::makeAny( sal_True ) );
204 2798 : xSettings->setPropertyValue( "CollapseEmptyCellPara", uno::makeAny( sal_True ) );
205 2798 : xSettings->setPropertyValue( "TabOverflow", uno::makeAny( sal_True ) );
206 2798 : xSettings->setPropertyValue( "UnbreakableNumberings", uno::makeAny( sal_True ) );
207 :
208 2798 : xSettings->setPropertyValue("FloattableNomargins", uno::makeAny( sal_True ));
209 2798 : xSettings->setPropertyValue( "ClippedPictures", uno::makeAny( sal_True ) );
210 2798 : xSettings->setPropertyValue( "BackgroundParaOverDrawings", uno::makeAny( sal_True ) );
211 2798 : xSettings->setPropertyValue( "TabOverMargin", uno::makeAny( sal_True ) );
212 5596 : xSettings->setPropertyValue("PropLineSpacingShrinksFirstLine", uno::makeAny(sal_True));
213 2798 : }
214 :
215 860 : void WriterFilter::setSourceDocument( const uno::Reference< lang::XComponent >& xDoc )
216 : throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception)
217 : {
218 860 : m_xSrcDoc = xDoc;
219 860 : }
220 :
221 :
222 :
223 3652 : void WriterFilter::initialize( const uno::Sequence< uno::Any >& /*aArguments*/ ) throw (uno::Exception, uno::RuntimeException, std::exception)
224 : {
225 3652 : }
226 :
227 :
228 40 : OUString WriterFilter_getImplementationName () throw (uno::RuntimeException)
229 : {
230 40 : return OUString ( "com.sun.star.comp.Writer.WriterFilter" );
231 : }
232 :
233 30 : uno::Sequence< OUString > WriterFilter_getSupportedServiceNames( ) throw (uno::RuntimeException)
234 : {
235 30 : uno::Sequence < OUString > aRet(2);
236 30 : OUString* pArray = aRet.getArray();
237 30 : pArray[0] = "com.sun.star.document.ImportFilter";
238 30 : pArray[1] = "com.sun.star.document.ExportFilter";
239 30 : return aRet;
240 : }
241 :
242 3658 : uno::Reference< uno::XInterface > WriterFilter_createInstance( const uno::Reference< uno::XComponentContext >& xContext)
243 : throw( uno::Exception )
244 : {
245 3658 : return (cppu::OWeakObject*) new WriterFilter( xContext );
246 : }
247 :
248 :
249 :
250 0 : OUString WriterFilter::getImplementationName( ) throw (uno::RuntimeException, std::exception)
251 : {
252 0 : return WriterFilter_getImplementationName();
253 : }
254 :
255 :
256 0 : sal_Bool WriterFilter::supportsService( const OUString& rServiceName ) throw (uno::RuntimeException, std::exception)
257 : {
258 0 : return cppu::supportsService( this, rServiceName );
259 : }
260 :
261 :
262 0 : uno::Sequence< OUString > WriterFilter::getSupportedServiceNames( ) throw (uno::RuntimeException, std::exception)
263 : {
264 0 : return WriterFilter_getSupportedServiceNames();
265 : }
266 :
267 2798 : void WriterFilter::putPropertiesToDocumentGrabBag( const comphelper::SequenceAsHashMap& rProperties )
268 : {
269 : try
270 : {
271 2798 : uno::Reference<beans::XPropertySet> xDocProps(m_xDstDoc, uno::UNO_QUERY);
272 2798 : if( xDocProps.is() )
273 : {
274 2798 : uno::Reference<beans::XPropertySetInfo> xPropsInfo = xDocProps->getPropertySetInfo();
275 :
276 5596 : const OUString aGrabBagPropName = "InteropGrabBag";
277 2798 : if( xPropsInfo.is() && xPropsInfo->hasPropertyByName( aGrabBagPropName ) )
278 : {
279 : // get existing grab bag
280 2798 : comphelper::SequenceAsHashMap aGrabBag(xDocProps->getPropertyValue(aGrabBagPropName));
281 :
282 : // put the new items
283 2798 : aGrabBag.update(rProperties);
284 :
285 : // put it back to the document
286 2798 : xDocProps->setPropertyValue(aGrabBagPropName, uno::Any(aGrabBag.getAsConstPropertyValueList()));
287 2798 : }
288 2798 : }
289 : }
290 0 : catch(const uno::Exception&)
291 : {
292 : SAL_WARN("writerfilter","Failed to save documents grab bag");
293 : }
294 2912 : }
295 :
296 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|