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 <memory>
21 :
22 : #include <com/sun/star/document/XExporter.hpp>
23 : #include <com/sun/star/document/XFilter.hpp>
24 : #include <com/sun/star/document/XImporter.hpp>
25 : #include <com/sun/star/io/WrongFormatException.hpp>
26 : #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
27 : #include <com/sun/star/lang/XInitialization.hpp>
28 : #include <com/sun/star/lang/XServiceInfo.hpp>
29 : #include <cppuhelper/implbase.hxx>
30 : #include <cppuhelper/implementationentry.hxx>
31 : #include <cppuhelper/supportsservice.hxx>
32 : #include <unotools/localfilehelper.hxx>
33 : #include <unotools/mediadescriptor.hxx>
34 : #include <unotools/streamwrap.hxx>
35 : #include <unotools/ucbstreamhelper.hxx>
36 :
37 : #include <dmapper/DomainMapperFactory.hxx>
38 : #include <rtftok/RTFDocument.hxx>
39 :
40 : using namespace ::com::sun::star;
41 :
42 : /// Invokes the RTF tokenizer + dmapper or RtfExportFilter in sw via UNO.
43 : class RtfFilter : public cppu::WeakImplHelper
44 : <
45 : document::XFilter,
46 : document::XImporter,
47 : document::XExporter,
48 : lang::XInitialization,
49 : lang::XServiceInfo
50 : >
51 : {
52 : uno::Reference<uno::XComponentContext> m_xContext;
53 : uno::Reference<lang::XComponent> m_xSrcDoc, m_xDstDoc;
54 :
55 : public:
56 : explicit RtfFilter(const uno::Reference<uno::XComponentContext>& xContext);
57 : virtual ~RtfFilter();
58 :
59 : // XFilter
60 : virtual sal_Bool SAL_CALL filter(const uno::Sequence<beans::PropertyValue>& rDescriptor) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE;
61 : virtual void SAL_CALL cancel() throw (uno::RuntimeException, std::exception) SAL_OVERRIDE;
62 :
63 : // XImporter
64 : virtual void SAL_CALL setTargetDocument(const uno::Reference<lang::XComponent>& xDoc) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
65 :
66 : // XExporter
67 : virtual void SAL_CALL setSourceDocument(const uno::Reference<lang::XComponent>& xDoc) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
68 :
69 : // XInitialization
70 : virtual void SAL_CALL initialize(const uno::Sequence<uno::Any>& rArguments) throw (uno::Exception, uno::RuntimeException, std::exception) SAL_OVERRIDE;
71 :
72 : // XServiceInfo
73 : virtual OUString SAL_CALL getImplementationName() throw (uno::RuntimeException, std::exception) SAL_OVERRIDE;
74 : virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE;
75 : virtual uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() throw (uno::RuntimeException, std::exception) SAL_OVERRIDE;
76 :
77 : };
78 :
79 532 : RtfFilter::RtfFilter(const uno::Reference< uno::XComponentContext >& rxContext)
80 532 : : m_xContext(rxContext)
81 : {
82 532 : }
83 :
84 1064 : RtfFilter::~RtfFilter()
85 : {
86 1064 : }
87 :
88 556 : sal_Bool RtfFilter::filter(const uno::Sequence< beans::PropertyValue >& aDescriptor) throw(uno::RuntimeException, std::exception)
89 : {
90 556 : sal_uInt32 nStartTime = osl_getGlobalTimer();
91 556 : if (m_xSrcDoc.is())
92 : {
93 95 : uno::Reference< lang::XMultiServiceFactory > xMSF(m_xContext->getServiceManager(), uno::UNO_QUERY_THROW);
94 190 : uno::Reference< uno::XInterface > xIfc(xMSF->createInstance("com.sun.star.comp.Writer.RtfExport"), uno::UNO_QUERY_THROW);
95 95 : if (!xIfc.is())
96 0 : return sal_False;
97 190 : uno::Reference< document::XExporter > xExporter(xIfc, uno::UNO_QUERY_THROW);
98 190 : uno::Reference< document::XFilter > xFilter(xIfc, uno::UNO_QUERY_THROW);
99 95 : if (!xExporter.is() || !xFilter.is())
100 0 : return sal_False;
101 95 : xExporter->setSourceDocument(m_xSrcDoc);
102 190 : return xFilter->filter(aDescriptor);
103 : }
104 :
105 461 : bool bResult(false);
106 461 : uno::Reference<task::XStatusIndicator> xStatusIndicator;
107 :
108 : try
109 : {
110 461 : utl::MediaDescriptor aMediaDesc(aDescriptor);
111 461 : bool bRepairStorage = aMediaDesc.getUnpackedValueOrDefault("RepairPackage", false);
112 461 : bool bIsNewDoc = !aMediaDesc.getUnpackedValueOrDefault("InsertMode", false);
113 922 : uno::Reference<text::XTextRange> xInsertTextRange = aMediaDesc.getUnpackedValueOrDefault("TextInsertModeRange", uno::Reference<text::XTextRange>());
114 922 : uno::Reference< io::XInputStream > xInputStream;
115 :
116 461 : aMediaDesc.addInputStream();
117 461 : aMediaDesc[ utl::MediaDescriptor::PROP_INPUTSTREAM() ] >>= xInputStream;
118 :
119 : // If this is set, write to this file, instead of the real document during paste.
120 461 : char* pEnv = getenv("SW_DEBUG_RTF_PASTE_TO");
121 922 : OUString aOutStr;
122 461 : if (!bIsNewDoc && pEnv && utl::LocalFileHelper::ConvertPhysicalNameToURL(OUString::fromUtf8(pEnv), aOutStr))
123 : {
124 0 : std::unique_ptr<SvStream> pOut(utl::UcbStreamHelper::CreateStream(aOutStr, StreamMode::WRITE));
125 0 : std::unique_ptr<SvStream> pIn(utl::UcbStreamHelper::CreateStream(xInputStream));
126 0 : pOut->WriteStream(*pIn);
127 0 : return true;
128 : }
129 :
130 : // If this is set, read from this file, instead of the real clipboard during paste.
131 461 : pEnv = getenv("SW_DEBUG_RTF_PASTE_FROM");
132 461 : if (!bIsNewDoc && pEnv)
133 : {
134 0 : OUString aInStr;
135 0 : utl::LocalFileHelper::ConvertPhysicalNameToURL(OUString::fromUtf8(pEnv), aInStr);
136 0 : SvStream* pStream = utl::UcbStreamHelper::CreateStream(aInStr, StreamMode::READ);
137 0 : uno::Reference<io::XStream> xStream(new utl::OStreamWrapper(*pStream));
138 0 : xInputStream.set(xStream, uno::UNO_QUERY);
139 : }
140 :
141 461 : uno::Reference<frame::XFrame> xFrame = aMediaDesc.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_FRAME(),
142 1383 : uno::Reference<frame::XFrame>());
143 :
144 922 : xStatusIndicator = aMediaDesc.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_STATUSINDICATOR(),
145 461 : uno::Reference<task::XStatusIndicator>());
146 :
147 461 : writerfilter::dmapper::SourceDocumentType eType = writerfilter::dmapper::SourceDocumentType::RTF;
148 : writerfilter::Stream::Pointer_t pStream(
149 921 : writerfilter::dmapper::DomainMapperFactory::createMapper(m_xContext, xInputStream, m_xDstDoc, bRepairStorage, eType, xInsertTextRange, aMediaDesc));
150 : writerfilter::rtftok::RTFDocument::Pointer_t pDocument(
151 920 : writerfilter::rtftok::RTFDocumentFactory::createDocument(m_xContext, xInputStream, m_xDstDoc, xFrame, xStatusIndicator, bIsNewDoc));
152 460 : pDocument->resolve(*pStream);
153 456 : bResult = true;
154 456 : sal_uInt32 nEndTime = osl_getGlobalTimer();
155 461 : SAL_INFO("writerfilter.profile", "RtfFilter::filter: finished in " << nEndTime - nStartTime << " ms");
156 : }
157 3 : catch (const io::WrongFormatException& e)
158 : {
159 : // cannot throw WrongFormatException directly :(
160 : throw lang::WrappedTargetRuntimeException("",
161 3 : static_cast<OWeakObject*>(this), uno::makeAny(e));
162 : }
163 2 : catch (const uno::Exception& e)
164 : {
165 : SAL_INFO("writerfilter", "Exception caught: " << e.Message);
166 : }
167 :
168 458 : if (xStatusIndicator.is())
169 410 : xStatusIndicator->end();
170 461 : return bResult;
171 : }
172 :
173 0 : void RtfFilter::cancel() throw(uno::RuntimeException, std::exception)
174 : {
175 0 : }
176 :
177 95 : void RtfFilter::setSourceDocument(const uno::Reference< lang::XComponent >& xDoc) throw(lang::IllegalArgumentException, uno::RuntimeException, std::exception)
178 : {
179 95 : m_xSrcDoc = xDoc;
180 95 : }
181 :
182 435 : void RtfFilter::setTargetDocument(const uno::Reference< lang::XComponent >& xDoc) throw(lang::IllegalArgumentException, uno::RuntimeException, std::exception)
183 : {
184 435 : m_xDstDoc = xDoc;
185 435 : }
186 :
187 520 : void RtfFilter::initialize(const uno::Sequence< uno::Any >& /*aArguments*/) throw(uno::Exception, uno::RuntimeException, std::exception)
188 : {
189 : // The DOCX exporter here extracts 'type' of the filter, ie 'Word' or
190 : // 'Word Template' but we don't need it for RTF.
191 520 : }
192 :
193 1 : OUString RtfFilter::getImplementationName() throw(uno::RuntimeException, std::exception)
194 : {
195 1 : return OUString("com.sun.star.comp.Writer.RtfFilter");
196 : }
197 :
198 0 : sal_Bool RtfFilter::supportsService(const OUString& rServiceName) throw(uno::RuntimeException, std::exception)
199 : {
200 0 : return cppu::supportsService(this, rServiceName);
201 : }
202 :
203 1 : uno::Sequence<OUString> RtfFilter::getSupportedServiceNames() throw(uno::RuntimeException, std::exception)
204 : {
205 : uno::Sequence<OUString> aRet =
206 : {
207 : OUString("com.sun.star.document.ImportFilter"),
208 : OUString("com.sun.star.document.ExportFilter")
209 1 : };
210 1 : return aRet;
211 : }
212 :
213 532 : extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface* SAL_CALL com_sun_star_comp_Writer_RtfFilter_get_implementation(uno::XComponentContext* pComponent, uno::Sequence<uno::Any> const&)
214 : {
215 532 : return cppu::acquire(new RtfFilter(pComponent));
216 : }
217 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|