/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* "This product is not manufactured, approved, or supported by * Corel Corporation or Corel Corporation Limited." */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "WordPerfectImportFilter.hxx" using ::ucbhelper::Content; using com::sun::star::uno::Sequence; using com::sun::star::uno::Reference; using com::sun::star::uno::Any; using com::sun::star::uno::UNO_QUERY; using com::sun::star::uno::XInterface; using com::sun::star::uno::Exception; using com::sun::star::uno::RuntimeException; using com::sun::star::uno::XComponentContext; using com::sun::star::beans::PropertyValue; using com::sun::star::document::XFilter; using com::sun::star::document::XExtendedFilterDetection; using com::sun::star::ucb::XCommandEnvironment; using com::sun::star::io::XInputStream; using com::sun::star::document::XImporter; using com::sun::star::xml::sax::InputSource; using com::sun::star::xml::sax::XAttributeList; using com::sun::star::xml::sax::XDocumentHandler; using com::sun::star::xml::sax::XParser; using writerperfect::DocumentHandler; using writerperfect::WPXSvInputStream; static bool handleEmbeddedWPGObject(const librevenge::RVNGBinaryData &data, OdfDocumentHandler *pHandler, const OdfStreamType streamType) { OdgGenerator exporter; exporter.addDocumentHandler(pHandler, streamType); libwpg::WPGFileFormat fileFormat = libwpg::WPG_AUTODETECT; if (!libwpg::WPGraphics::isSupported(data.getDataStream())) fileFormat = libwpg::WPG_WPG1; return libwpg::WPGraphics::parse(data.getDataStream(), &exporter, fileFormat); } static bool handleEmbeddedWPGImage(const librevenge::RVNGBinaryData &input, librevenge::RVNGBinaryData &output) { libwpg::WPGFileFormat fileFormat = libwpg::WPG_AUTODETECT; if (!libwpg::WPGraphics::isSupported(input.getDataStream())) fileFormat = libwpg::WPG_WPG1; librevenge::RVNGStringVector svgOutput; librevenge::RVNGSVGDrawingGenerator aSVGGenerator(svgOutput, ""); if (!libwpg::WPGraphics::parse(input.getDataStream(), &aSVGGenerator, fileFormat)) return false; assert(1 == svgOutput.size()); output.clear(); output.append(reinterpret_cast(svgOutput[0].cstr()), svgOutput[0].size()); return true; } bool SAL_CALL WordPerfectImportFilter::importImpl(const Sequence< ::com::sun::star::beans::PropertyValue > &aDescriptor) throw (RuntimeException, std::exception) { sal_Int32 nLength = aDescriptor.getLength(); const PropertyValue *pValue = aDescriptor.getConstArray(); Reference < XInputStream > xInputStream; for (sal_Int32 i = 0 ; i < nLength; i++) { if (pValue[i].Name == "InputStream") pValue[i].Value >>= xInputStream; } if (!xInputStream.is()) { OSL_ASSERT(false); return false; } WPXSvInputStream input(xInputStream); OString aUtf8Passwd; libwpd::WPDConfidence confidence = libwpd::WPDocument::isFileFormatSupported(&input); if (libwpd::WPD_CONFIDENCE_SUPPORTED_ENCRYPTION == confidence) { int unsuccessfulAttempts = 0; while (true) { SfxPasswordDialog aPasswdDlg(0); aPasswdDlg.SetMinLen(0); if (!aPasswdDlg.Execute()) return false; OUString aPasswd = aPasswdDlg.GetPassword(); aUtf8Passwd = OUStringToOString(aPasswd, RTL_TEXTENCODING_UTF8); if (libwpd::WPD_PASSWORD_MATCH_OK == libwpd::WPDocument::verifyPassword(&input, aUtf8Passwd.getStr())) break; else unsuccessfulAttempts++; if (unsuccessfulAttempts == 3) // timeout after 3 password atempts return false; } } // An XML import service: what we push sax messages to.. Reference < XDocumentHandler > xInternalHandler( mxContext->getServiceManager()->createInstanceWithContext( "com.sun.star.comp.Writer.XMLOasisImporter", mxContext), css::uno::UNO_QUERY_THROW); // The XImporter sets up an empty target document for XDocumentHandler to write to.. Reference < XImporter > xImporter(xInternalHandler, UNO_QUERY); xImporter->setTargetDocument(mxDoc); // OO Document Handler: abstract class to handle document SAX messages, concrete implementation here // writes to in-memory target doc DocumentHandler xHandler(xInternalHandler); OdtGenerator collector; collector.addDocumentHandler(&xHandler, ODF_FLAT_XML); collector.registerEmbeddedObjectHandler("image/x-wpg", &handleEmbeddedWPGObject); collector.registerEmbeddedImageHandler("image/x-wpg", &handleEmbeddedWPGImage); if (libwpd::WPD_OK == libwpd::WPDocument::parse(&input, &collector, aUtf8Passwd.isEmpty() ? 0 : aUtf8Passwd.getStr())) return true; return false; } sal_Bool SAL_CALL WordPerfectImportFilter::filter(const Sequence< ::com::sun::star::beans::PropertyValue > &aDescriptor) throw (RuntimeException, std::exception) { return importImpl(aDescriptor); } void SAL_CALL WordPerfectImportFilter::cancel() throw (RuntimeException, std::exception) { } // XImporter void SAL_CALL WordPerfectImportFilter::setTargetDocument(const Reference< ::com::sun::star::lang::XComponent > &xDoc) throw (::com::sun::star::lang::IllegalArgumentException, RuntimeException, std::exception) { mxDoc = xDoc; } // XExtendedFilterDetection OUString SAL_CALL WordPerfectImportFilter::detect(Sequence< PropertyValue > &Descriptor) throw(RuntimeException, std::exception) { libwpd::WPDConfidence confidence = libwpd::WPD_CONFIDENCE_NONE; OUString sTypeName; sal_Int32 nLength = Descriptor.getLength(); sal_Int32 location = nLength; const PropertyValue *pValue = Descriptor.getConstArray(); Reference < XInputStream > xInputStream; for (sal_Int32 i = 0 ; i < nLength; i++) { if (pValue[i].Name == "TypeName") location=i; else if (pValue[i].Name == "InputStream") pValue[i].Value >>= xInputStream; } if (!xInputStream.is()) return OUString(); WPXSvInputStream input(xInputStream); confidence = libwpd::WPDocument::isFileFormatSupported(&input); if (confidence == libwpd::WPD_CONFIDENCE_EXCELLENT || confidence == libwpd::WPD_CONFIDENCE_SUPPORTED_ENCRYPTION) sTypeName = "writer_WordPerfect_Document"; if (!sTypeName.isEmpty()) { if (location == nLength) { Descriptor.realloc(nLength+1); Descriptor[location].Name = "TypeName"; } Descriptor[location].Value <<=sTypeName; } return sTypeName; } // XInitialization void SAL_CALL WordPerfectImportFilter::initialize(const Sequence< Any > &aArguments) throw (Exception, RuntimeException, std::exception) { Sequence < PropertyValue > aAnySeq; sal_Int32 nLength = aArguments.getLength(); if (nLength && (aArguments[0] >>= aAnySeq)) { const PropertyValue *pValue = aAnySeq.getConstArray(); nLength = aAnySeq.getLength(); for (sal_Int32 i = 0 ; i < nLength; i++) { if (pValue[i].Name == "Type") { pValue[i].Value >>= msFilterName; break; } } } } OUString WordPerfectImportFilter_getImplementationName() throw (RuntimeException) { return OUString("com.sun.star.comp.Writer.WordPerfectImportFilter"); } Sequence< OUString > SAL_CALL WordPerfectImportFilter_getSupportedServiceNames() throw (RuntimeException) { Sequence < OUString > aRet(2); OUString *pArray = aRet.getArray(); pArray[0] = "com.sun.star.document.ImportFilter"; pArray[1] = "com.sun.star.document.ExtendedTypeDetection"; return aRet; } Reference< XInterface > SAL_CALL WordPerfectImportFilter_createInstance(const Reference< XComponentContext > &rContext) throw(Exception) { return (cppu::OWeakObject *) new WordPerfectImportFilter(rContext); } // XServiceInfo OUString SAL_CALL WordPerfectImportFilter::getImplementationName() throw (RuntimeException, std::exception) { return WordPerfectImportFilter_getImplementationName(); } sal_Bool SAL_CALL WordPerfectImportFilter::supportsService(const OUString &rServiceName) throw (RuntimeException, std::exception) { return cppu::supportsService(this, rServiceName); } Sequence< OUString > SAL_CALL WordPerfectImportFilter::getSupportedServiceNames() throw (RuntimeException, std::exception) { return WordPerfectImportFilter_getSupportedServiceNames(); } WordPerfectImportFilterDialog::WordPerfectImportFilterDialog(const Reference< XComponentContext > &rContext) : mxContext(rContext) {} WordPerfectImportFilterDialog::~WordPerfectImportFilterDialog() { } void SAL_CALL WordPerfectImportFilterDialog::setTitle(const OUString &) throw (RuntimeException, std::exception) { } sal_Int16 SAL_CALL WordPerfectImportFilterDialog::execute() throw (RuntimeException, std::exception) { WPXSvInputStream input(mxInputStream); OString aUtf8Passwd; libwpd::WPDConfidence confidence = libwpd::WPDocument::isFileFormatSupported(&input); if (libwpd::WPD_CONFIDENCE_SUPPORTED_ENCRYPTION == confidence) { int unsuccessfulAttempts = 0; while (true) { SfxPasswordDialog aPasswdDlg(0); aPasswdDlg.SetMinLen(0); if (!aPasswdDlg.Execute()) return com::sun::star::ui::dialogs::ExecutableDialogResults::CANCEL; msPassword = aPasswdDlg.GetPassword().getStr(); aUtf8Passwd = OUStringToOString(msPassword, RTL_TEXTENCODING_UTF8); if (libwpd::WPD_PASSWORD_MATCH_OK == libwpd::WPDocument::verifyPassword(&input, aUtf8Passwd.getStr())) break; else unsuccessfulAttempts++; if (unsuccessfulAttempts == 3) // timeout after 3 password atempts return com::sun::star::ui::dialogs::ExecutableDialogResults::CANCEL; } } return com::sun::star::ui::dialogs::ExecutableDialogResults::OK; } Sequence SAL_CALL WordPerfectImportFilterDialog::getPropertyValues() throw(RuntimeException, std::exception) { Sequence aRet(1); PropertyValue *pArray = aRet.getArray(); pArray[0].Name = "Password"; pArray[0].Value <<= msPassword; return aRet; } void SAL_CALL WordPerfectImportFilterDialog::setPropertyValues(const Sequence &aProps) throw(com::sun::star::beans::UnknownPropertyException, com::sun::star::beans::PropertyVetoException, com::sun::star::lang::IllegalArgumentException, com::sun::star::lang::WrappedTargetException, RuntimeException, std::exception) { const PropertyValue *pPropArray = aProps.getConstArray(); long nPropCount = aProps.getLength(); for (long i = 0; i < nPropCount; i++) { const PropertyValue &rProp = pPropArray[i]; OUString aPropName = rProp.Name; if (aPropName == "Password") rProp.Value >>= msPassword; else if (aPropName == "InputStream") rProp.Value >>= mxInputStream; } } // XServiceInfo OUString SAL_CALL WordPerfectImportFilterDialog::getImplementationName() throw (RuntimeException, std::exception) { return WordPerfectImportFilterDialog_getImplementationName(); } sal_Bool SAL_CALL WordPerfectImportFilterDialog::supportsService(const OUString &rServiceName) throw (RuntimeException, std::exception) { return cppu::supportsService(this, rServiceName); } Sequence< OUString > SAL_CALL WordPerfectImportFilterDialog::getSupportedServiceNames() throw (RuntimeException, std::exception) { return WordPerfectImportFilterDialog_getSupportedServiceNames(); } OUString WordPerfectImportFilterDialog_getImplementationName() throw (RuntimeException) { return OUString("com.sun.star.comp.Writer.WordPerfectImportFilterDialog"); } Sequence< OUString > SAL_CALL WordPerfectImportFilterDialog_getSupportedServiceNames() throw (RuntimeException) { Sequence < OUString > aRet(1); OUString *pArray = aRet.getArray(); pArray[0] = "com.sun.star.ui.dialogs.FilterOptionsDialog"; return aRet; } Reference< XInterface > SAL_CALL WordPerfectImportFilterDialog_createInstance(const Reference< XComponentContext > &rContext) throw(Exception) { return (cppu::OWeakObject *) new WordPerfectImportFilterDialog(rContext); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */