filters

hancomwordimport.cpp

00001 /* This file is part of the KDE project
00002    Copyright (C) 2002,2006 Ariya Hidayat <ariya@kde.org>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include <config.h>
00021 
00022 #ifdef HAVE_UNISTD_H
00023 #include <unistd.h>
00024 #endif
00025 
00026 #include <hancomwordimport.h>
00027 #include <hancomwordimport.moc>
00028 
00029 #include <qbuffer.h>
00030 #include <qcstring.h>
00031 #include <qfile.h>
00032 #include <qstring.h>
00033 #include <qstringlist.h>
00034 #include <qtextstream.h>
00035 
00036 #include <kdebug.h>
00037 #include <KoFilterChain.h>
00038 #include <KoGlobal.h>
00039 #include <KoUnit.h>
00040 #include <kgenericfactory.h>
00041 
00042 #include <KoXmlWriter.h>
00043 
00044 #include <iostream>
00045 #include "pole.h"
00046 
00047 typedef KGenericFactory<HancomWordImport, KoFilter> HancomWordImportFactory;
00048 K_EXPORT_COMPONENT_FACTORY( libhancomwordimport, HancomWordImportFactory( "kofficefilters" ) )
00049 
00050 class HancomWordImport::Private
00051 {
00052 public:
00053   QString inputFile;
00054   QString outputFile;
00055   
00056   QStringList paragraphs;
00057   
00058   QByteArray createStyles();
00059   QByteArray createContent();
00060   QByteArray createManifest();
00061 };
00062 
00063 HancomWordImport::HancomWordImport ( QObject*, const char*, const QStringList& )
00064     : KoFilter()
00065 {
00066   d = new Private;
00067 }
00068 
00069 HancomWordImport::~HancomWordImport()
00070 {
00071   delete d;
00072 }
00073 
00074 namespace
00075 {
00076 
00077 static inline unsigned long readU16( const void* p )
00078 {
00079   const unsigned char* ptr = (const unsigned char*) p;
00080   return ptr[0]+(ptr[1]<<8);
00081 }
00082 
00083 }
00084 
00085 KoFilter::ConversionStatus HancomWordImport::convert( const QCString& from, const QCString& to )
00086 {
00087   if ( from != "application/x-hancomword" )
00088     return KoFilter::NotImplemented; 
00089 
00090   if ( to != "application/vnd.oasis.opendocument.text" )
00091     return KoFilter::NotImplemented;
00092 
00093   d->inputFile = m_chain->inputFile();
00094   d->outputFile = m_chain->outputFile();
00095   d->paragraphs.clear();
00096 
00097   POLE::Storage storage( d->inputFile.latin1() );
00098   if( !storage.open() )
00099     return KoFilter::WrongFormat;
00100   
00101   POLE::Stream* stream;
00102   stream = new POLE::Stream( &storage, "/PrvText" );
00103   if( stream->fail() || (stream->size() == 0) )
00104   {
00105     delete stream;
00106     return KoFilter::WrongFormat;
00107   }
00108   
00109   int len = stream->size() / 2;
00110   QString plaindoc;
00111   plaindoc.reserve( len );
00112   
00113   unsigned char* buf = new unsigned char [stream->size()];
00114   stream->read( buf, stream->size());
00115   for(int i = 0; i < len; i++ )
00116     plaindoc.append( QChar((int)readU16(buf + i*2) ) );
00117   delete[] buf;
00118   delete stream;
00119 
00120   // split into paragraphs
00121   d->paragraphs = QStringList::split( "\n", plaindoc, true );
00122     
00123   // create output store
00124   KoStore* storeout;
00125   storeout = KoStore::createStore( d->outputFile, KoStore::Write, 
00126     "application/vnd.oasis.opendocument.text", KoStore::Zip );
00127 
00128   if ( !storeout )
00129   {
00130     kdWarning() << "Couldn't open the requested file." << endl;
00131     return KoFilter::FileNotFound;
00132   }
00133 
00134   if ( !storeout->open( "styles.xml" ) )
00135   {
00136     kdWarning() << "Couldn't open the file 'styles.xml'." << endl;
00137     return KoFilter::CreationError;
00138   }
00139   storeout->write( d->createStyles() );
00140   storeout->close();
00141 
00142   if ( !storeout->open( "content.xml" ) )
00143   {
00144     kdWarning() << "Couldn't open the file 'content.xml'." << endl;
00145     return KoFilter::CreationError;
00146   }
00147   storeout->write( d->createContent() );
00148   storeout->close();
00149 
00150   // store document manifest
00151   storeout->enterDirectory( "META-INF" );
00152   if ( !storeout->open( "manifest.xml" ) )
00153   {
00154      kdWarning() << "Couldn't open the file 'META-INF/manifest.xml'." << endl;
00155      return KoFilter::CreationError;
00156   }
00157   storeout->write( d->createManifest() );
00158   storeout->close();
00159 
00160   // we are done!
00161   d->inputFile = QString::null;
00162   d->outputFile = QString::null;
00163   delete storeout;
00164 
00165   return KoFilter::OK;
00166 }
00167 
00168 QByteArray HancomWordImport::Private::createContent()
00169 {
00170   KoXmlWriter* contentWriter;
00171   QByteArray contentData;
00172   QBuffer contentBuffer( contentData );
00173 
00174   contentBuffer.open( IO_WriteOnly );
00175   contentWriter = new KoXmlWriter( &contentBuffer );
00176 
00177   contentWriter->startDocument( "office:document-content" );
00178   contentWriter->startElement( "office:document-content" );
00179   
00180   contentWriter->addAttribute( "xmlns:office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0" );
00181   contentWriter->addAttribute( "xmlns:style", "urn:oasis:names:tc:opendocument:xmlns:style:1.0" );
00182   contentWriter->addAttribute( "xmlns:text", "urn:oasis:names:tc:opendocument:xmlns:text:1.0" );
00183   contentWriter->addAttribute( "xmlns:table", "urn:oasis:names:tc:opendocument:xmlns:table:1.0" );
00184   contentWriter->addAttribute( "xmlns:draw", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" );
00185   contentWriter->addAttribute( "xmlns:fo", "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" );
00186   contentWriter->addAttribute( "xmlns:svg","urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" );
00187   contentWriter->addAttribute( "office:version","1.0" );
00188 
00189   contentWriter->startElement( "office:automatic-styles" );
00190   contentWriter->endElement(); // office:automatic-style
00191 
00192   // office:body
00193   contentWriter->startElement( "office:body" );
00194   
00195   contentWriter->startElement( "office:text" );
00196   
00197   contentWriter->startElement( "text:sequence-decls" );
00198   contentWriter->endElement();  // text:sequence-decls
00199 
00200   for( uint i = 0; i < paragraphs.count(); i++ )
00201   {
00202     QString text = paragraphs[i];
00203     text.replace( '\r', ' ' );
00204     contentWriter->startElement( "text:p" );
00205     contentWriter->addTextNode( text );
00206     contentWriter->endElement();  // text:p
00207   }
00208   
00209   contentWriter->endElement();  //office:text
00210   contentWriter->endElement();  // office:body
00211   
00212   contentWriter->endElement();  // office:document-content
00213   contentWriter->endDocument();
00214   
00215   delete contentWriter;
00216 
00217   return contentData;
00218 }
00219 
00220 QByteArray HancomWordImport::Private::createStyles()
00221 {
00222   KoXmlWriter* stylesWriter;
00223   QByteArray stylesData;
00224   QBuffer stylesBuffer( stylesData );
00225 
00226   stylesBuffer.open( IO_WriteOnly );
00227   stylesWriter = new KoXmlWriter( &stylesBuffer );
00228 
00229   stylesWriter->startDocument( "office:document-styles" );
00230   stylesWriter->startElement( "office:document-styles" );
00231   stylesWriter->addAttribute( "xmlns:office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0" );
00232   stylesWriter->addAttribute( "xmlns:style", "urn:oasis:names:tc:opendocument:xmlns:style:1.0" );
00233   stylesWriter->addAttribute( "xmlns:text", "urn:oasis:names:tc:opendocument:xmlns:text:1.0" );
00234   stylesWriter->addAttribute( "xmlns:table", "urn:oasis:names:tc:opendocument:xmlns:table:1.0" );
00235   stylesWriter->addAttribute( "xmlns:draw", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" );
00236   stylesWriter->addAttribute( "xmlns:fo", "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" );
00237   stylesWriter->addAttribute( "xmlns:svg","urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" );
00238   stylesWriter->addAttribute( "office:version","1.0" );
00239   stylesWriter->startElement( "office:styles" );
00240   
00241   // dummy default paragraph style
00242   stylesWriter->startElement( "style:default-style" );
00243   stylesWriter->addAttribute( "style:family", "paragraph" );
00244   
00245   stylesWriter->startElement( "style:paragraph-properties" );
00246   stylesWriter->addAttribute( "fo:hyphenation-ladder-count", "no-limit" );
00247   stylesWriter->addAttribute( "style:text-autospace", "ideograph-alpha" );
00248   stylesWriter->addAttribute( "style:punctuation-wrap", "hanging" );
00249   stylesWriter->addAttribute( "style:line-break", "strict" );
00250   stylesWriter->addAttribute( "tyle:tab-stop-distance", "0.5in" );
00251   stylesWriter->addAttribute( "style:writing-mode", "page" );
00252   stylesWriter->endElement(); // style:paragraph-properties
00253 
00254   stylesWriter->startElement( "style:text-properties" );
00255   stylesWriter->addAttribute( "style:use-window-font-color", "true" );
00256   stylesWriter->addAttribute( "style:font-name", "Sans Serif" );
00257   stylesWriter->addAttribute( "fo:font-size", "12pt" );
00258   stylesWriter->addAttribute( "fo:hyphenate", "false" );
00259   stylesWriter->endElement(); // style:text-properties
00260   
00261   stylesWriter->endElement(); // style:default-style
00262   stylesWriter->endElement(); // office:styles
00263   
00264   // office:automatic-styles
00265   stylesWriter->startElement( "office:automatic-styles" );
00266   stylesWriter->endElement(); // office:automatic-styles
00267 
00268   stylesWriter->endElement();  // office:document-styles
00269   stylesWriter->endDocument();
00270   
00271   delete stylesWriter;
00272 
00273   return stylesData;
00274 }
00275 
00276 QByteArray HancomWordImport::Private::createManifest()
00277 {
00278   KoXmlWriter* manifestWriter;
00279   QByteArray manifestData;
00280   QBuffer manifestBuffer( manifestData );
00281 
00282   manifestBuffer.open( IO_WriteOnly );
00283   manifestWriter = new KoXmlWriter( &manifestBuffer );
00284   
00285   manifestWriter->startDocument( "manifest:manifest" );
00286   manifestWriter->startElement( "manifest:manifest" );
00287   manifestWriter->addAttribute( "xmlns:manifest", "urn:oasis:names:tc:openoffice:xmlns:manifest:1.0" );
00288   manifestWriter->addManifestEntry( "/", "application/vnd.oasis.opendocument.text" );
00289   manifestWriter->addManifestEntry( "styles.xml", "text/xml" );
00290   manifestWriter->addManifestEntry( "content.xml", "text/xml" );
00291   manifestWriter->endElement();
00292   manifestWriter->endDocument();
00293   delete manifestWriter;
00294 
00295   return manifestData;
00296 }
KDE Home | KDE Accessibility Home | Description of Access Keys