00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <qmap.h>
00034 #include <qiodevice.h>
00035 #include <qtextstream.h>
00036 #include <qdom.h>
00037
00038 #include <kdebug.h>
00039 #include <kmdcodec.h>
00040 #include <kfilterdev.h>
00041 #include <kgenericfactory.h>
00042 #include <kimageio.h>
00043
00044 #include <KoPageLayout.h>
00045 #include <KoFilterChain.h>
00046 #include <KoPictureKey.h>
00047
00048 #include <KWEFStructures.h>
00049 #include <KWEFUtil.h>
00050 #include <KWEFBaseWorker.h>
00051 #include <KWEFKWordLeader.h>
00052
00053 #include <abiwordexport.h>
00054 #include <abiwordexport.moc>
00055
00056 class ABIWORDExportFactory : KGenericFactory<ABIWORDExport, KoFilter>
00057 {
00058 public:
00059 ABIWORDExportFactory(void) : KGenericFactory<ABIWORDExport, KoFilter> ("kwordabiwordexport")
00060 {}
00061 protected:
00062 virtual void setupTranslations( void )
00063 {
00064 KGlobal::locale()->insertCatalogue( "kofficefilters" );
00065 }
00066 };
00067
00068 K_EXPORT_COMPONENT_FACTORY( libabiwordexport, ABIWORDExportFactory() )
00069
00070 class StyleMap : public QMap<QString,LayoutData>
00071 {
00072 public:
00073 StyleMap(void) {}
00074 ~StyleMap(void) {}
00075 };
00076
00077 class AbiWordWorker : public KWEFBaseWorker
00078 {
00079 public:
00080 AbiWordWorker(void);
00081 virtual ~AbiWordWorker(void) { delete m_streamOut; delete m_ioDevice; }
00082 public:
00083 virtual bool doOpenFile(const QString& filenameOut, const QString& to);
00084 virtual bool doCloseFile(void);
00085 virtual bool doOpenDocument(void);
00086 virtual bool doCloseDocument(void);
00087 virtual bool doFullParagraph(const QString& paraText, const LayoutData& layout,
00088 const ValueListFormatData& paraFormatDataList);
00089 virtual bool doOpenTextFrameSet(void);
00090 virtual bool doCloseTextFrameSet(void);
00091 virtual bool doFullPaperFormat(const int format,
00092 const double width, const double height, const int orientation);
00093 virtual bool doFullPaperBorders (const double top, const double left,
00094 const double bottom, const double right);
00095 virtual bool doCloseHead(void);
00096 virtual bool doOpenStyles(void);
00097 virtual bool doCloseStyles(void);
00098 virtual bool doFullDefineStyle(LayoutData& layout);
00099 virtual bool doOpenSpellCheckIgnoreList (void);
00100 virtual bool doCloseSpellCheckIgnoreList (void);
00101 virtual bool doFullSpellCheckIgnoreWord (const QString& ignoreword);
00102 virtual bool doFullDocumentInfo(const KWEFDocumentInfo& docInfo);
00103 private:
00104 void processParagraphData (const QString& paraText,
00105 const TextFormatting& formatLayout,
00106 const ValueListFormatData& paraFormatDataList);
00107 void processNormalText ( const QString& paraText,
00108 const TextFormatting& formatLayout,
00109 const FormatData& formatData);
00110 void processVariable ( const QString& paraText,
00111 const TextFormatting& formatLayout,
00112 const FormatData& formatData);
00113 void processAnchor ( const QString& paraText,
00114 const TextFormatting& formatLayout,
00115 const FormatData& formatData);
00116 QString textFormatToAbiProps(const TextFormatting& formatOrigin,
00117 const TextFormatting& formatData, const bool force) const;
00118 QString layoutToCss(const LayoutData& layoutOrigin,
00119 const LayoutData& layout, const bool force) const;
00120 QString escapeAbiWordText(const QString& strText) const;
00121 bool makeTable(const FrameAnchor& anchor);
00122 bool makePicture(const FrameAnchor& anchor);
00123 void writeAbiProps(const TextFormatting& formatLayout, const TextFormatting& format);
00124 void writePictureData(const QString& koStoreName, const QString& keyName);
00125 QString transformToTextDate(const QDateTime& dt);
00126 private:
00127 QIODevice* m_ioDevice;
00128 QTextStream* m_streamOut;
00129 QString m_pagesize;
00130 QMap<QString,KoPictureKey> m_mapPictureData;
00131 StyleMap m_styleMap;
00132 double m_paperBorderTop,m_paperBorderLeft,m_paperBorderBottom,m_paperBorderRight;
00133 bool m_inIgnoreWords;
00134 KWEFDocumentInfo m_docInfo;
00135 };
00136
00137 AbiWordWorker::AbiWordWorker(void) : m_ioDevice(NULL), m_streamOut(NULL),
00138 m_paperBorderTop(0.0),m_paperBorderLeft(0.0),
00139 m_paperBorderBottom(0.0),m_paperBorderRight(0.0)
00140 {
00141 }
00142
00143 QString AbiWordWorker::escapeAbiWordText(const QString& strText) const
00144 {
00145
00146
00147 return KWEFUtil::EscapeSgmlText(NULL,strText,true,true);
00148 }
00149
00150 bool AbiWordWorker::doOpenFile(const QString& filenameOut, const QString& )
00151 {
00152 kdDebug(30506) << "Opening file: " << filenameOut
00153 << " (in AbiWordWorker::doOpenFile)" << endl;
00154
00155 QString strExt;
00156 const int result=filenameOut.findRev('.');
00157 if (result>=0)
00158 {
00159 strExt=filenameOut.mid(result);
00160 }
00161
00162 QString strMimeType;
00163
00164 if ((strExt==".gz")||(strExt==".GZ")
00165 ||(strExt==".zabw")||(strExt==".ZABW"))
00166 {
00167
00168 strMimeType="application/x-gzip";
00169 }
00170 else if ((strExt==".bz2")||(strExt==".BZ2")
00171 ||(strExt==".bzabw")||(strExt==".BZABW"))
00172 {
00173
00174 strMimeType="application/x-bzip2";
00175 }
00176 else
00177 {
00178
00179 strMimeType="text/plain";
00180 }
00181
00182 kdDebug(30506) << "Compression: " << strMimeType << endl;
00183
00184 m_ioDevice = KFilterDev::deviceForFile(filenameOut,strMimeType);
00185
00186 if (!m_ioDevice)
00187 {
00188 kdError(30506) << "No output file! Aborting!" << endl;
00189 return false;
00190 }
00191
00192 if ( !m_ioDevice->open (IO_WriteOnly) )
00193 {
00194 kdError(30506) << "Unable to open output file! Aborting!" << endl;
00195 return false;
00196 }
00197
00198 m_streamOut=new QTextStream(m_ioDevice);
00199
00200
00201 m_streamOut->setEncoding( QTextStream::UnicodeUTF8 );
00202 return true;
00203 }
00204
00205 bool AbiWordWorker::doCloseFile(void)
00206 {
00207 delete m_streamOut;
00208 m_streamOut=NULL;
00209 if (m_ioDevice)
00210 m_ioDevice->close();
00211 return (m_ioDevice);
00212 }
00213
00214 bool AbiWordWorker::doOpenDocument(void)
00215 {
00216 kdDebug(30506)<< "AbiWordWorker::doOpenDocument" << endl;
00217
00218
00219
00220
00221 *m_streamOut << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
00222
00223
00224 *m_streamOut << "<!DOCTYPE abiword PUBLIC \"-//ABISOURCE//DTD AWML 1.0 Strict//EN\"";
00225 *m_streamOut << " \"http://www.abisource.com/awml.dtd\">\n";
00226
00227
00228 *m_streamOut << "<abiword";
00229
00230 *m_streamOut << " xmlns=\"http://www.abisource.com/awml.dtd\"";
00231
00232
00233 *m_streamOut << " xmlns:xlink=\"http://www.w3.org/1999/xlink\"";
00234
00235
00236
00237 *m_streamOut << " xml:space=\"preserve\" version=\"1.1.2\" template=\"false\" styles=\"unlocked\">\n";
00238
00239
00240 *m_streamOut << "<!-- This file is an AbiWord document. -->\n";
00241
00242
00243 *m_streamOut << "\n";
00244
00245
00246 return true;
00247 }
00248
00249 void AbiWordWorker::writePictureData(const QString& koStoreName, const QString& keyName)
00250 {
00251 kdDebug(30506) << "AbiWordWorker::writeImageData" << endl;
00252
00253 QByteArray image;
00254
00255 QString strExtension(koStoreName.lower());
00256 const int result=koStoreName.findRev(".");
00257 if (result>=0)
00258 {
00259 strExtension=koStoreName.mid(result+1);
00260 }
00261
00262 bool isImageLoaded=false;
00263
00264 if (strExtension=="png")
00265 {
00266 isImageLoaded=loadSubFile(koStoreName,image);
00267 }
00268 else
00269 {
00270
00271
00272 isImageLoaded=loadAndConvertToImage(koStoreName,strExtension,"PNG",image);
00273 }
00274
00275 if (isImageLoaded)
00276 {
00277 *m_streamOut << "<d name=\"" << keyName << "\""
00278 << " base64=\"yes\""
00279 << " mime=\"image/png\">\n";
00280
00281 QCString base64=KCodecs::base64Encode(image,true);
00282
00283 *m_streamOut << base64 << "\n";
00284
00285 *m_streamOut << "</d>\n";
00286 }
00287 else
00288 {
00289 kdWarning(30506) << "Unable to load picture: " << koStoreName << endl;
00290 }
00291 }
00292
00293 bool AbiWordWorker::doCloseDocument(void)
00294 {
00295
00296
00297
00298 if (m_kwordLeader && !m_mapPictureData.isEmpty())
00299 {
00300 *m_streamOut << "<data>\n";
00301
00302 QMap<QString,KoPictureKey>::ConstIterator it;
00303 QMap<QString,KoPictureKey>::ConstIterator end(m_mapPictureData.end());
00304
00305 for (it=m_mapPictureData.begin(); it!=end; ++it)
00306 {
00307
00308 writePictureData(it.key(),it.data().filename());
00309 }
00310
00311 *m_streamOut << "</data>\n";
00312 }
00313
00314 *m_streamOut << "</abiword>\n";
00315 return true;
00316 }
00317
00318 bool AbiWordWorker::doOpenTextFrameSet(void)
00319 {
00320 *m_streamOut << "<section props=\"";
00321 *m_streamOut << "page-margin-top: ";
00322 *m_streamOut << m_paperBorderTop;
00323 *m_streamOut << "pt; ";
00324 *m_streamOut << "page-margin-left: ";
00325 *m_streamOut << m_paperBorderLeft;
00326 *m_streamOut << "pt; ";
00327 *m_streamOut << "page-margin-bottom: ";
00328 *m_streamOut << m_paperBorderBottom;
00329 *m_streamOut << "pt; ";
00330 *m_streamOut << "page-margin-right: ";
00331 *m_streamOut << m_paperBorderRight;
00332 *m_streamOut << "pt";
00333 *m_streamOut << "\">\n";
00334 return true;
00335 }
00336
00337 bool AbiWordWorker::doCloseTextFrameSet(void)
00338 {
00339 *m_streamOut << "</section>\n";
00340 return true;
00341 }
00342
00343 bool AbiWordWorker::doOpenStyles(void)
00344 {
00345 *m_streamOut << "<styles>\n";
00346 return true;
00347 }
00348
00349 bool AbiWordWorker::doCloseStyles(void)
00350 {
00351 *m_streamOut << "</styles>\n";
00352 return true;
00353 }
00354
00355 QString AbiWordWorker::textFormatToAbiProps(const TextFormatting& formatOrigin,
00356 const TextFormatting& formatData, const bool force) const
00357 {
00358
00359 QString strElement;
00360
00361
00362 QString fontName = formatData.fontName;
00363 if ( !fontName.isEmpty()
00364 && (force || (formatOrigin.fontName!=formatData.fontName)))
00365 {
00366 strElement+="font-family: ";
00367 strElement+= escapeAbiWordText(fontName);
00368 strElement+="; ";
00369 }
00370
00371 if (force || (formatOrigin.italic!=formatData.italic))
00372 {
00373
00374 strElement+="font-style: ";
00375 if ( formatData.italic )
00376 {
00377 strElement+="italic";
00378 }
00379 else
00380 {
00381 strElement+="normal";
00382 }
00383 strElement+="; ";
00384 }
00385
00386 if (force || ((formatOrigin.weight>=75)!=(formatData.weight>=75)))
00387 {
00388 strElement+="font-weight: ";
00389 if ( formatData.weight >= 75 )
00390 {
00391 strElement+="bold";
00392 }
00393 else
00394 {
00395 strElement+="normal";
00396 }
00397 strElement+="; ";
00398 }
00399
00400 if (force || (formatOrigin.fontSize!=formatData.fontSize))
00401 {
00402 const int size=formatData.fontSize;
00403 if (size>0)
00404 {
00405
00406 strElement+="font-size: ";
00407 strElement+=QString::number(size,10);
00408 strElement+="pt; ";
00409 }
00410 }
00411
00412 if (force || (formatOrigin.fgColor!=formatData.fgColor))
00413 {
00414 if ( formatData.fgColor.isValid() )
00415 {
00416
00417 strElement+="color: ";
00418
00419
00420
00421 const int red=formatData.fgColor.red();
00422 strElement += QString::number((red&0xf0)>>4,16);
00423 strElement += QString::number(red&0x0f,16);
00424
00425 const int green=formatData.fgColor.green();
00426 strElement += QString::number((green&0xf0)>>4,16);
00427 strElement += QString::number(green&0x0f,16);
00428
00429 const int blue=formatData.fgColor.blue();
00430 strElement += QString::number((blue&0xf0)>>4,16);
00431 strElement += QString::number(blue&0x0f,16);
00432
00433 strElement+="; ";
00434 }
00435 }
00436
00437 if (force || (formatOrigin.bgColor!=formatData.bgColor))
00438 {
00439 if ( formatData.bgColor.isValid() )
00440 {
00441
00442 strElement+="bgcolor: ";
00443
00444
00445
00446 const int red=formatData.bgColor.red();
00447 strElement += QString::number((red&0xf0)>>4,16);
00448 strElement += QString::number(red&0x0f,16);
00449
00450 const int green=formatData.bgColor.green();
00451 strElement += QString::number((green&0xf0)>>4,16);
00452 strElement += QString::number(green&0x0f,16);
00453
00454 const int blue=formatData.bgColor.blue();
00455 strElement += QString::number((blue&0xf0)>>4,16);
00456 strElement += QString::number(blue&0x0f,16);
00457
00458 strElement+="; ";
00459 }
00460 }
00461
00462 if (force || (formatOrigin.underline!=formatData.underline)
00463 || (formatOrigin.strikeout!=formatData.strikeout))
00464 {
00465 strElement+="text-decoration: ";
00466 if ( formatData.underline )
00467 {
00468 strElement+="underline";
00469 }
00470 else if ( formatData.strikeout )
00471 {
00472 strElement+="line-through";
00473 }
00474 else
00475 {
00476 strElement+="none";
00477 }
00478 strElement+="; ";
00479 }
00480
00481 return strElement;
00482 }
00483
00484 bool AbiWordWorker::makeTable(const FrameAnchor& anchor)
00485 {
00486 #if 0
00487 *m_streamOut << "</p>\n";
00488 *m_streamOut << "<table>\n";
00489 #endif
00490
00491 QValueList<TableCell>::ConstIterator itCell;
00492 for (itCell=anchor.table.cellList.begin();
00493 itCell!=anchor.table.cellList.end(); itCell++)
00494 {
00495 #if 0
00496
00497
00498
00499 *m_streamOut << "<cell props=\"";
00500 *m_streamOut << "left-attach:" << (*itCell).col << "; ";
00501 *m_streamOut << "right-attach:" << (*itCell).col + 1 << "; ";
00502 *m_streamOut << "top-attach:" << (*itCell).row << "; ";
00503 *m_streamOut << "bot-attach:" << (*itCell).row + 1;
00504 *m_streamOut << "\">\n";
00505 #endif
00506 if (!doFullAllParagraphs(*(*itCell).paraList))
00507 {
00508 return false;
00509 }
00510 #if 0
00511 *m_streamOut << "</cell>\n";
00512 #endif
00513 }
00514 #if 0
00515 *m_streamOut << "</table>\n";
00516 *m_streamOut << "<p>\n";
00517 #endif
00518 return true;
00519 }
00520
00521 bool AbiWordWorker::makePicture(const FrameAnchor& anchor)
00522 {
00523 kdDebug(30506) << "New image/clipart: " << anchor.picture.koStoreName
00524 << " , " << anchor.picture.key.toString() << endl;
00525
00526 const double height=anchor.frame.bottom - anchor.frame.top;
00527 const double width =anchor.frame.right - anchor.frame.left;
00528
00529
00530
00531 *m_streamOut << "<image dataid=\"" << anchor.picture.key.filename() << "\"";
00532 *m_streamOut << " props= \"height:" << height << "pt;width:" << width << "pt\"";
00533 *m_streamOut << "/>";
00534
00535
00536 m_mapPictureData[anchor.picture.koStoreName]=anchor.picture.key;
00537
00538 return true;
00539 }
00540
00541 void AbiWordWorker::writeAbiProps (const TextFormatting& formatLayout, const TextFormatting& format)
00542 {
00543 QString abiprops=textFormatToAbiProps(formatLayout,format,false);
00544
00545
00546 const int result=abiprops.findRev(";");
00547
00548 if (result>=0)
00549 {
00550
00551 abiprops.remove(result,2);
00552 }
00553
00554 if (!abiprops.isEmpty())
00555 {
00556 *m_streamOut << " props=\"" << abiprops << "\"";
00557 }
00558 }
00559
00560 void AbiWordWorker::processNormalText ( const QString ¶Text,
00561 const TextFormatting& formatLayout,
00562 const FormatData& formatData)
00563 {
00564
00565 QString partialText=escapeAbiWordText(paraText.mid(formatData.pos,formatData.len));
00566
00567
00568 int pos;
00569 while ((pos=partialText.find(QChar(10)))>-1)
00570 {
00571 partialText.replace(pos,1,"<br/>");
00572 }
00573
00574 if (formatData.text.missing)
00575 {
00576
00577 *m_streamOut << partialText;
00578 }
00579 else
00580 {
00581 *m_streamOut << "<c";
00582 writeAbiProps(formatLayout,formatData.text);
00583 *m_streamOut << ">" << partialText << "</c>";
00584 }
00585 }
00586
00587 void AbiWordWorker::processVariable ( const QString&,
00588 const TextFormatting& formatLayout,
00589 const FormatData& formatData)
00590 {
00591 if (0==formatData.variable.m_type)
00592 {
00593
00594 *m_streamOut << "<field type=\"date_ntdfl\"";
00595 writeAbiProps(formatLayout,formatData.text);
00596 *m_streamOut << "/>";
00597 }
00598 else if (2==formatData.variable.m_type)
00599 {
00600
00601 *m_streamOut << "<field type=\"time\"";
00602 writeAbiProps(formatLayout,formatData.text);
00603 *m_streamOut << "/>";
00604 }
00605 else if (4==formatData.variable.m_type)
00606 {
00607
00608 QString strFieldType;
00609 if (formatData.variable.isPageNumber())
00610 {
00611 strFieldType="page_number";
00612 }
00613 else if (formatData.variable.isPageCount())
00614 {
00615 strFieldType="page_count";
00616 }
00617 if (strFieldType.isEmpty())
00618 {
00619
00620 *m_streamOut << formatData.variable.m_text;
00621 }
00622 else
00623 {
00624 *m_streamOut << "<field type=\"" << strFieldType <<"\"";
00625 writeAbiProps(formatLayout,formatData.text);
00626 *m_streamOut << "/>";
00627 }
00628 }
00629 else if (9==formatData.variable.m_type)
00630 {
00631
00632 *m_streamOut << "<a xlink:href=\""
00633 << escapeAbiWordText(formatData.variable.getHrefName())
00634 << "\"><c";
00635 writeAbiProps(formatLayout,formatData.text);
00636 *m_streamOut << ">"
00637 << escapeAbiWordText(formatData.variable.getLinkName())
00638 << "</c></a>";
00639 }
00640 #if 0
00641 else if (11==(*paraFormatDataIt).variable.m_type)
00642 {
00643
00644 QString value = (*paraFormatDataIt).variable.getFootnoteValue();
00645 bool automatic = (*paraFormatDataIt).variable.getFootnoteAuto();
00646 QValueList<ParaData> *paraList = (*paraFormatDataIt).variable.getFootnotePara();
00647 if( paraList )
00648 {
00649 QString fstr;
00650 QValueList<ParaData>::ConstIterator it;
00651 for (it=paraList->begin();it!=paraList->end();it++)
00652 fstr += ProcessParagraphData( (*it).text, (*it).layout,(*it).formattingList);
00653 str += "{\\super ";
00654 str += automatic ? "\\chftn " : value;
00655 str += "{\\footnote ";
00656 str += "{\\super ";
00657 str += automatic ? "\\chftn " : value;
00658 str += fstr;
00659 str += " }";
00660 str += " }";
00661 str += " }";
00662 }
00663 }
00664 #endif
00665 else
00666 {
00667
00668 *m_streamOut << formatData.variable.m_text;
00669 }
00670 }
00671
00672 void AbiWordWorker::processAnchor ( const QString&,
00673 const TextFormatting& ,
00674 const FormatData& formatData)
00675 {
00676
00677 if ( (2==formatData.frameAnchor.type)
00678 || (5==formatData.frameAnchor.type) )
00679 {
00680 makePicture(formatData.frameAnchor);
00681 }
00682 else if (6==formatData.frameAnchor.type)
00683 {
00684 makeTable(formatData.frameAnchor);
00685 }
00686 else
00687 {
00688 kdWarning(30506) << "Unsupported anchor type: "
00689 << formatData.frameAnchor.type << endl;
00690 }
00691 }
00692
00693 void AbiWordWorker::processParagraphData ( const QString ¶Text,
00694 const TextFormatting& formatLayout,
00695 const ValueListFormatData ¶FormatDataList)
00696 {
00697 if ( paraText.length () > 0 )
00698 {
00699 ValueListFormatData::ConstIterator paraFormatDataIt;
00700
00701 for ( paraFormatDataIt = paraFormatDataList.begin ();
00702 paraFormatDataIt != paraFormatDataList.end ();
00703 paraFormatDataIt++ )
00704 {
00705 if (1==(*paraFormatDataIt).id)
00706 {
00707 processNormalText(paraText, formatLayout, (*paraFormatDataIt));
00708 }
00709 else if (4==(*paraFormatDataIt).id)
00710 {
00711 processVariable(paraText, formatLayout, (*paraFormatDataIt));
00712 }
00713 else if (6==(*paraFormatDataIt).id)
00714 {
00715 processAnchor(paraText, formatLayout, (*paraFormatDataIt));
00716 }
00717 }
00718 }
00719 }
00720
00721 QString AbiWordWorker::layoutToCss(const LayoutData& layoutOrigin,
00722 const LayoutData& layout, const bool force) const
00723 {
00724 QString props;
00725
00726 if (force || (layoutOrigin.alignment!=layout.alignment))
00727 {
00728
00729 if ((layout.alignment == "left") || (layout.alignment == "right")
00730 || (layout.alignment == "center") || (layout.alignment == "justify"))
00731 {
00732 props += "text-align:";
00733 props += layout.alignment;
00734 props += "; ";
00735 }
00736 else if (layout.alignment == "auto")
00737 {
00738
00739 props += "text-align:left; ";
00740 }
00741 else
00742 {
00743 kdWarning(30506) << "Unknown alignment: " << layout.alignment << endl;
00744 }
00745 }
00746
00747
00748 #if 0
00749
00750 if (!layout.tabulator.isEmpty()
00751 && (force || (layoutOrigin.tabulator!=layout.tabulator)))
00752 {
00753 props += "tabstops:";
00754 props += layout.tabulator;
00755 props += "; ";
00756 }
00757 #endif
00758 if (!layout.tabulatorList.isEmpty()
00759 && (force || (layoutOrigin.tabulatorList!=layout.tabulatorList) ))
00760 {
00761 props += "tabstops:";
00762 bool first=true;
00763 TabulatorList::ConstIterator it;
00764 TabulatorList::ConstIterator end(layout.tabulatorList.end());
00765 for (it=layout.tabulatorList.begin();it!=end;++it)
00766 {
00767 if (first)
00768 {
00769 first=false;
00770 }
00771 else
00772 {
00773 props += ",";
00774 }
00775 props += QString::number((*it).m_ptpos);
00776 props += "pt";
00777
00778 switch ((*it).m_type)
00779 {
00780 case 0: props += "/L"; break;
00781 case 1: props += "/C"; break;
00782 case 2: props += "/R"; break;
00783 case 3: props += "/D"; break;
00784 default: props += "/L";
00785 }
00786
00787 props += "0";
00788 }
00789 props += "; ";
00790 }
00791
00792 if ((layout.indentLeft>=0.0)
00793 && (force || (layoutOrigin.indentLeft!=layout.indentLeft)))
00794 {
00795 props += QString("margin-left:%1pt; ").arg(layout.indentLeft);
00796 }
00797
00798 if ((layout.indentRight>=0.0)
00799 && (force || (layoutOrigin.indentRight!=layout.indentRight)))
00800 {
00801 props += QString("margin-right:%1pt; ").arg(layout.indentRight);
00802 }
00803
00804 if (force || (layoutOrigin.indentLeft!=layout.indentLeft))
00805 {
00806 props += "text-indent: ";
00807 props += QString::number(layout.indentFirst);
00808 props += "pt; ";
00809 }
00810
00811 if ((layout.marginBottom>=0.0)
00812 && ( force || ( layoutOrigin.marginBottom != layout.marginBottom ) ) )
00813 {
00814 props += QString("margin-bottom:%1pt; ").arg(layout.marginBottom);
00815 }
00816
00817 if ((layout.marginTop>=0.0)
00818 && ( force || ( layoutOrigin.marginTop != layout.marginTop ) ) )
00819 {
00820 props += QString("margin-top:%1pt; ").arg(layout.marginTop);
00821 }
00822
00823 if (force
00824 || ( layoutOrigin.lineSpacingType != layout.lineSpacingType )
00825 || ( layoutOrigin.lineSpacing != layout.lineSpacing ) )
00826 {
00827 switch ( layout.lineSpacingType )
00828 {
00829 case LayoutData::LS_CUSTOM:
00830 {
00831
00832 props += "line-height=:";
00833 props += QString::number( layout.lineSpacing );
00834 props += "pt+; ";
00835 break;
00836 }
00837 case LayoutData::LS_SINGLE:
00838 {
00839 props += "line-height:1.0; ";
00840 break;
00841 }
00842 case LayoutData::LS_ONEANDHALF:
00843 {
00844 props += "line-height:1.5; ";
00845 break;
00846 }
00847 case LayoutData::LS_DOUBLE:
00848 {
00849 props += "line-height:2.0; ";
00850 break;
00851 }
00852 case LayoutData::LS_MULTIPLE:
00853 {
00854 props += "line-height:";
00855 props += QString::number( layout.lineSpacing );
00856 props += "; ";
00857 break;
00858 }
00859 case LayoutData::LS_FIXED:
00860 {
00861
00862 props += "line-height:";
00863 props += QString::number( layout.lineSpacing );
00864 props += "pt; ";
00865 break;
00866 }
00867 case LayoutData::LS_ATLEAST:
00868 {
00869
00870 props += "line-height=:";
00871 props += QString::number( layout.lineSpacing );
00872 props += "pt+; ";
00873 break;
00874 }
00875 default:
00876 {
00877 kdWarning(30506) << "Unsupported lineSpacingType: " << layout.lineSpacingType << " (Ignoring!)" << endl;
00878 break;
00879 }
00880 }
00881 }
00882
00883
00884 props += textFormatToAbiProps(layoutOrigin.formatData.text,layout.formatData.text,force);
00885
00886 return props;
00887 }
00888
00889 bool AbiWordWorker::doFullParagraph(const QString& paraText, const LayoutData& layout,
00890 const ValueListFormatData& paraFormatDataList)
00891 {
00892 QString style=layout.styleName;
00893
00894 const LayoutData& styleLayout=m_styleMap[style];
00895
00896 QString props=layoutToCss(styleLayout,layout,false);
00897
00898 *m_streamOut << "<p";
00899 if (!style.isEmpty())
00900 {
00901 *m_streamOut << " style=\"" << EscapeXmlText(style,true,true) << "\"";
00902 }
00903 if (!props.isEmpty())
00904 {
00905
00906
00907 const int result=props.findRev(";");
00908 if (result>=0)
00909 {
00910
00911 props.remove(result,2);
00912 }
00913
00914 *m_streamOut << " props=\"" << props << "\"";
00915 }
00916 *m_streamOut << ">";
00917
00918
00919 if (layout.pageBreakBefore)
00920 {
00921
00922 *m_streamOut << "<pbr/>";
00923 }
00924
00925 processParagraphData(paraText, layout.formatData.text, paraFormatDataList);
00926
00927
00928 if (layout.pageBreakAfter)
00929 {
00930
00931 *m_streamOut << "<pbr/>";
00932 }
00933
00934 *m_streamOut << "</p>\n";
00935 return true;
00936 }
00937
00938 bool AbiWordWorker::doFullDefineStyle(LayoutData& layout)
00939 {
00940
00941 m_styleMap[layout.styleName]=layout;
00942
00943 *m_streamOut << "<s";
00944
00945
00946 *m_streamOut << " name=\"" << EscapeXmlText(layout.styleName,true,true) << "\"";
00947 *m_streamOut << " followedby=\"" << EscapeXmlText(layout.styleFollowing,true,true) << "\"";
00948
00949 if ( (layout.counter.numbering == CounterData::NUM_CHAPTER)
00950 && (layout.counter.depth<10) )
00951 {
00952 *m_streamOut << " level=\"";
00953 *m_streamOut << QString::number(layout.counter.depth+1,10);
00954 *m_streamOut << "\"";
00955 }
00956
00957 QString abiprops=layoutToCss(layout,layout,true);
00958
00959 const int result=abiprops.findRev(";");
00960 if (result>=0)
00961 {
00962
00963 abiprops.remove(result,2);
00964 }
00965
00966 *m_streamOut << " props=\"" << abiprops << "\"";
00967
00968 *m_streamOut << "/>\n";
00969
00970 return true;
00971 }
00972
00973 bool AbiWordWorker::doFullPaperFormat(const int format,
00974 const double width, const double height, const int orientation)
00975 {
00976 QString outputText = "<pagesize ";
00977
00978 switch (format)
00979 {
00980
00981 case PG_DIN_A0:
00982 case PG_DIN_A1:
00983 case PG_DIN_A2:
00984 case PG_DIN_A3:
00985 case PG_DIN_A4:
00986 case PG_DIN_A5:
00987 case PG_DIN_A6:
00988
00989 case PG_DIN_B0:
00990 case PG_DIN_B1:
00991 case PG_DIN_B2:
00992 case PG_DIN_B3:
00993 case PG_DIN_B4:
00994 case PG_DIN_B5:
00995 case PG_DIN_B6:
00996
00997 case PG_US_LETTER:
00998 case PG_US_LEGAL:
00999 {
01000 QString pagetype=KoPageFormat::formatString(KoFormat(format));
01001 outputText+="pagetype=\"";
01002 outputText+=pagetype;
01003
01004 QString strWidth, strHeight, strUnits;
01005 KWEFUtil::GetNativePaperFormat(format, strWidth, strHeight, strUnits);
01006 outputText+="\" width=\"";
01007 outputText+=strWidth;
01008 outputText+="\" height=\"";
01009 outputText+=strHeight;
01010 outputText+="\" units=\"";
01011 outputText+=strUnits;
01012 outputText+="\" ";
01013 break;
01014 }
01015 case PG_US_EXECUTIVE:
01016 {
01017
01018 #if 0
01019 outputText += "pagetype=\"Custom\" width=\"7.5\" height=\"10.0\" units=\"inch\" ";
01020 #else
01021
01022 outputText += "pagetype=\"Letter\" width=\"8.5\" height=\"11.0\" units=\"inch\" ";
01023 #endif
01024 break;
01025 }
01026
01027 case PG_DIN_A7:
01028 case PG_DIN_A8:
01029 case PG_DIN_A9:
01030 case PG_DIN_B10:
01031
01032 case PG_SCREEN:
01033 case PG_CUSTOM:
01034 default:
01035 {
01036
01037 if ((width<=1.0) || (height<=1.0) || true)
01038 {
01039
01040 outputText += "pagetype=\"A4\" width=\"21.0\" height=\"29.7\" units=\"cm\" ";
01041 }
01042 else
01043 {
01044 outputText += QString("pagetype=\"Custom\" width=\"%1\" height=\"%2\" units=\"inch\" ").arg(width/72.0).arg(height/72.0);
01045 }
01046 break;
01047 }
01048 }
01049
01050 outputText += "orientation=\"";
01051 if (1==orientation)
01052 {
01053 outputText += "landscape";
01054 }
01055 else
01056 {
01057 outputText += "portrait";
01058 }
01059 outputText += "\" ";
01060
01061 outputText += "page-scale=\"1.0\"/>\n";
01062
01063 m_pagesize=outputText;
01064 return true;
01065 }
01066
01067 bool AbiWordWorker::doFullPaperBorders (const double top, const double left,
01068 const double bottom, const double right)
01069 {
01070 m_paperBorderTop=top;
01071 m_paperBorderLeft=left;
01072 m_paperBorderBottom=bottom;
01073 m_paperBorderRight=right;
01074 return true;
01075 }
01076
01077 bool AbiWordWorker::doCloseHead(void)
01078 {
01079 if (!m_pagesize.isEmpty())
01080 {
01081 *m_streamOut << m_pagesize;
01082 }
01083 return true;
01084 }
01085
01086 bool AbiWordWorker::doOpenSpellCheckIgnoreList (void)
01087 {
01088 kdDebug(30506) << "AbiWordWorker::doOpenSpellCheckIgnoreList" << endl;
01089 m_inIgnoreWords=false;
01090 return true;
01091 }
01092
01093 bool AbiWordWorker::doCloseSpellCheckIgnoreList (void)
01094 {
01095 kdDebug(30506) << "AbiWordWorker::doCloseSpellCheckIgnoreList" << endl;
01096 if (m_inIgnoreWords)
01097 *m_streamOut << "</ignorewords>\n";
01098 return true;
01099 }
01100
01101 bool AbiWordWorker::doFullSpellCheckIgnoreWord (const QString& ignoreword)
01102 {
01103 kdDebug(30506) << "AbiWordWorker::doFullSpellCheckIgnoreWord: " << ignoreword << endl;
01104 if (!m_inIgnoreWords)
01105 {
01106 *m_streamOut << "<ignorewords>\n";
01107 m_inIgnoreWords=true;
01108 }
01109 *m_streamOut << " <iw>" << ignoreword << "</iw>\n";
01110 return true;
01111 }
01112
01113
01114 QString AbiWordWorker::transformToTextDate(const QDateTime& dt)
01115 {
01116 if (dt.isValid())
01117 {
01118 QString result;
01119
01120 const QDate date(dt.date());
01121
01122 const char* dayName[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
01123 const int dow = date.dayOfWeek() - 1;
01124 if ((dow<0) || (dow>6))
01125 result += "Mon";
01126 else
01127 result += dayName[dow];
01128 result += ' ';
01129
01130 const char* monthName[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
01131 const int month = date.month() - 1;
01132 if ((month<0) || (month>11))
01133 result += "Jan";
01134 else
01135 result += monthName[month];
01136 result += ' ';
01137
01138 QString temp;
01139
01140 temp = "00";
01141 temp += QString::number(date.day(), 10);
01142 result += temp.right(2);
01143 result += ' ';
01144
01145 const QTime time(dt.time());
01146
01147 temp = "00";
01148 temp += QString::number(time.hour(), 10);
01149 result += temp.right(2);
01150 result += ':';
01151
01152 temp = "00";
01153 temp += QString::number(time.minute(), 10);
01154 result += temp.right(2);
01155 result += ':';
01156
01157 temp = "00";
01158 temp += QString::number(time.second(), 10);
01159 result += temp.right(2);
01160 result += ' ';
01161
01162 temp = "0000";
01163 temp += QString::number(date.year(), 10);
01164 result += temp.right(4);
01165
01166 return result;
01167 }
01168 else
01169 {
01170
01171 return "Thu Jan 01 00:00:00 1970";
01172 }
01173 }
01174
01175 bool AbiWordWorker::doFullDocumentInfo(const KWEFDocumentInfo& docInfo)
01176 {
01177 m_docInfo=docInfo;
01178
01179 *m_streamOut << "<metadata>\n";
01180
01181
01182 *m_streamOut << "<m key=\"dc.format\">application/x-abiword</m>\n";
01183 if (!m_docInfo.title.isEmpty())
01184 {
01185 *m_streamOut << "<m key=\"dc.title\">" << escapeAbiWordText(m_docInfo.title) << "</m>\n";
01186 }
01187 if (!m_docInfo.abstract.isEmpty())
01188 {
01189 *m_streamOut << "<m key=\"dc.description\">" << escapeAbiWordText(m_docInfo.abstract) << "</m>\n";
01190 }
01191
01192 if ( !m_docInfo.keywords.isEmpty() )
01193 {
01194 *m_streamOut << "<m key=\"abiword.keywords\">" << escapeAbiWordText(m_docInfo.keywords) << "</m>\n";
01195 }
01196 if ( !m_docInfo.subject.isEmpty() )
01197 {
01198 *m_streamOut << "<m key=\"dc.subject\">" << escapeAbiWordText(m_docInfo.subject) << "</m>\n";
01199 }
01200
01201
01202 *m_streamOut << "<m key=\"abiword.generator\">KWord Export Filter";
01203
01204 QString strVersion("$Revision: 508787 $");
01205
01206
01207 *m_streamOut << strVersion.mid(10).remove('$');
01208
01209 *m_streamOut << "</m>\n";
01210
01211 QDateTime now (QDateTime::currentDateTime(Qt::UTC));
01212 *m_streamOut << "<m key=\"abiword.date_last_changed\">"
01213 << escapeAbiWordText(transformToTextDate(now))
01214 << "</m>\n";
01215
01216 *m_streamOut << "</metadata>\n";
01217
01218 return true;
01219 }
01220
01221
01222
01223
01224 ABIWORDExport::ABIWORDExport(KoFilter *, const char *, const QStringList &) :
01225 KoFilter() {
01226 }
01227
01228 KoFilter::ConversionStatus ABIWORDExport::convert( const QCString& from, const QCString& to )
01229 {
01230 if ( to != "application/x-abiword" || from != "application/x-kword" )
01231 {
01232 return KoFilter::NotImplemented;
01233 }
01234
01235
01236 KImageIO::registerFormats();
01237
01238 AbiWordWorker* worker=new AbiWordWorker();
01239
01240 if (!worker)
01241 {
01242 kdError(30506) << "Cannot create Worker! Aborting!" << endl;
01243 return KoFilter::StupidError;
01244 }
01245
01246 KWEFKWordLeader* leader=new KWEFKWordLeader(worker);
01247
01248 if (!leader)
01249 {
01250 kdError(30506) << "Cannot create Worker! Aborting!" << endl;
01251 delete worker;
01252 return KoFilter::StupidError;
01253 }
01254
01255 KoFilter::ConversionStatus result=leader->convert(m_chain,from,to);
01256
01257 delete leader;
01258 delete worker;
01259
01260 return result;
01261 }