Orb/Doxygen/src/rtfgen.cpp
changeset 0 42188c7ea2d9
child 4 468f4c8d3d5b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Orb/Doxygen/src/rtfgen.cpp	Thu Jan 21 17:29:01 2010 +0000
@@ -0,0 +1,2715 @@
+/******************************************************************************
+ *
+ * 
+ *
+ * Copyright (C) 1997-2008 by Parker Waechter & Dimitri van Heesch.
+ *
+ * Style sheet additions by Alexander Bartolich
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation under the terms of the GNU General Public License is hereby
+ * granted. No representations are made about the suitability of this software
+ * for any purpose. It is provided "as is" without express or implied warranty.
+ * See the GNU General Public License for more details.
+ *
+ * Documents produced by Doxygen are derivative works derived from the
+ * input used in their production; they are not affected by this license.
+ *
+ */
+
+#include <stdlib.h>
+
+#include "qtbc.h"
+#include <qdir.h>
+#include <qregexp.h>
+
+#include "rtfgen.h"
+#include "config.h"
+#include "message.h"
+#include "doxygen.h"
+#include "util.h"
+#include "diagram.h"
+#include "language.h"
+#include "dot.h"
+#include "version.h"
+#include "pagedef.h"
+#include "rtfstyle.h"
+#include "rtfdocvisitor.h"
+#include "docparser.h"
+#include "dirdef.h"
+#include "vhdldocgen.h"
+
+//#define DBG_RTF(x) x;
+#define DBG_RTF(x)
+
+static QCString dateToRTFDateString()
+{
+  const QDateTime &d = QDateTime::currentDateTime();
+  QCString result;
+  result.sprintf("\\yr%d\\mo%d\\dy%d\\hr%d\\min%d\\sec%d",
+      d.date().year(), d.date().month(), d.date().day(),
+      d.time().hour(),d.time().minute(),d.time().second());
+  return result;
+} 
+
+RTFGenerator::RTFGenerator() : OutputGenerator()
+{
+  dir=Config_getString("RTF_OUTPUT");
+  col=0;
+  //insideTabbing=FALSE;
+  m_listLevel = 0;
+  m_bstartedBody = FALSE;
+  m_omitParagraph = FALSE;
+  m_numCols = 0;
+}
+
+RTFGenerator::~RTFGenerator()
+{
+}
+
+//void RTFGenerator::append(const OutputGenerator *g)
+//{
+//  t << g->getContents();
+//  col+=((RTFGenerator *)g)->col;
+//  //insideTabbing=insideTabbing || ((RTFGenerator *)g)->insideTabbing;
+//  m_listLevel=((RTFGenerator *)g)->m_listLevel;
+//  m_omitParagraph=((RTFGenerator *)g)->m_omitParagraph;
+//  //printf("RTFGenerator::append(%s) insideTabbing=%s\n", g->getContents().data(),
+//  //    insideTabbing ? "TRUE" : "FALSE" );
+//}
+
+//OutputGenerator *RTFGenerator::copy()
+//{
+//  RTFGenerator *result = new RTFGenerator;
+//  //result->insideTabbing=insideTabbing;
+//  result->m_listLevel=m_listLevel;
+//  result->m_omitParagraph=m_omitParagraph;
+//  return result;
+//}
+
+void RTFGenerator::writeStyleSheetFile(QFile &file)
+{
+  QTextStream t(&file);
+  t << "# Generated by doxygen " << versionString << "\n\n";
+  t << "# This file describes styles used for generating RTF output.\n";
+  t << "# All text after a hash (#) is considered a comment and will be ignored.\n";
+  t << "# Remove a hash to activate a line.\n\n";
+
+  int i;
+  for ( i=0 ; rtf_Style_Default[i].reference!=0 ; i++ )
+  {
+    t << "# " << rtf_Style_Default[i].name << " = "
+              << rtf_Style_Default[i].reference
+              << rtf_Style_Default[i].definition << endl;
+  }
+}
+
+void RTFGenerator::writeExtensionsFile(QFile &file)
+{
+  QTextStream t(&file);
+  t << "# Generated by doxygen " << versionString << "\n\n";
+  t << "# This file describes extensions used for generating RTF output.\n";
+  t << "# All text after a hash (#) is considered a comment and will be ignored.\n";
+  t << "# Remove a hash to activate a line.\n\n";
+
+  t << "# Overrides the project title.\n";
+
+  t << "#Title           = \n\n";
+
+  t << "# Name of the company that produced this document.\n";
+  t << "#Company         = \n\n";
+
+  t << "# Filename of a company or project logo.\n";
+  t << "#LogoFilename    = \n\n";
+
+  t << "# Author of the document.\n";
+  t << "#Author          = \n\n";
+
+  t << "# Type of document (e.g. Design Specification, User Manual, etc.).\n";
+  t << "#DocumentType    = \n\n";
+
+  t << "# Document tracking number.\n";
+  t << "#DocumentId      = \n\n";
+
+  t << "# Name of the author's manager.\n";
+  t << "# This field is not displayed in the document itself, but it is \n";
+  t << "# available in the information block of the rtf file.  In Microsoft \n";
+  t << "# Word, it is available under File:Properties.\n";
+  t << "#Manager         = \n\n";
+
+  t << "# Subject of the document.\n";
+  t << "# This field is not displayed in the document itself, but it is \n";
+  t << "# available in the information block of the rtf file.  In Microsoft \n";
+  t << "# Word, it is available under File:Properties.\n";
+  t << "#Subject         = \n\n";
+
+  t << "# Comments regarding the document.\n";
+  t << "# This field is not displayed in the document itself, but it is \n";
+  t << "# available in the information block of the rtf file.  In Microsoft \n";
+  t << "# Word, it is available under File:Properties.\n";
+  t << "#Comments        = \n\n";
+
+  t << "# Keywords associated with the document.\n";
+  t << "# This field is not displayed in the document itself, but it is \n";
+  t << "# available in the information block of the rtf file.  In Microsoft \n";
+  t << "# Word, it is available under File:Properties.\n";
+  t << "#Keywords        = \n\n";
+}
+
+
+void RTFGenerator::init()
+{
+  QCString dir=Config_getString("RTF_OUTPUT");
+  QDir d(dir);
+  if (!d.exists() && !d.mkdir(dir))
+  {
+    err("Could not create output directory %s\n",dir.data());
+    exit(1);
+  }
+  rtf_Style.setAutoDelete(TRUE);
+
+  // first duplicate strings of rtf_Style_Default
+  const struct Rtf_Style_Default* def = rtf_Style_Default;
+  while(def->reference != 0)
+  {
+    if (def->definition == 0)
+      err("Internal error: rtf_Style_Default[%s] has no definition.\n", def->name);
+    StyleData* styleData = new StyleData(def->reference, def->definition);
+    rtf_Style.insert(def->name, styleData);
+    def++;
+  }
+
+  // overwrite some (or all) definitions from file
+  QCString &rtfStyleSheetFile = Config_getString("RTF_STYLESHEET_FILE");
+  if (!rtfStyleSheetFile.isEmpty())
+  {
+    loadStylesheet(rtfStyleSheetFile, rtf_Style);
+  }
+
+  // If user has defined an extension file, load its contents.
+  QCString &rtfExtensionsFile = Config_getString("RTF_EXTENSIONS_FILE");
+  if (!rtfExtensionsFile.isEmpty())
+  {
+    loadExtensions(rtfExtensionsFile);
+  }
+
+  createSubDirs(d);
+}
+
+static QCString makeIndexName(const char *s,int i)
+{
+  QCString result=s;
+  result+=(char)(i+'0');
+  return result;
+}
+
+void RTFGenerator::beginRTFDocument()
+{
+  /* all the included RTF files should begin with the
+   * same header
+   */
+  t <<"{\\rtf1\\ansi\\ansicpg" << theTranslator->trRTFansicp();
+  t <<"\\uc1 \\deff0\\deflang1033\\deflangfe1033\n";
+
+  DBG_RTF(t <<"{\\comment Begining font list}\n")
+  t <<"{\\fonttbl ";
+  t <<"{\\f0\\froman\\fcharset" << theTranslator->trRTFCharSet();
+  t <<"\\fprq2{\\*\\panose 02020603050405020304}Times New Roman;}\n";
+  t <<"{\\f1\\fswiss\\fcharset" << theTranslator->trRTFCharSet();
+  t <<"\\fprq2{\\*\\panose 020b0604020202020204}Arial;}\n";
+  t <<"{\\f2\\fmodern\\fcharset" << theTranslator->trRTFCharSet();
+  t <<"\\fprq1{\\*\\panose 02070309020205020404}Courier New;}\n";
+  t <<"{\\f3\\froman\\fcharset2\\fprq2{\\*\\panose 05050102010706020507}Symbol;}\n";
+  t <<"}\n";
+  DBG_RTF(t <<"{\\comment begin colors}\n")
+  t <<"{\\colortbl;";
+  t <<"\\red0\\green0\\blue0;";
+  t <<"\\red0\\green0\\blue255;";
+  t <<"\\red0\\green255\\blue255;";
+  t <<"\\red0\\green255\\blue0;";
+  t <<"\\red255\\green0\\blue255;";
+  t <<"\\red255\\green0\\blue0;";
+  t <<"\\red255\\green255\\blue0;";
+  t <<"\\red255\\green255\\blue255;";
+  t <<"\\red0\\green0\\blue128;";
+  t <<"\\red0\\green128\\blue128;";
+  t <<"\\red0\\green128\\blue0;";
+  t <<"\\red128\\green0\\blue128;";
+  t <<"\\red128\\green0\\blue0;";
+  t <<"\\red128\\green128\\blue0;";
+  t <<"\\red128\\green128\\blue128;";
+  t <<"\\red192\\green192\\blue192;}" << endl;
+
+  DBG_RTF(t <<"{\\comment Beginning style list}\n")
+  t <<"{\\stylesheet\n";
+  t <<"{\\widctlpar\\adjustright \\fs20\\cgrid \\snext0 Normal;}\n";
+
+  // sort styles ascending by \s-number via an intermediate QArray
+  QArray<const StyleData*> array(128);
+  array.fill(0);
+  QDictIterator<StyleData> iter(rtf_Style);
+  const StyleData* style;
+  for(; (style = iter.current()); ++iter)
+  {
+    unsigned index = style->index;
+    unsigned size = array.size();
+    if (index >= size)
+    {
+      // +1 to add at least one element, then align up to multiple of 8
+      array.resize((index + 1 + 7) & ~7);
+      array.fill(0, size);
+      ASSERT(index < array.size());
+    }
+    if (array.at(index) != 0)
+    {
+      QCString key(convertToQCString(iter.currentKey()));
+      msg("Style '%s' redefines \\s%d.\n", key.data(), index);
+    }
+    array.at(index) = style;
+  }
+
+  // write array elements
+  unsigned size = array.size();
+  for(unsigned i = 0; i < size; i++)
+  {
+    const StyleData* style = array.at(i);
+    if (style != 0)
+      t <<"{" << style->reference << style->definition << ";}\n";
+  }
+
+  t <<"}" << endl;
+  // this comment is needed for postprocessing!
+  t <<"{\\comment begin body}" << endl;
+
+}
+
+void RTFGenerator::beginRTFChapter()
+{
+  t <<"\n";
+  DBG_RTF(t << "{\\comment BeginRTFChapter}\n")
+  t << rtf_Style_Reset;
+
+  // if we are compact, no extra page breaks...
+  if (Config_getBool("COMPACT_RTF"))
+  {
+    //      t <<"\\sect\\sectd\\sbknone\n";
+    t <<"\\sect\\sbknone\n";
+    rtfwriteRuler_thick();
+  }
+  else
+    t <<"\\sect\\sbkpage\n";
+  //t <<"\\sect\\sectd\\sbkpage\n";
+
+  t << rtf_Style["Heading1"]->reference << "\n";
+}
+
+void RTFGenerator::beginRTFSection()
+{
+  t <<"\n";
+  DBG_RTF(t << "{\\comment BeginRTFSection}\n")
+  t << rtf_Style_Reset;
+
+  // if we are compact, no extra page breaks...
+  if (Config_getBool("COMPACT_RTF"))
+  {
+    //      t <<"\\sect\\sectd\\sbknone\n";
+    t <<"\\sect\\sbknone\n";
+    rtfwriteRuler_emboss();
+  }
+  else
+    t <<"\\sect\\sbkpage\n";
+  //t <<"\\sect\\sectd\\sbkpage\n";
+
+  t << rtf_Style["Heading2"]->reference << "\n";
+}
+
+void RTFGenerator::startFile(const char *name,const char *,const char *)
+{
+  setEncoding(QCString().sprintf("CP%s",theTranslator->trRTFansicp().data()));
+  QCString fileName=name;
+  relPath = relativePathToRoot(fileName);
+
+  if (fileName.right(4)!=".rtf" ) fileName+=".rtf";
+  startPlainFile(fileName);
+  beginRTFDocument();
+}
+
+void RTFGenerator::endFile()
+{
+  DBG_RTF(t << "{\\comment endFile}\n")
+  t << "}";
+
+  endPlainFile();
+}
+
+void RTFGenerator::startProjectNumber()
+{
+  DBG_RTF(t <<"{\\comment startProjectNumber }" << endl)
+  t << " ";
+}
+
+void RTFGenerator::endProjectNumber()
+{
+  DBG_RTF(t <<"{\\comment endProjectNumber }" << endl)
+}
+
+void RTFGenerator::startIndexSection(IndexSections is)
+{
+  //QCString paperName;
+
+  m_listLevel = 0;
+
+  switch (is)
+  {
+    case isTitlePageStart:
+      // basic RTFstart
+      // get readyfor author etc
+
+      t << "{\\info \n";
+      t << "{\\title {\\comment ";
+      break;
+    case isTitlePageAuthor:
+      t << "}\n";
+      if (rtf_subject)      t << "{\\subject "  << rtf_subject      << "}\n";
+      if (rtf_comments)     t << "{\\comment "  << rtf_comments     << "}\n";
+      if (rtf_company)      t << "{\\company "  << rtf_company      << "}\n";
+      if (rtf_author)       t << "{\\author "   << rtf_author       << "}\n";
+      if (rtf_manager)      t << "{\\manager "  << rtf_manager      << "}\n";
+      if (rtf_documentType) t << "{\\category " << rtf_documentType << "}\n";
+      if (rtf_keywords)     t << "{\\keywords " << rtf_keywords     << "}\n";
+      t << "{\\comment ";
+      break;
+    case isMainPage:
+      //Introduction
+      beginRTFChapter();
+      break;
+    //case isPackageIndex:
+    //  //Package Index
+    //  beginRTFChapter();
+    //  break;
+    case isModuleIndex:
+      //Module Index
+      beginRTFChapter();
+      break;
+    case isDirIndex:
+      //Directory Index
+      beginRTFChapter();
+      break;
+    case isNamespaceIndex:
+      //Namespace Index
+      beginRTFChapter();
+      break;
+    case isClassHierarchyIndex:
+      //Hierarchical Index
+      DBG_RTF(t << "{\\comment start classhierarchy}\n")
+      beginRTFChapter();
+      break;
+    case isCompoundIndex:
+      //Annotated Compound Index
+      beginRTFChapter();
+      break;
+    case isFileIndex:
+      //Annotated File Index
+      beginRTFChapter();
+      break;
+    case isPageIndex:
+      //Related Page Index
+      beginRTFChapter();
+      break;
+    case isModuleDocumentation:
+      {
+        //Module Documentation
+        GroupSDict::Iterator gli(*Doxygen::groupSDict);
+        GroupDef *gd;
+        bool found=FALSE;
+        for (gli.toFirst();(gd=gli.current()) && !found;++gli)
+        {
+          if (!gd->isReference())
+          {
+            beginRTFChapter();
+            found=TRUE;
+          }
+        }
+      }
+      break;
+    case isDirDocumentation:
+      {
+        //Directory Documentation
+        SDict<DirDef>::Iterator dli(*Doxygen::directories);
+        DirDef *dd;
+        bool found=FALSE;
+        for (dli.toFirst();(dd=dli.current()) && !found;++dli)
+        {
+          if (dd->isLinkableInProject())
+          {
+            beginRTFChapter();
+            found=TRUE;
+          }
+        }
+      }
+      break;
+    case isNamespaceDocumentation:
+      {
+        // Namespace Documentation
+        NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
+        NamespaceDef *nd;
+        bool found=FALSE;
+        for (nli.toFirst();(nd=nli.current()) && !found;++nli)
+        {
+          if (nd->isLinkableInProject())
+          {
+            beginRTFChapter();
+            found=TRUE;
+          }
+        }
+      }
+      break;
+    case isClassDocumentation:
+      {
+        //Compound Documentation
+        ClassSDict::Iterator cli(*Doxygen::classSDict);
+        ClassDef *cd=0;
+        bool found=FALSE;
+        for (cli.toFirst();(cd=cli.current()) && !found;++cli)
+        {
+          if (cd->isLinkableInProject() && cd->templateMaster()==0)
+          {
+            beginRTFChapter();
+            found=TRUE;
+          }
+        }
+      }
+      break;
+    case isFileDocumentation:
+      {
+        //File Documentation
+        bool isFirst=TRUE;
+        FileName *fn=Doxygen::inputNameList->first();
+        while (fn)
+        {
+          FileDef *fd=fn->first();
+          while (fd)
+          {
+            if (fd->isLinkableInProject())
+            {
+              if (isFirst)
+              {
+                beginRTFChapter();
+                isFirst=FALSE;
+                break;
+              }
+            }
+            fd=fn->next();
+          }
+          fn=Doxygen::inputNameList->next();
+        }
+      }
+      break;
+    case isExampleDocumentation:
+      {
+        //Example Documentation
+        beginRTFChapter();
+      }
+      break;
+    case isPageDocumentation:
+      {
+        //Page Documentation
+        beginRTFChapter();
+      }
+      break;
+    case isPageDocumentation2:
+      {
+        t << "{\\tc \\v ";
+      }
+      break;
+    case isEndIndex:
+      break;
+  }
+}
+
+void RTFGenerator::endIndexSection(IndexSections is)
+{
+  bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
+  bool vhdlOpt    = Config_getBool("OPTIMIZE_OUTPUT_VHDL");  
+  switch (is)
+  {
+    case isTitlePageStart:
+      if (rtf_title)
+        // User has overridden document title in extensions file
+        t << "}" << rtf_title;
+      else
+        t << "}" << Config_getString("PROJECT_NAME");
+      break;
+    case isTitlePageAuthor:
+      {
+        t << "Doxgyen. }\n";
+        t << "{\\creatim " << dateToRTFDateString() << "}\n}";
+        DBG_RTF(t << "{\\comment end of infoblock}\n");
+        // setup for this section
+        t << rtf_Style_Reset <<"\n";
+        t <<"\\sectd\\pgnlcrm\n";
+        t <<"{\\footer "<<rtf_Style["Footer"]->reference << "{\\chpgn}}\n";
+        // the title entry
+        DBG_RTF(t << "{\\comment begin title page}\n")
+
+
+        t << rtf_Style_Reset << rtf_Style["SubTitle"]->reference << endl; // set to title style
+
+        t << "\\vertalc\\qc\\par\\par\\par\\par\\par\\par\\par\n";
+        if (rtf_logoFilename)
+        {
+          t << "{\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"" << rtf_logoFilename;
+          t << "\" \\\\d \\\\*MERGEFORMAT} {\\fldrslt IMAGE }}\\par\\par\n";
+        }
+        if (rtf_company)
+        {
+          t << rtf_company << "\\par\\par\n";
+        }
+
+        t << rtf_Style_Reset << rtf_Style["Title"]->reference << endl; // set to title style
+        t << "{\\field\\fldedit {\\*\\fldinst TITLE \\\\*MERGEFORMAT}{\\fldrslt TITLE}}\\par" << endl;
+
+        t << rtf_Style_Reset << rtf_Style["SubTitle"]->reference << endl; // set to title style
+        t << "\\par\n";
+        if (rtf_documentType)
+        {
+          t << rtf_documentType << "\\par\n";
+        }
+        if (rtf_documentId)
+        {
+          t << rtf_documentId << "\\par\n";
+        }
+        t << "\\par\\par\\par\\par\\par\\par\\par\\par\\par\\par\\par\\par\n";
+
+        t << rtf_Style_Reset << rtf_Style["SubTitle"]->reference << endl; // set to subtitle style
+        t << "{\\field\\fldedit {\\*\\fldinst AUTHOR \\\\*MERGEFORMAT}{\\fldrslt AUTHOR}}\\par" << endl;
+        t << "Version " << Config_getString("PROJECT_NUMBER") << "\\par";
+        t << "{\\field\\fldedit {\\*\\fldinst CREATEDATE \\\\*MERGEFORMAT}"
+          "{\\fldrslt CREATEDATE}}\\par"<<endl;
+        t << "\\page\\page";
+        DBG_RTF(t << "{\\comment End title page}" << endl)
+
+        // table of contents section
+        DBG_RTF(t << "{\\comment Table of contents}\n")
+        t << "\\vertalt\n";
+        t << rtf_Style_Reset << endl;
+        t << rtf_Style["Heading1"]->reference;
+        t << theTranslator->trRTFTableOfContents() << "\\par"<< endl;
+        t << rtf_Style_Reset << "\\par" << endl;
+        t << "{\\field\\fldedit {\\*\\fldinst TOC \\\\f \\\\*MERGEFORMAT}{\\fldrslt Table of contents}}\\par\n";
+        t << rtf_Style_Reset << endl;
+      }
+      break;
+    case isMainPage:
+      t << "\\par " << rtf_Style_Reset << endl;
+      if (!Doxygen::mainPage || Doxygen::mainPage->title().isEmpty())
+      {
+        t << "{\\tc \\v " << theTranslator->trMainPage() << "}"<< endl;
+      }
+      else
+      {
+        t << "{\\tc \\v " << substitute(Doxygen::mainPage->title(),"%","") << "}"<< endl;
+      }
+      t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
+      if (Config_getBool("GENERATE_TREEVIEW")) t << "main"; else t << "index";
+      t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+      break;
+    //case isPackageIndex:
+    //  t << "\\par " << rtf_Style_Reset << endl;
+    //  t << "{\\tc \\v " << theTranslator->trPackageList() << "}"<< endl;
+    //  t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"packages.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+    //  break;
+    case isModuleIndex:
+      t << "\\par " << rtf_Style_Reset << endl;
+      t << "{\\tc \\v " << theTranslator->trModuleIndex() << "}"<< endl;
+      t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"modules.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+      break;
+    case isDirIndex:
+      t << "\\par " << rtf_Style_Reset << endl;
+      t << "{\\tc \\v " << theTranslator->trDirIndex() << "}"<< endl;
+      t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"dirs.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+      break;
+    case isNamespaceIndex:
+      t << "\\par " << rtf_Style_Reset << endl;
+      if (fortranOpt)
+      {
+          t << "{\\tc \\v " << theTranslator->trModulesIndex() << "}"<< endl;
+      }
+      else
+      {
+          t << "{\\tc \\v " << theTranslator->trNamespaceIndex() << "}"<< endl;
+      }
+      
+      t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"namespaces.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+      break;
+    case isClassHierarchyIndex:
+      t << "\\par " << rtf_Style_Reset << endl;
+      t << "{\\tc \\v " << theTranslator->trHierarchicalIndex() << "}"<< endl;
+      t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"hierarchy.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+      break;
+    case isCompoundIndex:
+      t << "\\par " << rtf_Style_Reset << endl;
+      if (fortranOpt)
+      {
+        t << "{\\tc \\v " << theTranslator->trCompoundIndexFortran() << "}"<< endl;
+      }
+      else if (vhdlOpt)
+      {
+        t << "{\\tc \\v " << VhdlDocGen::trDesignUnitIndex() << "}"<< endl;
+      }
+      else
+      {
+        t << "{\\tc \\v " << theTranslator->trCompoundIndex() << "}"<< endl;
+      }
+      t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"annotated.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+      break;
+    case isFileIndex:
+      t << "\\par " << rtf_Style_Reset << endl;
+      t << "{\\tc \\v " << theTranslator->trFileIndex() << "}"<< endl;
+      t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"files.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+      break;
+    case isPageIndex:
+      t << "\\par " << rtf_Style_Reset << endl;
+      t << "{\\tc \\v " << theTranslator->trPageIndex() << "}"<< endl;
+      t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"pages.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+      break;
+    case isModuleDocumentation:
+      {
+        GroupSDict::Iterator gli(*Doxygen::groupSDict);
+        GroupDef *gd;
+        t << "{\\tc \\v " << theTranslator->trModuleDocumentation() << "}"<< endl;
+        for (gli.toFirst();(gd=gli.current());++gli)
+        {
+          if (!gd->isReference())
+          {
+            t << "\\par " << rtf_Style_Reset << endl;
+            t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
+            t << gd->getOutputFileBase();
+            t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+          }
+        }
+      }
+      break;
+    case isDirDocumentation:
+      {
+        SDict<DirDef>::Iterator dli(*Doxygen::directories);
+        DirDef *dd;
+        t << "{\\tc \\v " << theTranslator->trDirDocumentation() << "}"<< endl;
+        for (dli.toFirst();(dd=dli.current());++dli)
+        {
+          if (dd->isLinkableInProject())
+          {
+            t << "\\par " << rtf_Style_Reset << endl;
+            t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
+            t << dd->getOutputFileBase();
+            t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+          }
+        }
+      }
+      break;
+    case isNamespaceDocumentation:
+      {
+        NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
+        NamespaceDef *nd;
+        bool found=FALSE;
+        for (nli.toFirst();(nd=nli.current()) && !found;++nli)
+        {
+          if (nd->isLinkableInProject())
+          {
+            t << "\\par " << rtf_Style_Reset << endl;
+            t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
+            t << nd->getOutputFileBase();
+            t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+            found=TRUE;
+          }
+        }
+        while ((nd=nli.current()))
+        {
+          if (nd->isLinkableInProject())
+          {
+            t << "\\par " << rtf_Style_Reset << endl;
+            beginRTFSection();
+            t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
+            t << nd->getOutputFileBase();
+            t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+          }
+          ++nli;
+        }
+      }
+      break;
+    case isClassDocumentation:
+      {
+        ClassSDict::Iterator cli(*Doxygen::classSDict);
+        ClassDef *cd=0;
+        bool found=FALSE;
+        if (fortranOpt)
+        {
+          t << "{\\tc \\v " << theTranslator->trTypeDocumentation() << "}"<< endl;
+        }
+        else
+        {
+          t << "{\\tc \\v " << theTranslator->trClassDocumentation() << "}"<< endl;
+        }
+        for (cli.toFirst();(cd=cli.current()) && !found;++cli)
+        {
+          if (cd->isLinkableInProject() && cd->templateMaster()==0)
+          {
+            t << "\\par " << rtf_Style_Reset << endl;
+            t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
+            t << cd->getOutputFileBase();
+            t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+            found=TRUE;
+          }
+        }
+        for (;(cd=cli.current());++cli)
+        {
+          if (cd->isLinkableInProject() && cd->templateMaster()==0)
+          {
+            t << "\\par " << rtf_Style_Reset << endl;
+            beginRTFSection();
+            t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
+            t << cd->getOutputFileBase();
+            t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+          }
+        }
+      }
+      break;
+    case isFileDocumentation:
+      {
+        bool isFirst=TRUE;
+        FileName *fn=Doxygen::inputNameList->first();
+
+        t << "{\\tc \\v " << theTranslator->trFileDocumentation() << "}"<< endl;
+        while (fn)
+        {
+          FileDef *fd=fn->first();
+          while (fd)
+          {
+            if (fd->isLinkableInProject())
+            {
+              if (isFirst)
+              {
+                t << "\\par " << rtf_Style_Reset << endl;
+                t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
+                t << fd->getOutputFileBase();
+                t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+                isFirst=FALSE;
+              }
+              else
+              {
+                t << "\\par " << rtf_Style_Reset << endl;
+                beginRTFSection();
+                t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
+                t << fd->getOutputFileBase();
+                t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+              }
+            }
+            fd=fn->next();
+          }
+          fn=Doxygen::inputNameList->next();
+        }
+      }
+      break;
+    case isExampleDocumentation:
+      {
+        //t << "}\n";
+        t << "{\\tc \\v " << theTranslator->trExampleDocumentation() << "}"<< endl;
+        PageSDict::Iterator pdi(*Doxygen::exampleSDict);
+        PageDef *pd=pdi.toFirst();
+        if (pd)
+        {
+          t << "\\par " << rtf_Style_Reset << endl;
+          t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
+          t << pd->getOutputFileBase();
+          t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+        }
+        for (++pdi;(pd=pdi.current());++pdi)
+        {
+          t << "\\par " << rtf_Style_Reset << endl;
+          beginRTFSection();
+          t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
+          t << pd->getOutputFileBase();
+          t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+        }
+      }
+      break;
+    case isPageDocumentation:
+      {
+//#error "fix me in the same way as the latex index..."
+        //t << "{\\tc \\v " << theTranslator->trPageDocumentation() << "}"<< endl;
+        //t << "}"<< endl;
+        //PageSDict::Iterator pdi(*Doxygen::pageSDict);
+        //PageDef *pd=pdi.toFirst();
+        //bool first=TRUE;
+        //for (pdi.toFirst();(pd=pdi.current());++pdi)
+        //{
+        //  if (!pd->getGroupDef() && !pd->isReference())
+        //  {
+        //    if (first) t << "\\par " << rtf_Style_Reset << endl;
+        //    t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
+        //    t << pd->getOutputFileBase();
+        //    t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+        //    first=FALSE;
+        //  }
+        //}
+      }
+      break;
+    case isPageDocumentation2:
+      {
+        t << "}";
+        t << "\\par " << rtf_Style_Reset << endl;
+      }
+      break;
+    case isEndIndex:
+      beginRTFChapter();
+      t << rtf_Style["Heading1"]->reference;
+      t << theTranslator->trRTFGeneralIndex() << "\\par "<< endl;
+      t << rtf_Style_Reset << endl;
+      t << "{\\tc \\v " << theTranslator->trRTFGeneralIndex() << "}" << endl;
+      t << "{\\field\\fldedit {\\*\\fldinst INDEX \\\\c2 \\\\*MERGEFORMAT}{\\fldrslt INDEX}}\n";
+
+      break;
+   }
+}
+
+void RTFGenerator::writePageLink(const char *name,bool first)
+{
+   if (first) t << "\\par " << rtf_Style_Reset << endl;
+   t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
+   t << name;
+   t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
+}
+
+void RTFGenerator::lastIndexPage()
+{
+  DBG_RTF(t <<"{\\comment Beginning Body of RTF Document}\n")
+  // end page and setup for rest of document
+  t <<"\\sect \\sbkpage \\pgndec \\pgnrestart\n";
+  t <<"\\sect \\sectd \\sbknone\n";
+
+  // set new footer with arabic numbers
+  t <<"{\\footer "<< rtf_Style["Footer"]->reference << "{\\chpgn}}\n";
+  //t << rtf_Style["Heading1"]->reference << "\n";
+
+}
+
+void RTFGenerator::writeStyleInfo(int)
+{
+}
+
+void RTFGenerator::lineBreak(const char *)
+{
+  DBG_RTF(t << "{\\comment (lineBreak)}"    << endl)
+  t << "\\par" << endl;
+  m_omitParagraph = TRUE;
+}
+
+void RTFGenerator::writeString(const char *text)
+{
+  t << text;
+}
+
+void RTFGenerator::startIndexList()
+{
+  DBG_RTF(t << "{\\comment (startIndexList)}" << endl)
+  t << "{" << endl;
+  t << "\\par" << endl;
+  incrementIndentLevel();
+  t << rtf_Style_Reset << rtf_LCList_DepthStyle() << endl;
+  m_omitParagraph = TRUE;
+}
+
+void RTFGenerator::endIndexList()
+{
+  DBG_RTF(t << "{\\comment (endIndexList)}" << endl)
+  if (!m_omitParagraph)
+  {
+    t << "\\par";
+    m_omitParagraph = TRUE;
+  }
+  t << "}";
+  decrementIndentLevel();
+}
+
+/*! start bullet list */
+void RTFGenerator::startItemList()
+{
+  newParagraph();
+  DBG_RTF(t << "{\\comment (startItemList level=" << m_listLevel << ") }" << endl)
+  t << "{";
+  incrementIndentLevel();
+  rtf_listItemInfo[m_listLevel].isEnum = FALSE;
+}
+
+/*! end bullet list */
+void RTFGenerator::endItemList()
+{
+  newParagraph();
+  DBG_RTF(t << "{\\comment (endItemList level=" << m_listLevel << ")}" << endl)
+  t << "}";
+  decrementIndentLevel();
+  m_omitParagraph = TRUE;
+}
+
+///*! start enumeration list */
+//void RTFGenerator::startEnumList()  // starts an enumeration list
+//{
+//  DBG_RTF(t << "{\\comment (startEnumList)}" << endl)
+//  t << "{" << endl;
+//  incrementIndentLevel();
+//  rtf_listItemInfo[m_listLevel].isEnum = TRUE;
+//  rtf_listItemInfo[m_listLevel].number = 1;
+//}
+//
+///*! end enumeration list */
+//void RTFGenerator::endEnumList()
+//{
+//  newParagraph();
+//  DBG_RTF(t << "{\\comment (endEnumList)}" << endl)
+//  t << "}";
+//  decrementIndentLevel();
+//  m_omitParagraph = TRUE;
+//}
+
+/*! write bullet or enum item */
+void RTFGenerator::startItemListItem()
+{
+  DBG_RTF(t << "{\\comment (startItemListItem)}" << endl)
+  newParagraph();
+  t << rtf_Style_Reset;
+  if (rtf_listItemInfo[m_listLevel].isEnum)
+  {
+    t << rtf_EList_DepthStyle() << endl;
+    t << rtf_listItemInfo[m_listLevel].number << ".\\tab ";
+    rtf_listItemInfo[m_listLevel].number++;
+  }
+  else
+  {
+    t << rtf_BList_DepthStyle() << endl;
+  }
+  m_omitParagraph = TRUE;
+}
+
+void RTFGenerator::endItemListItem()
+{
+  DBG_RTF(t << "{\\comment (endItemListItem)}" << endl)
+}
+
+void RTFGenerator::startIndexItem(const char *,const char *)
+{
+  DBG_RTF(t << "{\\comment (startIndexItem)}" << endl)
+
+  if (!m_omitParagraph)
+  {
+    t << "\\par" << endl;
+    m_omitParagraph = TRUE;
+  }
+}
+
+void RTFGenerator::endIndexItem(const char *ref,const char *fn)
+{
+  DBG_RTF(t << "{\\comment (endIndexItem)}" << endl)
+  if (!ref && fn)
+  {
+    t << "\\tab ";
+    writeRTFReference(fn);
+    t << endl;
+  }
+  else
+  {
+    t << endl;
+  }
+  m_omitParagraph = TRUE;
+}
+
+//void RTFGenerator::writeIndexFileItem(const char *,const char *text)
+//{
+//  t << "\\item\\contentsline{section}{";
+//  docify(text);
+//  t << "}{\\pageref{" << text << "}}" << endl;
+//}
+
+void RTFGenerator::startHtmlLink(const char *url)
+{
+
+  if (Config_getBool("RTF_HYPERLINKS"))
+  {
+    t << "{\\field {\\*\\fldinst { HYPERLINK  \\\\l \"";
+    t << url;
+    t << "\" }{}";
+    t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
+  }
+  else
+  {
+    startTypewriter();
+  }
+}
+
+void RTFGenerator::endHtmlLink()
+{
+  if (Config_getBool("RTF_HYPERLINKS"))
+  {
+    t << "}}}" << endl;
+  }
+  else
+  {
+    endTypewriter();
+  }
+}
+
+//void RTFGenerator::writeMailLink(const char *url)
+//{
+//  startTypewriter();
+//  docify(url);
+//  endTypewriter();
+//}
+
+void RTFGenerator::writeStartAnnoItem(const char *,const char *f,
+    const char *path,const char *name)
+{
+  DBG_RTF(t << "{\\comment (writeStartAnnoItem)}" << endl)
+  t << "{\\b ";
+  if (path) docify(path);
+  if (f && Config_getBool("RTF_HYPERLINKS"))
+  {
+    t << "{\\field {\\*\\fldinst { HYPERLINK  \\\\l \"";
+    t << rtfFormatBmkStr(f);
+    t << "\" }{}";
+    t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
+
+    docify(name);
+
+    t << "}}}" << endl;
+  }
+  else
+  {
+    docify(name);
+  }
+  t << "} ";
+}
+
+void RTFGenerator::writeEndAnnoItem(const char *name)
+{
+  DBG_RTF(t << "{\\comment (writeEndAnnoItem)}" << endl)
+  if (name)
+  {
+    t << "\\tab ";
+    writeRTFReference(name);
+    t << endl;
+  }
+  else
+  {
+    t << endl;
+  }
+  newParagraph();
+}
+
+void RTFGenerator::startIndexKey()
+{
+  DBG_RTF(t << "{\\comment (startIndexKey)}" << endl)
+  t << "{\\b ";
+}
+
+void RTFGenerator::endIndexKey()
+{
+  DBG_RTF(t << "{\\comment (endIndexKey)}" << endl)
+}
+
+void RTFGenerator::startIndexValue(bool hasBrief)
+{
+  DBG_RTF(t << "{\\comment (startIndexValue)}" << endl)
+  t << " ";
+  if (hasBrief) t << "(";
+}
+
+void RTFGenerator::endIndexValue(const char *name,bool hasBrief)
+{
+  DBG_RTF(t << "{\\comment (endIndexValue)}" << endl)
+  if (hasBrief) t << ")";
+  t << "} ";
+  if (name)
+  {
+    t << "\\tab ";
+    writeRTFReference(name);
+    t << endl;
+  }
+  else
+  {
+    t << endl;
+  }
+  m_omitParagraph=FALSE;
+  newParagraph();
+}
+
+void RTFGenerator::startSubsection()
+{
+  //beginRTFSubSection();
+  t <<"\n";
+  DBG_RTF(t << "{\\comment Begin SubSection}\n")
+  t << rtf_Style_Reset;
+  t << rtf_Style["Heading3"]->reference << "\n";
+}
+
+void RTFGenerator::endSubsection()
+{
+  newParagraph();
+  t << rtf_Style_Reset << endl;
+}
+
+void RTFGenerator::startSubsubsection()
+{
+  //beginRTFSubSubSection();
+  t << "\n";
+  DBG_RTF(t << "{\\comment Begin SubSubSection}\n")
+  t << "{" << endl;
+  t << rtf_Style_Reset << rtf_Style["Heading4"]->reference << "\n";
+}
+
+void RTFGenerator::endSubsubsection()
+{
+  newParagraph();
+  t << "}" << endl;
+}
+
+
+//void RTFGenerator::writeClassLink(const char *,const char *,
+//                                    const char *,const char *name)
+//{
+//  t << "{\\bf ";
+//  docify(name);
+//  t << "}";
+//}
+
+//void RTFGenerator::startTable(bool,int colNumbers) 
+//{
+//  DBG_RTF(t << "{\\comment startTable}\n";)
+//  m_numCols=colNumbers;
+//  t << "\\par\n";
+//}
+//
+//void RTFGenerator::endTable(bool hasCaption) 
+//{ 
+//  DBG_RTF(t << "{\\comment endTable}\n";)
+//  if (!hasCaption) 
+//    t << "\n\\pard \\widctlpar\\intbl\\adjustright\n{\\row }\n"; 
+//  t << "\\pard\n" << endl; 
+//}
+//
+//void  RTFGenerator::startCaption() 
+//{
+//  DBG_RTF(t << "{\\comment startCaption}\n";)
+//  endTableRow();
+//  t << "\\trowd \\trgaph108\\trleft-108\\trbrdrt\\brdrs\\brdrw10 \\trbrdrl\\brdrs\\brdrw10 \\trbrdrb\\brdrs\\brdrw10 \\trbrdrr\\brdrs\\brdrw10 \\trbrdrh\\brdrs\\brdrw10 \\trbrdrv\\brdrs\\brdrw10" << endl;
+//  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;
+//  nextTableColumn();
+//}
+//
+//void  RTFGenerator::endCaption() 
+//{
+//  DBG_RTF(t << "{\\comment endCaption}\n";)
+//  endTableColumn();
+//  endTableRow();
+//}
+//
+//void RTFGenerator::nextTableRow() 
+//{  
+//  DBG_RTF(t << "{\\comment nextTableRow}\n";)
+//  ASSERT(m_numCols>0 && m_numCols<25);
+//  uint columnWidth=rtf_pageWidth/m_numCols;
+//  t << "\\trowd \\trgaph108\\trleft-108\\trbrdrt\\brdrs\\brdrw10 "
+//       "\\trbrdrl\\brdrs\\brdrw10 \\trbrdrb\\brdrs\\brdrw10 "
+//       "\\trbrdrr\\brdrs\\brdrw10 \\trbrdrh\\brdrs\\brdrw10 "
+//       "\\trbrdrv\\brdrs\\brdrw10 "<<endl;
+//  for (int i=0;i<m_numCols;i++) 
+//  {
+//    t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10 \\clbrdrl\\brdrs\\brdrw10 "
+//         "\\clbrdrb\\brdrs\\brdrw10 \\clbrdrr \\brdrs\\brdrw10 \\cltxlrtb "
+//         "\\cellx" << (i*columnWidth) << endl;
+//  }
+//  t << "\\pard \\widctlpar\\intbl\\adjustright\n{";
+//}
+// 
+//void RTFGenerator::endTableRow() 
+//{ 
+//  DBG_RTF(t << "{\\comment endTableRow}\n";)
+//  t << "\n\\pard \\widctlpar\\intbl\\adjustright\n{\\row }\n";
+//}
+// 
+//void RTFGenerator::nextTableColumn() 
+//{
+//  DBG_RTF(t << "{\\comment nextTableColumn}\n";)
+//  t << "{ ";
+//}
+//
+//void RTFGenerator::endTableColumn() 
+//{ 
+//  DBG_RTF(t << "{\\comment endTableColumn}\n";)
+//  t << " \\cell }";
+//}
+//
+void RTFGenerator::startTextLink(const char *f,const char *anchor)
+{
+  if (Config_getBool("RTF_HYPERLINKS"))
+  {
+    QCString ref;
+    if (f)
+    {
+      ref+=f;
+    }
+    if (anchor)
+    {
+      ref+='_';
+      ref+=anchor;
+    }
+
+    t << "{\\field {\\*\\fldinst { HYPERLINK  \\\\l \"";
+    t << rtfFormatBmkStr(ref);
+    t << "\" }{}";
+    t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
+  }
+}
+
+void RTFGenerator::endTextLink()
+{
+  if (Config_getBool("RTF_HYPERLINKS"))
+  {
+    t << "}}}" << endl;
+  }
+}
+
+void RTFGenerator::writeObjectLink(const char *ref, const char *f,
+    const char *anchor, const char *text)
+{
+  if (!ref && Config_getBool("RTF_HYPERLINKS"))
+  {
+    QCString refName;
+    if (f)
+    {
+      refName+=f;
+    }
+    if (anchor)
+    {
+      refName+='_';
+      refName+=anchor;
+    }
+
+    t << "{\\field {\\*\\fldinst { HYPERLINK  \\\\l \"";
+    t << rtfFormatBmkStr(refName);
+    t << "\" }{}";
+    t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
+
+    docify(text);
+
+    t << "}}}" << endl;
+  }
+  else
+  {
+    startBold();
+    docify(text);
+    endBold();
+  }
+}
+
+void RTFGenerator::startPageRef()
+{
+  t << " (";
+  startEmphasis();
+}
+
+void RTFGenerator::endPageRef(const char *clname, const char *anchor)
+{
+  QCString ref;
+  if (clname)
+  {
+    ref+=clname;
+  }
+  if (anchor)
+  {
+    ref+='_';
+    ref+=anchor;
+  }
+  writeRTFReference(ref);
+  endEmphasis();
+  t << ")";
+}
+
+void RTFGenerator::writeCodeLink(const char *ref,const char *f,
+                                 const char *anchor,const char *name,
+                                 const char *)
+{
+  if (!ref && Config_getBool("RTF_HYPERLINKS"))
+  {
+    QCString refName;
+    if (f)
+    {
+      refName+=f;
+    }
+    if (anchor)
+    {
+      refName+='_';
+      refName+=anchor;
+    }
+
+    t << "{\\field {\\*\\fldinst { HYPERLINK  \\\\l \"";
+    t << rtfFormatBmkStr(refName);
+    t << "\" }{}";
+    t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
+
+    codify(name);
+
+    t << "}}}" << endl;
+  }
+  else
+  {
+    codify(name);
+  }
+}
+
+void RTFGenerator::startTitleHead(const char *)
+{
+  DBG_RTF(t <<"{\\comment startTitleHead}" << endl)
+
+  //    beginRTFSection();
+  t << rtf_Style_Reset << rtf_Style["Heading2"]->reference << endl;
+}
+
+void RTFGenerator::endTitleHead(const char *fileName,const char *name)
+{
+  DBG_RTF(t <<"{\\comment endTitleHead}" << endl)
+  t << "\\par " << rtf_Style_Reset << endl;
+  if (name)
+  {
+    // make table of contents entry
+    t << "{\\tc\\tcl2 \\v ";
+    docify(name);
+    t << "}" << endl;
+
+    // make an index entry
+    addIndexItem(name,0);
+
+    //if (name)
+    //{
+    //  writeAnchor(0,name);
+    //}
+    //
+    //if (Config_getBool("RTF_HYPERLINKS") && fileName)
+    //{
+      writeAnchor(fileName,0);
+    //}
+  }
+}
+
+void RTFGenerator::startTitle()
+{
+  DBG_RTF(t <<"{\\comment startTitle}" << endl)
+  if (Config_getBool("COMPACT_RTF"))
+    beginRTFSection();
+  else
+    beginRTFChapter();
+}
+
+void RTFGenerator::startGroupHeader()
+{
+  DBG_RTF(t <<"{\\comment startGroupHeader}" << endl)
+  //newParagraph();
+  t << rtf_Style_Reset;
+  t << rtf_Style["Heading3"]->reference;
+  t << endl;
+}
+
+void RTFGenerator::endGroupHeader()
+{
+  DBG_RTF(t <<"{\\comment endGroupHeader}" << endl)
+  t << "\\par" << endl;
+  t << rtf_Style_Reset << endl;
+}
+
+void RTFGenerator::startMemberDoc(const char *clname,
+    const char *memname,
+    const char *,
+    const char *)
+{
+  DBG_RTF(t << "{\\comment startMemberDoc}" << endl)
+  if (memname && memname[0]!='@')
+  {
+    addIndexItem(memname,clname);
+    addIndexItem(clname,memname);
+  }
+  t << rtf_Style_Reset << rtf_Style["Heading4"]->reference;
+  //styleStack.push(rtf_Style_Heading4);
+  t << "{" << endl;
+  //printf("RTFGenerator::startMemberDoc() `%s'\n",rtf_Style["Heading4"]->reference);
+  startBold();
+  t << endl;
+}
+
+void RTFGenerator::endMemberDoc(bool)
+{
+  DBG_RTF(t << "{\\comment endMemberDoc}" << endl)
+  t << "}" << endl;
+  //const char *style = styleStack.pop();
+  //printf("RTFGenerator::endMemberDoc() `%s'\n",style);
+  //ASSERT(style==rtf_Style["Heading4"]->reference);
+  endBold();
+  newParagraph();
+}
+
+void RTFGenerator::startDoxyAnchor(const char *,const char *,
+                                   const char *,const char *,
+                                   const char *
+                                  )
+{
+  DBG_RTF(t << "{\\comment startDoxyAnchor}" << endl)
+}
+
+void RTFGenerator::endDoxyAnchor(const char *fName,const char *anchor)
+{
+  QCString ref;
+  if (fName)
+  {
+    ref+=fName;
+  }
+  if (anchor)
+  {
+    ref+='_';
+    ref+=anchor;
+  }
+
+  DBG_RTF(t << "{\\comment endDoxyAnchor}" << endl)
+  t << "{\\bkmkstart ";
+  t << rtfFormatBmkStr(ref);
+  t << "}" << endl;
+  t << "{\\bkmkend ";
+  t << rtfFormatBmkStr(ref);
+  t << "}" << endl;
+}
+
+
+//void RTFGenerator::writeLatexLabel(const char *clName,const char *anchor)
+//{
+//  writeDoxyAnchor(0,clName,anchor,0);
+//}
+
+void RTFGenerator::addIndexItem(const char *s1,const char *s2)
+{
+  if (s1)
+  {
+    t << "{\\xe \\v ";
+    docify(s1);
+    if (s2)
+    {
+      t << "\\:";
+      docify(s2);
+    }
+    t << "}" << endl;
+  }
+}
+
+void RTFGenerator::startIndent()
+{
+  incrementIndentLevel();
+  DBG_RTF(t << "{\\comment (startIndent) }" << endl)
+  t << "{" << endl;
+  t << rtf_Style_Reset << rtf_CList_DepthStyle() << endl;
+}
+
+void RTFGenerator::endIndent()
+{
+  t << "}" << endl;
+  decrementIndentLevel();
+}
+
+
+void RTFGenerator::startDescription()
+{
+  DBG_RTF(t << "{\\comment (startDescription)}"    << endl)
+  t << "{" << endl;
+  t << rtf_Style_Reset << rtf_DList_DepthStyle();
+}
+
+void RTFGenerator::endDescription()
+{
+  DBG_RTF(t << "{\\comment (endDescription)}"    << endl)
+  newParagraph();
+  t << "}";
+}
+
+void RTFGenerator::startDescItem()
+{
+  newParagraph();
+  DBG_RTF(t << "{\\comment (startDescItem)}"    << endl)
+  t << "{\\b ";
+}
+
+void RTFGenerator::endDescItem()
+{
+  DBG_RTF(t << "{\\comment (endDescItem)}"    << endl)
+  t << "}" << endl;
+  newParagraph();
+}
+
+void RTFGenerator::startMemberDescription()
+{
+  DBG_RTF(t << "{\\comment (startMemberDescription)}"    << endl)
+  t << "{" << endl;
+  incrementIndentLevel();
+  t << rtf_Style_Reset << rtf_CList_DepthStyle();
+  startEmphasis();
+}
+
+void RTFGenerator::endMemberDescription()
+{
+  DBG_RTF(t << "{\\comment (endMemberDescription)}"    << endl)
+  endEmphasis();
+  newParagraph();
+  decrementIndentLevel();
+  //t << "\\par";
+  t << "}" << endl;
+  //m_omitParagraph = TRUE;
+}
+
+void RTFGenerator::startDescList(SectionTypes)
+{
+  DBG_RTF(t << "{\\comment (startDescList)}"    << endl)
+  t << "{"; // ends at endDescList
+  t << "{"; // ends at endDescTitle
+  startBold();
+  newParagraph();
+}
+
+//void RTFGenerator::endDescTitle()
+//{
+//  DBG_RTF(t << "{\\comment (endDescTitle) }"    << endl)
+//  endBold();
+//  t << "}";
+//  newParagraph();
+//  incrementIndentLevel();
+//  t << rtf_Style_Reset << rtf_DList_DepthStyle();
+//}
+
+void RTFGenerator::startDescForItem()
+{
+  DBG_RTF(t << "{\\comment (startDescForItem) }"    << endl)
+}
+
+void RTFGenerator::endDescForItem()
+{
+  DBG_RTF(t << "{\\comment (endDescForItem) }"    << endl)
+}
+
+//void RTFGenerator::endDescList()
+//{
+//  DBG_RTF(t << "{\\comment (endDescList)}"    << endl)
+//  newParagraph();
+//  decrementIndentLevel();
+//  m_omitParagraph = TRUE;
+//  t << "}";
+//}
+
+
+void RTFGenerator::startSection(const char *,const char *title,SectionInfo::SectionType type)
+{
+  DBG_RTF(t << "{\\comment (startSection)}"    << endl)
+  t << "{";
+  t<< rtf_Style_Reset;
+  int num=4;
+  switch(type)
+  {
+    case SectionInfo::Page:          num=2; break;
+    case SectionInfo::Section:       num=3; break;
+    case SectionInfo::Subsection:    num=4; break;
+    case SectionInfo::Subsubsection: num=4; break;
+    case SectionInfo::Paragraph:     num=4; break;
+    default: ASSERT(0); break;
+  }
+  QCString heading;
+  heading.sprintf("Heading%d",num);
+  // set style
+  t << rtf_Style[heading]->reference;
+  // make table of contents entry
+  t << "{\\tc\\tcl" << num << " \\v ";
+  docify(title);
+  t << "}" << endl;
+}
+
+void RTFGenerator::endSection(const char *lab,SectionInfo::SectionType)
+{
+  DBG_RTF(t << "{\\comment (endSection)}"    << endl)
+  // make bookmark
+  m_omitParagraph=FALSE;
+  newParagraph();
+  writeAnchor(0,lab);
+  t << "}";
+}
+
+//void RTFGenerator::writeSectionRef(const char *ref,const char *,
+//                                   const char *lab,const char *title)
+//{
+//  if (ref)
+//  {
+//    docify(title);
+//  }
+//  else
+//  {
+//    startBold();
+//    docify(title);
+//    endBold();
+//    t << " (";
+//    docify(theTranslator->trPageAbbreviation());
+//    writeRTFReference(lab);
+//    t << ")" << endl;
+//  }
+//}
+//
+//void RTFGenerator::writeSectionRefItem(const char *,const char *lab,
+//    const char *title)
+//{
+//  docify(title);
+//  t << "\\tab";
+//  writeRTFReference(lab);
+//  t << endl;
+//}
+//
+//void RTFGenerator::writeSectionRefAnchor(const char *name,const char *lab,
+//    const char *title)
+//{
+//  writeSectionRef(name,lab,title);
+//}
+
+//char* RTFGenerator::getMultiByte(int c)
+//{
+//    static char s[10];
+//
+//    sprintf(s,"\\'%X",c);
+//    return s;
+//}
+
+void RTFGenerator::docify(const char *str)
+{
+  if (str)
+  {
+    const unsigned char *p=(const unsigned char *)str;
+    unsigned char c;
+    unsigned char pc='\0';
+    while (*p)
+    {
+      //static bool MultiByte = FALSE;
+      c=*p++;
+
+#if 0
+      if ( MultiByte )
+      {
+        t << getMultiByte( c );
+        MultiByte = FALSE;
+        continue;
+      }
+      if ( c >= 0x80 )
+      {
+        MultiByte = TRUE;
+        t << getMultiByte( c );
+        continue;
+      }
+#endif
+
+      switch (c)
+      {
+        case '{':  t << "\\{";            break;
+        case '}':  t << "\\}";            break;
+        case '\\': t << "\\\\";           break;
+        default:
+          {
+            // see if we can insert an hyphenation hint
+            //if (isupper(c) && islower(pc) && !insideTabbing) t << "\\-";
+            t << (char)c;
+          }
+      }
+      pc = c;
+      m_omitParagraph = FALSE;
+    }
+  }
+}
+
+void RTFGenerator::codify(const char *str)
+{
+  // note that RTF does not have a "verbatim", so "\n" means
+  // nothing... add a "newParagraph()";
+  //static char spaces[]="        ";
+  if (str)
+  {
+    const unsigned char *p=(const unsigned char *)str;
+    unsigned char c;
+    int spacesToNextTabStop;
+
+    while (*p)
+    {
+      //static bool MultiByte = FALSE;
+
+      c=*p++;
+
+#if 0
+      if( MultiByte )
+      {
+        t << getMultiByte( c );
+        MultiByte = FALSE;
+        continue;
+      }
+      if( c >= 0x80 )
+      {
+        MultiByte = TRUE;
+        t << getMultiByte( c );
+        continue;
+      }
+#endif
+
+      switch(c)
+      {
+        case '\t':  spacesToNextTabStop = Config_getInt("TAB_SIZE") - (col%Config_getInt("TAB_SIZE"));
+                    t << Doxygen::spaces.left(spacesToNextTabStop);
+                    col+=spacesToNextTabStop;
+                    break;
+        case '\n':  newParagraph();
+                    t << '\n'; col=0;
+                    break;
+        case '{':   t << "\\{"; col++;          break;
+        case '}':   t << "\\}"; col++;          break;
+        case '\\':  t << "\\\\"; col++;         break;
+        default:    t << (char)c; col++;           break;
+      }
+    }
+  }
+}
+
+void RTFGenerator::writeChar(char c)
+{
+  char cs[2];
+  cs[0]=c;
+  cs[1]=0;
+  docify(cs);
+}
+
+void RTFGenerator::startClassDiagram()
+{
+  DBG_RTF(t <<"{\\comment startClassDiagram }" << endl)
+}
+
+void RTFGenerator::endClassDiagram(const ClassDiagram &d,
+    const char *fileName,const char *)
+{
+  newParagraph();
+
+  // create a png file
+  d.writeImage(t,dir,relPath,fileName,FALSE);
+
+  // display the file
+  t << "{" << endl;
+  t << rtf_Style_Reset << endl;
+  t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
+  t << fileName << ".png\"";
+  t << " \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
+  t << "}" << endl;
+}
+
+//void RTFGenerator::writeFormula(const char *,const char *text)
+//{
+//  t << text;
+//}
+
+void RTFGenerator::startMemberItem(int)
+{
+  DBG_RTF(t <<"{\\comment startMemberItem }" << endl)
+  t << rtf_Style_Reset << rtf_BList_DepthStyle() << endl; // set style to apropriate depth
+}
+
+void RTFGenerator::endMemberItem()
+{
+  DBG_RTF(t <<"{\\comment endMemberItem }" << endl)
+  newParagraph();
+}
+
+void RTFGenerator::writeAnchor(const char *fileName,const char *name)
+{
+  QCString anchor;
+  if (fileName)
+  {
+    anchor+=fileName;
+  }
+  if (fileName && name)
+  {
+    anchor+='_';
+  }
+  if (name)
+  {
+    anchor+=name;
+  }
+
+  DBG_RTF(t <<"{\\comment writeAnchor (" << anchor << ")}" << endl)
+  t << "{\\bkmkstart " << rtfFormatBmkStr(anchor) << "}" << endl;
+  t << "{\\bkmkend " << rtfFormatBmkStr(anchor) << "}" << endl;
+}
+
+void RTFGenerator::writeRTFReference(const char *label)
+{
+  t << "{\\field\\fldedit {\\*\\fldinst PAGEREF ";
+  t << rtfFormatBmkStr(label);
+  t << " \\\\*MERGEFORMAT}{\\fldrslt pagenum}}";
+}
+
+void RTFGenerator::startCodeFragment()
+{
+  DBG_RTF(t << "{\\comment (startCodeFragment) }"    << endl)
+  t << "{" << endl;
+  //newParagraph();
+  t << rtf_Style_Reset << rtf_Code_DepthStyle();
+  //styleStack.push(rtf_Style_CodeExample);
+}
+
+void RTFGenerator::endCodeFragment()
+{
+  //newParagraph();
+  //styleStack.pop();
+  //printf("RTFGenerator::endCodeFrament() top=%s\n",styleStack.top());
+  //t << rtf_Style_Reset << styleStack.top() << endl;
+  DBG_RTF(t << "{\\comment (endCodeFragment) }"    << endl)
+  t << "}" << endl;
+  m_omitParagraph = TRUE;
+}
+
+void RTFGenerator::writeNonBreakableSpace(int)
+{
+  t << "\\~ ";
+}
+
+
+void RTFGenerator::startMemberList()
+{
+  t << endl;
+  DBG_RTF(t << "{\\comment (startMemberList) }"    << endl)
+  t << "{" << endl;
+#ifdef DELETEDCODE
+  if (!insideTabbing)
+    t << "\\begin{CompactItemize}" << endl;
+#endif
+}
+
+void RTFGenerator::endMemberList()
+{
+  DBG_RTF(t << "{\\comment (endMemberList) }"    << endl)
+  t << "}" << endl;
+#ifdef DELETEDCODE
+  if (!insideTabbing)
+    t << "\\end{CompactItemize}"   << endl;
+#endif
+}
+
+//void RTFGenerator::startImage(const char *name,const char *,bool)
+//{
+//  newParagraph();
+//  t << "{" << endl;
+//  t << rtf_Style_Reset << endl;
+//  t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE ";
+//  t << name;
+//  t << " \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
+//  t << "}" << endl;
+//}
+//
+//void RTFGenerator::endImage(bool)
+//{
+//  // not yet implemented
+//}
+//
+//void RTFGenerator::startDotFile(const char *name,bool)
+//{
+//  QCString baseName=name;
+//  int i;
+//  if ((i=baseName.findRev('/'))!=-1 || (i=baseName.findRev('\\'))!=-1)
+//  {
+//    baseName=baseName.right(baseName.length()-i-1);
+//  }
+//  QCString outDir = Config_getString("RTF_OUTPUT");
+//  writeDotGraphFromFile(name,outDir,baseName,BITMAP);
+//  newParagraph();
+//  t << "{" << endl;
+//  t << rtf_Style_Reset << endl;
+//  t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE ";
+//  t << outDir << "\\" << baseName;
+//  t << " \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
+//  t << "}" << endl;
+//}
+//
+//void RTFGenerator::endDotFile(bool)
+//{
+//  // not yet implemented
+//}
+//
+void RTFGenerator::startDescTable()
+{
+  DBG_RTF(t << "{\\comment (startDescTable) }"    << endl)
+  //t << "{" << endl;
+  //incrementIndentLevel();
+  //t << rtf_Style_Reset << rtf_CList_DepthStyle();
+}
+
+void RTFGenerator::endDescTable()
+{
+  //decrementIndentLevel();
+  DBG_RTF(t << "{\\comment (endDescTable)}"      << endl)
+  //t << "}" << endl;
+  //t << rtf_Style_Reset << styleStack.top();
+}
+
+void RTFGenerator::startDescTableTitle()
+{
+  //t << rtf_BList_DepthStyle() << endl;
+  DBG_RTF(t << "{\\comment (startDescTableTitle) }"    << endl)
+  startBold();
+  startEmphasis();
+}
+
+void RTFGenerator::endDescTableTitle()
+{
+  DBG_RTF(t << "{\\comment (endDescTableTitle) }"    << endl)
+  endEmphasis();
+  endBold();
+  t << "  ";
+}
+
+void RTFGenerator::startDescTableData()
+{
+  DBG_RTF(t << "{\\comment (startDescTableData) }"    << endl)
+  m_omitParagraph = FALSE;
+}
+
+void RTFGenerator::endDescTableData()
+{
+  DBG_RTF(t << "{\\comment (endDescTableData) }"    << endl)
+  newParagraph();
+  m_omitParagraph = TRUE;
+}
+
+// a style for list formatted as a "bulleted list"
+
+void RTFGenerator::incrementIndentLevel()
+{
+  m_listLevel++;
+  if (m_listLevel>rtf_maxIndentLevels-1)
+  {
+    warn_cont("Warning: Maximum indent level (%d) exceeded while generating RTF output!\n",rtf_maxIndentLevels);
+    m_listLevel=rtf_maxIndentLevels-1;
+  }
+}
+
+void RTFGenerator::decrementIndentLevel()
+{
+  m_listLevel--;
+  if (m_listLevel<0)
+  {
+    warn_cont("Warning: Negative indent level while generating RTF output!\n");
+    m_listLevel=0;
+  }
+}
+
+// a style for list formatted with "list continue" style
+const char * RTFGenerator::rtf_CList_DepthStyle()
+{
+  QCString n=makeIndexName("ListContinue",m_listLevel);
+  return rtf_Style[n]->reference;
+}
+
+// a style for list formatted as a "latext style" table of contents
+const char * RTFGenerator::rtf_LCList_DepthStyle()
+{
+  QCString n=makeIndexName("LatexTOC",m_listLevel);
+  return rtf_Style[n]->reference;
+}
+
+// a style for list formatted as a "bullet" style
+const char * RTFGenerator::rtf_BList_DepthStyle()
+{
+  QCString n=makeIndexName("ListBullet",m_listLevel);
+  return rtf_Style[n]->reference;
+}
+
+// a style for list formatted as a "enumeration" style
+const char * RTFGenerator::rtf_EList_DepthStyle()
+{
+  QCString n=makeIndexName("ListEnum",m_listLevel);
+  return rtf_Style[n]->reference;
+}
+
+const char * RTFGenerator::rtf_DList_DepthStyle()
+{
+  QCString n=makeIndexName("DescContinue",m_listLevel);
+  return rtf_Style[n]->reference;
+}
+
+const char * RTFGenerator::rtf_Code_DepthStyle()
+{
+  QCString n=makeIndexName("CodeExample",m_listLevel);
+  return rtf_Style[n]->reference;
+}
+
+void RTFGenerator::startTextBlock(bool dense)
+{
+  DBG_RTF(t << "{\\comment startTextBlock}" << endl)
+  t << "{" << endl;
+  t << rtf_Style_Reset;
+  if (dense) // no spacing between "paragraphs"
+  {
+    t << rtf_Style["DenseText"]->reference;
+  }
+  else // some spacing
+  {
+    t << rtf_Style["BodyText"]->reference;
+  }
+}
+
+void RTFGenerator::endTextBlock(bool /*paraBreak*/)
+{
+  newParagraph();
+  DBG_RTF(t << "{\\comment endTextBlock}" << endl)
+  t << "}" << endl;
+  //m_omitParagraph = TRUE;
+}
+
+void RTFGenerator::newParagraph()
+{
+  if (!m_omitParagraph)
+  {
+    DBG_RTF(t << "{\\comment (newParagraph)}"    << endl)
+    t << "\\par" << endl;
+  }
+  m_omitParagraph = FALSE;
+}
+
+void RTFGenerator::startParagraph()
+{
+  DBG_RTF(t << "{\\comment startParagraph}" << endl)
+  newParagraph();
+  t << "{" << endl;
+}
+
+void RTFGenerator::endParagraph()
+{
+  DBG_RTF(t << "{\\comment endParagraph}" << endl)
+  t << "}\\par" << endl;
+  m_omitParagraph = TRUE;
+}
+
+void RTFGenerator::startMemberSubtitle()
+{
+  DBG_RTF(t << "{\\comment startMemberSubtitle}" << endl)
+  t << "{" << endl;
+  t << rtf_Style_Reset << rtf_CList_DepthStyle() << endl;
+}
+
+void RTFGenerator::endMemberSubtitle()
+{
+  DBG_RTF(t << "{\\comment endMemberSubtitle}" << endl)
+  newParagraph();
+  t << "}" << endl;
+}
+
+//void RTFGenerator::writeUmlaut(char c)
+//{
+//  switch(c)
+//  {
+//    case 'A' : t << '\304'; break;
+//    case 'E' : t << '\313'; break;
+//    case 'I' : t << '\317'; break;
+//    case 'O' : t << '\326'; break;
+//    case 'U' : t << '\334'; break;
+//    case 'Y' : t << 'Y';    break;
+//    case 'a' : t << '\344'; break;
+//    case 'e' : t << '\353'; break;
+//    case 'i' : t << '\357'; break;
+//    case 'o' : t << '\366'; break;
+//    case 'u' : t << '\374'; break;
+//    case 'y' : t << '\377'; break;
+//    default: t << '?'; break;
+//  }
+//}
+//
+//void RTFGenerator::writeAcute(char c)
+//{
+//  switch(c)
+//  {
+//    case 'A' : t << '\301'; break;
+//    case 'E' : t << '\311'; break;
+//    case 'I' : t << '\315'; break;
+//    case 'O' : t << '\323'; break;
+//    case 'U' : t << '\332'; break;
+//    case 'Y' : t << '\335'; break;
+//    case 'a' : t << '\341'; break;
+//    case 'e' : t << '\351'; break;
+//    case 'i' : t << '\355'; break;
+//    case 'o' : t << '\363'; break;
+//    case 'u' : t << '\372'; break;
+//    case 'y' : t << '\375'; break;
+//    default: t << '?'; break;
+//  }
+//}
+//
+//void RTFGenerator::writeGrave(char c)
+//{
+//  switch(c)
+//  {
+//    case 'A' : t << '\300'; break;
+//    case 'E' : t << '\310'; break;
+//    case 'I' : t << '\314'; break;
+//    case 'O' : t << '\322'; break;
+//    case 'U' : t << '\331'; break;
+//    case 'a' : t << '\340'; break;
+//    case 'e' : t << '\350'; break;
+//    case 'i' : t << '\354'; break;
+//    case 'o' : t << '\362'; break;
+//    case 'u' : t << '\371'; break;
+//    default: t << '?'; break;
+//  }
+//}
+//
+//void RTFGenerator::writeCirc(char c)
+//{
+//  switch(c)
+//  {
+//    case 'A' : t << '\302'; break;
+//    case 'E' : t << '\312'; break;
+//    case 'I' : t << '\316'; break;
+//    case 'O' : t << '\324'; break;
+//    case 'U' : t << '\333'; break;
+//    case 'a' : t << '\342'; break;
+//    case 'e' : t << '\352'; break;
+//    case 'i' : t << '\356'; break;
+//    case 'o' : t << '\364'; break;
+//    case 'u' : t << '\373'; break;
+//    default: t << '?'; break;
+//  }
+//}
+//
+//void RTFGenerator::writeTilde(char c)
+//{
+//  switch(c)
+//  {
+//    case 'A' : t << '\303'; break;
+//    case 'N' : t << '\321'; break;
+//    case 'O' : t << '\325'; break;
+//    case 'a' : t << '\343'; break;
+//    case 'n' : t << '\361'; break;
+//    case 'o' : t << '\365'; break;
+//    default: t << '?'; break;
+//  }
+//}
+//
+//void RTFGenerator::writeRing(char c)
+//{
+//  switch(c)
+//  {
+//    case 'A' : t << '\305'; break;
+//    case 'a' : t << '\345'; break;
+//    default: t << '?'; break;
+//  }
+//}
+//
+//void RTFGenerator::writeCCedil(char c)
+//{
+//  switch(c)
+//  {
+//    case 'C' : t << '\307'; break;
+//    case 'c' : t << '\347'; break;
+//    default: t << '?'; break;
+//  }
+//}
+//
+/**
+ * VERY brittle routine inline RTF's included by other RTF's.
+ * it is recursive and ugly.
+ */
+static bool PreProcessFile(QDir &d,QCString &infName, QTextStream &t, bool bIncludeHeader=TRUE)
+{
+  QFile f(infName);
+  if (!f.open(IO_ReadOnly))
+  {
+    err("Error opening rtf file %s for reading\n",infName.data());
+    return FALSE;
+  }
+
+  const int maxLineLength = 10240;
+  static QCString lineBuf(maxLineLength);
+
+  // scan until find end of header
+  // this is EXTREEEEEEEMLY brittle.  It works on OUR rtf
+  // files because the first line before the body
+  // ALWAYS contains "{\comment begin body}"
+  do
+  {
+    if (f.readLine(lineBuf.data(),maxLineLength)==-1)
+    {
+      err("ERROR - read error in %s before end of RTF header!\n",infName.data());
+      return FALSE;
+    }
+    if (bIncludeHeader) t << lineBuf;
+  } while (lineBuf.find("\\comment begin body")==-1);
+
+
+  //while (fgets(buffer,sizeof(buffer),infp) != NULL)
+  while (f.readLine(lineBuf.data(),maxLineLength)!=-1)
+  {
+    int pos;
+    if ((pos=lineBuf.find("INCLUDETEXT"))!=-1)
+    {
+      int startNamePos  = lineBuf.find('"',pos)+1;
+      int endNamePos    = lineBuf.find('"',startNamePos);
+      QCString fileName = lineBuf.mid(startNamePos,endNamePos-startNamePos);
+      DBG_RTF(t << "{\\comment begin include " << fileName << "}" << endl)
+      if (!PreProcessFile(d,fileName,t,FALSE)) return FALSE;
+      DBG_RTF(t << "{\\comment end include " << fileName << "}" << endl)
+    }
+    else
+    {
+      // elaborate hoopla to skip  the final "}" if we didn't include the
+      // headers
+      if (!f.atEnd() || bIncludeHeader)
+      {
+        t << lineBuf;
+      }
+      else
+      {
+        // null terminate at the last '}'
+        //char *str = strrchr(buffer,'}');
+        int pos = lineBuf.findRev('}');
+
+        if (pos != -1)
+          lineBuf.at(pos) = '\0';
+        else
+          err("Strange, the last char was not a '}'\n");
+        t << lineBuf;
+      }
+    }
+  }
+  f.close();
+  // remove temporary file
+  d.remove(infName);
+  return TRUE;
+}
+
+void RTFGenerator::startDotGraph()
+{
+  DBG_RTF(t << "{\\comment (startDotGraph)}"    << endl)
+}
+
+void RTFGenerator::endDotGraph(const DotClassGraph &g)
+{
+  newParagraph();
+
+  QCString fileName =
+    g.writeGraph(t,BITMAP,Config_getString("RTF_OUTPUT"),relPath,TRUE,FALSE);
+
+  // display the file
+  t << "{" << endl;
+  t << rtf_Style_Reset << endl;
+  t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
+  t << fileName << "." << Config_getEnum("DOT_IMAGE_FORMAT");
+  t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
+  t << "}" << endl;
+  newParagraph();
+  DBG_RTF(t << "{\\comment (endDotGraph)}"    << endl)
+}
+
+void RTFGenerator::startInclDepGraph()
+{
+  DBG_RTF(t << "{\\comment (startInclDepGraph)}"    << endl)
+}
+
+void RTFGenerator::endInclDepGraph(const DotInclDepGraph &g)
+{
+  newParagraph();
+
+  QCString fileName = g.writeGraph(t,BITMAP,Config_getString("RTF_OUTPUT"),
+                         relPath,FALSE);
+
+  // display the file
+  t << "{" << endl;
+  t << rtf_Style_Reset << endl;
+  t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
+  t << fileName << "." << Config_getEnum("DOT_IMAGE_FORMAT");
+  t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
+  t << "}" << endl;
+  DBG_RTF(t << "{\\comment (endInclDepGraph)}"    << endl)
+}
+
+void RTFGenerator::startGroupCollaboration()
+{
+}
+
+void RTFGenerator::endGroupCollaboration(const DotGroupCollaboration &)
+{
+}
+
+void RTFGenerator::startCallGraph()
+{
+  DBG_RTF(t << "{\\comment (startCallGraph)}"    << endl)
+}
+
+void RTFGenerator::endCallGraph(const DotCallGraph &g)
+{
+  newParagraph();
+
+  QCString fileName = g.writeGraph(t,BITMAP,Config_getString("RTF_OUTPUT"),
+                        relPath,FALSE);
+
+  // display the file
+  t << "{" << endl;
+  t << rtf_Style_Reset << endl;
+  t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
+  t << fileName << "." << Config_getEnum("DOT_IMAGE_FORMAT");
+  t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
+  t << "}" << endl;
+  DBG_RTF(t << "{\\comment (endCallGraph)}"    << endl)
+}
+
+void RTFGenerator::startDirDepGraph()
+{
+  DBG_RTF(t << "{\\comment (startDirDepGraph)}"    << endl)
+}
+
+void RTFGenerator::endDirDepGraph(const DotDirDeps &g)
+{
+  newParagraph();
+
+  QCString fileName = g.writeGraph(t,BITMAP,Config_getString("RTF_OUTPUT"),
+                        relPath,FALSE);
+
+  // display the file
+  t << "{" << endl;
+  t << rtf_Style_Reset << endl;
+  t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
+  t << fileName << "." << Config_getEnum("DOT_IMAGE_FORMAT");
+  t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
+  t << "}" << endl;
+  DBG_RTF(t << "{\\comment (endDirDepGraph)}"    << endl)
+}
+
+/** Tests the integrity of the result by counting brackets.
+ *
+ */
+void testRTFOutput(const char *name)
+{
+  int bcount=0;
+  int line=1;
+  int c;
+  QFile f(name);
+  if (f.open(IO_ReadOnly))
+  {
+    while ((c=f.getch())!=-1)
+    {
+      if (c=='\\') // escape char
+      {
+        c=f.getch();
+        if (c==-1) break;
+      }
+      else if (c=='{') // open bracket
+      {
+        bcount++;
+      }
+      else if (c=='}') // close bracket
+      {
+        bcount--;
+        if (bcount<0)
+        {
+          goto err;
+          break;
+        }
+      }
+      else if (c=='\n') // newline
+      {
+        line++;
+      }
+    }
+  }
+  if (bcount==0) return; // file is OK.
+err:
+  err("Error: RTF integrity test failed at line %d of %s due to a bracket mismatch.\n",line,name);
+  err("       Please try to create a small code example that produces this error \n"
+      "       and send that to dimitri@stack.nl.\n");
+}
+
+/**
+ * This is an API to a VERY brittle RTF preprocessor that combines nested
+ * RTF files.  This version replaces the infile with the new file
+ */
+bool RTFGenerator::preProcessFileInplace(const char *path,const char *name)
+{
+  QDir d(path);
+  // store the original directory
+  if (!d.exists())
+  {
+    err("Error: Output dir %s does not exist!\n",path);
+    return FALSE;
+  }
+  QCString oldDir = convertToQCString(QDir::currentDirPath());
+
+  // go to the html output directory (i.e. path)
+  QDir::setCurrent(d.absPath());
+  QDir thisDir;
+
+  QCString combinedName = (QCString)path+"/combined.rtf";
+  QCString mainRTFName  = (QCString)path+"/"+name;
+
+  QFile outf(combinedName);
+  if (!outf.open(IO_WriteOnly))
+  {
+    err("Failed to open %s for writing!\n",combinedName.data());
+    return FALSE;
+  }
+  QTextStream outt(&outf);
+  outt.setEncoding(QTextStream::UnicodeUTF8);
+
+  if (!PreProcessFile(thisDir,mainRTFName,outt))
+  {
+    // it failed, remove the temp file
+    outf.close();
+    thisDir.remove(combinedName);
+    QDir::setCurrent(oldDir);
+    return FALSE;
+  }
+
+  // everything worked, move the files
+  outf.close();
+  thisDir.remove(mainRTFName);
+  thisDir.rename(combinedName,mainRTFName);
+
+  testRTFOutput(mainRTFName);
+
+  QDir::setCurrent(oldDir);
+  return TRUE;
+}
+
+void RTFGenerator::startMemberGroupHeader(bool hasHeader)
+{
+  DBG_RTF(t << "{\\comment startMemberGroupHeader}" << endl)
+  t << "{" << endl;
+  if (hasHeader) incrementIndentLevel();
+  t << rtf_Style_Reset << rtf_Style["GroupHeader"]->reference;
+}
+
+void RTFGenerator::endMemberGroupHeader()
+{
+  DBG_RTF(t << "{\\comment endMemberGroupHeader}" << endl)
+  newParagraph();
+  t << rtf_Style_Reset << rtf_CList_DepthStyle();
+}
+
+void RTFGenerator::startMemberGroupDocs()
+{
+  DBG_RTF(t << "{\\comment startMemberGroupDocs}" << endl)
+  startEmphasis();
+}
+
+void RTFGenerator::endMemberGroupDocs()
+{
+  DBG_RTF(t << "{\\comment endMemberGroupDocs}" << endl)
+  endEmphasis();
+  newParagraph();
+}
+
+void RTFGenerator::startMemberGroup()
+{
+  DBG_RTF(t << "{\\comment startMemberGroup}" << endl)
+  t << rtf_Style_Reset << rtf_BList_DepthStyle() << endl;
+}
+
+void RTFGenerator::endMemberGroup(bool hasHeader)
+{
+  DBG_RTF(t << "{\\comment endMemberGroup}" << endl)
+  if (hasHeader) decrementIndentLevel();
+  t << "}";
+}
+
+void RTFGenerator::startSimpleSect(SectionTypes,const char *file,const char *anchor,const char *title)
+{
+  DBG_RTF(t << "{\\comment (startSimpleSect)}"    << endl)
+  t << "{"; // ends at endDescList
+  t << "{"; // ends at endDescTitle
+  startBold();
+  newParagraph();
+  if (file)
+  {
+    writeObjectLink(0,file,anchor,title);
+  }
+  else
+  {
+    docify(title);
+  }
+  endBold();
+  t << "}";
+  newParagraph();
+  incrementIndentLevel();
+  t << rtf_Style_Reset << rtf_DList_DepthStyle();
+}
+
+void RTFGenerator::endSimpleSect()
+{
+  DBG_RTF(t << "{\\comment (endSimpleSect)}"    << endl)
+  newParagraph();
+  decrementIndentLevel();
+  m_omitParagraph = TRUE;
+  t << "}";
+}
+
+void RTFGenerator::startParamList(ParamListTypes,const char *title)
+{
+  DBG_RTF(t << "{\\comment (startParamList)}"    << endl)
+  t << "{"; // ends at endParamList
+  t << "{"; // ends at endDescTitle
+  startBold();
+  newParagraph();
+  docify(title);
+  endBold();
+  t << "}";
+  newParagraph();
+  incrementIndentLevel();
+  t << rtf_Style_Reset << rtf_DList_DepthStyle();
+}
+
+void RTFGenerator::endParamList()
+{
+  DBG_RTF(t << "{\\comment (endParamList)}"    << endl)
+  newParagraph();
+  decrementIndentLevel();
+  m_omitParagraph = TRUE;
+  t << "}";
+}
+
+void RTFGenerator::startParameterType(bool first,const char *key)
+{
+  DBG_RTF(t << "{\\comment (startParameterList)}"    << endl)
+  if (!first)
+  {
+    t << " " << key << " ";
+  }
+}
+
+void RTFGenerator::printDoc(DocNode *n,const char *langExt)
+{
+  RTFDocVisitor *visitor = new RTFDocVisitor(t,*this,langExt);
+  n->accept(visitor);
+  delete visitor; 
+  m_omitParagraph = TRUE;
+}
+
+void RTFGenerator::rtfwriteRuler_doubleline() 
+{ 
+  DBG_RTF(t << "{\\comment (rtfwriteRuler_doubleline)}"    << endl)
+  t << "{\\pard\\widctlpar\\brdrb\\brdrdb\\brdrw15\\brsp20 \\adjustright \\par}" << endl; 
+}
+
+void RTFGenerator::rtfwriteRuler_emboss() 
+{ 
+  DBG_RTF(t << "{\\comment (rtfwriteRuler_emboss)}"    << endl)
+  t << "{\\pard\\widctlpar\\brdrb\\brdremboss\\brdrw15\\brsp20 \\adjustright \\par}" << endl; 
+}
+
+void RTFGenerator::rtfwriteRuler_thick() 
+{ 
+  DBG_RTF(t << "{\\comment (rtfwriteRuler_thick)}"    << endl)
+  t << "{\\pard\\widctlpar\\brdrb\\brdrs\\brdrw75\\brsp20 \\adjustright \\par}" << endl; 
+}
+
+void RTFGenerator::rtfwriteRuler_thin() 
+{ 
+  DBG_RTF(t << "{\\comment (rtfwriteRuler_thin)}"    << endl)
+  t << "{\\pard\\widctlpar\\brdrb\\brdrs\\brdrw5\\brsp20 \\adjustright \\par}" << endl; 
+}
+
+void RTFGenerator::postProcess(QByteArray &a)
+{
+  QByteArray enc(a.size()*4); // worst case
+  int off=0;
+  uint i;
+  bool mbFlag=FALSE;
+  for (i=0;i<a.size();i++)
+  {
+    unsigned char c = (unsigned char)a.at(i);
+    
+    // treat characters > 0x80 as multibyte characters, except when they
+    // are control characters 
+    if (c>0x80 || (mbFlag && c!='\\' && c!='{' && c!='}'))
+    {
+      char s[10];
+      sprintf(s,"\\'%X",c);
+      qstrcpy(enc.data()+off,s);
+      off+=qstrlen(s);
+      mbFlag=c>0x80;
+    }
+    else
+    {
+      enc.at(off++)=c;
+    }
+  }
+  enc.resize(off);
+  a = enc;
+}
+
+void RTFGenerator::startConstraintList(const char *header)
+{
+  DBG_RTF(t << "{\\comment (startConstraintList)}"    << endl)
+  t << "{"; // ends at endConstraintList
+  t << "{"; 
+  startBold();
+  newParagraph();
+  docify(header);
+  endBold();
+  t << "}";
+  newParagraph();
+  incrementIndentLevel();
+  t << rtf_Style_Reset << rtf_DList_DepthStyle();
+}
+
+void RTFGenerator::startConstraintParam()
+{
+  DBG_RTF(t << "{\\comment (startConstraintParam)}"    << endl)
+  startEmphasis();
+}
+
+void RTFGenerator::endConstraintParam()
+{
+  DBG_RTF(t << "{\\comment (endConstraintParam)}"    << endl)
+  endEmphasis();
+  t << " : ";
+}
+
+void RTFGenerator::startConstraintType()
+{
+  DBG_RTF(t << "{\\comment (startConstraintType)}"    << endl)
+  startEmphasis();
+}
+
+void RTFGenerator::endConstraintType()
+{
+  DBG_RTF(t << "{\\comment (endConstraintType)}"    << endl)
+  endEmphasis();
+  t << " ";
+}
+
+void RTFGenerator::startConstraintDocs()
+{
+  DBG_RTF(t << "{\\comment (startConstraintDocs)}"    << endl)
+}
+
+void RTFGenerator::endConstraintDocs()
+{
+  DBG_RTF(t << "{\\comment (endConstraintDocs)}"    << endl)
+  newParagraph();
+}
+
+void RTFGenerator::endConstraintList()
+{
+  DBG_RTF(t << "{\\comment (endConstraintList)}"    << endl)
+  newParagraph();
+  decrementIndentLevel();
+  m_omitParagraph = TRUE;
+  t << "}";
+}
+
+
+
+