Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 : */
7 : /* "This product is not manufactured, approved, or supported by
8 : * Corel Corporation or Corel Corporation Limited."
9 : */
10 :
11 : #include <osl/diagnose.h>
12 : #include <rtl/tencinfo.h>
13 :
14 : #include <com/sun/star/io/XInputStream.hpp>
15 : #include <com/sun/star/xml/sax/XAttributeList.hpp>
16 : #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
17 : #include <com/sun/star/xml/sax/InputSource.hpp>
18 : #include <com/sun/star/xml/sax/XParser.hpp>
19 : #include <com/sun/star/io/XSeekable.hpp>
20 : #include <com/sun/star/uno/Reference.h>
21 : #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
22 : #include <cppuhelper/supportsservice.hxx>
23 :
24 : #include <xmloff/attrlist.hxx>
25 : #include <sfx2/passwd.hxx>
26 : #include <ucbhelper/content.hxx>
27 :
28 : #include <libwpd/libwpd.h>
29 : #include <libodfgen/libodfgen.hxx>
30 :
31 : #include "common/DocumentHandler.hxx"
32 : #include "common/WPXSvStream.hxx"
33 : #include "WordPerfectImportFilter.hxx"
34 :
35 : using ::ucbhelper::Content;
36 : using com::sun::star::uno::Sequence;
37 : using com::sun::star::uno::Reference;
38 : using com::sun::star::uno::Any;
39 : using com::sun::star::uno::UNO_QUERY;
40 : using com::sun::star::uno::XInterface;
41 : using com::sun::star::uno::Exception;
42 : using com::sun::star::uno::RuntimeException;
43 : using com::sun::star::uno::XComponentContext;
44 : using com::sun::star::beans::PropertyValue;
45 : using com::sun::star::document::XFilter;
46 : using com::sun::star::document::XExtendedFilterDetection;
47 : using com::sun::star::ucb::XCommandEnvironment;
48 :
49 : using com::sun::star::io::XInputStream;
50 : using com::sun::star::document::XImporter;
51 : using com::sun::star::xml::sax::InputSource;
52 : using com::sun::star::xml::sax::XAttributeList;
53 : using com::sun::star::xml::sax::XDocumentHandler;
54 : using com::sun::star::xml::sax::XParser;
55 :
56 :
57 0 : static bool handleEmbeddedWPGObject(const WPXBinaryData &data, OdfDocumentHandler *pHandler, const OdfStreamType streamType)
58 : {
59 0 : OdgGenerator exporter(pHandler, streamType);
60 :
61 0 : libwpg::WPGFileFormat fileFormat = libwpg::WPG_AUTODETECT;
62 :
63 0 : if (!libwpg::WPGraphics::isSupported(const_cast<WPXInputStream *>(data.getDataStream())))
64 0 : fileFormat = libwpg::WPG_WPG1;
65 :
66 0 : return libwpg::WPGraphics::parse(const_cast<WPXInputStream *>(data.getDataStream()), &exporter, fileFormat);
67 : }
68 :
69 0 : static bool handleEmbeddedWPGImage(const WPXBinaryData &input, WPXBinaryData &output)
70 : {
71 0 : WPXString svgOutput;
72 0 : libwpg::WPGFileFormat fileFormat = libwpg::WPG_AUTODETECT;
73 :
74 0 : if (!libwpg::WPGraphics::isSupported(const_cast<WPXInputStream *>(input.getDataStream())))
75 0 : fileFormat = libwpg::WPG_WPG1;
76 :
77 0 : if (!libwpg::WPGraphics::generateSVG(const_cast<WPXInputStream *>(input.getDataStream()), svgOutput, fileFormat))
78 0 : return false;
79 :
80 0 : output.clear();
81 0 : output.append((unsigned char *)svgOutput.cstr(), strlen(svgOutput.cstr()));
82 0 : return true;
83 : }
84 :
85 5 : sal_Bool SAL_CALL WordPerfectImportFilter::importImpl( const Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
86 : throw (RuntimeException)
87 : {
88 : SAL_INFO("writerperfect", "WordPerfectImportFilter::importImpl");
89 :
90 5 : sal_Int32 nLength = aDescriptor.getLength();
91 5 : const PropertyValue *pValue = aDescriptor.getConstArray();
92 5 : Reference < XInputStream > xInputStream;
93 25 : for ( sal_Int32 i = 0 ; i < nLength; i++)
94 : {
95 20 : if ( pValue[i].Name == "InputStream" )
96 5 : pValue[i].Value >>= xInputStream;
97 : }
98 5 : if ( !xInputStream.is() )
99 : {
100 : OSL_ASSERT( false );
101 0 : return sal_False;
102 : }
103 :
104 10 : WPXSvInputStream input( xInputStream );
105 :
106 10 : OString aUtf8Passwd;
107 :
108 5 : WPDConfidence confidence = WPDocument::isFileFormatSupported(&input);
109 :
110 5 : if (WPD_CONFIDENCE_SUPPORTED_ENCRYPTION == confidence)
111 : {
112 0 : int unsuccessfulAttempts = 0;
113 : while (true )
114 : {
115 0 : SfxPasswordDialog aPasswdDlg( 0 );
116 0 : aPasswdDlg.SetMinLen(0);
117 0 : if(!aPasswdDlg.Execute())
118 0 : return sal_False;
119 0 : OUString aPasswd = aPasswdDlg.GetPassword();
120 0 : aUtf8Passwd = OUStringToOString(aPasswd, RTL_TEXTENCODING_UTF8);
121 0 : if (WPD_PASSWORD_MATCH_OK == WPDocument::verifyPassword(&input, aUtf8Passwd.getStr()))
122 0 : break;
123 : else
124 0 : unsuccessfulAttempts++;
125 0 : if (unsuccessfulAttempts == 3) // timeout after 3 password atempts
126 0 : return sal_False;
127 0 : }
128 : }
129 :
130 : // An XML import service: what we push sax messages to..
131 : Reference < XDocumentHandler > xInternalHandler(
132 10 : mxContext->getServiceManager()->createInstanceWithContext(
133 5 : "com.sun.star.comp.Writer.XMLOasisImporter", mxContext),
134 10 : css::uno::UNO_QUERY_THROW);
135 :
136 : // The XImporter sets up an empty target document for XDocumentHandler to write to..
137 10 : Reference < XImporter > xImporter(xInternalHandler, UNO_QUERY);
138 5 : xImporter->setTargetDocument(mxDoc);
139 :
140 : // OO Document Handler: abstract class to handle document SAX messages, concrete implementation here
141 : // writes to in-memory target doc
142 10 : DocumentHandler xHandler(xInternalHandler);
143 :
144 10 : OdtGenerator collector(&xHandler, ODF_FLAT_XML);
145 5 : collector.registerEmbeddedObjectHandler("image/x-wpg", &handleEmbeddedWPGObject);
146 5 : collector.registerEmbeddedImageHandler("image/x-wpg", &handleEmbeddedWPGImage);
147 5 : if (WPD_OK == WPDocument::parse(&input, &collector, aUtf8Passwd.isEmpty() ? 0 : aUtf8Passwd.getStr()))
148 5 : return sal_True;
149 5 : return sal_False;
150 : }
151 :
152 5 : sal_Bool SAL_CALL WordPerfectImportFilter::filter( const Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
153 : throw (RuntimeException, std::exception)
154 : {
155 : SAL_INFO("writerperfect", "WordPerfectImportFilter::filter");
156 5 : return importImpl ( aDescriptor );
157 : }
158 0 : void SAL_CALL WordPerfectImportFilter::cancel( )
159 : throw (RuntimeException, std::exception)
160 : {
161 : SAL_INFO("writerperfect", "WordPerfectImportFilter::cancel");
162 0 : }
163 :
164 : // XImporter
165 5 : void SAL_CALL WordPerfectImportFilter::setTargetDocument( const Reference< ::com::sun::star::lang::XComponent >& xDoc )
166 : throw (::com::sun::star::lang::IllegalArgumentException, RuntimeException, std::exception)
167 : {
168 : SAL_INFO("writerperfect", "WordPerfectImportFilter::getTargetDocument");
169 5 : mxDoc = xDoc;
170 5 : }
171 :
172 : // XExtendedFilterDetection
173 5 : OUString SAL_CALL WordPerfectImportFilter::detect( Sequence< PropertyValue >& Descriptor )
174 : throw( RuntimeException, std::exception )
175 : {
176 : SAL_INFO("writerperfect", "WordPerfectImportFilter::detect");
177 :
178 5 : WPDConfidence confidence = WPD_CONFIDENCE_NONE;
179 5 : OUString sTypeName;
180 5 : sal_Int32 nLength = Descriptor.getLength();
181 5 : sal_Int32 location = nLength;
182 5 : const PropertyValue *pValue = Descriptor.getConstArray();
183 10 : Reference < XInputStream > xInputStream;
184 15 : for ( sal_Int32 i = 0 ; i < nLength; i++)
185 : {
186 10 : if ( pValue[i].Name == "TypeName" )
187 0 : location=i;
188 10 : else if ( pValue[i].Name == "InputStream" )
189 5 : pValue[i].Value >>= xInputStream;
190 : }
191 :
192 5 : if (!xInputStream.is())
193 0 : return OUString();
194 :
195 10 : WPXSvInputStream input( xInputStream );
196 :
197 5 : confidence = WPDocument::isFileFormatSupported(&input);
198 :
199 5 : if (confidence == WPD_CONFIDENCE_EXCELLENT || confidence == WPD_CONFIDENCE_SUPPORTED_ENCRYPTION)
200 5 : sTypeName = "writer_WordPerfect_Document";
201 :
202 5 : if (!sTypeName.isEmpty())
203 : {
204 5 : if ( location == nLength )
205 : {
206 5 : Descriptor.realloc(nLength+1);
207 5 : Descriptor[location].Name = "TypeName";
208 : }
209 :
210 5 : Descriptor[location].Value <<=sTypeName;
211 : }
212 :
213 10 : return sTypeName;
214 : }
215 :
216 :
217 : // XInitialization
218 0 : void SAL_CALL WordPerfectImportFilter::initialize( const Sequence< Any >& aArguments )
219 : throw (Exception, RuntimeException, std::exception)
220 : {
221 : SAL_INFO("writerperfect", "WordPerfectImportFilter::initialize");
222 0 : Sequence < PropertyValue > aAnySeq;
223 0 : sal_Int32 nLength = aArguments.getLength();
224 0 : if ( nLength && ( aArguments[0] >>= aAnySeq ) )
225 : {
226 0 : const PropertyValue *pValue = aAnySeq.getConstArray();
227 0 : nLength = aAnySeq.getLength();
228 0 : for ( sal_Int32 i = 0 ; i < nLength; i++)
229 : {
230 0 : if ( pValue[i].Name == "Type" )
231 : {
232 0 : pValue[i].Value >>= msFilterName;
233 0 : break;
234 : }
235 : }
236 0 : }
237 0 : }
238 11 : OUString WordPerfectImportFilter_getImplementationName ()
239 : throw (RuntimeException)
240 : {
241 11 : return OUString ( "com.sun.star.comp.Writer.WordPerfectImportFilter" );
242 : }
243 :
244 1 : Sequence< OUString > SAL_CALL WordPerfectImportFilter_getSupportedServiceNames( )
245 : throw (RuntimeException)
246 : {
247 1 : Sequence < OUString > aRet(2);
248 1 : OUString *pArray = aRet.getArray();
249 1 : pArray[0] = "com.sun.star.document.ImportFilter";
250 1 : pArray[1] = "com.sun.star.document.ExtendedTypeDetection";
251 1 : return aRet;
252 : }
253 :
254 1 : Reference< XInterface > SAL_CALL WordPerfectImportFilter_createInstance( const Reference< XComponentContext > & rContext)
255 : throw( Exception )
256 : {
257 1 : return (cppu::OWeakObject *) new WordPerfectImportFilter( rContext );
258 : }
259 :
260 : // XServiceInfo
261 0 : OUString SAL_CALL WordPerfectImportFilter::getImplementationName( )
262 : throw (RuntimeException, std::exception)
263 : {
264 0 : return WordPerfectImportFilter_getImplementationName();
265 : }
266 0 : sal_Bool SAL_CALL WordPerfectImportFilter::supportsService( const OUString &rServiceName )
267 : throw (RuntimeException, std::exception)
268 : {
269 0 : return cppu::supportsService( this, rServiceName );
270 : }
271 0 : Sequence< OUString > SAL_CALL WordPerfectImportFilter::getSupportedServiceNames( )
272 : throw (RuntimeException, std::exception)
273 : {
274 0 : return WordPerfectImportFilter_getSupportedServiceNames();
275 : }
276 :
277 :
278 0 : WordPerfectImportFilterDialog::WordPerfectImportFilterDialog( const Reference< XComponentContext > & rContext) :
279 0 : mxContext( rContext ) {}
280 :
281 0 : WordPerfectImportFilterDialog::~WordPerfectImportFilterDialog()
282 : {
283 0 : }
284 :
285 0 : void SAL_CALL WordPerfectImportFilterDialog::setTitle( const OUString & )
286 : throw (RuntimeException, std::exception)
287 : {
288 0 : }
289 :
290 0 : sal_Int16 SAL_CALL WordPerfectImportFilterDialog::execute()
291 : throw (RuntimeException, std::exception)
292 : {
293 0 : WPXSvInputStream input( mxInputStream );
294 :
295 0 : OString aUtf8Passwd;
296 :
297 0 : WPDConfidence confidence = WPDocument::isFileFormatSupported(&input);
298 :
299 0 : if (WPD_CONFIDENCE_SUPPORTED_ENCRYPTION == confidence)
300 : {
301 0 : int unsuccessfulAttempts = 0;
302 : while (true )
303 : {
304 0 : SfxPasswordDialog aPasswdDlg(0);
305 0 : aPasswdDlg.SetMinLen(0);
306 0 : if(!aPasswdDlg.Execute())
307 0 : return com::sun::star::ui::dialogs::ExecutableDialogResults::CANCEL;
308 0 : msPassword = aPasswdDlg.GetPassword().getStr();
309 0 : aUtf8Passwd = OUStringToOString(msPassword, RTL_TEXTENCODING_UTF8);
310 0 : if (WPD_PASSWORD_MATCH_OK == WPDocument::verifyPassword(&input, aUtf8Passwd.getStr()))
311 0 : break;
312 : else
313 0 : unsuccessfulAttempts++;
314 0 : if (unsuccessfulAttempts == 3) // timeout after 3 password atempts
315 0 : return com::sun::star::ui::dialogs::ExecutableDialogResults::CANCEL;
316 0 : }
317 : }
318 0 : return com::sun::star::ui::dialogs::ExecutableDialogResults::OK;
319 : }
320 :
321 0 : Sequence<PropertyValue> SAL_CALL WordPerfectImportFilterDialog::getPropertyValues() throw(RuntimeException, std::exception)
322 : {
323 0 : Sequence<PropertyValue> aRet(1);
324 0 : PropertyValue *pArray = aRet.getArray();
325 :
326 0 : pArray[0].Name = "Password";
327 0 : pArray[0].Value <<= msPassword;
328 :
329 0 : return aRet;
330 : }
331 :
332 0 : void SAL_CALL WordPerfectImportFilterDialog::setPropertyValues( const Sequence<PropertyValue>& aProps)
333 : throw(com::sun::star::beans::UnknownPropertyException, com::sun::star::beans::PropertyVetoException,
334 : com::sun::star::lang::IllegalArgumentException, com::sun::star::lang::WrappedTargetException, RuntimeException, std::exception)
335 : {
336 0 : const PropertyValue *pPropArray = aProps.getConstArray();
337 0 : long nPropCount = aProps.getLength();
338 0 : for (long i = 0; i < nPropCount; i++)
339 : {
340 0 : const PropertyValue &rProp = pPropArray[i];
341 0 : OUString aPropName = rProp.Name;
342 :
343 0 : if ( aPropName == "Password" )
344 0 : rProp.Value >>= msPassword;
345 0 : else if ( aPropName == "InputStream" )
346 0 : rProp.Value >>= mxInputStream;
347 0 : }
348 0 : }
349 :
350 :
351 : // XServiceInfo
352 0 : OUString SAL_CALL WordPerfectImportFilterDialog::getImplementationName( )
353 : throw (RuntimeException, std::exception)
354 : {
355 0 : return WordPerfectImportFilterDialog_getImplementationName();
356 : }
357 :
358 0 : sal_Bool SAL_CALL WordPerfectImportFilterDialog::supportsService( const OUString &rServiceName )
359 : throw (RuntimeException, std::exception)
360 : {
361 0 : return cppu::supportsService( this, rServiceName );
362 : }
363 :
364 0 : Sequence< OUString > SAL_CALL WordPerfectImportFilterDialog::getSupportedServiceNames( )
365 : throw (RuntimeException, std::exception)
366 : {
367 0 : return WordPerfectImportFilterDialog_getSupportedServiceNames();
368 : }
369 :
370 0 : OUString WordPerfectImportFilterDialog_getImplementationName ()
371 : throw (RuntimeException)
372 : {
373 0 : return OUString ( "com.sun.star.comp.Writer.WordPerfectImportFilterDialog" );
374 : }
375 :
376 0 : Sequence< OUString > SAL_CALL WordPerfectImportFilterDialog_getSupportedServiceNames( )
377 : throw (RuntimeException)
378 : {
379 0 : Sequence < OUString > aRet(1);
380 0 : OUString *pArray = aRet.getArray();
381 0 : pArray[0] = "com.sun.star.ui.dialogs.FilterOptionsDialog";
382 0 : return aRet;
383 : }
384 :
385 0 : Reference< XInterface > SAL_CALL WordPerfectImportFilterDialog_createInstance( const Reference< XComponentContext > & rContext)
386 : throw( Exception )
387 : {
388 0 : return (cppu::OWeakObject *) new WordPerfectImportFilterDialog( rContext );
389 9 : }
390 :
391 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|