|
|
|
/* This file is part of the KDE project
|
|
|
|
Copyright (C) 2002,2006 Ariya Hidayat <ariya@kde.org>
|
|
|
|
|
|
|
|
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 <config.h>
|
|
|
|
|
|
|
|
#ifdef HAVE_UNISTD_H
|
|
|
|
#include <unistd.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <hancomwordimport.h>
|
|
|
|
#include <hancomwordimport.moc>
|
|
|
|
|
|
|
|
#include <tqbuffer.h>
|
|
|
|
#include <tqcstring.h>
|
|
|
|
#include <tqfile.h>
|
|
|
|
#include <tqstring.h>
|
|
|
|
#include <tqstringlist.h>
|
|
|
|
#include <textstream.h>
|
|
|
|
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <KoFilterChain.h>
|
|
|
|
#include <KoGlobal.h>
|
|
|
|
#include <KoUnit.h>
|
|
|
|
#include <kgenericfactory.h>
|
|
|
|
|
|
|
|
#include <KoXmlWriter.h>
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
#include "pole.h"
|
|
|
|
|
|
|
|
typedef KGenericFactory<HancomWordImport, KoFilter> 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::ConversionStatus 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.replace( '\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;
|
|
|
|
}
|