24#include <tqtextcodec.h>
26#include <tqfileinfo.h>
27#include <tqfontinfo.h>
28#include <tqfontdatabase.h>
33#include <tqdatetime.h>
40#include <KWEFBaseWorker.h>
42#include "ExportFilter.h"
48#define TWIP_TO_MM(x) (x)*25.4/1440.0
49#define MM_TO_TWIP(x) (x)*1440.0/25.4
50#define PT_TO_TWIP(x) (x)*20
51#define TWIP_TO_PT(x) (x)/20
55static TQString mapFieldName(
const TQString& kwordField )
59 if( kwordField ==
"fileName" ) rtfField =
"FILENAME";
60 else if( kwordField ==
"authorName" ) rtfField =
"AUTHOR";
61 else if( kwordField ==
"docTitle" ) rtfField =
"TITLE";
66RTFWorker::RTFWorker():
67 m_ioDevice(NULL), m_streamOut(NULL), m_eol(
"\r\n"), m_inTable(false),
68 m_paperOrientation(false), m_paperWidth(20), m_paperHeight(20),
69 m_paperMarginTop(72), m_paperMarginLeft(72),
70 m_paperMarginBottom(72), m_paperMarginRight(72), m_startPageNumber(1)
74static TQString WritePositiveKeyword(
const TQString& keyword,
const int value)
80 str += TQString::number( value );
87TQString RTFWorker::writeRow(
const TQString& textCellHeader,
const TQString& rowText,
const FrameData& frame)
91 row +=
"\\trowd\\trgaph60\\trql";
92 row += WritePositiveKeyword(
"\\trrh", tqRound(PT_TO_TWIP(frame.minHeight)));
93 row += WritePositiveKeyword(
"\\trleft", tqRound(PT_TO_TWIP(frame.left) - m_paperMarginLeft));
95 row += textCellHeader;
102TQString RTFWorker::writeBorder(
const char whichBorder,
const int borderWidth,
const TQColor& color)
109 str +=
"\\brdrs\\brdrw";
110 str += TQString::number(borderWidth);
113 str += lookupColor(
"\\brdrcf",color);
119TQString RTFWorker::makeTable(
const FrameAnchor& anchor)
122 textBody += m_prefix;
123 m_prefix = TQString();
127 bool firstCellInRow =
true;
128 FrameData firstFrameData;
129 int debugCellCurrent = 0;
130 int debugRowCurrent = 0;
131 TQString textCellHeader;
133 const bool oldInTable = m_inTable;
136 TQValueList<TableCell>::ConstIterator itCell;
137 for (itCell=anchor.table.cellList.begin();
138 itCell!=anchor.table.cellList.end(); itCell++)
141 if (rowCurrent!=(*itCell).row)
143 rowCurrent = (*itCell).row;
144 textBody += writeRow( textCellHeader, rowText, firstFrameData);
147 rowText = TQString();
148 textCellHeader = TQString();
151 debugCellCurrent = 0;
154 const FrameData& frame = (*itCell).frame;
158 firstFrameData=frame;
159 firstCellInRow=
false;
162 kdDebug(30515) <<
"Cell: " << debugRowCurrent <<
"," << debugCellCurrent
163 <<
" left: " << frame.left <<
" right: " << frame.right <<
" top: " << frame.top <<
" bottom " << frame.bottom << endl;
164 textCellHeader += writeBorder(
't',tqRound(PT_TO_TWIP(frame.tWidth)),frame.tColor);
165 textCellHeader += writeBorder(
'l',tqRound(PT_TO_TWIP(frame.lWidth)),frame.lColor);
166 textCellHeader += writeBorder(
'b',tqRound(PT_TO_TWIP(frame.bWidth)),frame.bColor);
167 textCellHeader += writeBorder(
'r',tqRound(PT_TO_TWIP(frame.rWidth)),frame.rColor);
168 textCellHeader += WritePositiveKeyword(
"\\cellx",tqRound(PT_TO_TWIP(frame.right) - m_paperMarginRight));
170 TQString endOfParagraph;
171 TQValueList<ParaData> *paraList = (*itCell).paraList;
172 TQValueList<ParaData>::ConstIterator it;
173 TQValueList<ParaData>::ConstIterator end(paraList->end());
174 for (it=paraList->begin();it!=end;++it)
176 rowText += endOfParagraph;
177 rowText += ProcessParagraphData( (*it).text,(*it).layout,(*it).formattingList);
179 endOfParagraph =
"\\par";
185 textBody += writeRow( textCellHeader, rowText, firstFrameData);
186 textBody +=
"\\row\\pard";
188 m_inTable = oldInTable;
193TQString RTFWorker::makeImage(
const FrameAnchor& anchor)
197 TQString strImageName(anchor.picture.koStoreName);
201 kdDebug(30515) <<
"RTFWorker::makeImage" << endl << anchor.picture.koStoreName << endl;
203 const int pos=strImageName.findRev(
'.');
204 if(pos!=-1) strExt = strImageName.mid(pos+1).lower();
210 else if (strExt==
"bmp")
213 else if ( (strExt==
"jpeg") || (strExt==
"jpg") )
215 else if (strExt==
"wmf")
216 strTag=
"\\wmetafile8";
221 kdDebug(30515) <<
"Converting image " << anchor.picture.koStoreName << endl;
224 if( !loadAndConvertToImage(anchor.picture.koStoreName,strExt,
"PNG",image) )
226 kdWarning(30515) <<
"Unable to convert " << anchor.picture.koStoreName << endl;
234 if (!loadSubFile(anchor.picture.koStoreName,image))
236 kdWarning(30515) <<
"Unable to load picture " << anchor.picture.koStoreName << endl;
242 const long width = (long)(PT_TO_TWIP(anchor.frame.right - anchor.frame.left));
243 const long height = (long)(PT_TO_TWIP(anchor.frame.bottom - anchor.frame.top));
246 long origWidth = width;
247 long origHeight = height;
248 if( strExt ==
"wmf" )
252 TQ_UINT8* data = (TQ_UINT8*) image.data();
253 if( ( data[0] == 0xd7 ) && ( data[1] == 0xcd ) &&
254 ( data[2] == 0xc6 ) && ( data[3] == 0x9a ) &&
255 ( image.size() > 22 ) )
258 unsigned left = data[6]+(data[7]<<8);
259 unsigned top = data[8]+(data[9]<<8);
260 unsigned right = data[10]+(data[11]<<8);
261 unsigned bottom = data[12]+(data[13]<<8);
262 origWidth = (long) (MM_TO_TWIP(right-left)/100);
263 origHeight = (long) (MM_TO_TWIP(bottom-top)/100);
266 for( uint i=0; i<image.size()-22; i++)
267 image.at(i) = image.at(i+22);
268 image.resize( image.size()-22 );
274 TQImage img( image );
277 kdWarning(30515) <<
"Unable to load picture as image " << anchor.picture.koStoreName << endl;
281 int resx = img.dotsPerMeterX();
282 int resy = img.dotsPerMeterY();
283 if( resx <= 0 ) resx = 2835;
284 if( resy <= 0 ) resy = 2835;
286 origWidth = long(img.width() * 2834.65 * 20 / resx);
287 origHeight = long(img.height() * 2834.65 * 20 / resy);
291 textBody +=
"{\\pict";
295 int scaleX = width * 100 / origWidth;
296 int scaleY = height * 100 / origHeight;
299 int picw = (int)(100 * TWIP_TO_MM(origWidth));
300 int pich = (int)(100 * TWIP_TO_MM(origHeight));
302 textBody +=
"\\picscalex";
303 textBody += TQString::number(scaleX, 10);
304 textBody +=
"\\picscaley";
305 textBody += TQString::number(scaleY, 10);
306 textBody +=
"\\picw";
307 textBody += TQString::number(picw,10);
308 textBody +=
"\\pich";
309 textBody += TQString::number(pich,10);
310 textBody +=
"\\picwgoal";
311 textBody += TQString::number(origWidth, 10);
312 textBody +=
"\\pichgoal";
313 textBody += TQString::number(origHeight, 10);
316 const char hex[] =
"0123456789abcdef";
317 for (uint i=0; i<image.size(); i++)
321 const char ch=image.at(i);
322 textBody += hex[(ch>>4)&0x0f];
323 textBody += hex[(ch&0x0f)];
332TQString RTFWorker::formatTextParagraph(
const TQString& strText,
333 const FormatData& formatOrigin,
const FormatData& format)
340 str+=openSpan(formatOrigin,format);
343 TQString strEscaped = escapeRtfText(strText);
347 TQString strBr(
"\\line ");
348 while ((pos=strEscaped.find(TQChar(10)))>-1)
350 strEscaped.replace(pos,1,strBr);
358 str+=closeSpan(formatOrigin,format);
364TQString RTFWorker::ProcessParagraphData (
const TQString ¶Text,
365 const LayoutData& layout,
const ValueListFormatData ¶FormatDataList)
377 if (layout.counter.style)
379 markup +=
"{\\pntext\\pard\\plain";
380 if( layout.formatData.text.fontSize >= 0)
383 markup += TQString::number((2 * layout.formatData.text.fontSize));
384 markup += lookupFont(
"\\f",layout.formatData.text.fontName);
387 markup += layout.counter.
text;
388 markup +=
"\\tab}{\\*\\pn";
389 if (layout.counter.style > 5)
391 markup +=
"\\pnlvlblt ";
392 markup +=
"{\\pntxtb ";
393 if (!layout.counter.lefttext.isEmpty() && layout.counter.lefttext !=
"{" && layout.counter.lefttext !=
"}")
395 markup += layout.counter.lefttext;
397 switch (layout.counter.style)
404 markup += layout.counter.customCharacter;
410 markup += layout.counter.
text;
417 markup +=
"\\bullet";
424 markup +=
"\\bullet";
431 markup +=
"\\bullet";
438 markup += layout.counter.
text;
442 markup +=
"\\bullet";
448 if (layout.counter.numbering!=0)
451 markup += TQString::number(layout.counter.depth + 1);
452 markup +=
"\\pnprev1";
454 else if (layout.counter.style==1)
456 markup +=
"\\pnlvlbody";
461 markup += TQString::number(11 - layout.counter.style);
464 switch (layout.counter.style)
473 markup +=
"\\pnlcltr";
478 markup +=
"\\pnucltr";
483 markup +=
"\\pnlcrm";
488 markup +=
"\\pnucrm";
494 markup +=
"{\\pntxtb ";
495 markup += layout.counter.lefttext;
498 markup +=
"{\\pntxta ";
499 markup += layout.counter.righttext;
503 if (layout.counter.start!=0)
505 markup +=
"\\pnstart";
506 markup += TQString::number(layout.counter.start);
510 markup +=
"\\pnstart1";
512 markup +=
"\\pnindent0\\pnhang";
514 if( layout.formatData.text.fontSize > 0 )
517 markup += TQString::number((2 * layout.formatData.text.fontSize));
520 if( !layout.formatData.text.fontName.isEmpty() )
522 markup += lookupFont(
"\\pnf", layout.formatData.text.fontName);
529 LayoutData styleLayout;
530 markup += lookupStyle(layout.styleName, styleLayout);
531 markup += layoutToRtf(styleLayout,layout,
true);
533 if ( 1==layout.formatData.text.verticalAlignment )
537 else if ( 2==layout.formatData.text.verticalAlignment )
543 if (layout.pageBreakBefore)
544 content +=
"\\page ";
550 if (!paraText.isEmpty())
553 ValueListFormatData::ConstIterator paraFormatDataIt;
555 TQString partialText;
557 FormatData formatRef = layout.formatData;
559 for ( paraFormatDataIt = paraFormatDataList.begin ();
560 paraFormatDataIt != paraFormatDataList.end ();
563 if (1==(*paraFormatDataIt).id)
566 partialText=paraText.mid ( (*paraFormatDataIt).pos, (*paraFormatDataIt).len );
567 content +=formatTextParagraph(partialText, formatRef, *paraFormatDataIt);
569 else if (4==(*paraFormatDataIt).id)
572 if ( (0==(*paraFormatDataIt).variable.m_type)
573 || (2==(*paraFormatDataIt).variable.m_type) )
576 content +=
"{\\field{\\*\\fldinst ";
577 if (0==(*paraFormatDataIt).variable.m_type)
581 TQString key((*paraFormatDataIt).variable.m_key.mid(4));
582 kdDebug(30515) <<
"Time format: " << key << endl;
583 if (key.startsWith(
"locale"))
585 if (key ==
"locale" )
587 if (0==(*paraFormatDataIt).variable.m_type)
588 key = TDEGlobal::locale()->dateFormat();
590 key = TDEGlobal::locale()->timeFormat();
592 else if ( key ==
"localeshort" )
593 key = TDEGlobal::locale()->dateFormatShort();
594 else if ( key ==
"localedatetime" )
596 key = TDEGlobal::locale()->dateFormat();
598 key += TDEGlobal::locale()->timeFormat();
600 else if ( key ==
"localedatetimeshort" )
602 key = TDEGlobal::locale()->dateFormat();
604 key += TDEGlobal::locale()->timeFormat();
607 kdDebug(30515) <<
"Locale date in TDELocale format: " << key << endl;
612 key.replace(
"%Y",
"yyyy" );
613 key.replace(
"%y",
"yy" );
614 key.replace(
"%n",
"M" );
615 key.replace(
"%m",
"MM" );
616 key.replace(
"%e",
"d" );
617 key.replace(
"%d",
"dd" );
618 key.replace(
"%b",
"MMM" );
619 key.replace(
"%B",
"MMMM" );
620 key.replace(
"%a",
"ddd" );
621 key.replace(
"%A",
"dddd" );
623 key.replace(
"%p",
"am/pm" );
624 key.replace(
"%I",
"hh" );
625 key.replace(
"%l",
"h" );
627 key.replace(
"%H",
"HH" );
628 key.replace(
"%k",
"H" );
630 key.replace(
"%M",
"mm" );
631 key.replace(
"%S",
"ss" );
633 kdDebug(30515) <<
"Locale date in RTF format: " << key << endl;
635 else if (!key.isEmpty())
637 const TQRegExp regexp(
"AP",
false);
638 if (regexp.search(key)!=-1)
641 key.replace(
"ap",
"am/pm");
642 key.replace(
"AP",
"AM/PM");
647 key.replace(
'h',
'H');
650 key.replace(
"PPP",
"MMM");
651 key.replace(
"PPPP",
"MMMM");
652 key.replace(
"zzz",
"000");
653 kdDebug(30515) <<
"New format: " << key << endl;
658 content +=
"\\* MERGEFORMAT }{\\fldrslt ";
659 content += escapeRtfText((*paraFormatDataIt).variable.m_text);
662 else if (4==(*paraFormatDataIt).variable.m_type)
664 TQString strFieldType;
665 if ((*paraFormatDataIt).variable.isPageNumber())
667 content +=
"{\\field{\\*\\fldinst PAGE \\* MERGEFORMAT }{\\fldrslt ";
668 content += escapeRtfText((*paraFormatDataIt).variable.m_text);
671 else if ((*paraFormatDataIt).variable.isPageCount())
673 content +=
"{\\field{\\*\\fldinst NUMPAGES \\* MERGEFORMAT }{\\fldrslt ";
674 content += escapeRtfText((*paraFormatDataIt).variable.m_text);
680 content += escapeRtfText((*paraFormatDataIt).variable.m_text);
683 else if (8==(*paraFormatDataIt).variable.m_type)
686 TQString name = escapeRtfText((*paraFormatDataIt).variable.getFieldName());
687 TQString value = escapeRtfText((*paraFormatDataIt).variable.getFieldValue());
688 TQString rtfField = mapFieldName(name);
690 if( rtfField.isEmpty() )
692 content += escapeRtfText((*paraFormatDataIt).variable.m_text);
695 content +=
"{\\field";
696 content +=
"{\\*\\fldinst ";
698 content +=
" \\* MERGEFORMAT }";
699 content +=
"{\\fldrslt {";
704 else if (9==(*paraFormatDataIt).variable.m_type)
707 content +=
"{\\field";
708 content +=
"{\\*\\fldinst HYPERLINK ";
709 content += escapeRtfText((*paraFormatDataIt).variable.getHrefName());
711 content +=
"{\\fldrslt ";
713 content += lookupColor(
"\\cf",TQColor(0,0,255));
714 content += escapeRtfText((*paraFormatDataIt).variable.getLinkName());
717 else if (11==(*paraFormatDataIt).variable.m_type)
720 TQString value = (*paraFormatDataIt).variable.getFootnoteValue();
721 bool automatic = (*paraFormatDataIt).variable.getFootnoteAuto();
722 TQValueList<ParaData> *paraList = (*paraFormatDataIt).variable.getFootnotePara();
726 TQValueList<ParaData>::ConstIterator it;
727 TQValueList<ParaData>::ConstIterator end(paraList->end());
728 const TQString prefixSaved = m_prefix;
729 m_prefix = TQString();
730 for (it=paraList->begin();it!=end;++it)
731 fstr += ProcessParagraphData( (*it).text, (*it).layout,(*it).formattingList);
732 m_prefix = prefixSaved;
733 content +=
"{\\super ";
734 content += automatic ?
"\\chftn " : value;
735 content +=
"{\\footnote ";
736 content +=
"{\\super ";
737 content += automatic ?
"\\chftn " : value;
745 content += escapeRtfText((*paraFormatDataIt).variable.m_text);
748 else if (6==(*paraFormatDataIt).id)
750 kdDebug(30515) <<
"Found an anchor of type: " << (*paraFormatDataIt).frameAnchor.type << endl;
753 if (6==(*paraFormatDataIt).frameAnchor.type)
757 if (!content.isEmpty())
765 content = TQString();
771 str += makeTable((*paraFormatDataIt).frameAnchor);
773 else if ((2==(*paraFormatDataIt).frameAnchor.type) || (5==(*paraFormatDataIt).frameAnchor.type))
775 content += makeImage((*paraFormatDataIt).frameAnchor);
782 if (layout.pageBreakAfter)
785 if (!content.isEmpty())
793 if (m_inTable==
false)
800 str =
"\\par\\pard\\plain";
801 if (m_inTable==
false)
809bool RTFWorker::doFullParagraph(
const TQString& paraText,
810 const LayoutData& layout,
const ValueListFormatData& paraFormatDataList)
812 kdDebug(30515) <<
"Entering RTFWorker::doFullParagraph" << endl << paraText << endl;
813 TQString par = ProcessParagraphData( paraText, layout, paraFormatDataList);
815 kdDebug(30515) <<
"Quiting RTFWorker::doFullParagraph" << endl;
819bool RTFWorker::doHeader(
const HeaderData& header)
823 if( header.page == HeaderData::PAGE_ODD )
824 str =
"\\facingp{\\headerr";
825 else if( header.page == HeaderData::PAGE_EVEN )
826 str =
"\\facingp{\\headerl";
827 else if( header.page == HeaderData::PAGE_FIRST )
828 str =
"\\facingp{\\headerl";
829 else if( header.page == HeaderData::PAGE_ALL )
836 TQValueList<ParaData>::ConstIterator it;
837 TQValueList<ParaData>::ConstIterator end(header.para.end());
838 for (it=header.para.begin();it!=end;++it)
839 content += ProcessParagraphData( (*it).text,(*it).layout,(*it).formattingList);
841 if (content!=
"\\par\\pard\\plain")
854bool RTFWorker::doFooter(
const FooterData& footer)
858 if( footer.page == FooterData::PAGE_ODD )
859 str =
"\\facingp{\\footerr";
860 else if( footer.page == FooterData::PAGE_EVEN )
861 str =
"\\facingp{\\footerl";
862 else if( footer.page == FooterData::PAGE_FIRST )
863 str =
"\\facingp{\\headerl";
864 else if( footer.page == FooterData::PAGE_ALL )
871 TQValueList<ParaData>::ConstIterator it;
872 TQValueList<ParaData>::ConstIterator end(footer.para.end());
873 for (it=footer.para.begin();it!=end;++it)
874 content += ProcessParagraphData( (*it).text,(*it).layout,(*it).formattingList);
876 if (content!=
"\\par\\pard\\plain")
889bool RTFWorker::doOpenFile(
const TQString& filenameOut,
const TQString& )
891 m_ioDevice=
new TQFile(filenameOut);
895 kdError(30515) <<
"No output file! Aborting!" << endl;
899 if ( !m_ioDevice->open (IO_WriteOnly) )
901 kdError(30515) <<
"Unable to open output file!" << endl;
905 m_streamOut=
new TQTextStream(m_ioDevice);
908 m_streamOut->setEncoding(TQTextStream::Latin1);
910 m_fileName=filenameOut;
915bool RTFWorker::doCloseFile(
void)
917 kdDebug(30515) << __FILE__ <<
":" << __LINE__ << endl;
925bool RTFWorker::doOpenDocument(
void)
931 *m_streamOut <<
"{\\rtf1\\ansi\\ansicpg1252\\uc1\\deff0" << m_eol;
935 << TQColor(0,0,0) << TQColor(0,0,255) << TQColor(0,255,255)
936 << TQColor(0,255,0) << TQColor(255,0,255) << TQColor(255,0,0)
937 << TQColor(255,255,0) << TQColor(255,255,255) << TQColor(0,0,128)
938 << TQColor(0,128,128) << TQColor(0,128,0) << TQColor(128,0,128)
939 << TQColor(128,0,0) << TQColor(128,128,0) << TQColor(128,128,128);
944void RTFWorker::writeFontData(
void)
946 kdDebug(30515) <<
"Fonts:" << m_fontList << endl;
947 *m_streamOut <<
"{\\fonttbl";
949 TQFontDatabase fontDatabase;
950 TQStringList::ConstIterator it;
951 for (count=0, it=m_fontList.begin();
952 it!=m_fontList.end();
955 const TQString strLower( (*it).lower() );
956 *m_streamOut <<
"{\\f" << count;
957 if ( (strLower.find(
"symbol")>-1) || (strLower.find(
"dingbat")>-1) )
958 *m_streamOut <<
"\\ftech";
959 else if ( (strLower.find(
"script")>-1) )
960 *m_streamOut <<
"\\fscript";
966 *m_streamOut <<
"\\fnil";
972 TQFontInfo info(*it);
973 switch (info.styleHint())
975 case TQFont::SansSerif:
978 *m_streamOut <<
"\\fswiss";
983 *m_streamOut <<
"\\froman";
986 case TQFont::Courier:
988 *m_streamOut <<
"\\fmodern";
991 case TQFont::OldEnglish:
993 *m_streamOut <<
"\\fdecor";
1000 *m_streamOut <<
"\\fprq" << ( fontDatabase.isFixedPitch( *it ) ? 1 : 2 ) <<
" ";
1001 *m_streamOut << escapeRtfText( *it );
1002 *m_streamOut <<
";}" << m_eol;
1004 *m_streamOut <<
"}";
1007void RTFWorker::writeColorData(
void)
1009 *m_streamOut <<
"{\\colortbl;";
1011 TQValueList<TQColor>::ConstIterator it;
1012 for (count=0, it=m_colorList.begin();
1013 it!=m_colorList.end();
1016 *m_streamOut <<
"\\red" << (*it).red();
1017 *m_streamOut <<
"\\green" << (*it).green();
1018 *m_streamOut <<
"\\blue" << (*it).blue();
1019 *m_streamOut <<
";";
1021 *m_streamOut <<
"}";
1024void RTFWorker::writeStyleData(
void)
1026 *m_streamOut <<
"{\\stylesheet" << m_eol;
1029 TQValueList<LayoutData>::ConstIterator it;
1030 for (count=0, it=m_styleList.begin();
1031 it!=m_styleList.end();
1034 *m_streamOut <<
"{";
1036 *m_streamOut <<
"\\s" << count;
1038 *m_streamOut << layoutToRtf((*it),(*it),
true);
1043 TQValueList < LayoutData > ::ConstIterator it2;
1044 for( it2 = m_styleList.begin(); it2 != m_styleList.end(); counter++, ++it2 )
1046 if ( (*it2).styleName == (*it).styleFollowing )
1048 *m_streamOut <<
"\\snext" << counter;
1053 *m_streamOut <<
" " << (*it).styleName <<
";";
1054 *m_streamOut <<
"}";
1055 *m_streamOut << m_eol;
1058 *m_streamOut <<
"}";
1061bool RTFWorker::doCloseDocument(
void)
1068 if (!m_textDocInfo.isEmpty())
1070 *m_streamOut <<
"{\\info ";
1071 *m_streamOut << m_textDocInfo;
1072 *m_streamOut <<
"}";
1074 *m_streamOut <<
"\\paperw" << int(m_paperWidth);
1075 *m_streamOut <<
"\\paperh" << int(m_paperHeight);
1076 if (1==m_paperOrientation)
1077 *m_streamOut <<
"\\landscape";
1078 *m_streamOut <<
"\\margl" << int(m_paperMarginLeft);
1079 *m_streamOut <<
"\\margr" << int(m_paperMarginRight);
1080 *m_streamOut <<
"\\margt" << int(m_paperMarginTop);
1081 *m_streamOut <<
"\\margb" << int(m_paperMarginBottom);
1082 *m_streamOut << m_textPage;
1083 *m_streamOut <<
"\\widowctrl\\ftnbj\\aenddoc\\formshade \\fet0\\sectd\n";
1084 if (m_startPageNumber >= 1)
1085 *m_streamOut <<
"\\pgnstart" << m_startPageNumber << endl;
1087 *m_streamOut <<
"\\pard\\plain";
1088 *m_streamOut << m_textBody;
1090 *m_streamOut <<
"}" << m_eol;
1094bool RTFWorker::doFullDocumentInfo(
const KWEFDocumentInfo& docInfo)
1097 if ( !docInfo.title.isEmpty() )
1099 m_textDocInfo +=
"{\\title ";
1100 m_textDocInfo += escapeRtfText( docInfo.title );
1101 m_textDocInfo +=
"}";
1104 if ( !docInfo.fullName.isEmpty() )
1106 m_textDocInfo +=
"{\\author ";
1107 m_textDocInfo += escapeRtfText( docInfo.fullName );
1108 m_textDocInfo +=
"}";
1111 if ( !docInfo.keywords.isEmpty() )
1113 m_textDocInfo +=
"{\\keywords ";
1114 m_textDocInfo += escapeRtfText( docInfo.keywords );
1115 m_textDocInfo +=
"}";
1117 if ( !docInfo.subject.isEmpty() )
1119 m_textDocInfo +=
"{\\subject ";
1120 m_textDocInfo += escapeRtfText( docInfo.subject );
1121 m_textDocInfo +=
"}";
1124 if ( !docInfo.company.isEmpty() )
1126 m_textDocInfo +=
"{\\company ";
1127 m_textDocInfo += escapeRtfText( docInfo.company );
1128 m_textDocInfo +=
"}";
1132 TQString revision(
"$Revision: 549975 $");
1133 m_textDocInfo +=
"{\\comment ";
1134 m_textDocInfo +=
"Generated by KWord's RTF Export Filter";
1135 m_textDocInfo += revision.mid(10).remove(
'$');
1136 m_textDocInfo +=
"}";
1138 if ( !docInfo.abstract.isEmpty() )
1140 m_textDocInfo +=
"{\\doccomm ";
1141 m_textDocInfo += escapeRtfText( docInfo.abstract );
1142 m_textDocInfo +=
"}";
1148bool RTFWorker::doOpenTextFrameSet(
void)
1153bool RTFWorker::doCloseTextFrameSet(
void)
1158TQString RTFWorker::openSpan(
const FormatData& formatOrigin,
const FormatData& format)
1163 result += textFormatToRtf(formatOrigin.text,format.text,
false);
1165 if ( 1==format.text.verticalAlignment )
1169 else if ( 2==format.text.verticalAlignment )
1171 result +=
"\\super";
1178TQString RTFWorker::closeSpan(
const FormatData& ,
const FormatData& )
1188TQString RTFWorker::escapeRtfText (
const TQString& text )
const
1191 TQString escapedText;
1192 const uint length = text.length();
1193 for ( uint i = 0; i < length; i++ )
1195 TQChar TQCh ( text.at( i ) );
1196 const ushort ch = TQCh.unicode();
1198 if ( TQCh ==
'\\' ) escapedText +=
"\\\\";
1199 else if ( TQCh ==
'{' ) escapedText +=
"\\{";
1200 else if ( TQCh ==
'}' ) escapedText +=
"\\}";
1201 else if ( ch >= 32 && ch <= 127)
1202 escapedText += TQCh;
1203 else if ( ch == 0x0009 ) escapedText +=
"\\tab ";
1204 else if ( ch == 0x00a0 ) escapedText +=
"\\~";
1205 else if ( ch == 0x00ad ) escapedText +=
"\\-";
1206 else if ( ch == 0x00b7 ) escapedText +=
"\\|";
1207 else if ( ch == 0x2011 ) escapedText +=
"\\_";
1208 else if ( ch == 0x2002 ) escapedText +=
"\\enspace ";
1209 else if ( ch == 0x2003 ) escapedText +=
"\\emspace ";
1210 else if ( ch == 0x2004 ) escapedText +=
"\\qmspace ";
1211 else if ( ch == 0x200c ) escapedText +=
"\\zwnj ";
1212 else if ( ch == 0x200d ) escapedText +=
"\\zwj ";
1213 else if ( ch == 0x200e ) escapedText +=
"\\ltrmark ";
1214 else if ( ch == 0x200f ) escapedText +=
"\\rtlmark ";
1215 else if ( ch == 0x2013 ) escapedText +=
"\\endash ";
1216 else if ( ch == 0x2014 ) escapedText +=
"\\emdash ";
1217 else if ( ch == 0x2018 ) escapedText +=
"\\lquote ";
1218 else if ( ch == 0x2019 ) escapedText +=
"\\rquote ";
1219 else if ( ch == 0x201c ) escapedText +=
"\\ldblquote ";
1220 else if ( ch == 0x201d ) escapedText +=
"\\rdblquote ";
1221 else if ( ch == 0x2022 ) escapedText +=
"\\bullet ";
1222 else if ( ch >= 160 && ch < 256)
1224 escapedText +=
"\\\'";
1225 escapedText += TQString::number ( ch, 16 );
1227 else if ( ch >= 256)
1230 escapedText +=
"\\u";
1231 escapedText += TQString::number ( ch, 10 );
1235 TQChar replacement ( TQCh.decomposition().at(0) );
1236 kdDebug(30515) <<
"Proposed replacement character: " << TQString(replacement) << endl;
1238 if (replacement.isNull() || (
int)replacement<=
' ' || (
int)replacement>=
char(127)
1239 || replacement==
'{' || replacement==
'}' || replacement==
'\\')
1242 escapedText += replacement;
1246 escapedText += TQCh ;
1254bool RTFWorker::doFullPaperFormat(
const int ,
1255 const double width,
const double height,
const int orientation)
1257 m_paperWidth=width*20;
1258 m_paperHeight=height*20;
1259 m_paperOrientation=orientation;
1263bool RTFWorker::doFullPaperBorders (
const double top,
const double left,
1264 const double bottom,
const double right)
1266 m_paperMarginTop=top*20;
1267 m_paperMarginLeft=left*20;
1268 m_paperMarginBottom=bottom*20;
1269 m_paperMarginRight=right*20;
1273bool RTFWorker::doFullDefineStyle(
LayoutData& layout)
1276 m_styleList << layout;
1279 lookupFont(
"\\f", layout.formatData.text.fontName);
1280 lookupColor(TQString(), layout.formatData.text.fgColor);
1281 lookupColor(TQString(), layout.formatData.text.bgColor);
1286static TQString writeDate(
const TQString keyword,
const TQDateTime& now)
1291 kdDebug(30515) <<
"Date " << keyword <<
" " << now.toString() << endl;
1294 const TQDate nowDate(now.date());
1296 str += TQString::number(nowDate.year());
1298 str += TQString::number(nowDate.month());
1300 str += TQString::number(nowDate.day());
1301 const TQTime nowTime(now.time());
1303 str += TQString::number(nowTime.hour());
1305 str += TQString::number(nowTime.minute());
1307 str += TQString::number(nowTime.second());
1311 kdWarning(30515) <<
"Date " << keyword <<
" is not valid! Skipping!" << endl;
1318 m_textDocInfo += writeDate(
"\\creatim",vs.creationTime);
1319 m_textDocInfo += writeDate(
"\\revtim", vs.modificationTime);
1320 m_textDocInfo += writeDate(
"\\printim",vs.printTime);
1321 m_startPageNumber = vs.startingPageNumber;
1326TQString RTFWorker::textFormatToRtf(
const TextFormatting& formatOrigin,
1330 TQString strElement;
1333 const TQString fontName(formatData.fontName);
1334 if (!fontName.isEmpty()
1335 && (force || (formatOrigin.fontName!=formatData.fontName)))
1337 strElement+=lookupFont(
"\\f", fontName);
1340 if (force || (formatOrigin.fontSize!=formatData.fontSize))
1342 const int size=formatData.fontSize;
1346 strElement+=TQString::number(2*size,10);
1350 if (force || (formatOrigin.italic!=formatData.italic))
1353 if ( formatData.italic )
1363 if (force || ((formatOrigin.weight>=75)!=(formatData.weight>=75)))
1365 if ( formatData.weight >= 75 )
1375 if (force || (formatOrigin.fgColor!=formatData.fgColor))
1377 if ( formatData.fgColor.isValid() )
1379 strElement+=lookupColor(
"\\cf", formatData.fgColor);
1383 if (force || (formatOrigin.bgColor!=formatData.bgColor))
1385 if ( formatData.bgColor.isValid() )
1387 strElement+=lookupColor(
"\\cb", formatData.bgColor);
1388 strElement+=lookupColor(
"\\highlight", formatData.bgColor);
1404 TQString ul (
"\\ul" );
1406 if( underlineStyle.isEmpty() ) underlineStyle =
"solid";
1407 if( underlineValue ==
"1" ) underlineValue =
"single";
1409 if( underlineValue ==
"double" )
1411 else if( underlineValue ==
"single-bold" )
1413 else if( underlineValue ==
"wave" )
1415 else if( underlineValue ==
"single" )
1417 if( underlineStyle ==
"dash" )
1419 else if( underlineStyle ==
"dot" )
1421 else if( underlineStyle ==
"dashdot" )
1423 else if( underlineStyle ==
"dashdotdot" )
1425 else if( underlineWord )
1437 strElement+=
"\\ul0";
1448 strElement+=
"\\striked1";
1450 strElement+=
"\\strike";
1454 strElement+=
"\\strike0";
1461TQString RTFWorker::layoutToRtf(
const LayoutData& layoutOrigin,
1470 strLayout +=
"\\ql";
1472 strLayout +=
"\\qr";
1474 strLayout +=
"\\qc";
1476 strLayout +=
"\\qj";
1484 kdWarning(30515) <<
"Unknown alignment: " << layout.
alignment << endl;
1491 strLayout +=
"\\li";
1492 strLayout += TQString::number(
int(layout.
indentLeft)*20, 10);
1498 strLayout +=
"\\ri";
1499 strLayout += TQString::number(
int(layout.
indentRight)*20, 10);
1504 strLayout +=
"\\fi";
1505 strLayout += TQString::number(
int(layout.
indentFirst)*20, 10);
1511 strLayout +=
"\\sa";
1512 strLayout += TQString::number(
int(layout.
marginBottom)*20 ,10);
1518 strLayout +=
"\\sb";
1519 strLayout += TQString::number(
int(layout.
marginTop)*20, 10);
1522 if (force || (layoutOrigin.keepLinesTogether!=layout.keepLinesTogether))
1524 if(layout.keepLinesTogether) strLayout +=
"\\keep";
1532 if (force || (layoutOrigin.pageBreakBefore!=layout.pageBreakBefore))
1534 if(layout.pageBreakBefore) strLayout +=
"\\pagebb";
1539 if (force || (layoutOrigin.pageBreakAfter!=layout.pageBreakAfter))
1541 if(layout.pageBreakAfter) strLayout +=
"\\*\\pgbrk0";
1553 strLayout +=
"\\sl360\\slmult1";
1556 strLayout +=
"\\sl480\\slmult1";
1559 strLayout += TQString(
"\\sl%1\\slmult0").arg(
int(layout.
lineSpacing)*20);
1562 strLayout += TQString(
"\\sl%1\\slmult1").arg(
int(layout.
lineSpacing)*240 );
1566 strLayout += TQString(
"\\sl-%1\\slmult0").arg(
int(layout.
lineSpacing)*20);
1569 kdWarning(30515) <<
"Unsupported lineSpacingType: " << layout.
lineSpacingType <<
" (Ignoring!)" << endl;
1575 TabulatorList::ConstIterator it;
1578 switch ((*it).m_type)
1580 case 0:
default:
break;
1581 case 1: strLayout +=
"\\tqc";
break;
1582 case 2: strLayout +=
"\\tqr";
break;
1583 case 3: strLayout +=
"\\tqdec";
break;
1586 switch ((*it).m_filling)
1588 case TabulatorData::TF_NONE:
default:
break;
1589 case TabulatorData::TF_DOT: strLayout +=
"\\tldot";
break;
1590 case TabulatorData::TF_LINE: strLayout +=
"\\tlul";
break;
1593 case TabulatorData::TF_DASH:
1594 case TabulatorData::TF_DASHDOT:
1595 case TabulatorData::TF_DASHDOTDOT:
1596 strLayout +=
"\\tlul";
break;
1600 strLayout +=
"\\tx";
1601 strLayout += TQString::number(
int((*it).m_ptpos)*20, 10);
1611 strLayout +=
"\\shad";
1617 strLayout+=textFormatToRtf(layoutOrigin.formatData.text,
1618 layout.formatData.text,force);
1624TQString RTFWorker::lookupFont(
const TQString& markup,
const TQString& fontName)
1626 if (fontName.isEmpty())
1630 TQString cookedFontName(fontName);
1631 TQRegExp regexp(
"\\s*\\[\\S*\\]");
1632 cookedFontName.remove(regexp);
1634 if (cookedFontName.isEmpty())
1635 cookedFontName=fontName;
1637 kdDebug(30515) <<
"RTFWorker::lookupFont " << fontName <<
" cooked: " << cookedFontName << endl;
1640 TQString strFont(markup);
1641 TQStringList::ConstIterator it;
1644 for( it = m_fontList.begin(); it != m_fontList.end(); counter++, ++it )
1646 if((*it) == cookedFontName)
1648 strFont += TQString::number(counter);
1649 kdDebug(30515) << strFont << endl;
1654 kdDebug(30515) <<
"New font: " << cookedFontName <<
" count: " << counter << endl;
1655 m_fontList << cookedFontName;
1657 strFont += TQString::number(counter);
1661TQString RTFWorker::lookupColor(
const TQString& markup,
const TQColor& color)
1663 if (!color.isValid())
1667 TQString strColor(markup);
1669 TQValueList < TQColor > ::ConstIterator it;
1672 for( it = m_colorList.begin(); it != m_colorList.end(); counter++, ++it )
1674 if ( (*it) == color )
1676 strColor += TQString::number(counter);
1681 kdDebug(30515) <<
"New color: " << TQString(color.name()) <<
" count: " << counter << endl;
1682 m_colorList << color;
1684 strColor += TQString::number(counter);
1688TQString RTFWorker::lookupStyle(
const TQString& styleName,
LayoutData& returnLayout)
1690 if (styleName.isEmpty())
1694 TQString strMarkup(
"\\s");
1696 TQValueList < LayoutData > ::ConstIterator it;
1697 TQValueList < LayoutData > ::ConstIterator end(m_styleList.end());
1700 for( it = m_styleList.begin(); it != end; counter++, ++it )
1702 if ( (*it).styleName == styleName )
1704 strMarkup += TQString::number(counter);
1710 kdDebug(30515) <<
"New style: " << styleName <<
" count: " << counter << endl;
1712 m_styleList << layout;
1713 returnLayout=layout;
1715 strMarkup += TQString::number(counter);
TQString text
text at the time of saving (no formatting info though)
This is basically <FRAMESET> tag.
double lineSpacing
Space between lines in pt, if lineSpacingType==0.
TabulatorList tabulatorList
List of tabulators.
double indentFirst
indentation correction of first line (can be negative!)
double indentRight
right indentation (a negative value means invalid)
double shadowDistance
distance of <SHADOW>
double indentLeft
left indentation (a negative value means invalid)
TQString alignment
left, right, center, justify
int lineSpacingType
0=custom, 10=one line, 15=one and half lines, 20= 2 lines
double marginTop
space before the paragraph (a negative value means invalid)
double marginBottom
space after the paragraph (a negative value means invalid)
TextFormatting is a container for data retrieved from the <FORMAT> tag and its subtags to be used in ...
bool underlineWord
true if word-by-word (i.e spaces are not underlined)
bool underline
Any underline? (If true, we do not know if simple or double or what else).
TQColor underlineColor
color of the line
bool strikeout
true if strikeout
TQString underlineStyle
underline style: solid, dash, dot dash, ....
TQString underlineValue
"value" of the underline: single, double, bold-single...
bool missing
true if this TextFormatting object does not correspond to a real <FORMAT> element
TQString strikeoutType
type of strikeout: single, bold, double
see <VARIABLESETTINGS> in the KWord DTD