1 /******************************************************************************
5 * Copyright (C) 1997-2015 by Parker Waechter & Dimitri van Heesch.
7 * Style sheet additions by Alexander Bartolich
9 * Permission to use, copy, modify, and distribute this software and its
10 * documentation under the terms of the GNU General Public License is hereby
11 * granted. No representations are made about the suitability of this software
12 * for any purpose. It is provided "as is" without express or implied warranty.
13 * See the GNU General Public License for more details.
15 * Documents produced by Doxygen are derivative works derived from the
16 * input used in their production; they are not affected by this license.
24 #include <qtextstream.h>
37 #include "rtfdocvisitor.h"
38 #include "docparser.h"
40 #include "vhdldocgen.h"
43 #include "classlist.h"
45 #include "namespacedef.h"
47 //#define DBG_RTF(x) x;
50 static QCString dateToRTFDateString()
52 const QDateTime &d = QDateTime::currentDateTime();
54 result.sprintf("\\yr%d\\mo%d\\dy%d\\hr%d\\min%d\\sec%d",
55 d.date().year(), d.date().month(), d.date().day(),
56 d.time().hour(),d.time().minute(),d.time().second());
60 RTFGenerator::RTFGenerator() : OutputGenerator()
62 dir=Config_getString(RTF_OUTPUT);
64 //insideTabbing=FALSE;
66 m_bstartedBody = FALSE;
67 m_omitParagraph = FALSE;
69 m_prettyCode=Config_getBool(RTF_SOURCE_CODE);
72 RTFGenerator::~RTFGenerator()
76 //void RTFGenerator::append(const OutputGenerator *g)
78 // t << g->getContents();
79 // col+=((RTFGenerator *)g)->col;
80 // //insideTabbing=insideTabbing || ((RTFGenerator *)g)->insideTabbing;
81 // m_listLevel=((RTFGenerator *)g)->m_listLevel;
82 // m_omitParagraph=((RTFGenerator *)g)->m_omitParagraph;
83 // //printf("RTFGenerator::append(%s) insideTabbing=%s\n", g->getContents().data(),
84 // // insideTabbing ? "TRUE" : "FALSE" );
87 //OutputGenerator *RTFGenerator::copy()
89 // RTFGenerator *result = new RTFGenerator;
90 // //result->insideTabbing=insideTabbing;
91 // result->m_listLevel=m_listLevel;
92 // result->m_omitParagraph=m_omitParagraph;
96 void RTFGenerator::writeStyleSheetFile(QFile &file)
99 t << "# Generated by doxygen " << versionString << "\n\n";
100 t << "# This file describes styles used for generating RTF output.\n";
101 t << "# All text after a hash (#) is considered a comment and will be ignored.\n";
102 t << "# Remove a hash to activate a line.\n\n";
105 for ( i=0 ; rtf_Style_Default[i].reference!=0 ; i++ )
107 t << "# " << rtf_Style_Default[i].name << " = "
108 << rtf_Style_Default[i].reference
109 << rtf_Style_Default[i].definition << endl;
113 void RTFGenerator::writeExtensionsFile(QFile &file)
115 FTextStream t(&file);
116 t << "# Generated by doxygen " << versionString << "\n\n";
117 t << "# This file describes extensions used for generating RTF output.\n";
118 t << "# All text after a hash (#) is considered a comment and will be ignored.\n";
119 t << "# Remove a hash to activate a line.\n\n";
121 t << "# Overrides the project title.\n";
123 t << "#Title = \n\n";
125 t << "# Name of the company that produced this document.\n";
126 t << "#Company = \n\n";
128 t << "# Filename of a company or project logo.\n";
129 t << "#LogoFilename = \n\n";
131 t << "# Author of the document.\n";
132 t << "#Author = \n\n";
134 t << "# Type of document (e.g. Design Specification, User Manual, etc.).\n";
135 t << "#DocumentType = \n\n";
137 t << "# Document tracking number.\n";
138 t << "#DocumentId = \n\n";
140 t << "# Name of the author's manager.\n";
141 t << "# This field is not displayed in the document itself, but it is \n";
142 t << "# available in the information block of the rtf file. In Microsoft \n";
143 t << "# Word, it is available under File:Properties.\n";
144 t << "#Manager = \n\n";
146 t << "# Subject of the document.\n";
147 t << "# This field is not displayed in the document itself, but it is \n";
148 t << "# available in the information block of the rtf file. In Microsoft \n";
149 t << "# Word, it is available under File:Properties.\n";
150 t << "#Subject = \n\n";
152 t << "# Comments regarding the document.\n";
153 t << "# This field is not displayed in the document itself, but it is \n";
154 t << "# available in the information block of the rtf file. In Microsoft \n";
155 t << "# Word, it is available under File:Properties.\n";
156 t << "#Comments = \n\n";
158 t << "# Keywords associated with the document.\n";
159 t << "# This field is not displayed in the document itself, but it is \n";
160 t << "# available in the information block of the rtf file. In Microsoft \n";
161 t << "# Word, it is available under File:Properties.\n";
162 t << "#Keywords = \n\n";
166 void RTFGenerator::init()
168 QCString dir=Config_getString(RTF_OUTPUT);
170 if (!d.exists() && !d.mkdir(dir))
172 err("Could not create output directory %s\n",dir.data());
175 rtf_Style.setAutoDelete(TRUE);
177 // first duplicate strings of rtf_Style_Default
178 const struct Rtf_Style_Default* def = rtf_Style_Default;
179 while(def->reference != 0)
181 if (def->definition == 0)
182 err("Internal: rtf_Style_Default[%s] has no definition.\n", def->name);
183 StyleData* styleData = new StyleData(def->reference, def->definition);
184 rtf_Style.insert(def->name, styleData);
188 // overwrite some (or all) definitions from file
189 QCString &rtfStyleSheetFile = Config_getString(RTF_STYLESHEET_FILE);
190 if (!rtfStyleSheetFile.isEmpty())
192 loadStylesheet(rtfStyleSheetFile, rtf_Style);
195 // If user has defined an extension file, load its contents.
196 QCString &rtfExtensionsFile = Config_getString(RTF_EXTENSIONS_FILE);
197 if (!rtfExtensionsFile.isEmpty())
199 loadExtensions(rtfExtensionsFile);
205 static QCString makeIndexName(const char *s,int i)
208 result+=(char)(i+'0');
212 void RTFGenerator::beginRTFDocument()
214 /* all the included RTF files should begin with the
217 t <<"{\\rtf1\\ansi\\ansicpg" << theTranslator->trRTFansicp();
218 t <<"\\uc1 \\deff0\\deflang1033\\deflangfe1033\n";
220 DBG_RTF(t <<"{\\comment Beginning font list}\n")
222 t <<"{\\f0\\froman\\fcharset" << theTranslator->trRTFCharSet();
223 t <<"\\fprq2{\\*\\panose 02020603050405020304}Times New Roman;}\n";
224 t <<"{\\f1\\fswiss\\fcharset" << theTranslator->trRTFCharSet();
225 t <<"\\fprq2{\\*\\panose 020b0604020202020204}Arial;}\n";
226 t <<"{\\f2\\fmodern\\fcharset" << theTranslator->trRTFCharSet();
227 t <<"\\fprq1{\\*\\panose 02070309020205020404}Courier New;}\n";
228 t <<"{\\f3\\froman\\fcharset2\\fprq2{\\*\\panose 05050102010706020507}Symbol;}\n";
230 DBG_RTF(t <<"{\\comment begin colors}\n")
232 t <<"\\red0\\green0\\blue0;";
233 t <<"\\red0\\green0\\blue255;";
234 t <<"\\red0\\green255\\blue255;";
235 t <<"\\red0\\green255\\blue0;";
236 t <<"\\red255\\green0\\blue255;";
237 t <<"\\red255\\green0\\blue0;";
238 t <<"\\red255\\green255\\blue0;";
239 t <<"\\red255\\green255\\blue255;";
240 t <<"\\red0\\green0\\blue128;";
241 t <<"\\red0\\green128\\blue128;";
242 t <<"\\red0\\green128\\blue0;";
243 t <<"\\red128\\green0\\blue128;";
244 t <<"\\red128\\green0\\blue0;";
245 t <<"\\red128\\green128\\blue0;";
246 t <<"\\red128\\green128\\blue128;";
247 t <<"\\red192\\green192\\blue192;}" << endl;
249 DBG_RTF(t <<"{\\comment Beginning style list}\n")
250 t <<"{\\stylesheet\n";
251 t <<"{\\widctlpar\\adjustright \\fs20\\cgrid \\snext0 Normal;}\n";
253 // set the paper dimensions according to PAPER_TYPE
254 QCString paperName = Config_getEnum(PAPER_TYPE);
258 t << "\\paperw11900\\paperh16840"; // width & height values are inches * 1440
260 else if (paperName=="letter")
262 t << "\\paperw12240\\paperh15840";
264 else if (paperName=="legal")
266 t << "\\paperw12240\\paperh20160";
268 else if (paperName=="executive")
270 t << "\\paperw10440\\paperh15120";
272 t << "\\margl1800\\margr1800\\margt1440\\margb1440\\gutter0\\ltrsect}\n";
274 // sort styles ascending by \s-number via an intermediate QArray
275 QArray<const StyleData*> array(128);
277 QDictIterator<StyleData> iter(rtf_Style);
278 const StyleData* style;
279 for(; (style = iter.current()); ++iter)
281 unsigned index = style->index;
282 unsigned size = array.size();
285 // +1 to add at least one element, then align up to multiple of 8
286 array.resize((index + 1 + 7) & ~7);
288 ASSERT(index < array.size());
290 if (array.at(index) != 0)
292 QCString key(iter.currentKey());
293 msg("Style '%s' redefines \\s%d.\n", key.data(), index);
295 array.at(index) = style;
298 // write array elements
299 unsigned size = array.size();
300 for(unsigned i = 0; i < size; i++)
302 const StyleData* style = array.at(i);
304 t <<"{" << style->reference << style->definition << ";}\n";
308 // this comment is needed for postprocessing!
309 t <<"{\\comment begin body}" << endl;
313 void RTFGenerator::beginRTFChapter()
316 DBG_RTF(t << "{\\comment BeginRTFChapter}\n")
317 t << rtf_Style_Reset;
319 // if we are compact, no extra page breaks...
320 if (Config_getBool(COMPACT_RTF))
322 // t <<"\\sect\\sectd\\sbknone\n";
323 t <<"\\sect\\sbknone\n";
324 rtfwriteRuler_thick();
327 t <<"\\sect\\sbkpage\n";
328 //t <<"\\sect\\sectd\\sbkpage\n";
330 t << rtf_Style["Heading1"]->reference << "\n";
333 void RTFGenerator::beginRTFSection()
336 DBG_RTF(t << "{\\comment BeginRTFSection}\n")
337 t << rtf_Style_Reset;
339 // if we are compact, no extra page breaks...
340 if (Config_getBool(COMPACT_RTF))
342 // t <<"\\sect\\sectd\\sbknone\n";
343 t <<"\\sect\\sbknone\n";
344 rtfwriteRuler_emboss();
347 t <<"\\sect\\sbkpage\n";
348 //t <<"\\sect\\sectd\\sbkpage\n";
350 t << rtf_Style["Heading2"]->reference << "\n";
353 void RTFGenerator::startFile(const char *name,const char *,const char *)
355 //setEncoding(QCString().sprintf("CP%s",theTranslator->trRTFansicp()));
356 QCString fileName=name;
357 relPath = relativePathToRoot(fileName);
359 if (fileName.right(4)!=".rtf" ) fileName+=".rtf";
360 startPlainFile(fileName);
364 void RTFGenerator::endFile()
366 DBG_RTF(t << "{\\comment endFile}\n")
372 void RTFGenerator::startProjectNumber()
374 DBG_RTF(t <<"{\\comment startProjectNumber }" << endl)
378 void RTFGenerator::endProjectNumber()
380 DBG_RTF(t <<"{\\comment endProjectNumber }" << endl)
383 void RTFGenerator::startIndexSection(IndexSections is)
385 //QCString paperName;
391 case isTitlePageStart:
393 // get readyfor author etc
396 t << "{\\title {\\comment ";
398 case isTitlePageAuthor:
400 if (rtf_subject) t << "{\\subject " << rtf_subject << "}\n";
401 if (rtf_comments) t << "{\\comment " << rtf_comments << "}\n";
402 if (rtf_company) t << "{\\company " << rtf_company << "}\n";
403 if (rtf_author) t << "{\\author " << rtf_author << "}\n";
404 if (rtf_manager) t << "{\\manager " << rtf_manager << "}\n";
405 if (rtf_documentType) t << "{\\category " << rtf_documentType << "}\n";
406 if (rtf_keywords) t << "{\\keywords " << rtf_keywords << "}\n";
413 //case isPackageIndex:
415 // beginRTFChapter();
425 case isNamespaceIndex:
429 case isClassHierarchyIndex:
431 DBG_RTF(t << "{\\comment start classhierarchy}\n")
434 case isCompoundIndex:
435 //Annotated Compound Index
439 //Annotated File Index
446 case isModuleDocumentation:
448 //Module Documentation
449 GroupSDict::Iterator gli(*Doxygen::groupSDict);
452 for (gli.toFirst();(gd=gli.current()) && !found;++gli)
454 if (!gd->isReference())
462 case isDirDocumentation:
464 //Directory Documentation
465 SDict<DirDef>::Iterator dli(*Doxygen::directories);
468 for (dli.toFirst();(dd=dli.current()) && !found;++dli)
470 if (dd->isLinkableInProject())
478 case isNamespaceDocumentation:
480 // Namespace Documentation
481 NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
484 for (nli.toFirst();(nd=nli.current()) && !found;++nli)
486 if (nd->isLinkableInProject())
494 case isClassDocumentation:
496 //Compound Documentation
497 ClassSDict::Iterator cli(*Doxygen::classSDict);
500 for (cli.toFirst();(cd=cli.current()) && !found;++cli)
502 if (cd->isLinkableInProject() &&
503 cd->templateMaster()==0 &&
504 !cd->isEmbeddedInOuterScope()
513 case isFileDocumentation:
517 FileNameListIterator fnli(*Doxygen::inputNameList);
519 for (fnli.toFirst();(fn=fnli.current());++fnli)
521 FileNameIterator fni(*fn);
523 for (;(fd=fni.current());++fni)
525 if (fd->isLinkableInProject())
538 case isExampleDocumentation:
540 //Example Documentation
544 case isPageDocumentation:
550 case isPageDocumentation2:
560 void RTFGenerator::endIndexSection(IndexSections is)
562 bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
563 bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
564 static bool sourceBrowser = Config_getBool(SOURCE_BROWSER);
565 static QCString projectName = Config_getString(PROJECT_NAME);
569 case isTitlePageStart:
571 // User has overridden document title in extensions file
572 t << "}" << rtf_title;
574 t << "}" << projectName;
576 case isTitlePageAuthor:
579 t << "{\\creatim " << dateToRTFDateString() << "}\n}";
580 DBG_RTF(t << "{\\comment end of infoblock}\n");
581 // setup for this section
582 t << rtf_Style_Reset <<"\n";
583 t <<"\\sectd\\pgnlcrm\n";
584 t <<"{\\footer "<<rtf_Style["Footer"]->reference << "{\\chpgn}}\n";
586 DBG_RTF(t << "{\\comment begin title page}\n")
589 t << rtf_Style_Reset << rtf_Style["SubTitle"]->reference << endl; // set to title style
591 t << "\\vertalc\\qc\\par\\par\\par\\par\\par\\par\\par\n";
592 if (rtf_logoFilename)
594 t << "{\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"" << rtf_logoFilename;
595 t << "\" \\\\d \\\\*MERGEFORMAT} {\\fldrslt IMAGE }}\\par\\par\n";
599 t << rtf_company << "\\par\\par\n";
602 t << rtf_Style_Reset << rtf_Style["Title"]->reference << endl; // set to title style
604 // User has overridden document title in extensions file
605 t << "{\\field\\fldedit {\\*\\fldinst " << rtf_title << " \\\\*MERGEFORMAT}{\\fldrslt " << rtf_title << "}}\\par" << endl;
608 DocText *root = validatingParseText(projectName);
609 t << "{\\field\\fldedit {\\*\\fldinst TITLE \\\\*MERGEFORMAT}{\\fldrslt ";
611 t << "}}\\par" << endl;
615 t << rtf_Style_Reset << rtf_Style["SubTitle"]->reference << endl; // set to title style
617 if (rtf_documentType)
619 t << rtf_documentType << "\\par\n";
623 t << rtf_documentId << "\\par\n";
625 t << "\\par\\par\\par\\par\\par\\par\\par\\par\\par\\par\\par\\par\n";
627 t << rtf_Style_Reset << rtf_Style["SubTitle"]->reference << endl; // set to subtitle style
629 t << "{\\field\\fldedit {\\*\\fldinst AUTHOR \\\\*MERGEFORMAT}{\\fldrslt "<< rtf_author << " }}\\par" << endl;
631 t << "{\\field\\fldedit {\\*\\fldinst AUTHOR \\\\*MERGEFORMAT}{\\fldrslt AUTHOR}}\\par" << endl;
633 t << theTranslator->trVersion() << " " << Config_getString(PROJECT_NUMBER) << "\\par";
634 t << "{\\field\\fldedit {\\*\\fldinst CREATEDATE \\\\*MERGEFORMAT}"
635 "{\\fldrslt "<< dateToString(FALSE) << " }}\\par"<<endl;
637 DBG_RTF(t << "{\\comment End title page}" << endl)
639 // table of contents section
640 DBG_RTF(t << "{\\comment Table of contents}\n")
642 t << rtf_Style_Reset << endl;
643 t << rtf_Style["Heading1"]->reference;
644 t << theTranslator->trRTFTableOfContents() << "\\par"<< endl;
645 t << rtf_Style_Reset << "\\par" << endl;
646 t << "{\\field\\fldedit {\\*\\fldinst TOC \\\\f \\\\*MERGEFORMAT}{\\fldrslt Table of contents}}\\par\n";
647 t << rtf_Style_Reset << endl;
651 t << "\\par " << rtf_Style_Reset << endl;
652 if (!Doxygen::mainPage || Doxygen::mainPage->title().isEmpty())
654 t << "{\\tc \\v " << theTranslator->trMainPage() << "}"<< endl;
658 t << "{\\tc \\v " << substitute(Doxygen::mainPage->title(),"%","") << "}"<< endl;
660 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
661 //if (Config_getBool(GENERATE_TREEVIEW)) t << "main"; else t << "index";
663 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
665 //case isPackageIndex:
666 // t << "\\par " << rtf_Style_Reset << endl;
667 // t << "{\\tc \\v " << theTranslator->trPackageList() << "}"<< endl;
668 // t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"packages.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
671 t << "\\par " << rtf_Style_Reset << endl;
672 t << "{\\tc \\v " << theTranslator->trModuleIndex() << "}"<< endl;
673 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"modules.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
676 t << "\\par " << rtf_Style_Reset << endl;
677 t << "{\\tc \\v " << theTranslator->trDirIndex() << "}"<< endl;
678 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"dirs.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
680 case isNamespaceIndex:
681 t << "\\par " << rtf_Style_Reset << endl;
684 t << "{\\tc \\v " << theTranslator->trModulesIndex() << "}" << endl;
688 t << "{\\tc \\v " << theTranslator->trNamespaceIndex() << "}" << endl;
691 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"namespaces.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
693 case isClassHierarchyIndex:
694 t << "\\par " << rtf_Style_Reset << endl;
695 t << "{\\tc \\v " << theTranslator->trHierarchicalIndex() << "}"<< endl;
696 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"hierarchy.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
698 case isCompoundIndex:
699 t << "\\par " << rtf_Style_Reset << endl;
702 t << "{\\tc \\v " << theTranslator->trCompoundIndexFortran() << "}"<< endl;
706 t << "{\\tc \\v " << VhdlDocGen::trDesignUnitIndex() << "}"<< endl;
710 t << "{\\tc \\v " << theTranslator->trCompoundIndex() << "}"<< endl;
712 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"annotated.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
715 t << "\\par " << rtf_Style_Reset << endl;
716 t << "{\\tc \\v " << theTranslator->trFileIndex() << "}"<< endl;
717 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"files.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
720 t << "\\par " << rtf_Style_Reset << endl;
721 t << "{\\tc \\v " << theTranslator->trPageIndex() << "}"<< endl;
722 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"pages.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
724 case isModuleDocumentation:
726 GroupSDict::Iterator gli(*Doxygen::groupSDict);
728 t << "{\\tc \\v " << theTranslator->trModuleDocumentation() << "}"<< endl;
729 for (gli.toFirst();(gd=gli.current());++gli)
731 if (!gd->isReference())
733 t << "\\par " << rtf_Style_Reset << endl;
734 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
735 t << gd->getOutputFileBase();
736 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
741 case isDirDocumentation:
743 SDict<DirDef>::Iterator dli(*Doxygen::directories);
745 t << "{\\tc \\v " << theTranslator->trDirDocumentation() << "}"<< endl;
746 for (dli.toFirst();(dd=dli.current());++dli)
748 if (dd->isLinkableInProject())
750 t << "\\par " << rtf_Style_Reset << endl;
751 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
752 t << dd->getOutputFileBase();
753 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
758 case isNamespaceDocumentation:
760 NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
763 for (nli.toFirst();(nd=nli.current()) && !found;++nli)
765 if (nd->isLinkableInProject())
767 t << "\\par " << rtf_Style_Reset << endl;
768 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
769 t << nd->getOutputFileBase();
770 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
774 while ((nd=nli.current()))
776 if (nd->isLinkableInProject())
778 t << "\\par " << rtf_Style_Reset << endl;
780 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
781 t << nd->getOutputFileBase();
782 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
788 case isClassDocumentation:
790 ClassSDict::Iterator cli(*Doxygen::classSDict);
795 t << "{\\tc \\v " << theTranslator->trTypeDocumentation() << "}"<< endl;
799 t << "{\\tc \\v " << theTranslator->trClassDocumentation() << "}"<< endl;
801 for (cli.toFirst();(cd=cli.current()) && !found;++cli)
803 if (cd->isLinkableInProject() &&
804 cd->templateMaster()==0 &&
805 !cd->isEmbeddedInOuterScope()
808 t << "\\par " << rtf_Style_Reset << endl;
809 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
810 t << cd->getOutputFileBase();
811 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
815 for (;(cd=cli.current());++cli)
817 if (cd->isLinkableInProject() &&
818 cd->templateMaster()==0 &&
819 !cd->isEmbeddedInOuterScope()
822 t << "\\par " << rtf_Style_Reset << endl;
824 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
825 t << cd->getOutputFileBase();
826 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
831 case isFileDocumentation:
835 t << "{\\tc \\v " << theTranslator->trFileDocumentation() << "}"<< endl;
836 FileNameListIterator fnli(*Doxygen::inputNameList);
838 for (fnli.toFirst();(fn=fnli.current());++fnli)
840 FileNameIterator fni(*fn);
842 for (;(fd=fni.current());++fni)
844 if (fd->isLinkableInProject())
848 t << "\\par " << rtf_Style_Reset << endl;
849 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
850 t << fd->getOutputFileBase();
851 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
852 if (sourceBrowser && m_prettyCode && fd->generateSourceFile())
854 t << "\\par " << rtf_Style_Reset << endl;
855 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"" << fd->getSourceFileBase() << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
861 t << "\\par " << rtf_Style_Reset << endl;
863 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
864 t << fd->getOutputFileBase();
865 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
866 if (sourceBrowser && m_prettyCode && fd->generateSourceFile())
868 t << "\\par " << rtf_Style_Reset << endl;
869 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"" << fd->getSourceFileBase() << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
877 case isExampleDocumentation:
880 t << "{\\tc \\v " << theTranslator->trExampleDocumentation() << "}"<< endl;
881 PageSDict::Iterator pdi(*Doxygen::exampleSDict);
882 PageDef *pd=pdi.toFirst();
885 t << "\\par " << rtf_Style_Reset << endl;
886 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
887 t << pd->getOutputFileBase();
888 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
890 for (++pdi;(pd=pdi.current());++pdi)
892 t << "\\par " << rtf_Style_Reset << endl;
894 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
895 t << pd->getOutputFileBase();
896 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
900 case isPageDocumentation:
902 //#error "fix me in the same way as the latex index..."
903 //t << "{\\tc \\v " << theTranslator->trPageDocumentation() << "}"<< endl;
905 //PageSDict::Iterator pdi(*Doxygen::pageSDict);
906 //PageDef *pd=pdi.toFirst();
908 //for (pdi.toFirst();(pd=pdi.current());++pdi)
910 // if (!pd->getGroupDef() && !pd->isReference())
912 // if (first) t << "\\par " << rtf_Style_Reset << endl;
913 // t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
914 // t << pd->getOutputFileBase();
915 // t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
921 case isPageDocumentation2:
924 t << "\\par " << rtf_Style_Reset << endl;
929 t << rtf_Style["Heading1"]->reference;
930 t << theTranslator->trRTFGeneralIndex() << "\\par "<< endl;
931 t << rtf_Style_Reset << endl;
932 t << "{\\tc \\v " << theTranslator->trRTFGeneralIndex() << "}" << endl;
933 t << "{\\field\\fldedit {\\*\\fldinst INDEX \\\\c2 \\\\*MERGEFORMAT}{\\fldrslt INDEX}}\n";
939 void RTFGenerator::writePageLink(const char *name,bool first)
941 if (first) t << "\\par " << rtf_Style_Reset << endl;
942 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
944 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
947 void RTFGenerator::lastIndexPage()
949 DBG_RTF(t <<"{\\comment Beginning Body of RTF Document}\n")
950 // end page and setup for rest of document
951 t <<"\\sect \\sbkpage \\pgndec \\pgnrestart\n";
952 t <<"\\sect \\sectd \\sbknone\n";
954 // set new footer with arabic numbers
955 t <<"{\\footer "<< rtf_Style["Footer"]->reference << "{\\chpgn}}\n";
956 //t << rtf_Style["Heading1"]->reference << "\n";
960 void RTFGenerator::writeStyleInfo(int)
964 void RTFGenerator::lineBreak(const char *)
966 DBG_RTF(t << "{\\comment (lineBreak)}" << endl)
967 t << "\\par" << endl;
968 m_omitParagraph = TRUE;
971 void RTFGenerator::writeString(const char *text)
976 void RTFGenerator::startIndexList()
978 DBG_RTF(t << "{\\comment (startIndexList)}" << endl)
980 t << "\\par" << endl;
981 incrementIndentLevel();
982 t << rtf_Style_Reset << rtf_LCList_DepthStyle() << endl;
983 m_omitParagraph = TRUE;
986 void RTFGenerator::endIndexList()
988 DBG_RTF(t << "{\\comment (endIndexList)}" << endl)
989 if (!m_omitParagraph)
992 m_omitParagraph = TRUE;
995 decrementIndentLevel();
998 /*! start bullet list */
999 void RTFGenerator::startItemList()
1002 DBG_RTF(t << "{\\comment (startItemList level=" << m_listLevel << ") }" << endl)
1004 incrementIndentLevel();
1005 rtf_listItemInfo[m_listLevel].isEnum = FALSE;
1008 /*! end bullet list */
1009 void RTFGenerator::endItemList()
1012 DBG_RTF(t << "{\\comment (endItemList level=" << m_listLevel << ")}" << endl)
1014 decrementIndentLevel();
1015 m_omitParagraph = TRUE;
1018 ///*! start enumeration list */
1019 //void RTFGenerator::startEnumList() // starts an enumeration list
1021 // DBG_RTF(t << "{\\comment (startEnumList)}" << endl)
1022 // t << "{" << endl;
1023 // incrementIndentLevel();
1024 // rtf_listItemInfo[m_listLevel].isEnum = TRUE;
1025 // rtf_listItemInfo[m_listLevel].number = 1;
1028 ///*! end enumeration list */
1029 //void RTFGenerator::endEnumList()
1032 // DBG_RTF(t << "{\\comment (endEnumList)}" << endl)
1034 // decrementIndentLevel();
1035 // m_omitParagraph = TRUE;
1038 /*! write bullet or enum item */
1039 void RTFGenerator::startItemListItem()
1041 DBG_RTF(t << "{\\comment (startItemListItem)}" << endl)
1043 t << rtf_Style_Reset;
1044 if (rtf_listItemInfo[m_listLevel].isEnum)
1046 t << rtf_EList_DepthStyle() << endl;
1047 t << rtf_listItemInfo[m_listLevel].number << ".\\tab ";
1048 rtf_listItemInfo[m_listLevel].number++;
1052 t << rtf_BList_DepthStyle() << endl;
1054 m_omitParagraph = TRUE;
1057 void RTFGenerator::endItemListItem()
1059 DBG_RTF(t << "{\\comment (endItemListItem)}" << endl)
1062 void RTFGenerator::startIndexItem(const char *,const char *)
1064 DBG_RTF(t << "{\\comment (startIndexItem)}" << endl)
1066 if (!m_omitParagraph)
1068 t << "\\par" << endl;
1069 m_omitParagraph = TRUE;
1073 void RTFGenerator::endIndexItem(const char *ref,const char *fn)
1075 DBG_RTF(t << "{\\comment (endIndexItem)}" << endl)
1079 writeRTFReference(fn);
1086 m_omitParagraph = TRUE;
1089 //void RTFGenerator::writeIndexFileItem(const char *,const char *text)
1091 // t << "\\item\\contentsline{section}{";
1093 // t << "}{\\pageref{" << text << "}}" << endl;
1096 void RTFGenerator::startHtmlLink(const char *url)
1099 if (Config_getBool(RTF_HYPERLINKS))
1101 t << "{\\field {\\*\\fldinst { HYPERLINK \"";
1104 t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
1112 void RTFGenerator::endHtmlLink()
1114 if (Config_getBool(RTF_HYPERLINKS))
1124 //void RTFGenerator::writeMailLink(const char *url)
1126 // startTypewriter();
1131 void RTFGenerator::writeStartAnnoItem(const char *,const char *f,
1132 const char *path,const char *name)
1134 DBG_RTF(t << "{\\comment (writeStartAnnoItem)}" << endl)
1136 if (path) docify(path);
1137 if (f && Config_getBool(RTF_HYPERLINKS))
1139 t << "{\\field {\\*\\fldinst { HYPERLINK \\\\l \"";
1140 t << rtfFormatBmkStr(f);
1142 t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
1155 void RTFGenerator::writeEndAnnoItem(const char *name)
1157 DBG_RTF(t << "{\\comment (writeEndAnnoItem)}" << endl)
1161 writeRTFReference(name);
1171 void RTFGenerator::startIndexKey()
1173 DBG_RTF(t << "{\\comment (startIndexKey)}" << endl)
1177 void RTFGenerator::endIndexKey()
1179 DBG_RTF(t << "{\\comment (endIndexKey)}" << endl)
1182 void RTFGenerator::startIndexValue(bool hasBrief)
1184 DBG_RTF(t << "{\\comment (startIndexValue)}" << endl)
1186 if (hasBrief) t << "(";
1189 void RTFGenerator::endIndexValue(const char *name,bool hasBrief)
1191 DBG_RTF(t << "{\\comment (endIndexValue)}" << endl)
1192 if (hasBrief) t << ")";
1197 writeRTFReference(name);
1204 m_omitParagraph=FALSE;
1208 void RTFGenerator::startSubsection()
1210 //beginRTFSubSection();
1212 DBG_RTF(t << "{\\comment Begin SubSection}\n")
1213 t << rtf_Style_Reset;
1214 t << rtf_Style["Heading3"]->reference << "\n";
1217 void RTFGenerator::endSubsection()
1220 t << rtf_Style_Reset << endl;
1223 void RTFGenerator::startSubsubsection()
1225 //beginRTFSubSubSection();
1227 DBG_RTF(t << "{\\comment Begin SubSubSection}\n")
1229 t << rtf_Style_Reset << rtf_Style["Heading4"]->reference << "\n";
1232 void RTFGenerator::endSubsubsection()
1239 //void RTFGenerator::writeClassLink(const char *,const char *,
1240 // const char *,const char *name)
1247 //void RTFGenerator::startTable(bool,int colNumbers)
1249 // DBG_RTF(t << "{\\comment startTable}\n";)
1250 // m_numCols=colNumbers;
1254 //void RTFGenerator::endTable(bool hasCaption)
1256 // DBG_RTF(t << "{\\comment endTable}\n";)
1258 // t << "\n\\pard \\widctlpar\\intbl\\adjustright\n{\\row }\n";
1259 // t << "\\pard\n" << endl;
1262 //void RTFGenerator::startCaption()
1264 // DBG_RTF(t << "{\\comment startCaption}\n";)
1266 // t << "\\trowd \\trgaph108\\trleft-108\\trbrdrt\\brdrs\\brdrw10 \\trbrdrl\\brdrs\\brdrw10 \\trbrdrb\\brdrs\\brdrw10 \\trbrdrr\\brdrs\\brdrw10 \\trbrdrh\\brdrs\\brdrw10 \\trbrdrv\\brdrs\\brdrw10" << endl;
1267 // t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10 \\clbrdrl\\brdrs\\brdrw10 \\clbrdrb\\brdrs\\brdrw10 \\clbrdrr \\brdrs\\brdrw10 \\cltxlrtb \\cellx"<<rtf_pageWidth<<"\\pard \\qc\\nowidctlpar\\widctlpar\\intbl\\adjustright " << endl;
1268 // nextTableColumn();
1271 //void RTFGenerator::endCaption()
1273 // DBG_RTF(t << "{\\comment endCaption}\n";)
1274 // endTableColumn();
1278 //void RTFGenerator::nextTableRow()
1280 // DBG_RTF(t << "{\\comment nextTableRow}\n";)
1281 // ASSERT(m_numCols>0 && m_numCols<25);
1282 // uint columnWidth=rtf_pageWidth/m_numCols;
1283 // t << "\\trowd \\trgaph108\\trleft-108\\trbrdrt\\brdrs\\brdrw10 "
1284 // "\\trbrdrl\\brdrs\\brdrw10 \\trbrdrb\\brdrs\\brdrw10 "
1285 // "\\trbrdrr\\brdrs\\brdrw10 \\trbrdrh\\brdrs\\brdrw10 "
1286 // "\\trbrdrv\\brdrs\\brdrw10 "<<endl;
1287 // for (int i=0;i<m_numCols;i++)
1289 // t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10 \\clbrdrl\\brdrs\\brdrw10 "
1290 // "\\clbrdrb\\brdrs\\brdrw10 \\clbrdrr \\brdrs\\brdrw10 \\cltxlrtb "
1291 // "\\cellx" << (i*columnWidth) << endl;
1293 // t << "\\pard \\widctlpar\\intbl\\adjustright\n{";
1296 //void RTFGenerator::endTableRow()
1298 // DBG_RTF(t << "{\\comment endTableRow}\n";)
1299 // t << "\n\\pard \\widctlpar\\intbl\\adjustright\n{\\row }\n";
1302 //void RTFGenerator::nextTableColumn()
1304 // DBG_RTF(t << "{\\comment nextTableColumn}\n";)
1308 //void RTFGenerator::endTableColumn()
1310 // DBG_RTF(t << "{\\comment endTableColumn}\n";)
1311 // t << " \\cell }";
1314 void RTFGenerator::startTextLink(const char *f,const char *anchor)
1316 if (Config_getBool(RTF_HYPERLINKS))
1329 t << "{\\field {\\*\\fldinst { HYPERLINK \\\\l \"";
1330 t << rtfFormatBmkStr(ref);
1332 t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
1336 void RTFGenerator::endTextLink()
1338 if (Config_getBool(RTF_HYPERLINKS))
1344 void RTFGenerator::writeObjectLink(const char *ref, const char *f,
1345 const char *anchor, const char *text)
1347 if (!ref && Config_getBool(RTF_HYPERLINKS))
1360 t << "{\\field {\\*\\fldinst { HYPERLINK \\\\l \"";
1361 t << rtfFormatBmkStr(refName);
1363 t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
1377 void RTFGenerator::startPageRef()
1383 void RTFGenerator::endPageRef(const char *clname, const char *anchor)
1395 writeRTFReference(ref);
1400 void RTFGenerator::writeCodeLink(const char *ref,const char *f,
1401 const char *anchor,const char *name,
1404 if (!ref && Config_getBool(RTF_HYPERLINKS))
1417 t << "{\\field {\\*\\fldinst { HYPERLINK \\\\l \"";
1418 t << rtfFormatBmkStr(refName);
1420 t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
1432 void RTFGenerator::startTitleHead(const char *)
1434 DBG_RTF(t <<"{\\comment startTitleHead}" << endl)
1436 // beginRTFSection();
1437 t << rtf_Style_Reset << rtf_Style["Heading2"]->reference << endl;
1440 void RTFGenerator::endTitleHead(const char *fileName,const char *name)
1442 DBG_RTF(t <<"{\\comment endTitleHead}" << endl)
1443 t << "\\par " << rtf_Style_Reset << endl;
1446 // make table of contents entry
1447 t << "{\\tc\\tcl2 \\v ";
1451 // make an index entry
1452 addIndexItem(name,0);
1456 // writeAnchor(0,name);
1459 //if (Config_getBool(RTF_HYPERLINKS) && fileName)
1461 writeAnchor(fileName,0);
1466 void RTFGenerator::startTitle()
1468 DBG_RTF(t <<"{\\comment startTitle}" << endl)
1469 if (Config_getBool(COMPACT_RTF))
1475 void RTFGenerator::startGroupHeader(int extraIndent)
1477 DBG_RTF(t <<"{\\comment startGroupHeader}" << endl)
1479 t << rtf_Style_Reset;
1482 t << rtf_Style["Heading5"]->reference;
1484 else if (extraIndent==1)
1486 t << rtf_Style["Heading4"]->reference;
1488 else // extraIndent==0
1490 t << rtf_Style["Heading3"]->reference;
1495 void RTFGenerator::endGroupHeader(int)
1497 DBG_RTF(t <<"{\\comment endGroupHeader}" << endl)
1498 t << "\\par" << endl;
1499 t << rtf_Style_Reset << endl;
1502 void RTFGenerator::startMemberDoc(const char *clname,
1503 const char *memname,
1510 DBG_RTF(t << "{\\comment startMemberDoc}" << endl)
1511 if (memname && memname[0]!='@')
1513 addIndexItem(memname,clname);
1514 addIndexItem(clname,memname);
1516 t << rtf_Style_Reset << rtf_Style[showInline ? "Heading5" : "Heading4"]->reference;
1517 //styleStack.push(rtf_Style_Heading4);
1519 //printf("RTFGenerator::startMemberDoc() `%s'\n",rtf_Style["Heading4"]->reference);
1524 void RTFGenerator::endMemberDoc(bool)
1526 DBG_RTF(t << "{\\comment endMemberDoc}" << endl)
1527 //const char *style = styleStack.pop();
1528 //printf("RTFGenerator::endMemberDoc() `%s'\n",style);
1529 //ASSERT(style==rtf_Style["Heading4"]->reference);
1535 void RTFGenerator::startDoxyAnchor(const char *,const char *,
1536 const char *,const char *,
1540 DBG_RTF(t << "{\\comment startDoxyAnchor}" << endl)
1543 void RTFGenerator::endDoxyAnchor(const char *fName,const char *anchor)
1556 DBG_RTF(t << "{\\comment endDoxyAnchor}" << endl)
1557 t << "{\\bkmkstart ";
1558 t << rtfFormatBmkStr(ref);
1561 t << rtfFormatBmkStr(ref);
1566 //void RTFGenerator::writeLatexLabel(const char *clName,const char *anchor)
1568 // writeDoxyAnchor(0,clName,anchor,0);
1571 void RTFGenerator::addIndexItem(const char *s1,const char *s2)
1586 void RTFGenerator::startIndent()
1588 incrementIndentLevel();
1589 DBG_RTF(t << "{\\comment (startIndent) }" << endl)
1591 t << rtf_Style_Reset << rtf_CList_DepthStyle() << endl;
1594 void RTFGenerator::endIndent()
1597 decrementIndentLevel();
1601 void RTFGenerator::startDescription()
1603 DBG_RTF(t << "{\\comment (startDescription)}" << endl)
1605 t << rtf_Style_Reset << rtf_DList_DepthStyle();
1608 void RTFGenerator::endDescription()
1610 DBG_RTF(t << "{\\comment (endDescription)}" << endl)
1615 void RTFGenerator::startDescItem()
1618 DBG_RTF(t << "{\\comment (startDescItem)}" << endl)
1622 void RTFGenerator::endDescItem()
1624 DBG_RTF(t << "{\\comment (endDescItem)}" << endl)
1629 void RTFGenerator::startMemberDescription(const char *,const char *)
1631 DBG_RTF(t << "{\\comment (startMemberDescription)}" << endl)
1633 incrementIndentLevel();
1634 t << rtf_Style_Reset << rtf_CList_DepthStyle();
1638 void RTFGenerator::endMemberDescription()
1640 DBG_RTF(t << "{\\comment (endMemberDescription)}" << endl)
1643 decrementIndentLevel();
1646 //m_omitParagraph = TRUE;
1649 void RTFGenerator::startDescList(SectionTypes)
1651 DBG_RTF(t << "{\\comment (startDescList)}" << endl)
1652 t << "{"; // ends at endDescList
1653 t << "{"; // ends at endDescTitle
1658 //void RTFGenerator::endDescTitle()
1660 // DBG_RTF(t << "{\\comment (endDescTitle) }" << endl)
1664 // incrementIndentLevel();
1665 // t << rtf_Style_Reset << rtf_DList_DepthStyle();
1668 void RTFGenerator::startDescForItem()
1670 DBG_RTF(t << "{\\comment (startDescForItem) }" << endl)
1673 void RTFGenerator::endDescForItem()
1675 DBG_RTF(t << "{\\comment (endDescForItem) }" << endl)
1678 //void RTFGenerator::endDescList()
1680 // DBG_RTF(t << "{\\comment (endDescList)}" << endl)
1682 // decrementIndentLevel();
1683 // m_omitParagraph = TRUE;
1688 void RTFGenerator::startSection(const char *,const char *title,SectionInfo::SectionType type)
1690 DBG_RTF(t << "{\\comment (startSection)}" << endl)
1692 t<< rtf_Style_Reset;
1696 case SectionInfo::Page: num=2; break;
1697 case SectionInfo::Section: num=3; break;
1698 case SectionInfo::Subsection: num=4; break;
1699 case SectionInfo::Subsubsection: num=4; break;
1700 case SectionInfo::Paragraph: num=4; break;
1701 default: ASSERT(0); break;
1704 heading.sprintf("Heading%d",num);
1706 t << rtf_Style[heading]->reference;
1707 // make table of contents entry
1708 t << "{\\tc\\tcl" << num << " \\v ";
1713 void RTFGenerator::endSection(const char *lab,SectionInfo::SectionType)
1715 DBG_RTF(t << "{\\comment (endSection)}" << endl)
1717 m_omitParagraph=FALSE;
1723 //void RTFGenerator::writeSectionRef(const char *ref,const char *,
1724 // const char *lab,const char *title)
1736 // docify(theTranslator->trPageAbbreviation());
1737 // writeRTFReference(lab);
1738 // t << ")" << endl;
1742 //void RTFGenerator::writeSectionRefItem(const char *,const char *lab,
1743 // const char *title)
1747 // writeRTFReference(lab);
1751 //void RTFGenerator::writeSectionRefAnchor(const char *name,const char *lab,
1752 // const char *title)
1754 // writeSectionRef(name,lab,title);
1757 //char* RTFGenerator::getMultiByte(int c)
1759 // static char s[10];
1761 // sprintf(s,"\\'%X",c);
1765 void RTFGenerator::docify(const char *str)
1769 const unsigned char *p=(const unsigned char *)str;
1771 //unsigned char pc='\0';
1774 //static bool MultiByte = FALSE;
1780 t << getMultiByte( c );
1787 t << getMultiByte( c );
1794 case '{': t << "\\{"; break;
1795 case '}': t << "\\}"; break;
1796 case '\\': t << "\\\\"; break;
1799 // see if we can insert an hyphenation hint
1800 //if (isupper(c) && islower(pc) && !insideTabbing) t << "\\-";
1805 m_omitParagraph = FALSE;
1810 void RTFGenerator::codify(const char *str)
1812 // note that RTF does not have a "verbatim", so "\n" means
1813 // nothing... add a "newParagraph()";
1814 //static char spaces[]=" ";
1817 const unsigned char *p=(const unsigned char *)str;
1819 int spacesToNextTabStop;
1823 //static bool MultiByte = FALSE;
1829 case '\t': spacesToNextTabStop = Config_getInt(TAB_SIZE) - (col%Config_getInt(TAB_SIZE));
1830 t << Doxygen::spaces.left(spacesToNextTabStop);
1831 col+=spacesToNextTabStop;
1833 case '\n': newParagraph();
1836 case '{': t << "\\{"; col++; break;
1837 case '}': t << "\\}"; col++; break;
1838 case '\\': t << "\\\\"; col++; break;
1839 default: p=(const unsigned char *)writeUtf8Char(t,(const char *)p-1); col++; break;
1845 void RTFGenerator::writeChar(char c)
1853 void RTFGenerator::startClassDiagram()
1855 DBG_RTF(t <<"{\\comment startClassDiagram }" << endl)
1858 void RTFGenerator::endClassDiagram(const ClassDiagram &d,
1859 const char *fileName,const char *)
1863 // create a png file
1864 d.writeImage(t,dir,relPath,fileName,FALSE);
1868 t << rtf_Style_Reset << endl;
1869 t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
1870 t << fileName << ".png\"";
1871 t << " \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
1875 //void RTFGenerator::writeFormula(const char *,const char *text)
1880 void RTFGenerator::startMemberItem(const char *,int,const char *)
1882 DBG_RTF(t <<"{\\comment startMemberItem }" << endl)
1883 t << rtf_Style_Reset << rtf_BList_DepthStyle() << endl; // set style to appropriate depth
1886 void RTFGenerator::endMemberItem()
1888 DBG_RTF(t <<"{\\comment endMemberItem }" << endl)
1892 void RTFGenerator::writeAnchor(const char *fileName,const char *name)
1899 if (fileName && name)
1908 DBG_RTF(t <<"{\\comment writeAnchor (" << anchor << ")}" << endl)
1909 t << "{\\bkmkstart " << rtfFormatBmkStr(anchor) << "}" << endl;
1910 t << "{\\bkmkend " << rtfFormatBmkStr(anchor) << "}" << endl;
1913 void RTFGenerator::writeRTFReference(const char *label)
1915 t << "{\\field\\fldedit {\\*\\fldinst PAGEREF ";
1916 t << rtfFormatBmkStr(label);
1917 t << " \\\\*MERGEFORMAT}{\\fldrslt pagenum}}";
1920 void RTFGenerator::startCodeFragment()
1922 DBG_RTF(t << "{\\comment (startCodeFragment) }" << endl)
1925 t << rtf_Style_Reset << rtf_Code_DepthStyle();
1926 //styleStack.push(rtf_Style_CodeExample);
1929 void RTFGenerator::endCodeFragment()
1933 //printf("RTFGenerator::endCodeFrament() top=%s\n",styleStack.top());
1934 //t << rtf_Style_Reset << styleStack.top() << endl;
1935 DBG_RTF(t << "{\\comment (endCodeFragment) }" << endl)
1937 m_omitParagraph = TRUE;
1940 void RTFGenerator::writeNonBreakableSpace(int)
1946 void RTFGenerator::startMemberList()
1949 DBG_RTF(t << "{\\comment (startMemberList) }" << endl)
1953 t << "\\begin{CompactItemize}" << endl;
1957 void RTFGenerator::endMemberList()
1959 DBG_RTF(t << "{\\comment (endMemberList) }" << endl)
1963 t << "\\end{CompactItemize}" << endl;
1967 //void RTFGenerator::startImage(const char *name,const char *,bool)
1970 // t << "{" << endl;
1971 // t << rtf_Style_Reset << endl;
1972 // t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE ";
1974 // t << " \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
1975 // t << "}" << endl;
1978 //void RTFGenerator::endImage(bool)
1980 // // not yet implemented
1983 //void RTFGenerator::startDotFile(const char *name,bool)
1985 // QCString baseName=name;
1987 // if ((i=baseName.findRev('/'))!=-1 || (i=baseName.findRev('\\'))!=-1)
1989 // baseName=baseName.right(baseName.length()-i-1);
1991 // QCString outDir = Config_getString(RTF_OUTPUT);
1992 // writeDotGraphFromFile(name,outDir,baseName,BITMAP);
1994 // t << "{" << endl;
1995 // t << rtf_Style_Reset << endl;
1996 // t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE ";
1997 // t << outDir << "\\" << baseName;
1998 // t << " \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
1999 // t << "}" << endl;
2002 //void RTFGenerator::endDotFile(bool)
2004 // // not yet implemented
2007 void RTFGenerator::startDescTable(const char *title)
2009 DBG_RTF(t << "{\\comment (startDescTable) }" << endl)
2010 t << "{\\par" << endl;
2011 t << "{" << rtf_Style["Heading5"]->reference << endl;
2013 t << ":\\par}" << endl;
2014 t << rtf_Style_Reset << rtf_DList_DepthStyle();
2015 t << "\\trowd \\trgaph108\\trleft426\\tblind426"
2016 "\\trbrdrt\\brdrs\\brdrw10\\brdrcf15 "
2017 "\\trbrdrl\\brdrs\\brdrw10\\brdrcf15 "
2018 "\\trbrdrb\\brdrs\\brdrw10\\brdrcf15 "
2019 "\\trbrdrr\\brdrs\\brdrw10\\brdrcf15 "
2020 "\\trbrdrh\\brdrs\\brdrw10\\brdrcf15 "
2021 "\\trbrdrv\\brdrs\\brdrw10\\brdrcf15 "<< endl;
2022 int i,columnPos[2] = { 25, 100 };
2025 t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10\\brdrcf15 "
2026 "\\clbrdrl\\brdrs\\brdrw10\\brdrcf15 "
2027 "\\clbrdrb\\brdrs\\brdrw10\\brdrcf15 "
2028 "\\clbrdrr \\brdrs\\brdrw10\\brdrcf15 "
2030 "\\cellx" << (rtf_pageWidth*columnPos[i]/100) << endl;
2032 t << "\\pard \\widctlpar\\intbl\\adjustright" << endl;
2035 void RTFGenerator::endDescTable()
2037 DBG_RTF(t << "{\\comment (endDescTable)}" << endl)
2041 void RTFGenerator::startDescTableRow()
2045 void RTFGenerator::endDescTableRow()
2049 void RTFGenerator::startDescTableTitle()
2051 DBG_RTF(t << "{\\comment (startDescTableTitle) }" << endl)
2055 void RTFGenerator::endDescTableTitle()
2057 DBG_RTF(t << "{\\comment (endDescTableTitle) }" << endl)
2061 void RTFGenerator::startDescTableData()
2063 DBG_RTF(t << "{\\comment (startDescTableData) }" << endl)
2067 void RTFGenerator::endDescTableData()
2069 DBG_RTF(t << "{\\comment (endDescTableData) }" << endl)
2070 t << "\\cell }{\\row }" << endl;
2073 // a style for list formatted as a "bulleted list"
2075 void RTFGenerator::incrementIndentLevel()
2078 if (m_listLevel>rtf_maxIndentLevels-1)
2080 err("Maximum indent level (%d) exceeded while generating RTF output!\n",rtf_maxIndentLevels);
2081 m_listLevel=rtf_maxIndentLevels-1;
2085 void RTFGenerator::decrementIndentLevel()
2090 err("Negative indent level while generating RTF output!\n");
2095 // a style for list formatted with "list continue" style
2096 const char * RTFGenerator::rtf_CList_DepthStyle()
2098 QCString n=makeIndexName("ListContinue",m_listLevel);
2099 return rtf_Style[n]->reference;
2102 // a style for list formatted as a "latext style" table of contents
2103 const char * RTFGenerator::rtf_LCList_DepthStyle()
2105 QCString n=makeIndexName("LatexTOC",m_listLevel);
2106 return rtf_Style[n]->reference;
2109 // a style for list formatted as a "bullet" style
2110 const char * RTFGenerator::rtf_BList_DepthStyle()
2112 QCString n=makeIndexName("ListBullet",m_listLevel);
2113 return rtf_Style[n]->reference;
2116 // a style for list formatted as a "enumeration" style
2117 const char * RTFGenerator::rtf_EList_DepthStyle()
2119 QCString n=makeIndexName("ListEnum",m_listLevel);
2120 return rtf_Style[n]->reference;
2123 const char * RTFGenerator::rtf_DList_DepthStyle()
2125 QCString n=makeIndexName("DescContinue",m_listLevel);
2126 return rtf_Style[n]->reference;
2129 const char * RTFGenerator::rtf_Code_DepthStyle()
2131 QCString n=makeIndexName("CodeExample",m_listLevel);
2132 return rtf_Style[n]->reference;
2135 void RTFGenerator::startTextBlock(bool dense)
2137 DBG_RTF(t << "{\\comment startTextBlock}" << endl)
2139 t << rtf_Style_Reset;
2140 if (dense) // no spacing between "paragraphs"
2142 t << rtf_Style["DenseText"]->reference;
2144 else // some spacing
2146 t << rtf_Style["BodyText"]->reference;
2150 void RTFGenerator::endTextBlock(bool /*paraBreak*/)
2153 DBG_RTF(t << "{\\comment endTextBlock}" << endl)
2155 //m_omitParagraph = TRUE;
2158 void RTFGenerator::newParagraph()
2160 if (!m_omitParagraph)
2162 DBG_RTF(t << "{\\comment (newParagraph)}" << endl)
2163 t << "\\par" << endl;
2165 m_omitParagraph = FALSE;
2168 void RTFGenerator::startParagraph(const char *)
2170 DBG_RTF(t << "{\\comment startParagraph}" << endl)
2175 void RTFGenerator::endParagraph()
2177 DBG_RTF(t << "{\\comment endParagraph}" << endl)
2178 t << "}\\par" << endl;
2179 m_omitParagraph = TRUE;
2182 void RTFGenerator::startMemberSubtitle()
2184 DBG_RTF(t << "{\\comment startMemberSubtitle}" << endl)
2186 t << rtf_Style_Reset << rtf_CList_DepthStyle() << endl;
2189 void RTFGenerator::endMemberSubtitle()
2191 DBG_RTF(t << "{\\comment endMemberSubtitle}" << endl)
2196 //void RTFGenerator::writeUmlaut(char c)
2200 // case 'A' : t << '\304'; break;
2201 // case 'E' : t << '\313'; break;
2202 // case 'I' : t << '\317'; break;
2203 // case 'O' : t << '\326'; break;
2204 // case 'U' : t << '\334'; break;
2205 // case 'Y' : t << 'Y'; break;
2206 // case 'a' : t << '\344'; break;
2207 // case 'e' : t << '\353'; break;
2208 // case 'i' : t << '\357'; break;
2209 // case 'o' : t << '\366'; break;
2210 // case 'u' : t << '\374'; break;
2211 // case 'y' : t << '\377'; break;
2212 // default: t << '?'; break;
2216 //void RTFGenerator::writeAcute(char c)
2220 // case 'A' : t << '\301'; break;
2221 // case 'E' : t << '\311'; break;
2222 // case 'I' : t << '\315'; break;
2223 // case 'O' : t << '\323'; break;
2224 // case 'U' : t << '\332'; break;
2225 // case 'Y' : t << '\335'; break;
2226 // case 'a' : t << '\341'; break;
2227 // case 'e' : t << '\351'; break;
2228 // case 'i' : t << '\355'; break;
2229 // case 'o' : t << '\363'; break;
2230 // case 'u' : t << '\372'; break;
2231 // case 'y' : t << '\375'; break;
2232 // default: t << '?'; break;
2236 //void RTFGenerator::writeGrave(char c)
2240 // case 'A' : t << '\300'; break;
2241 // case 'E' : t << '\310'; break;
2242 // case 'I' : t << '\314'; break;
2243 // case 'O' : t << '\322'; break;
2244 // case 'U' : t << '\331'; break;
2245 // case 'a' : t << '\340'; break;
2246 // case 'e' : t << '\350'; break;
2247 // case 'i' : t << '\354'; break;
2248 // case 'o' : t << '\362'; break;
2249 // case 'u' : t << '\371'; break;
2250 // default: t << '?'; break;
2254 //void RTFGenerator::writeCirc(char c)
2258 // case 'A' : t << '\302'; break;
2259 // case 'E' : t << '\312'; break;
2260 // case 'I' : t << '\316'; break;
2261 // case 'O' : t << '\324'; break;
2262 // case 'U' : t << '\333'; break;
2263 // case 'a' : t << '\342'; break;
2264 // case 'e' : t << '\352'; break;
2265 // case 'i' : t << '\356'; break;
2266 // case 'o' : t << '\364'; break;
2267 // case 'u' : t << '\373'; break;
2268 // default: t << '?'; break;
2272 //void RTFGenerator::writeTilde(char c)
2276 // case 'A' : t << '\303'; break;
2277 // case 'N' : t << '\321'; break;
2278 // case 'O' : t << '\325'; break;
2279 // case 'a' : t << '\343'; break;
2280 // case 'n' : t << '\361'; break;
2281 // case 'o' : t << '\365'; break;
2282 // default: t << '?'; break;
2286 //void RTFGenerator::writeRing(char c)
2290 // case 'A' : t << '\305'; break;
2291 // case 'a' : t << '\345'; break;
2292 // default: t << '?'; break;
2296 //void RTFGenerator::writeCCedil(char c)
2300 // case 'C' : t << '\307'; break;
2301 // case 'c' : t << '\347'; break;
2302 // default: t << '?'; break;
2307 bool isLeadBytes(int c)
2311 QCString codePage = theTranslator->trRTFansicp();
2313 if (codePage == "932") // cp932 (Japanese Shift-JIS)
2315 result = (0x81<=c && c<=0x9f) || (0xe0<=c && c<=0xfc);
2317 else if (codePage == "936") // cp936 (Simplified Chinese GBK)
2319 result = 0x81<=c && c<=0xFE;
2321 else if (codePage == "949") // cp949 (Korean)
2323 result = 0x81<=c && c<=0xFE;
2325 else if (codePage == "950") // cp950 (Traditional Chinese Big5)
2327 result = 0x81<=c && c<=0xFE;
2329 else // for SBCS Codepages (cp1252,1251 etc...)
2338 // note: function is not reentrant!
2339 static void encodeForOutput(FTextStream &t,const char *s)
2343 bool converted=FALSE;
2345 static QByteArray enc;
2346 if (l*4>(int)enc.size()) enc.resize(l*4); // worst case
2347 encoding.sprintf("CP%s",theTranslator->trRTFansicp().data());
2348 if (!encoding.isEmpty())
2350 // convert from UTF-8 back to the output encoding
2351 void *cd = portable_iconv_open(encoding,"UTF-8");
2352 if (cd!=(void *)(-1))
2355 size_t oLeft=enc.size();
2356 char *inputPtr = (char*)s;
2357 char *outputPtr = enc.data();
2358 if (!portable_iconv(cd, &inputPtr, &iLeft, &outputPtr, &oLeft))
2360 enc.resize(enc.size()-(unsigned int)oLeft);
2363 portable_iconv_close(cd);
2366 if (!converted) // if we did not convert anything, copy as is.
2368 memcpy(enc.data(),s,l);
2372 bool multiByte = FALSE;
2374 for (i=0;i<enc.size();i++)
2376 uchar c = (uchar)enc.at(i);
2378 if (c>=0x80 || multiByte)
2381 sprintf(esc,"\\'%X",c); // escape sequence for SBCS and DBCS(1st&2nd bytes).
2386 multiByte = isLeadBytes(c); // It may be DBCS Codepages.
2390 multiByte = FALSE; // end of Double Bytes Character.
2401 * VERY brittle routine inline RTF's included by other RTF's.
2402 * it is recursive and ugly.
2404 static bool preProcessFile(QDir &d,QCString &infName, FTextStream &t, bool bIncludeHeader=TRUE)
2407 if (!f.open(IO_ReadOnly))
2409 err("problems opening rtf file %s for reading\n",infName.data());
2413 const int maxLineLength = 10240;
2414 static QCString lineBuf(maxLineLength);
2416 // scan until find end of header
2417 // this is EXTREEEEEEEMLY brittle. It works on OUR rtf
2418 // files because the first line before the body
2419 // ALWAYS contains "{\comment begin body}"
2423 lineBuf.resize(maxLineLength);
2424 if ((len=f.readLine(lineBuf.rawData(),maxLineLength))==-1)
2426 err("read error in %s before end of RTF header!\n",infName.data());
2429 lineBuf.resize(len+1);
2430 if (lineBuf.find("\\comment begin body")!=-1) break;
2431 if (bIncludeHeader) encodeForOutput(t,lineBuf.data());
2435 lineBuf.resize(maxLineLength);
2436 while ((len=f.readLine(lineBuf.rawData(),maxLineLength))!=-1)
2438 lineBuf.resize(len+1);
2440 if ((pos=lineBuf.find("INCLUDETEXT"))!=-1)
2442 int startNamePos = lineBuf.find('"',pos)+1;
2443 int endNamePos = lineBuf.find('"',startNamePos);
2444 QCString fileName = lineBuf.mid(startNamePos,endNamePos-startNamePos);
2445 DBG_RTF(t << "{\\comment begin include " << fileName << "}" << endl)
2446 if (!preProcessFile(d,fileName,t,FALSE)) return FALSE;
2447 DBG_RTF(t << "{\\comment end include " << fileName << "}" << endl)
2449 else // no INCLUDETEXT on this line
2451 // elaborate hoopla to skip the final "}" if we didn't include the
2453 if (!f.atEnd() || bIncludeHeader)
2455 encodeForOutput(t,lineBuf);
2457 else // last line of included file
2459 // null terminate at the last '}'
2460 //char *str = strrchr(buffer,'}');
2461 int pos = lineBuf.findRev('}');
2464 lineBuf.at(pos) = '\0';
2466 err("Strange, the last char was not a '}'\n");
2467 encodeForOutput(t,lineBuf);
2470 lineBuf.resize(maxLineLength);
2473 // remove temporary file
2478 void RTFGenerator::startDotGraph()
2480 DBG_RTF(t << "{\\comment (startDotGraph)}" << endl)
2483 void RTFGenerator::endDotGraph(const DotClassGraph &g)
2488 g.writeGraph(t,GOF_BITMAP,EOF_Rtf,Config_getString(RTF_OUTPUT),fileName,relPath,TRUE,FALSE);
2492 t << rtf_Style_Reset << endl;
2493 t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
2494 QCString imgExt = getDotImageExtension();
2495 t << fn << "." << imgExt;
2496 t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
2499 DBG_RTF(t << "{\\comment (endDotGraph)}" << endl)
2502 void RTFGenerator::startInclDepGraph()
2504 DBG_RTF(t << "{\\comment (startInclDepGraph)}" << endl)
2507 void RTFGenerator::endInclDepGraph(const DotInclDepGraph &g)
2511 QCString fn = g.writeGraph(t,GOF_BITMAP,EOF_Rtf,Config_getString(RTF_OUTPUT),
2512 fileName,relPath,FALSE);
2516 t << rtf_Style_Reset << endl;
2517 t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
2518 QCString imgExt = getDotImageExtension();
2519 t << fn << "." << imgExt;
2520 t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
2522 DBG_RTF(t << "{\\comment (endInclDepGraph)}" << endl)
2525 void RTFGenerator::startGroupCollaboration()
2529 void RTFGenerator::endGroupCollaboration(const DotGroupCollaboration &)
2533 void RTFGenerator::startCallGraph()
2535 DBG_RTF(t << "{\\comment (startCallGraph)}" << endl)
2538 void RTFGenerator::endCallGraph(const DotCallGraph &g)
2542 QCString fn = g.writeGraph(t,GOF_BITMAP,EOF_Rtf,Config_getString(RTF_OUTPUT),
2543 fileName,relPath,FALSE);
2547 t << rtf_Style_Reset << endl;
2548 t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
2549 QCString imgExt = getDotImageExtension();
2550 t << fn << "." << imgExt;
2551 t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
2553 DBG_RTF(t << "{\\comment (endCallGraph)}" << endl)
2556 void RTFGenerator::startDirDepGraph()
2558 DBG_RTF(t << "{\\comment (startDirDepGraph)}" << endl)
2561 void RTFGenerator::endDirDepGraph(const DotDirDeps &g)
2565 QCString fn = g.writeGraph(t,GOF_BITMAP,EOF_Rtf,Config_getString(RTF_OUTPUT),
2566 fileName,relPath,FALSE);
2570 t << rtf_Style_Reset << endl;
2571 t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
2572 QCString imgExt = getDotImageExtension();
2573 t << fn << "." << imgExt;
2574 t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
2576 DBG_RTF(t << "{\\comment (endDirDepGraph)}" << endl)
2579 /** Tests the integrity of the result by counting brackets.
2582 void testRTFOutput(const char *name)
2588 if (f.open(IO_ReadOnly))
2590 while ((c=f.getch())!=-1)
2592 if (c=='\\') // escape char
2597 else if (c=='{') // open bracket
2601 else if (c=='}') // close bracket
2610 else if (c=='\n') // newline
2616 if (bcount==0) return; // file is OK.
2618 err("RTF integrity test failed at line %d of %s due to a bracket mismatch.\n"
2619 " Please try to create a small code example that produces this error \n"
2620 " and send that to dimitri@stack.nl.\n",line,name);
2624 * This is an API to a VERY brittle RTF preprocessor that combines nested
2625 * RTF files. This version replaces the infile with the new file
2627 bool RTFGenerator::preProcessFileInplace(const char *path,const char *name)
2630 // store the original directory
2633 err("Output dir %s does not exist!\n",path);
2636 QCString oldDir = QDir::currentDirPath().utf8();
2638 // go to the html output directory (i.e. path)
2639 QDir::setCurrent(d.absPath());
2642 QCString combinedName = (QCString)path+"/combined.rtf";
2643 QCString mainRTFName = (QCString)path+"/"+name;
2645 QFile outf(combinedName);
2646 if (!outf.open(IO_WriteOnly))
2648 err("Failed to open %s for writing!\n",combinedName.data());
2649 QDir::setCurrent(oldDir);
2652 FTextStream outt(&outf);
2654 if (!preProcessFile(thisDir,mainRTFName,outt))
2656 // it failed, remove the temp file
2658 thisDir.remove(combinedName);
2659 QDir::setCurrent(oldDir);
2663 // everything worked, move the files
2665 thisDir.remove(mainRTFName);
2666 thisDir.rename(combinedName,mainRTFName);
2668 testRTFOutput(mainRTFName);
2670 QDir::setCurrent(oldDir);
2674 void RTFGenerator::startMemberGroupHeader(bool hasHeader)
2676 DBG_RTF(t << "{\\comment startMemberGroupHeader}" << endl)
2678 if (hasHeader) incrementIndentLevel();
2679 t << rtf_Style_Reset << rtf_Style["GroupHeader"]->reference;
2682 void RTFGenerator::endMemberGroupHeader()
2684 DBG_RTF(t << "{\\comment endMemberGroupHeader}" << endl)
2686 t << rtf_Style_Reset << rtf_CList_DepthStyle();
2689 void RTFGenerator::startMemberGroupDocs()
2691 DBG_RTF(t << "{\\comment startMemberGroupDocs}" << endl)
2695 void RTFGenerator::endMemberGroupDocs()
2697 DBG_RTF(t << "{\\comment endMemberGroupDocs}" << endl)
2702 void RTFGenerator::startMemberGroup()
2704 DBG_RTF(t << "{\\comment startMemberGroup}" << endl)
2705 t << rtf_Style_Reset << rtf_BList_DepthStyle() << endl;
2708 void RTFGenerator::endMemberGroup(bool hasHeader)
2710 DBG_RTF(t << "{\\comment endMemberGroup}" << endl)
2711 if (hasHeader) decrementIndentLevel();
2715 void RTFGenerator::startSimpleSect(SectionTypes,const char *file,const char *anchor,const char *title)
2717 DBG_RTF(t << "{\\comment (startSimpleSect)}" << endl)
2718 t << "{"; // ends at endDescList
2719 t << "{"; // ends at endDescTitle
2724 writeObjectLink(0,file,anchor,title);
2733 incrementIndentLevel();
2734 t << rtf_Style_Reset << rtf_DList_DepthStyle();
2737 void RTFGenerator::endSimpleSect()
2739 DBG_RTF(t << "{\\comment (endSimpleSect)}" << endl)
2740 m_omitParagraph = FALSE;
2742 decrementIndentLevel();
2743 m_omitParagraph = TRUE;
2747 void RTFGenerator::startParamList(ParamListTypes,const char *title)
2749 DBG_RTF(t << "{\\comment (startParamList)}" << endl)
2750 t << "{"; // ends at endParamList
2751 t << "{"; // ends at endDescTitle
2758 incrementIndentLevel();
2759 t << rtf_Style_Reset << rtf_DList_DepthStyle();
2762 void RTFGenerator::endParamList()
2764 DBG_RTF(t << "{\\comment (endParamList)}" << endl)
2766 decrementIndentLevel();
2767 m_omitParagraph = TRUE;
2771 void RTFGenerator::startParameterType(bool first,const char *key)
2773 DBG_RTF(t << "{\\comment (startParameterType)}" << endl)
2776 t << " " << key << " ";
2780 void RTFGenerator::endParameterType()
2782 DBG_RTF(t << "{\\comment (endParameterType)}" << endl)
2786 void RTFGenerator::exceptionEntry(const char* prefix,bool closeBracket)
2788 DBG_RTF(t << "{\\comment (exceptionEntry)}" << endl)
2791 else if (closeBracket)
2796 void RTFGenerator::writeDoc(DocNode *n,Definition *ctx,MemberDef *)
2798 RTFDocVisitor *visitor = new RTFDocVisitor(t,*this,ctx?ctx->getDefFileExtension():QCString(""));
2801 m_omitParagraph = TRUE;
2804 void RTFGenerator::rtfwriteRuler_doubleline()
2806 DBG_RTF(t << "{\\comment (rtfwriteRuler_doubleline)}" << endl)
2807 t << "{\\pard\\widctlpar\\brdrb\\brdrdb\\brdrw15\\brsp20 \\adjustright \\par}" << endl;
2810 void RTFGenerator::rtfwriteRuler_emboss()
2812 DBG_RTF(t << "{\\comment (rtfwriteRuler_emboss)}" << endl)
2813 t << "{\\pard\\widctlpar\\brdrb\\brdremboss\\brdrw15\\brsp20 \\adjustright \\par}" << endl;
2816 void RTFGenerator::rtfwriteRuler_thick()
2818 DBG_RTF(t << "{\\comment (rtfwriteRuler_thick)}" << endl)
2819 t << "{\\pard\\widctlpar\\brdrb\\brdrs\\brdrw75\\brsp20 \\adjustright \\par}" << endl;
2822 void RTFGenerator::rtfwriteRuler_thin()
2824 DBG_RTF(t << "{\\comment (rtfwriteRuler_thin)}" << endl)
2825 t << "{\\pard\\widctlpar\\brdrb\\brdrs\\brdrw5\\brsp20 \\adjustright \\par}" << endl;
2829 void RTFGenerator::postProcess(QByteArray &a)
2831 QByteArray enc(a.size()*4); // worst case
2835 for (i=0;i<a.size();i++)
2837 unsigned char c = (unsigned char)a.at(i);
2839 // treat characters > 0x80 as multibyte characters, except when they
2840 // are control characters
2841 if (c>0x80 || (mbFlag && c!='\\' && c!='{' && c!='}'))
2844 sprintf(s,"\\'%X",c);
2845 qstrcpy(enc.data()+off,s);
2859 void RTFGenerator::startConstraintList(const char *header)
2861 DBG_RTF(t << "{\\comment (startConstraintList)}" << endl)
2862 t << "{"; // ends at endConstraintList
2870 incrementIndentLevel();
2871 t << rtf_Style_Reset << rtf_DList_DepthStyle();
2874 void RTFGenerator::startConstraintParam()
2876 DBG_RTF(t << "{\\comment (startConstraintParam)}" << endl)
2880 void RTFGenerator::endConstraintParam()
2882 DBG_RTF(t << "{\\comment (endConstraintParam)}" << endl)
2887 void RTFGenerator::startConstraintType()
2889 DBG_RTF(t << "{\\comment (startConstraintType)}" << endl)
2893 void RTFGenerator::endConstraintType()
2895 DBG_RTF(t << "{\\comment (endConstraintType)}" << endl)
2900 void RTFGenerator::startConstraintDocs()
2902 DBG_RTF(t << "{\\comment (startConstraintDocs)}" << endl)
2905 void RTFGenerator::endConstraintDocs()
2907 DBG_RTF(t << "{\\comment (endConstraintDocs)}" << endl)
2911 void RTFGenerator::endConstraintList()
2913 DBG_RTF(t << "{\\comment (endConstraintList)}" << endl)
2915 decrementIndentLevel();
2916 m_omitParagraph = TRUE;
2920 void RTFGenerator::startIndexListItem()
2922 DBG_RTF(t << "{\\comment (startIndexListItem)}" << endl)
2925 void RTFGenerator::endIndexListItem()
2927 DBG_RTF(t << "{\\comment (endIndexListItem)}" << endl)
2928 t << "\\par" << endl;
2931 void RTFGenerator::startInlineHeader()
2933 DBG_RTF(t << "{\\comment (startInlineHeader)}" << endl)
2935 t << rtf_Style_Reset << rtf_Style["Heading5"]->reference;
2939 void RTFGenerator::endInlineHeader()
2941 DBG_RTF(t << "{\\comment (endInlineHeader)}" << endl)
2947 void RTFGenerator::startMemberDocSimple(bool isEnum)
2949 DBG_RTF(t << "{\\comment (startMemberDocSimple)}" << endl)
2950 t << "{\\par" << endl;
2951 t << "{" << rtf_Style["Heading5"]->reference << endl;
2954 t << theTranslator->trEnumerationValues();
2958 t << theTranslator->trCompoundMembers();
2960 t << ":\\par}" << endl;
2961 t << rtf_Style_Reset << rtf_DList_DepthStyle();
2962 t << "\\trowd \\trgaph108\\trleft426\\tblind426"
2963 "\\trbrdrt\\brdrs\\brdrw10\\brdrcf15 "
2964 "\\trbrdrl\\brdrs\\brdrw10\\brdrcf15 "
2965 "\\trbrdrb\\brdrs\\brdrw10\\brdrcf15 "
2966 "\\trbrdrr\\brdrs\\brdrw10\\brdrcf15 "
2967 "\\trbrdrh\\brdrs\\brdrw10\\brdrcf15 "
2968 "\\trbrdrv\\brdrs\\brdrw10\\brdrcf15 "<< endl;
2969 int i,n=3,columnPos[3] = { 25, 50, 100 };
2978 t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10\\brdrcf15 "
2979 "\\clbrdrl\\brdrs\\brdrw10\\brdrcf15 "
2980 "\\clbrdrb\\brdrs\\brdrw10\\brdrcf15 "
2981 "\\clbrdrr \\brdrs\\brdrw10\\brdrcf15 "
2983 "\\cellx" << (rtf_pageWidth*columnPos[i]/100) << endl;
2985 t << "\\pard \\widctlpar\\intbl\\adjustright" << endl;
2988 void RTFGenerator::endMemberDocSimple(bool)
2990 DBG_RTF(t << "{\\comment (endMemberDocSimple)}" << endl)
2994 void RTFGenerator::startInlineMemberType()
2996 DBG_RTF(t << "{\\comment (startInlineMemberType)}" << endl)
3000 void RTFGenerator::endInlineMemberType()
3002 DBG_RTF(t << "{\\comment (endInlineMemberType)}" << endl)
3006 void RTFGenerator::startInlineMemberName()
3008 DBG_RTF(t << "{\\comment (startInlineMemberName)}" << endl)
3012 void RTFGenerator::endInlineMemberName()
3014 DBG_RTF(t << "{\\comment (endInlineMemberName)}" << endl)
3018 void RTFGenerator::startInlineMemberDoc()
3020 DBG_RTF(t << "{\\comment (startInlineMemberDoc)}" << endl)
3024 void RTFGenerator::endInlineMemberDoc()
3026 DBG_RTF(t << "{\\comment (endInlineMemberDoc)}" << endl)
3027 t << "\\cell }{\\row }" << endl;
3030 void RTFGenerator::startLabels()
3034 void RTFGenerator::writeLabel(const char *l,bool isLast)
3036 t << "{\\f2 [" << l << "]}";
3037 if (!isLast) t << ", ";
3040 void RTFGenerator::endLabels()