Branch data 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 <com/sun/star/ucb/XCommandEnvironment.hpp>
23 : :
24 : : #include <comphelper/componentcontext.hxx>
25 : : #include <xmloff/attrlist.hxx>
26 : : #include <sfx2/passwd.hxx>
27 : : #include <ucbhelper/content.hxx>
28 : :
29 : : #include <libwpd/libwpd.h>
30 : :
31 : : #include "filter/FilterInternal.hxx"
32 : : #include "filter/DocumentHandler.hxx"
33 : : #include "filter/OdgGenerator.hxx"
34 : : #include "filter/OdtGenerator.hxx"
35 : : #include "stream/WPXSvStream.h"
36 : : #include "WordPerfectImportFilter.hxx"
37 : :
38 : : using ::rtl::OString;
39 : : using ::rtl::OUString;
40 : : using ::ucbhelper::Content;
41 : : using com::sun::star::uno::Sequence;
42 : : using com::sun::star::uno::Reference;
43 : : using com::sun::star::uno::Any;
44 : : using com::sun::star::uno::UNO_QUERY;
45 : : using com::sun::star::uno::XInterface;
46 : : using com::sun::star::uno::Exception;
47 : : using com::sun::star::uno::RuntimeException;
48 : : using com::sun::star::uno::XComponentContext;
49 : : using com::sun::star::beans::PropertyValue;
50 : : using com::sun::star::document::XFilter;
51 : : using com::sun::star::document::XExtendedFilterDetection;
52 : : using com::sun::star::ucb::XCommandEnvironment;
53 : :
54 : : using com::sun::star::io::XInputStream;
55 : : using com::sun::star::document::XImporter;
56 : : using com::sun::star::xml::sax::InputSource;
57 : : using com::sun::star::xml::sax::XAttributeList;
58 : : using com::sun::star::xml::sax::XDocumentHandler;
59 : : using com::sun::star::xml::sax::XParser;
60 : :
61 : : void callHandler(Reference < XDocumentHandler > xDocHandler);
62 : :
63 : :
64 : 0 : static bool handleEmbeddedWPGObject(const WPXBinaryData &data, OdfDocumentHandler *pHandler, const OdfStreamType streamType)
65 : : {
66 [ # # ]: 0 : OdgGenerator exporter(pHandler, streamType);
67 : :
68 : 0 : libwpg::WPGFileFormat fileFormat = libwpg::WPG_AUTODETECT;
69 : :
70 [ # # ][ # # ]: 0 : if (!libwpg::WPGraphics::isSupported(const_cast<WPXInputStream *>(data.getDataStream())))
[ # # ]
71 : 0 : fileFormat = libwpg::WPG_WPG1;
72 : :
73 [ # # ][ # # ]: 0 : return libwpg::WPGraphics::parse(const_cast<WPXInputStream *>(data.getDataStream()), &exporter, fileFormat);
[ # # ]
74 : : }
75 : :
76 : 0 : static bool handleEmbeddedWPGImage(const WPXBinaryData &input, WPXBinaryData &output)
77 : : {
78 [ # # ]: 0 : WPXString svgOutput;
79 : 0 : libwpg::WPGFileFormat fileFormat = libwpg::WPG_AUTODETECT;
80 : :
81 [ # # ][ # # ]: 0 : if (!libwpg::WPGraphics::isSupported(const_cast<WPXInputStream *>(input.getDataStream())))
[ # # ]
82 : 0 : fileFormat = libwpg::WPG_WPG1;
83 : :
84 [ # # ][ # # ]: 0 : if (!libwpg::WPGraphics::generateSVG(const_cast<WPXInputStream *>(input.getDataStream()), svgOutput, fileFormat))
[ # # ]
85 : 0 : return false;
86 : :
87 [ # # ]: 0 : output.clear();
88 [ # # ][ # # ]: 0 : output.append((unsigned char *)svgOutput.cstr(), strlen(svgOutput.cstr()));
[ # # ]
89 [ # # ]: 0 : return true;
90 : : }
91 : :
92 : 0 : sal_Bool SAL_CALL WordPerfectImportFilter::importImpl( const Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
93 : : throw (RuntimeException)
94 : : {
95 : : WRITER_DEBUG_MSG(("WordPerfectImportFilter::importImpl: Got here!\n"));
96 : :
97 : 0 : sal_Int32 nLength = aDescriptor.getLength();
98 : 0 : const PropertyValue *pValue = aDescriptor.getConstArray();
99 : 0 : OUString sURL;
100 : 0 : Reference < XInputStream > xInputStream;
101 [ # # ]: 0 : for ( sal_Int32 i = 0 ; i < nLength; i++)
102 : : {
103 [ # # ]: 0 : if ( pValue[i].Name == "InputStream" )
104 [ # # ]: 0 : pValue[i].Value >>= xInputStream;
105 [ # # ]: 0 : else if ( pValue[i].Name == "URL" )
106 : 0 : pValue[i].Value >>= sURL;
107 : : }
108 [ # # ]: 0 : if ( !xInputStream.is() )
109 : : {
110 : : OSL_ASSERT( 0 );
111 : 0 : return sal_False;
112 : : }
113 : :
114 [ # # ]: 0 : WPXSvInputStream input( xInputStream );
115 : :
116 : 0 : OString aUtf8Passwd;
117 : :
118 [ # # ]: 0 : WPDConfidence confidence = WPDocument::isFileFormatSupported(&input);
119 : :
120 [ # # ]: 0 : if (WPD_CONFIDENCE_SUPPORTED_ENCRYPTION == confidence)
121 : : {
122 : 0 : int unsuccessfulAttempts = 0;
123 : 0 : while (true )
124 : : {
125 [ # # ]: 0 : SfxPasswordDialog aPasswdDlg( 0 );
126 [ # # ]: 0 : aPasswdDlg.SetMinLen(0);
127 [ # # ][ # # ]: 0 : if(!aPasswdDlg.Execute())
128 : 0 : return sal_False;
129 [ # # ]: 0 : String aPasswd = aPasswdDlg.GetPassword();
130 : 0 : OUString aUniPasswd(aPasswd.GetBuffer() /*, aPasswd.Len(), RTL_TEXTENCODING_UCS2 */);
131 [ # # ]: 0 : aUtf8Passwd = OUStringToOString(aUniPasswd, RTL_TEXTENCODING_UTF8);
132 [ # # ][ # # ]: 0 : if (WPD_PASSWORD_MATCH_OK == WPDocument::verifyPassword(&input, aUtf8Passwd.getStr()))
133 : : break;
134 : : else
135 : 0 : unsuccessfulAttempts++;
136 [ # # ]: 0 : if (unsuccessfulAttempts == 3) // timeout after 3 password atempts
137 : 0 : return sal_False;
138 [ # # # ]: 0 : }
[ # # ]
[ # # # ]
[ # # ]
[ # # # ]
139 : : }
140 : :
141 : : // An XML import service: what we push sax messages to..
142 : 0 : OUString sXMLImportService ( "com.sun.star.comp.Writer.XMLOasisImporter" );
143 [ # # ][ # # ]: 0 : Reference < XDocumentHandler > xInternalHandler( comphelper::ComponentContext( mxContext ).createComponent( sXMLImportService ), UNO_QUERY );
[ # # ][ # # ]
144 : :
145 : : // The XImporter sets up an empty target document for XDocumentHandler to write to..
146 [ # # ]: 0 : Reference < XImporter > xImporter(xInternalHandler, UNO_QUERY);
147 [ # # ][ # # ]: 0 : xImporter->setTargetDocument(mxDoc);
148 : :
149 : : // OO Document Handler: abstract class to handle document SAX messages, concrete implementation here
150 : : // writes to in-memory target doc
151 [ # # ]: 0 : DocumentHandler xHandler(xInternalHandler);
152 : :
153 [ # # ]: 0 : OdtGenerator collector(&xHandler, ODF_FLAT_XML);
154 [ # # ][ # # ]: 0 : collector.registerEmbeddedObjectHandler("image/x-wpg", &handleEmbeddedWPGObject);
[ # # ]
155 [ # # ][ # # ]: 0 : collector.registerEmbeddedImageHandler("image/x-wpg", &handleEmbeddedWPGImage);
[ # # ]
156 [ # # ][ # # ]: 0 : if (WPD_OK == WPDocument::parse(&input, &collector, aUtf8Passwd.isEmpty() ? 0 : aUtf8Passwd.getStr()))
[ # # ]
157 : 0 : return sal_True;
158 [ # # ][ # # ]: 0 : return sal_False;
159 : : }
160 : :
161 : 0 : sal_Bool SAL_CALL WordPerfectImportFilter::filter( const Sequence< ::com::sun::star::beans::PropertyValue >& aDescriptor )
162 : : throw (RuntimeException)
163 : : {
164 : : WRITER_DEBUG_MSG(("WordPerfectImportFilter::filter: Got here!\n"));
165 : 0 : return importImpl ( aDescriptor );
166 : : }
167 : 0 : void SAL_CALL WordPerfectImportFilter::cancel( )
168 : : throw (RuntimeException)
169 : : {
170 : : WRITER_DEBUG_MSG(("WordPerfectImportFilter::cancel: Got here!\n"));
171 : 0 : }
172 : :
173 : : // XImporter
174 : 0 : void SAL_CALL WordPerfectImportFilter::setTargetDocument( const Reference< ::com::sun::star::lang::XComponent >& xDoc )
175 : : throw (::com::sun::star::lang::IllegalArgumentException, RuntimeException)
176 : : {
177 : : WRITER_DEBUG_MSG(("WordPerfectImportFilter::getTargetDocument: Got here!\n"));
178 : 0 : mxDoc = xDoc;
179 : 0 : }
180 : :
181 : : // XExtendedFilterDetection
182 : 10 : OUString SAL_CALL WordPerfectImportFilter::detect( Sequence< PropertyValue >& Descriptor )
183 : : throw( RuntimeException )
184 : : {
185 : : WRITER_DEBUG_MSG(("WordPerfectImportFilter::detect: Got here!\n"));
186 : :
187 : 10 : WPDConfidence confidence = WPD_CONFIDENCE_NONE;
188 : 10 : OUString sTypeName;
189 : 10 : sal_Int32 nLength = Descriptor.getLength();
190 : 10 : sal_Int32 location = nLength;
191 : 10 : OUString sURL;
192 : 10 : const PropertyValue *pValue = Descriptor.getConstArray();
193 : 10 : Reference < XInputStream > xInputStream;
194 [ + + ]: 80 : for ( sal_Int32 i = 0 ; i < nLength; i++)
195 : : {
196 [ - + ]: 70 : if ( pValue[i].Name == "TypeName" )
197 : 0 : location=i;
198 [ + + ]: 70 : else if ( pValue[i].Name == "InputStream" )
199 [ + - ]: 10 : pValue[i].Value >>= xInputStream;
200 [ + + ]: 60 : else if ( pValue[i].Name == "URL" )
201 : 10 : pValue[i].Value >>= sURL;
202 : : }
203 : :
204 : 10 : Reference< com::sun::star::ucb::XCommandEnvironment > xEnv;
205 [ - + ]: 10 : if (!xInputStream.is())
206 : : {
207 : : try
208 : : {
209 [ # # ]: 0 : Content aContent(sURL, xEnv);
210 [ # # ][ # # ]: 0 : xInputStream = aContent.openStream();
[ # # ]
211 : : }
212 [ # # ]: 0 : catch ( ... )
213 : : {
214 : 0 : return ::rtl::OUString();
215 : : }
216 : :
217 [ # # ]: 0 : if (!xInputStream.is())
218 : 0 : return ::rtl::OUString();
219 : : }
220 : :
221 [ + - ]: 10 : WPXSvInputStream input( xInputStream );
222 : :
223 [ - + ][ + - ]: 10 : if (input.atEOS())
224 : 0 : return ::rtl::OUString();
225 : :
226 [ + - ]: 10 : confidence = WPDocument::isFileFormatSupported(&input);
227 : :
228 [ + - ][ - + ]: 10 : if (confidence == WPD_CONFIDENCE_EXCELLENT || confidence == WPD_CONFIDENCE_SUPPORTED_ENCRYPTION)
229 : 0 : sTypeName = OUString( "writer_WordPerfect_Document" );
230 : :
231 [ - + ]: 10 : if (!sTypeName.isEmpty())
232 : : {
233 [ # # ]: 0 : if ( location == Descriptor.getLength() )
234 : : {
235 [ # # ]: 0 : Descriptor.realloc(nLength+1);
236 [ # # ]: 0 : Descriptor[location].Name = ::rtl::OUString("TypeName");
237 : : }
238 : :
239 [ # # ][ # # ]: 0 : Descriptor[location].Value <<=sTypeName;
240 : : }
241 : :
242 [ + - ]: 10 : return sTypeName;
243 : : }
244 : :
245 : :
246 : : // XInitialization
247 : 0 : void SAL_CALL WordPerfectImportFilter::initialize( const Sequence< Any >& aArguments )
248 : : throw (Exception, RuntimeException)
249 : : {
250 : : WRITER_DEBUG_MSG(("WordPerfectImportFilter::initialize: Got here!\n"));
251 [ # # ]: 0 : Sequence < PropertyValue > aAnySeq;
252 : 0 : sal_Int32 nLength = aArguments.getLength();
253 [ # # ][ # # ]: 0 : if ( nLength && ( aArguments[0] >>= aAnySeq ) )
[ # # ][ # # ]
254 : : {
255 : 0 : const PropertyValue *pValue = aAnySeq.getConstArray();
256 : 0 : nLength = aAnySeq.getLength();
257 [ # # ]: 0 : for ( sal_Int32 i = 0 ; i < nLength; i++)
258 : : {
259 [ # # ]: 0 : if ( pValue[i].Name == "Type" )
260 : : {
261 : 0 : pValue[i].Value >>= msFilterName;
262 : 0 : break;
263 : : }
264 : : }
265 [ # # ]: 0 : }
266 : 0 : }
267 : 12 : OUString WordPerfectImportFilter_getImplementationName ()
268 : : throw (RuntimeException)
269 : : {
270 : 12 : return OUString ( "com.sun.star.comp.Writer.WordPerfectImportFilter" );
271 : : }
272 : :
273 : : #define SERVICE_NAME1 "com.sun.star.document.ImportFilter"
274 : : #define SERVICE_NAME2 "com.sun.star.document.ExtendedTypeDetection"
275 : 0 : sal_Bool SAL_CALL WordPerfectImportFilter_supportsService( const OUString &ServiceName )
276 : : throw (RuntimeException)
277 : : {
278 [ # # ][ # # ]: 0 : return ( ServiceName == SERVICE_NAME1 || ServiceName == SERVICE_NAME2 );
279 : : }
280 : 6 : Sequence< OUString > SAL_CALL WordPerfectImportFilter_getSupportedServiceNames( )
281 : : throw (RuntimeException)
282 : : {
283 : 6 : Sequence < OUString > aRet(2);
284 [ + - ]: 6 : OUString *pArray = aRet.getArray();
285 : 6 : pArray[0] = OUString ( SERVICE_NAME1 );
286 : 6 : pArray[1] = OUString ( SERVICE_NAME2 );
287 : 6 : return aRet;
288 : : }
289 : : #undef SERVICE_NAME2
290 : : #undef SERVICE_NAME1
291 : :
292 : 10 : Reference< XInterface > SAL_CALL WordPerfectImportFilter_createInstance( const Reference< XComponentContext > & rContext)
293 : : throw( Exception )
294 : : {
295 [ + - ]: 10 : return (cppu::OWeakObject *) new WordPerfectImportFilter( rContext );
296 : : }
297 : :
298 : : // XServiceInfo
299 : 0 : OUString SAL_CALL WordPerfectImportFilter::getImplementationName( )
300 : : throw (RuntimeException)
301 : : {
302 : 0 : return WordPerfectImportFilter_getImplementationName();
303 : : }
304 : 0 : sal_Bool SAL_CALL WordPerfectImportFilter::supportsService( const OUString &rServiceName )
305 : : throw (RuntimeException)
306 : : {
307 : 0 : return WordPerfectImportFilter_supportsService( rServiceName );
308 : : }
309 : 0 : Sequence< OUString > SAL_CALL WordPerfectImportFilter::getSupportedServiceNames( )
310 : : throw (RuntimeException)
311 : : {
312 : 0 : return WordPerfectImportFilter_getSupportedServiceNames();
313 : : }
314 : :
315 : :
316 : 0 : WordPerfectImportFilterDialog::WordPerfectImportFilterDialog( const Reference< XComponentContext > & rContext) :
317 : 0 : mxContext( rContext ) {}
318 : :
319 : 0 : WordPerfectImportFilterDialog::~WordPerfectImportFilterDialog()
320 : : {
321 [ # # ]: 0 : }
322 : :
323 : 0 : void SAL_CALL WordPerfectImportFilterDialog::setTitle( const ::rtl::OUString & )
324 : : throw (RuntimeException)
325 : : {
326 : 0 : }
327 : :
328 : 0 : sal_Int16 SAL_CALL WordPerfectImportFilterDialog::execute()
329 : : throw (RuntimeException)
330 : : {
331 [ # # ]: 0 : WPXSvInputStream input( mxInputStream );
332 : :
333 : 0 : OString aUtf8Passwd;
334 : :
335 [ # # ]: 0 : WPDConfidence confidence = WPDocument::isFileFormatSupported(&input);
336 : :
337 [ # # ]: 0 : if (WPD_CONFIDENCE_SUPPORTED_ENCRYPTION == confidence)
338 : : {
339 : 0 : int unsuccessfulAttempts = 0;
340 : 0 : while (true )
341 : : {
342 [ # # ]: 0 : SfxPasswordDialog aPasswdDlg(0);
343 [ # # ]: 0 : aPasswdDlg.SetMinLen(0);
344 [ # # ][ # # ]: 0 : if(!aPasswdDlg.Execute())
345 : 0 : return com::sun::star::ui::dialogs::ExecutableDialogResults::CANCEL;
346 [ # # ][ # # ]: 0 : msPassword = ::rtl::OUString(aPasswdDlg.GetPassword().GetBuffer());
347 [ # # ]: 0 : aUtf8Passwd = OUStringToOString(msPassword, RTL_TEXTENCODING_UTF8);
348 [ # # ][ # # ]: 0 : if (WPD_PASSWORD_MATCH_OK == WPDocument::verifyPassword(&input, aUtf8Passwd.getStr()))
349 : : break;
350 : : else
351 : 0 : unsuccessfulAttempts++;
352 [ # # ]: 0 : if (unsuccessfulAttempts == 3) // timeout after 3 password atempts
353 : 0 : return com::sun::star::ui::dialogs::ExecutableDialogResults::CANCEL;
354 [ # # ]: 0 : }
[ # # # ]
355 : : }
356 [ # # ]: 0 : return com::sun::star::ui::dialogs::ExecutableDialogResults::OK;
357 : : }
358 : :
359 : 0 : Sequence<PropertyValue> SAL_CALL WordPerfectImportFilterDialog::getPropertyValues() throw(RuntimeException)
360 : : {
361 : 0 : Sequence<PropertyValue> aRet(1);
362 [ # # ]: 0 : PropertyValue *pArray = aRet.getArray();
363 : :
364 : 0 : pArray[0].Name = rtl::OUString( "Password" );
365 [ # # ]: 0 : pArray[0].Value <<= msPassword;
366 : :
367 : 0 : return aRet;
368 : : }
369 : :
370 : 0 : void SAL_CALL WordPerfectImportFilterDialog::setPropertyValues( const Sequence<PropertyValue>& aProps)
371 : : throw(com::sun::star::beans::UnknownPropertyException, com::sun::star::beans::PropertyVetoException,
372 : : com::sun::star::lang::IllegalArgumentException, com::sun::star::lang::WrappedTargetException, RuntimeException)
373 : : {
374 : 0 : const PropertyValue *pPropArray = aProps.getConstArray();
375 : 0 : long nPropCount = aProps.getLength();
376 [ # # ]: 0 : for (long i = 0; i < nPropCount; i++)
377 : : {
378 : 0 : const PropertyValue &rProp = pPropArray[i];
379 : 0 : ::rtl::OUString aPropName = rProp.Name;
380 : :
381 [ # # ]: 0 : if ( aPropName == ::rtl::OUString("Password") )
382 : 0 : rProp.Value >>= msPassword;
383 [ # # ]: 0 : else if ( aPropName == "InputStream" )
384 [ # # ]: 0 : rProp.Value >>= mxInputStream;
385 : 0 : }
386 : 0 : }
387 : :
388 : :
389 : : // XServiceInfo
390 : 0 : OUString SAL_CALL WordPerfectImportFilterDialog::getImplementationName( )
391 : : throw (RuntimeException)
392 : : {
393 : 0 : return WordPerfectImportFilterDialog_getImplementationName();
394 : : }
395 : :
396 : 0 : sal_Bool SAL_CALL WordPerfectImportFilterDialog::supportsService( const OUString &rServiceName )
397 : : throw (RuntimeException)
398 : : {
399 : 0 : return WordPerfectImportFilterDialog_supportsService( rServiceName );
400 : : }
401 : :
402 : 0 : Sequence< OUString > SAL_CALL WordPerfectImportFilterDialog::getSupportedServiceNames( )
403 : : throw (RuntimeException)
404 : : {
405 : 0 : return WordPerfectImportFilterDialog_getSupportedServiceNames();
406 : : }
407 : :
408 : 0 : OUString WordPerfectImportFilterDialog_getImplementationName ()
409 : : throw (RuntimeException)
410 : : {
411 : 0 : return OUString ( "com.sun.star.comp.Writer.WordPerfectImportFilterDialog" );
412 : : }
413 : :
414 : : #define SERVICE_NAME "com.sun.star.ui.dialogs.FilterOptionsDialog"
415 : 0 : sal_Bool SAL_CALL WordPerfectImportFilterDialog_supportsService( const OUString &ServiceName )
416 : : throw (RuntimeException)
417 : : {
418 : 0 : return ( ServiceName == SERVICE_NAME );
419 : : }
420 : :
421 : 0 : Sequence< OUString > SAL_CALL WordPerfectImportFilterDialog_getSupportedServiceNames( )
422 : : throw (RuntimeException)
423 : : {
424 : 0 : Sequence < OUString > aRet(1);
425 [ # # ]: 0 : OUString *pArray = aRet.getArray();
426 : 0 : pArray[0] = OUString ( SERVICE_NAME );
427 : 0 : return aRet;
428 : : }
429 : : #undef SERVICE_NAME
430 : :
431 : 0 : Reference< XInterface > SAL_CALL WordPerfectImportFilterDialog_createInstance( const Reference< XComponentContext > & rContext)
432 : : throw( Exception )
433 : : {
434 [ # # ]: 0 : return (cppu::OWeakObject *) new WordPerfectImportFilterDialog( rContext );
435 : : }
436 : :
437 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|