summaryrefslogtreecommitdiffstats
path: root/src/rtfgen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/rtfgen.cpp')
-rw-r--r--src/rtfgen.cpp180
1 files changed, 171 insertions, 9 deletions
diff --git a/src/rtfgen.cpp b/src/rtfgen.cpp
index efae422..9b9196f 100644
--- a/src/rtfgen.cpp
+++ b/src/rtfgen.cpp
@@ -46,6 +46,16 @@ struct ListItemInfo
};
static ListItemInfo listItemInfo[indentLevels];
+static QCString title;
+static QCString subject;
+static QCString comments;
+static QCString company;
+static QCString logoFilename;
+static QCString author;
+static QCString manager;
+static QCString documentType;
+static QCString documentId;
+static QCString keywords;
// it is undocumented as far as I know, but
// "."'s in a bookmarkname are converted to "_"'s
@@ -582,6 +592,102 @@ static void loadStylesheet(const char *name, QDict<StyleData>& dict)
static QDict<StyleData> Rtf_Style(257);
+
+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";
+}
+
+static void loadExtensions(const char *name)
+{
+ QFile file(name);
+ if (!file.open(IO_ReadOnly))
+ {
+ err("Can't open RTF extensions file %s. Using defaults.\n",name);
+ return;
+ }
+ msg("Loading RTF extensions %s...\n",name);
+
+ static const QRegExp separator("[ \t]*=[ \t]*");
+ uint lineNr=1;
+ QTextStream t(&file);
+ while (!t.eof())
+ {
+ QCString s(4096); // string buffer of max line length
+ s = t.readLine().stripWhiteSpace();
+ if (s.length()==0 || s.at(0)=='#') continue; // skip blanks & comments
+ int sepLength;
+ int sepStart = separator.match(s,0,&sepLength);
+ if (sepStart<=0) // no valid assignment statement
+ {
+ warn(name,lineNr,"Assignment of extension field expected!\n");
+ continue;
+ }
+ QCString key=s.left(sepStart);
+ QCString data=s.data() + sepStart + sepLength;
+
+ if (key == "Title") title = data.data();
+ if (key == "Subject") subject = data.data();
+ if (key == "Comments") comments = data.data();
+ if (key == "Company") company = data.data();
+ if (key == "LogoFilename") logoFilename = data.data();
+ if (key == "Author") author = data.data();
+ if (key == "Manager") manager = data.data();
+ if (key == "DocumentType") documentType = data.data();
+ if (key == "DocumentId") documentId = data.data();
+ if (key == "Keywords") keywords = data.data();
+ lineNr++;
+ }
+}
+
+
void RTFGenerator::init()
{
QCString dir=Config::rtfOutputDir;
@@ -607,6 +713,12 @@ void RTFGenerator::init()
// overwrite some (or all) definitions from file
if (!Config::rtfStylesheetFile.isEmpty())
loadStylesheet(Config::rtfStylesheetFile, Rtf_Style);
+
+ // If user has defined an extension file, load its contents.
+ if (Config::rtfExtensionsFile)
+ {
+ loadExtensions(Config::rtfExtensionsFile);
+ }
}
static QCString makeIndexName(const char *s,int i)
@@ -768,11 +880,20 @@ void RTFGenerator::startIndexSection(IndexSections is)
case isTitlePageStart:
// basic RTFstart
// get readyfor author etc
+
t << "{\\info \n";
- t << "{\\title ";
+ t << "{\\title {\\comment ";
break;
case isTitlePageAuthor:
- t << "}\n{\\author ";
+ t << "}\n";
+ if (subject) t << "{\\subject " << subject << "}\n";
+ if (comments) t << "{\\comment " << comments << "}\n";
+ if (company) t << "{\\company " << company << "}\n";
+ if (author) t << "{\\author " << author << "}\n";
+ if (manager) t << "{\\manager " << manager << "}\n";
+ if (documentType) t << "{\\category " << documentType << "}\n";
+ if (keywords) t << "{\\keywords " << keywords << "}\n";
+ t << "{\\comment ";
break;
case isMainPage:
//Introduction
@@ -917,29 +1038,64 @@ void RTFGenerator::endIndexSection(IndexSections is)
switch (is)
{
case isTitlePageStart:
+ if (title)
+ // User has overridden document title in extensions file
+ t << "}" << title;
+ else
+ t << "}" << Config::projectName;
break;
case isTitlePageAuthor:
{
- t << " Doxygen}\n"
- "{\\creatim " << dateToRTFDateString() << "}\n"
- "}";
- DBG_RTF(t << "{\\comment end of infoblock}\n")
+ 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";
+ if (logoFilename)
+ {
+ t << "{\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE " << logoFilename;
+ t << " \\\\*MERGEFORMAT} {\\fldrslt IMAGE }}\\par\\par\n";
+ }
+ if (company)
+ {
+ t << 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 (documentType)
+ {
+ t << documentType << "\\par\n";
+ }
+ if (documentId)
+ {
+ t << 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::projectNumber << "\\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 << "{\\field\\fldedit {\\*\\fldinst TOC \\\\f \\\\*MERGEFORMAT}{\\fldrslt Table of contents}}\\par\n";
t << Rtf_Style_Reset << endl;
@@ -1743,7 +1899,7 @@ void RTFGenerator::endMemberDescription()
endEmphasis();
newParagraph();
decrementIndentLevel();
- t << "}" << endl;
+ t << "\\par}" << endl;
}
void RTFGenerator::startDescList()
@@ -2013,9 +2169,15 @@ void RTFGenerator::endMemberList()
#endif
}
-void RTFGenerator::startImage(const char *,const char *,bool)
+void RTFGenerator::startImage(const char *name,const char *,bool)
{
- // not yet implemented
+ newParagraph();
+ t << "{" << endl;
+ t << Rtf_Style_Reset << endl;
+ t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE ";
+ t << name;
+ t << " \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
+ t << "}" << endl;
}
void RTFGenerator::endImage(bool)