Chameleon

Chameleon Svn Source Tree

Root/branches/xZenu/src/util/doxygen/src/rtfgen.cpp

Source at commit 1322 created 12 years 8 months ago.
By meklort, Add doxygen to utils folder
1/******************************************************************************
2 *
3 * $Id: rtfgen.cpp,v 1.14 2001/03/19 19:27:41 root Exp $
4 *
5 * Copyright (C) 1997-2011 by Parker Waechter & Dimitri van Heesch.
6 *
7 * Style sheet additions by Alexander Bartolich
8 *
9 * Permission to use, copy, modify, and distribute this software and its
10 * documentation under the terms of the GNU General Public License is hereby
11 * granted. No representations are made about the suitability of this software
12 * for any purpose. It is provided "as is" without express or implied warranty.
13 * See the GNU General Public License for more details.
14 *
15 * Documents produced by Doxygen are derivative works derived from the
16 * input used in their production; they are not affected by this license.
17 *
18 */
19
20#include <stdlib.h>
21
22#include "qtbc.h"
23#include <qdir.h>
24#include <qregexp.h>
25
26#include "rtfgen.h"
27#include "config.h"
28#include "message.h"
29#include "doxygen.h"
30#include "util.h"
31#include "diagram.h"
32#include "language.h"
33#include "dot.h"
34#include "version.h"
35#include "pagedef.h"
36#include "rtfstyle.h"
37#include "rtfdocvisitor.h"
38#include "docparser.h"
39#include "dirdef.h"
40#include "vhdldocgen.h"
41#include "portable.h"
42
43//#define DBG_RTF(x) x;
44#define DBG_RTF(x)
45
46static QCString dateToRTFDateString()
47{
48 const QDateTime &d = QDateTime::currentDateTime();
49 QCString result;
50 result.sprintf("\\yr%d\\mo%d\\dy%d\\hr%d\\min%d\\sec%d",
51 d.date().year(), d.date().month(), d.date().day(),
52 d.time().hour(),d.time().minute(),d.time().second());
53 return result;
54}
55
56RTFGenerator::RTFGenerator() : OutputGenerator()
57{
58 dir=Config_getString("RTF_OUTPUT");
59 col=0;
60 //insideTabbing=FALSE;
61 m_listLevel = 0;
62 m_bstartedBody = FALSE;
63 m_omitParagraph = FALSE;
64 m_numCols = 0;
65}
66
67RTFGenerator::~RTFGenerator()
68{
69}
70
71//void RTFGenerator::append(const OutputGenerator *g)
72//{
73// t << g->getContents();
74// col+=((RTFGenerator *)g)->col;
75// //insideTabbing=insideTabbing || ((RTFGenerator *)g)->insideTabbing;
76// m_listLevel=((RTFGenerator *)g)->m_listLevel;
77// m_omitParagraph=((RTFGenerator *)g)->m_omitParagraph;
78// //printf("RTFGenerator::append(%s) insideTabbing=%s\n", g->getContents().data(),
79// // insideTabbing ? "TRUE" : "FALSE" );
80//}
81
82//OutputGenerator *RTFGenerator::copy()
83//{
84// RTFGenerator *result = new RTFGenerator;
85// //result->insideTabbing=insideTabbing;
86// result->m_listLevel=m_listLevel;
87// result->m_omitParagraph=m_omitParagraph;
88// return result;
89//}
90
91void RTFGenerator::writeStyleSheetFile(QFile &file)
92{
93 QTextStream t(&file);
94 t << "# Generated by doxygen " << versionString << "\n\n";
95 t << "# This file describes styles used for generating RTF output.\n";
96 t << "# All text after a hash (#) is considered a comment and will be ignored.\n";
97 t << "# Remove a hash to activate a line.\n\n";
98
99 int i;
100 for ( i=0 ; rtf_Style_Default[i].reference!=0 ; i++ )
101 {
102 t << "# " << rtf_Style_Default[i].name << " = "
103 << rtf_Style_Default[i].reference
104 << rtf_Style_Default[i].definition << endl;
105 }
106}
107
108void RTFGenerator::writeExtensionsFile(QFile &file)
109{
110 QTextStream t(&file);
111 t << "# Generated by doxygen " << versionString << "\n\n";
112 t << "# This file describes extensions used for generating RTF output.\n";
113 t << "# All text after a hash (#) is considered a comment and will be ignored.\n";
114 t << "# Remove a hash to activate a line.\n\n";
115
116 t << "# Overrides the project title.\n";
117
118 t << "#Title = \n\n";
119
120 t << "# Name of the company that produced this document.\n";
121 t << "#Company = \n\n";
122
123 t << "# Filename of a company or project logo.\n";
124 t << "#LogoFilename = \n\n";
125
126 t << "# Author of the document.\n";
127 t << "#Author = \n\n";
128
129 t << "# Type of document (e.g. Design Specification, User Manual, etc.).\n";
130 t << "#DocumentType = \n\n";
131
132 t << "# Document tracking number.\n";
133 t << "#DocumentId = \n\n";
134
135 t << "# Name of the author's manager.\n";
136 t << "# This field is not displayed in the document itself, but it is \n";
137 t << "# available in the information block of the rtf file. In Microsoft \n";
138 t << "# Word, it is available under File:Properties.\n";
139 t << "#Manager = \n\n";
140
141 t << "# Subject of the document.\n";
142 t << "# This field is not displayed in the document itself, but it is \n";
143 t << "# available in the information block of the rtf file. In Microsoft \n";
144 t << "# Word, it is available under File:Properties.\n";
145 t << "#Subject = \n\n";
146
147 t << "# Comments regarding the document.\n";
148 t << "# This field is not displayed in the document itself, but it is \n";
149 t << "# available in the information block of the rtf file. In Microsoft \n";
150 t << "# Word, it is available under File:Properties.\n";
151 t << "#Comments = \n\n";
152
153 t << "# Keywords associated with the document.\n";
154 t << "# This field is not displayed in the document itself, but it is \n";
155 t << "# available in the information block of the rtf file. In Microsoft \n";
156 t << "# Word, it is available under File:Properties.\n";
157 t << "#Keywords = \n\n";
158}
159
160
161void RTFGenerator::init()
162{
163 QCString dir=Config_getString("RTF_OUTPUT");
164 QDir d(dir);
165 if (!d.exists() && !d.mkdir(dir))
166 {
167 err("Could not create output directory %s\n",dir.data());
168 exit(1);
169 }
170 rtf_Style.setAutoDelete(TRUE);
171
172 // first duplicate strings of rtf_Style_Default
173 const struct Rtf_Style_Default* def = rtf_Style_Default;
174 while(def->reference != 0)
175 {
176 if (def->definition == 0)
177 err("Internal error: rtf_Style_Default[%s] has no definition.\n", def->name);
178 StyleData* styleData = new StyleData(def->reference, def->definition);
179 rtf_Style.insert(def->name, styleData);
180 def++;
181 }
182
183 // overwrite some (or all) definitions from file
184 QCString &rtfStyleSheetFile = Config_getString("RTF_STYLESHEET_FILE");
185 if (!rtfStyleSheetFile.isEmpty())
186 {
187 loadStylesheet(rtfStyleSheetFile, rtf_Style);
188 }
189
190 // If user has defined an extension file, load its contents.
191 QCString &rtfExtensionsFile = Config_getString("RTF_EXTENSIONS_FILE");
192 if (!rtfExtensionsFile.isEmpty())
193 {
194 loadExtensions(rtfExtensionsFile);
195 }
196
197 createSubDirs(d);
198}
199
200static QCString makeIndexName(const char *s,int i)
201{
202 QCString result=s;
203 result+=(char)(i+'0');
204 return result;
205}
206
207void RTFGenerator::beginRTFDocument()
208{
209 /* all the included RTF files should begin with the
210 * same header
211 */
212 t <<"{\\rtf1\\ansi\\ansicpg" << theTranslator->trRTFansicp();
213 t <<"\\uc1 \\deff0\\deflang1033\\deflangfe1033\n";
214
215 DBG_RTF(t <<"{\\comment Begining font list}\n")
216 t <<"{\\fonttbl ";
217 t <<"{\\f0\\froman\\fcharset" << theTranslator->trRTFCharSet();
218 t <<"\\fprq2{\\*\\panose 02020603050405020304}Times New Roman;}\n";
219 t <<"{\\f1\\fswiss\\fcharset" << theTranslator->trRTFCharSet();
220 t <<"\\fprq2{\\*\\panose 020b0604020202020204}Arial;}\n";
221 t <<"{\\f2\\fmodern\\fcharset" << theTranslator->trRTFCharSet();
222 t <<"\\fprq1{\\*\\panose 02070309020205020404}Courier New;}\n";
223 t <<"{\\f3\\froman\\fcharset2\\fprq2{\\*\\panose 05050102010706020507}Symbol;}\n";
224 t <<"}\n";
225 DBG_RTF(t <<"{\\comment begin colors}\n")
226 t <<"{\\colortbl;";
227 t <<"\\red0\\green0\\blue0;";
228 t <<"\\red0\\green0\\blue255;";
229 t <<"\\red0\\green255\\blue255;";
230 t <<"\\red0\\green255\\blue0;";
231 t <<"\\red255\\green0\\blue255;";
232 t <<"\\red255\\green0\\blue0;";
233 t <<"\\red255\\green255\\blue0;";
234 t <<"\\red255\\green255\\blue255;";
235 t <<"\\red0\\green0\\blue128;";
236 t <<"\\red0\\green128\\blue128;";
237 t <<"\\red0\\green128\\blue0;";
238 t <<"\\red128\\green0\\blue128;";
239 t <<"\\red128\\green0\\blue0;";
240 t <<"\\red128\\green128\\blue0;";
241 t <<"\\red128\\green128\\blue128;";
242 t <<"\\red192\\green192\\blue192;}" << endl;
243
244 DBG_RTF(t <<"{\\comment Beginning style list}\n")
245 t <<"{\\stylesheet\n";
246 t <<"{\\widctlpar\\adjustright \\fs20\\cgrid \\snext0 Normal;}\n";
247
248 // sort styles ascending by \s-number via an intermediate QArray
249 QArray<const StyleData*> array(128);
250 array.fill(0);
251 QDictIterator<StyleData> iter(rtf_Style);
252 const StyleData* style;
253 for(; (style = iter.current()); ++iter)
254 {
255 unsigned index = style->index;
256 unsigned size = array.size();
257 if (index >= size)
258 {
259 // +1 to add at least one element, then align up to multiple of 8
260 array.resize((index + 1 + 7) & ~7);
261 array.fill(0, size);
262 ASSERT(index < array.size());
263 }
264 if (array.at(index) != 0)
265 {
266 QCString key(convertToQCString(iter.currentKey()));
267 msg("Style '%s' redefines \\s%d.\n", key.data(), index);
268 }
269 array.at(index) = style;
270 }
271
272 // write array elements
273 unsigned size = array.size();
274 for(unsigned i = 0; i < size; i++)
275 {
276 const StyleData* style = array.at(i);
277 if (style != 0)
278 t <<"{" << style->reference << style->definition << ";}\n";
279 }
280
281 t <<"}" << endl;
282 // this comment is needed for postprocessing!
283 t <<"{\\comment begin body}" << endl;
284
285}
286
287void RTFGenerator::beginRTFChapter()
288{
289 t <<"\n";
290 DBG_RTF(t << "{\\comment BeginRTFChapter}\n")
291 t << rtf_Style_Reset;
292
293 // if we are compact, no extra page breaks...
294 if (Config_getBool("COMPACT_RTF"))
295 {
296 // t <<"\\sect\\sectd\\sbknone\n";
297 t <<"\\sect\\sbknone\n";
298 rtfwriteRuler_thick();
299 }
300 else
301 t <<"\\sect\\sbkpage\n";
302 //t <<"\\sect\\sectd\\sbkpage\n";
303
304 t << rtf_Style["Heading1"]->reference << "\n";
305}
306
307void RTFGenerator::beginRTFSection()
308{
309 t <<"\n";
310 DBG_RTF(t << "{\\comment BeginRTFSection}\n")
311 t << rtf_Style_Reset;
312
313 // if we are compact, no extra page breaks...
314 if (Config_getBool("COMPACT_RTF"))
315 {
316 // t <<"\\sect\\sectd\\sbknone\n";
317 t <<"\\sect\\sbknone\n";
318 rtfwriteRuler_emboss();
319 }
320 else
321 t <<"\\sect\\sbkpage\n";
322 //t <<"\\sect\\sectd\\sbkpage\n";
323
324 t << rtf_Style["Heading2"]->reference << "\n";
325}
326
327void RTFGenerator::startFile(const char *name,const char *,const char *)
328{
329 //setEncoding(QCString().sprintf("CP%s",theTranslator->trRTFansicp()));
330 QCString fileName=name;
331 relPath = relativePathToRoot(fileName);
332
333 if (fileName.right(4)!=".rtf" ) fileName+=".rtf";
334 startPlainFile(fileName);
335 beginRTFDocument();
336}
337
338void RTFGenerator::endFile()
339{
340 DBG_RTF(t << "{\\comment endFile}\n")
341 t << "}";
342
343 endPlainFile();
344}
345
346void RTFGenerator::startProjectNumber()
347{
348 DBG_RTF(t <<"{\\comment startProjectNumber }" << endl)
349 t << " ";
350}
351
352void RTFGenerator::endProjectNumber()
353{
354 DBG_RTF(t <<"{\\comment endProjectNumber }" << endl)
355}
356
357void RTFGenerator::startIndexSection(IndexSections is)
358{
359 //QCString paperName;
360
361 m_listLevel = 0;
362
363 switch (is)
364 {
365 case isTitlePageStart:
366 // basic RTFstart
367 // get readyfor author etc
368
369 t << "{\\info \n";
370 t << "{\\title {\\comment ";
371 break;
372 case isTitlePageAuthor:
373 t << "}\n";
374 if (rtf_subject) t << "{\\subject " << rtf_subject << "}\n";
375 if (rtf_comments) t << "{\\comment " << rtf_comments << "}\n";
376 if (rtf_company) t << "{\\company " << rtf_company << "}\n";
377 if (rtf_author) t << "{\\author " << rtf_author << "}\n";
378 if (rtf_manager) t << "{\\manager " << rtf_manager << "}\n";
379 if (rtf_documentType) t << "{\\category " << rtf_documentType << "}\n";
380 if (rtf_keywords) t << "{\\keywords " << rtf_keywords << "}\n";
381 t << "{\\comment ";
382 break;
383 case isMainPage:
384 //Introduction
385 beginRTFChapter();
386 break;
387 //case isPackageIndex:
388 // //Package Index
389 // beginRTFChapter();
390 // break;
391 case isModuleIndex:
392 //Module Index
393 beginRTFChapter();
394 break;
395 case isDirIndex:
396 //Directory Index
397 beginRTFChapter();
398 break;
399 case isNamespaceIndex:
400 //Namespace Index
401 beginRTFChapter();
402 break;
403 case isClassHierarchyIndex:
404 //Hierarchical Index
405 DBG_RTF(t << "{\\comment start classhierarchy}\n")
406 beginRTFChapter();
407 break;
408 case isCompoundIndex:
409 //Annotated Compound Index
410 beginRTFChapter();
411 break;
412 case isFileIndex:
413 //Annotated File Index
414 beginRTFChapter();
415 break;
416 case isPageIndex:
417 //Related Page Index
418 beginRTFChapter();
419 break;
420 case isModuleDocumentation:
421 {
422 //Module Documentation
423 GroupSDict::Iterator gli(*Doxygen::groupSDict);
424 GroupDef *gd;
425 bool found=FALSE;
426 for (gli.toFirst();(gd=gli.current()) && !found;++gli)
427 {
428 if (!gd->isReference())
429 {
430 beginRTFChapter();
431 found=TRUE;
432 }
433 }
434 }
435 break;
436 case isDirDocumentation:
437 {
438 //Directory Documentation
439 SDict<DirDef>::Iterator dli(*Doxygen::directories);
440 DirDef *dd;
441 bool found=FALSE;
442 for (dli.toFirst();(dd=dli.current()) && !found;++dli)
443 {
444 if (dd->isLinkableInProject())
445 {
446 beginRTFChapter();
447 found=TRUE;
448 }
449 }
450 }
451 break;
452 case isNamespaceDocumentation:
453 {
454 // Namespace Documentation
455 NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
456 NamespaceDef *nd;
457 bool found=FALSE;
458 for (nli.toFirst();(nd=nli.current()) && !found;++nli)
459 {
460 if (nd->isLinkableInProject())
461 {
462 beginRTFChapter();
463 found=TRUE;
464 }
465 }
466 }
467 break;
468 case isClassDocumentation:
469 {
470 //Compound Documentation
471 ClassSDict::Iterator cli(*Doxygen::classSDict);
472 ClassDef *cd=0;
473 bool found=FALSE;
474 for (cli.toFirst();(cd=cli.current()) && !found;++cli)
475 {
476 if (cd->isLinkableInProject() &&
477 cd->templateMaster()==0 &&
478 !cd->isEmbeddedInGroupDocs()
479 )
480 {
481 beginRTFChapter();
482 found=TRUE;
483 }
484 }
485 }
486 break;
487 case isFileDocumentation:
488 {
489 //File Documentation
490 bool isFirst=TRUE;
491 FileName *fn=Doxygen::inputNameList->first();
492 while (fn)
493 {
494 FileDef *fd=fn->first();
495 while (fd)
496 {
497 if (fd->isLinkableInProject())
498 {
499 if (isFirst)
500 {
501 beginRTFChapter();
502 isFirst=FALSE;
503 break;
504 }
505 }
506 fd=fn->next();
507 }
508 fn=Doxygen::inputNameList->next();
509 }
510 }
511 break;
512 case isExampleDocumentation:
513 {
514 //Example Documentation
515 beginRTFChapter();
516 }
517 break;
518 case isPageDocumentation:
519 {
520 //Page Documentation
521 beginRTFChapter();
522 }
523 break;
524 case isPageDocumentation2:
525 {
526 t << "{\\tc \\v ";
527 }
528 break;
529 case isEndIndex:
530 break;
531 }
532}
533
534void RTFGenerator::endIndexSection(IndexSections is)
535{
536 bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
537 bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
538 switch (is)
539 {
540 case isTitlePageStart:
541 if (rtf_title)
542 // User has overridden document title in extensions file
543 t << "}" << rtf_title;
544 else
545 t << "}" << Config_getString("PROJECT_NAME");
546 break;
547 case isTitlePageAuthor:
548 {
549 t << "Doxgyen. }\n";
550 t << "{\\creatim " << dateToRTFDateString() << "}\n}";
551 DBG_RTF(t << "{\\comment end of infoblock}\n");
552 // setup for this section
553 t << rtf_Style_Reset <<"\n";
554 t <<"\\sectd\\pgnlcrm\n";
555 t <<"{\\footer "<<rtf_Style["Footer"]->reference << "{\\chpgn}}\n";
556 // the title entry
557 DBG_RTF(t << "{\\comment begin title page}\n")
558
559
560 t << rtf_Style_Reset << rtf_Style["SubTitle"]->reference << endl; // set to title style
561
562 t << "\\vertalc\\qc\\par\\par\\par\\par\\par\\par\\par\n";
563 if (rtf_logoFilename)
564 {
565 t << "{\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"" << rtf_logoFilename;
566 t << "\" \\\\d \\\\*MERGEFORMAT} {\\fldrslt IMAGE }}\\par\\par\n";
567 }
568 if (rtf_company)
569 {
570 t << rtf_company << "\\par\\par\n";
571 }
572
573 t << rtf_Style_Reset << rtf_Style["Title"]->reference << endl; // set to title style
574 t << "{\\field\\fldedit {\\*\\fldinst TITLE \\\\*MERGEFORMAT}{\\fldrslt TITLE}}\\par" << endl;
575
576 t << rtf_Style_Reset << rtf_Style["SubTitle"]->reference << endl; // set to title style
577 t << "\\par\n";
578 if (rtf_documentType)
579 {
580 t << rtf_documentType << "\\par\n";
581 }
582 if (rtf_documentId)
583 {
584 t << rtf_documentId << "\\par\n";
585 }
586 t << "\\par\\par\\par\\par\\par\\par\\par\\par\\par\\par\\par\\par\n";
587
588 t << rtf_Style_Reset << rtf_Style["SubTitle"]->reference << endl; // set to subtitle style
589 t << "{\\field\\fldedit {\\*\\fldinst AUTHOR \\\\*MERGEFORMAT}{\\fldrslt AUTHOR}}\\par" << endl;
590 t << "Version " << Config_getString("PROJECT_NUMBER") << "\\par";
591 t << "{\\field\\fldedit {\\*\\fldinst CREATEDATE \\\\*MERGEFORMAT}"
592 "{\\fldrslt CREATEDATE}}\\par"<<endl;
593 t << "\\page\\page";
594 DBG_RTF(t << "{\\comment End title page}" << endl)
595
596 // table of contents section
597 DBG_RTF(t << "{\\comment Table of contents}\n")
598 t << "\\vertalt\n";
599 t << rtf_Style_Reset << endl;
600 t << rtf_Style["Heading1"]->reference;
601 t << theTranslator->trRTFTableOfContents() << "\\par"<< endl;
602 t << rtf_Style_Reset << "\\par" << endl;
603 t << "{\\field\\fldedit {\\*\\fldinst TOC \\\\f \\\\*MERGEFORMAT}{\\fldrslt Table of contents}}\\par\n";
604 t << rtf_Style_Reset << endl;
605 }
606 break;
607 case isMainPage:
608 t << "\\par " << rtf_Style_Reset << endl;
609 if (!Doxygen::mainPage || Doxygen::mainPage->title().isEmpty())
610 {
611 t << "{\\tc \\v " << theTranslator->trMainPage() << "}"<< endl;
612 }
613 else
614 {
615 t << "{\\tc \\v " << substitute(Doxygen::mainPage->title(),"%","") << "}"<< endl;
616 }
617 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
618 if (Config_getBool("GENERATE_TREEVIEW")) t << "main"; else t << "index";
619 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
620 break;
621 //case isPackageIndex:
622 // t << "\\par " << rtf_Style_Reset << endl;
623 // t << "{\\tc \\v " << theTranslator->trPackageList() << "}"<< endl;
624 // t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"packages.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
625 // break;
626 case isModuleIndex:
627 t << "\\par " << rtf_Style_Reset << endl;
628 t << "{\\tc \\v " << theTranslator->trModuleIndex() << "}"<< endl;
629 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"modules.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
630 break;
631 case isDirIndex:
632 t << "\\par " << rtf_Style_Reset << endl;
633 t << "{\\tc \\v " << theTranslator->trDirIndex() << "}"<< endl;
634 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"dirs.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
635 break;
636 case isNamespaceIndex:
637 t << "\\par " << rtf_Style_Reset << endl;
638 if (fortranOpt)
639 {
640 t << "{\\tc \\v " << theTranslator->trModulesIndex() << "}" << endl;
641 }
642 else
643 {
644 t << "{\\tc \\v " << theTranslator->trNamespaceIndex() << "}" << endl;
645 }
646
647 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"namespaces.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
648 break;
649 case isClassHierarchyIndex:
650 t << "\\par " << rtf_Style_Reset << endl;
651 t << "{\\tc \\v " << theTranslator->trHierarchicalIndex() << "}"<< endl;
652 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"hierarchy.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
653 break;
654 case isCompoundIndex:
655 t << "\\par " << rtf_Style_Reset << endl;
656 if (fortranOpt)
657 {
658 t << "{\\tc \\v " << theTranslator->trCompoundIndexFortran() << "}"<< endl;
659 }
660 else if (vhdlOpt)
661 {
662 t << "{\\tc \\v " << VhdlDocGen::trDesignUnitIndex() << "}"<< endl;
663 }
664 else
665 {
666 t << "{\\tc \\v " << theTranslator->trCompoundIndex() << "}"<< endl;
667 }
668 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"annotated.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
669 break;
670 case isFileIndex:
671 t << "\\par " << rtf_Style_Reset << endl;
672 t << "{\\tc \\v " << theTranslator->trFileIndex() << "}"<< endl;
673 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"files.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
674 break;
675 case isPageIndex:
676 t << "\\par " << rtf_Style_Reset << endl;
677 t << "{\\tc \\v " << theTranslator->trPageIndex() << "}"<< endl;
678 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"pages.rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
679 break;
680 case isModuleDocumentation:
681 {
682 GroupSDict::Iterator gli(*Doxygen::groupSDict);
683 GroupDef *gd;
684 t << "{\\tc \\v " << theTranslator->trModuleDocumentation() << "}"<< endl;
685 for (gli.toFirst();(gd=gli.current());++gli)
686 {
687 if (!gd->isReference())
688 {
689 t << "\\par " << rtf_Style_Reset << endl;
690 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
691 t << gd->getOutputFileBase();
692 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
693 }
694 }
695 }
696 break;
697 case isDirDocumentation:
698 {
699 SDict<DirDef>::Iterator dli(*Doxygen::directories);
700 DirDef *dd;
701 t << "{\\tc \\v " << theTranslator->trDirDocumentation() << "}"<< endl;
702 for (dli.toFirst();(dd=dli.current());++dli)
703 {
704 if (dd->isLinkableInProject())
705 {
706 t << "\\par " << rtf_Style_Reset << endl;
707 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
708 t << dd->getOutputFileBase();
709 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
710 }
711 }
712 }
713 break;
714 case isNamespaceDocumentation:
715 {
716 NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
717 NamespaceDef *nd;
718 bool found=FALSE;
719 for (nli.toFirst();(nd=nli.current()) && !found;++nli)
720 {
721 if (nd->isLinkableInProject())
722 {
723 t << "\\par " << rtf_Style_Reset << endl;
724 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
725 t << nd->getOutputFileBase();
726 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
727 found=TRUE;
728 }
729 }
730 while ((nd=nli.current()))
731 {
732 if (nd->isLinkableInProject())
733 {
734 t << "\\par " << rtf_Style_Reset << endl;
735 beginRTFSection();
736 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
737 t << nd->getOutputFileBase();
738 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
739 }
740 ++nli;
741 }
742 }
743 break;
744 case isClassDocumentation:
745 {
746 ClassSDict::Iterator cli(*Doxygen::classSDict);
747 ClassDef *cd=0;
748 bool found=FALSE;
749 if (fortranOpt)
750 {
751 t << "{\\tc \\v " << theTranslator->trTypeDocumentation() << "}"<< endl;
752 }
753 else
754 {
755 t << "{\\tc \\v " << theTranslator->trClassDocumentation() << "}"<< endl;
756 }
757 for (cli.toFirst();(cd=cli.current()) && !found;++cli)
758 {
759 if (cd->isLinkableInProject() &&
760 cd->templateMaster()==0 &&
761 !cd->isEmbeddedInGroupDocs()
762 )
763 {
764 t << "\\par " << rtf_Style_Reset << endl;
765 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
766 t << cd->getOutputFileBase();
767 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
768 found=TRUE;
769 }
770 }
771 for (;(cd=cli.current());++cli)
772 {
773 if (cd->isLinkableInProject() &&
774 cd->templateMaster()==0 &&
775 !cd->isEmbeddedInGroupDocs()
776 )
777 {
778 t << "\\par " << rtf_Style_Reset << endl;
779 beginRTFSection();
780 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
781 t << cd->getOutputFileBase();
782 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
783 }
784 }
785 }
786 break;
787 case isFileDocumentation:
788 {
789 bool isFirst=TRUE;
790 FileName *fn=Doxygen::inputNameList->first();
791
792 t << "{\\tc \\v " << theTranslator->trFileDocumentation() << "}"<< endl;
793 while (fn)
794 {
795 FileDef *fd=fn->first();
796 while (fd)
797 {
798 if (fd->isLinkableInProject())
799 {
800 if (isFirst)
801 {
802 t << "\\par " << rtf_Style_Reset << endl;
803 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
804 t << fd->getOutputFileBase();
805 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
806 isFirst=FALSE;
807 }
808 else
809 {
810 t << "\\par " << rtf_Style_Reset << endl;
811 beginRTFSection();
812 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
813 t << fd->getOutputFileBase();
814 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
815 }
816 }
817 fd=fn->next();
818 }
819 fn=Doxygen::inputNameList->next();
820 }
821 }
822 break;
823 case isExampleDocumentation:
824 {
825 //t << "}\n";
826 t << "{\\tc \\v " << theTranslator->trExampleDocumentation() << "}"<< endl;
827 PageSDict::Iterator pdi(*Doxygen::exampleSDict);
828 PageDef *pd=pdi.toFirst();
829 if (pd)
830 {
831 t << "\\par " << rtf_Style_Reset << endl;
832 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
833 t << pd->getOutputFileBase();
834 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
835 }
836 for (++pdi;(pd=pdi.current());++pdi)
837 {
838 t << "\\par " << rtf_Style_Reset << endl;
839 beginRTFSection();
840 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
841 t << pd->getOutputFileBase();
842 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
843 }
844 }
845 break;
846 case isPageDocumentation:
847 {
848//#error "fix me in the same way as the latex index..."
849 //t << "{\\tc \\v " << theTranslator->trPageDocumentation() << "}"<< endl;
850 //t << "}"<< endl;
851 //PageSDict::Iterator pdi(*Doxygen::pageSDict);
852 //PageDef *pd=pdi.toFirst();
853 //bool first=TRUE;
854 //for (pdi.toFirst();(pd=pdi.current());++pdi)
855 //{
856 // if (!pd->getGroupDef() && !pd->isReference())
857 // {
858 // if (first) t << "\\par " << rtf_Style_Reset << endl;
859 // t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
860 // t << pd->getOutputFileBase();
861 // t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
862 // first=FALSE;
863 // }
864 //}
865 }
866 break;
867 case isPageDocumentation2:
868 {
869 t << "}";
870 t << "\\par " << rtf_Style_Reset << endl;
871 }
872 break;
873 case isEndIndex:
874 beginRTFChapter();
875 t << rtf_Style["Heading1"]->reference;
876 t << theTranslator->trRTFGeneralIndex() << "\\par "<< endl;
877 t << rtf_Style_Reset << endl;
878 t << "{\\tc \\v " << theTranslator->trRTFGeneralIndex() << "}" << endl;
879 t << "{\\field\\fldedit {\\*\\fldinst INDEX \\\\c2 \\\\*MERGEFORMAT}{\\fldrslt INDEX}}\n";
880
881 break;
882 }
883}
884
885void RTFGenerator::writePageLink(const char *name,bool first)
886{
887 if (first) t << "\\par " << rtf_Style_Reset << endl;
888 t << "{\\field\\fldedit{\\*\\fldinst INCLUDETEXT \"";
889 t << name;
890 t << ".rtf\" \\\\*MERGEFORMAT}{\\fldrslt includedstuff}}\n";
891}
892
893void RTFGenerator::lastIndexPage()
894{
895 DBG_RTF(t <<"{\\comment Beginning Body of RTF Document}\n")
896 // end page and setup for rest of document
897 t <<"\\sect \\sbkpage \\pgndec \\pgnrestart\n";
898 t <<"\\sect \\sectd \\sbknone\n";
899
900 // set new footer with arabic numbers
901 t <<"{\\footer "<< rtf_Style["Footer"]->reference << "{\\chpgn}}\n";
902 //t << rtf_Style["Heading1"]->reference << "\n";
903
904}
905
906void RTFGenerator::writeStyleInfo(int)
907{
908}
909
910void RTFGenerator::lineBreak(const char *)
911{
912 DBG_RTF(t << "{\\comment (lineBreak)}" << endl)
913 t << "\\par" << endl;
914 m_omitParagraph = TRUE;
915}
916
917void RTFGenerator::writeString(const char *text)
918{
919 t << text;
920}
921
922void RTFGenerator::startIndexList()
923{
924 DBG_RTF(t << "{\\comment (startIndexList)}" << endl)
925 t << "{" << endl;
926 t << "\\par" << endl;
927 incrementIndentLevel();
928 t << rtf_Style_Reset << rtf_LCList_DepthStyle() << endl;
929 m_omitParagraph = TRUE;
930}
931
932void RTFGenerator::endIndexList()
933{
934 DBG_RTF(t << "{\\comment (endIndexList)}" << endl)
935 if (!m_omitParagraph)
936 {
937 t << "\\par";
938 m_omitParagraph = TRUE;
939 }
940 t << "}";
941 decrementIndentLevel();
942}
943
944/*! start bullet list */
945void RTFGenerator::startItemList()
946{
947 newParagraph();
948 DBG_RTF(t << "{\\comment (startItemList level=" << m_listLevel << ") }" << endl)
949 t << "{";
950 incrementIndentLevel();
951 rtf_listItemInfo[m_listLevel].isEnum = FALSE;
952}
953
954/*! end bullet list */
955void RTFGenerator::endItemList()
956{
957 newParagraph();
958 DBG_RTF(t << "{\\comment (endItemList level=" << m_listLevel << ")}" << endl)
959 t << "}";
960 decrementIndentLevel();
961 m_omitParagraph = TRUE;
962}
963
964///*! start enumeration list */
965//void RTFGenerator::startEnumList() // starts an enumeration list
966//{
967// DBG_RTF(t << "{\\comment (startEnumList)}" << endl)
968// t << "{" << endl;
969// incrementIndentLevel();
970// rtf_listItemInfo[m_listLevel].isEnum = TRUE;
971// rtf_listItemInfo[m_listLevel].number = 1;
972//}
973//
974///*! end enumeration list */
975//void RTFGenerator::endEnumList()
976//{
977// newParagraph();
978// DBG_RTF(t << "{\\comment (endEnumList)}" << endl)
979// t << "}";
980// decrementIndentLevel();
981// m_omitParagraph = TRUE;
982//}
983
984/*! write bullet or enum item */
985void RTFGenerator::startItemListItem()
986{
987 DBG_RTF(t << "{\\comment (startItemListItem)}" << endl)
988 newParagraph();
989 t << rtf_Style_Reset;
990 if (rtf_listItemInfo[m_listLevel].isEnum)
991 {
992 t << rtf_EList_DepthStyle() << endl;
993 t << rtf_listItemInfo[m_listLevel].number << ".\\tab ";
994 rtf_listItemInfo[m_listLevel].number++;
995 }
996 else
997 {
998 t << rtf_BList_DepthStyle() << endl;
999 }
1000 m_omitParagraph = TRUE;
1001}
1002
1003void RTFGenerator::endItemListItem()
1004{
1005 DBG_RTF(t << "{\\comment (endItemListItem)}" << endl)
1006}
1007
1008void RTFGenerator::startIndexItem(const char *,const char *)
1009{
1010 DBG_RTF(t << "{\\comment (startIndexItem)}" << endl)
1011
1012 if (!m_omitParagraph)
1013 {
1014 t << "\\par" << endl;
1015 m_omitParagraph = TRUE;
1016 }
1017}
1018
1019void RTFGenerator::endIndexItem(const char *ref,const char *fn)
1020{
1021 DBG_RTF(t << "{\\comment (endIndexItem)}" << endl)
1022 if (!ref && fn)
1023 {
1024 t << "\\tab ";
1025 writeRTFReference(fn);
1026 t << endl;
1027 }
1028 else
1029 {
1030 t << endl;
1031 }
1032 m_omitParagraph = TRUE;
1033}
1034
1035//void RTFGenerator::writeIndexFileItem(const char *,const char *text)
1036//{
1037// t << "\\item\\contentsline{section}{";
1038// docify(text);
1039// t << "}{\\pageref{" << text << "}}" << endl;
1040//}
1041
1042void RTFGenerator::startHtmlLink(const char *url)
1043{
1044
1045 if (Config_getBool("RTF_HYPERLINKS"))
1046 {
1047 t << "{\\field {\\*\\fldinst { HYPERLINK \\\\l \"";
1048 t << url;
1049 t << "\" }{}";
1050 t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
1051 }
1052 else
1053 {
1054 startTypewriter();
1055 }
1056}
1057
1058void RTFGenerator::endHtmlLink()
1059{
1060 if (Config_getBool("RTF_HYPERLINKS"))
1061 {
1062 t << "}}}" << endl;
1063 }
1064 else
1065 {
1066 endTypewriter();
1067 }
1068}
1069
1070//void RTFGenerator::writeMailLink(const char *url)
1071//{
1072// startTypewriter();
1073// docify(url);
1074// endTypewriter();
1075//}
1076
1077void RTFGenerator::writeStartAnnoItem(const char *,const char *f,
1078 const char *path,const char *name)
1079{
1080 DBG_RTF(t << "{\\comment (writeStartAnnoItem)}" << endl)
1081 t << "{\\b ";
1082 if (path) docify(path);
1083 if (f && Config_getBool("RTF_HYPERLINKS"))
1084 {
1085 t << "{\\field {\\*\\fldinst { HYPERLINK \\\\l \"";
1086 t << rtfFormatBmkStr(f);
1087 t << "\" }{}";
1088 t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
1089
1090 docify(name);
1091
1092 t << "}}}" << endl;
1093 }
1094 else
1095 {
1096 docify(name);
1097 }
1098 t << "} ";
1099}
1100
1101void RTFGenerator::writeEndAnnoItem(const char *name)
1102{
1103 DBG_RTF(t << "{\\comment (writeEndAnnoItem)}" << endl)
1104 if (name)
1105 {
1106 t << "\\tab ";
1107 writeRTFReference(name);
1108 t << endl;
1109 }
1110 else
1111 {
1112 t << endl;
1113 }
1114 newParagraph();
1115}
1116
1117void RTFGenerator::startIndexKey()
1118{
1119 DBG_RTF(t << "{\\comment (startIndexKey)}" << endl)
1120 t << "{\\b ";
1121}
1122
1123void RTFGenerator::endIndexKey()
1124{
1125 DBG_RTF(t << "{\\comment (endIndexKey)}" << endl)
1126}
1127
1128void RTFGenerator::startIndexValue(bool hasBrief)
1129{
1130 DBG_RTF(t << "{\\comment (startIndexValue)}" << endl)
1131 t << " ";
1132 if (hasBrief) t << "(";
1133}
1134
1135void RTFGenerator::endIndexValue(const char *name,bool hasBrief)
1136{
1137 DBG_RTF(t << "{\\comment (endIndexValue)}" << endl)
1138 if (hasBrief) t << ")";
1139 t << "} ";
1140 if (name)
1141 {
1142 t << "\\tab ";
1143 writeRTFReference(name);
1144 t << endl;
1145 }
1146 else
1147 {
1148 t << endl;
1149 }
1150 m_omitParagraph=FALSE;
1151 newParagraph();
1152}
1153
1154void RTFGenerator::startSubsection()
1155{
1156 //beginRTFSubSection();
1157 t <<"\n";
1158 DBG_RTF(t << "{\\comment Begin SubSection}\n")
1159 t << rtf_Style_Reset;
1160 t << rtf_Style["Heading3"]->reference << "\n";
1161}
1162
1163void RTFGenerator::endSubsection()
1164{
1165 newParagraph();
1166 t << rtf_Style_Reset << endl;
1167}
1168
1169void RTFGenerator::startSubsubsection()
1170{
1171 //beginRTFSubSubSection();
1172 t << "\n";
1173 DBG_RTF(t << "{\\comment Begin SubSubSection}\n")
1174 t << "{" << endl;
1175 t << rtf_Style_Reset << rtf_Style["Heading4"]->reference << "\n";
1176}
1177
1178void RTFGenerator::endSubsubsection()
1179{
1180 newParagraph();
1181 t << "}" << endl;
1182}
1183
1184
1185//void RTFGenerator::writeClassLink(const char *,const char *,
1186// const char *,const char *name)
1187//{
1188// t << "{\\bf ";
1189// docify(name);
1190// t << "}";
1191//}
1192
1193//void RTFGenerator::startTable(bool,int colNumbers)
1194//{
1195// DBG_RTF(t << "{\\comment startTable}\n";)
1196// m_numCols=colNumbers;
1197// t << "\\par\n";
1198//}
1199//
1200//void RTFGenerator::endTable(bool hasCaption)
1201//{
1202// DBG_RTF(t << "{\\comment endTable}\n";)
1203// if (!hasCaption)
1204// t << "\n\\pard \\widctlpar\\intbl\\adjustright\n{\\row }\n";
1205// t << "\\pard\n" << endl;
1206//}
1207//
1208//void RTFGenerator::startCaption()
1209//{
1210// DBG_RTF(t << "{\\comment startCaption}\n";)
1211// endTableRow();
1212// t << "\\trowd \\trgaph108\\trleft-108\\trbrdrt\\brdrs\\brdrw10 \\trbrdrl\\brdrs\\brdrw10 \\trbrdrb\\brdrs\\brdrw10 \\trbrdrr\\brdrs\\brdrw10 \\trbrdrh\\brdrs\\brdrw10 \\trbrdrv\\brdrs\\brdrw10" << endl;
1213// 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;
1214// nextTableColumn();
1215//}
1216//
1217//void RTFGenerator::endCaption()
1218//{
1219// DBG_RTF(t << "{\\comment endCaption}\n";)
1220// endTableColumn();
1221// endTableRow();
1222//}
1223//
1224//void RTFGenerator::nextTableRow()
1225//{
1226// DBG_RTF(t << "{\\comment nextTableRow}\n";)
1227// ASSERT(m_numCols>0 && m_numCols<25);
1228// uint columnWidth=rtf_pageWidth/m_numCols;
1229// t << "\\trowd \\trgaph108\\trleft-108\\trbrdrt\\brdrs\\brdrw10 "
1230// "\\trbrdrl\\brdrs\\brdrw10 \\trbrdrb\\brdrs\\brdrw10 "
1231// "\\trbrdrr\\brdrs\\brdrw10 \\trbrdrh\\brdrs\\brdrw10 "
1232// "\\trbrdrv\\brdrs\\brdrw10 "<<endl;
1233// for (int i=0;i<m_numCols;i++)
1234// {
1235// t << "\\clvertalt\\clbrdrt\\brdrs\\brdrw10 \\clbrdrl\\brdrs\\brdrw10 "
1236// "\\clbrdrb\\brdrs\\brdrw10 \\clbrdrr \\brdrs\\brdrw10 \\cltxlrtb "
1237// "\\cellx" << (i*columnWidth) << endl;
1238// }
1239// t << "\\pard \\widctlpar\\intbl\\adjustright\n{";
1240//}
1241//
1242//void RTFGenerator::endTableRow()
1243//{
1244// DBG_RTF(t << "{\\comment endTableRow}\n";)
1245// t << "\n\\pard \\widctlpar\\intbl\\adjustright\n{\\row }\n";
1246//}
1247//
1248//void RTFGenerator::nextTableColumn()
1249//{
1250// DBG_RTF(t << "{\\comment nextTableColumn}\n";)
1251// t << "{ ";
1252//}
1253//
1254//void RTFGenerator::endTableColumn()
1255//{
1256// DBG_RTF(t << "{\\comment endTableColumn}\n";)
1257// t << " \\cell }";
1258//}
1259//
1260void RTFGenerator::startTextLink(const char *f,const char *anchor)
1261{
1262 if (Config_getBool("RTF_HYPERLINKS"))
1263 {
1264 QCString ref;
1265 if (f)
1266 {
1267 ref+=f;
1268 }
1269 if (anchor)
1270 {
1271 ref+='_';
1272 ref+=anchor;
1273 }
1274
1275 t << "{\\field {\\*\\fldinst { HYPERLINK \\\\l \"";
1276 t << rtfFormatBmkStr(ref);
1277 t << "\" }{}";
1278 t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
1279 }
1280}
1281
1282void RTFGenerator::endTextLink()
1283{
1284 if (Config_getBool("RTF_HYPERLINKS"))
1285 {
1286 t << "}}}" << endl;
1287 }
1288}
1289
1290void RTFGenerator::writeObjectLink(const char *ref, const char *f,
1291 const char *anchor, const char *text)
1292{
1293 if (!ref && Config_getBool("RTF_HYPERLINKS"))
1294 {
1295 QCString refName;
1296 if (f)
1297 {
1298 refName+=f;
1299 }
1300 if (anchor)
1301 {
1302 refName+='_';
1303 refName+=anchor;
1304 }
1305
1306 t << "{\\field {\\*\\fldinst { HYPERLINK \\\\l \"";
1307 t << rtfFormatBmkStr(refName);
1308 t << "\" }{}";
1309 t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
1310
1311 docify(text);
1312
1313 t << "}}}" << endl;
1314 }
1315 else
1316 {
1317 startBold();
1318 docify(text);
1319 endBold();
1320 }
1321}
1322
1323void RTFGenerator::startPageRef()
1324{
1325 t << " (";
1326 startEmphasis();
1327}
1328
1329void RTFGenerator::endPageRef(const char *clname, const char *anchor)
1330{
1331 QCString ref;
1332 if (clname)
1333 {
1334 ref+=clname;
1335 }
1336 if (anchor)
1337 {
1338 ref+='_';
1339 ref+=anchor;
1340 }
1341 writeRTFReference(ref);
1342 endEmphasis();
1343 t << ")";
1344}
1345
1346void RTFGenerator::writeCodeLink(const char *ref,const char *f,
1347 const char *anchor,const char *name,
1348 const char *)
1349{
1350 if (!ref && Config_getBool("RTF_HYPERLINKS"))
1351 {
1352 QCString refName;
1353 if (f)
1354 {
1355 refName+=f;
1356 }
1357 if (anchor)
1358 {
1359 refName+='_';
1360 refName+=anchor;
1361 }
1362
1363 t << "{\\field {\\*\\fldinst { HYPERLINK \\\\l \"";
1364 t << rtfFormatBmkStr(refName);
1365 t << "\" }{}";
1366 t << "}{\\fldrslt {\\cs37\\ul\\cf2 ";
1367
1368 codify(name);
1369
1370 t << "}}}" << endl;
1371 }
1372 else
1373 {
1374 codify(name);
1375 }
1376}
1377
1378void RTFGenerator::startTitleHead(const char *)
1379{
1380 DBG_RTF(t <<"{\\comment startTitleHead}" << endl)
1381
1382 // beginRTFSection();
1383 t << rtf_Style_Reset << rtf_Style["Heading2"]->reference << endl;
1384}
1385
1386void RTFGenerator::endTitleHead(const char *fileName,const char *name)
1387{
1388 DBG_RTF(t <<"{\\comment endTitleHead}" << endl)
1389 t << "\\par " << rtf_Style_Reset << endl;
1390 if (name)
1391 {
1392 // make table of contents entry
1393 t << "{\\tc\\tcl2 \\v ";
1394 docify(name);
1395 t << "}" << endl;
1396
1397 // make an index entry
1398 addIndexItem(name,0);
1399
1400 //if (name)
1401 //{
1402 // writeAnchor(0,name);
1403 //}
1404 //
1405 //if (Config_getBool("RTF_HYPERLINKS") && fileName)
1406 //{
1407 writeAnchor(fileName,0);
1408 //}
1409 }
1410}
1411
1412void RTFGenerator::startTitle()
1413{
1414 DBG_RTF(t <<"{\\comment startTitle}" << endl)
1415 if (Config_getBool("COMPACT_RTF"))
1416 beginRTFSection();
1417 else
1418 beginRTFChapter();
1419}
1420
1421void RTFGenerator::startGroupHeader(int extraIndent)
1422{
1423 DBG_RTF(t <<"{\\comment startGroupHeader}" << endl)
1424 //newParagraph();
1425 t << rtf_Style_Reset;
1426 if (extraIndent==2)
1427 {
1428 t << rtf_Style["Heading5"]->reference;
1429 }
1430 else if (extraIndent==1)
1431 {
1432 t << rtf_Style["Heading4"]->reference;
1433 }
1434 else // extraIndent==0
1435 {
1436 t << rtf_Style["Heading3"]->reference;
1437 }
1438 t << endl;
1439}
1440
1441void RTFGenerator::endGroupHeader(int)
1442{
1443 DBG_RTF(t <<"{\\comment endGroupHeader}" << endl)
1444 t << "\\par" << endl;
1445 t << rtf_Style_Reset << endl;
1446}
1447
1448void RTFGenerator::startMemberDoc(const char *clname,
1449 const char *memname,
1450 const char *,
1451 const char *,
1452 bool showInline)
1453{
1454 DBG_RTF(t << "{\\comment startMemberDoc}" << endl)
1455 if (memname && memname[0]!='@')
1456 {
1457 addIndexItem(memname,clname);
1458 addIndexItem(clname,memname);
1459 }
1460 t << rtf_Style_Reset << rtf_Style[showInline ? "Heading5" : "Heading4"]->reference;
1461 //styleStack.push(rtf_Style_Heading4);
1462 t << "{" << endl;
1463 //printf("RTFGenerator::startMemberDoc() `%s'\n",rtf_Style["Heading4"]->reference);
1464 startBold();
1465 t << endl;
1466}
1467
1468void RTFGenerator::endMemberDoc(bool)
1469{
1470 DBG_RTF(t << "{\\comment endMemberDoc}" << endl)
1471 //const char *style = styleStack.pop();
1472 //printf("RTFGenerator::endMemberDoc() `%s'\n",style);
1473 //ASSERT(style==rtf_Style["Heading4"]->reference);
1474 endBold();
1475 t << "}" << endl;
1476 newParagraph();
1477}
1478
1479void RTFGenerator::startDoxyAnchor(const char *,const char *,
1480 const char *,const char *,
1481 const char *
1482 )
1483{
1484 DBG_RTF(t << "{\\comment startDoxyAnchor}" << endl)
1485}
1486
1487void RTFGenerator::endDoxyAnchor(const char *fName,const char *anchor)
1488{
1489 QCString ref;
1490 if (fName)
1491 {
1492 ref+=fName;
1493 }
1494 if (anchor)
1495 {
1496 ref+='_';
1497 ref+=anchor;
1498 }
1499
1500 DBG_RTF(t << "{\\comment endDoxyAnchor}" << endl)
1501 t << "{\\bkmkstart ";
1502 t << rtfFormatBmkStr(ref);
1503 t << "}" << endl;
1504 t << "{\\bkmkend ";
1505 t << rtfFormatBmkStr(ref);
1506 t << "}" << endl;
1507}
1508
1509
1510//void RTFGenerator::writeLatexLabel(const char *clName,const char *anchor)
1511//{
1512// writeDoxyAnchor(0,clName,anchor,0);
1513//}
1514
1515void RTFGenerator::addIndexItem(const char *s1,const char *s2)
1516{
1517 if (s1)
1518 {
1519 t << "{\\xe \\v ";
1520 docify(s1);
1521 if (s2)
1522 {
1523 t << "\\:";
1524 docify(s2);
1525 }
1526 t << "}" << endl;
1527 }
1528}
1529
1530void RTFGenerator::startIndent()
1531{
1532 incrementIndentLevel();
1533 DBG_RTF(t << "{\\comment (startIndent) }" << endl)
1534 t << "{" << endl;
1535 t << rtf_Style_Reset << rtf_CList_DepthStyle() << endl;
1536}
1537
1538void RTFGenerator::endIndent()
1539{
1540 t << "}" << endl;
1541 decrementIndentLevel();
1542}
1543
1544
1545void RTFGenerator::startDescription()
1546{
1547 DBG_RTF(t << "{\\comment (startDescription)}" << endl)
1548 t << "{" << endl;
1549 t << rtf_Style_Reset << rtf_DList_DepthStyle();
1550}
1551
1552void RTFGenerator::endDescription()
1553{
1554 DBG_RTF(t << "{\\comment (endDescription)}" << endl)
1555 newParagraph();
1556 t << "}";
1557}
1558
1559void RTFGenerator::startDescItem()
1560{
1561 newParagraph();
1562 DBG_RTF(t << "{\\comment (startDescItem)}" << endl)
1563 t << "{\\b ";
1564}
1565
1566void RTFGenerator::endDescItem()
1567{
1568 DBG_RTF(t << "{\\comment (endDescItem)}" << endl)
1569 t << "}" << endl;
1570 newParagraph();
1571}
1572
1573void RTFGenerator::startMemberDescription()
1574{
1575 DBG_RTF(t << "{\\comment (startMemberDescription)}" << endl)
1576 t << "{" << endl;
1577 incrementIndentLevel();
1578 t << rtf_Style_Reset << rtf_CList_DepthStyle();
1579 startEmphasis();
1580}
1581
1582void RTFGenerator::endMemberDescription()
1583{
1584 DBG_RTF(t << "{\\comment (endMemberDescription)}" << endl)
1585 endEmphasis();
1586 newParagraph();
1587 decrementIndentLevel();
1588 //t << "\\par";
1589 t << "}" << endl;
1590 //m_omitParagraph = TRUE;
1591}
1592
1593void RTFGenerator::startDescList(SectionTypes)
1594{
1595 DBG_RTF(t << "{\\comment (startDescList)}" << endl)
1596 t << "{"; // ends at endDescList
1597 t << "{"; // ends at endDescTitle
1598 startBold();
1599 newParagraph();
1600}
1601
1602//void RTFGenerator::endDescTitle()
1603//{
1604// DBG_RTF(t << "{\\comment (endDescTitle) }" << endl)
1605// endBold();
1606// t << "}";
1607// newParagraph();
1608// incrementIndentLevel();
1609// t << rtf_Style_Reset << rtf_DList_DepthStyle();
1610//}
1611
1612void RTFGenerator::startDescForItem()
1613{
1614 DBG_RTF(t << "{\\comment (startDescForItem) }" << endl)
1615}
1616
1617void RTFGenerator::endDescForItem()
1618{
1619 DBG_RTF(t << "{\\comment (endDescForItem) }" << endl)
1620}
1621
1622//void RTFGenerator::endDescList()
1623//{
1624// DBG_RTF(t << "{\\comment (endDescList)}" << endl)
1625// newParagraph();
1626// decrementIndentLevel();
1627// m_omitParagraph = TRUE;
1628// t << "}";
1629//}
1630
1631
1632void RTFGenerator::startSection(const char *,const char *title,SectionInfo::SectionType type)
1633{
1634 DBG_RTF(t << "{\\comment (startSection)}" << endl)
1635 t << "{";
1636 t<< rtf_Style_Reset;
1637 int num=4;
1638 switch(type)
1639 {
1640 case SectionInfo::Page: num=2; break;
1641 case SectionInfo::Section: num=3; break;
1642 case SectionInfo::Subsection: num=4; break;
1643 case SectionInfo::Subsubsection: num=4; break;
1644 case SectionInfo::Paragraph: num=4; break;
1645 default: ASSERT(0); break;
1646 }
1647 QCString heading;
1648 heading.sprintf("Heading%d",num);
1649 // set style
1650 t << rtf_Style[heading]->reference;
1651 // make table of contents entry
1652 t << "{\\tc\\tcl" << num << " \\v ";
1653 docify(title);
1654 t << "}" << endl;
1655}
1656
1657void RTFGenerator::endSection(const char *lab,SectionInfo::SectionType)
1658{
1659 DBG_RTF(t << "{\\comment (endSection)}" << endl)
1660 // make bookmark
1661 m_omitParagraph=FALSE;
1662 newParagraph();
1663 writeAnchor(0,lab);
1664 t << "}";
1665}
1666
1667//void RTFGenerator::writeSectionRef(const char *ref,const char *,
1668// const char *lab,const char *title)
1669//{
1670// if (ref)
1671// {
1672// docify(title);
1673// }
1674// else
1675// {
1676// startBold();
1677// docify(title);
1678// endBold();
1679// t << " (";
1680// docify(theTranslator->trPageAbbreviation());
1681// writeRTFReference(lab);
1682// t << ")" << endl;
1683// }
1684//}
1685//
1686//void RTFGenerator::writeSectionRefItem(const char *,const char *lab,
1687// const char *title)
1688//{
1689// docify(title);
1690// t << "\\tab";
1691// writeRTFReference(lab);
1692// t << endl;
1693//}
1694//
1695//void RTFGenerator::writeSectionRefAnchor(const char *name,const char *lab,
1696// const char *title)
1697//{
1698// writeSectionRef(name,lab,title);
1699//}
1700
1701//char* RTFGenerator::getMultiByte(int c)
1702//{
1703// static char s[10];
1704//
1705// sprintf(s,"\\'%X",c);
1706// return s;
1707//}
1708
1709void RTFGenerator::docify(const char *str)
1710{
1711 if (str)
1712 {
1713 const unsigned char *p=(const unsigned char *)str;
1714 unsigned char c;
1715 unsigned char pc='\0';
1716 while (*p)
1717 {
1718 //static bool MultiByte = FALSE;
1719 c=*p++;
1720
1721#if 0
1722 if ( MultiByte )
1723 {
1724 t << getMultiByte( c );
1725 MultiByte = FALSE;
1726 continue;
1727 }
1728 if ( c >= 0x80 )
1729 {
1730 MultiByte = TRUE;
1731 t << getMultiByte( c );
1732 continue;
1733 }
1734#endif
1735
1736 switch (c)
1737 {
1738 case '{': t << "\\{"; break;
1739 case '}': t << "\\}"; break;
1740 case '\\': t << "\\\\"; break;
1741 default:
1742 {
1743 // see if we can insert an hyphenation hint
1744 //if (isupper(c) && islower(pc) && !insideTabbing) t << "\\-";
1745 t << (char)c;
1746 }
1747 }
1748 pc = c;
1749 m_omitParagraph = FALSE;
1750 }
1751 }
1752}
1753
1754void RTFGenerator::codify(const char *str)
1755{
1756 // note that RTF does not have a "verbatim", so "\n" means
1757 // nothing... add a "newParagraph()";
1758 //static char spaces[]=" ";
1759 if (str)
1760 {
1761 const unsigned char *p=(const unsigned char *)str;
1762 unsigned char c;
1763 int spacesToNextTabStop;
1764
1765 while (*p)
1766 {
1767 //static bool MultiByte = FALSE;
1768
1769 c=*p++;
1770
1771#if 0
1772 if( MultiByte )
1773 {
1774 t << getMultiByte( c );
1775 MultiByte = FALSE;
1776 continue;
1777 }
1778 if( c >= 0x80 )
1779 {
1780 MultiByte = TRUE;
1781 t << getMultiByte( c );
1782 continue;
1783 }
1784#endif
1785
1786 switch(c)
1787 {
1788 case '\t': spacesToNextTabStop = Config_getInt("TAB_SIZE") - (col%Config_getInt("TAB_SIZE"));
1789 t << Doxygen::spaces.left(spacesToNextTabStop);
1790 col+=spacesToNextTabStop;
1791 break;
1792 case '\n': newParagraph();
1793 t << '\n'; col=0;
1794 break;
1795 case '{': t << "\\{"; col++; break;
1796 case '}': t << "\\}"; col++; break;
1797 case '\\': t << "\\\\"; col++; break;
1798 default: t << (char)c; col++; break;
1799 }
1800 }
1801 }
1802}
1803
1804void RTFGenerator::writeChar(char c)
1805{
1806 char cs[2];
1807 cs[0]=c;
1808 cs[1]=0;
1809 docify(cs);
1810}
1811
1812void RTFGenerator::startClassDiagram()
1813{
1814 DBG_RTF(t <<"{\\comment startClassDiagram }" << endl)
1815}
1816
1817void RTFGenerator::endClassDiagram(const ClassDiagram &d,
1818 const char *fileName,const char *)
1819{
1820 newParagraph();
1821
1822 // create a png file
1823 d.writeImage(t,dir,relPath,fileName,FALSE);
1824
1825 // display the file
1826 t << "{" << endl;
1827 t << rtf_Style_Reset << endl;
1828 t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
1829 t << fileName << ".png\"";
1830 t << " \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
1831 t << "}" << endl;
1832}
1833
1834//void RTFGenerator::writeFormula(const char *,const char *text)
1835//{
1836// t << text;
1837//}
1838
1839void RTFGenerator::startMemberItem(int)
1840{
1841 DBG_RTF(t <<"{\\comment startMemberItem }" << endl)
1842 t << rtf_Style_Reset << rtf_BList_DepthStyle() << endl; // set style to apropriate depth
1843}
1844
1845void RTFGenerator::endMemberItem()
1846{
1847 DBG_RTF(t <<"{\\comment endMemberItem }" << endl)
1848 newParagraph();
1849}
1850
1851void RTFGenerator::writeAnchor(const char *fileName,const char *name)
1852{
1853 QCString anchor;
1854 if (fileName)
1855 {
1856 anchor+=fileName;
1857 }
1858 if (fileName && name)
1859 {
1860 anchor+='_';
1861 }
1862 if (name)
1863 {
1864 anchor+=name;
1865 }
1866
1867 DBG_RTF(t <<"{\\comment writeAnchor (" << anchor << ")}" << endl)
1868 t << "{\\bkmkstart " << rtfFormatBmkStr(anchor) << "}" << endl;
1869 t << "{\\bkmkend " << rtfFormatBmkStr(anchor) << "}" << endl;
1870}
1871
1872void RTFGenerator::writeRTFReference(const char *label)
1873{
1874 t << "{\\field\\fldedit {\\*\\fldinst PAGEREF ";
1875 t << rtfFormatBmkStr(label);
1876 t << " \\\\*MERGEFORMAT}{\\fldrslt pagenum}}";
1877}
1878
1879void RTFGenerator::startCodeFragment()
1880{
1881 DBG_RTF(t << "{\\comment (startCodeFragment) }" << endl)
1882 t << "{" << endl;
1883 //newParagraph();
1884 t << rtf_Style_Reset << rtf_Code_DepthStyle();
1885 //styleStack.push(rtf_Style_CodeExample);
1886}
1887
1888void RTFGenerator::endCodeFragment()
1889{
1890 //newParagraph();
1891 //styleStack.pop();
1892 //printf("RTFGenerator::endCodeFrament() top=%s\n",styleStack.top());
1893 //t << rtf_Style_Reset << styleStack.top() << endl;
1894 DBG_RTF(t << "{\\comment (endCodeFragment) }" << endl)
1895 t << "}" << endl;
1896 m_omitParagraph = TRUE;
1897}
1898
1899void RTFGenerator::writeNonBreakableSpace(int)
1900{
1901 t << "\\~ ";
1902}
1903
1904
1905void RTFGenerator::startMemberList()
1906{
1907 t << endl;
1908 DBG_RTF(t << "{\\comment (startMemberList) }" << endl)
1909 t << "{" << endl;
1910#ifdef DELETEDCODE
1911 if (!insideTabbing)
1912 t << "\\begin{CompactItemize}" << endl;
1913#endif
1914}
1915
1916void RTFGenerator::endMemberList()
1917{
1918 DBG_RTF(t << "{\\comment (endMemberList) }" << endl)
1919 t << "}" << endl;
1920#ifdef DELETEDCODE
1921 if (!insideTabbing)
1922 t << "\\end{CompactItemize}" << endl;
1923#endif
1924}
1925
1926//void RTFGenerator::startImage(const char *name,const char *,bool)
1927//{
1928// newParagraph();
1929// t << "{" << endl;
1930// t << rtf_Style_Reset << endl;
1931// t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE ";
1932// t << name;
1933// t << " \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
1934// t << "}" << endl;
1935//}
1936//
1937//void RTFGenerator::endImage(bool)
1938//{
1939// // not yet implemented
1940//}
1941//
1942//void RTFGenerator::startDotFile(const char *name,bool)
1943//{
1944// QCString baseName=name;
1945// int i;
1946// if ((i=baseName.findRev('/'))!=-1 || (i=baseName.findRev('\\'))!=-1)
1947// {
1948// baseName=baseName.right(baseName.length()-i-1);
1949// }
1950// QCString outDir = Config_getString("RTF_OUTPUT");
1951// writeDotGraphFromFile(name,outDir,baseName,BITMAP);
1952// newParagraph();
1953// t << "{" << endl;
1954// t << rtf_Style_Reset << endl;
1955// t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE ";
1956// t << outDir << "\\" << baseName;
1957// t << " \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
1958// t << "}" << endl;
1959//}
1960//
1961//void RTFGenerator::endDotFile(bool)
1962//{
1963// // not yet implemented
1964//}
1965//
1966void RTFGenerator::startDescTable()
1967{
1968 DBG_RTF(t << "{\\comment (startDescTable) }" << endl)
1969 //t << "{" << endl;
1970 //incrementIndentLevel();
1971 //t << rtf_Style_Reset << rtf_CList_DepthStyle();
1972}
1973
1974void RTFGenerator::endDescTable()
1975{
1976 //decrementIndentLevel();
1977 DBG_RTF(t << "{\\comment (endDescTable)}" << endl)
1978 //t << "}" << endl;
1979 //t << rtf_Style_Reset << styleStack.top();
1980}
1981
1982void RTFGenerator::startDescTableTitle()
1983{
1984 //t << rtf_BList_DepthStyle() << endl;
1985 DBG_RTF(t << "{\\comment (startDescTableTitle) }" << endl)
1986 startBold();
1987 startEmphasis();
1988}
1989
1990void RTFGenerator::endDescTableTitle()
1991{
1992 DBG_RTF(t << "{\\comment (endDescTableTitle) }" << endl)
1993 endEmphasis();
1994 endBold();
1995 t << " ";
1996}
1997
1998void RTFGenerator::startDescTableData()
1999{
2000 DBG_RTF(t << "{\\comment (startDescTableData) }" << endl)
2001 m_omitParagraph = FALSE;
2002}
2003
2004void RTFGenerator::endDescTableData()
2005{
2006 DBG_RTF(t << "{\\comment (endDescTableData) }" << endl)
2007 newParagraph();
2008 m_omitParagraph = TRUE;
2009}
2010
2011// a style for list formatted as a "bulleted list"
2012
2013void RTFGenerator::incrementIndentLevel()
2014{
2015 m_listLevel++;
2016 if (m_listLevel>rtf_maxIndentLevels-1)
2017 {
2018 err("error: Maximum indent level (%d) exceeded while generating RTF output!\n",rtf_maxIndentLevels);
2019 m_listLevel=rtf_maxIndentLevels-1;
2020 }
2021}
2022
2023void RTFGenerator::decrementIndentLevel()
2024{
2025 m_listLevel--;
2026 if (m_listLevel<0)
2027 {
2028 err("error: Negative indent level while generating RTF output!\n");
2029 m_listLevel=0;
2030 }
2031}
2032
2033// a style for list formatted with "list continue" style
2034const char * RTFGenerator::rtf_CList_DepthStyle()
2035{
2036 QCString n=makeIndexName("ListContinue",m_listLevel);
2037 return rtf_Style[n]->reference;
2038}
2039
2040// a style for list formatted as a "latext style" table of contents
2041const char * RTFGenerator::rtf_LCList_DepthStyle()
2042{
2043 QCString n=makeIndexName("LatexTOC",m_listLevel);
2044 return rtf_Style[n]->reference;
2045}
2046
2047// a style for list formatted as a "bullet" style
2048const char * RTFGenerator::rtf_BList_DepthStyle()
2049{
2050 QCString n=makeIndexName("ListBullet",m_listLevel);
2051 return rtf_Style[n]->reference;
2052}
2053
2054// a style for list formatted as a "enumeration" style
2055const char * RTFGenerator::rtf_EList_DepthStyle()
2056{
2057 QCString n=makeIndexName("ListEnum",m_listLevel);
2058 return rtf_Style[n]->reference;
2059}
2060
2061const char * RTFGenerator::rtf_DList_DepthStyle()
2062{
2063 QCString n=makeIndexName("DescContinue",m_listLevel);
2064 return rtf_Style[n]->reference;
2065}
2066
2067const char * RTFGenerator::rtf_Code_DepthStyle()
2068{
2069 QCString n=makeIndexName("CodeExample",m_listLevel);
2070 return rtf_Style[n]->reference;
2071}
2072
2073void RTFGenerator::startTextBlock(bool dense)
2074{
2075 DBG_RTF(t << "{\\comment startTextBlock}" << endl)
2076 t << "{" << endl;
2077 t << rtf_Style_Reset;
2078 if (dense) // no spacing between "paragraphs"
2079 {
2080 t << rtf_Style["DenseText"]->reference;
2081 }
2082 else // some spacing
2083 {
2084 t << rtf_Style["BodyText"]->reference;
2085 }
2086}
2087
2088void RTFGenerator::endTextBlock(bool /*paraBreak*/)
2089{
2090 newParagraph();
2091 DBG_RTF(t << "{\\comment endTextBlock}" << endl)
2092 t << "}" << endl;
2093 //m_omitParagraph = TRUE;
2094}
2095
2096void RTFGenerator::newParagraph()
2097{
2098 if (!m_omitParagraph)
2099 {
2100 DBG_RTF(t << "{\\comment (newParagraph)}" << endl)
2101 t << "\\par" << endl;
2102 }
2103 m_omitParagraph = FALSE;
2104}
2105
2106void RTFGenerator::startParagraph()
2107{
2108 DBG_RTF(t << "{\\comment startParagraph}" << endl)
2109 newParagraph();
2110 t << "{" << endl;
2111}
2112
2113void RTFGenerator::endParagraph()
2114{
2115 DBG_RTF(t << "{\\comment endParagraph}" << endl)
2116 t << "}\\par" << endl;
2117 m_omitParagraph = TRUE;
2118}
2119
2120void RTFGenerator::startMemberSubtitle()
2121{
2122 DBG_RTF(t << "{\\comment startMemberSubtitle}" << endl)
2123 t << "{" << endl;
2124 t << rtf_Style_Reset << rtf_CList_DepthStyle() << endl;
2125}
2126
2127void RTFGenerator::endMemberSubtitle()
2128{
2129 DBG_RTF(t << "{\\comment endMemberSubtitle}" << endl)
2130 newParagraph();
2131 t << "}" << endl;
2132}
2133
2134//void RTFGenerator::writeUmlaut(char c)
2135//{
2136// switch(c)
2137// {
2138// case 'A' : t << '\304'; break;
2139// case 'E' : t << '\313'; break;
2140// case 'I' : t << '\317'; break;
2141// case 'O' : t << '\326'; break;
2142// case 'U' : t << '\334'; break;
2143// case 'Y' : t << 'Y'; break;
2144// case 'a' : t << '\344'; break;
2145// case 'e' : t << '\353'; break;
2146// case 'i' : t << '\357'; break;
2147// case 'o' : t << '\366'; break;
2148// case 'u' : t << '\374'; break;
2149// case 'y' : t << '\377'; break;
2150// default: t << '?'; break;
2151// }
2152//}
2153//
2154//void RTFGenerator::writeAcute(char c)
2155//{
2156// switch(c)
2157// {
2158// case 'A' : t << '\301'; break;
2159// case 'E' : t << '\311'; break;
2160// case 'I' : t << '\315'; break;
2161// case 'O' : t << '\323'; break;
2162// case 'U' : t << '\332'; break;
2163// case 'Y' : t << '\335'; break;
2164// case 'a' : t << '\341'; break;
2165// case 'e' : t << '\351'; break;
2166// case 'i' : t << '\355'; break;
2167// case 'o' : t << '\363'; break;
2168// case 'u' : t << '\372'; break;
2169// case 'y' : t << '\375'; break;
2170// default: t << '?'; break;
2171// }
2172//}
2173//
2174//void RTFGenerator::writeGrave(char c)
2175//{
2176// switch(c)
2177// {
2178// case 'A' : t << '\300'; break;
2179// case 'E' : t << '\310'; break;
2180// case 'I' : t << '\314'; break;
2181// case 'O' : t << '\322'; break;
2182// case 'U' : t << '\331'; break;
2183// case 'a' : t << '\340'; break;
2184// case 'e' : t << '\350'; break;
2185// case 'i' : t << '\354'; break;
2186// case 'o' : t << '\362'; break;
2187// case 'u' : t << '\371'; break;
2188// default: t << '?'; break;
2189// }
2190//}
2191//
2192//void RTFGenerator::writeCirc(char c)
2193//{
2194// switch(c)
2195// {
2196// case 'A' : t << '\302'; break;
2197// case 'E' : t << '\312'; break;
2198// case 'I' : t << '\316'; break;
2199// case 'O' : t << '\324'; break;
2200// case 'U' : t << '\333'; break;
2201// case 'a' : t << '\342'; break;
2202// case 'e' : t << '\352'; break;
2203// case 'i' : t << '\356'; break;
2204// case 'o' : t << '\364'; break;
2205// case 'u' : t << '\373'; break;
2206// default: t << '?'; break;
2207// }
2208//}
2209//
2210//void RTFGenerator::writeTilde(char c)
2211//{
2212// switch(c)
2213// {
2214// case 'A' : t << '\303'; break;
2215// case 'N' : t << '\321'; break;
2216// case 'O' : t << '\325'; break;
2217// case 'a' : t << '\343'; break;
2218// case 'n' : t << '\361'; break;
2219// case 'o' : t << '\365'; break;
2220// default: t << '?'; break;
2221// }
2222//}
2223//
2224//void RTFGenerator::writeRing(char c)
2225//{
2226// switch(c)
2227// {
2228// case 'A' : t << '\305'; break;
2229// case 'a' : t << '\345'; break;
2230// default: t << '?'; break;
2231// }
2232//}
2233//
2234//void RTFGenerator::writeCCedil(char c)
2235//{
2236// switch(c)
2237// {
2238// case 'C' : t << '\307'; break;
2239// case 'c' : t << '\347'; break;
2240// default: t << '?'; break;
2241// }
2242//}
2243//
2244
2245// note: function is not reentrant!
2246static void encodeForOutput(FTextStream &t,const QCString &s)
2247{
2248 QCString encoding;
2249 bool converted=FALSE;
2250 int l = s.length();
2251 static QByteArray enc;
2252 if (l*4>(int)enc.size()) enc.resize(l*4); // worst case
2253 encoding.sprintf("CP%s",theTranslator->trRTFansicp().data());
2254 if (!encoding.isEmpty())
2255 {
2256 // convert from UTF-8 back to the output encoding
2257 void *cd = portable_iconv_open(encoding,"UTF-8");
2258 if (cd!=(void *)(-1))
2259 {
2260 size_t iLeft=l;
2261 size_t oLeft=enc.size();
2262 const char *inputPtr = s.data();
2263 char *outputPtr = enc.data();
2264 if (!portable_iconv(cd, &inputPtr, &iLeft, &outputPtr, &oLeft))
2265 {
2266 enc.resize(enc.size()-oLeft);
2267 converted=TRUE;
2268 }
2269 portable_iconv_close(cd);
2270 }
2271 }
2272 if (!converted) // if we did not convert anything, copy as is.
2273 {
2274 memcpy(enc.data(),s.data(),l);
2275 enc.resize(l);
2276 }
2277 uint i;
2278 for (i=0;i<enc.size();i++)
2279 {
2280 uchar c = (uchar)enc.at(i);
2281 if (c>=0x80)
2282 {
2283 char esc[10];
2284 sprintf(esc,"\\'%X",c);
2285 t << esc;
2286 }
2287 else
2288 {
2289 t << (char)c;
2290 }
2291 }
2292}
2293
2294/**
2295 * VERY brittle routine inline RTF's included by other RTF's.
2296 * it is recursive and ugly.
2297 */
2298static bool preProcessFile(QDir &d,QCString &infName, FTextStream &t, bool bIncludeHeader=TRUE)
2299{
2300 QFile f(infName);
2301 if (!f.open(IO_ReadOnly))
2302 {
2303 err("error: problems opening rtf file %s for reading\n",infName.data());
2304 return FALSE;
2305 }
2306
2307 const int maxLineLength = 10240;
2308 static QCString lineBuf(maxLineLength);
2309
2310 // scan until find end of header
2311 // this is EXTREEEEEEEMLY brittle. It works on OUR rtf
2312 // files because the first line before the body
2313 // ALWAYS contains "{\comment begin body}"
2314 do
2315 {
2316 if (f.readLine(lineBuf.data(),maxLineLength)==-1)
2317 {
2318 err("ERROR - read error in %s before end of RTF header!\n",infName.data());
2319 return FALSE;
2320 }
2321 if (bIncludeHeader) encodeForOutput(t,lineBuf);
2322 } while (lineBuf.find("\\comment begin body")==-1);
2323
2324
2325 while (f.readLine(lineBuf.data(),maxLineLength)!=-1)
2326 {
2327 int pos;
2328 if ((pos=lineBuf.find("INCLUDETEXT"))!=-1)
2329 {
2330 int startNamePos = lineBuf.find('"',pos)+1;
2331 int endNamePos = lineBuf.find('"',startNamePos);
2332 QCString fileName = lineBuf.mid(startNamePos,endNamePos-startNamePos);
2333 DBG_RTF(t << "{\\comment begin include " << fileName << "}" << endl)
2334 if (!preProcessFile(d,fileName,t,FALSE)) return FALSE;
2335 DBG_RTF(t << "{\\comment end include " << fileName << "}" << endl)
2336 }
2337 else // no INCLUDETEXT on this line
2338 {
2339 // elaborate hoopla to skip the final "}" if we didn't include the
2340 // headers
2341 if (!f.atEnd() || bIncludeHeader)
2342 {
2343 encodeForOutput(t,lineBuf);
2344 }
2345 else // last line of included file
2346 {
2347 // null terminate at the last '}'
2348 //char *str = strrchr(buffer,'}');
2349 int pos = lineBuf.findRev('}');
2350
2351 if (pos != -1)
2352 lineBuf.at(pos) = '\0';
2353 else
2354 err("Strange, the last char was not a '}'\n");
2355 encodeForOutput(t,lineBuf);
2356 }
2357 }
2358 }
2359 f.close();
2360 // remove temporary file
2361 d.remove(infName);
2362 return TRUE;
2363}
2364
2365void RTFGenerator::startDotGraph()
2366{
2367 DBG_RTF(t << "{\\comment (startDotGraph)}" << endl)
2368}
2369
2370void RTFGenerator::endDotGraph(const DotClassGraph &g)
2371{
2372 newParagraph();
2373
2374 QCString fileName =
2375 g.writeGraph(t,BITMAP,Config_getString("RTF_OUTPUT"),fileName,relPath,TRUE,FALSE);
2376
2377 // display the file
2378 t << "{" << endl;
2379 t << rtf_Style_Reset << endl;
2380 t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
2381 t << fileName << "." << Config_getEnum("DOT_IMAGE_FORMAT");
2382 t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
2383 t << "}" << endl;
2384 newParagraph();
2385 DBG_RTF(t << "{\\comment (endDotGraph)}" << endl)
2386}
2387
2388void RTFGenerator::startInclDepGraph()
2389{
2390 DBG_RTF(t << "{\\comment (startInclDepGraph)}" << endl)
2391}
2392
2393void RTFGenerator::endInclDepGraph(const DotInclDepGraph &g)
2394{
2395 newParagraph();
2396
2397 QCString fn = g.writeGraph(t,BITMAP,Config_getString("RTF_OUTPUT"),
2398 fileName,relPath,FALSE);
2399
2400 // display the file
2401 t << "{" << endl;
2402 t << rtf_Style_Reset << endl;
2403 t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
2404 t << fn << "." << Config_getEnum("DOT_IMAGE_FORMAT");
2405 t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
2406 t << "}" << endl;
2407 DBG_RTF(t << "{\\comment (endInclDepGraph)}" << endl)
2408}
2409
2410void RTFGenerator::startGroupCollaboration()
2411{
2412}
2413
2414void RTFGenerator::endGroupCollaboration(const DotGroupCollaboration &)
2415{
2416}
2417
2418void RTFGenerator::startCallGraph()
2419{
2420 DBG_RTF(t << "{\\comment (startCallGraph)}" << endl)
2421}
2422
2423void RTFGenerator::endCallGraph(const DotCallGraph &g)
2424{
2425 newParagraph();
2426
2427 QCString fn = g.writeGraph(t,BITMAP,Config_getString("RTF_OUTPUT"),
2428 fileName,relPath,FALSE);
2429
2430 // display the file
2431 t << "{" << endl;
2432 t << rtf_Style_Reset << endl;
2433 t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
2434 t << fn << "." << Config_getEnum("DOT_IMAGE_FORMAT");
2435 t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
2436 t << "}" << endl;
2437 DBG_RTF(t << "{\\comment (endCallGraph)}" << endl)
2438}
2439
2440void RTFGenerator::startDirDepGraph()
2441{
2442 DBG_RTF(t << "{\\comment (startDirDepGraph)}" << endl)
2443}
2444
2445void RTFGenerator::endDirDepGraph(const DotDirDeps &g)
2446{
2447 newParagraph();
2448
2449 QCString fileName = g.writeGraph(t,BITMAP,Config_getString("RTF_OUTPUT"),
2450 fileName,relPath,FALSE);
2451
2452 // display the file
2453 t << "{" << endl;
2454 t << rtf_Style_Reset << endl;
2455 t << "\\par\\pard \\qc {\\field\\flddirty {\\*\\fldinst INCLUDEPICTURE \"";
2456 t << fileName << "." << Config_getEnum("DOT_IMAGE_FORMAT");
2457 t << "\" \\\\d \\\\*MERGEFORMAT}{\\fldrslt IMAGE}}\\par" << endl;
2458 t << "}" << endl;
2459 DBG_RTF(t << "{\\comment (endDirDepGraph)}" << endl)
2460}
2461
2462/** Tests the integrity of the result by counting brackets.
2463 *
2464 */
2465void testRTFOutput(const char *name)
2466{
2467 int bcount=0;
2468 int line=1;
2469 int c;
2470 QFile f(name);
2471 if (f.open(IO_ReadOnly))
2472 {
2473 while ((c=f.getch())!=-1)
2474 {
2475 if (c=='\\') // escape char
2476 {
2477 c=f.getch();
2478 if (c==-1) break;
2479 }
2480 else if (c=='{') // open bracket
2481 {
2482 bcount++;
2483 }
2484 else if (c=='}') // close bracket
2485 {
2486 bcount--;
2487 if (bcount<0)
2488 {
2489 goto err;
2490 break;
2491 }
2492 }
2493 else if (c=='\n') // newline
2494 {
2495 line++;
2496 }
2497 }
2498 }
2499 if (bcount==0) return; // file is OK.
2500err:
2501 err("error: RTF integrity test failed at line %d of %s due to a bracket mismatch.\n",line,name);
2502 err(" Please try to create a small code example that produces this error \n"
2503 " and send that to dimitri@stack.nl.\n");
2504}
2505
2506/**
2507 * This is an API to a VERY brittle RTF preprocessor that combines nested
2508 * RTF files. This version replaces the infile with the new file
2509 */
2510bool RTFGenerator::preProcessFileInplace(const char *path,const char *name)
2511{
2512 QDir d(path);
2513 // store the original directory
2514 if (!d.exists())
2515 {
2516 err("error: Output dir %s does not exist!\n",path);
2517 return FALSE;
2518 }
2519 QCString oldDir = convertToQCString(QDir::currentDirPath());
2520
2521 // go to the html output directory (i.e. path)
2522 QDir::setCurrent(d.absPath());
2523 QDir thisDir;
2524
2525 QCString combinedName = (QCString)path+"/combined.rtf";
2526 QCString mainRTFName = (QCString)path+"/"+name;
2527
2528 QFile outf(combinedName);
2529 if (!outf.open(IO_WriteOnly))
2530 {
2531 err("Failed to open %s for writing!\n",combinedName.data());
2532 return FALSE;
2533 }
2534 FTextStream outt(&outf);
2535
2536 if (!preProcessFile(thisDir,mainRTFName,outt))
2537 {
2538 // it failed, remove the temp file
2539 outf.close();
2540 thisDir.remove(combinedName);
2541 QDir::setCurrent(oldDir);
2542 return FALSE;
2543 }
2544
2545 // everything worked, move the files
2546 outf.close();
2547 thisDir.remove(mainRTFName);
2548 thisDir.rename(combinedName,mainRTFName);
2549
2550 testRTFOutput(mainRTFName);
2551
2552 QDir::setCurrent(oldDir);
2553 return TRUE;
2554}
2555
2556void RTFGenerator::startMemberGroupHeader(bool hasHeader)
2557{
2558 DBG_RTF(t << "{\\comment startMemberGroupHeader}" << endl)
2559 t << "{" << endl;
2560 if (hasHeader) incrementIndentLevel();
2561 t << rtf_Style_Reset << rtf_Style["GroupHeader"]->reference;
2562}
2563
2564void RTFGenerator::endMemberGroupHeader()
2565{
2566 DBG_RTF(t << "{\\comment endMemberGroupHeader}" << endl)
2567 newParagraph();
2568 t << rtf_Style_Reset << rtf_CList_DepthStyle();
2569}
2570
2571void RTFGenerator::startMemberGroupDocs()
2572{
2573 DBG_RTF(t << "{\\comment startMemberGroupDocs}" << endl)
2574 startEmphasis();
2575}
2576
2577void RTFGenerator::endMemberGroupDocs()
2578{
2579 DBG_RTF(t << "{\\comment endMemberGroupDocs}" << endl)
2580 endEmphasis();
2581 newParagraph();
2582}
2583
2584void RTFGenerator::startMemberGroup()
2585{
2586 DBG_RTF(t << "{\\comment startMemberGroup}" << endl)
2587 t << rtf_Style_Reset << rtf_BList_DepthStyle() << endl;
2588}
2589
2590void RTFGenerator::endMemberGroup(bool hasHeader)
2591{
2592 DBG_RTF(t << "{\\comment endMemberGroup}" << endl)
2593 if (hasHeader) decrementIndentLevel();
2594 t << "}";
2595}
2596
2597void RTFGenerator::startSimpleSect(SectionTypes,const char *file,const char *anchor,const char *title)
2598{
2599 DBG_RTF(t << "{\\comment (startSimpleSect)}" << endl)
2600 t << "{"; // ends at endDescList
2601 t << "{"; // ends at endDescTitle
2602 startBold();
2603 newParagraph();
2604 if (file)
2605 {
2606 writeObjectLink(0,file,anchor,title);
2607 }
2608 else
2609 {
2610 docify(title);
2611 }
2612 endBold();
2613 t << "}";
2614 newParagraph();
2615 incrementIndentLevel();
2616 t << rtf_Style_Reset << rtf_DList_DepthStyle();
2617}
2618
2619void RTFGenerator::endSimpleSect()
2620{
2621 DBG_RTF(t << "{\\comment (endSimpleSect)}" << endl)
2622 newParagraph();
2623 decrementIndentLevel();
2624 m_omitParagraph = TRUE;
2625 t << "}";
2626}
2627
2628void RTFGenerator::startParamList(ParamListTypes,const char *title)
2629{
2630 DBG_RTF(t << "{\\comment (startParamList)}" << endl)
2631 t << "{"; // ends at endParamList
2632 t << "{"; // ends at endDescTitle
2633 startBold();
2634 newParagraph();
2635 docify(title);
2636 endBold();
2637 t << "}";
2638 newParagraph();
2639 incrementIndentLevel();
2640 t << rtf_Style_Reset << rtf_DList_DepthStyle();
2641}
2642
2643void RTFGenerator::endParamList()
2644{
2645 DBG_RTF(t << "{\\comment (endParamList)}" << endl)
2646 newParagraph();
2647 decrementIndentLevel();
2648 m_omitParagraph = TRUE;
2649 t << "}";
2650}
2651
2652void RTFGenerator::startParameterType(bool first,const char *key)
2653{
2654 DBG_RTF(t << "{\\comment (startParameterList)}" << endl)
2655 if (!first && key)
2656 {
2657 t << " " << key << " ";
2658 }
2659}
2660
2661void RTFGenerator::printDoc(DocNode *n,const char *langExt)
2662{
2663 RTFDocVisitor *visitor = new RTFDocVisitor(t,*this,langExt);
2664 n->accept(visitor);
2665 delete visitor;
2666 m_omitParagraph = TRUE;
2667}
2668
2669void RTFGenerator::rtfwriteRuler_doubleline()
2670{
2671 DBG_RTF(t << "{\\comment (rtfwriteRuler_doubleline)}" << endl)
2672 t << "{\\pard\\widctlpar\\brdrb\\brdrdb\\brdrw15\\brsp20 \\adjustright \\par}" << endl;
2673}
2674
2675void RTFGenerator::rtfwriteRuler_emboss()
2676{
2677 DBG_RTF(t << "{\\comment (rtfwriteRuler_emboss)}" << endl)
2678 t << "{\\pard\\widctlpar\\brdrb\\brdremboss\\brdrw15\\brsp20 \\adjustright \\par}" << endl;
2679}
2680
2681void RTFGenerator::rtfwriteRuler_thick()
2682{
2683 DBG_RTF(t << "{\\comment (rtfwriteRuler_thick)}" << endl)
2684 t << "{\\pard\\widctlpar\\brdrb\\brdrs\\brdrw75\\brsp20 \\adjustright \\par}" << endl;
2685}
2686
2687void RTFGenerator::rtfwriteRuler_thin()
2688{
2689 DBG_RTF(t << "{\\comment (rtfwriteRuler_thin)}" << endl)
2690 t << "{\\pard\\widctlpar\\brdrb\\brdrs\\brdrw5\\brsp20 \\adjustright \\par}" << endl;
2691}
2692
2693#if 0
2694void RTFGenerator::postProcess(QByteArray &a)
2695{
2696 QByteArray enc(a.size()*4); // worst case
2697 int off=0;
2698 uint i;
2699 bool mbFlag=FALSE;
2700 for (i=0;i<a.size();i++)
2701 {
2702 unsigned char c = (unsigned char)a.at(i);
2703
2704 // treat characters > 0x80 as multibyte characters, except when they
2705 // are control characters
2706 if (c>0x80 || (mbFlag && c!='\\' && c!='{' && c!='}'))
2707 {
2708 char s[10];
2709 sprintf(s,"\\'%X",c);
2710 qstrcpy(enc.data()+off,s);
2711 off+=qstrlen(s);
2712 mbFlag=c>0x80;
2713 }
2714 else
2715 {
2716 enc.at(off++)=c;
2717 }
2718 }
2719 enc.resize(off);
2720 a = enc;
2721}
2722#endif
2723
2724void RTFGenerator::startConstraintList(const char *header)
2725{
2726 DBG_RTF(t << "{\\comment (startConstraintList)}" << endl)
2727 t << "{"; // ends at endConstraintList
2728 t << "{";
2729 startBold();
2730 newParagraph();
2731 docify(header);
2732 endBold();
2733 t << "}";
2734 newParagraph();
2735 incrementIndentLevel();
2736 t << rtf_Style_Reset << rtf_DList_DepthStyle();
2737}
2738
2739void RTFGenerator::startConstraintParam()
2740{
2741 DBG_RTF(t << "{\\comment (startConstraintParam)}" << endl)
2742 startEmphasis();
2743}
2744
2745void RTFGenerator::endConstraintParam()
2746{
2747 DBG_RTF(t << "{\\comment (endConstraintParam)}" << endl)
2748 endEmphasis();
2749 t << " : ";
2750}
2751
2752void RTFGenerator::startConstraintType()
2753{
2754 DBG_RTF(t << "{\\comment (startConstraintType)}" << endl)
2755 startEmphasis();
2756}
2757
2758void RTFGenerator::endConstraintType()
2759{
2760 DBG_RTF(t << "{\\comment (endConstraintType)}" << endl)
2761 endEmphasis();
2762 t << " ";
2763}
2764
2765void RTFGenerator::startConstraintDocs()
2766{
2767 DBG_RTF(t << "{\\comment (startConstraintDocs)}" << endl)
2768}
2769
2770void RTFGenerator::endConstraintDocs()
2771{
2772 DBG_RTF(t << "{\\comment (endConstraintDocs)}" << endl)
2773 newParagraph();
2774}
2775
2776void RTFGenerator::endConstraintList()
2777{
2778 DBG_RTF(t << "{\\comment (endConstraintList)}" << endl)
2779 newParagraph();
2780 decrementIndentLevel();
2781 m_omitParagraph = TRUE;
2782 t << "}";
2783}
2784
2785void RTFGenerator::startIndexListItem()
2786{
2787 DBG_RTF(t << "{\\comment (startIndexListItem)}" << endl)
2788}
2789
2790void RTFGenerator::endIndexListItem()
2791{
2792 DBG_RTF(t << "{\\comment (endIndexListItem)}" << endl)
2793 t << "\\par" << endl;
2794}
2795
2796void RTFGenerator::startInlineDescription()
2797{
2798 DBG_RTF(t << "{\\comment (startInlineDescription)}" << endl)
2799}
2800
2801void RTFGenerator::endInlineDescription()
2802{
2803 DBG_RTF(t << "{\\comment (endInlineDescription)}" << endl)
2804}
2805
2806void RTFGenerator::startInlineHeader()
2807{
2808 DBG_RTF(t << "{\\comment (startInlineHeader)}" << endl)
2809 t << "{" << endl;
2810 t << rtf_Style_Reset << rtf_Style["Heading5"]->reference;
2811 startBold();
2812}
2813
2814void RTFGenerator::endInlineHeader()
2815{
2816 DBG_RTF(t << "{\\comment (endInlineHeader)}" << endl)
2817 endBold();
2818 t << "\\par";
2819 t << "}" << endl;
2820}
2821
2822
2823

Archive Download this file

Revision: 1322