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 const QString prefixSaved = m_prefix;
00729 m_prefix = QString::null;
00730 for (it=paraList->begin();it!=end;++it)
00731 fstr += ProcessParagraphData( (*it).text, (*it).layout,(*it).formattingList);
00732 m_prefix = prefixSaved;
00733 content += "{\\super ";
00734 content += automatic ? "\\chftn " : value;
00735 content += "{\\footnote ";
00736 content += "{\\super ";
00737 content += automatic ? "\\chftn " : value;
00738 content += fstr;
00739 content += "}}}";
00740 }
00741 }
00742 else
00743 {
00744
00745 content += escapeRtfText((*paraFormatDataIt).variable.m_text);
00746 }
00747 }
00748 else if (6==(*paraFormatDataIt).id)
00749 {
00750 kdDebug(30515) << "Found an anchor of type: " << (*paraFormatDataIt).frameAnchor.type << endl;
00751
00752
00753 if (6==(*paraFormatDataIt).frameAnchor.type)
00754 {
00755
00756
00757 if (!content.isEmpty())
00758 {
00759 str += m_prefix;
00760 str += markup;
00761 str += " {";
00762 str += content;
00763 str += "}";
00764 str += m_eol;
00765 content = QString::null;
00766 if (!m_inTable)
00767 {
00768 m_prefix = "\\par";
00769 }
00770 }
00771 str += makeTable((*paraFormatDataIt).frameAnchor);
00772 }
00773 else if ((2==(*paraFormatDataIt).frameAnchor.type) || (5==(*paraFormatDataIt).frameAnchor.type))
00774 {
00775 content += makeImage((*paraFormatDataIt).frameAnchor);
00776
00777 }
00778 }
00779 }
00780 }
00781
00782 if (layout.pageBreakAfter)
00783 content += "\\page";
00784
00785 if (!content.isEmpty())
00786 {
00787 str += m_prefix;
00788 str += markup;
00789 str += " {";
00790 str += content;
00791 str += "}";
00792 str += m_eol;
00793 if (m_inTable==false)
00794 {
00795 m_prefix = "\\par";
00796 }
00797 }
00798 if (str.isEmpty())
00799 {
00800 str ="\\par\\pard\\plain";
00801 if (m_inTable==false)
00802 {
00803 m_prefix = "\\par";
00804 }
00805 }
00806 return str;
00807 }
00808
00809 bool RTFWorker::doFullParagraph(const QString& paraText,
00810 const LayoutData& layout, const ValueListFormatData& paraFormatDataList)
00811 {
00812 kdDebug(30515) << "Entering RTFWorker::doFullParagraph" << endl << paraText << endl;
00813 QString par = ProcessParagraphData( paraText, layout, paraFormatDataList);
00814 m_textBody += par;
00815 kdDebug(30515) << "Quiting RTFWorker::doFullParagraph" << endl;
00816 return true;
00817 }
00818
00819 bool RTFWorker::doHeader(const HeaderData& header)
00820 {
00821 QString str;
00822 QString content;
00823 if( header.page == HeaderData::PAGE_ODD )
00824 str = "\\facingp{\\headerr";
00825 else if( header.page == HeaderData::PAGE_EVEN )
00826 str = "\\facingp{\\headerl";
00827 else if( header.page == HeaderData::PAGE_FIRST )
00828 str = "\\facingp{\\headerl";
00829 else if( header.page == HeaderData::PAGE_ALL )
00830 str = "{\\header";
00831 else
00832 return false;
00833
00834 str += " {";
00835
00836 QValueList<ParaData>::ConstIterator it;
00837 QValueList<ParaData>::ConstIterator end(header.para.end());
00838 for (it=header.para.begin();it!=end;++it)
00839 content += ProcessParagraphData( (*it).text,(*it).layout,(*it).formattingList);
00840
00841 if (content!="\\par\\pard\\plain")
00842 {
00843 str += content;
00844 str += "}";
00845
00846 str += "}";
00847
00848 m_textBody += str;
00849 }
00850 m_prefix=QString::null;
00851 return true;
00852 }
00853
00854 bool RTFWorker::doFooter(const FooterData& footer)
00855 {
00856 QString str;
00857 QString content;
00858 if( footer.page == FooterData::PAGE_ODD )
00859 str = "\\facingp{\\footerr";
00860 else if( footer.page == FooterData::PAGE_EVEN )
00861 str = "\\facingp{\\footerl";
00862 else if( footer.page == FooterData::PAGE_FIRST )
00863 str = "\\facingp{\\headerl";
00864 else if( footer.page == FooterData::PAGE_ALL )
00865 str = "{\\footer";
00866 else
00867 return false;
00868
00869 str += " {";
00870
00871 QValueList<ParaData>::ConstIterator it;
00872 QValueList<ParaData>::ConstIterator end(footer.para.end());
00873 for (it=footer.para.begin();it!=end;++it)
00874 content += ProcessParagraphData( (*it).text,(*it).layout,(*it).formattingList);
00875
00876 if (content!="\\par\\pard\\plain")
00877 {
00878 str += content;
00879 str += "}";
00880
00881 str += "}";
00882
00883 m_textBody += str;
00884 }
00885 m_prefix=QString::null;
00886 return true;
00887 }
00888
00889 bool RTFWorker::doOpenFile(const QString& filenameOut, const QString& )
00890 {
00891 m_ioDevice=new QFile(filenameOut);
00892
00893 if (!m_ioDevice)
00894 {
00895 kdError(30515) << "No output file! Aborting!" << endl;
00896 return false;
00897 }
00898
00899 if ( !m_ioDevice->open (IO_WriteOnly) )
00900 {
00901 kdError(30515) << "Unable to open output file!" << endl;
00902 return false;
00903 }
00904
00905 m_streamOut=new QTextStream(m_ioDevice);
00906
00907
00908 m_streamOut->setEncoding(QTextStream::Latin1);
00909
00910 m_fileName=filenameOut;
00911
00912 return true;
00913 }
00914
00915 bool RTFWorker::doCloseFile(void)
00916 {
00917 kdDebug(30515) << __FILE__ << ":" << __LINE__ << endl;
00918 delete m_streamOut;
00919 m_streamOut=NULL;
00920 if (m_ioDevice)
00921 m_ioDevice->close();
00922 return true;
00923 }
00924
00925 bool RTFWorker::doOpenDocument(void)
00926 {
00927
00928
00929
00930
00931 *m_streamOut << "{\\rtf1\\ansi\\ansicpg1252\\uc1\\deff0" << m_eol;
00932
00933
00934 m_colorList
00935 << QColor(0,0,0) << QColor(0,0,255) << QColor(0,255,255)
00936 << QColor(0,255,0) << QColor(255,0,255) << QColor(255,0,0)
00937 << QColor(255,255,0) << QColor(255,255,255) << QColor(0,0,128)
00938 << QColor(0,128,128) << QColor(0,128,0) << QColor(128,0,128)
00939 << QColor(128,0,0) << QColor(128,128,0) << QColor(128,128,128);
00940
00941 return true;
00942 }
00943
00944 void RTFWorker::writeFontData(void)
00945 {
00946 kdDebug(30515) << "Fonts:" << m_fontList << endl;
00947 *m_streamOut << "{\\fonttbl";
00948 uint count;
00949 QFontDatabase fontDatabase;
00950 QStringList::ConstIterator it;
00951 for (count=0, it=m_fontList.begin();
00952 it!=m_fontList.end();
00953 count++, it++)
00954 {
00955 const QString strLower( (*it).lower() );
00956 *m_streamOut << "{\\f" << count;
00957 if ( (strLower.find("symbol")>-1) || (strLower.find("dingbat")>-1) )
00958 *m_streamOut << "\\ftech";
00959 else if ( (strLower.find("script")>-1) )
00960 *m_streamOut << "\\fscript";
00961
00962 #if 1
00963 else
00964 {
00965
00966 *m_streamOut << "\\fnil";
00967 }
00968 #else
00969 else
00970
00971 {
00972 QFontInfo info(*it);
00973 switch (info.styleHint())
00974 {
00975 case QFont::SansSerif:
00976 default:
00977 {
00978 *m_streamOut << "\\fswiss";
00979 break;
00980 }
00981 case QFont::Serif:
00982 {
00983 *m_streamOut << "\\froman";
00984 break;
00985 }
00986 case QFont::Courier:
00987 {
00988 *m_streamOut << "\\fmodern";
00989 break;
00990 }
00991 case QFont::OldEnglish:
00992 {
00993 *m_streamOut << "\\fdecor";
00994 break;
00995 }
00996 }
00997 }
00998 #endif
00999
01000 *m_streamOut << "\\fprq" << ( fontDatabase.isFixedPitch( *it ) ? 1 : 2 ) << " ";
01001 *m_streamOut << escapeRtfText( *it );
01002 *m_streamOut << ";}" << m_eol;
01003 }
01004 *m_streamOut << "}";
01005 }
01006
01007 void RTFWorker::writeColorData(void)
01008 {
01009 *m_streamOut << "{\\colortbl;";
01010 uint count;
01011 QValueList<QColor>::ConstIterator it;
01012 for (count=0, it=m_colorList.begin();
01013 it!=m_colorList.end();
01014 count++, it++)
01015 {
01016 *m_streamOut << "\\red" << (*it).red();
01017 *m_streamOut << "\\green" << (*it).green();
01018 *m_streamOut << "\\blue" << (*it).blue();
01019 *m_streamOut << ";";
01020 }
01021 *m_streamOut << "}";
01022 }
01023
01024 void RTFWorker::writeStyleData(void)
01025 {
01026 *m_streamOut << "{\\stylesheet" << m_eol;
01027
01028 uint count;
01029 QValueList<LayoutData>::ConstIterator it;
01030 for (count=0, it=m_styleList.begin();
01031 it!=m_styleList.end();
01032 count++, it++)
01033 {
01034 *m_streamOut << "{";
01035 if (count>0)
01036 *m_streamOut << "\\s" << count;
01037
01038 *m_streamOut << layoutToRtf((*it),(*it),true);
01039
01040
01041
01042 uint counter=0;
01043 QValueList < LayoutData > ::ConstIterator it2;
01044 for( it2 = m_styleList.begin(); it2 != m_styleList.end(); counter++, ++it2 )
01045 {
01046 if ( (*it2).styleName == (*it).styleFollowing )
01047 {
01048 *m_streamOut << "\\snext" << counter;
01049 break;
01050 }
01051 }
01052
01053 *m_streamOut << " " << (*it).styleName << ";";
01054 *m_streamOut << "}";
01055 *m_streamOut << m_eol;
01056 }
01057
01058 *m_streamOut << "}";
01059 }
01060
01061 bool RTFWorker::doCloseDocument(void)
01062 {
01063
01064 writeFontData();
01065 writeColorData();
01066 writeStyleData();
01067
01068 if (!m_textDocInfo.isEmpty())
01069 {
01070 *m_streamOut << "{\\info ";
01071 *m_streamOut << m_textDocInfo;
01072 *m_streamOut << "}";
01073 }
01074 *m_streamOut << "\\paperw" << int(m_paperWidth);
01075 *m_streamOut << "\\paperh" << int(m_paperHeight);
01076 if (1==m_paperOrientation)
01077 *m_streamOut << "\\landscape";
01078 *m_streamOut << "\\margl" << int(m_paperMarginLeft);
01079 *m_streamOut << "\\margr" << int(m_paperMarginRight);
01080 *m_streamOut << "\\margt" << int(m_paperMarginTop);
01081 *m_streamOut << "\\margb" << int(m_paperMarginBottom);
01082 *m_streamOut << m_textPage;
01083 *m_streamOut << "\\widowctrl\\ftnbj\\aenddoc\\formshade \\fet0\\sectd\n";
01084 if (m_startPageNumber >= 1)
01085 *m_streamOut << "\\pgnstart" << m_startPageNumber << endl;
01086
01087 *m_streamOut << "\\pard\\plain";
01088 *m_streamOut << m_textBody;
01089
01090 *m_streamOut << "}" << m_eol;
01091 return true;
01092 }
01093
01094 bool RTFWorker::doFullDocumentInfo(const KWEFDocumentInfo& docInfo)
01095 {
01096
01097 if ( !docInfo.title.isEmpty() )
01098 {
01099 m_textDocInfo += "{\\title ";
01100 m_textDocInfo += escapeRtfText( docInfo.title );
01101 m_textDocInfo += "}";
01102 }
01103
01104 if ( !docInfo.fullName.isEmpty() )
01105 {
01106 m_textDocInfo += "{\\author ";
01107 m_textDocInfo += escapeRtfText( docInfo.fullName );
01108 m_textDocInfo += "}";
01109 }
01110
01111 if ( !docInfo.keywords.isEmpty() )
01112 {
01113 m_textDocInfo += "{\\keywords ";
01114 m_textDocInfo += escapeRtfText( docInfo.keywords );
01115 m_textDocInfo += "}";
01116 }
01117 if ( !docInfo.subject.isEmpty() )
01118 {
01119 m_textDocInfo += "{\\subject ";
01120 m_textDocInfo += escapeRtfText( docInfo.subject );
01121 m_textDocInfo += "}";
01122 }
01123
01124 if ( !docInfo.company.isEmpty() )
01125 {
01126 m_textDocInfo += "{\\company ";
01127 m_textDocInfo += escapeRtfText( docInfo.company );
01128 m_textDocInfo += "}";
01129 }
01130
01131
01132 QString revision("$Revision: 549975 $");
01133 m_textDocInfo += "{\\comment ";
01134 m_textDocInfo += "Generated by KWord's RTF Export Filter";
01135 m_textDocInfo += revision.mid(10).remove('$');
01136 m_textDocInfo += "}";
01137
01138 if ( !docInfo.abstract.isEmpty() )
01139 {
01140 m_textDocInfo += "{\\doccomm ";
01141 m_textDocInfo += escapeRtfText( docInfo.abstract );
01142 m_textDocInfo += "}";
01143 }
01144
01145 return true;
01146 }
01147
01148 bool RTFWorker::doOpenTextFrameSet(void)
01149 {
01150 return true;
01151 }
01152
01153 bool RTFWorker::doCloseTextFrameSet(void)
01154 {
01155 return true;
01156 }
01157
01158 QString RTFWorker::openSpan(const FormatData& formatOrigin, const FormatData& format)
01159 {
01160 QString result;
01161
01162 result += "{";
01163 result += textFormatToRtf(formatOrigin.text,format.text,false);
01164
01165 if ( 1==format.text.verticalAlignment )
01166 {
01167 result += "\\sub";
01168 }
01169 else if ( 2==format.text.verticalAlignment )
01170 {
01171 result += "\\super";
01172 }
01173
01174 result += " ";
01175 return result;
01176 }
01177
01178 QString RTFWorker::closeSpan(const FormatData& , const FormatData& )
01179 {
01180 QString result;
01181 result += "}";
01182 return result;
01183 }
01184
01185
01186
01187
01188 QString RTFWorker::escapeRtfText ( const QString& text ) const
01189 {
01190
01191 QString escapedText;
01192 const uint length = text.length();
01193 for ( uint i = 0; i < length; i++ )
01194 {
01195 QChar QCh ( text.at( i ) );
01196 const ushort ch = QCh.unicode();
01197
01198 if ( QCh == '\\' ) escapedText += "\\\\";
01199 else if ( QCh == '{' ) escapedText += "\\{";
01200 else if ( QCh == '}' ) escapedText += "\\}";
01201 else if ( ch >= 32 && ch <= 127)
01202 escapedText += QCh;
01203 else if ( ch == 0x0009 ) escapedText += "\\tab ";
01204 else if ( ch == 0x00a0 ) escapedText += "\\~";
01205 else if ( ch == 0x00ad ) escapedText += "\\-";
01206 else if ( ch == 0x00b7 ) escapedText += "\\|";
01207 else if ( ch == 0x2011 ) escapedText += "\\_";
01208 else if ( ch == 0x2002 ) escapedText += "\\enspace ";
01209 else if ( ch == 0x2003 ) escapedText += "\\emspace ";
01210 else if ( ch == 0x2004 ) escapedText += "\\qmspace ";
01211 else if ( ch == 0x200c ) escapedText += "\\zwnj ";
01212 else if ( ch == 0x200d ) escapedText += "\\zwj ";
01213 else if ( ch == 0x200e ) escapedText += "\\ltrmark ";
01214 else if ( ch == 0x200f ) escapedText += "\\rtlmark ";
01215 else if ( ch == 0x2013 ) escapedText += "\\endash ";
01216 else if ( ch == 0x2014 ) escapedText += "\\emdash ";
01217 else if ( ch == 0x2018 ) escapedText += "\\lquote ";
01218 else if ( ch == 0x2019 ) escapedText += "\\rquote ";
01219 else if ( ch == 0x201c ) escapedText += "\\ldblquote ";
01220 else if ( ch == 0x201d ) escapedText += "\\rdblquote ";
01221 else if ( ch == 0x2022 ) escapedText += "\\bullet ";
01222 else if ( ch >= 160 && ch < 256)
01223 {
01224 escapedText += "\\\'";
01225 escapedText += QString::number ( ch, 16 );
01226 }
01227 else if ( ch >= 256)
01228 {
01229
01230 escapedText += "\\u";
01231 escapedText += QString::number ( ch, 10 );
01232
01233
01234
01235 QChar replacement ( QCh.decomposition().at(0) );
01236 kdDebug(30515) << "Proposed replacement character: " << QString(replacement) << endl;
01237
01238 if (replacement.isNull() || replacement<=' ' || replacement>=char(127)
01239 || replacement=='{' || replacement=='}' || replacement=='\\')
01240 replacement='?';
01241
01242 escapedText += replacement;
01243
01244 }
01245 else
01246 escapedText += QCh ;
01247
01248 }
01249
01250 return escapedText;
01251
01252 }
01253
01254 bool RTFWorker::doFullPaperFormat(const int ,
01255 const double width, const double height, const int orientation)
01256 {
01257 m_paperWidth=width*20;
01258 m_paperHeight=height*20;
01259 m_paperOrientation=orientation;
01260 return true;
01261 }
01262
01263 bool RTFWorker::doFullPaperBorders (const double top, const double left,
01264 const double bottom, const double right)
01265 {
01266 m_paperMarginTop=top*20;
01267 m_paperMarginLeft=left*20;
01268 m_paperMarginBottom=bottom*20;
01269 m_paperMarginRight=right*20;
01270 return true;
01271 }
01272
01273 bool RTFWorker::doFullDefineStyle(LayoutData& layout)
01274 {
01275
01276 m_styleList << layout;
01277
01278
01279 lookupFont("\\f", layout.formatData.text.fontName);
01280 lookupColor(QString::null, layout.formatData.text.fgColor);
01281 lookupColor(QString::null, layout.formatData.text.bgColor);
01282
01283 return true;
01284 }
01285
01286 static QString writeDate(const QString keyword, const QDateTime& now)
01287 {
01288 QString str;
01289 if (now.isValid())
01290 {
01291 kdDebug(30515) << "Date " << keyword << " " << now.toString() << endl;
01292 str += '{';
01293 str += keyword;
01294 const QDate nowDate(now.date());
01295 str += "\\yr";
01296 str += QString::number(nowDate.year());
01297 str += "\\mo";
01298 str += QString::number(nowDate.month());
01299 str += "\\dy";
01300 str += QString::number(nowDate.day());
01301 const QTime nowTime(now.time());
01302 str += "\\hr";
01303 str += QString::number(nowTime.hour());
01304 str += "\\min";
01305 str += QString::number(nowTime.minute());
01306 str += "\\sec";
01307 str += QString::number(nowTime.second());
01308 str += '}';
01309 }
01310 else
01311 kdWarning(30515) << "Date " << keyword << " is not valid! Skipping!" << endl;
01312
01313 return str;
01314 }
01315
01316 bool RTFWorker::doVariableSettings(const VariableSettingsData& vs)
01317 {
01318 m_textDocInfo += writeDate("\\creatim",vs.creationTime);
01319 m_textDocInfo += writeDate("\\revtim", vs.modificationTime);
01320 m_textDocInfo += writeDate("\\printim",vs.printTime);
01321 m_startPageNumber = vs.startingPageNumber;
01322
01323 return true;
01324 }
01325
01326 QString RTFWorker::textFormatToRtf(const TextFormatting& formatOrigin,
01327 const TextFormatting& formatData, const bool force)
01328 {
01329
01330 QString strElement;
01331
01332
01333 const QString fontName(formatData.fontName);
01334 if (!fontName.isEmpty()
01335 && (force || (formatOrigin.fontName!=formatData.fontName)))
01336 {
01337 strElement+=lookupFont("\\f", fontName);
01338 }
01339
01340 if (force || (formatOrigin.fontSize!=formatData.fontSize))
01341 {
01342 const int size=formatData.fontSize;
01343 if (size>0)
01344 {
01345 strElement+="\\fs";
01346 strElement+=QString::number(2*size,10);
01347 }
01348 }
01349
01350 if (force || (formatOrigin.italic!=formatData.italic))
01351 {
01352
01353 if ( formatData.italic )
01354 {
01355 strElement+="\\i";
01356 }
01357 else
01358 {
01359 strElement+="\\i0";
01360 }
01361 }
01362
01363 if (force || ((formatOrigin.weight>=75)!=(formatData.weight>=75)))
01364 {
01365 if ( formatData.weight >= 75 )
01366 {
01367 strElement+="\\b";
01368 }
01369 else
01370 {
01371 strElement+="\\b0";
01372 }
01373 }
01374
01375 if (force || (formatOrigin.fgColor!=formatData.fgColor))
01376 {
01377 if ( formatData.fgColor.isValid() )
01378 {
01379 strElement+=lookupColor("\\cf", formatData.fgColor);
01380 }
01381 }
01382
01383 if (force || (formatOrigin.bgColor!=formatData.bgColor))
01384 {
01385 if ( formatData.bgColor.isValid() )
01386 {
01387 strElement+=lookupColor("\\cb", formatData.bgColor);
01388 strElement+=lookupColor("\\highlight", formatData.bgColor);
01389
01390 }
01391 }
01392
01393 if ( force
01394 || ( formatOrigin.underline != formatData.underline )
01395 || ( formatOrigin.underlineValue != formatData.underlineValue )
01396 || ( formatOrigin.underlineStyle != formatData.underlineStyle )
01397 || ( formatOrigin.underlineWord != formatData.underlineWord ) )
01398 {
01399 if ( formatData.underline )
01400 {
01401 QString underlineValue = formatData.underlineValue;
01402 QString underlineStyle = formatData.underlineStyle;
01403 bool underlineWord = formatData.underlineWord;
01404 QString ul ( "\\ul" );
01405
01406 if( underlineStyle.isEmpty() ) underlineStyle = "solid";
01407 if( underlineValue == "1" ) underlineValue = "single";
01408
01409 if( underlineValue == "double" )
01410 ul = "\\uldb";
01411 else if( underlineValue == "single-bold" )
01412 ul = "\\ulth";
01413 else if( underlineValue == "wave" )
01414 ul = "\\ulwave";
01415 else if( underlineValue == "single" )
01416 {
01417 if( underlineStyle == "dash" )
01418 ul = "\\uldash";
01419 else if( underlineStyle == "dot" )
01420 ul = "\\uld";
01421 else if( underlineStyle == "dashdot" )
01422 ul = "\\uldashd";
01423 else if( underlineStyle == "dashdotdot" )
01424 ul = "\\uldashdd";
01425 else if( underlineWord )
01426 ul = "\\ulw";
01427 };
01428
01429 strElement+= ul;
01430 if (formatData.underlineColor.isValid())
01431 {
01432 strElement+=lookupColor("\\ulc",formatData.underlineColor);
01433 }
01434 }
01435 else
01436 {
01437 strElement+="\\ul0";
01438 }
01439 }
01440
01441 if ( force
01442 || ( formatOrigin.strikeout != formatData.strikeout )
01443 || ( formatOrigin.strikeoutType != formatData.strikeoutType ) )
01444 {
01445 if ( formatData.strikeout )
01446 {
01447 if( formatData.strikeoutType == "double" )
01448 strElement+="\\striked1";
01449 else
01450 strElement+="\\strike";
01451 }
01452 else
01453 {
01454 strElement+="\\strike0";
01455 }
01456 }
01457
01458 return strElement;
01459 }
01460
01461 QString RTFWorker::layoutToRtf(const LayoutData& layoutOrigin,
01462 const LayoutData& layout, const bool force)
01463 {
01464 QString strLayout;
01465
01466
01467 if (force || (layoutOrigin.alignment!=layout.alignment))
01468 {
01469 if (layout.alignment=="left")
01470 strLayout += "\\ql";
01471 else if (layout.alignment== "right")
01472 strLayout += "\\qr";
01473 else if (layout.alignment=="center")
01474 strLayout += "\\qc";
01475 else if (layout.alignment=="justify")
01476 strLayout += "\\qj";
01477 else if ( layout.alignment=="auto")
01478 {
01479
01480
01481 }
01482 else
01483 {
01484 kdWarning(30515) << "Unknown alignment: " << layout.alignment << endl;
01485 }
01486 }
01487
01488 if ((layout.indentLeft>=0.0)
01489 && (force || (layoutOrigin.indentLeft!=layout.indentLeft)))
01490 {
01491 strLayout += "\\li";
01492 strLayout += QString::number(int(layout.indentLeft)*20, 10);
01493 }
01494
01495 if ((layout.indentRight>=0.0)
01496 && (force || (layoutOrigin.indentRight!=layout.indentRight)))
01497 {
01498 strLayout += "\\ri";
01499 strLayout += QString::number(int(layout.indentRight)*20, 10);
01500 }
01501
01502 if (force || (layoutOrigin.indentFirst!=layout.indentFirst))
01503 {
01504 strLayout += "\\fi";
01505 strLayout += QString::number(int(layout.indentFirst)*20, 10);
01506 }
01507
01508 if ((layout.marginBottom>=0.0)
01509 && (force || (layoutOrigin.marginBottom!=layout.marginBottom)))
01510 {
01511 strLayout += "\\sa";
01512 strLayout += QString::number(int(layout.marginBottom)*20 ,10);
01513 }
01514
01515 if ((layout.marginTop>=0.0)
01516 && (force || (layoutOrigin.marginTop!=layout.marginTop)))
01517 {
01518 strLayout += "\\sb";
01519 strLayout += QString::number(int(layout.marginTop)*20, 10);
01520 }
01521
01522 if (force || (layoutOrigin.keepLinesTogether!=layout.keepLinesTogether))
01523 {
01524 if(layout.keepLinesTogether) strLayout += "\\keep";
01525 }
01526
01527
01528
01529
01530
01531 #if 0
01532 if (force || (layoutOrigin.pageBreakBefore!=layout.pageBreakBefore))
01533 {
01534 if(layout.pageBreakBefore) strLayout += "\\pagebb";
01535 }
01536
01537
01538
01539 if (force || (layoutOrigin.pageBreakAfter!=layout.pageBreakAfter))
01540 {
01541 if(layout.pageBreakAfter) strLayout += "\\*\\pgbrk0";
01542 }
01543 #endif
01544
01545 if (force
01546 || ( layoutOrigin.lineSpacingType != layout.lineSpacingType )
01547 || ( layoutOrigin.lineSpacing != layout.lineSpacing ) )
01548 {
01549 if ( layout.lineSpacingType==LayoutData::LS_SINGLE )
01550 ;
01551
01552 else if ( layout.lineSpacingType==LayoutData::LS_ONEANDHALF )
01553 strLayout += "\\sl360\\slmult1";
01554
01555 else if ( layout.lineSpacingType==LayoutData::LS_DOUBLE )
01556 strLayout += "\\sl480\\slmult1";
01557
01558 else if ( layout.lineSpacingType==LayoutData::LS_ATLEAST )
01559 strLayout += QString("\\sl%1\\slmult0").arg(int(layout.lineSpacing)*20);
01560
01561 else if ( layout.lineSpacingType==LayoutData::LS_MULTIPLE )
01562 strLayout += QString("\\sl%1\\slmult1").arg( int(layout.lineSpacing)*240 );
01563
01564 else if ( layout.lineSpacingType==LayoutData::LS_CUSTOM )
01565
01566 strLayout += QString("\\sl-%1\\slmult0").arg(int(layout.lineSpacing)*20);
01567
01568 else
01569 kdWarning(30515) << "Unsupported lineSpacingType: " << layout.lineSpacingType << " (Ignoring!)" << endl;
01570 }
01571
01572 if (!layout.tabulatorList.isEmpty()
01573 && (force || (layoutOrigin.tabulatorList!=layout.tabulatorList) ))
01574 {
01575 TabulatorList::ConstIterator it;
01576 for (it=layout.tabulatorList.begin();it!=layout.tabulatorList.end();++it)
01577 {
01578 switch ((*it).m_type)
01579 {
01580 case 0: default: break;
01581 case 1: strLayout += "\\tqc"; break;
01582 case 2: strLayout += "\\tqr"; break;
01583 case 3: strLayout += "\\tqdec"; break;
01584 }
01585
01586 switch ((*it).m_filling)
01587 {
01588 case TabulatorData::TF_NONE: default: break;
01589 case TabulatorData::TF_DOT: strLayout += "\\tldot"; break;
01590 case TabulatorData::TF_LINE: strLayout += "\\tlul"; break;
01591
01592
01593 case TabulatorData::TF_DASH:
01594 case TabulatorData::TF_DASHDOT:
01595 case TabulatorData::TF_DASHDOTDOT:
01596 strLayout += "\\tlul"; break;
01597 }
01598
01599
01600 strLayout += "\\tx";
01601 strLayout += QString::number(int((*it).m_ptpos)*20, 10);
01602
01603 }
01604 }
01605
01606
01607
01608
01609 if( layout.shadowDistance > 0 )
01610 {
01611 strLayout += "\\shad";
01612 }
01613
01614
01615
01616
01617 strLayout+=textFormatToRtf(layoutOrigin.formatData.text,
01618 layout.formatData.text,force);
01619
01620 return strLayout;
01621 }
01622
01623
01624 QString RTFWorker::lookupFont(const QString& markup, const QString& fontName)
01625 {
01626 if (fontName.isEmpty())
01627 return QString::null;
01628
01629
01630 QString cookedFontName(fontName);
01631 QRegExp regexp("\\s*\\[\\S*\\]");
01632 cookedFontName.remove(regexp);
01633
01634 if (cookedFontName.isEmpty())
01635 cookedFontName=fontName;
01636
01637 kdDebug(30515) << "RTFWorker::lookupFont " << fontName << " cooked: " << cookedFontName << endl;
01638
01639 uint counter=0;
01640 QString strFont(markup);
01641 QStringList::ConstIterator it;
01642
01643
01644 for( it = m_fontList.begin(); it != m_fontList.end(); counter++, ++it )
01645 {
01646 if((*it) == cookedFontName)
01647 {
01648 strFont += QString::number(counter);
01649 kdDebug(30515) << strFont << endl;
01650 return strFont;
01651 }
01652 }
01653
01654 kdDebug(30515) << "New font: " << cookedFontName << " count: " << counter << endl;
01655 m_fontList << cookedFontName;
01656
01657 strFont += QString::number(counter);
01658 return strFont;
01659 }
01660
01661 QString RTFWorker::lookupColor(const QString& markup, const QColor& color)
01662 {
01663 if (!color.isValid())
01664 return QString::null;
01665
01666 uint counter=1;
01667 QString strColor(markup);
01668
01669 QValueList < QColor > ::ConstIterator it;
01670
01671
01672 for( it = m_colorList.begin(); it != m_colorList.end(); counter++, ++it )
01673 {
01674 if ( (*it) == color )
01675 {
01676 strColor += QString::number(counter);
01677 return strColor;
01678 }
01679 }
01680
01681 kdDebug(30515) << "New color: " << color.name() << " count: " << counter << endl;
01682 m_colorList << color;
01683
01684 strColor += QString::number(counter);
01685 return strColor;
01686 }
01687
01688 QString RTFWorker::lookupStyle(const QString& styleName, LayoutData& returnLayout)
01689 {
01690 if (styleName.isEmpty())
01691 return QString::null;
01692
01693 uint counter=0;
01694 QString strMarkup("\\s");
01695
01696 QValueList < LayoutData > ::ConstIterator it;
01697 QValueList < LayoutData > ::ConstIterator end(m_styleList.end());
01698
01699
01700 for( it = m_styleList.begin(); it != end; counter++, ++it )
01701 {
01702 if ( (*it).styleName == styleName )
01703 {
01704 strMarkup += QString::number(counter);
01705 returnLayout=(*it);
01706 return strMarkup;
01707 }
01708 }
01709
01710 kdDebug(30515) << "New style: " << styleName << " count: " << counter << endl;
01711 LayoutData layout;
01712 m_styleList << layout;
01713 returnLayout=layout;
01714
01715 strMarkup += QString::number(counter);
01716 return strMarkup;
01717 }