/* This file is part of the KDE project Copyright (C) 2002,2006 Ariya Hidayat This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include #ifdef HAVE_UNISTD_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pole.h" typedef KGenericFactory HancomWordImportFactory; K_EXPORT_COMPONENT_FACTORY( libhancomwordimport, HancomWordImportFactory( "kofficefilters" ) ) class HancomWordImport::Private { public: TQString inputFile; TQString outputFile; TQStringList paragraphs; TQByteArray createStyles(); TQByteArray createContent(); TQByteArray createManifest(); }; HancomWordImport::HancomWordImport ( TQObject*, const char*, const TQStringList& ) : KoFilter() { d = new Private; } HancomWordImport::~HancomWordImport() { delete d; } namespace { static inline unsigned long readU16( const void* p ) { const unsigned char* ptr = (const unsigned char*) p; return ptr[0]+(ptr[1]<<8); } } KoFilter::ConversiontqStatus HancomWordImport::convert( const TQCString& from, const TQCString& to ) { if ( from != "application/x-hancomword" ) return KoFilter::NotImplemented; if ( to != "application/vnd.oasis.opendocument.text" ) return KoFilter::NotImplemented; d->inputFile = m_chain->inputFile(); d->outputFile = m_chain->outputFile(); d->paragraphs.clear(); POLE::Storage storage( d->inputFile.latin1() ); if( !storage.open() ) return KoFilter::WrongFormat; POLE::Stream* stream; stream = new POLE::Stream( &storage, "/PrvText" ); if( stream->fail() || (stream->size() == 0) ) { delete stream; return KoFilter::WrongFormat; } int len = stream->size() / 2; TQString plaindoc; plaindoc.reserve( len ); unsigned char* buf = new unsigned char [stream->size()]; stream->read( buf, stream->size()); for(int i = 0; i < len; i++ ) plaindoc.append( TQChar((int)readU16(buf + i*2) ) ); delete[] buf; delete stream; // split into paragraphs d->paragraphs = TQStringList::split( "\n", plaindoc, true ); // create output store KoStore* storeout; storeout = KoStore::createStore( d->outputFile, KoStore::Write, "application/vnd.oasis.opendocument.text", KoStore::Zip ); if ( !storeout ) { kdWarning() << "Couldn't open the requested file." << endl; return KoFilter::FileNotFound; } if ( !storeout->open( "styles.xml" ) ) { kdWarning() << "Couldn't open the file 'styles.xml'." << endl; return KoFilter::CreationError; } storeout->write( d->createStyles() ); storeout->close(); if ( !storeout->open( "content.xml" ) ) { kdWarning() << "Couldn't open the file 'content.xml'." << endl; return KoFilter::CreationError; } storeout->write( d->createContent() ); storeout->close(); // store document manifest storeout->enterDirectory( "META-INF" ); if ( !storeout->open( "manifest.xml" ) ) { kdWarning() << "Couldn't open the file 'META-INF/manifest.xml'." << endl; return KoFilter::CreationError; } storeout->write( d->createManifest() ); storeout->close(); // we are done! d->inputFile = TQString(); d->outputFile = TQString(); delete storeout; return KoFilter::OK; } TQByteArray HancomWordImport::Private::createContent() { KoXmlWriter* contentWriter; TQByteArray contentData; TQBuffer contentBuffer( contentData ); contentBuffer.open( IO_WriteOnly ); contentWriter = new KoXmlWriter( TQT_TQIODEVICE(&contentBuffer) ); contentWriter->startDocument( "office:document-content" ); contentWriter->startElement( "office:document-content" ); contentWriter->addAttribute( "xmlns:office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0" ); contentWriter->addAttribute( "xmlns:style", "urn:oasis:names:tc:opendocument:xmlns:style:1.0" ); contentWriter->addAttribute( "xmlns:text", "urn:oasis:names:tc:opendocument:xmlns:text:1.0" ); contentWriter->addAttribute( "xmlns:table", "urn:oasis:names:tc:opendocument:xmlns:table:1.0" ); contentWriter->addAttribute( "xmlns:draw", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" ); contentWriter->addAttribute( "xmlns:fo", "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" ); contentWriter->addAttribute( "xmlns:svg","urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" ); contentWriter->addAttribute( "office:version","1.0" ); contentWriter->startElement( "office:automatic-styles" ); contentWriter->endElement(); // office:automatic-style // office:body contentWriter->startElement( "office:body" ); contentWriter->startElement( "office:text" ); contentWriter->startElement( "text:sequence-decls" ); contentWriter->endElement(); // text:sequence-decls for( uint i = 0; i < paragraphs.count(); i++ ) { TQString text = paragraphs[i]; text.tqreplace( '\r', ' ' ); contentWriter->startElement( "text:p" ); contentWriter->addTextNode( text ); contentWriter->endElement(); // text:p } contentWriter->endElement(); //office:text contentWriter->endElement(); // office:body contentWriter->endElement(); // office:document-content contentWriter->endDocument(); delete contentWriter; return contentData; } TQByteArray HancomWordImport::Private::createStyles() { KoXmlWriter* stylesWriter; TQByteArray stylesData; TQBuffer stylesBuffer( stylesData ); stylesBuffer.open( IO_WriteOnly ); stylesWriter = new KoXmlWriter( TQT_TQIODEVICE(&stylesBuffer) ); stylesWriter->startDocument( "office:document-styles" ); stylesWriter->startElement( "office:document-styles" ); stylesWriter->addAttribute( "xmlns:office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0" ); stylesWriter->addAttribute( "xmlns:style", "urn:oasis:names:tc:opendocument:xmlns:style:1.0" ); stylesWriter->addAttribute( "xmlns:text", "urn:oasis:names:tc:opendocument:xmlns:text:1.0" ); stylesWriter->addAttribute( "xmlns:table", "urn:oasis:names:tc:opendocument:xmlns:table:1.0" ); stylesWriter->addAttribute( "xmlns:draw", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" ); stylesWriter->addAttribute( "xmlns:fo", "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" ); stylesWriter->addAttribute( "xmlns:svg","urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" ); stylesWriter->addAttribute( "office:version","1.0" ); stylesWriter->startElement( "office:styles" ); // dummy default paragraph style stylesWriter->startElement( "style:default-style" ); stylesWriter->addAttribute( "style:family", "paragraph" ); stylesWriter->startElement( "style:paragraph-properties" ); stylesWriter->addAttribute( "fo:hyphenation-ladder-count", "no-limit" ); stylesWriter->addAttribute( "style:text-autospace", "ideograph-alpha" ); stylesWriter->addAttribute( "style:punctuation-wrap", "hanging" ); stylesWriter->addAttribute( "style:line-break", "strict" ); stylesWriter->addAttribute( "tyle:tab-stop-distance", "0.5in" ); stylesWriter->addAttribute( "style:writing-mode", "page" ); stylesWriter->endElement(); // style:paragraph-properties stylesWriter->startElement( "style:text-properties" ); stylesWriter->addAttribute( "style:use-window-font-color", "true" ); stylesWriter->addAttribute( "style:font-name", "Sans Serif" ); stylesWriter->addAttribute( "fo:font-size", "12pt" ); stylesWriter->addAttribute( "fo:hyphenate", "false" ); stylesWriter->endElement(); // style:text-properties stylesWriter->endElement(); // style:default-style stylesWriter->endElement(); // office:styles // office:automatic-styles stylesWriter->startElement( "office:automatic-styles" ); stylesWriter->endElement(); // office:automatic-styles stylesWriter->endElement(); // office:document-styles stylesWriter->endDocument(); delete stylesWriter; return stylesData; } TQByteArray HancomWordImport::Private::createManifest() { KoXmlWriter* manifestWriter; TQByteArray manifestData; TQBuffer manifestBuffer( manifestData ); manifestBuffer.open( IO_WriteOnly ); manifestWriter = new KoXmlWriter( TQT_TQIODEVICE(&manifestBuffer) ); manifestWriter->startDocument( "manifest:manifest" ); manifestWriter->startElement( "manifest:manifest" ); manifestWriter->addAttribute( "xmlns:manifest", "urn:oasis:names:tc:openoffice:xmlns:manifest:1.0" ); manifestWriter->addManifestEntry( "/", "application/vnd.oasis.opendocument.text" ); manifestWriter->addManifestEntry( "styles.xml", "text/xml" ); manifestWriter->addManifestEntry( "content.xml", "text/xml" ); manifestWriter->endElement(); manifestWriter->endDocument(); delete manifestWriter; return manifestData; }