Contribution of a new version of ORB and CXX DITA plug-in bug 1461 bug 1621 bug 1962
/******************************************************************************
*
*
*
* 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 << "}";
}