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