LCOV - code coverage report
Current view: top level - writerperfect/source/writer - WordPerfectImportFilter.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 68 175 38.9 %
Date: 2015-06-13 12:38:46 Functions: 11 29 37.9 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11