/* -*- 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: */