filters
amiproimport.cc00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #ifdef HAVE_UNISTD_H
00023 #include <unistd.h>
00024 #endif
00025
00026 #include <qregexp.h>
00027 #include <qfileinfo.h>
00028 #include <qvaluelist.h>
00029 #include <qfont.h>
00030
00031 #include <kdebug.h>
00032 #include <KoFilterChain.h>
00033 #include <kgenericfactory.h>
00034 #include <KoGlobal.h>
00035
00036 #include <amiproimport.h>
00037 #include <amiproparser.h>
00038
00039 typedef KGenericFactory<AmiProImport, KoFilter> AmiProImportFactory;
00040 K_EXPORT_COMPONENT_FACTORY( libamiproimport, AmiProImportFactory( "kofficefilters" ) )
00041
00042 AmiProImport::AmiProImport( KoFilter *, const char *, const QStringList& ):
00043 KoFilter()
00044 {
00045 }
00046
00047 class AmiProConverter: public AmiProListener
00048 {
00049 public:
00050 AmiProConverter();
00051 QString root, documentInfo;
00052 virtual bool doOpenDocument();
00053 virtual bool doCloseDocument();
00054 virtual bool doDefineStyle( const AmiProStyle& style );
00055 virtual bool doParagraph( const QString& text, AmiProFormatList formatList,
00056 AmiProLayout& l );
00057 private:
00058 AmiProStyleList styleList;
00059 };
00060
00061
00062 static QString XMLEscape( const QString& str )
00063 {
00064 QString result;
00065
00066 for( unsigned i=0; i<str.length(); i++ )
00067 if( str[i] == '&' ) result += "&";
00068 else if( str[i] == '<' ) result += "<";
00069 else if( str[i] == '>' ) result += ">";
00070 else if( str[i] == '"' ) result += """;
00071 else if( str[i] == QChar(39) ) result += "'";
00072 else result += str[i];
00073
00074 return result;
00075 }
00076
00077
00078 static QString AmiProFormatAsXML( AmiProFormat format )
00079 {
00080 QString result;
00081
00082 QString fontname = format.fontFamily;
00083 if( fontname.isEmpty() ) fontname = KoGlobal::defaultFont().family();
00084 QString fontsize = QString::number( format.fontSize );
00085 QString boldness = format.bold ? "75" : "50";
00086 QString italic = format.italic ? "1" : "0";
00087 QString strikeout = format.strikethrough ? "1" : "0";
00088 QString vertalign = format.superscript ? "2" : format.subscript ? "1" : "0";
00089 QString underline = format.double_underline ? "double" :
00090 format.underline|format.word_underline ? "1" : "0";
00091
00092 result = "<FORMAT id=\"1\" pos=\"" + QString::number(format.pos) +
00093 "\" len=\"" + QString::number(format.len) + "\">\n";
00094 result.append( " <FONT name=\"" + fontname + "\" />\n" );
00095 result.append( " <SIZE value=\"" + fontsize + "\" />\n" );
00096 result.append( " <WEIGHT value=\"" + boldness + "\" />\n" );
00097 result.append( " <ITALIC value=\"" + italic + "\" />\n" );
00098 result.append( " <STRIKEOUT value=\"" + strikeout + "\" />\n" );
00099 result.append( " <VERTALIGN value=\"" + vertalign + "\" />\n" );
00100 result.append( " <UNDERLINE value=\"" + underline + "\" />\n" );
00101 result.append( "</FORMAT>\n" );
00102
00103 return result;
00104 }
00105
00106
00107 static QString AmiProFormatListAsXML( AmiProFormatList& formatList )
00108 {
00109 QString result;
00110
00111 AmiProFormatList::iterator it;
00112 for( it=formatList.begin(); it!=formatList.end(); ++it )
00113 {
00114 AmiProFormat& format = *it;
00115 result.append( AmiProFormatAsXML(format) );
00116 }
00117
00118 if( !result.isEmpty() )
00119 {
00120 result.prepend( "<FORMATS>\n" );
00121 result.append( "</FORMATS>\n" );
00122 }
00123
00124 return result;
00125 }
00126
00127
00128 static QString AmiProLayoutAsXML( const AmiProLayout& layout )
00129 {
00130 QString result;
00131
00132 QString referredStyle = layout.name;
00133 if( referredStyle.isEmpty() ) referredStyle = "Standard";
00134
00135 QString fontname = layout.fontFamily;
00136 if( fontname.isEmpty() ) fontname = KoGlobal::defaultFont().family();
00137 QString fontsize = QString::number( layout.fontSize );
00138 QString fontcolor = "red=\"" + QString::number( layout.fontColor.red() ) +
00139 "\" green=\"" + QString::number( layout.fontColor.green() ) +
00140 "\" blue=\"" + QString::number( layout.fontColor.blue() ) + "\"";
00141 QString boldness = layout.bold ? "75" : "50";
00142 QString italic = layout.italic ? "1" : "0";
00143 QString strikeout = layout.strikethrough ? "1" : "0";
00144 QString vertalign = layout.superscript ? "2" : layout.subscript ? "1" : "0";
00145 QString underline = layout.double_underline ? "double" :
00146 layout.underline|layout.word_underline ? "1" : "0";
00147
00148 QString align;
00149 align = layout.align==Qt::AlignLeft ? "left" :
00150 layout.align==Qt::AlignRight ? "right" :
00151 layout.align==Qt::AlignCenter ? "center" :
00152 layout.align==Qt::AlignJustify ? "justify" :
00153 "left";
00154
00155 QString offsets;
00156 offsets = "before=\"" + QString::number(layout.spaceBefore) +
00157 "\" after=\"" + QString::number(layout.spaceAfter) + "\"";
00158
00159 QString linespacing;
00160 linespacing = layout.linespace==AmiPro::LS_Single ? QString::fromLatin1( "0" ) :
00161 layout.linespace==AmiPro::LS_OneAndHalf ? QString::fromLatin1( "oneandhalf" ) :
00162 layout.linespace==AmiPro::LS_Double ? QString::fromLatin1( "double" ) :
00163 QString::number( layout.linespace );
00164
00165 result.append( "<LAYOUT>\n" );
00166 result.append( " <NAME value=\"" + XMLEscape( referredStyle ) + "\" />\n" );
00167 result.append( " <FLOW align=\"" + align + "\" />\n" );
00168 result.append( " <LINESPACING value=\"" + linespacing + "\" />\n" );
00169 result.append( " <OFFSETS " + offsets + " />\n" );
00170 result.append( " <LEFTBORDER width=\"0\" style=\"0\" />\n" );
00171 result.append( " <RIGHTBORDER width=\"0\" style=\"0\" />\n" );
00172 result.append( " <TOPBORDER width=\"0\" style=\"0\" />\n" );
00173 result.append( " <BOTTOMBORDER width=\"0\" style=\"0\" />\n" );
00174 result.append( " <INDENTS />\n" );
00175 result.append( " <OFFSETS />\n" );
00176 result.append( " <PAGEBREAKING />\n" );
00177 result.append( " <COUNTER />\n" );
00178 result.append( " <FORMAT id=\"1\">\n" );
00179 result.append( " <FONT name=\"" + fontname + "\" />\n" );
00180 result.append( " <SIZE value=\"" + fontsize + "\" />\n" );
00181 result.append( " <COLOR " + fontcolor + " />\n" );
00182 result.append( " <WEIGHT value=\"" + boldness + "\" />\n" );
00183 result.append( " <ITALIC value=\"" + italic + "\" />\n" );
00184 result.append( " <STRIKEOUT value=\"" + strikeout + "\" />\n" );
00185 result.append( " <VERTALIGN value=\"" + vertalign + "\" />\n" );
00186 result.append( " <UNDERLINE value=\"" + underline + "\" />\n" );
00187 result.append( " </FORMAT>\n" );
00188 result.append( "</LAYOUT>\n" );
00189
00190 return result;
00191 }
00192
00193
00194 static QString AmiProStyleAsXML( const AmiProStyle& style )
00195 {
00196 QString result;
00197
00198 QString fontname = style.fontFamily;
00199 if( fontname.isEmpty() ) fontname = KoGlobal::defaultFont().family();
00200 QString fontsize = QString::number( style.fontSize );
00201 QString boldness = style.bold ? "75" : "50";
00202 QString italic = style.italic ? "1" : "0";
00203 QString strikeout = style.strikethrough ? "1" : "0";
00204 QString vertalign = style.superscript ? "2" : style.subscript ? "1" : "0";
00205 QString underline = style.double_underline ? "double" :
00206 style.underline|style.word_underline ? "1" : "0";
00207
00208 QString align;
00209 align = style.align==Qt::AlignLeft ? "left" :
00210 style.align==Qt::AlignRight ? "right" :
00211 style.align==Qt::AlignCenter ? "center" :
00212 style.align==Qt::AlignJustify ? "justify" :
00213 "left";
00214
00215 QString linespacing;
00216 linespacing = style.linespace==AmiPro::LS_Single ? QString::fromLatin1( "0" ) :
00217 style.linespace==AmiPro::LS_OneAndHalf ? QString::fromLatin1( "oneandhalf" ) :
00218 style.linespace==AmiPro::LS_Double ? QString::fromLatin1( "double" ) :
00219 QString::number( style.linespace );
00220
00221 QString offsets;
00222 offsets = "before=\"" + QString::number(style.spaceBefore) +
00223 "\" after=\"" + QString::number(style.spaceAfter) + "\"";
00224
00225 result.append( "<STYLE>\n" );
00226 result.append( " <NAME value=\"" + XMLEscape( style.name ) + "\" />\n" );
00227 result.append( " <FOLLOWING name=\"Body Text\" />\n" );
00228 result.append( " <FLOW align=\"" + align + "\" />\n" );
00229 result.append( " <LINESPACING value=\"" + linespacing + "\" />\n" );
00230 result.append( " <OFFSETS " + offsets + " />\n" );
00231 result.append( " <LEFTBORDER width=\"0\" style=\"0\" />\n" );
00232 result.append( " <RIGHTBORDER width=\"0\" style=\"0\" />\n" );
00233 result.append( " <TOPBORDER width=\"0\" style=\"0\" />\n" );
00234 result.append( " <BOTTOMBORDER width=\"0\" style=\"0\" />\n" );
00235 result.append( " <FORMAT id=\"1\">\n" );
00236 result.append( " <FONT name=\"" + fontname + "\" />\n" );
00237 result.append( " <SIZE value=\"" + fontsize + "\" />\n" );
00238 result.append( " <WEIGHT value=\"" + boldness + "\" />\n" );
00239 result.append( " <ITALIC value=\"" + italic + "\" />\n" );
00240 result.append( " <STRIKEOUT value=\"" + strikeout + "\" />\n" );
00241 result.append( " <VERTALIGN value=\"" + vertalign + "\" />\n" );
00242 result.append( " <UNDERLINE value=\"" + underline + "\" />\n" );
00243 result.append( " </FORMAT>\n" );
00244 result.append( "</STYLE>\n" );
00245
00246 return result;
00247 }
00248
00249
00250 static QString AmiProStyleListAsXML( AmiProStyleList& styleList )
00251 {
00252 QString result;
00253
00254 AmiProStyleList::iterator it;
00255 for( it=styleList.begin(); it!=styleList.end(); ++it )
00256 {
00257 AmiProStyle& style = *it;
00258 result.append( AmiProStyleAsXML( style ) );
00259 }
00260
00261 if( !result.isEmpty() )
00262 {
00263 result.prepend ( "<STYLES>\n" );
00264 result.append( "</STYLES>\n" );
00265 }
00266
00267 return result;
00268 }
00269
00270 AmiProConverter::AmiProConverter()
00271 {
00272 root = "";
00273 }
00274
00275 bool AmiProConverter::doOpenDocument()
00276 {
00277 QString prolog = "<!DOCTYPE DOC>\n";
00278
00279 prolog.append( "<DOC mime=\"application/x-kword\" syntaxVersion=\"2\" editor=\"KWord\">\n");
00280 prolog.append( "<PAPER width=\"595\" height=\"841\" format=\"1\" fType=\"0\" orientation=\"0\" hType=\"0\" columns=\"1\">\n" );
00281 prolog.append( " <PAPERBORDERS left=\"36\" right=\"36\" top=\"36\" bottom=\"36\" />\n" );
00282 prolog.append( "</PAPER>\n" );
00283 prolog.append( "<ATTRIBUTES standardpage=\"1\" hasFooter=\"0\" hasHeader=\"0\" processing=\"0\" />\n" );
00284 prolog.append( "<FRAMESETS>\n" );
00285 prolog.append( "<FRAMESET removable=\"0\" frameType=\"1\" frameInfo=\"0\" autoCreateNewFrame=\"1\">\n" );
00286 prolog.append( "<FRAME right=\"567\" left=\"28\" top=\"42\" bottom=\"799\" />\n" );
00287 root = prolog;
00288
00289 return true;
00290 }
00291
00292 bool AmiProConverter::doCloseDocument()
00293 {
00294 QString epilog = "</FRAMESET>\n";
00295 epilog.append( "</FRAMESETS>\n" );
00296 epilog.append( AmiProStyleListAsXML( styleList ) );
00297 epilog.append( "</DOC>\n" );
00298
00299 root.append( epilog );
00300
00301 return true;
00302 }
00303
00304 bool AmiProConverter::doDefineStyle( const AmiProStyle& style )
00305 {
00306 styleList.append( style );
00307 return true;
00308 }
00309
00310 bool AmiProConverter::doParagraph( const QString& text, AmiProFormatList formatList,
00311 AmiProLayout& layout )
00312 {
00313 root.append( "<PARAGRAPH>\n" );
00314 root.append( "<TEXT>" + XMLEscape( text ) + "</TEXT>\n" );
00315 root.append( AmiProFormatListAsXML( formatList ) );
00316 root.append( AmiProLayoutAsXML( layout ) );
00317 root.append( "</PARAGRAPH>\n" );
00318
00319 return true;
00320 }
00321
00322 KoFilter::ConversionStatus AmiProImport::convert( const QCString& from, const QCString& to )
00323 {
00324
00325 if( to!= "application/x-kword" || from != "application/x-amipro" )
00326 return KoFilter::NotImplemented;
00327
00328
00329 AmiProParser *parser = new AmiProParser;
00330 AmiProConverter *converter = new AmiProConverter;
00331 parser->setListener( converter );
00332
00333 parser->process( m_chain->inputFile() );
00334
00335 if( converter->root.isEmpty() )
00336 return KoFilter::StupidError;
00337
00338 QString root = converter->root;
00339 QString documentInfo = converter->documentInfo;
00340
00341 delete converter;
00342 delete parser;
00343
00344
00345 KoStoreDevice* out=m_chain->storageFile( "root", KoStore::Write );
00346
00347
00348 if( out )
00349 {
00350 QCString cstring = root.utf8();
00351 cstring.prepend( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
00352 out->writeBlock( (const char*) cstring, cstring.length() );
00353 }
00354
00355
00356 out = m_chain->storageFile( "documentinfo.xml", KoStore::Write );
00357 if ( out )
00358 {
00359 QCString cstring = documentInfo.utf8();
00360 cstring.prepend( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
00361
00362 out->writeBlock( (const char*) cstring, cstring.length() );
00363 }
00364
00365 return KoFilter::OK;
00366 }
00367
00368 #include "amiproimport.moc"
|