rtfgen.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  * $Id: rtfgen.cpp,v 1.14 2001/03/19 19:27:41 root Exp $
00004  *
00005  * Copyright (C) 1997-2008 by Parker Waechter & Dimitri van Heesch.
00006  *
00007  * Style sheet additions by Alexander Bartolich
00008  *
00009  * Permission to use, copy, modify, and distribute this software and its
00010  * documentation under the terms of the GNU General Public License is hereby
00011  * granted. No representations are made about the suitability of this software
00012  * for any purpose. It is provided "as is" without express or implied warranty.
00013  * See the GNU General Public License for more details.
00014  *
00015  * Documents produced by Doxygen are derivative works derived from the
00016  * input used in their production; they are not affected by this license.
00017  *
00018  */
00019 
00020 #include <stdlib.h>
00021 
00022 #include "qtbc.h"
00023 #include <qdir.h>
00024 #include <qregexp.h>
00025 
00026 #include "rtfgen.h"
00027 #include "config.h"
00028 #include "message.h"
00029 #include "doxygen.h"
00030 #include "util.h"
00031 #include "diagram.h"
00032 #include "language.h"
00033 #include "dot.h"
00034 #include "version.h"
00035 #include "pagedef.h"
00036 #include "rtfstyle.h"
00037 #include "rtfdocvisitor.h"
00038 #include "docparser.h"
00039 #include "dirdef.h"
00040 #include "vhdldocgen.h"
00041 
00042 //#define DBG_RTF(x) x;
00043 #define DBG_RTF(x)
00044 
00045 static QCString dateToRTFDateString()
00046 {
00047   const QDateTime &d = QDateTime::currentDateTime();
00048   QCString result;
00049   result.sprintf("\\yr%d\\mo%d\\dy%d\\hr%d\\min%d\\sec%d",
00050       d.date().year(), d.date().month(), d.date().day(),
00051       d.time().hour(),d.time().minute(),d.time().second());
00052   return result;
00053 } 
00054 
00055 RTFGenerator::RTFGenerator() : OutputGenerator()
00056 {
00057   dir=Config_getString("RTF_OUTPUT");
00058   col=0;
00059   //insideTabbing=FALSE;
00060   m_listLevel = 0;
00061   m_bstartedBody = FALSE;
00062   m_omitParagraph = FALSE;
00063   m_numCols = 0;
00064 }
00065 
00066 RTFGenerator::~RTFGenerator()
00067 {
00068 }
00069 
00070 //void RTFGenerator::append(const OutputGenerator *g)
00071 //{
00072 //  t << g->getContents();
00073 //  col+=((RTFGenerator *)g)->col;
00074 //  //insideTabbing=insideTabbing || ((RTFGenerator *)g)->insideTabbing;
00075 //  m_listLevel=((RTFGenerator *)g)->m_listLevel;
00076 //  m_omitParagraph=((RTFGenerator *)g)->m_omitParagraph;
00077 //  //printf("RTFGenerator::append(%s) insideTabbing=%s\n", g->getContents().data(),
00078 //  //    insideTabbing ? "TRUE" : "FALSE" );
00079 //}
00080 
00081 //OutputGenerator *RTFGenerator::copy()
00082 //{
00083 //  RTFGenerator *result = new RTFGenerator;
00084 //  //result->insideTabbing=insideTabbing;
00085 //  result->m_listLevel=m_listLevel;
00086 //  result->m_omitParagraph=m_omitParagraph;
00087 //  return result;
00088 //}
00089 
00090 void RTFGenerator::writeStyleSheetFile(QFile &file)
00091 {
00092   QTextStream t(&file);
00093   t << "# Generated by doxygen " << versionString << "\n\n";
00094   t << "# This file describes styles used for generating RTF output.\n";
00095   t << "# All text after a hash (#) is considered a comment and will be ignored.\n";
00096   t << "# Remove a hash to activate a line.\n\n";
00097 
00098   int i;
00099   for ( i=0 ; rtf_Style_Default[i].reference!=0 ; i++ )
00100   {
00101     t << "# " << rtf_Style_Default[i].name << " = "
00102               << rtf_Style_Default[i].reference
00103               << rtf_Style_Default[i].definition << endl;
00104   }
00105 }
00106 
00107 void RTFGenerator::writeExtensionsFile(QFile &file)
00108 {
00109   QTextStream t(&file);
00110   t << "# Generated by doxygen " << versionString << "\n\n";
00111   t << "# This file describes extensions used for generating RTF output.\n";
00112   t << "# All text after a hash (#) is considered a comment and will be ignored.\n";
00113   t << "# Remove a hash to activate a line.\n\n";
00114 
00115   t << "# Overrides the project title.\n";
00116 
00117   t << "#Title           = \n\n";
00118 
00119   t << "# Name of the company that produced this document.\n";
00120   t << "#Company         = \n\n";
00121 
00122   t << "# Filename of a company or project logo.\n";
00123   t << "#LogoFilename    = \n\n";
00124 
00125   t << "# Author of the document.\n";
00126   t << "#Author          = \n\n";
00127 
00128   t << "# Type of document (e.g. Design Specification, User Manual, etc.).\n";
00129   t << "#DocumentType    = \n\n";
00130 
00131   t << "# Document tracking number.\n";
00132   t << "#DocumentId      = \n\n";
00133 
00134   t << "# Name of the author's manager.\n";
00135   t << "# This field is not displayed in the document itself, but it is \n";
00136   t << "# available in the information block of the rtf file.  In Microsoft \n";
00137   t << "# Word, it is available under File:Properties.\n";
00138   t << "#Manager         = \n\n";
00139 
00140   t << "# Subject of the document.\n";
00141   t << "# This field is not displayed in the document itself, but it is \n";
00142   t << "# available in the information block of the rtf file.  In Microsoft \n";
00143   t << "# Word, it is available under File:Properties.\n";
00144   t << "#Subject         = \n\n";
00145 
00146   t << "# Comments regarding the document.\n";
00147   t << "# This field is not displayed in the document itself, but it is \n";
00148   t << "# available in the information block of the rtf file.  In Microsoft \n";
00149   t << "# Word, it is available under File:Properties.\n";
00150   t << "#Comments        = \n\n";
00151 
00152   t << "# Keywords associated with the document.\n";
00153   t << "# This field is not displayed in the document itself, but it is \n";
00154   t << "# available in the information block of the rtf file.  In Microsoft \n";
00155   t << "# Word, it is available under File:Properties.\n";
00156   t << "#Keywords        = \n\n";
00157 }
00158 
00159 
00160 void RTFGenerator::init()
00161 {
00162   QCString dir=Config_getString("RTF_OUTPUT");
00163   QDir d(dir);
00164   if (!d.exists() && !d.mkdir(dir))
00165   {
00166     err("Could not create output directory %s\n",dir.data());
00167     exit(1);
00168   }
00169   rtf_Style.setAutoDelete(TRUE);
00170 
00171   // first duplicate strings of rtf_Style_Default
00172   const struct Rtf_Style_Default* def = rtf_Style_Default;
00173   while(def->reference != 0)
00174   {
00175     if (def->definition == 0)
00176       err("Internal error: rtf_Style_Default[%s] has no definition.\n", def->name);
00177     StyleData* styleData = new StyleData(def->reference, def->definition);
00178     rtf_Style.insert(def->name, styleData);
00179     def++;
00180   }
00181 
00182   // overwrite some (or all) definitions from file
00183   QCString &rtfStyleSheetFile = Config_getString("RTF_STYLESHEET_FILE");
00184   if (!rtfStyleSheetFile.isEmpty())
00185   {
00186     loadStylesheet(rtfStyleSheetFile, rtf_Style);
00187   }
00188 
00189   // If user has defined an extension file, load its contents.
00190   QCString &rtfExtensionsFile = Config_getString("RTF_EXTENSIONS_FILE");
00191   if (!rtfExtensionsFile.isEmpty())
00192   {
00193     loadExtensions(rtfExtensionsFile);
00194   }
00195 
00196   createSubDirs(d);
00197 }
00198 
00199 static QCString makeIndexName(const char *s,int i)
00200 {
00201   QCString result=s;
00202   result+=(char)(i+'0');
00203   return result;
00204 }
00205 
00206 void RTFGenerator::beginRTFDocument()
00207 {
00208   /* all the included RTF files should begin with the
00209    * same header
00210    */
00211   t <<"{\\rtf1\\ansi\\ansicpg" << theTranslator->trRTFansicp();
00212   t <<"\\uc1 \\deff0\\deflang1033\\deflangfe1033\n";
00213 
00214   DBG_RTF(t <<"{\\comment Begining font list}\n")
00215   t <<"{\\fonttbl ";
00216   t <<"{\\f0\\froman\\fcharset" << theTranslator->trRTFCharSet();
00217   t <<"\\fprq2{\\*\\panose 02020603050405020304}Times New Roman;}\n";
00218   t <<"{\\f1\\fswiss\\fcharset" << theTranslator->trRTFCharSet();
00219   t <<"\\fprq2{\\*\\panose 020b0604020202020204}Arial;}\n";
00220   t <<"{\\f2\\fmodern\\fcharset" << theTranslator->trRTFCharSet();
00221   t <<"\\fprq1{\\*\\panose 02070309020205020404}Courier New;}\n";
00222   t <<"{\\f3\\froman\\fcharset2\\fprq2{\\*\\panose 05050102010706020507}Symbol;}\n";
00223   t <<"}\n";
00224   DBG_RTF(t <<"{\\comment begin colors}\n")
00225   t <<"{\\colortbl;";
00226   t <<"\\red0\\green0\\blue0;";
00227   t <<"\\red0\\green0\\blue255;";
00228   t <<"\\red0\\green255\\blue255;";
00229   t <<"\\red0\\green255\\blue0;";
00230   t <<"\\red255\\green0\\blue255;";
00231   t <<"\\red255\\green0\\blue0;";
00232   t <<"\\red255\\green255\\blue0;";
00233   t <<"\\red255\\green255\\blue255;";
00234   t <<"\\red0\\green0\\blue128;";
00235   t <<"\\red0\\green128\\blue128;";
00236   t <<"\\red0\\green128\\blue0;";
00237   t <<"\\red128\\green0\\blue128;";
00238   t <<"\\red128\\green0\\blue0;";
00239   t <<"\\red128\\green128\\blue0;";
00240   t <<"\\red128\\green128\\blue128;";
00241   t <<"\\red192\\green192\\blue192;}" << endl;
00242 
00243   DBG_RTF(t <<"{\\comment Beginning style list}\n")
00244   t <<"{\\stylesheet\n";
00245   t <<"{\\widctlpar\\adjustright \\fs20\\cgrid \\snext0 Normal;}\n";
00246 
00247   // sort styles ascending by \s-number via an intermediate QArray
00248   QArray<const StyleData*> array(128);
00249   array.fill(0);
00250   QDictIterator<StyleData> iter(rtf_Style);
00251   const StyleData* style;
00252   for(; (style = iter.current()); ++iter)
00253   {
00254     unsigned index = style->index;
00255     unsigned size = array.size();
00256     if (index >= size)
00257     {
00258       // +1 to add at least one element, then align up to multiple of 8
00259       array.resize((index + 1 + 7) & ~7);
00260       array.fill(0, size);
00261       ASSERT(index < array.size());
00262     }
00263     if (array.at(index) != 0)
00264     {
00265       QCString key(convertToQCString(iter.currentKey()));
00266       msg("Style '%s' redefines \\s%d.\n", key.data(), index);
00267     }
00268     array.at(index) = style;
00269   }
00270 
00271   // write array elements
00272   unsigned size = array.size();
00273   for(unsigned i = 0; i < size; i++)
00274   {
00275     const StyleData* style = array.at(i);
00276     if (style != 0)
00277       t <<"{" << style->reference << style->definition << ";}\n";
00278   }
00279 
00280   t <<"}" << endl;
00281   // this comment is needed for postprocessing!
00282   t <<"{\\comment begin body}" << endl;
00283 
00284 }
00285 
00286 void RTFGenerator::beginRTFChapter()
00287 {
00288   t <<"\n";
00289   DBG_RTF(t << "{\\comment BeginRTFChapter}\n")
00290   t << rtf_Style_Reset;
00291 
00292   // if we are compact, no extra page breaks...
00293   if (Config_getBool("COMPACT_RTF"))
00294   {
00295     //      t <<"\\sect\\sectd\\sbknone\n";
00296     t <<"\\sect\\sbknone\n";
00297     rtfwriteRuler_thick();
00298   }
00299   else
00300     t <<"\\sect\\sbkpage\n";
00301   //t <<"\\sect\\sectd\\sbkpage\n";
00302 
00303   t << rtf_Style["Heading1"]->reference << "\n";
00304 }
00305 
00306 void RTFGenerator::beginRTFSection()
00307 {
00308   t <<"\n";
00309   DBG_RTF(t << "{\\comment BeginRTFSection}\n")
00310   t << rtf_Style_Reset;
00311 
00312   // if we are compact, no extra page breaks...
00313   if (Config_getBool("COMPACT_RTF"))
00314   {
00315     //      t <<"\\sect\\sectd\\sbknone\n";
00316     t <<"\\sect\\sbknone\n";
00317     rtfwriteRuler_emboss();
00318   }
00319   else
00320     t <<"\\sect\\sbkpage\n";
00321   //t <<"\\sect\\sectd\\sbkpage\n";
00322 
00323   t << rtf_Style["Heading2"]->reference << "\n";
00324 }
00325 
00326 void RTFGenerator::startFile(const char *name,const char *,const char *)
00327 {
00328   setEncoding(QCString().sprintf("CP%s",theTranslator->trRTFansicp().data()));
00329   QCString fileName=name;
00330   relPath = relativePathToRoot(fileName);
00331 
00332   if (fileName.right(4)!=".rtf" ) fileName+=".rtf";
00333   startPlainFile(fileName);
00334   beginRTFDocument();
00335 }
00336 
00337 void RTFGenerator::endFile()
00338 {
00339   DBG_RTF(t << "{\\comment endFile}\n")
00340   t << "}";
00341 
00342   endPlainFile();
00343 }
00344 
00345 void RTFGenerator::startProjectNumber()
00346 {
00347   DBG_RTF(t <<"{\\comment startProjectNumber }" << endl)
00348   t << " ";
00349 }
00350 
00351 void RTFGenerator::endProjectNumber()
00352 {
00353   DBG_RTF(t <<"{\\comment endProjectNumber }" << endl)
00354 }
00355 
00356 void RTFGenerator::startIndexSection(IndexSections is)
00357 {
00358   //QCString paperName;
00359 
00360   m_listLevel = 0;
00361 
00362   switch (is)
00363   {
00364     case isTitlePageStart:
00365       // basic RTFstart
00366       // get readyfor author etc
00367 
00368       t << "{\\info \n";
00369       t << "{\\title {\\comment ";
00370       break;
00371     case isTitlePageAuthor:
00372       t << "}\n";
00373       if (rtf_subject)      t << "{\\subject "  << rtf_subject      << "}\n";
00374       if (rtf_comments)     t << "{\\comment "  << rtf_comments     << "}\n";
00375       if (rtf_company)      t << "{\\company "  << rtf_company      << "}\n";
00376       if (rtf_author)       t << "{\\author "   << rtf_author       << "}\n";
00377       if (rtf_manager)      t << "{\\manager "  << rtf_manager      << "}\n";
00378       if (rtf_documentType) t << "{\\category " << rtf_documentType << "}\n";
00379       if (rtf_keywords)     t << "{\\keywords " << rtf_keywords     << "}\n";
00380       t << "{\\comment ";
00381       break;
00382     case isMainPage:
00383       //Introduction
00384       beginRTFChapter();
00385       break;
00386     //case isPackageIndex:
00387     //  //Package Index
00388     //  beginRTFChapter();
00389     //  break;
00390     case isModuleIndex:
00391       //Module Index
00392       beginRTFChapter();
00393       break;
00394     case isDirIndex:
00395       //Directory Index
00396       beginRTFChapter();
00397       break;
00398     case isNamespaceIndex:
00399       //Namespace Index
00400       beginRTFChapter();
00401       break;
00402     case isClassHierarchyIndex:
00403       //Hierarchical Index
00404       DBG_RTF(t << "{\\comment start classhierarchy}\n")
00405       beginRTFChapter();
00406       break;
00407     case isCompoundIndex:
00408       //Annotated Compound Index
00409       beginRTFChapter();
00410       break;
00411     case isFileIndex:
00412       //Annotated File Index
00413       beginRTFChapter();
00414       break;
00415     case isPageIndex:
00416       //Related Page Index
00417       beginRTFChapter();
00418       break;
00419     case isModuleDocumentation:
00420       {
00421         //Module Documentation
00422         GroupSDict::Iterator gli(*Doxygen::groupSDict);
00423         GroupDef *gd;
00424         bool found=FALSE;
00425         for (gli.toFirst();(gd=gli.current()) && !found;++gli)
00426         {
00427           if (!gd->isReference())
00428           {
00429             beginRTFChapter();
00430             found=TRUE;
00431           }
00432         }
00433       }
00434       break;
00435     case isDirDocumentation:
00436       {
00437         //Directory Documentation
00438         SDict<DirDef>::Iterator dli(*Doxygen::directories);
00439         DirDef *dd;
00440         bool found=FALSE;
00441         for (dli.toFirst();(dd=dli.current()) && !found;++dli)
00442         {
00443           if (dd->isLinkableInProject())
00444           {
00445             beginRTFChapter();
00446             found=TRUE;
00447           }
00448         }
00449       }
00450       break;
00451     case isNamespaceDocumentation:
00452       {
00453         // Namespace Documentation
00454         NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
00455         NamespaceDef *nd;
00456         bool found=FALSE;
00457         for (nli.toFirst();(nd=nli.current()) && !found;++nli)
00458         {
00459           if (nd->isLinkableInProject())
00460           {
00461             beginRTFChapter();
00462             found=TRUE;
00463           }
00464         }
00465       }
00466       break;
00467     case isClassDocumentation:
00468       {
00469         //Compound Documentation
00470         ClassSDict::Iterator cli(*Doxygen::classSDict);
00471         ClassDef *cd=0;
00472         bool found=FALSE;
00473         for (cli.toFirst();(cd=cli.current()) && !found;++cli)
00474         {
00475           if (cd->isLinkableInProject() && cd->templateMaster()==0)
00476           {
00477             beginRTFChapter();
00478             found=TRUE;
00479           }
00480         }
00481       }
00482       break;
00483     case isFileDocumentation:
00484       {
00485         //File Documentation
00486         bool isFirst=TRUE;
00487         FileName *fn=Doxygen::inputNameList->first();
00488         while (fn)
00489         {
00490           FileDef *fd=fn->first();
00491           while (fd)
00492           {
00493             if (fd->isLinkableInProject())
00494             {
00495               if (isFirst)
00496               {
00497                 beginRTFChapter();
00498                 isFirst=FALSE;
00499                 break;
00500               }
00501             }
00502             fd=fn->next();
00503           }
00504           fn=Doxygen::inputNameList->next();
00505         }
00506       }
00507       break;
00508     case isExampleDocumentation:
00509       {
00510         //Example Documentation
00511         beginRTFChapter();
00512       }
00513       break;
00514     case isPageDocumentation:
00515       {
00516         //Page Documentation
00517         beginRTFChapter();
00518         t << "{\\tc \\v ";
00519       }
00520       break;
00521     case isEndIndex:
00522       break;
00523   }
00524 }
00525 
00526 void RTFGenerator::endIndexSection(IndexSections is)
00527 {
00528   bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
00529   bool vhdlOpt    = Config_getBool("OPTIMIZE_OUTPUT_VHDL");  
00530   switch (is)
00531   {
00532     case isTitlePageStart:
00533       if (rtf_title)
00534         // User has overridden document title in extensions file
00535         t << "}" << rtf_title;
00536       else
00537         t << "}" << Config_getString("PROJECT_NAME");
00538       break;
00539     case isTitlePageAuthor:
00540       {
00541         t << "Doxgyen. }\n";
00542         t << "{\\creatim " << dateToRTFDateString() << "}\n}";
00543         DBG_RTF(t << "{\\comment end of infoblock}\n");
00544         // setup for this section
00545         t << rtf_Style_Reset <<"\n";
00546         t <<"\\sectd\\pgnlcrm\n";
00547         t <<"{\\footer "<<rtf_Style["Footer"]->reference << "{\\chpgn}}\n";
00548         // the title entry
00549         DBG_RTF(t << "{\\comment begin title page}\n")
00550 
00551 
00552         t << rtf_Style_Reset << rtf_Style["SubTitle"]->reference << endl; // set to title style
00553 
00554         t << "\\vertalc\\qc\\par\\par\\par\\par\\par\\par\\par\n";
00555         if (rtf_logoFilename)
00556         {
00557           t << "{\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"" << rtf_logoFilename;
00558           t << "\" \\\\d \\\\*MERGEFORMAT} {\\fldrslt IMAGE }}\\par\\par\n";
00559         }
00560         if (rtf_company)
00561         {
00562           t << rtf_company << "\\par\\par\n";
00563         }
00564 
00565         t << rtf_Style_Reset << rtf_Style["Title"]->reference << endl; // set to title style
00566         t << "{\\field\\fldedit {\\*\\fldinst TITLE \\\\*MERGEFORMAT}{\\fldrslt TITLE}}\\par" << endl;
00567 
00568         t << rtf_Style_Reset << rtf_Style["SubTitle"]->reference << endl; // set to title style
00569         t << "\\par\n";
00570         if (rtf_documentType)
00571         {
00572           t << rtf_documentType << "\\par\n";
00573         }
00574         if (rtf_documentId)
00575         {
00576           t << rtf_documentId << "\\par\n";
00577         }
00578         t << "\\par\\par\\par\\par\\par\\par\\par\\par\\par\\par\\par\\par\n";
00579 
00580         t << rtf_Style_Reset << rtf_Style["SubTitle"]->reference << endl; // set to subtitle style
00581         t << "{\\field\\fldedit {\\*\\fldinst AUTHOR \\\\*MERGEFORMAT}{\\fldrslt AUTHOR}}\\par" << endl;
00582         t << "Version " << Config_getString("PROJECT_NUMBER") << "\\par";
00583         t << "{\\field\\fldedit {\\*\\fldinst CREATEDATE \\\\*MERGEFORMAT}"
00584           "{\\fldrslt CREATEDATE}}\\par"<<endl;
00585         t << "\\page\\page";
00586         DBG_RTF(t << "{\\comment End title page}" << endl)
00587 
00588         // table of contents section
00589         DBG_RTF(t << "{\\comment Table of contents}\n")
00590         t << "\\vertalt\n";
00591         t << rtf_Style_Reset << endl;
00592         t << rtf_Style["Heading1"]->reference;
00593         t << theTranslator->trRTFTableOfContents() << "\\par"<< endl;
00594         t << rtf_Style_Reset << "\\par" << endl;
00595         t << "{\\field\\fldedit {\\*\\fldinst TOC \\\\f \\\\*MERGEFORMAT}{\\fldrslt Table of contents}}\\par\n";
00596         t << rtf_Style_Reset << endl;
00597       }
00598       break;
00599     case isMainPage:
00600       t << "\\par " << rtf_Style_Reset << endl;
00601       if (!Doxygen::mainPage || Doxygen::mainPage->title().isEmpty())
00602       {
00603         t << "{\\tc \\v " << theTranslator->trMainPage() << "}"<< endl;
00604       }
00605       else
00606       {
00607         t << "{\\tc \\v " << substitute(Doxygen::mainPage->title(),"%","") << "}"<< endl;
00608       }
00609       t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
00610       if (Config_getBool("GENERATE_TREEVIEW")) t << "main"; else t << "index";
00611       t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
00612       break;
00613     //case isPackageIndex:
00614     //  t << "\\par " << rtf_Style_Reset << endl;
00615     //  t << "{\\tc \\v " << theTranslator->trPackageList() << "}"<< endl;
00616     //  t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"packages.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
00617     //  break;
00618     case isModuleIndex:
00619       t << "\\par " << rtf_Style_Reset << endl;
00620       t << "{\\tc \\v " << theTranslator->trModuleIndex() << "}"<< endl;
00621       t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"modules.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
00622       break;
00623     case isDirIndex:
00624       t << "\\par " << rtf_Style_Reset << endl;
00625       t << "{\\tc \\v " << theTranslator->trDirIndex() << "}"<< endl;
00626       t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"dirs.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
00627       break;
00628     case isNamespaceIndex:
00629       t << "\\par " << rtf_Style_Reset << endl;
00630       if (fortranOpt)
00631       {
00632           t << "{\\tc \\v " << theTranslator->trModulesIndex() << "}"<< endl;
00633       }
00634       else
00635       {
00636           t << "{\\tc \\v " << theTranslator->trNamespaceIndex() << "}"<< endl;
00637       }
00638       
00639       t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"namespaces.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
00640       break;
00641     case isClassHierarchyIndex:
00642       t << "\\par " << rtf_Style_Reset << endl;
00643       t << "{\\tc \\v " << theTranslator->trHierarchicalIndex() << "}"<< endl;
00644       t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"hierarchy.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
00645       break;
00646     case isCompoundIndex:
00647       t << "\\par " << rtf_Style_Reset << endl;
00648       if (fortranOpt)
00649       {
00650         t << "{\\tc \\v " << theTranslator->trCompoundIndexFortran() << "}"<< endl;
00651       }
00652       else if (vhdlOpt)
00653       {
00654         t << "{\\tc \\v " << VhdlDocGen::trDesignUnitIndex() << "}"<< endl;
00655       }
00656       else
00657       {
00658         t << "{\\tc \\v " << theTranslator->trCompoundIndex() << "}"<< endl;
00659       }
00660       t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"annotated.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
00661       break;
00662     case isFileIndex:
00663       t << "\\par " << rtf_Style_Reset << endl;
00664       t << "{\\tc \\v " << theTranslator->trFileIndex() << "}"<< endl;
00665       t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"files.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
00666       break;
00667     case isPageIndex:
00668       t << "\\par " << rtf_Style_Reset << endl;
00669       t << "{\\tc \\v " << theTranslator->trPageIndex() << "}"<< endl;
00670       t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"pages.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
00671       break;
00672     case isModuleDocumentation:
00673       {
00674         GroupSDict::Iterator gli(*Doxygen::groupSDict);
00675         GroupDef *gd;
00676         t << "{\\tc \\v " << theTranslator->trModuleDocumentation() << "}"<< endl;
00677         for (gli.toFirst();(gd=gli.current());++gli)
00678         {
00679           if (!gd->isReference())
00680           {
00681             t << "\\par " << rtf_Style_Reset << endl;
00682             t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
00683             t << gd->getOutputFileBase();
00684             t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
00685           }
00686         }
00687       }
00688       break;
00689     case isDirDocumentation:
00690       {
00691         SDict<DirDef>::Iterator dli(*Doxygen::directories);
00692         DirDef *dd;
00693         t << "{\\tc \\v " << theTranslator->trDirDocumentation() << "}"<< endl;
00694         for (dli.toFirst();(dd=dli.current());++dli)
00695         {
00696           if (dd->isLinkableInProject())
00697           {
00698             t << "\\par " << rtf_Style_Reset << endl;
00699             t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
00700             t << dd->getOutputFileBase();
00701             t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
00702           }
00703         }
00704       }
00705       break;
00706     case isNamespaceDocumentation:
00707       {
00708         NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
00709         NamespaceDef *nd;
00710         bool found=FALSE;
00711         for (nli.toFirst();(nd=nli.current()) && !found;++nli)
00712         {
00713           if (nd->isLinkableInProject())
00714           {
00715             t << "\\par " << rtf_Style_Reset << endl;
00716             t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
00717             t << nd->getOutputFileBase();
00718             t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
00719             found=TRUE;
00720           }
00721         }
00722         while ((nd=nli.current()))
00723         {
00724           if (nd->isLinkableInProject())
00725           {
00726             t << "\\par " << rtf_Style_Reset << endl;
00727             beginRTFSection();
00728             t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
00729             t << nd->getOutputFileBase();
00730             t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
00731           }
00732           ++nli;
00733         }
00734       }
00735       break;
00736     case isClassDocumentation:
00737       {
00738         ClassSDict::Iterator cli(*Doxygen::classSDict);
00739         ClassDef *cd=0;
00740         bool found=FALSE;
00741         if (fortranOpt)
00742         {
00743           t << "{\\tc \\v " << theTranslator->trTypeDocumentation() << "}"<< endl;
00744         }
00745         else
00746         {
00747           t << "{\\tc \\v " << theTranslator->trClassDocumentation() << "}"<< endl;
00748         }
00749         for (cli.toFirst();(cd=cli.current()) && !found;++cli)
00750         {
00751           if (cd->isLinkableInProject() && cd->templateMaster()==0)
00752           {
00753             t << "\\par " << rtf_Style_Reset << endl;
00754             t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
00755             t << cd->getOutputFileBase();
00756             t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
00757             found=TRUE;
00758           }
00759         }
00760         for (;(cd=cli.current());++cli)
00761         {
00762           if (cd->isLinkableInProject() && cd->templateMaster()==0)
00763           {
00764             t << "\\par " << rtf_Style_Reset << endl;
00765             beginRTFSection();
00766             t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
00767             t << cd->getOutputFileBase();
00768             t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
00769           }
00770         }
00771       }
00772       break;
00773     case isFileDocumentation:
00774       {
00775         bool isFirst=TRUE;
00776         FileName *fn=Doxygen::inputNameList->first();
00777 
00778         t << "{\\tc \\v " << theTranslator->trFileDocumentation() << "}"<< endl;
00779         while (fn)
00780         {
00781           FileDef *fd=fn->first();
00782           while (fd)
00783           {
00784             if (fd->isLinkableInProject())
00785             {
00786               if (isFirst)
00787               {
00788                 t << "\\par " << rtf_Style_Reset << endl;
00789                 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
00790                 t << fd->getOutputFileBase();
00791                 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
00792                 isFirst=FALSE;
00793               }
00794               else
00795               {
00796                 t << "\\par " << rtf_Style_Reset << endl;
00797                 beginRTFSection();
00798                 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
00799                 t << fd->getOutputFileBase();
00800                 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
00801               }
00802             }
00803             fd=fn->next();
00804           }
00805           fn=Doxygen::inputNameList->next();
00806         }
00807       }
00808       break;
00809     case isExampleDocumentation:
00810       {
00811         //t << "}\n";
00812         t << "{\\tc \\v " << theTranslator->trExampleDocumentation() << "}"<< endl;
00813         PageSDict::Iterator pdi(*Doxygen::exampleSDict);
00814         PageDef *pd=pdi.toFirst();
00815         if (pd)
00816         {
00817           t << "\\par " << rtf_Style_Reset << endl;
00818           t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
00819           t << pd->getOutputFileBase();
00820           t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
00821         }
00822         for (++pdi;(pd=pdi.current());++pdi)
00823         {
00824           t << "\\par " << rtf_Style_Reset << endl;
00825           beginRTFSection();
00826           t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
00827           t << pd->getOutputFileBase();
00828           t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
00829         }
00830       }
00831       break;
00832     case isPageDocumentation:
00833       {
00834 //#error "fix me in the same way as the latex index..."
00835         //t << "{\\tc \\v " << theTranslator->trPageDocumentation() << "}"<< endl;
00836         t << "}"<< endl;
00837         //PageSDict::Iterator pdi(*Doxygen::pageSDict);
00838         //PageDef *pd=pdi.toFirst();
00839         //bool first=TRUE;
00840         //for (pdi.toFirst();(pd=pdi.current());++pdi)
00841         //{
00842         //  if (!pd->getGroupDef() && !pd->isReference())
00843         //  {
00844         //    if (first) t << "\\par " << rtf_Style_Reset << endl;
00845         //    t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
00846         //    t << pd->getOutputFileBase();
00847         //    t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
00848         //    first=FALSE;
00849         //  }
00850         //}
00851       }
00852       break;
00853     case isEndIndex:
00854       beginRTFChapter();
00855       t << rtf_Style["Heading1"]->reference;
00856       t << theTranslator->trRTFGeneralIndex() << "\\par "<< endl;
00857       t << rtf_Style_Reset << endl;
00858       t << "{\\tc \\v " << theTranslator->trRTFGeneralIndex() << "}" << endl;
00859       t << "{\\field\\fldedit {\\*\\fldinst INDEX \\\\c2 \\\\*MERGEFORMAT}{\\fldrslt INDEX}}\n";
00860 
00861       break;
00862    }
00863 }
00864 
00865 void RTFGenerator::writePageLink(const char *name,bool first)
00866 {
00867    if (first) t << "\\par " << rtf_Style_Reset << endl;
00868    t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
00869    t << name;
00870    t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
00871 }
00872 
00873 void RTFGenerator::lastIndexPage()
00874 {
00875   DBG_RTF(t <<"{\\comment Beginning Body of RTF Document}\n")
00876   // end page and setup for rest of document
00877   t <<"\\sect \\sbkpage \\pgndec \\pgnrestart\n";
00878   t <<"\\sect \\sectd \\sbknone\n";
00879 
00880   // set new footer with arabic numbers
00881   t <<"{\\footer "<< rtf_Style["Footer"]->reference << "{\\chpgn}}\n";
00882   //t << rtf_Style["Heading1"]->reference << "\n";
00883 
00884 }
00885 
00886 void RTFGenerator::writeStyleInfo(int)
00887 {
00888 }
00889 
00890 void RTFGenerator::lineBreak()
00891 {
00892   DBG_RTF(t << "{\\comment (lineBreak)}"    << endl)
00893   t << "\\par" << endl;
00894   m_omitParagraph = TRUE;
00895 }
00896 
00897 void RTFGenerator::writeString(const char *text)
00898 {
00899   t << text;
00900 }
00901 
00902 void RTFGenerator::startIndexList()
00903 {
00904   DBG_RTF(t << "{\\comment (startIndexList)}" << endl)
00905   t << "{" << endl;
00906   t << "\\par" << endl;
00907   incrementIndentLevel();
00908   t << rtf_Style_Reset << rtf_LCList_DepthStyle() << endl;
00909   m_omitParagraph = TRUE;
00910 }
00911 
00912 void RTFGenerator::endIndexList()
00913 {
00914   DBG_RTF(t << "{\\comment (endIndexList)}" << endl)
00915   t << "\\par";
00916   t << "}";
00917   decrementIndentLevel();
00918   m_omitParagraph = TRUE;
00919 }
00920 
00922 void RTFGenerator::startItemList()
00923 {
00924   newParagraph();
00925   DBG_RTF(t << "{\\comment (startItemList level=" << m_listLevel << ") }" << endl)
00926   t << "{";
00927   incrementIndentLevel();
00928   rtf_listItemInfo[m_listLevel].isEnum = FALSE;
00929 }
00930 
00932 void RTFGenerator::endItemList()
00933 {
00934   newParagraph();
00935   DBG_RTF(t << "{\\comment (endItemList level=" << m_listLevel << ")}" << endl)
00936   t << "}";
00937   decrementIndentLevel();
00938   m_omitParagraph = TRUE;
00939 }
00940 
00942 //void RTFGenerator::startEnumList()  // starts an enumeration list
00943 //{
00944 //  DBG_RTF(t << "{\\comment (startEnumList)}" << endl)
00945 //  t << "{" << endl;
00946 //  incrementIndentLevel();
00947 //  rtf_listItemInfo[m_listLevel].isEnum = TRUE;
00948 //  rtf_listItemInfo[m_listLevel].number = 1;
00949 //}
00950 //
00952 //void RTFGenerator::endEnumList()
00953 //{
00954 //  newParagraph();
00955 //  DBG_RTF(t << "{\\comment (endEnumList)}" << endl)
00956 //  t << "}";
00957 //  decrementIndentLevel();
00958 //  m_omitParagraph = TRUE;
00959 //}
00960 
00962 void RTFGenerator::writeListItem()
00963 {
00964   DBG_RTF(t << "{\\comment (writeListItem)}" << endl)
00965   newParagraph();
00966   t << rtf_Style_Reset;
00967   if (rtf_listItemInfo[m_listLevel].isEnum)
00968   {
00969     t << rtf_EList_DepthStyle() << endl;
00970     t << rtf_listItemInfo[m_listLevel].number << ".\\tab ";
00971     rtf_listItemInfo[m_listLevel].number++;
00972   }
00973   else
00974   {
00975     t << rtf_BList_DepthStyle() << endl;
00976   }
00977   m_omitParagraph = TRUE;
00978 }
00979 
00980 void RTFGenerator::startIndexItem(const char *,const char *)
00981 {
00982   DBG_RTF(t << "{\\comment (startIndexItem)}" << endl)
00983 }
00984 
00985 void RTFGenerator::endIndexItem(const char *ref,const char *fn)
00986 {
00987   DBG_RTF(t << "{\\comment (endIndexItem)}" << endl)
00988   if (!ref && fn)
00989   {
00990     t << "\\tab ";
00991     writeRTFReference(fn);
00992     t << endl;
00993   }
00994   else
00995   {
00996     t << endl;
00997   }
00998   m_omitParagraph = TRUE;
00999   newParagraph();
01000 }
01001 
01002 //void RTFGenerator::writeIndexFileItem(const char *,const char *text)
01003 //{
01004 //  t << "\\item\\contentsline{section}{";
01005 //  docify(text);
01006 //  t << "}{\\pageref{" << text << "}}" << endl;
01007 //}
01008 
01009 void RTFGenerator::startHtmlLink(const char *url)
01010 {
01011 
01012   if (Config_getBool("RTF_HYPERLINKS"))
01013   {
01014     t << "{\\field {\\*\\fldinst { HYPERLINK  \\\\l \"";
01015     t << url;
01016     t << "\" }{}";
01017     t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
01018   }
01019   else
01020   {
01021     startTypewriter();
01022   }
01023 }
01024 
01025 void RTFGenerator::endHtmlLink()
01026 {
01027   if (Config_getBool("RTF_HYPERLINKS"))
01028   {
01029     t << "}}}" << endl;
01030   }
01031   else
01032   {
01033     endTypewriter();
01034   }
01035 }
01036 
01037 //void RTFGenerator::writeMailLink(const char *url)
01038 //{
01039 //  startTypewriter();
01040 //  docify(url);
01041 //  endTypewriter();
01042 //}
01043 
01044 void RTFGenerator::writeStartAnnoItem(const char *,const char *f,
01045     const char *path,const char *name)
01046 {
01047   DBG_RTF(t << "{\\comment (writeStartAnnoItem)}" << endl)
01048   t << "{\\b ";
01049   if (path) docify(path);
01050   if (f && Config_getBool("RTF_HYPERLINKS"))
01051   {
01052     t << "{\\field {\\*\\fldinst { HYPERLINK  \\\\l \"";
01053     t << rtfFormatBmkStr(f);
01054     t << "\" }{}";
01055     t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
01056 
01057     docify(name);
01058 
01059     t << "}}}" << endl;
01060   }
01061   else
01062   {
01063     docify(name);
01064   }
01065   t << "} ";
01066 }
01067 
01068 void RTFGenerator::writeEndAnnoItem(const char *name)
01069 {
01070   DBG_RTF(t << "{\\comment (writeEndAnnoItem)}" << endl)
01071   if (name)
01072   {
01073     t << "\\tab ";
01074     writeRTFReference(name);
01075     t << endl;
01076   }
01077   else
01078   {
01079     t << endl;
01080   }
01081   newParagraph();
01082 }
01083 
01084 void RTFGenerator::startIndexKey()
01085 {
01086   DBG_RTF(t << "{\\comment (startIndexKey)}" << endl)
01087   t << "{\\b ";
01088 }
01089 
01090 void RTFGenerator::endIndexKey()
01091 {
01092   DBG_RTF(t << "{\\comment (endIndexKey)}" << endl)
01093 }
01094 
01095 void RTFGenerator::startIndexValue(bool hasBrief)
01096 {
01097   DBG_RTF(t << "{\\comment (startIndexValue)}" << endl)
01098   t << " ";
01099   if (hasBrief) t << "(";
01100 }
01101 
01102 void RTFGenerator::endIndexValue(const char *name,bool hasBrief)
01103 {
01104   DBG_RTF(t << "{\\comment (endIndexValue)}" << endl)
01105   if (hasBrief) t << ")";
01106   t << "} ";
01107   if (name)
01108   {
01109     t << "\\tab ";
01110     writeRTFReference(name);
01111     t << endl;
01112   }
01113   else
01114   {
01115     t << endl;
01116   }
01117   m_omitParagraph=FALSE;
01118   newParagraph();
01119 }
01120 
01121 void RTFGenerator::startSubsection()
01122 {
01123   //beginRTFSubSection();
01124   t <<"\n";
01125   DBG_RTF(t << "{\\comment Begin SubSection}\n")
01126   t << rtf_Style_Reset;
01127   t << rtf_Style["Heading3"]->reference << "\n";
01128 }
01129 
01130 void RTFGenerator::endSubsection()
01131 {
01132   newParagraph();
01133   t << rtf_Style_Reset << endl;
01134 }
01135 
01136 void RTFGenerator::startSubsubsection()
01137 {
01138   //beginRTFSubSubSection();
01139   t << "\n";
01140   DBG_RTF(t << "{\\comment Begin SubSubSection}\n")
01141   t << "{" << endl;
01142   t << rtf_Style_Reset << rtf_Style["Heading4"]->reference << "\n";
01143 }
01144 
01145 void RTFGenerator::endSubsubsection()
01146 {
01147   newParagraph();
01148   t << "}" << endl;
01149 }
01150 
01151 
01152 //void RTFGenerator::writeClassLink(const char *,const char *,
01153 //                                    const char *,const char *name)
01154 //{
01155 //  t << "{\\bf ";
01156 //  docify(name);
01157 //  t << "}";
01158 //}
01159 
01160 //void RTFGenerator::startTable(bool,int colNumbers) 
01161 //{
01162 //  DBG_RTF(t << "{\\comment startTable}\n";)
01163 //  m_numCols=colNumbers;
01164 //  t << "\\par\n";
01165 //}
01166 //
01167 //void RTFGenerator::endTable(bool hasCaption) 
01168 //{ 
01169 //  DBG_RTF(t << "{\\comment endTable}\n";)
01170 //  if (!hasCaption) 
01171 //    t << "\n\\pard \\widctlpar\\intbl\\adjustright\n{\\row }\n"; 
01172 //  t << "\\pard\n" << endl; 
01173 //}
01174 //
01175 //void  RTFGenerator::startCaption() 
01176 //{
01177 //  DBG_RTF(t << "{\\comment startCaption}\n";)
01178 //  endTableRow();
01179 //  t << "\\trowd \\trgaph108\\trleft-108\\trbrdrt\\brdrs\\brdrw10 \\trbrdrl\\brdrs\\brdrw10 \\trbrdrb\\brdrs\\brdrw10 \\trbrdrr\\brdrs\\brdrw10 \\trbrdrh\\brdrs\\brdrw10 \\trbrdrv\\brdrs\\brdrw10" << endl;
01180 //  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;
01181 //  nextTableColumn();
01182 //}
01183 //
01184 //void  RTFGenerator::endCaption() 
01185 //{
01186 //  DBG_RTF(t << "{\\comment endCaption}\n";)
01187 //  endTableColumn();
01188 //  endTableRow();
01189 //}
01190 //
01191 //void RTFGenerator::nextTableRow() 
01192 //{  
01193 //  DBG_RTF(t << "{\\comment nextTableRow}\n";)
01194 //  ASSERT(m_numCols>0 && m_numCols<25);
01195 //  uint columnWidth=rtf_pageWidth/m_numCols;
01196 //  t << "\\trowd \\trgaph108\\trleft-108\\trbrdrt\\brdrs\\brdrw10 "
01197 //       "\\trbrdrl\\brdrs\\brdrw10 \\trbrdrb\\brdrs\\brdrw10 "
01198 //       "\\trbrdrr\\brdrs\\brdrw10 \\trbrdrh\\brdrs\\brdrw10 "
01199 //       "\\trbrdrv\\brdrs\\brdrw10 "<<endl;
01200 //  for (int i=0;i<m_numCols;i++) 
01201 //  {
01202 //    t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10 \\clbrdrl\\brdrs\\brdrw10 "
01203 //         "\\clbrdrb\\brdrs\\brdrw10 \\clbrdrr \\brdrs\\brdrw10 \\cltxlrtb "
01204 //         "\\cellx" << (i*columnWidth) << endl;
01205 //  }
01206 //  t << "\\pard \\widctlpar\\intbl\\adjustright\n{";
01207 //}
01208 // 
01209 //void RTFGenerator::endTableRow() 
01210 //{ 
01211 //  DBG_RTF(t << "{\\comment endTableRow}\n";)
01212 //  t << "\n\\pard \\widctlpar\\intbl\\adjustright\n{\\row }\n";
01213 //}
01214 // 
01215 //void RTFGenerator::nextTableColumn() 
01216 //{
01217 //  DBG_RTF(t << "{\\comment nextTableColumn}\n";)
01218 //  t << "{ ";
01219 //}
01220 //
01221 //void RTFGenerator::endTableColumn() 
01222 //{ 
01223 //  DBG_RTF(t << "{\\comment endTableColumn}\n";)
01224 //  t << " \\cell }";
01225 //}
01226 //
01227 void RTFGenerator::startTextLink(const char *f,const char *anchor)
01228 {
01229   if (Config_getBool("RTF_HYPERLINKS"))
01230   {
01231     QCString ref;
01232     if (f)
01233     {
01234       ref+=f;
01235     }
01236     if (anchor)
01237     {
01238       ref+='_';
01239       ref+=anchor;
01240     }
01241 
01242     t << "{\\field {\\*\\fldinst { HYPERLINK  \\\\l \"";
01243     t << rtfFormatBmkStr(ref);
01244     t << "\" }{}";
01245     t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
01246   }
01247 }
01248 
01249 void RTFGenerator::endTextLink()
01250 {
01251   if (Config_getBool("RTF_HYPERLINKS"))
01252   {
01253     t << "}}}" << endl;
01254   }
01255 }
01256 
01257 void RTFGenerator::writeObjectLink(const char *ref, const char *f,
01258     const char *anchor, const char *text)
01259 {
01260   if (!ref && Config_getBool("RTF_HYPERLINKS"))
01261   {
01262     QCString refName;
01263     if (f)
01264     {
01265       refName+=f;
01266     }
01267     if (anchor)
01268     {
01269       refName+='_';
01270       refName+=anchor;
01271     }
01272 
01273     t << "{\\field {\\*\\fldinst { HYPERLINK  \\\\l \"";
01274     t << rtfFormatBmkStr(refName);
01275     t << "\" }{}";
01276     t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
01277 
01278     docify(text);
01279 
01280     t << "}}}" << endl;
01281   }
01282   else
01283   {
01284     startBold();
01285     docify(text);
01286     endBold();
01287   }
01288 }
01289 
01290 void RTFGenerator::startPageRef()
01291 {
01292   t << " (";
01293   startEmphasis();
01294 }
01295 
01296 void RTFGenerator::endPageRef(const char *clname, const char *anchor)
01297 {
01298   QCString ref;
01299   if (clname)
01300   {
01301     ref+=clname;
01302   }
01303   if (anchor)
01304   {
01305     ref+='_';
01306     ref+=anchor;
01307   }
01308   writeRTFReference(ref);
01309   endEmphasis();
01310   t << ")";
01311 }
01312 
01313 void RTFGenerator::writeCodeLink(const char *ref,const char *f,
01314                                  const char *anchor,const char *name,
01315                                  const char *)
01316 {
01317   if (!ref && Config_getBool("RTF_HYPERLINKS"))
01318   {
01319     QCString refName;
01320     if (f)
01321     {
01322       refName+=f;
01323     }
01324     if (anchor)
01325     {
01326       refName+='_';
01327       refName+=anchor;
01328     }
01329 
01330     t << "{\\field {\\*\\fldinst { HYPERLINK  \\\\l \"";
01331     t << rtfFormatBmkStr(refName);
01332     t << "\" }{}";
01333     t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
01334 
01335     codify(name);
01336 
01337     t << "}}}" << endl;
01338   }
01339   else
01340   {
01341     codify(name);
01342   }
01343 }
01344 
01345 void RTFGenerator::startTitleHead(const char *)
01346 {
01347   DBG_RTF(t <<"{\\comment startTitleHead}" << endl)
01348 
01349   //    beginRTFSection();
01350   t << rtf_Style_Reset << rtf_Style["Heading2"]->reference << endl;
01351 }
01352 
01353 void RTFGenerator::endTitleHead(const char *fileName,const char *name)
01354 {
01355   DBG_RTF(t <<"{\\comment endTitleHead}" << endl)
01356   t << "\\par " << rtf_Style_Reset << endl;
01357   if (name)
01358   {
01359     // make table of contents entry
01360     t << "{\\tc\\tcl2 \\v ";
01361     docify(name);
01362     t << "}" << endl;
01363 
01364     // make an index entry
01365     addIndexItem(name,0);
01366 
01367     //if (name)
01368     //{
01369     //  writeAnchor(0,name);
01370     //}
01371     //
01372     //if (Config_getBool("RTF_HYPERLINKS") && fileName)
01373     //{
01374       writeAnchor(fileName,0);
01375     //}
01376   }
01377 }
01378 
01379 void RTFGenerator::startTitle()
01380 {
01381   DBG_RTF(t <<"{\\comment startTitle}" << endl)
01382   if (Config_getBool("COMPACT_RTF"))
01383     beginRTFSection();
01384   else
01385     beginRTFChapter();
01386 }
01387 
01388 void RTFGenerator::startGroupHeader()
01389 {
01390   DBG_RTF(t <<"{\\comment startGroupHeader}" << endl)
01391   //newParagraph();
01392   t << rtf_Style_Reset;
01393   t << rtf_Style["Heading3"]->reference;
01394   t << endl;
01395 }
01396 
01397 void RTFGenerator::endGroupHeader()
01398 {
01399   DBG_RTF(t <<"{\\comment endGroupHeader}" << endl)
01400   t << "\\par" << endl;
01401   t << rtf_Style_Reset << endl;
01402 }
01403 
01404 void RTFGenerator::startMemberDoc(const char *clname,
01405     const char *memname,
01406     const char *,
01407     const char *)
01408 {
01409   DBG_RTF(t << "{\\comment startMemberDoc}" << endl)
01410   if (memname && memname[0]!='@')
01411   {
01412     addIndexItem(memname,clname);
01413     addIndexItem(clname,memname);
01414   }
01415   t << rtf_Style_Reset << rtf_Style["Heading4"]->reference;
01416   //styleStack.push(rtf_Style_Heading4);
01417   t << "{" << endl;
01418   //printf("RTFGenerator::startMemberDoc() `%s'\n",rtf_Style["Heading4"]->reference);
01419   startBold();
01420   t << endl;
01421 }
01422 
01423 void RTFGenerator::endMemberDoc(bool)
01424 {
01425   DBG_RTF(t << "{\\comment endMemberDoc}" << endl)
01426   t << "}" << endl;
01427   //const char *style = styleStack.pop();
01428   //printf("RTFGenerator::endMemberDoc() `%s'\n",style);
01429   //ASSERT(style==rtf_Style["Heading4"]->reference);
01430   endBold();
01431   newParagraph();
01432 }
01433 
01434 void RTFGenerator::startDoxyAnchor(const char *,const char *,
01435                                    const char *,const char *,
01436                                    const char *
01437                                   )
01438 {
01439   DBG_RTF(t << "{\\comment startDoxyAnchor}" << endl)
01440 }
01441 
01442 void RTFGenerator::endDoxyAnchor(const char *fName,const char *anchor)
01443 {
01444   QCString ref;
01445   if (fName)
01446   {
01447     ref+=fName;
01448   }
01449   if (anchor)
01450   {
01451     ref+='_';
01452     ref+=anchor;
01453   }
01454 
01455   DBG_RTF(t << "{\\comment endDoxyAnchor}" << endl)
01456   t << "{\\bkmkstart ";
01457   t << rtfFormatBmkStr(ref);
01458   t << "}" << endl;
01459   t << "{\\bkmkend ";
01460   t << rtfFormatBmkStr(ref);
01461   t << "}" << endl;
01462 }
01463 
01464 
01465 //void RTFGenerator::writeLatexLabel(const char *clName,const char *anchor)
01466 //{
01467 //  writeDoxyAnchor(0,clName,anchor,0);
01468 //}
01469 
01470 void RTFGenerator::addIndexItem(const char *s1,const char *s2)
01471 {
01472   if (s1)
01473   {
01474     t << "{\\xe \\v ";
01475     docify(s1);
01476     if (s2)
01477     {
01478       t << "\\:";
01479       docify(s2);
01480     }
01481     t << "}" << endl;
01482   }
01483 }
01484 
01485 void RTFGenerator::startIndent()
01486 {
01487   incrementIndentLevel();
01488   DBG_RTF(t << "{\\comment (startIndent) }" << endl)
01489   t << "{" << endl;
01490   t << rtf_Style_Reset << rtf_CList_DepthStyle() << endl;
01491 }
01492 
01493 void RTFGenerator::endIndent()
01494 {
01495   t << "}" << endl;
01496   decrementIndentLevel();
01497 }
01498 
01499 
01500 void RTFGenerator::startDescription()
01501 {
01502   DBG_RTF(t << "{\\comment (startDescription)}"    << endl)
01503   t << "{" << endl;
01504   t << rtf_Style_Reset << rtf_DList_DepthStyle();
01505 }
01506 
01507 void RTFGenerator::endDescription()
01508 {
01509   DBG_RTF(t << "{\\comment (endDescription)}"    << endl)
01510   newParagraph();
01511   t << "}";
01512 }
01513 
01514 void RTFGenerator::startDescItem()
01515 {
01516   newParagraph();
01517   DBG_RTF(t << "{\\comment (startDescItem)}"    << endl)
01518   t << "{\\b ";
01519 }
01520 
01521 void RTFGenerator::endDescItem()
01522 {
01523   DBG_RTF(t << "{\\comment (endDescItem)}"    << endl)
01524   t << "}" << endl;
01525   newParagraph();
01526 }
01527 
01528 void RTFGenerator::startMemberDescription()
01529 {
01530   DBG_RTF(t << "{\\comment (startMemberDescription)}"    << endl)
01531   t << "{" << endl;
01532   incrementIndentLevel();
01533   t << rtf_Style_Reset << rtf_CList_DepthStyle();
01534   startEmphasis();
01535 }
01536 
01537 void RTFGenerator::endMemberDescription()
01538 {
01539   DBG_RTF(t << "{\\comment (endMemberDescription)}"    << endl)
01540   endEmphasis();
01541   newParagraph();
01542   decrementIndentLevel();
01543   //t << "\\par";
01544   t << "}" << endl;
01545   //m_omitParagraph = TRUE;
01546 }
01547 
01548 void RTFGenerator::startDescList(SectionTypes)
01549 {
01550   DBG_RTF(t << "{\\comment (startDescList)}"    << endl)
01551   t << "{"; // ends at endDescList
01552   t << "{"; // ends at endDescTitle
01553   startBold();
01554   newParagraph();
01555 }
01556 
01557 //void RTFGenerator::endDescTitle()
01558 //{
01559 //  DBG_RTF(t << "{\\comment (endDescTitle) }"    << endl)
01560 //  endBold();
01561 //  t << "}";
01562 //  newParagraph();
01563 //  incrementIndentLevel();
01564 //  t << rtf_Style_Reset << rtf_DList_DepthStyle();
01565 //}
01566 
01567 void RTFGenerator::writeDescItem()
01568 {
01569   DBG_RTF(t << "{\\comment (writeDescItem) }"    << endl)
01570 }
01571 
01572 //void RTFGenerator::endDescList()
01573 //{
01574 //  DBG_RTF(t << "{\\comment (endDescList)}"    << endl)
01575 //  newParagraph();
01576 //  decrementIndentLevel();
01577 //  m_omitParagraph = TRUE;
01578 //  t << "}";
01579 //}
01580 
01581 
01582 void RTFGenerator::startSection(const char *,const char *title,SectionInfo::SectionType type)
01583 {
01584   DBG_RTF(t << "{\\comment (startSection)}"    << endl)
01585   t << "{";
01586   t<< rtf_Style_Reset;
01587   int num=4;
01588   switch(type)
01589   {
01590     case SectionInfo::Page:          num=2; break;
01591     case SectionInfo::Section:       num=3; break;
01592     case SectionInfo::Subsection:    num=4; break;
01593     case SectionInfo::Subsubsection: num=4; break;
01594     case SectionInfo::Paragraph:     num=4; break;
01595     default: ASSERT(0); break;
01596   }
01597   QCString heading;
01598   heading.sprintf("Heading%d",num);
01599   // set style
01600   t << rtf_Style[heading]->reference;
01601   // make table of contents entry
01602   t << "{\\tc\\tcl" << num << " \\v ";
01603   docify(title);
01604   t << "}" << endl;
01605 }
01606 
01607 void RTFGenerator::endSection(const char *lab,SectionInfo::SectionType)
01608 {
01609   DBG_RTF(t << "{\\comment (endSection)}"    << endl)
01610   newParagraph();
01611   // make bookmark
01612   writeAnchor(0,lab);
01613   t << "}";
01614 }
01615 
01616 //void RTFGenerator::writeSectionRef(const char *ref,const char *,
01617 //                                   const char *lab,const char *title)
01618 //{
01619 //  if (ref)
01620 //  {
01621 //    docify(title);
01622 //  }
01623 //  else
01624 //  {
01625 //    startBold();
01626 //    docify(title);
01627 //    endBold();
01628 //    t << " (";
01629 //    docify(theTranslator->trPageAbbreviation());
01630 //    writeRTFReference(lab);
01631 //    t << ")" << endl;
01632 //  }
01633 //}
01634 //
01635 //void RTFGenerator::writeSectionRefItem(const char *,const char *lab,
01636 //    const char *title)
01637 //{
01638 //  docify(title);
01639 //  t << "\\tab";
01640 //  writeRTFReference(lab);
01641 //  t << endl;
01642 //}
01643 //
01644 //void RTFGenerator::writeSectionRefAnchor(const char *name,const char *lab,
01645 //    const char *title)
01646 //{
01647 //  writeSectionRef(name,lab,title);
01648 //}
01649 
01650 //char* RTFGenerator::getMultiByte(int c)
01651 //{
01652 //    static char s[10];
01653 //
01654 //    sprintf(s,"\\'%X",c);
01655 //    return s;
01656 //}
01657 
01658 void RTFGenerator::docify(const char *str)
01659 {
01660   if (str)
01661   {
01662     const unsigned char *p=(const unsigned char *)str;
01663     unsigned char c;
01664     unsigned char pc='\0';
01665     while (*p)
01666     {
01667       //static bool MultiByte = FALSE;
01668       c=*p++;
01669 
01670 #if 0
01671       if ( MultiByte )
01672       {
01673         t << getMultiByte( c );
01674         MultiByte = FALSE;
01675         continue;
01676       }
01677       if ( c >= 0x80 )
01678       {
01679         MultiByte = TRUE;
01680         t << getMultiByte( c );
01681         continue;
01682       }
01683 #endif
01684 
01685       switch (c)
01686       {
01687         case '{':  t << "\\{";            break;
01688         case '}':  t << "\\}";            break;
01689         case '\\': t << "\\\\";           break;
01690         default:
01691           {
01692             // see if we can insert an hyphenation hint
01693             //if (isupper(c) && islower(pc) && !insideTabbing) t << "\\-";
01694             t << (char)c;
01695           }
01696       }
01697       pc = c;
01698       m_omitParagraph = FALSE;
01699     }
01700   }
01701 }
01702 
01703 void RTFGenerator::codify(const char *str)
01704 {
01705   // note that RTF does not have a "verbatim", so "\n" means
01706   // nothing... add a "newParagraph()";
01707   //static char spaces[]="        ";
01708   if (str)
01709   {
01710     const unsigned char *p=(const unsigned char *)str;
01711     unsigned char c;
01712     int spacesToNextTabStop;
01713 
01714     while (*p)
01715     {
01716       //static bool MultiByte = FALSE;
01717 
01718       c=*p++;
01719 
01720 #if 0
01721       if( MultiByte )
01722       {
01723         t << getMultiByte( c );
01724         MultiByte = FALSE;
01725         continue;
01726       }
01727       if( c >= 0x80 )
01728       {
01729         MultiByte = TRUE;
01730         t << getMultiByte( c );
01731         continue;
01732       }
01733 #endif
01734 
01735       switch(c)
01736       {
01737         case '\t':  spacesToNextTabStop = Config_getInt("TAB_SIZE") - (col%Config_getInt("TAB_SIZE"));
01738                     t << spaces.left(spacesToNextTabStop);
01739                     col+=spacesToNextTabStop;
01740                     break;
01741         case '\n':  newParagraph();
01742                     t << '\n'; col=0;
01743                     break;
01744         case '{':   t << "\\{"; col++;          break;
01745         case '}':   t << "\\}"; col++;          break;
01746         case '\\':  t << "\\\\"; col++;         break;
01747         default:    t << (char)c; col++;           break;
01748       }
01749     }
01750   }
01751 }
01752 
01753 void RTFGenerator::writeChar(char c)
01754 {
01755   char cs[2];
01756   cs[0]=c;
01757   cs[1]=0;
01758   docify(cs);
01759 }
01760 
01761 void RTFGenerator::startClassDiagram()
01762 {
01763   DBG_RTF(t <<"{\\comment startClassDiagram }" << endl)
01764 }
01765 
01766 void RTFGenerator::endClassDiagram(const ClassDiagram &d,
01767     const char *fileName,const char *)
01768 {
01769   newParagraph();
01770 
01771   // create a png file
01772   d.writeImage(t,dir,relPath,fileName,FALSE);
01773 
01774   // display the file
01775   t << "{" << endl;
01776   t << rtf_Style_Reset << endl;
01777   t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
01778   t << fileName << ".png\"";
01779   t << " \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
01780   t << "}" << endl;
01781 }
01782 
01783 //void RTFGenerator::writeFormula(const char *,const char *text)
01784 //{
01785 //  t << text;
01786 //}
01787 
01788 void RTFGenerator::startMemberItem(int)
01789 {
01790   DBG_RTF(t <<"{\\comment startMemberItem }" << endl)
01791   t << rtf_Style_Reset << rtf_BList_DepthStyle() << endl; // set style to apropriate depth
01792 }
01793 
01794 void RTFGenerator::endMemberItem()
01795 {
01796   DBG_RTF(t <<"{\\comment endMemberItem }" << endl)
01797   newParagraph();
01798 }
01799 
01800 void RTFGenerator::writeAnchor(const char *fileName,const char *name)
01801 {
01802   QCString anchor;
01803   if (fileName)
01804   {
01805     anchor+=fileName;
01806   }
01807   if (fileName && name)
01808   {
01809     anchor+='_';
01810   }
01811   if (name)
01812   {
01813     anchor+=name;
01814   }
01815 
01816   DBG_RTF(t <<"{\\comment writeAncheor (" << anchor << ")}" << endl)
01817   t << "{\\bkmkstart " << rtfFormatBmkStr(anchor) << "}" << endl;
01818   t << "{\\bkmkend " << rtfFormatBmkStr(anchor) << "}" << endl;
01819 }
01820 
01821 void RTFGenerator::writeRTFReference(const char *label)
01822 {
01823   t << "{\\field\\fldedit {\\*\\fldinst PAGEREF ";
01824   t << rtfFormatBmkStr(label);
01825   t << " \\\\*MERGEFORMAT}{\\fldrslt pagenum}}";
01826 }
01827 
01828 void RTFGenerator::startCodeFragment()
01829 {
01830   DBG_RTF(t << "{\\comment (startCodeFragment) }"    << endl)
01831   t << "{" << endl;
01832   //newParagraph();
01833   t << rtf_Style_Reset << rtf_Code_DepthStyle();
01834   //styleStack.push(rtf_Style_CodeExample);
01835 }
01836 
01837 void RTFGenerator::endCodeFragment()
01838 {
01839   //newParagraph();
01840   //styleStack.pop();
01841   //printf("RTFGenerator::endCodeFrament() top=%s\n",styleStack.top());
01842   //t << rtf_Style_Reset << styleStack.top() << endl;
01843   DBG_RTF(t << "{\\comment (endCodeFragment) }"    << endl)
01844   t << "}" << endl;
01845   m_omitParagraph = TRUE;
01846 }
01847 
01848 void RTFGenerator::writeNonBreakableSpace(int)
01849 {
01850   t << "\\~ ";
01851 }
01852 
01853 
01854 void RTFGenerator::startMemberList()
01855 {
01856   t << endl;
01857   DBG_RTF(t << "{\\comment (startMemberList) }"    << endl)
01858   t << "{" << endl;
01859 #ifdef DELETEDCODE
01860   if (!insideTabbing)
01861     t << "\\begin{CompactItemize}" << endl;
01862 #endif
01863 }
01864 
01865 void RTFGenerator::endMemberList()
01866 {
01867   DBG_RTF(t << "{\\comment (endMemberList) }"    << endl)
01868   t << "}" << endl;
01869 #ifdef DELETEDCODE
01870   if (!insideTabbing)
01871     t << "\\end{CompactItemize}"   << endl;
01872 #endif
01873 }
01874 
01875 //void RTFGenerator::startImage(const char *name,const char *,bool)
01876 //{
01877 //  newParagraph();
01878 //  t << "{" << endl;
01879 //  t << rtf_Style_Reset << endl;
01880 //  t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE ";
01881 //  t << name;
01882 //  t << " \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
01883 //  t << "}" << endl;
01884 //}
01885 //
01886 //void RTFGenerator::endImage(bool)
01887 //{
01888 //  // not yet implemented
01889 //}
01890 //
01891 //void RTFGenerator::startDotFile(const char *name,bool)
01892 //{
01893 //  QCString baseName=name;
01894 //  int i;
01895 //  if ((i=baseName.findRev('/'))!=-1 || (i=baseName.findRev('\\'))!=-1)
01896 //  {
01897 //    baseName=baseName.right(baseName.length()-i-1);
01898 //  }
01899 //  QCString outDir = Config_getString("RTF_OUTPUT");
01900 //  writeDotGraphFromFile(name,outDir,baseName,BITMAP);
01901 //  newParagraph();
01902 //  t << "{" << endl;
01903 //  t << rtf_Style_Reset << endl;
01904 //  t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE ";
01905 //  t << outDir << "\\" << baseName;
01906 //  t << " \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
01907 //  t << "}" << endl;
01908 //}
01909 //
01910 //void RTFGenerator::endDotFile(bool)
01911 //{
01912 //  // not yet implemented
01913 //}
01914 //
01915 void RTFGenerator::startDescTable()
01916 {
01917   DBG_RTF(t << "{\\comment (startDescTable) }"    << endl)
01918   //t << "{" << endl;
01919   //incrementIndentLevel();
01920   //t << rtf_Style_Reset << rtf_CList_DepthStyle();
01921 }
01922 
01923 void RTFGenerator::endDescTable()
01924 {
01925   //decrementIndentLevel();
01926   DBG_RTF(t << "{\\comment (endDescTable)}"      << endl)
01927   //t << "}" << endl;
01928   //t << rtf_Style_Reset << styleStack.top();
01929 }
01930 
01931 void RTFGenerator::startDescTableTitle()
01932 {
01933   //t << rtf_BList_DepthStyle() << endl;
01934   DBG_RTF(t << "{\\comment (startDescTableTitle) }"    << endl)
01935   startBold();
01936   startEmphasis();
01937 }
01938 
01939 void RTFGenerator::endDescTableTitle()
01940 {
01941   DBG_RTF(t << "{\\comment (endDescTableTitle) }"    << endl)
01942   endEmphasis();
01943   endBold();
01944   t << "  ";
01945 }
01946 
01947 void RTFGenerator::startDescTableData()
01948 {
01949   DBG_RTF(t << "{\\comment (startDescTableData) }"    << endl)
01950   m_omitParagraph = FALSE;
01951 }
01952 
01953 void RTFGenerator::endDescTableData()
01954 {
01955   DBG_RTF(t << "{\\comment (endDescTableData) }"    << endl)
01956   newParagraph();
01957   m_omitParagraph = TRUE;
01958 }
01959 
01960 // a style for list formatted as a "bulleted list"
01961 
01962 void RTFGenerator::incrementIndentLevel()
01963 {
01964   m_listLevel++;
01965   if (m_listLevel>rtf_maxIndentLevels-1)
01966   {
01967     warn_cont("Warning: Maximum indent level (%d) exceeded while generating RTF output!\n",rtf_maxIndentLevels);
01968     m_listLevel=rtf_maxIndentLevels-1;
01969   }
01970 }
01971 
01972 void RTFGenerator::decrementIndentLevel()
01973 {
01974   m_listLevel--;
01975   if (m_listLevel<0)
01976   {
01977     warn_cont("Warning: Negative indent level while generating RTF output!\n");
01978     m_listLevel=0;
01979   }
01980 }
01981 
01982 // a style for list formatted with "list continue" style
01983 const char * RTFGenerator::rtf_CList_DepthStyle()
01984 {
01985   QCString n=makeIndexName("ListContinue",m_listLevel);
01986   return rtf_Style[n]->reference;
01987 }
01988 
01989 // a style for list formatted as a "latext style" table of contents
01990 const char * RTFGenerator::rtf_LCList_DepthStyle()
01991 {
01992   QCString n=makeIndexName("LatexTOC",m_listLevel);
01993   return rtf_Style[n]->reference;
01994 }
01995 
01996 // a style for list formatted as a "bullet" style
01997 const char * RTFGenerator::rtf_BList_DepthStyle()
01998 {
01999   QCString n=makeIndexName("ListBullet",m_listLevel);
02000   return rtf_Style[n]->reference;
02001 }
02002 
02003 // a style for list formatted as a "enumeration" style
02004 const char * RTFGenerator::rtf_EList_DepthStyle()
02005 {
02006   QCString n=makeIndexName("ListEnum",m_listLevel);
02007   return rtf_Style[n]->reference;
02008 }
02009 
02010 const char * RTFGenerator::rtf_DList_DepthStyle()
02011 {
02012   QCString n=makeIndexName("DescContinue",m_listLevel);
02013   return rtf_Style[n]->reference;
02014 }
02015 
02016 const char * RTFGenerator::rtf_Code_DepthStyle()
02017 {
02018   QCString n=makeIndexName("CodeExample",m_listLevel);
02019   return rtf_Style[n]->reference;
02020 }
02021 
02022 void RTFGenerator::startTextBlock(bool dense)
02023 {
02024   DBG_RTF(t << "{\\comment startTextBlock}" << endl)
02025   t << "{" << endl;
02026   t << rtf_Style_Reset;
02027   if (dense) // no spacing between "paragraphs"
02028   {
02029     t << rtf_Style["DenseText"]->reference;
02030   }
02031   else // some spacing
02032   {
02033     t << rtf_Style["BodyText"]->reference;
02034   }
02035 }
02036 
02037 void RTFGenerator::endTextBlock(bool /*paraBreak*/)
02038 {
02039   newParagraph();
02040   DBG_RTF(t << "{\\comment endTextBlock}" << endl)
02041   t << "}" << endl;
02042   //m_omitParagraph = TRUE;
02043 }
02044 
02045 void RTFGenerator::newParagraph()
02046 {
02047   if (!m_omitParagraph)
02048   {
02049     DBG_RTF(t << "{\\comment (newParagraph)}"    << endl)
02050     t << "\\par" << endl;
02051   }
02052   m_omitParagraph = FALSE;
02053 }
02054 
02055 void RTFGenerator::startParagraph()
02056 {
02057   DBG_RTF(t << "{\\comment startParagraph}" << endl)
02058   newParagraph();
02059   t << "{" << endl;
02060 }
02061 
02062 void RTFGenerator::endParagraph()
02063 {
02064   DBG_RTF(t << "{\\comment endParagraph}" << endl)
02065   t << "}\\par" << endl;
02066   m_omitParagraph = TRUE;
02067 }
02068 
02069 void RTFGenerator::startMemberSubtitle()
02070 {
02071   DBG_RTF(t << "{\\comment startMemberSubtitle}" << endl)
02072   t << "{" << endl;
02073   t << rtf_Style_Reset << rtf_CList_DepthStyle() << endl;
02074 }
02075 
02076 void RTFGenerator::endMemberSubtitle()
02077 {
02078   DBG_RTF(t << "{\\comment endMemberSubtitle}" << endl)
02079   newParagraph();
02080   t << "}" << endl;
02081 }
02082 
02083 //void RTFGenerator::writeUmlaut(char c)
02084 //{
02085 //  switch(c)
02086 //  {
02087 //    case 'A' : t << '\304'; break;
02088 //    case 'E' : t << '\313'; break;
02089 //    case 'I' : t << '\317'; break;
02090 //    case 'O' : t << '\326'; break;
02091 //    case 'U' : t << '\334'; break;
02092 //    case 'Y' : t << 'Y';    break;
02093 //    case 'a' : t << '\344'; break;
02094 //    case 'e' : t << '\353'; break;
02095 //    case 'i' : t << '\357'; break;
02096 //    case 'o' : t << '\366'; break;
02097 //    case 'u' : t << '\374'; break;
02098 //    case 'y' : t << '\377'; break;
02099 //    default: t << '?'; break;
02100 //  }
02101 //}
02102 //
02103 //void RTFGenerator::writeAcute(char c)
02104 //{
02105 //  switch(c)
02106 //  {
02107 //    case 'A' : t << '\301'; break;
02108 //    case 'E' : t << '\311'; break;
02109 //    case 'I' : t << '\315'; break;
02110 //    case 'O' : t << '\323'; break;
02111 //    case 'U' : t << '\332'; break;
02112 //    case 'Y' : t << '\335'; break;
02113 //    case 'a' : t << '\341'; break;
02114 //    case 'e' : t << '\351'; break;
02115 //    case 'i' : t << '\355'; break;
02116 //    case 'o' : t << '\363'; break;
02117 //    case 'u' : t << '\372'; break;
02118 //    case 'y' : t << '\375'; break;
02119 //    default: t << '?'; break;
02120 //  }
02121 //}
02122 //
02123 //void RTFGenerator::writeGrave(char c)
02124 //{
02125 //  switch(c)
02126 //  {
02127 //    case 'A' : t << '\300'; break;
02128 //    case 'E' : t << '\310'; break;
02129 //    case 'I' : t << '\314'; break;
02130 //    case 'O' : t << '\322'; break;
02131 //    case 'U' : t << '\331'; break;
02132 //    case 'a' : t << '\340'; break;
02133 //    case 'e' : t << '\350'; break;
02134 //    case 'i' : t << '\354'; break;
02135 //    case 'o' : t << '\362'; break;
02136 //    case 'u' : t << '\371'; break;
02137 //    default: t << '?'; break;
02138 //  }
02139 //}
02140 //
02141 //void RTFGenerator::writeCirc(char c)
02142 //{
02143 //  switch(c)
02144 //  {
02145 //    case 'A' : t << '\302'; break;
02146 //    case 'E' : t << '\312'; break;
02147 //    case 'I' : t << '\316'; break;
02148 //    case 'O' : t << '\324'; break;
02149 //    case 'U' : t << '\333'; break;
02150 //    case 'a' : t << '\342'; break;
02151 //    case 'e' : t << '\352'; break;
02152 //    case 'i' : t << '\356'; break;
02153 //    case 'o' : t << '\364'; break;
02154 //    case 'u' : t << '\373'; break;
02155 //    default: t << '?'; break;
02156 //  }
02157 //}
02158 //
02159 //void RTFGenerator::writeTilde(char c)
02160 //{
02161 //  switch(c)
02162 //  {
02163 //    case 'A' : t << '\303'; break;
02164 //    case 'N' : t << '\321'; break;
02165 //    case 'O' : t << '\325'; break;
02166 //    case 'a' : t << '\343'; break;
02167 //    case 'n' : t << '\361'; break;
02168 //    case 'o' : t << '\365'; break;
02169 //    default: t << '?'; break;
02170 //  }
02171 //}
02172 //
02173 //void RTFGenerator::writeRing(char c)
02174 //{
02175 //  switch(c)
02176 //  {
02177 //    case 'A' : t << '\305'; break;
02178 //    case 'a' : t << '\345'; break;
02179 //    default: t << '?'; break;
02180 //  }
02181 //}
02182 //
02183 //void RTFGenerator::writeCCedil(char c)
02184 //{
02185 //  switch(c)
02186 //  {
02187 //    case 'C' : t << '\307'; break;
02188 //    case 'c' : t << '\347'; break;
02189 //    default: t << '?'; break;
02190 //  }
02191 //}
02192 //
02197 static bool PreProcessFile(QDir &d,QCString &infName, QTextStream &t, bool bIncludeHeader=TRUE)
02198 {
02199   QFile f(infName);
02200   if (!f.open(IO_ReadOnly))
02201   {
02202     err("Error opening rtf file %s for reading\n",infName.data());
02203     return FALSE;
02204   }
02205 
02206   const int maxLineLength = 10240;
02207   static QCString lineBuf(maxLineLength);
02208 
02209   // scan until find end of header
02210   // this is EXTREEEEEEEMLY brittle.  It works on OUR rtf
02211   // files because the first line before the body
02212   // ALWAYS contains "{\comment begin body}"
02213   do
02214   {
02215     if (f.readLine(lineBuf.data(),maxLineLength)==-1)
02216     {
02217       err("ERROR - read error in %s before end of RTF header!\n",infName.data());
02218       return FALSE;
02219     }
02220     if (bIncludeHeader) t << lineBuf;
02221   } while (lineBuf.find("\\comment begin body")==-1);
02222 
02223 
02224   //while (fgets(buffer,sizeof(buffer),infp) != NULL)
02225   while (f.readLine(lineBuf.data(),maxLineLength)!=-1)
02226   {
02227     int pos;
02228     if ((pos=lineBuf.find("INCLUDETEXT"))!=-1)
02229     {
02230       int startNamePos  = lineBuf.find('"',pos)+1;
02231       int endNamePos    = lineBuf.find('"',startNamePos);
02232       QCString fileName = lineBuf.mid(startNamePos,endNamePos-startNamePos);
02233       DBG_RTF(t << "{\\comment begin include " << fileName << "}" << endl)
02234       if (!PreProcessFile(d,fileName,t,FALSE)) return FALSE;
02235       DBG_RTF(t << "{\\comment end include " << fileName << "}" << endl)
02236     }
02237     else
02238     {
02239       // elaborate hoopla to skip  the final "}" if we didn't include the
02240       // headers
02241       if (!f.atEnd() || bIncludeHeader)
02242       {
02243         t << lineBuf;
02244       }
02245       else
02246       {
02247         // null terminate at the last '}'
02248         //char *str = strrchr(buffer,'}');
02249         int pos = lineBuf.findRev('}');
02250 
02251         if (pos != -1)
02252           lineBuf.at(pos) = '\0';
02253         else
02254           err("Strange, the last char was not a '}'\n");
02255         t << lineBuf;
02256       }
02257     }
02258   }
02259   f.close();
02260   // remove temporary file
02261   d.remove(infName);
02262   return TRUE;
02263 }
02264 
02265 void RTFGenerator::startDotGraph()
02266 {
02267   DBG_RTF(t << "{\\comment (startDotGraph)}"    << endl)
02268 }
02269 
02270 void RTFGenerator::endDotGraph(const DotClassGraph &g)
02271 {
02272   newParagraph();
02273 
02274   QCString fileName =
02275     g.writeGraph(t,BITMAP,Config_getString("RTF_OUTPUT"),relPath,TRUE,FALSE);
02276 
02277   // display the file
02278   t << "{" << endl;
02279   t << rtf_Style_Reset << endl;
02280   t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
02281   t << fileName << "." << Config_getEnum("DOT_IMAGE_FORMAT");
02282   t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
02283   t << "}" << endl;
02284   newParagraph();
02285   DBG_RTF(t << "{\\comment (endDotGraph)}"    << endl)
02286 }
02287 
02288 void RTFGenerator::startInclDepGraph()
02289 {
02290   DBG_RTF(t << "{\\comment (startInclDepGraph)}"    << endl)
02291 }
02292 
02293 void RTFGenerator::endInclDepGraph(const DotInclDepGraph &g)
02294 {
02295   newParagraph();
02296 
02297   QCString fileName = g.writeGraph(t,BITMAP,Config_getString("RTF_OUTPUT"),
02298                          relPath,FALSE);
02299 
02300   // display the file
02301   t << "{" << endl;
02302   t << rtf_Style_Reset << endl;
02303   t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
02304   t << fileName << "." << Config_getEnum("DOT_IMAGE_FORMAT");
02305   t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
02306   t << "}" << endl;
02307   DBG_RTF(t << "{\\comment (endInclDepGraph)}"    << endl)
02308 }
02309 
02310 void RTFGenerator::startGroupCollaboration()
02311 {
02312 }
02313 
02314 void RTFGenerator::endGroupCollaboration(const DotGroupCollaboration &)
02315 {
02316 }
02317 
02318 void RTFGenerator::startCallGraph()
02319 {
02320   DBG_RTF(t << "{\\comment (startCallGraph)}"    << endl)
02321 }
02322 
02323 void RTFGenerator::endCallGraph(const DotCallGraph &g)
02324 {
02325   newParagraph();
02326 
02327   QCString fileName = g.writeGraph(t,BITMAP,Config_getString("RTF_OUTPUT"),
02328                         relPath,FALSE);
02329 
02330   // display the file
02331   t << "{" << endl;
02332   t << rtf_Style_Reset << endl;
02333   t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
02334   t << fileName << "." << Config_getEnum("DOT_IMAGE_FORMAT");
02335   t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
02336   t << "}" << endl;
02337   DBG_RTF(t << "{\\comment (endCallGraph)}"    << endl)
02338 }
02339 
02340 void RTFGenerator::startDirDepGraph()
02341 {
02342   DBG_RTF(t << "{\\comment (startDirDepGraph)}"    << endl)
02343 }
02344 
02345 void RTFGenerator::endDirDepGraph(const DotDirDeps &g)
02346 {
02347   newParagraph();
02348 
02349   QCString fileName = g.writeGraph(t,BITMAP,Config_getString("RTF_OUTPUT"),
02350                         relPath,FALSE);
02351 
02352   // display the file
02353   t << "{" << endl;
02354   t << rtf_Style_Reset << endl;
02355   t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
02356   t << fileName << "." << Config_getEnum("DOT_IMAGE_FORMAT");
02357   t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
02358   t << "}" << endl;
02359   DBG_RTF(t << "{\\comment (endDirDepGraph)}"    << endl)
02360 }
02361 
02365 void testRTFOutput(const char *name)
02366 {
02367   int bcount=0;
02368   int line=1;
02369   int c;
02370   QFile f(name);
02371   if (f.open(IO_ReadOnly))
02372   {
02373     while ((c=f.getch())!=-1)
02374     {
02375       if (c=='\\') // escape char
02376       {
02377         c=f.getch();
02378         if (c==-1) break;
02379       }
02380       else if (c=='{') // open bracket
02381       {
02382         bcount++;
02383       }
02384       else if (c=='}') // close bracket
02385       {
02386         bcount--;
02387         if (bcount<0)
02388         {
02389           goto err;
02390           break;
02391         }
02392       }
02393       else if (c=='\n') // newline
02394       {
02395         line++;
02396       }
02397     }
02398   }
02399   if (bcount==0) return; // file is OK.
02400 err:
02401   err("Error: RTF integrity test failed at line %d of %s due to a bracket mismatch.\n",line,name);
02402   err("       Please try to create a small code example that produces this error \n"
02403       "       and send that to dimitri@stack.nl.\n");
02404 }
02405 
02410 bool RTFGenerator::preProcessFileInplace(const char *path,const char *name)
02411 {
02412   QDir d(path);
02413   // store the original directory
02414   if (!d.exists())
02415   {
02416     err("Error: Output dir %s does not exist!\n",path);
02417     return FALSE;
02418   }
02419   QCString oldDir = convertToQCString(QDir::currentDirPath());
02420 
02421   // go to the html output directory (i.e. path)
02422   QDir::setCurrent(d.absPath());
02423   QDir thisDir;
02424 
02425   QCString combinedName = (QCString)path+"/combined.rtf";
02426   QCString mainRTFName  = (QCString)path+"/"+name;
02427 
02428   QFile outf(combinedName);
02429   if (!outf.open(IO_WriteOnly))
02430   {
02431     err("Failed to open %s for writing!\n",combinedName.data());
02432     return FALSE;
02433   }
02434   QTextStream outt(&outf);
02435   outt.setEncoding(QTextStream::UnicodeUTF8);
02436 
02437   if (!PreProcessFile(thisDir,mainRTFName,outt))
02438   {
02439     // it failed, remove the temp file
02440     outf.close();
02441     thisDir.remove(combinedName);
02442     QDir::setCurrent(oldDir);
02443     return FALSE;
02444   }
02445 
02446   // everything worked, move the files
02447   outf.close();
02448   thisDir.remove(mainRTFName);
02449   thisDir.rename(combinedName,mainRTFName);
02450 
02451   testRTFOutput(mainRTFName);
02452 
02453   QDir::setCurrent(oldDir);
02454   return TRUE;
02455 }
02456 
02457 void RTFGenerator::startMemberGroupHeader(bool hasHeader)
02458 {
02459   DBG_RTF(t << "{\\comment startMemberGroupHeader}" << endl)
02460   t << "{" << endl;
02461   if (hasHeader) incrementIndentLevel();
02462   t << rtf_Style_Reset << rtf_Style["GroupHeader"]->reference;
02463 }
02464 
02465 void RTFGenerator::endMemberGroupHeader()
02466 {
02467   DBG_RTF(t << "{\\comment endMemberGroupHeader}" << endl)
02468   newParagraph();
02469   t << rtf_Style_Reset << rtf_CList_DepthStyle();
02470 }
02471 
02472 void RTFGenerator::startMemberGroupDocs()
02473 {
02474   DBG_RTF(t << "{\\comment startMemberGroupDocs}" << endl)
02475   startEmphasis();
02476 }
02477 
02478 void RTFGenerator::endMemberGroupDocs()
02479 {
02480   DBG_RTF(t << "{\\comment endMemberGroupDocs}" << endl)
02481   endEmphasis();
02482   newParagraph();
02483 }
02484 
02485 void RTFGenerator::startMemberGroup()
02486 {
02487   DBG_RTF(t << "{\\comment startMemberGroup}" << endl)
02488   t << rtf_Style_Reset << rtf_BList_DepthStyle() << endl;
02489 }
02490 
02491 void RTFGenerator::endMemberGroup(bool hasHeader)
02492 {
02493   DBG_RTF(t << "{\\comment endMemberGroup}" << endl)
02494   if (hasHeader) decrementIndentLevel();
02495   t << "}";
02496 }
02497 
02498 void RTFGenerator::startSimpleSect(SectionTypes,const char *file,const char *anchor,const char *title)
02499 {
02500   DBG_RTF(t << "{\\comment (startSimpleSect)}"    << endl)
02501   t << "{"; // ends at endDescList
02502   t << "{"; // ends at endDescTitle
02503   startBold();
02504   newParagraph();
02505   if (file)
02506   {
02507     writeObjectLink(0,file,anchor,title);
02508   }
02509   else
02510   {
02511     docify(title);
02512   }
02513   endBold();
02514   t << "}";
02515   newParagraph();
02516   incrementIndentLevel();
02517   t << rtf_Style_Reset << rtf_DList_DepthStyle();
02518 }
02519 
02520 void RTFGenerator::endSimpleSect()
02521 {
02522   DBG_RTF(t << "{\\comment (endSimpleSect)}"    << endl)
02523   newParagraph();
02524   decrementIndentLevel();
02525   m_omitParagraph = TRUE;
02526   t << "}";
02527 }
02528 
02529 void RTFGenerator::startParamList(ParamListTypes,const char *title)
02530 {
02531   DBG_RTF(t << "{\\comment (startParamList)}"    << endl)
02532   t << "{"; // ends at endParamList
02533   t << "{"; // ends at endDescTitle
02534   startBold();
02535   newParagraph();
02536   docify(title);
02537   endBold();
02538   t << "}";
02539   newParagraph();
02540   incrementIndentLevel();
02541   t << rtf_Style_Reset << rtf_DList_DepthStyle();
02542 }
02543 
02544 void RTFGenerator::endParamList()
02545 {
02546   DBG_RTF(t << "{\\comment (endParamList)}"    << endl)
02547   newParagraph();
02548   decrementIndentLevel();
02549   m_omitParagraph = TRUE;
02550   t << "}";
02551 }
02552 
02553 void RTFGenerator::startParameterType(bool first,const char *key)
02554 {
02555   DBG_RTF(t << "{\\comment (startParameterList)}"    << endl)
02556   if (!first)
02557   {
02558     t << " " << key << " ";
02559   }
02560 }
02561 
02562 void RTFGenerator::printDoc(DocNode *n,const char *langExt)
02563 {
02564   RTFDocVisitor *visitor = new RTFDocVisitor(t,*this,langExt);
02565   n->accept(visitor);
02566   delete visitor; 
02567   m_omitParagraph = TRUE;
02568 }
02569 
02570 void RTFGenerator::rtfwriteRuler_doubleline() 
02571 { 
02572   DBG_RTF(t << "{\\comment (rtfwriteRuler_doubleline)}"    << endl)
02573   t << "{\\pard\\widctlpar\\brdrb\\brdrdb\\brdrw15\\brsp20 \\adjustright \\par}" << endl; 
02574 }
02575 
02576 void RTFGenerator::rtfwriteRuler_emboss() 
02577 { 
02578   DBG_RTF(t << "{\\comment (rtfwriteRuler_emboss)}"    << endl)
02579   t << "{\\pard\\widctlpar\\brdrb\\brdremboss\\brdrw15\\brsp20 \\adjustright \\par}" << endl; 
02580 }
02581 
02582 void RTFGenerator::rtfwriteRuler_thick() 
02583 { 
02584   DBG_RTF(t << "{\\comment (rtfwriteRuler_thick)}"    << endl)
02585   t << "{\\pard\\widctlpar\\brdrb\\brdrs\\brdrw75\\brsp20 \\adjustright \\par}" << endl; 
02586 }
02587 
02588 void RTFGenerator::rtfwriteRuler_thin() 
02589 { 
02590   DBG_RTF(t << "{\\comment (rtfwriteRuler_thin)}"    << endl)
02591   t << "{\\pard\\widctlpar\\brdrb\\brdrs\\brdrw5\\brsp20 \\adjustright \\par}" << endl; 
02592 }
02593 
02594 void RTFGenerator::postProcess(QByteArray &a)
02595 {
02596   QByteArray enc(a.size()*4); // worst case
02597   int off=0;
02598   uint i;
02599   for (i=0;i<a.size();i++)
02600   {
02601     unsigned char c = (unsigned char)a.at(i);
02602     if (c>0x80)
02603     {
02604       char s[10];
02605       sprintf(s,"\\'%X",c);
02606       qstrcpy(enc.data()+off,s);
02607       off+=qstrlen(s);
02608     }
02609     else
02610     {
02611       enc.at(off++)=c;
02612     }
02613   }
02614   enc.resize(off);
02615   a = enc;
02616 }
02617 
02618 void RTFGenerator::startConstraintList(const char *header)
02619 {
02620   DBG_RTF(t << "{\\comment (startConstraintList)}"    << endl)
02621   t << "{"; // ends at endConstraintList
02622   t << "{"; 
02623   startBold();
02624   newParagraph();
02625   docify(header);
02626   endBold();
02627   t << "}";
02628   newParagraph();
02629   incrementIndentLevel();
02630   t << rtf_Style_Reset << rtf_DList_DepthStyle();
02631 }
02632 
02633 void RTFGenerator::startConstraintParam()
02634 {
02635   DBG_RTF(t << "{\\comment (startConstraintParam)}"    << endl)
02636   startEmphasis();
02637 }
02638 
02639 void RTFGenerator::endConstraintParam()
02640 {
02641   DBG_RTF(t << "{\\comment (endConstraintParam)}"    << endl)
02642   endEmphasis();
02643   t << " : ";
02644 }
02645 
02646 void RTFGenerator::startConstraintType()
02647 {
02648   DBG_RTF(t << "{\\comment (startConstraintType)}"    << endl)
02649   startEmphasis();
02650 }
02651 
02652 void RTFGenerator::endConstraintType()
02653 {
02654   DBG_RTF(t << "{\\comment (endConstraintType)}"    << endl)
02655   endEmphasis();
02656   t << " ";
02657 }
02658 
02659 void RTFGenerator::startConstraintDocs()
02660 {
02661   DBG_RTF(t << "{\\comment (startConstraintDocs)}"    << endl)
02662 }
02663 
02664 void RTFGenerator::endConstraintDocs()
02665 {
02666   DBG_RTF(t << "{\\comment (endConstraintDocs)}"    << endl)
02667   newParagraph();
02668 }
02669 
02670 void RTFGenerator::endConstraintList()
02671 {
02672   DBG_RTF(t << "{\\comment (endConstraintList)}"    << endl)
02673   newParagraph();
02674   decrementIndentLevel();
02675   m_omitParagraph = TRUE;
02676   t << "}";
02677 }
02678 
02679 
02680 
02681 



Generated on Mon Mar 31 10:58:43 2008 by  doxygen 1.5.1