00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <qstring.h>
00024 #include <qtextcodec.h>
00025 #include <qfile.h>
00026 #include <qfileinfo.h>
00027 #include <qfontinfo.h>
00028 #include <qfontdatabase.h>
00029 #include <qpicture.h>
00030 #include <qimage.h>
00031 #include <qregexp.h>
00032 #include <qcolor.h>
00033 #include <qdatetime.h>
00034
00035 #include <klocale.h>
00036 #include <kglobal.h>
00037 #include <kdebug.h>
00038
00039 #include <KWEFUtil.h>
00040 #include <KWEFBaseWorker.h>
00041
00042 #include "ExportFilter.h"
00043
00044
00045
00046
00047
00048 #define TWIP_TO_MM(x) (x)*25.4/1440.0
00049 #define MM_TO_TWIP(x) (x)*1440.0/25.4
00050 #define PT_TO_TWIP(x) (x)*20
00051 #define TWIP_TO_PT(x) (x)/20
00052
00053
00054
00055 static QString mapFieldName( const QString& kwordField )
00056 {
00057 QString rtfField;
00058
00059 if( kwordField == "fileName" ) rtfField = "FILENAME";
00060 else if( kwordField == "authorName" ) rtfField = "AUTHOR";
00061 else if( kwordField == "docTitle" ) rtfField = "TITLE";
00062
00063 return rtfField;
00064 }
00065
00066 RTFWorker::RTFWorker():
00067 m_ioDevice(NULL), m_streamOut(NULL), m_eol("\r\n"), m_inTable(false),
00068 m_paperOrientation(false), m_paperWidth(20), m_paperHeight(20),
00069 m_paperMarginTop(72), m_paperMarginLeft(72),
00070 m_paperMarginBottom(72), m_paperMarginRight(72), m_startPageNumber(1)
00071 {
00072 }
00073
00074 static QString WritePositiveKeyword(const QString& keyword, const int value)
00075 {
00076 QString str;
00077 str += keyword;
00078
00079 if (value>0)
00080 str += QString::number( value );
00081 else
00082 str += '0';
00083
00084 return str;
00085 }
00086
00087 QString RTFWorker::writeRow(const QString& textCellHeader, const QString& rowText, const FrameData& frame)
00088 {
00089 QString row;
00090
00091 row += "\\trowd\\trgaph60\\trql";
00092 row += WritePositiveKeyword("\\trrh", qRound(PT_TO_TWIP(frame.minHeight)));
00093 row += WritePositiveKeyword("\\trleft", qRound(PT_TO_TWIP(frame.left) - m_paperMarginLeft));
00094
00095 row += textCellHeader;
00096 row += " ";
00097 row += rowText;
00098
00099 return row;
00100 }
00101
00102 QString RTFWorker::writeBorder(const char whichBorder, const int borderWidth, const QColor& color)
00103 {
00104 QString str;
00105 if (borderWidth > 0)
00106 {
00107 str += "\\clbrdr";
00108 str += whichBorder;
00109 str += "\\brdrs\\brdrw";
00110 str += QString::number(borderWidth);
00111 if (color.isValid())
00112 {
00113 str += lookupColor("\\brdrcf",color);
00114 }
00115 }
00116 return str;
00117 }
00118
00119 QString RTFWorker::makeTable(const FrameAnchor& anchor)
00120 {
00121 QString textBody;
00122 textBody += m_prefix;
00123 m_prefix = QString::null;
00124 QString rowText;
00125
00126 int rowCurrent = 0;
00127 bool firstCellInRow = true;
00128 FrameData firstFrameData;
00129 int debugCellCurrent = 0;
00130 int debugRowCurrent = 0;
00131 QString textCellHeader;
00132
00133 const bool oldInTable = m_inTable;
00134 m_inTable = true;
00135
00136 QValueList<TableCell>::ConstIterator itCell;
00137 for (itCell=anchor.table.cellList.begin();
00138 itCell!=anchor.table.cellList.end(); itCell++)
00139 {
00140
00141 if (rowCurrent!=(*itCell).row)
00142 {
00143 rowCurrent = (*itCell).row;
00144 textBody += writeRow( textCellHeader, rowText, firstFrameData);
00145 textBody += "\\row";
00146 textBody += m_eol;
00147 rowText = QString::null;
00148 textCellHeader = QString::null;
00149 firstCellInRow=true;
00150 debugRowCurrent ++;
00151 debugCellCurrent = 0;
00152 }
00153
00154 const FrameData& frame = (*itCell).frame;
00155
00156 if (firstCellInRow)
00157 {
00158 firstFrameData=frame;
00159 firstCellInRow=false;
00160 }
00161
00162 kdDebug(30515) << "Cell: " << debugRowCurrent << "," << debugCellCurrent
00163 << " left: " << frame.left << " right: " << frame.right << " top: " << frame.top << " bottom " << frame.bottom << endl;
00164 textCellHeader += writeBorder('t',qRound(PT_TO_TWIP(frame.tWidth)),frame.tColor);
00165 textCellHeader += writeBorder('l',qRound(PT_TO_TWIP(frame.lWidth)),frame.lColor);
00166 textCellHeader += writeBorder('b',qRound(PT_TO_TWIP(frame.bWidth)),frame.bColor);
00167 textCellHeader += writeBorder('r',qRound(PT_TO_TWIP(frame.rWidth)),frame.rColor);
00168 textCellHeader += WritePositiveKeyword("\\cellx",qRound(PT_TO_TWIP(frame.right) - m_paperMarginRight));
00169
00170 QString endOfParagraph;
00171 QValueList<ParaData> *paraList = (*itCell).paraList;
00172 QValueList<ParaData>::ConstIterator it;
00173 QValueList<ParaData>::ConstIterator end(paraList->end());
00174 for (it=paraList->begin();it!=end;++it)
00175 {
00176 rowText += endOfParagraph;
00177 rowText += ProcessParagraphData( (*it).text,(*it).layout,(*it).formattingList);
00178 rowText += m_eol;
00179 endOfParagraph = "\\par";
00180 }
00181 rowText += "\\cell";
00182 debugCellCurrent ++;
00183 }
00184
00185 textBody += writeRow( textCellHeader, rowText, firstFrameData);
00186 textBody += "\\row\\pard";
00187 textBody += m_eol;
00188 m_inTable = oldInTable;
00189
00190 return textBody;
00191 }
00192
00193 QString RTFWorker::makeImage(const FrameAnchor& anchor)
00194 {
00195 QString textBody;
00196
00197 QString strImageName(anchor.picture.koStoreName);
00198 QString strExt;
00199 QByteArray image;
00200
00201 kdDebug(30515) << "RTFWorker::makeImage" << endl << anchor.picture.koStoreName << endl;
00202
00203 const int pos=strImageName.findRev('.');
00204 if(pos!=-1) strExt = strImageName.mid(pos+1).lower();
00205
00206 QString strTag;
00207 if (strExt=="png")
00208 strTag="\\pngblip";
00209 #if 0
00210 else if (strExt=="bmp")
00211 strTag="\\dibitmap";
00212 #endif
00213 else if ( (strExt=="jpeg") || (strExt=="jpg") )
00214 strTag="\\jpegblip";
00215 else if (strExt=="wmf")
00216 strTag="\\wmetafile8";
00217 else
00218 {
00219
00220
00221 kdDebug(30515) << "Converting image " << anchor.picture.koStoreName << endl;
00222
00223 strTag="\\pngblip";
00224 if( !loadAndConvertToImage(anchor.picture.koStoreName,strExt,"PNG",image) )
00225 {
00226 kdWarning(30515) << "Unable to convert " << anchor.picture.koStoreName << endl;
00227 return QString::null;
00228 }
00229 }
00230
00231
00232
00233 if( !image.size() )
00234 if (!loadSubFile(anchor.picture.koStoreName,image))
00235 {
00236 kdWarning(30515) << "Unable to load picture " << anchor.picture.koStoreName << endl;
00237 return QString::null;
00238 }
00239
00240
00241
00242 const long width = (long)(PT_TO_TWIP(anchor.frame.right - anchor.frame.left));
00243 const long height = (long)(PT_TO_TWIP(anchor.frame.bottom - anchor.frame.top));
00244
00245
00246 long origWidth = width;
00247 long origHeight = height;
00248 if( strExt == "wmf" )
00249 {
00250
00251
00252 Q_UINT8* data = (Q_UINT8*) image.data();
00253 if( ( data[0] == 0xd7 ) && ( data[1] == 0xcd ) &&
00254 ( data[2] == 0xc6 ) && ( data[3] == 0x9a ) &&
00255 ( image.size() > 22 ) )
00256 {
00257
00258 unsigned left = data[6]+(data[7]<<8);
00259 unsigned top = data[8]+(data[9]<<8);
00260 unsigned right = data[10]+(data[11]<<8);
00261 unsigned bottom = data[12]+(data[13]<<8);
00262 origWidth = (long) (MM_TO_TWIP(right-left)/100);
00263 origHeight = (long) (MM_TO_TWIP(bottom-top)/100);
00264
00265
00266 for( uint i=0; i<image.size()-22; i++)
00267 image.at(i) = image.at(i+22);
00268 image.resize( image.size()-22 );
00269 }
00270 }
00271 else
00272 {
00273
00274 QImage img( image );
00275 if( img.isNull() )
00276 {
00277 kdWarning(30515) << "Unable to load picture as image " << anchor.picture.koStoreName << endl;
00278 return QString::null;
00279 }
00280
00281 int resx = img.dotsPerMeterX();
00282 int resy = img.dotsPerMeterY();
00283 if( resx <= 0 ) resx = 2835;
00284 if( resy <= 0 ) resy = 2835;
00285
00286 origWidth = long(img.width() * 2834.65 * 20 / resx);
00287 origHeight = long(img.height() * 2834.65 * 20 / resy);
00288 }
00289
00290
00291 textBody += "{\\pict";
00292 textBody += strTag;
00293
00294
00295 int scaleX = width * 100 / origWidth;
00296 int scaleY = height * 100 / origHeight;
00297
00298
00299 int picw = (int)(100 * TWIP_TO_MM(origWidth));
00300 int pich = (int)(100 * TWIP_TO_MM(origHeight));
00301
00302 textBody += "\\picscalex";
00303 textBody += QString::number(scaleX, 10);
00304 textBody += "\\picscaley";
00305 textBody += QString::number(scaleY, 10);
00306 textBody += "\\picw";
00307 textBody += QString::number(picw,10);
00308 textBody += "\\pich";
00309 textBody += QString::number(pich,10);
00310 textBody += "\\picwgoal";
00311 textBody += QString::number(origWidth, 10);
00312 textBody += "\\pichgoal";
00313 textBody += QString::number(origHeight, 10);
00314
00315 textBody+=" ";
00316 const char hex[] = "0123456789abcdef";
00317 for (uint i=0; i<image.size(); i++)
00318 {
00319 if (!(i%40))
00320 textBody += m_eol;
00321 const char ch=image.at(i);
00322 textBody += hex[(ch>>4)&0x0f];
00323 textBody += hex[(ch&0x0f)];
00324 }
00325
00326
00327 textBody+="}";
00328
00329 return textBody;
00330 }
00331
00332 QString RTFWorker::formatTextParagraph(const QString& strText,
00333 const FormatData& formatOrigin, const FormatData& format)
00334 {
00335 QString str;
00336
00337 if (!format.text.missing)
00338 {
00339
00340 str+=openSpan(formatOrigin,format);
00341 }
00342
00343 QString strEscaped = escapeRtfText(strText);
00344
00345
00346 int pos;
00347 QString strBr("\\line ");
00348 while ((pos=strEscaped.find(QChar(10)))>-1)
00349 {
00350 strEscaped.replace(pos,1,strBr);
00351 }
00352
00353 str+=strEscaped;
00354
00355 if (!format.text.missing)
00356 {
00357
00358 str+=closeSpan(formatOrigin,format);
00359 }
00360
00361 return str;
00362 }
00363
00364 QString RTFWorker::ProcessParagraphData ( const QString ¶Text,
00365 const LayoutData& layout, const ValueListFormatData ¶FormatDataList)
00366 {
00367 QString str;
00368 QString content;
00369 QString markup;
00370
00371 markup += "\\pard";
00372 markup += "\\plain";
00373 if (m_inTable)
00374 markup += "\\intbl";
00375
00376
00377 if (layout.counter.style)
00378 {
00379 markup += "{\\pntext\\pard\\plain";
00380 if( layout.formatData.text.fontSize >= 0)
00381 {
00382 markup += "\\fs";
00383 markup += QString::number((2 * layout.formatData.text.fontSize));
00384 markup += lookupFont("\\f",layout.formatData.text.fontName);
00385 }
00386 markup += " ";
00387 markup += layout.counter.text;
00388 markup += "\\tab}{\\*\\pn";
00389 if (layout.counter.style > 5)
00390 {
00391 markup += "\\pnlvlblt ";
00392 markup += "{\\pntxtb ";
00393 if (!layout.counter.lefttext.isEmpty() && layout.counter.lefttext != "{" && layout.counter.lefttext != "}")
00394 {
00395 markup += layout.counter.lefttext;
00396 }
00397 switch (layout.counter.style)
00398 {
00399 case 6:
00400 {
00401
00402
00403
00404 markup += layout.counter.customCharacter;
00405 break;
00406 }
00407 case 7:
00408 {
00409
00410 markup += layout.counter.text;
00411 break;
00412 }
00413 case 8:
00414 {
00415
00416
00417 markup += "\\bullet";
00418 break;
00419 }
00420 case 9:
00421 {
00422
00423
00424 markup += "\\bullet";
00425 break;
00426 }
00427 case 10:
00428 {
00429
00430
00431 markup += "\\bullet";
00432 break;
00433 }
00434 case 11:
00435 {
00436
00437
00438 markup += layout.counter.text;
00439 break;
00440 }
00441 default:
00442 markup += "\\bullet";
00443 }
00444 markup += "}";
00445 }
00446 else
00447 {
00448 if (layout.counter.numbering!=0)
00449 {
00450 markup += "\\pnlvl";
00451 markup += QString::number(layout.counter.depth + 1);
00452 markup += "\\pnprev1";
00453 }
00454 else if (layout.counter.style==1)
00455 {
00456 markup += "\\pnlvlbody";
00457 }
00458 else
00459 {
00460 markup += "\\pnlvl";
00461 markup += QString::number(11 - layout.counter.style);
00462 }
00463
00464 switch (layout.counter.style)
00465 {
00466 case 1:
00467 {
00468 markup += "\\pndec";
00469 break;
00470 }
00471 case 2:
00472 {
00473 markup += "\\pnlcltr";
00474 break;
00475 }
00476 case 3:
00477 {
00478 markup += "\\pnucltr";
00479 break;
00480 }
00481 case 4:
00482 {
00483 markup += "\\pnlcrm";
00484 break;
00485 }
00486 case 5:
00487 {
00488 markup += "\\pnucrm";
00489 break;
00490 }
00491 default:
00492 markup += "\\pndec";
00493 }
00494 markup += "{\\pntxtb ";
00495 markup += layout.counter.lefttext;
00496 markup += " }";
00497 }
00498 markup += "{\\pntxta ";
00499 markup += layout.counter.righttext;
00500 markup += " }";
00501
00502
00503 if (layout.counter.start!=0)
00504 {
00505 markup += "\\pnstart";
00506 markup += QString::number(layout.counter.start);
00507 }
00508 else
00509 {
00510 markup += "\\pnstart1";
00511 }
00512 markup += "\\pnindent0\\pnhang";
00513
00514 if( layout.formatData.text.fontSize > 0 )
00515 {
00516 markup += "\\pnfs";
00517 markup += QString::number((2 * layout.formatData.text.fontSize));
00518 }
00519
00520 if( !layout.formatData.text.fontName.isEmpty() )
00521 {
00522 markup += lookupFont("\\pnf", layout.formatData.text.fontName);
00523 }
00524
00525 markup += "}";
00526 }
00527
00528
00529 LayoutData styleLayout;
00530 markup += lookupStyle(layout.styleName, styleLayout);
00531 markup += layoutToRtf(styleLayout,layout,true);
00532
00533 if ( 1==layout.formatData.text.verticalAlignment )
00534 {
00535 markup += "\\sub";
00536 }
00537 else if ( 2==layout.formatData.text.verticalAlignment )
00538 {
00539 markup += "\\super";
00540 }
00541
00542
00543 if (layout.pageBreakBefore)
00544 content += "\\page ";
00545
00546
00547
00548
00549
00550 if (!paraText.isEmpty())
00551 {
00552
00553 ValueListFormatData::ConstIterator paraFormatDataIt;
00554
00555 QString partialText;
00556
00557 FormatData formatRef = layout.formatData;
00558
00559 for ( paraFormatDataIt = paraFormatDataList.begin ();
00560 paraFormatDataIt != paraFormatDataList.end ();
00561 paraFormatDataIt++ )
00562 {
00563 if (1==(*paraFormatDataIt).id)
00564 {
00565
00566 partialText=paraText.mid ( (*paraFormatDataIt).pos, (*paraFormatDataIt).len );
00567 content +=formatTextParagraph(partialText, formatRef, *paraFormatDataIt);
00568 }
00569 else if (4==(*paraFormatDataIt).id)
00570 {
00571
00572 if ( (0==(*paraFormatDataIt).variable.m_type)
00573 || (2==(*paraFormatDataIt).variable.m_type) )
00574 {
00575
00576 content += "{\\field{\\*\\fldinst ";
00577 if (0==(*paraFormatDataIt).variable.m_type)
00578 content += "DATE ";
00579 else
00580 content += "TIME ";
00581 QString key((*paraFormatDataIt).variable.m_key.mid(4));
00582 kdDebug(30515) << "Time format: " << key << endl;
00583 if (key.startsWith("locale"))
00584 {
00585 if (key == "locale" )
00586 {
00587 if (0==(*paraFormatDataIt).variable.m_type)
00588 key = KGlobal::locale()->dateFormat();
00589 else
00590 key = KGlobal::locale()->timeFormat();
00591 }
00592 else if ( key == "localeshort" )
00593 key = KGlobal::locale()->dateFormatShort();
00594 else if ( key == "localedatetime" )
00595 {
00596 key = KGlobal::locale()->dateFormat();
00597 key += ' ';
00598 key += KGlobal::locale()->timeFormat();
00599 }
00600 else if ( key == "localedatetimeshort" )
00601 {
00602 key = KGlobal::locale()->dateFormat();
00603 key += ' ';
00604 key += KGlobal::locale()->timeFormat();
00605 }
00606
00607 kdDebug(30515) << "Locale date in KLocale format: " << key << endl;
00608
00609
00610
00611
00612 key.replace( "%Y", "yyyy" );
00613 key.replace( "%y", "yy" );
00614 key.replace( "%n", "M" );
00615 key.replace( "%m", "MM" );
00616 key.replace( "%e", "d" );
00617 key.replace( "%d", "dd" );
00618 key.replace( "%b", "MMM" );
00619 key.replace( "%B", "MMMM" );
00620 key.replace( "%a", "ddd" );
00621 key.replace( "%A", "dddd" );
00622
00623 key.replace( "%p", "am/pm" );
00624 key.replace( "%I", "hh" );
00625 key.replace( "%l", "h" );
00626
00627 key.replace( "%H", "HH" );
00628 key.replace( "%k", "H" );
00629
00630 key.replace( "%M", "mm" );
00631 key.replace( "%S", "ss" );
00632
00633 kdDebug(30515) << "Locale date in RTF format: " << key << endl;
00634 }
00635 else if (!key.isEmpty())
00636 {
00637 const QRegExp regexp("AP",false);
00638 if (regexp.search(key)!=-1)
00639 {
00640
00641 key.replace("ap","am/pm");
00642 key.replace("AP","AM/PM");
00643 }
00644 else
00645 {
00646
00647 key.replace('h','H');
00648 }
00649
00650 key.replace("PPP","MMM");
00651 key.replace("PPPP","MMMM");
00652 key.replace("zzz","000");
00653 kdDebug(30515) << "New format: " << key << endl;
00654 content += "\\@ \"";
00655 content += key;
00656 content += "\" ";
00657 }
00658 content += "\\* MERGEFORMAT }{\\fldrslt ";
00659 content += escapeRtfText((*paraFormatDataIt).variable.m_text);
00660 content += "}}";
00661 }
00662 else if (4==(*paraFormatDataIt).variable.m_type)
00663 {
00664 QString strFieldType;
00665 if ((*paraFormatDataIt).variable.isPageNumber())
00666 {
00667 content += "{\\field{\\*\\fldinst PAGE \\* MERGEFORMAT }{\\fldrslt ";
00668 content += escapeRtfText((*paraFormatDataIt).variable.m_text);
00669 content += "}}";
00670 }
00671 else if ((*paraFormatDataIt).variable.isPageCount())
00672 {
00673 content += "{\\field{\\*\\fldinst NUMPAGES \\* MERGEFORMAT }{\\fldrslt ";
00674 content += escapeRtfText((*paraFormatDataIt).variable.m_text);
00675 content += "}}";
00676 }
00677 else
00678 {
00679
00680 content += escapeRtfText((*paraFormatDataIt).variable.m_text);
00681 }
00682 }
00683 else if (8==(*paraFormatDataIt).variable.m_type)
00684 {
00685
00686 QString name = escapeRtfText((*paraFormatDataIt).variable.getFieldName());
00687 QString value = escapeRtfText((*paraFormatDataIt).variable.getFieldValue());
00688 QString rtfField = mapFieldName(name);
00689
00690 if( rtfField.isEmpty() )
00691
00692 content += escapeRtfText((*paraFormatDataIt).variable.m_text);
00693 else
00694 {
00695 content += "{\\field";
00696 content += "{\\*\\fldinst ";
00697 content += rtfField;
00698 content += " \\* MERGEFORMAT }";
00699 content += "{\\fldrslt {";
00700 content += value;
00701 content += "}}}";
00702 }
00703 }
00704 else if (9==(*paraFormatDataIt).variable.m_type)
00705 {
00706
00707 content += "{\\field";
00708 content += "{\\*\\fldinst HYPERLINK ";
00709 content += escapeRtfText((*paraFormatDataIt).variable.getHrefName());
00710 content += "}";
00711 content += "{\\fldrslt ";
00712 content += "{\\ul";
00713 content += lookupColor("\\cf",QColor(0,0,255));
00714 content += escapeRtfText((*paraFormatDataIt).variable.getLinkName());
00715 content += "}}}";
00716 }
00717 else if (11==(*paraFormatDataIt).variable.m_type)
00718 {
00719
00720 QString value = (*paraFormatDataIt).variable.getFootnoteValue();
00721 bool automatic = (*paraFormatDataIt).variable.getFootnoteAuto();
00722 QValueList<ParaData> *paraList = (*paraFormatDataIt).variable.getFootnotePara();
00723 if( paraList )
00724 {
00725 QString fstr;
00726 QValueList<ParaData>::ConstIterator it;
00727 QValueList<ParaData>::ConstIterator end(paraList->end());
00728 for (it=paraList->begin();it!=end;++it)
00729 fstr += ProcessParagraphData( (*it).text, (*it).layout,(*it).formattingList);
00730 content += "{\\super ";
00731 content += automatic ? "\\chftn " : value;
00732 content += "{\\footnote ";
00733 content += "{\\super ";
00734 content += automatic ? "\\chftn " : value;
00735 content += fstr;
00736 content += " }";
00737 content += " }";
00738 content += " }";
00739 }
00740 }
00741 else
00742 {
00743
00744 content += escapeRtfText((*paraFormatDataIt).variable.m_text);
00745 }
00746 }
00747 else if (6==(*paraFormatDataIt).id)
00748 {
00749 kdDebug(30515) << "Found an anchor of type: " << (*paraFormatDataIt).frameAnchor.type << endl;
00750
00751
00752 if (6==(*paraFormatDataIt).frameAnchor.type)
00753 {
00754
00755
00756 if (!content.isEmpty())
00757 {
00758 str += m_prefix;
00759 str += markup;
00760 str += " {";
00761 str += content;
00762 str += "}";
00763 str += m_eol;
00764 content = QString::null;
00765 if (!m_inTable)
00766 {
00767 m_prefix = "\\par";
00768 }
00769 }
00770 str += makeTable((*paraFormatDataIt).frameAnchor);
00771 }
00772 else if ((2==(*paraFormatDataIt).frameAnchor.type) || (5==(*paraFormatDataIt).frameAnchor.type))
00773 {
00774 content += makeImage((*paraFormatDataIt).frameAnchor);
00775
00776 }
00777 }
00778 }
00779 }
00780
00781 if (layout.pageBreakAfter)
00782 content += "\\page";
00783
00784 if (!content.isEmpty())
00785 {
00786 str += m_prefix;
00787 str += markup;
00788 str += " {";
00789 str += content;
00790 str += "}";
00791 str += m_eol;
00792 if (m_inTable==false)
00793 {
00794 m_prefix = "\\par";
00795 }
00796 }
00797 if (str.isEmpty())
00798 {
00799 str ="\\par\\pard\\plain";
00800 if (m_inTable==false)
00801 {
00802 m_prefix = "\\par";
00803 }
00804 }
00805 return str;
00806 }
00807
00808 bool RTFWorker::doFullParagraph(const QString& paraText,
00809 const LayoutData& layout, const ValueListFormatData& paraFormatDataList)
00810 {
00811 kdDebug(30515) << "Entering RTFWorker::doFullParagraph" << endl << paraText << endl;
00812 QString par = ProcessParagraphData( paraText, layout, paraFormatDataList);
00813 m_textBody += par;
00814 kdDebug(30515) << "Quiting RTFWorker::doFullParagraph" << endl;
00815 return true;
00816 }
00817
00818 bool RTFWorker::doHeader(const HeaderData& header)
00819 {
00820 QString str;
00821 QString content;
00822 if( header.page == HeaderData::PAGE_ODD )
00823 str = "\\facingp{\\headerr";
00824 else if( header.page == HeaderData::PAGE_EVEN )
00825 str = "\\facingp{\\headerl";
00826 else if( header.page == HeaderData::PAGE_FIRST )
00827 str = "\\facingp{\\headerl";
00828 else if( header.page == HeaderData::PAGE_ALL )
00829 str = "{\\header";
00830 else
00831 return false;
00832
00833 str += " {";
00834
00835 QValueList<ParaData>::ConstIterator it;
00836 QValueList<ParaData>::ConstIterator end(header.para.end());
00837 for (it=header.para.begin();it!=end;++it)
00838 content += ProcessParagraphData( (*it).text,(*it).layout,(*it).formattingList);
00839
00840 if (content!="\\par\\pard\\plain")
00841 {
00842 str += content;
00843 str += "}";
00844
00845 str += "}";
00846
00847 m_textBody += str;
00848 }
00849 m_prefix=QString::null;
00850 return true;
00851 }
00852
00853 bool RTFWorker::doFooter(const FooterData& footer)
00854 {
00855 QString str;
00856 QString content;
00857 if( footer.page == FooterData::PAGE_ODD )
00858 str = "\\facingp{\\footerr";
00859 else if( footer.page == FooterData::PAGE_EVEN )
00860 str = "\\facingp{\\footerl";
00861 else if( footer.page == FooterData::PAGE_FIRST )
00862 str = "\\facingp{\\headerl";
00863 else if( footer.page == FooterData::PAGE_ALL )
00864 str = "{\\footer";
00865 else
00866 return false;
00867
00868 str += " {";
00869
00870 QValueList<ParaData>::ConstIterator it;
00871 QValueList<ParaData>::ConstIterator end(footer.para.end());
00872 for (it=footer.para.begin();it!=end;++it)
00873 content += ProcessParagraphData( (*it).text,(*it).layout,(*it).formattingList);
00874
00875 if (content!="\\par\\pard\\plain")
00876 {
00877 str += content;
00878 str += "}";
00879
00880 str += "}";
00881
00882 m_textBody += str;
00883 }
00884 m_prefix=QString::null;
00885 return true;
00886 }
00887
00888 bool RTFWorker::doOpenFile(const QString& filenameOut, const QString& )
00889 {
00890 m_ioDevice=new QFile(filenameOut);
00891
00892 if (!m_ioDevice)
00893 {
00894 kdError(30515) << "No output file! Aborting!" << endl;
00895 return false;
00896 }
00897
00898 if ( !m_ioDevice->open (IO_WriteOnly) )
00899 {
00900 kdError(30515) << "Unable to open output file!" << endl;
00901 return false;
00902 }
00903
00904 m_streamOut=new QTextStream(m_ioDevice);
00905
00906
00907 m_streamOut->setEncoding(QTextStream::Latin1);
00908
00909 m_fileName=filenameOut;
00910
00911 return true;
00912 }
00913
00914 bool RTFWorker::doCloseFile(void)
00915 {
00916 kdDebug(30515) << __FILE__ << ":" << __LINE__ << endl;
00917 delete m_streamOut;
00918 m_streamOut=NULL;
00919 if (m_ioDevice)
00920 m_ioDevice->close();
00921 return true;
00922 }
00923
00924 bool RTFWorker::doOpenDocument(void)
00925 {
00926
00927
00928
00929
00930 *m_streamOut << "{\\rtf1\\ansi\\ansicpg1252\\uc1\\deff0" << m_eol;
00931
00932
00933 m_colorList
00934 << QColor(0,0,0) << QColor(0,0,255) << QColor(0,255,255)
00935 << QColor(0,255,0) << QColor(255,0,255) << QColor(255,0,0)
00936 << QColor(255,255,0) << QColor(255,255,255) << QColor(0,0,128)
00937 << QColor(0,128,128) << QColor(0,128,0) << QColor(128,0,128)
00938 << QColor(128,0,0) << QColor(128,128,0) << QColor(128,128,128);
00939
00940 return true;
00941 }
00942
00943 void RTFWorker::writeFontData(void)
00944 {
00945 kdDebug(30515) << "Fonts:" << m_fontList << endl;
00946 *m_streamOut << "{\\fonttbl";
00947 uint count;
00948 QFontDatabase fontDatabase;
00949 QStringList::ConstIterator it;
00950 for (count=0, it=m_fontList.begin();
00951 it!=m_fontList.end();
00952 count++, it++)
00953 {
00954 const QString strLower( (*it).lower() );
00955 *m_streamOut << "{\\f" << count;
00956 if ( (strLower.find("symbol")>-1) || (strLower.find("dingbat")>-1) )
00957 *m_streamOut << "\\ftech";
00958 else if ( (strLower.find("script")>-1) )
00959 *m_streamOut << "\\fscript";
00960
00961 #if 1
00962 else
00963 {
00964
00965 *m_streamOut << "\\fnil";
00966 }
00967 #else
00968 else
00969
00970 {
00971 QFontInfo info(*it);
00972 switch (info.styleHint())
00973 {
00974 case QFont::SansSerif:
00975 default:
00976 {
00977 *m_streamOut << "\\fswiss";
00978 break;
00979 }
00980 case QFont::Serif:
00981 {
00982 *m_streamOut << "\\froman";
00983 break;
00984 }
00985 case QFont::Courier:
00986 {
00987 *m_streamOut << "\\fmodern";
00988 break;
00989 }
00990 case QFont::OldEnglish:
00991 {
00992 *m_streamOut << "\\fdecor";
00993 break;
00994 }
00995 }
00996 }
00997 #endif
00998
00999 *m_streamOut << "\\fprq" << ( fontDatabase.isFixedPitch( *it ) ? 1 : 2 ) << " ";
01000 *m_streamOut << escapeRtfText( *it );
01001 *m_streamOut << ";}" << m_eol;
01002 }
01003 *m_streamOut << "}";
01004 }
01005
01006 void RTFWorker::writeColorData(void)
01007 {
01008 *m_streamOut << "{\\colortbl;";
01009 uint count;
01010 QValueList<QColor>::ConstIterator it;
01011 for (count=0, it=m_colorList.begin();
01012 it!=m_colorList.end();
01013 count++, it++)
01014 {
01015 *m_streamOut << "\\red" << (*it).red();
01016 *m_streamOut << "\\green" << (*it).green();
01017 *m_streamOut << "\\blue" << (*it).blue();
01018 *m_streamOut << ";";
01019 }
01020 *m_streamOut << "}";
01021 }
01022
01023 void RTFWorker::writeStyleData(void)
01024 {
01025 *m_streamOut << "{\\stylesheet" << m_eol;
01026
01027 uint count;
01028 QValueList<LayoutData>::ConstIterator it;
01029 for (count=0, it=m_styleList.begin();
01030 it!=m_styleList.end();
01031 count++, it++)
01032 {
01033 *m_streamOut << "{";
01034 if (count>0)
01035 *m_streamOut << "\\s" << count;
01036
01037 *m_streamOut << layoutToRtf((*it),(*it),true);
01038
01039
01040
01041 uint counter=0;
01042 QValueList < LayoutData > ::ConstIterator it2;
01043 for( it2 = m_styleList.begin(); it2 != m_styleList.end(); counter++, ++it2 )
01044 {
01045 if ( (*it2).styleName == (*it).styleFollowing )
01046 {
01047 *m_streamOut << "\\snext" << counter;
01048 break;
01049 }
01050 }
01051
01052 *m_streamOut << " " << (*it).styleName << ";";
01053 *m_streamOut << "}";
01054 *m_streamOut << m_eol;
01055 }
01056
01057 *m_streamOut << "}";
01058 }
01059
01060 bool RTFWorker::doCloseDocument(void)
01061 {
01062
01063 writeFontData();
01064 writeColorData();
01065 writeStyleData();
01066
01067 if (!m_textDocInfo.isEmpty())
01068 {
01069 *m_streamOut << "{\\info ";
01070 *m_streamOut << m_textDocInfo;
01071 *m_streamOut << "}";
01072 }
01073 *m_streamOut << "\\paperw" << int(m_paperWidth);
01074 *m_streamOut << "\\paperh" << int(m_paperHeight);
01075 if (1==m_paperOrientation)
01076 *m_streamOut << "\\landscape";
01077 *m_streamOut << "\\margl" << int(m_paperMarginLeft);
01078 *m_streamOut << "\\margr" << int(m_paperMarginRight);
01079 *m_streamOut << "\\margt" << int(m_paperMarginTop);
01080 *m_streamOut << "\\margb" << int(m_paperMarginBottom);
01081 *m_streamOut << m_textPage;
01082 *m_streamOut << "\\widowctrl\\ftnbj\\aenddoc\\formshade \\fet0\\sectd\n";
01083 if (m_startPageNumber >= 1)
01084 *m_streamOut << "\\pgnstart" << m_startPageNumber << endl;
01085
01086 *m_streamOut << "\\pard\\plain";
01087 *m_streamOut << m_textBody;
01088
01089 *m_streamOut << "}" << m_eol;
01090 return true;
01091 }
01092
01093 bool RTFWorker::doFullDocumentInfo(const KWEFDocumentInfo& docInfo)
01094 {
01095
01096 if ( !docInfo.title.isEmpty() )
01097 {
01098 m_textDocInfo += "{\\title ";
01099 m_textDocInfo += escapeRtfText( docInfo.title );
01100 m_textDocInfo += "}";
01101 }
01102
01103 if ( !docInfo.fullName.isEmpty() )
01104 {
01105 m_textDocInfo += "{\\author ";
01106 m_textDocInfo += escapeRtfText( docInfo.fullName );
01107 m_textDocInfo += "}";
01108 }
01109
01110 if ( !docInfo.keywords.isEmpty() )
01111 {
01112 m_textDocInfo += "{\\keywords ";
01113 m_textDocInfo += escapeRtfText( docInfo.keywords );
01114 m_textDocInfo += "}";
01115 }
01116 if ( !docInfo.subject.isEmpty() )
01117 {
01118 m_textDocInfo += "{\\subject ";
01119 m_textDocInfo += escapeRtfText( docInfo.subject );
01120 m_textDocInfo += "}";
01121 }
01122
01123 if ( !docInfo.company.isEmpty() )
01124 {
01125 m_textDocInfo += "{\\company ";
01126 m_textDocInfo += escapeRtfText( docInfo.company );
01127 m_textDocInfo += "}";
01128 }
01129
01130
01131 QString revision("$Revision: 466447 $");
01132 m_textDocInfo += "{\\comment ";
01133 m_textDocInfo += "Generated by KWord's RTF Export Filter";
01134 m_textDocInfo += revision.mid(10).remove('$');
01135 m_textDocInfo += "}";
01136
01137 if ( !docInfo.abstract.isEmpty() )
01138 {
01139 m_textDocInfo += "{\\doccomm ";
01140 m_textDocInfo += escapeRtfText( docInfo.abstract );
01141 m_textDocInfo += "}";
01142 }
01143
01144 return true;
01145 }
01146
01147 bool RTFWorker::doOpenTextFrameSet(void)
01148 {
01149 return true;
01150 }
01151
01152 bool RTFWorker::doCloseTextFrameSet(void)
01153 {
01154 return true;
01155 }
01156
01157 QString RTFWorker::openSpan(const FormatData& formatOrigin, const FormatData& format)
01158 {
01159 QString result;
01160
01161 result += "{";
01162 result += textFormatToRtf(formatOrigin.text,format.text,false);
01163
01164 if ( 1==format.text.verticalAlignment )
01165 {
01166 result += "\\sub";
01167 }
01168 else if ( 2==format.text.verticalAlignment )
01169 {
01170 result += "\\super";
01171 }
01172
01173 result += " ";
01174 return result;
01175 }
01176
01177 QString RTFWorker::closeSpan(const FormatData& , const FormatData& )
01178 {
01179 QString result;
01180 result += "}";
01181 return result;
01182 }
01183
01184
01185
01186
01187 QString RTFWorker::escapeRtfText ( const QString& text ) const
01188 {
01189
01190 QString escapedText;
01191 const uint length = text.length();
01192 for ( uint i = 0; i < length; i++ )
01193 {
01194 QChar QCh ( text.at( i ) );
01195 const ushort ch = QCh.unicode();
01196
01197 if ( QCh == '\\' ) escapedText += "\\\\";
01198 else if ( QCh == '{' ) escapedText += "\\{";
01199 else if ( QCh == '}' ) escapedText += "\\}";
01200 else if ( ch >= 32 && ch <= 127)
01201 escapedText += QCh;
01202 else if ( ch == 0x0009 ) escapedText += "\\tab ";
01203 else if ( ch == 0x00a0 ) escapedText += "\\~";
01204 else if ( ch == 0x00ad ) escapedText += "\\-";
01205 else if ( ch == 0x00b7 ) escapedText += "\\|";
01206 else if ( ch == 0x2011 ) escapedText += "\\_";
01207 else if ( ch == 0x2002 ) escapedText += "\\enspace ";
01208 else if ( ch == 0x2003 ) escapedText += "\\emspace ";
01209 else if ( ch == 0x2004 ) escapedText += "\\qmspace ";
01210 else if ( ch == 0x200c ) escapedText += "\\zwnj ";
01211 else if ( ch == 0x200d ) escapedText += "\\zwj ";
01212 else if ( ch == 0x200e ) escapedText += "\\ltrmark ";
01213 else if ( ch == 0x200f ) escapedText += "\\rtlmark ";
01214 else if ( ch == 0x2013 ) escapedText += "\\endash ";
01215 else if ( ch == 0x2014 ) escapedText += "\\emdash ";
01216 else if ( ch == 0x2018 ) escapedText += "\\lquote ";
01217 else if ( ch == 0x2019 ) escapedText += "\\rquote ";
01218 else if ( ch == 0x201c ) escapedText += "\\ldblquote ";
01219 else if ( ch == 0x201d ) escapedText += "\\rdblquote ";
01220 else if ( ch == 0x2022 ) escapedText += "\\bullet ";
01221 else if ( ch >= 160 && ch < 256)
01222 {
01223 escapedText += "\\\'";
01224 escapedText += QString::number ( ch, 16 );
01225 }
01226 else if ( ch >= 256)
01227 {
01228
01229 escapedText += "\\u";
01230 escapedText += QString::number ( ch, 10 );
01231
01232
01233
01234 QChar replacement ( QCh.decomposition().at(0) );
01235 kdDebug(30515) << "Proposed replacement character: " << QString(replacement) << endl;
01236
01237 if (replacement.isNull() || replacement<=' ' || replacement>=char(127)
01238 || replacement=='{' || replacement=='}' || replacement=='\\')
01239 replacement='?';
01240
01241 escapedText += replacement;
01242
01243 }
01244 else
01245 escapedText += QCh ;
01246
01247 }
01248
01249 return escapedText;
01250
01251 }
01252
01253 bool RTFWorker::doFullPaperFormat(const int ,
01254 const double width, const double height, const int orientation)
01255 {
01256 m_paperWidth=width*20;
01257 m_paperHeight=height*20;
01258 m_paperOrientation=orientation;
01259 return true;
01260 }
01261
01262 bool RTFWorker::doFullPaperBorders (const double top, const double left,
01263 const double bottom, const double right)
01264 {
01265 m_paperMarginTop=top*20;
01266 m_paperMarginLeft=left*20;
01267 m_paperMarginBottom=bottom*20;
01268 m_paperMarginRight=right*20;
01269 return true;
01270 }
01271
01272 bool RTFWorker::doFullDefineStyle(LayoutData& layout)
01273 {
01274
01275 m_styleList << layout;
01276
01277
01278 lookupFont("\\f", layout.formatData.text.fontName);
01279 lookupColor(QString::null, layout.formatData.text.fgColor);
01280 lookupColor(QString::null, layout.formatData.text.bgColor);
01281
01282 return true;
01283 }
01284
01285 static QString writeDate(const QString keyword, const QDateTime& now)
01286 {
01287 QString str;
01288 if (now.isValid())
01289 {
01290 kdDebug(30515) << "Date " << keyword << " " << now.toString() << endl;
01291 str += '{';
01292 str += keyword;
01293 const QDate nowDate(now.date());
01294 str += "\\yr";
01295 str += QString::number(nowDate.year());
01296 str += "\\mo";
01297 str += QString::number(nowDate.month());
01298 str += "\\dy";
01299 str += QString::number(nowDate.day());
01300 const QTime nowTime(now.time());
01301 str += "\\hr";
01302 str += QString::number(nowTime.hour());
01303 str += "\\min";
01304 str += QString::number(nowTime.minute());
01305 str += "\\sec";
01306 str += QString::number(nowTime.second());
01307 str += '}';
01308 }
01309 else
01310 kdWarning(30515) << "Date " << keyword << " is not valid! Skipping!" << endl;
01311
01312 return str;
01313 }
01314
01315 bool RTFWorker::doVariableSettings(const VariableSettingsData& vs)
01316 {
01317 m_textDocInfo += writeDate("\\creatim",vs.creationTime);
01318 m_textDocInfo += writeDate("\\revtim", vs.modificationTime);
01319 m_textDocInfo += writeDate("\\printim",vs.printTime);
01320 m_startPageNumber = vs.startingPageNumber;
01321
01322 return true;
01323 }
01324
01325 QString RTFWorker::textFormatToRtf(const TextFormatting& formatOrigin,
01326 const TextFormatting& formatData, const bool force)
01327 {
01328
01329 QString strElement;
01330
01331
01332 const QString fontName(formatData.fontName);
01333 if (!fontName.isEmpty()
01334 && (force || (formatOrigin.fontName!=formatData.fontName)))
01335 {
01336 strElement+=lookupFont("\\f", fontName);
01337 }
01338
01339 if (force || (formatOrigin.fontSize!=formatData.fontSize))
01340 {
01341 const int size=formatData.fontSize;
01342 if (size>0)
01343 {
01344 strElement+="\\fs";
01345 strElement+=QString::number(2*size,10);
01346 }
01347 }
01348
01349 if (force || (formatOrigin.italic!=formatData.italic))
01350 {
01351
01352 if ( formatData.italic )
01353 {
01354 strElement+="\\i";
01355 }
01356 else
01357 {
01358 strElement+="\\i0";
01359 }
01360 }
01361
01362 if (force || ((formatOrigin.weight>=75)!=(formatData.weight>=75)))
01363 {
01364 if ( formatData.weight >= 75 )
01365 {
01366 strElement+="\\b";
01367 }
01368 else
01369 {
01370 strElement+="\\b0";
01371 }
01372 }
01373
01374 if (force || (formatOrigin.fgColor!=formatData.fgColor))
01375 {
01376 if ( formatData.fgColor.isValid() )
01377 {
01378 strElement+=lookupColor("\\cf", formatData.fgColor);
01379 }
01380 }
01381
01382 if (force || (formatOrigin.bgColor!=formatData.bgColor))
01383 {
01384 if ( formatData.bgColor.isValid() )
01385 {
01386 strElement+=lookupColor("\\cb", formatData.bgColor);
01387 strElement+=lookupColor("\\highlight", formatData.bgColor);
01388
01389 }
01390 }
01391
01392 if ( force
01393 || ( formatOrigin.underline != formatData.underline )
01394 || ( formatOrigin.underlineValue != formatData.underlineValue )
01395 || ( formatOrigin.underlineStyle != formatData.underlineStyle )
01396 || ( formatOrigin.underlineWord != formatData.underlineWord ) )
01397 {
01398 if ( formatData.underline )
01399 {
01400 QString underlineValue = formatData.underlineValue;
01401 QString underlineStyle = formatData.underlineStyle;
01402 bool underlineWord = formatData.underlineWord;
01403 QString ul ( "\\ul" );
01404
01405 if( underlineStyle.isEmpty() ) underlineStyle = "solid";
01406 if( underlineValue == "1" ) underlineValue = "single";
01407
01408 if( underlineValue == "double" )
01409 ul = "\\uldb";
01410 else if( underlineValue == "single-bold" )
01411 ul = "\\ulth";
01412 else if( underlineValue == "wave" )
01413 ul = "\\ulwave";
01414 else if( underlineValue == "single" )
01415 {
01416 if( underlineStyle == "dash" )
01417 ul = "\\uldash";
01418 else if( underlineStyle == "dot" )
01419 ul = "\\uld";
01420 else if( underlineStyle == "dashdot" )
01421 ul = "\\uldashd";
01422 else if( underlineStyle == "dashdotdot" )
01423 ul = "\\uldashdd";
01424 else if( underlineWord )
01425 ul = "\\ulw";
01426 };
01427
01428 strElement+= ul;
01429 if (formatData.underlineColor.isValid())
01430 {
01431 strElement+=lookupColor("\\ulc",formatData.underlineColor);
01432 }
01433 }
01434 else
01435 {
01436 strElement+="\\ul0";
01437 }
01438 }
01439
01440 if ( force
01441 || ( formatOrigin.strikeout != formatData.strikeout )
01442 || ( formatOrigin.strikeoutType != formatData.strikeoutType ) )
01443 {
01444 if ( formatData.strikeout )
01445 {
01446 if( formatData.strikeoutType == "double" )
01447 strElement+="\\striked1";
01448 else
01449 strElement+="\\strike";
01450 }
01451 else
01452 {
01453 strElement+="\\strike0";
01454 }
01455 }
01456
01457 return strElement;
01458 }
01459
01460 QString RTFWorker::layoutToRtf(const LayoutData& layoutOrigin,
01461 const LayoutData& layout, const bool force)
01462 {
01463 QString strLayout;
01464
01465
01466 if (force || (layoutOrigin.alignment!=layout.alignment))
01467 {
01468 if (layout.alignment=="left")
01469 strLayout += "\\ql";
01470 else if (layout.alignment== "right")
01471 strLayout += "\\qr";
01472 else if (layout.alignment=="center")
01473 strLayout += "\\qc";
01474 else if (layout.alignment=="justify")
01475 strLayout += "\\qj";
01476 else if ( layout.alignment=="auto")
01477 {
01478
01479
01480 }
01481 else
01482 {
01483 kdWarning(30515) << "Unknown alignment: " << layout.alignment << endl;
01484 }
01485 }
01486
01487 if ((layout.indentLeft>=0.0)
01488 && (force || (layoutOrigin.indentLeft!=layout.indentLeft)))
01489 {
01490 strLayout += "\\li";
01491 strLayout += QString::number(int(layout.indentLeft)*20, 10);
01492 }
01493
01494 if ((layout.indentRight>=0.0)
01495 && (force || (layoutOrigin.indentRight!=layout.indentRight)))
01496 {
01497 strLayout += "\\ri";
01498 strLayout += QString::number(int(layout.indentRight)*20, 10);
01499 }
01500
01501 if (force || (layoutOrigin.indentFirst!=layout.indentFirst))
01502 {
01503 strLayout += "\\fi";
01504 strLayout += QString::number(int(layout.indentFirst)*20, 10);
01505 }
01506
01507 if ((layout.marginBottom>=0.0)
01508 && (force || (layoutOrigin.marginBottom!=layout.marginBottom)))
01509 {
01510 strLayout += "\\sa";
01511 strLayout += QString::number(int(layout.marginBottom)*20 ,10);
01512 }
01513
01514 if ((layout.marginTop>=0.0)
01515 && (force || (layoutOrigin.marginTop!=layout.marginTop)))
01516 {
01517 strLayout += "\\sb";
01518 strLayout += QString::number(int(layout.marginTop)*20, 10);
01519 }
01520
01521 if (force || (layoutOrigin.keepLinesTogether!=layout.keepLinesTogether))
01522 {
01523 if(layout.keepLinesTogether) strLayout += "\\keep";
01524 }
01525
01526
01527
01528
01529
01530 #if 0
01531 if (force || (layoutOrigin.pageBreakBefore!=layout.pageBreakBefore))
01532 {
01533 if(layout.pageBreakBefore) strLayout += "\\pagebb";
01534 }
01535
01536
01537
01538 if (force || (layoutOrigin.pageBreakAfter!=layout.pageBreakAfter))
01539 {
01540 if(layout.pageBreakAfter) strLayout += "\\*\\pgbrk0";
01541 }
01542 #endif
01543
01544 if (force
01545 || ( layoutOrigin.lineSpacingType != layout.lineSpacingType )
01546 || ( layoutOrigin.lineSpacing != layout.lineSpacing ) )
01547 {
01548 if ( layout.lineSpacingType==LayoutData::LS_SINGLE )
01549 ;
01550
01551 else if ( layout.lineSpacingType==LayoutData::LS_ONEANDHALF )
01552 strLayout += "\\sl360\\slmult1";
01553
01554 else if ( layout.lineSpacingType==LayoutData::LS_DOUBLE )
01555 strLayout += "\\sl480\\slmult1";
01556
01557 else if ( layout.lineSpacingType==LayoutData::LS_ATLEAST )
01558 strLayout += QString("\\sl%1\\slmult0").arg(int(layout.lineSpacing)*20);
01559
01560 else if ( layout.lineSpacingType==LayoutData::LS_MULTIPLE )
01561 strLayout += QString("\\sl%1\\slmult1").arg( int(layout.lineSpacing)*240 );
01562
01563 else if ( layout.lineSpacingType==LayoutData::LS_CUSTOM )
01564
01565 strLayout += QString("\\sl-%1\\slmult0").arg(int(layout.lineSpacing)*20);
01566
01567 else
01568 kdWarning(30515) << "Unsupported lineSpacingType: " << layout.lineSpacingType << " (Ignoring!)" << endl;
01569 }
01570
01571 if (!layout.tabulatorList.isEmpty()
01572 && (force || (layoutOrigin.tabulatorList!=layout.tabulatorList) ))
01573 {
01574 TabulatorList::ConstIterator it;
01575 for (it=layout.tabulatorList.begin();it!=layout.tabulatorList.end();++it)
01576 {
01577 switch ((*it).m_type)
01578 {
01579 case 0: default: break;
01580 case 1: strLayout += "\\tqc"; break;
01581 case 2: strLayout += "\\tqr"; break;
01582 case 3: strLayout += "\\tqdec"; break;
01583 }
01584
01585 switch ((*it).m_filling)
01586 {
01587 case TabulatorData::TF_NONE: default: break;
01588 case TabulatorData::TF_DOT: strLayout += "\\tldot"; break;
01589 case TabulatorData::TF_LINE: strLayout += "\\tlul"; break;
01590
01591
01592 case TabulatorData::TF_DASH:
01593 case TabulatorData::TF_DASHDOT:
01594 case TabulatorData::TF_DASHDOTDOT:
01595 strLayout += "\\tlul"; break;
01596 }
01597
01598
01599 strLayout += "\\tx";
01600 strLayout += QString::number(int((*it).m_ptpos)*20, 10);
01601
01602 }
01603 }
01604
01605
01606
01607
01608 if( layout.shadowDistance > 0 )
01609 {
01610 strLayout += "\\shad";
01611 }
01612
01613
01614
01615
01616 strLayout+=textFormatToRtf(layoutOrigin.formatData.text,
01617 layout.formatData.text,force);
01618
01619 return strLayout;
01620 }
01621
01622
01623 QString RTFWorker::lookupFont(const QString& markup, const QString& fontName)
01624 {
01625 if (fontName.isEmpty())
01626 return QString::null;
01627
01628
01629 QString cookedFontName(fontName);
01630 QRegExp regexp("\\s*\\[\\S*\\]");
01631 cookedFontName.remove(regexp);
01632
01633 if (cookedFontName.isEmpty())
01634 cookedFontName=fontName;
01635
01636 kdDebug(30515) << "RTFWorker::lookupFont " << fontName << " cooked: " << cookedFontName << endl;
01637
01638 uint counter=0;
01639 QString strFont(markup);
01640 QStringList::ConstIterator it;
01641
01642
01643 for( it = m_fontList.begin(); it != m_fontList.end(); counter++, ++it )
01644 {
01645 if((*it) == cookedFontName)
01646 {
01647 strFont += QString::number(counter);
01648 kdDebug(30515) << strFont << endl;
01649 return strFont;
01650 }
01651 }
01652
01653 kdDebug(30515) << "New font: " << cookedFontName << " count: " << counter << endl;
01654 m_fontList << cookedFontName;
01655
01656 strFont += QString::number(counter);
01657 return strFont;
01658 }
01659
01660 QString RTFWorker::lookupColor(const QString& markup, const QColor& color)
01661 {
01662 if (!color.isValid())
01663 return QString::null;
01664
01665 uint counter=1;
01666 QString strColor(markup);
01667
01668 QValueList < QColor > ::ConstIterator it;
01669
01670
01671 for( it = m_colorList.begin(); it != m_colorList.end(); counter++, ++it )
01672 {
01673 if ( (*it) == color )
01674 {
01675 strColor += QString::number(counter);
01676 return strColor;
01677 }
01678 }
01679
01680 kdDebug(30515) << "New color: " << color.name() << " count: " << counter << endl;
01681 m_colorList << color;
01682
01683 strColor += QString::number(counter);
01684 return strColor;
01685 }
01686
01687 QString RTFWorker::lookupStyle(const QString& styleName, LayoutData& returnLayout)
01688 {
01689 if (styleName.isEmpty())
01690 return QString::null;
01691
01692 uint counter=0;
01693 QString strMarkup("\\s");
01694
01695 QValueList < LayoutData > ::ConstIterator it;
01696 QValueList < LayoutData > ::ConstIterator end(m_styleList.end());
01697
01698
01699 for( it = m_styleList.begin(); it != end; counter++, ++it )
01700 {
01701 if ( (*it).styleName == styleName )
01702 {
01703 strMarkup += QString::number(counter);
01704 returnLayout=(*it);
01705 return strMarkup;
01706 }
01707 }
01708
01709 kdDebug(30515) << "New style: " << styleName << " count: " << counter << endl;
01710 LayoutData layout;
01711 m_styleList << layout;
01712 returnLayout=layout;
01713
01714 strMarkup += QString::number(counter);
01715 return strMarkup;
01716 }