Chameleon

Chameleon Svn Source Tree

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

Source at commit 1322 created 9 years 5 months ago.
By meklort, Add doxygen to utils folder
1/******************************************************************************
2 *
3 * $Id: index.cpp,v 1.63 2001/03/19 19:27:40 root Exp $
4 *
5 * Copyright (C) 1997-2011 by Dimitri van Heesch.
6 *
7 * Permission to use, copy, modify, and distribute this software and its
8 * documentation under the terms of the GNU General Public License is hereby
9 * granted. No representations are made about the suitability of this software
10 * for any purpose. It is provided "as is" without express or implied warranty.
11 * See the GNU General Public License for more details.
12 *
13 * Documents produced by Doxygen are derivative works derived from the
14 * input used in their production; they are not affected by this license.
15 *
16 */
17
18/** @file
19 * @brief This file contains functions for the various index pages.
20 */
21
22#include <stdlib.h>
23
24#include <qtextstream.h>
25#include <qdatetime.h>
26#include <qdir.h>
27#include <qregexp.h>
28
29#include "message.h"
30#include "index.h"
31#include "doxygen.h"
32#include "config.h"
33#include "filedef.h"
34#include "outputlist.h"
35#include "util.h"
36#include "groupdef.h"
37#include "language.h"
38#include "htmlgen.h"
39#include "htmlhelp.h"
40#include "ftvhelp.h"
41#include "dot.h"
42#include "pagedef.h"
43#include "dirdef.h"
44#include "vhdldocgen.h"
45#include "layout.h"
46
47#define MAX_ITEMS_BEFORE_MULTIPAGE_INDEX 200
48#define MAX_ITEMS_BEFORE_QUICK_INDEX 30
49
50static const char search_script[]=
51#include "search_js.h"
52;
53
54//static const char navindex_script[]=
55//#include "navindex_js.h"
56//;
57
58int annotatedClasses;
59int annotatedClassesPrinted;
60int hierarchyClasses;
61int documentedFiles;
62int documentedGroups;
63int documentedNamespaces;
64int indexedPages;
65int documentedClassMembers[CMHL_Total];
66int documentedFileMembers[FMHL_Total];
67int documentedNamespaceMembers[NMHL_Total];
68int documentedHtmlFiles;
69int documentedPages;
70int documentedDirs;
71
72int countClassHierarchy();
73int countClassMembers(int filter=CMHL_All);
74int countFileMembers(int filter=FMHL_All);
75void countFiles(int &htmlFiles,int &files);
76int countGroups();
77int countDirs();
78int countNamespaces();
79int countAnnotatedClasses(int *cp);
80int countNamespaceMembers(int filter=NMHL_All);
81int countIncludeFiles();
82void countRelatedPages(int &docPages,int &indexPages);
83
84void countDataStructures()
85{
86 annotatedClasses = countAnnotatedClasses(&annotatedClassesPrinted); // "classes" + "annotated"
87 hierarchyClasses = countClassHierarchy(); // "hierarchy"
88 countFiles(documentedHtmlFiles,documentedFiles); // "files"
89 countRelatedPages(documentedPages,indexedPages); // "pages"
90 documentedGroups = countGroups(); // "modules"
91 documentedNamespaces = countNamespaces(); // "namespaces"
92 documentedDirs = countDirs(); // "dirs"
93 // "globals"
94 // "namespacemembers"
95 // "functions"
96}
97
98static void startIndexHierarchy(OutputList &ol,int level)
99{
100 ol.pushGeneratorState();
101 ol.disable(OutputGenerator::Man);
102 ol.disable(OutputGenerator::Html);
103 if (level<6) ol.startIndexList();
104 ol.enableAll();
105 ol.disable(OutputGenerator::Latex);
106 ol.disable(OutputGenerator::RTF);
107 ol.startItemList();
108 ol.popGeneratorState();
109}
110
111static void endIndexHierarchy(OutputList &ol,int level)
112{
113 ol.pushGeneratorState();
114 ol.disable(OutputGenerator::Man);
115 ol.disable(OutputGenerator::Html);
116 if (level<6) ol.endIndexList();
117 ol.enableAll();
118 ol.disable(OutputGenerator::Latex);
119 ol.disable(OutputGenerator::RTF);
120 ol.endItemList();
121 ol.popGeneratorState();
122}
123
124//----------------------------------------------------------------------------
125
126class MemberIndexList : public QList<MemberDef>
127{
128 public:
129 MemberIndexList() : QList<MemberDef>() {}
130 ~MemberIndexList() {}
131 int compareItems(GCI item1, GCI item2)
132 {
133 MemberDef *md1=(MemberDef *)item1;
134 MemberDef *md2=(MemberDef *)item2;
135 return stricmp(md1->name(),md2->name());
136 }
137};
138
139#define MEMBER_INDEX_ENTRIES 256
140
141static MemberIndexList g_memberIndexLetterUsed[CMHL_Total][MEMBER_INDEX_ENTRIES];
142static MemberIndexList g_fileIndexLetterUsed[FMHL_Total][MEMBER_INDEX_ENTRIES];
143static MemberIndexList g_namespaceIndexLetterUsed[NMHL_Total][MEMBER_INDEX_ENTRIES];
144
145static bool g_classIndexLetterUsed[CHL_Total][256];
146
147const int maxItemsBeforeQuickIndex = MAX_ITEMS_BEFORE_QUICK_INDEX;
148
149//----------------------------------------------------------------------------
150
151// strips w from s iff s starts with w
152bool stripWord(QCString &s,QCString w)
153{
154 bool success=FALSE;
155 if (s.left(w.length())==w)
156 {
157 success=TRUE;
158 s=s.right(s.length()-w.length());
159 }
160 return success;
161}
162
163//----------------------------------------------------------------------------
164// some quasi intelligent brief description abbreviator :^)
165QCString abbreviate(const char *s,const char *name)
166{
167 QCString scopelessName=name;
168 int i=scopelessName.findRev("::");
169 if (i!=-1) scopelessName=scopelessName.mid(i+2);
170 QCString result=s;
171 result=result.stripWhiteSpace();
172 // strip trailing .
173 if (!result.isEmpty() && result.at(result.length()-1)=='.')
174 result=result.left(result.length()-1);
175
176 // strip any predefined prefix
177 QStrList &briefDescAbbrev = Config_getList("ABBREVIATE_BRIEF");
178 const char *p = briefDescAbbrev.first();
179 while (p)
180 {
181 QCString s = p;
182 s.replace(QRegExp("\\$name"), scopelessName); // replace $name with entity name
183 s += " ";
184 stripWord(result,s);
185 p = briefDescAbbrev.next();
186 }
187
188 // capitalize first word
189 if (!result.isEmpty())
190 {
191 int c=result[0];
192 if (c>='a' && c<='z') c+='A'-'a';
193 result[0]=c;
194 }
195 return result;
196}
197
198//----------------------------------------------------------------------------
199
200static void startQuickIndexList(OutputList &ol,bool letterTabs=FALSE)
201{
202 bool fancyTabs = TRUE;
203 if (fancyTabs)
204 {
205 if (letterTabs)
206 {
207 ol.writeString(" <div id=\"navrow4\" class=\"tabs3\">\n");
208 }
209 else
210 {
211 ol.writeString(" <div id=\"navrow3\" class=\"tabs2\">\n");
212 }
213 ol.writeString(" <ul class=\"tablist\">\n");
214 }
215 else
216 {
217 ol.writeString(" <div class=\"qindex\">");
218 }
219}
220
221static void endQuickIndexList(OutputList &ol)
222{
223 bool fancyTabs = TRUE;
224 if (fancyTabs)
225 {
226 ol.writeString(" </ul>\n");
227 }
228 ol.writeString(" </div>\n");
229}
230
231static void startQuickIndexItem(OutputList &ol,const char *l,
232 bool hl,bool compact,bool &first)
233{
234 bool fancyTabs = TRUE;
235 if (!first && compact && !fancyTabs) ol.writeString(" | ");
236 first=FALSE;
237 if (fancyTabs)
238 {
239 ol.writeString(" <li");
240 if (hl) ol.writeString(" class=\"current\"");
241 ol.writeString("><a ");
242 }
243 else
244 {
245 if (!compact) ol.writeString("<li>");
246 if (hl && compact)
247 {
248 ol.writeString("<a class=\"qindexHL\" ");
249 }
250 else
251 {
252 ol.writeString("<a class=\"qindex\" ");
253 }
254 }
255 ol.writeString("href=\"");
256 ol.writeString(l);
257 ol.writeString("\">");
258 if (fancyTabs)
259 {
260 ol.writeString("<span>");
261 }
262}
263
264static void endQuickIndexItem(OutputList &ol)
265{
266 bool fancyTabs=TRUE;
267 if (fancyTabs) ol.writeString("</span>");
268 ol.writeString("</a>");
269 if (fancyTabs) ol.writeString("</li>\n");
270}
271
272
273static QCString fixSpaces(const QCString &s)
274{
275 return substitute(s," ","&#160;");
276}
277
278
279void startTitle(OutputList &ol,const char *fileName,Definition *def)
280{
281 ol.startHeaderSection();
282 if (def) def->writeSummaryLinks(ol);
283 ol.startTitleHead(fileName);
284 ol.pushGeneratorState();
285 ol.disable(OutputGenerator::Man);
286}
287
288void endTitle(OutputList &ol,const char *fileName,const char *name)
289{
290 ol.popGeneratorState();
291 ol.endTitleHead(fileName,name);
292 ol.endHeaderSection();
293}
294
295void startFile(OutputList &ol,const char *name,const char *manName,
296 const char *title,HighlightedItem hli,bool additionalIndices,
297 const char *altSidebarName)
298{
299 static bool disableIndex = Config_getBool("DISABLE_INDEX");
300 static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
301 ol.startFile(name,manName,title);
302 ol.startQuickIndices();
303 if (!disableIndex)
304 {
305 ol.writeQuickLinks(TRUE,hli);
306 }
307 if (!additionalIndices)
308 {
309 ol.endQuickIndices();
310 }
311 if (generateTreeView)
312 {
313 ol.writeSplitBar(altSidebarName ? altSidebarName : name);
314 }
315}
316
317void endFile(OutputList &ol,bool skipNavIndex)
318{
319 static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
320 static bool hasCustomFooter = !Config_getString("HTML_FOOTER").isEmpty();
321 ol.pushGeneratorState();
322 ol.disableAllBut(OutputGenerator::Html);
323 if (!skipNavIndex)
324 {
325 ol.endContents();
326 if (generateTreeView)
327 {
328 ol.writeString("</div>\n");
329 ol.writeString(" <div id=\"nav-path\" class=\"navpath\">\n");
330 ol.writeString(" <ul>\n");
331 if (!hasCustomFooter)
332 {
333 ol.writeString(" <li class=\"footer\">");
334 ol.writeLogo();
335 ol.writeString("</li>\n");
336 ol.writeString(" </ul>\n");
337 ol.writeString(" </div>\n");
338 }
339 }
340 }
341 ol.writeFooter(); // write the footer
342 ol.popGeneratorState();
343 ol.endFile();
344}
345
346//----------------------------------------------------------------------------
347
348static bool classHasVisibleChildren(ClassDef *cd)
349{
350 bool vhdl=Config_getBool("OPTIMIZE_OUTPUT_VHDL");
351
352 BaseClassList *bcl;
353
354 if (vhdl) // reverse baseClass/subClass relation
355 {
356 if (cd->baseClasses()==0) return FALSE;
357 bcl=cd->baseClasses();
358 }
359 else
360 {
361 if (cd->subClasses()==0) return FALSE;
362 bcl=cd->subClasses();
363 }
364
365 BaseClassListIterator bcli(*bcl);
366 for ( ; bcli.current() ; ++bcli)
367 {
368 if (bcli.current()->classDef->isVisibleInHierarchy())
369 {
370 return TRUE;
371 }
372 }
373 return FALSE;
374}
375
376void writeClassTree(OutputList &ol,BaseClassList *bcl,bool hideSuper,int level,FTVHelp* ftv)
377{
378 static bool vhdl=Config_getBool("OPTIMIZE_OUTPUT_VHDL");
379
380 if (bcl==0) return;
381 BaseClassListIterator bcli(*bcl);
382 bool started=FALSE;
383 for ( ; bcli.current() ; ++bcli)
384 {
385 ClassDef *cd=bcli.current()->classDef;
386 bool b;
387 if (vhdl)
388 {
389 b=hasVisibleRoot(cd->subClasses());
390 }
391 else
392 {
393 b=hasVisibleRoot(cd->baseClasses());
394 }
395
396 if (cd->isVisibleInHierarchy() && b) // hasVisibleRoot(cd->baseClasses()))
397 {
398 if (!started)
399 {
400 startIndexHierarchy(ol,level);
401 Doxygen::indexList.incContentsDepth();
402 if (ftv)
403 ftv->incContentsDepth();
404 started=TRUE;
405 }
406 ol.startIndexListItem();
407 //printf("Passed...\n");
408 bool hasChildren = !cd->visited && !hideSuper && classHasVisibleChildren(cd);
409 //printf("tree4: Has children %s: %d\n",cd->name().data(),hasChildren);
410 if (cd->isLinkable())
411 {
412 //printf("Writing class %s\n",cd->displayName().data());
413 ol.startIndexItem(cd->getReference(),cd->getOutputFileBase());
414 ol.parseText(cd->displayName());
415 ol.endIndexItem(cd->getReference(),cd->getOutputFileBase());
416 if (cd->isReference())
417 {
418 ol.startTypewriter();
419 ol.docify(" [external]");
420 ol.endTypewriter();
421 }
422 Doxygen::indexList.addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor());
423 if (ftv)
424 ftv->addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor());
425 }
426 else
427 {
428 ol.startIndexItem(0,0);
429 ol.parseText(cd->name());
430 ol.endIndexItem(0,0);
431 Doxygen::indexList.addContentsItem(hasChildren,cd->displayName(),0,0,0);
432 if (ftv)
433 ftv->addContentsItem(hasChildren,cd->displayName(),0,0,0);
434 }
435 if (hasChildren)
436 {
437 //printf("Class %s at %p visited=%d\n",cd->name().data(),cd,cd->visited);
438 bool wasVisited=cd->visited;
439 cd->visited=TRUE;
440 if (vhdl)
441 {
442 writeClassTree(ol,cd->baseClasses(),wasVisited,level+1,ftv);
443 }
444 else
445 {
446 writeClassTree(ol,cd->subClasses(),wasVisited,level+1,ftv);
447 }
448 }
449 ol.endIndexListItem();
450 }
451 }
452 if (started)
453 {
454 endIndexHierarchy(ol,level);
455 Doxygen::indexList.decContentsDepth();
456 if (ftv)
457 ftv->decContentsDepth();
458 }
459}
460
461
462//----------------------------------------------------------------------------
463/*! Generates HTML Help tree of classes */
464
465void writeClassTree(BaseClassList *cl,int level)
466{
467 if (cl==0) return;
468 BaseClassListIterator cli(*cl);
469 bool started=FALSE;
470 for ( ; cli.current() ; ++cli)
471 {
472 ClassDef *cd=cli.current()->classDef;
473 if (cd->isVisibleInHierarchy() && hasVisibleRoot(cd->baseClasses()))
474 //if (cd->isVisibleInHierarchy() && !cd->visited)
475 {
476 if (!started)
477 {
478 Doxygen::indexList.incContentsDepth();
479 started=TRUE;
480 }
481 bool hasChildren = !cd->visited && classHasVisibleChildren(cd);
482 //printf("tree2: Has children %s: %d\n",cd->name().data(),hasChildren);
483 if (cd->isLinkable())
484 {
485 Doxygen::indexList.addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor());
486 }
487 if (hasChildren)
488 {
489 writeClassTree(cd->subClasses(),level+1);
490 }
491 cd->visited=TRUE;
492 }
493 }
494 if (started)
495 {
496 Doxygen::indexList.decContentsDepth();
497 }
498}
499
500//----------------------------------------------------------------------------
501/*! Generates HTML Help tree of classes */
502
503void writeClassTreeNode(ClassDef *cd,bool &started,int level)
504{
505 //printf("writeClassTreeNode(%s) visited=%d\n",cd->name().data(),cd->visited);
506 static bool vhdl=Config_getBool("OPTIMIZE_OUTPUT_VHDL");
507
508 if (cd->isVisibleInHierarchy() && !cd->visited)
509 {
510 if (!started)
511 {
512 started=TRUE;
513 }
514 bool hasChildren = classHasVisibleChildren(cd);
515 //printf("node: Has children %s: %d\n",cd->name().data(),hasChildren);
516 if (cd->isLinkable())
517 {
518 Doxygen::indexList.addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor());
519 }
520 if (hasChildren)
521 {
522 if (vhdl)
523 {
524 writeClassTree(cd->baseClasses(),level+1);
525 }
526 else
527 {
528 writeClassTree(cd->subClasses(),level+1);
529 }
530 }
531 cd->visited=TRUE;
532 }
533}
534
535void writeClassTree(ClassList *cl,int level)
536{
537 if (cl==0) return;
538 ClassListIterator cli(*cl);
539 bool started=FALSE;
540 for ( cli.toFirst() ; cli.current() ; ++cli)
541 {
542 cli.current()->visited=FALSE;
543 }
544 for ( cli.toFirst() ; cli.current() ; ++cli)
545 {
546 writeClassTreeNode(cli.current(),started,level);
547 }
548}
549
550void writeClassTree(ClassSDict *d,int level)
551{
552 if (d==0) return;
553 ClassSDict::Iterator cli(*d);
554 bool started=FALSE;
555 for ( cli.toFirst() ; cli.current() ; ++cli)
556 {
557 cli.current()->visited=FALSE;
558 }
559 for ( cli.toFirst() ; cli.current() ; ++cli)
560 {
561 writeClassTreeNode(cli.current(),started,level);
562 }
563}
564
565//----------------------------------------------------------------------------
566
567static void writeClassTreeForList(OutputList &ol,ClassSDict *cl,bool &started,FTVHelp* ftv)
568{
569 static bool vhdl=Config_getBool("OPTIMIZE_OUTPUT_VHDL");
570 ClassSDict::Iterator cli(*cl);
571 for (;cli.current(); ++cli)
572 {
573 ClassDef *cd=cli.current();
574 //printf("class %s hasVisibleRoot=%d isVisibleInHierarchy=%d\n",
575 // cd->name().data(),
576 // hasVisibleRoot(cd->baseClasses()),
577 // cd->isVisibleInHierarchy()
578 // );
579 bool b;
580 if (vhdl)
581 {
582 if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKAGECLASS ||
583 (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS)
584 {
585 continue;
586 }
587 b=!hasVisibleRoot(cd->subClasses());
588 }
589 else
590 {
591 b=!hasVisibleRoot(cd->baseClasses());
592 }
593
594 if (b) //filter on root classes
595 {
596 if (cd->isVisibleInHierarchy()) // should it be visible
597 {
598 if (!started)
599 {
600 startIndexHierarchy(ol,0);
601 Doxygen::indexList.incContentsDepth();
602 started=TRUE;
603 }
604 ol.startIndexListItem();
605 bool hasChildren = !cd->visited && classHasVisibleChildren(cd);
606 //printf("list: Has children %s: %d\n",cd->name().data(),hasChildren);
607 if (cd->isLinkable())
608 {
609 //printf("Writing class %s isLinkable()=%d isLinkableInProject()=%d cd->templateMaster()=%p\n",
610 // cd->displayName().data(),cd->isLinkable(),cd->isLinkableInProject(),cd->templateMaster());
611 ol.startIndexItem(cd->getReference(),cd->getOutputFileBase());
612 ol.parseText(cd->displayName());
613 ol.endIndexItem(cd->getReference(),cd->getOutputFileBase());
614 if (cd->isReference())
615 {
616 ol.startTypewriter();
617 ol.docify(" [external]");
618 ol.endTypewriter();
619 }
620 Doxygen::indexList.addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor());
621 if (ftv)
622 ftv->addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor());
623 }
624 else
625 {
626 ol.startIndexItem(0,0);
627 ol.parseText(cd->displayName());
628 ol.endIndexItem(0,0);
629 Doxygen::indexList.addContentsItem(hasChildren,cd->displayName(),0,0,0);
630 if (ftv)
631 ftv->addContentsItem(hasChildren,cd->displayName(),0,0,0);
632 }
633 if (vhdl && hasChildren)
634 {
635 writeClassTree(ol,cd->baseClasses(),cd->visited,1,ftv);
636 cd->visited=TRUE;
637 }
638 else if (hasChildren)
639 {
640 writeClassTree(ol,cd->subClasses(),cd->visited,1,ftv);
641 cd->visited=TRUE;
642 }
643 ol.endIndexListItem();
644 }
645 }
646 }
647}
648
649void writeClassHierarchy(OutputList &ol, FTVHelp* ftv)
650{
651 initClassHierarchy(Doxygen::classSDict);
652 initClassHierarchy(Doxygen::hiddenClasses);
653 if (ftv)
654 {
655 ol.pushGeneratorState();
656 ol.disable(OutputGenerator::Html);
657 }
658 bool started=FALSE;
659 writeClassTreeForList(ol,Doxygen::classSDict,started,ftv);
660 writeClassTreeForList(ol,Doxygen::hiddenClasses,started,ftv);
661 if (started)
662 {
663 endIndexHierarchy(ol,0);
664 Doxygen::indexList.decContentsDepth();
665 }
666 if (ftv)
667 ol.popGeneratorState();
668}
669
670//----------------------------------------------------------------------------
671
672static int countClassesInTreeList(const ClassSDict &cl)
673{
674 int count=0;
675 ClassSDict::Iterator cli(cl);
676 for (;cli.current(); ++cli)
677 {
678 ClassDef *cd=cli.current();
679 if (!hasVisibleRoot(cd->baseClasses())) // filter on root classes
680 {
681 if (cd->isVisibleInHierarchy()) // should it be visible
682 {
683 if (cd->subClasses()) // should have sub classes
684 {
685 count++;
686 }
687 }
688 }
689 }
690 return count;
691}
692
693int countClassHierarchy()
694{
695 int count=0;
696 initClassHierarchy(Doxygen::classSDict);
697 initClassHierarchy(Doxygen::hiddenClasses);
698 count+=countClassesInTreeList(*Doxygen::classSDict);
699 count+=countClassesInTreeList(*Doxygen::hiddenClasses);
700 return count;
701}
702
703//----------------------------------------------------------------------------
704
705void writeHierarchicalIndex(OutputList &ol)
706{
707 if (hierarchyClasses==0) return;
708 ol.pushGeneratorState();
709 ol.disable(OutputGenerator::Man);
710 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassHierarchy);
711 QCString title = lne->title();
712 startFile(ol,"hierarchy",0, title, HLI_Hierarchy);
713 startTitle(ol,0);
714 ol.parseText(title);
715 endTitle(ol,0,0);
716 ol.startContents();
717 ol.startTextBlock();
718 Doxygen::indexList.addContentsItem(TRUE,title,0,"hierarchy",0);
719 if (Config_getBool("HAVE_DOT") && Config_getBool("GRAPHICAL_HIERARCHY"))
720 {
721 ol.disable(OutputGenerator::Latex);
722 ol.disable(OutputGenerator::RTF);
723 ol.startParagraph();
724 ol.startTextLink("inherits",0);
725 ol.parseText(theTranslator->trGotoGraphicalHierarchy());
726 ol.endTextLink();
727 ol.endParagraph();
728 ol.enable(OutputGenerator::Latex);
729 ol.enable(OutputGenerator::RTF);
730 }
731 ol.parseText(lne->intro());
732 ol.endTextBlock();
733
734 FTVHelp* ftv = 0;
735 bool treeView=Config_getBool("USE_INLINE_TREES");
736 if (treeView)
737 {
738 ftv = new FTVHelp(FALSE);
739 }
740
741 writeClassHierarchy(ol,ftv);
742
743 if (ftv)
744 {
745 QGString outStr;
746 FTextStream t(&outStr);
747 ftv->generateTreeViewInline(t);
748 ol.pushGeneratorState();
749 ol.disableAllBut(OutputGenerator::Html);
750 ol.writeString(outStr);
751 ol.popGeneratorState();
752 delete ftv;
753 }
754 endFile(ol);
755 ol.popGeneratorState();
756}
757
758//----------------------------------------------------------------------------
759
760void writeGraphicalClassHierarchy(OutputList &ol)
761{
762 if (hierarchyClasses==0) return;
763 ol.disableAllBut(OutputGenerator::Html);
764 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassHierarchy);
765 QCString title = lne->title();
766 startFile(ol,"inherits",0,title,HLI_Hierarchy,FALSE,"hierarchy");
767 startTitle(ol,0);
768 //if (!Config_getString("PROJECT_NAME").isEmpty())
769 //{
770 // title.prepend(Config_getString("PROJECT_NAME")+" ");
771 //}
772 ol.parseText(title);
773 endTitle(ol,0,0);
774 ol.startContents();
775 ol.startTextBlock();
776 //Doxygen::indexList.addContentsItem(FALSE,theTranslator->trGraphicalHierarchy(),0,"inherits",0);
777 ol.startParagraph();
778 ol.startTextLink("hierarchy",0);
779 ol.parseText(theTranslator->trGotoTextualHierarchy());
780 ol.endTextLink();
781 ol.endParagraph();
782 //parseText(ol,theTranslator->trClassHierarchyDescription());
783 //ol.newParagraph();
784 ol.endTextBlock();
785 DotGfxHierarchyTable g;
786 ol.writeGraphicalHierarchy(g);
787 endFile(ol);
788 ol.enableAll();
789}
790
791//----------------------------------------------------------------------------
792
793void countFiles(int &htmlFiles,int &files)
794{
795 htmlFiles=0;
796 files=0;
797 FileNameListIterator fnli(*Doxygen::inputNameList);
798 FileName *fn;
799 for (;(fn=fnli.current());++fnli)
800 {
801 FileNameIterator fni(*fn);
802 FileDef *fd;
803 for (;(fd=fni.current());++fni)
804 {
805 bool doc = fd->isLinkableInProject();
806 bool src = fd->generateSourceFile();
807 bool nameOk = !fd->isDocumentationFile();
808 if (nameOk)
809 {
810 if (doc || src)
811 {
812 htmlFiles++;
813 }
814 if (doc)
815 {
816 files++;
817 }
818 }
819 }
820 }
821}
822
823//----------------------------------------------------------------------------
824
825void writeFileIndex(OutputList &ol)
826{
827 if (documentedHtmlFiles==0) return;
828 ol.pushGeneratorState();
829 ol.disable(OutputGenerator::Man);
830 if (documentedFiles==0) ol.disableAllBut(OutputGenerator::Html);
831 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Files);
832 QCString title = lne->title();
833 startFile(ol,"files",0,title,HLI_Files);
834 startTitle(ol,0);
835 //if (!Config_getString("PROJECT_NAME").isEmpty())
836 //{
837 // title.prepend(Config_getString("PROJECT_NAME")+" ");
838 //}
839 ol.parseText(title);
840 endTitle(ol,0,0);
841 ol.startContents();
842 ol.startTextBlock();
843 Doxygen::indexList.addContentsItem(TRUE,title,0,"files",0);
844 Doxygen::indexList.incContentsDepth();
845 ol.parseText(lne->intro());
846 ol.endTextBlock();
847
848 OutputNameDict outputNameDict(1009);
849 OutputNameList outputNameList;
850 outputNameList.setAutoDelete(TRUE);
851
852 if (Config_getBool("FULL_PATH_NAMES"))
853 {
854 // re-sort input files in (dir,file) output order instead of (file,dir) input order
855 FileName *fn=Doxygen::inputNameList->first();
856 while (fn)
857 {
858 FileDef *fd=fn->first();
859 while (fd)
860 {
861 QCString path=fd->getPath();
862 if (path.isEmpty()) path="[external]";
863 FileList *fl = outputNameDict.find(path);
864 if (fl)
865 {
866 fl->inSort(fd);
867 //printf("+ inserting %s---%s\n",fd->getPath().data(),fd->name().data());
868 }
869 else
870 {
871 //printf("o inserting %s---%s\n",fd->getPath().data(),fd->name().data());
872 fl = new FileList(path);
873 fl->inSort(fd);
874 outputNameList.inSort(fl);
875 outputNameDict.insert(path,fl);
876 }
877 fd=fn->next();
878 }
879 fn=Doxygen::inputNameList->next();
880 }
881 }
882
883 ol.startIndexList();
884 FileList *fl=0;
885 if (Config_getBool("FULL_PATH_NAMES"))
886 {
887 fl = outputNameList.first();
888 }
889 else
890 {
891 fl = Doxygen::inputNameList->first();
892 }
893 while (fl)
894 {
895 FileDef *fd=fl->first();
896 while (fd)
897 {
898 //printf("Found filedef %s\n",fd->name().data());
899 bool doc = fd->isLinkableInProject();
900 bool src = fd->generateSourceFile();
901 bool nameOk = !fd->isDocumentationFile();
902 if (nameOk && (doc || src) &&
903 !fd->isReference())
904 {
905 QCString path;
906 if (Config_getBool("FULL_PATH_NAMES"))
907 {
908 path=stripFromPath(fd->getPath().copy());
909 }
910 QCString fullName=fd->name();
911 if (!path.isEmpty())
912 {
913 if (path.at(path.length()-1)!='/') fullName.prepend("/");
914 fullName.prepend(path);
915 }
916
917 ol.startIndexKey();
918 ol.docify(path);
919 if (doc)
920 {
921 ol.writeObjectLink(0,fd->getOutputFileBase(),0,fd->name());
922 Doxygen::indexList.addContentsItem(FALSE,fullName,fd->getReference(),fd->getOutputFileBase(),0);
923 }
924 else
925 {
926 ol.startBold();
927 ol.docify(fd->name());
928 ol.endBold();
929 Doxygen::indexList.addContentsItem(FALSE,fullName,0,0,0);
930 }
931 if (src)
932 {
933 ol.pushGeneratorState();
934 ol.disableAllBut(OutputGenerator::Html);
935 ol.docify(" ");
936 ol.startTextLink(fd->includeName(),0);
937 ol.docify("[");
938 ol.parseText(theTranslator->trCode());
939 ol.docify("]");
940 ol.endTextLink();
941 ol.popGeneratorState();
942 }
943 ol.endIndexKey();
944 bool hasBrief = !fd->briefDescription().isEmpty();
945 ol.startIndexValue(hasBrief);
946 if (hasBrief)
947 {
948 //ol.docify(" (");
949 ol.parseDoc(
950 fd->briefFile(),fd->briefLine(),
951 fd,0,
952 abbreviate(fd->briefDescription(),fd->name()),
953 FALSE, // index words
954 FALSE, // isExample
955 0, // example name
956 TRUE, // single line
957 TRUE // link from index
958 );
959 //ol.docify(")");
960 }
961 ol.endIndexValue(fd->getOutputFileBase(),hasBrief);
962 //ol.popGeneratorState();
963 // --------------------------------------------------------
964 }
965 fd=fl->next();
966 }
967 if (Config_getBool("FULL_PATH_NAMES"))
968 {
969 fl=outputNameList.next();
970 }
971 else
972 {
973 fl=Doxygen::inputNameList->next();
974 }
975 }
976 ol.endIndexList();
977 Doxygen::indexList.decContentsDepth();
978 endFile(ol);
979 ol.popGeneratorState();
980}
981
982//----------------------------------------------------------------------------
983int countNamespaces()
984{
985 int count=0;
986 NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
987 NamespaceDef *nd;
988 for (;(nd=nli.current());++nli)
989 {
990 if (nd->isLinkableInProject()) count++;
991 }
992 return count;
993}
994
995//----------------------------------------------------------------------------
996
997void writeNamespaceIndex(OutputList &ol)
998{
999 if (documentedNamespaces==0) return;
1000 ol.pushGeneratorState();
1001 ol.disable(OutputGenerator::Man);
1002 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Namespaces);
1003 QCString title = lne->title();
1004 startFile(ol,"namespaces",0,title,HLI_Namespaces);
1005 startTitle(ol,0);
1006 //if (!Config_getString("PROJECT_NAME").isEmpty())
1007 //{
1008 // longTitle.prepend(Config_getString("PROJECT_NAME")+" ");
1009 //}
1010 ol.parseText(title);
1011 endTitle(ol,0,0);
1012 ol.startContents();
1013 ol.startTextBlock();
1014 Doxygen::indexList.addContentsItem(TRUE,title,0,"namespaces",0);
1015 Doxygen::indexList.incContentsDepth();
1016 ol.parseText(lne->intro());
1017 ol.endTextBlock();
1018
1019 bool first=TRUE;
1020
1021 NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
1022 NamespaceDef *nd;
1023 for (nli.toFirst();(nd=nli.current());++nli)
1024 {
1025 if (nd->isLinkableInProject())
1026 {
1027 if (first)
1028 {
1029 ol.startIndexList();
1030 first=FALSE;
1031 }
1032 //ol.writeStartAnnoItem("namespace",nd->getOutputFileBase(),0,nd->name());
1033 ol.startIndexKey();
1034 ol.writeObjectLink(0,nd->getOutputFileBase(),0,nd->displayName());
1035 ol.endIndexKey();
1036 bool hasBrief = !nd->briefDescription().isEmpty();
1037 ol.startIndexValue(hasBrief);
1038 if (hasBrief)
1039 {
1040 //ol.docify(" (");
1041 ol.parseDoc(
1042 nd->briefFile(),nd->briefLine(),
1043 nd,0,
1044 abbreviate(nd->briefDescription(),nd->displayName()),
1045 FALSE, // index words
1046 FALSE, // isExample
1047 0, // example name
1048 TRUE, // single line
1049 TRUE // link from index
1050 );
1051 //ol.docify(")");
1052 }
1053 ol.endIndexValue(nd->getOutputFileBase(),hasBrief);
1054 //ol.writeEndAnnoItem(nd->getOutputFileBase());
1055 Doxygen::indexList.addContentsItem(FALSE,nd->displayName(),nd->getReference(),nd->getOutputFileBase(),0);
1056 }
1057 }
1058 if (!first) ol.endIndexList();
1059 Doxygen::indexList.decContentsDepth();
1060 endFile(ol);
1061 ol.popGeneratorState();
1062}
1063
1064//----------------------------------------------------------------------------
1065
1066int countAnnotatedClasses(int *cp)
1067{
1068 int count=0;
1069 int countPrinted=0;
1070 ClassSDict::Iterator cli(*Doxygen::classSDict);
1071 ClassDef *cd;
1072 for (;(cd=cli.current());++cli)
1073 {
1074 if (cd->isLinkableInProject() && cd->templateMaster()==0)
1075 {
1076 if (!cd->isEmbeddedInGroupDocs())
1077 {
1078 countPrinted++;
1079 }
1080 count++;
1081 }
1082 }
1083 *cp = countPrinted;
1084 return count;
1085}
1086
1087
1088//----------------------------------------------------------------------
1089
1090void writeAnnotatedClassList(OutputList &ol)
1091{
1092 ol.startIndexList();
1093 ClassSDict::Iterator cli(*Doxygen::classSDict);
1094 ClassDef *cd;
1095
1096 // clear index
1097 int x,y;
1098 for (y=0;y<CHL_Total;y++)
1099 {
1100 for (x=0;x<256;x++)
1101 {
1102 g_classIndexLetterUsed[y][x]=FALSE;
1103 }
1104 }
1105
1106 // see which elements are in use
1107 for (cli.toFirst();(cd=cli.current());++cli)
1108 {
1109 if (cd->isLinkableInProject() && cd->templateMaster()==0)
1110 {
1111 QCString dispName = cd->displayName();
1112 int c = dispName.at(getPrefixIndex(dispName));
1113 g_classIndexLetterUsed[CHL_All][c]=TRUE;
1114 switch(cd->compoundType())
1115 {
1116 case ClassDef::Class:
1117 g_classIndexLetterUsed[CHL_Classes][c]=TRUE;
1118 break;
1119 case ClassDef::Struct:
1120 g_classIndexLetterUsed[CHL_Structs][c]=TRUE;
1121 break;
1122 case ClassDef::Union:
1123 g_classIndexLetterUsed[CHL_Unions][c]=TRUE;
1124 break;
1125 case ClassDef::Interface:
1126 g_classIndexLetterUsed[CHL_Interfaces][c]=TRUE;
1127 break;
1128 case ClassDef::Protocol:
1129 g_classIndexLetterUsed[CHL_Protocols][c]=TRUE;
1130 break;
1131 case ClassDef::Category:
1132 g_classIndexLetterUsed[CHL_Categories][c]=TRUE;
1133 break;
1134 case ClassDef::Exception:
1135 g_classIndexLetterUsed[CHL_Exceptions][c]=TRUE;
1136 break;
1137
1138 }
1139 }
1140 }
1141
1142 for (cli.toFirst();(cd=cli.current());++cli)
1143 {
1144 ol.pushGeneratorState();
1145 if (cd->isEmbeddedInGroupDocs())
1146 {
1147 ol.disable(OutputGenerator::Latex);
1148 ol.disable(OutputGenerator::RTF);
1149 }
1150 if (cd->isLinkableInProject() && cd->templateMaster()==0)
1151 {
1152 QCString type=cd->compoundTypeString();
1153 ol.startIndexKey();
1154 static bool vhdl = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
1155 if (vhdl)
1156 {
1157 QCString prot= VhdlDocGen::getProtectionName((VhdlDocGen::VhdlClasses)cd->protection());
1158 ol.docify(prot.data());
1159 ol.writeString(" ");
1160 ol.insertMemberAlign();
1161 }
1162 ol.writeObjectLink(0,cd->getOutputFileBase(),cd->anchor(),cd->displayName());
1163 ol.endIndexKey();
1164 bool hasBrief = !cd->briefDescription().isEmpty();
1165 ol.startIndexValue(hasBrief);
1166 if (hasBrief)
1167 {
1168 ol.parseDoc(
1169 cd->briefFile(),cd->briefLine(),
1170 cd,0,
1171 abbreviate(cd->briefDescription(),cd->displayName()),
1172 FALSE, // indexWords
1173 FALSE, // isExample
1174 0, // example name
1175 TRUE, // single line
1176 TRUE // link from index
1177 );
1178 }
1179 ol.endIndexValue(cd->getOutputFileBase(),hasBrief);
1180 //ol.writeEndAnnoItem(cd->getOutputFileBase());
1181 Doxygen::indexList.addContentsItem(FALSE,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor());
1182 }
1183 ol.popGeneratorState();
1184 }
1185 ol.endIndexList();
1186}
1187
1188static QCString letterToLabel(char startLetter)
1189{
1190 QCString s(5);
1191 if (isId(startLetter))
1192 {
1193 s[0]=startLetter; s[1]=0;
1194 }
1195 else
1196 {
1197 const char hex[]="0123456789abcdef";
1198 s[0]='0';
1199 s[1]='x';
1200 s[2]=hex[startLetter>>4];
1201 s[3]=hex[startLetter&0xF];
1202 s[4]=0;
1203 }
1204 return s;
1205}
1206
1207//----------------------------------------------------------------------------
1208
1209class PrefixIgnoreClassList : public ClassList
1210{
1211public:
1212 virtual int compareItems(GCI item1, GCI item2)
1213 {
1214 ClassDef *c1=(ClassDef *)item1;
1215 ClassDef *c2=(ClassDef *)item2;
1216
1217 QCString n1 = c1->className();
1218 n1.remove (0, getPrefixIndex(n1));
1219 QCString n2 = c2->className();
1220 n2.remove (0, getPrefixIndex(n2));
1221
1222 return stricmp (n1, n2);
1223 }
1224};
1225
1226// write an alphabetical index of all class with a header for each letter
1227void writeAlphabeticalClassList(OutputList &ol)
1228{
1229 //ol.startAlphabeticalIndexList();
1230 // What starting letters are used
1231 bool indexLetterUsed[256];
1232 memset (indexLetterUsed, 0, sizeof (indexLetterUsed));
1233
1234 // first count the number of headers
1235 ClassSDict::Iterator cli(*Doxygen::classSDict);
1236 ClassDef *cd;
1237 uint startLetter=0;
1238 int headerItems=0;
1239 for (;(cd=cli.current());++cli)
1240 {
1241 if (cd->isLinkableInProject() && cd->templateMaster()==0)
1242 {
1243 int index = getPrefixIndex(cd->className());
1244 //printf("name=%s index=%d\n",cd->className().data(),index);
1245 startLetter=toupper(cd->className().at(index))&0xFF;
1246 indexLetterUsed[startLetter] = true;
1247 }
1248 }
1249
1250 QCString alphaLinks = "<div class=\"qindex\">";
1251 int l;
1252 for (l = 0; l < 256; l++)
1253 {
1254 if (indexLetterUsed[l])
1255 {
1256 if (headerItems) alphaLinks += "&#160;|&#160;";
1257 headerItems++;
1258 alphaLinks += (QCString)"<a class=\"qindex\" href=\"#letter_" +
1259 (char)l + "\">" +
1260 (char)l + "</a>";
1261 }
1262 }
1263
1264 alphaLinks += "</div>\n";
1265 ol.writeString(alphaLinks);
1266
1267 ol.writeString("<table align=\"center\" width=\"95%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n");
1268
1269 // the number of columns in the table
1270 const int columns = Config_getInt("COLS_IN_ALPHA_INDEX");
1271
1272 int i,j;
1273 int totalItems = headerItems + annotatedClasses; // number of items in the table
1274 int rows = (totalItems + columns - 1)/columns; // number of rows in the table
1275 int itemsInLastRow = (totalItems + columns -1)%columns + 1; // number of items in the last row
1276
1277 //printf("headerItems=%d totalItems=%d columns=%d rows=%d itemsInLastRow=%d\n",
1278 // headerItems,totalItems,columns,rows,itemsInLastRow);
1279
1280 // Keep a list of classes for each starting letter
1281 PrefixIgnoreClassList classesByLetter[256];
1282
1283 // fill the columns with the class list (row elements in each column,
1284 // expect for the columns with number >= itemsInLastRow, which get on
1285 // item less.
1286 //int icount=0;
1287 startLetter=0;
1288 for (cli.toFirst();(cd=cli.current());++cli)
1289 {
1290 if (cd->isLinkableInProject() && cd->templateMaster()==0)
1291 {
1292 int index = getPrefixIndex(cd->className());
1293 startLetter=toupper(cd->className().at(index))&0xFF;
1294 // Do some sorting again, since the classes are sorted by name with
1295 // prefix, which should be ignored really.
1296 classesByLetter[startLetter].inSort (cd);
1297 }
1298 }
1299
1300 // create one class list for each column
1301 ClassList *colList = new ClassList[columns];
1302
1303 // fill the columns with the class list (row elements in each column,
1304 // expect for the columns with number >= itemsInLastRow, which get on
1305 // item less.
1306 int col=0,row=0;
1307 //int icount=0;
1308 startLetter=0;
1309 for (l = 0; l < 256; l++)
1310 {
1311 if (!indexLetterUsed[l]) continue;
1312
1313 // insert a new header using a dummy class pointer.
1314 colList[col].append((ClassDef *)8); // insert dummy for the header
1315 row++;
1316 if ( row >= rows + ((col<itemsInLastRow) ? 0 : -1))
1317 {
1318 // if the header is the last item in the row, we add an extra
1319 // row to make it easier to find the text of the header (this
1320 // is then contained in the next cell)
1321 colList[col].append(classesByLetter[l].at (0));
1322 col++;
1323 row=0;
1324 }
1325 uint i;
1326 for (i = 0; i < classesByLetter[l].count(); i++)
1327 {
1328 // add the class definition to the correct column list
1329 colList[col].append (classesByLetter[l].at (i));
1330 row++;
1331 if ( row >= rows + ((col<itemsInLastRow) ? 0 : -1)) { col++; row=0; }
1332 }
1333 }
1334
1335 // create iterators for each column
1336 ClassListIterator **colIterators = new ClassListIterator*[columns];
1337 for (i=0;i<columns;i++)
1338 {
1339 colIterators[i] = new ClassListIterator(colList[i]);
1340 }
1341
1342 // generate table
1343 for (i=0;i<rows;i++) // foreach table row
1344 {
1345 //ol.nextTableRow();
1346 ol.writeString("<tr>");
1347 // the last column may contain less items then the others
1348 int colsInRow = (i<rows-1) ? columns : itemsInLastRow;
1349 //printf("row [%d]\n",i);
1350 for (j=0;j<colsInRow;j++) // foreach table column
1351 {
1352 ol.writeString("<td>");
1353 ClassDef *cd = colIterators[j]->current();
1354 //printf("columns [%d] cd=%p\n",j,cd);
1355 if (cd==(ClassDef *)8) // the class pointer is really a header
1356 {
1357 cd=++(*colIterators[j]); // get the next item
1358 if (cd)
1359 {
1360 //printf("head ClassDef=%p %s\n",cd,cd ? cd->name().data() : "<none>");
1361 int index = getPrefixIndex(cd->className());
1362 startLetter=toupper(cd->className().at(index));
1363 QCString s = letterToLabel(startLetter);
1364 //ol.writeIndexHeading(s);
1365 ol.writeString("<a name=\"letter_");
1366 ol.writeString(s);
1367 ol.writeString("\"></a>");
1368 ol.writeString("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">"
1369 "<tr>"
1370 "<td><div class=\"ah\">&#160;&#160;");
1371 ol.writeString(s);
1372 ol.writeString( "&#160;&#160;</div>"
1373 "</td>"
1374 "</tr>"
1375 "</table>\n");
1376
1377 }
1378 }
1379 else if (cd) // a real class, insert a link
1380 {
1381 QCString namesp,cname;
1382 //if (cd->getNamespaceDef()) namesp=cd->getNamespaceDef()->displayName();
1383 //QCString cname=cd->className();
1384 extractNamespaceName(cd->name(),cname,namesp);
1385 QCString nsDispName;
1386 if (Config_getBool("OPTIMIZE_OUTPUT_JAVA"))
1387 {
1388 nsDispName=substitute(namesp,"::",".");
1389 }
1390 else
1391 {
1392 nsDispName=namesp.copy();
1393 }
1394 if (cname.right(2)=="-g" || cname.right(2)=="-p")
1395 {
1396 cname = cname.left(cname.length()-2);
1397 }
1398
1399 ol.writeObjectLink(cd->getReference(),
1400 cd->getOutputFileBase(),cd->anchor(),cname);
1401 if (!namesp.isEmpty())
1402 {
1403 ol.docify(" (");
1404 NamespaceDef *nd = getResolvedNamespace(namesp);
1405 if (nd && nd->isLinkable())
1406 {
1407 ol.writeObjectLink(nd->getReference(),
1408 nd->getOutputFileBase(),0,nsDispName);
1409 }
1410 else
1411 {
1412 ol.docify(nsDispName);
1413 }
1414 ol.docify(")");
1415 }
1416 ol.writeNonBreakableSpace(3);
1417 //printf("item ClassDef=%p %s\n",cd,cd ? cd->name().data() : "<none>");
1418 ++(*colIterators[j]);
1419 }
1420 //ol.endTableColumn();
1421 ol.writeString("</td>");
1422 //if (j<colsInRow-1) ol.nextTableColumn();
1423 }
1424 //ol.endTableRow();
1425 ol.writeString("</tr>");
1426 }
1427 //ol.endAlphabeticalIndexList();
1428 ol.writeString("</table>");
1429
1430 ol.writeString(alphaLinks);
1431
1432 // release the temporary memory
1433 for (i=0;i<columns;i++)
1434 {
1435 delete colIterators[i];
1436 }
1437 delete[] colIterators;
1438 delete[] colList;
1439}
1440
1441//----------------------------------------------------------------------------
1442
1443void writeAlphabeticalIndex(OutputList &ol)
1444{
1445 if (annotatedClasses==0) return;
1446 ol.pushGeneratorState();
1447 ol.disableAllBut(OutputGenerator::Html);
1448 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Classes);
1449 QCString title = lne->title();
1450 startFile(ol,"classes",0,title,HLI_Classes);
1451 startTitle(ol,0);
1452 ol.parseText(title);
1453 Doxygen::indexList.addContentsItem(TRUE,title,0,"classes",0);
1454 //ol.parseText(/*Config_getString("PROJECT_NAME")+" "+*/
1455 // (fortranOpt ? theTranslator->trCompoundIndexFortran() :
1456 // vhdlOpt ? VhdlDocGen::trDesignUnitIndex() :
1457 // theTranslator->trCompoundIndex()
1458 // ));
1459 endTitle(ol,0,0);
1460 ol.startContents();
1461 writeAlphabeticalClassList(ol);
1462 endFile(ol);
1463 ol.popGeneratorState();
1464}
1465
1466//----------------------------------------------------------------------------
1467
1468void writeAnnotatedIndex(OutputList &ol)
1469{
1470 //printf("writeAnnotatedIndex: count=%d printed=%d\n",
1471 // annotatedClasses,annotatedClassesPrinted);
1472 if (annotatedClasses==0) return;
1473
1474 ol.pushGeneratorState();
1475 ol.disable(OutputGenerator::Man);
1476 if (annotatedClassesPrinted==0)
1477 {
1478 ol.disable(OutputGenerator::Latex);
1479 ol.disable(OutputGenerator::RTF);
1480 }
1481 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassAnnotated);
1482 QCString title = lne->title();
1483 startFile(ol,"annotated",0,title,HLI_Annotated);
1484 startTitle(ol,0);
1485 //QCString longTitle = title;
1486 //if (!Config_getString("PROJECT_NAME").isEmpty())
1487 //{
1488 // longTitle.prepend(Config_getString("PROJECT_NAME")+" ");
1489 //}
1490 ol.parseText(title);
1491 endTitle(ol,0,0);
1492 ol.startContents();
1493 ol.startTextBlock();
1494 Doxygen::indexList.addContentsItem(TRUE,title,0,"annotated",0);
1495 Doxygen::indexList.incContentsDepth();
1496 ol.parseText(lne->intro());
1497 ol.endTextBlock();
1498 writeAnnotatedClassList(ol);
1499 Doxygen::indexList.decContentsDepth();
1500
1501 endFile(ol);
1502 ol.popGeneratorState();
1503}
1504
1505//----------------------------------------------------------------------------
1506static void writeClassLinkForMember(OutputList &ol,MemberDef *md,const char *separator,
1507 QCString &prevClassName)
1508{
1509 ClassDef *cd=md->getClassDef();
1510 if ( cd && prevClassName!=cd->displayName())
1511 {
1512 ol.docify(separator);
1513 ol.writeObjectLink(md->getReference(),md->getOutputFileBase(),md->anchor(),
1514 cd->displayName());
1515 ol.writeString("\n");
1516 prevClassName = cd->displayName();
1517 }
1518}
1519
1520static void writeFileLinkForMember(OutputList &ol,MemberDef *md,const char *separator,
1521 QCString &prevFileName)
1522{
1523 FileDef *fd=md->getFileDef();
1524 if (fd && prevFileName!=fd->name())
1525 {
1526 ol.docify(separator);
1527 ol.writeObjectLink(md->getReference(),md->getOutputFileBase(),md->anchor(),
1528 fd->name());
1529 ol.writeString("\n");
1530 prevFileName = fd->name();
1531 }
1532}
1533
1534static void writeNamespaceLinkForMember(OutputList &ol,MemberDef *md,const char *separator,
1535 QCString &prevNamespaceName)
1536{
1537 NamespaceDef *nd=md->getNamespaceDef();
1538 if (nd && prevNamespaceName!=nd->name())
1539 {
1540 ol.docify(separator);
1541 ol.writeObjectLink(md->getReference(),md->getOutputFileBase(),md->anchor(),
1542 nd->name());
1543 ol.writeString("\n");
1544 prevNamespaceName = nd->name();
1545 }
1546}
1547
1548static void writeMemberList(OutputList &ol,bool useSections,int page,
1549 MemberIndexList memberLists[MEMBER_INDEX_ENTRIES],
1550 DefinitionIntf::DefType type)
1551{
1552 int pi;
1553 // page==-1 => write all member indices to one page (used when total members is small)
1554 // page!=-1 => write all member for this page only (used when total member is large)
1555 int startIndex = page==-1 ? 0 : page;
1556 int endIndex = page==-1 ? MEMBER_INDEX_ENTRIES-1 : page;
1557 ASSERT((int)type<3);
1558
1559 typedef void (*writeLinkForMember_t)(OutputList &ol,MemberDef *md,const char *separator,
1560 QCString &prevNamespaceName);
1561
1562 // each index tab has its own write function
1563 static writeLinkForMember_t writeLinkForMemberMap[3] =
1564 {
1565 &writeClassLinkForMember,
1566 &writeFileLinkForMember,
1567 &writeNamespaceLinkForMember
1568 };
1569 QCString prevName;
1570 QCString prevDefName;
1571 bool first=TRUE;
1572 bool firstSection=TRUE;
1573 bool firstItem=TRUE;
1574 for (pi=startIndex; pi<=endIndex; pi++) // page==-1 => pi=[0..127], page!=-1 => pi=page
1575 {
1576 MemberIndexList *ml = &memberLists[pi];
1577 if (ml->count()==0) continue;
1578 ml->sort();
1579 QListIterator<MemberDef> mli(*ml);
1580 MemberDef *md;
1581 for (mli.toFirst();(md=mli.current());++mli)
1582 {
1583 const char *sep;
1584 bool isFunc=!md->isObjCMethod() &&
1585 (md->isFunction() || md->isSlot() || md->isSignal());
1586 QCString name=md->name();
1587 int startIndex = getPrefixIndex(name);
1588 if (QCString(name.data()+startIndex)!=prevName) // new entry
1589 {
1590 if ((prevName.isEmpty() ||
1591 tolower(name.at(startIndex))!=tolower(prevName.at(0))) &&
1592 useSections) // new section
1593 {
1594 if (!firstItem) ol.endItemListItem();
1595 if (!firstSection) ol.endItemList();
1596 char cl[2];
1597 cl[0] = tolower(name.at(startIndex));
1598 cl[1] = 0;
1599 QCString cs = letterToLabel(cl[0]);
1600 QCString anchor=(QCString)"index_"+cs;
1601 QCString title=(QCString)"- "+cl+" -";
1602 ol.startSection(anchor,title,SectionInfo::Subsection);
1603 ol.docify(title);
1604 ol.endSection(anchor,SectionInfo::Subsection);
1605 ol.startItemList();
1606 firstSection=FALSE;
1607 firstItem=TRUE;
1608 }
1609 else if (!useSections && first)
1610 {
1611 ol.startItemList();
1612 first=FALSE;
1613 }
1614
1615 // member name
1616 if (!firstItem) ol.endItemListItem();
1617 ol.startItemListItem();
1618 firstItem=FALSE;
1619 ol.docify(name);
1620 if (isFunc) ol.docify("()");
1621 ol.writeString("\n");
1622
1623 // link to class
1624 prevDefName="";
1625 sep = ": ";
1626 prevName = name.data()+startIndex;
1627 }
1628 else // same entry
1629 {
1630 sep = ", ";
1631 // link to class for other members with the same name
1632 }
1633 // write the link for the specific list type
1634 writeLinkForMemberMap[(int)type](ol,md,sep,prevDefName);
1635 }
1636 }
1637 if (!firstItem) ol.endItemListItem();
1638 ol.endItemList();
1639}
1640
1641//----------------------------------------------------------------------------
1642
1643void initClassMemberIndices()
1644{
1645 int i=0;
1646 int j=0;
1647 for (j=0;j<CMHL_Total;j++)
1648 {
1649 documentedClassMembers[j]=0;
1650 for (i=0;i<MEMBER_INDEX_ENTRIES;i++)
1651 {
1652 g_memberIndexLetterUsed[j][i].clear();
1653 }
1654 }
1655}
1656
1657void addClassMemberNameToIndex(MemberDef *md)
1658{
1659 static bool hideFriendCompounds = Config_getBool("HIDE_FRIEND_COMPOUNDS");
1660 static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
1661 ClassDef *cd=0;
1662
1663 if (vhdlOpt && (VhdlDocGen::isRecord(md) || VhdlDocGen::isUnit(md)))
1664 {
1665 VhdlDocGen::adjustRecordMember(md);
1666 }
1667
1668 if (md->isLinkableInProject() &&
1669 (cd=md->getClassDef()) &&
1670 cd->isLinkableInProject() &&
1671 cd->templateMaster()==0)
1672 {
1673 QCString n = md->name();
1674 int index = getPrefixIndex(n);
1675 uchar charCode = (uchar)n.at(index);
1676 uint letter = charCode<128 ? tolower(charCode) : charCode;
1677 if (!n.isEmpty())
1678 {
1679 bool isFriendToHide = hideFriendCompounds &&
1680 (QCString(md->typeString())=="friend class" ||
1681 QCString(md->typeString())=="friend struct" ||
1682 QCString(md->typeString())=="friend union");
1683 if (!(md->isFriend() && isFriendToHide))
1684 {
1685 g_memberIndexLetterUsed[CMHL_All][letter].append(md);
1686 documentedClassMembers[CMHL_All]++;
1687 }
1688 if (md->isFunction() || md->isSlot() || md->isSignal())
1689 {
1690 g_memberIndexLetterUsed[CMHL_Functions][letter].append(md);
1691 documentedClassMembers[CMHL_Functions]++;
1692 }
1693 else if (md->isVariable())
1694 {
1695 g_memberIndexLetterUsed[CMHL_Variables][letter].append(md);
1696 documentedClassMembers[CMHL_Variables]++;
1697 }
1698 else if (md->isTypedef())
1699 {
1700 g_memberIndexLetterUsed[CMHL_Typedefs][letter].append(md);
1701 documentedClassMembers[CMHL_Typedefs]++;
1702 }
1703 else if (md->isEnumerate())
1704 {
1705 g_memberIndexLetterUsed[CMHL_Enums][letter].append(md);
1706 documentedClassMembers[CMHL_Enums]++;
1707 }
1708 else if (md->isEnumValue())
1709 {
1710 g_memberIndexLetterUsed[CMHL_EnumValues][letter].append(md);
1711 documentedClassMembers[CMHL_EnumValues]++;
1712 }
1713 else if (md->isProperty())
1714 {
1715 g_memberIndexLetterUsed[CMHL_Properties][letter].append(md);
1716 documentedClassMembers[CMHL_Properties]++;
1717 }
1718 else if (md->isEvent())
1719 {
1720 g_memberIndexLetterUsed[CMHL_Events][letter].append(md);
1721 documentedClassMembers[CMHL_Events]++;
1722 }
1723 else if (md->isRelated() || md->isForeign() ||
1724 (md->isFriend() && !isFriendToHide))
1725 {
1726 g_memberIndexLetterUsed[CMHL_Related][letter].append(md);
1727 documentedClassMembers[CMHL_Related]++;
1728 }
1729 }
1730 }
1731}
1732
1733//----------------------------------------------------------------------------
1734
1735void initNamespaceMemberIndices()
1736{
1737 int i=0;
1738 int j=0;
1739 for (j=0;j<NMHL_Total;j++)
1740 {
1741 documentedNamespaceMembers[j]=0;
1742 for (i=0;i<MEMBER_INDEX_ENTRIES;i++)
1743 {
1744 g_namespaceIndexLetterUsed[j][i].clear();
1745 }
1746 }
1747}
1748
1749void addNamespaceMemberNameToIndex(MemberDef *md)
1750{
1751 NamespaceDef *nd=md->getNamespaceDef();
1752 if (nd && nd->isLinkableInProject() && md->isLinkableInProject())
1753 {
1754 QCString n = md->name();
1755 int index = getPrefixIndex(n);
1756 uchar charCode = (uchar)n.at(index);
1757 uint letter = charCode<128 ? tolower(charCode) : charCode;
1758 if (!n.isEmpty())
1759 {
1760 g_namespaceIndexLetterUsed[NMHL_All][letter].append(md);
1761 documentedNamespaceMembers[NMHL_All]++;
1762
1763 if (md->isFunction())
1764 {
1765 g_namespaceIndexLetterUsed[NMHL_Functions][letter].append(md);
1766 documentedNamespaceMembers[NMHL_Functions]++;
1767 }
1768 else if (md->isVariable())
1769 {
1770 g_namespaceIndexLetterUsed[NMHL_Variables][letter].append(md);
1771 documentedNamespaceMembers[NMHL_Variables]++;
1772 }
1773 else if (md->isTypedef())
1774 {
1775 g_namespaceIndexLetterUsed[NMHL_Typedefs][letter].append(md);
1776 documentedNamespaceMembers[NMHL_Typedefs]++;
1777 }
1778 else if (md->isEnumerate())
1779 {
1780 g_namespaceIndexLetterUsed[NMHL_Enums][letter].append(md);
1781 documentedNamespaceMembers[NMHL_Enums]++;
1782 }
1783 else if (md->isEnumValue())
1784 {
1785 g_namespaceIndexLetterUsed[NMHL_EnumValues][letter].append(md);
1786 documentedNamespaceMembers[NMHL_EnumValues]++;
1787 }
1788 }
1789 }
1790}
1791
1792//----------------------------------------------------------------------------
1793
1794void initFileMemberIndices()
1795{
1796 int i=0;
1797 int j=0;
1798 for (j=0;j<NMHL_Total;j++)
1799 {
1800 documentedFileMembers[j]=0;
1801 for (i=0;i<MEMBER_INDEX_ENTRIES;i++)
1802 {
1803 g_fileIndexLetterUsed[j][i].clear();
1804 }
1805 }
1806}
1807
1808void addFileMemberNameToIndex(MemberDef *md)
1809{
1810 FileDef *fd=md->getFileDef();
1811 if (fd && fd->isLinkableInProject() && md->isLinkableInProject())
1812 {
1813 QCString n = md->name();
1814 int index = getPrefixIndex(n);
1815 uchar charCode = (uchar)n.at(index);
1816 uint letter = charCode<128 ? tolower(charCode) : charCode;
1817 if (!n.isEmpty())
1818 {
1819 g_fileIndexLetterUsed[FMHL_All][letter].append(md);
1820 documentedFileMembers[FMHL_All]++;
1821
1822 if (md->isFunction())
1823 {
1824 g_fileIndexLetterUsed[FMHL_Functions][letter].append(md);
1825 documentedFileMembers[FMHL_Functions]++;
1826 }
1827 else if (md->isVariable())
1828 {
1829 g_fileIndexLetterUsed[FMHL_Variables][letter].append(md);
1830 documentedFileMembers[FMHL_Variables]++;
1831 }
1832 else if (md->isTypedef())
1833 {
1834 g_fileIndexLetterUsed[FMHL_Typedefs][letter].append(md);
1835 documentedFileMembers[FMHL_Typedefs]++;
1836 }
1837 else if (md->isEnumerate())
1838 {
1839 g_fileIndexLetterUsed[FMHL_Enums][letter].append(md);
1840 documentedFileMembers[FMHL_Enums]++;
1841 }
1842 else if (md->isEnumValue())
1843 {
1844 g_fileIndexLetterUsed[FMHL_EnumValues][letter].append(md);
1845 documentedFileMembers[FMHL_EnumValues]++;
1846 }
1847 else if (md->isDefine())
1848 {
1849 g_fileIndexLetterUsed[FMHL_Defines][letter].append(md);
1850 documentedFileMembers[FMHL_Defines]++;
1851 }
1852 }
1853 }
1854}
1855
1856//----------------------------------------------------------------------------
1857
1858void writeQuickMemberIndex(OutputList &ol,
1859 MemberIndexList charUsed[MEMBER_INDEX_ENTRIES],int page,
1860 QCString fullName,bool multiPage)
1861{
1862 bool first=TRUE;
1863 int i;
1864 startQuickIndexList(ol,TRUE);
1865 for (i=33;i<127;i++)
1866 {
1867 char is[2];is[0]=(char)i;is[1]='\0';
1868 QCString ci = letterToLabel((char)i);
1869 if (charUsed[i].count()>0)
1870 {
1871 QCString anchor;
1872 QCString extension=Doxygen::htmlFileExtension;
1873 if (!multiPage)
1874 anchor="#index_";
1875 else if (first)
1876 anchor=fullName+extension+"#index_";
1877 else
1878 anchor=fullName+QCString().sprintf("_0x%02x",i)+extension+"#index_";
1879 startQuickIndexItem(ol,anchor+ci,i==page,TRUE,first);
1880 ol.writeString(is);
1881 endQuickIndexItem(ol);
1882 first=FALSE;
1883 }
1884 }
1885 endQuickIndexList(ol);
1886}
1887
1888//----------------------------------------------------------------------------
1889
1890struct CmhlInfo
1891{
1892 CmhlInfo(const char *fn,const char *t) : fname(fn), title(t) {}
1893 const char *fname;
1894 QCString title;
1895};
1896
1897static const CmhlInfo *getCmhlInfo(int hl)
1898{
1899 static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
1900 static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
1901 static CmhlInfo cmhlInfo[] =
1902 {
1903 CmhlInfo("functions", theTranslator->trAll()),
1904 CmhlInfo("functions_func",
1905 fortranOpt ? theTranslator->trSubprograms() :
1906 vhdlOpt ? VhdlDocGen::trFunctionAndProc() :
1907 theTranslator->trFunctions()),
1908 CmhlInfo("functions_vars",theTranslator->trVariables()),
1909 CmhlInfo("functions_type",theTranslator->trTypedefs()),
1910 CmhlInfo("functions_enum",theTranslator->trEnumerations()),
1911 CmhlInfo("functions_eval",theTranslator->trEnumerationValues()),
1912 CmhlInfo("functions_prop",theTranslator->trProperties()),
1913 CmhlInfo("functions_evnt",theTranslator->trEvents()),
1914 CmhlInfo("functions_rela",theTranslator->trRelatedFunctions())
1915 };
1916 return &cmhlInfo[hl];
1917}
1918
1919static void writeClassMemberIndexFiltered(OutputList &ol, ClassMemberHighlight hl)
1920{
1921 if (documentedClassMembers[hl]==0) return;
1922
1923 static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
1924 static bool disableIndex = Config_getBool("DISABLE_INDEX");
1925
1926 bool multiPageIndex=FALSE;
1927 int numPages=1;
1928 if (documentedClassMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX)
1929 {
1930 multiPageIndex=TRUE;
1931 numPages=127;
1932 }
1933
1934 ol.pushGeneratorState();
1935 ol.disableAllBut(OutputGenerator::Html);
1936
1937 QCString extension=Doxygen::htmlFileExtension;
1938 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassMembers);
1939 QCString title = lne->title();
1940 if (hl!=CMHL_All) title+=(QCString)" - "+getCmhlInfo(hl)->title;
1941
1942 int page;
1943 bool first=TRUE;
1944 for (page=0;page<numPages;page++)
1945 {
1946 if (!multiPageIndex || g_memberIndexLetterUsed[hl][page].count()>0)
1947 {
1948 QCString fileName = getCmhlInfo(hl)->fname;
1949 if (multiPageIndex && !first)
1950 {
1951 fileName+=QCString().sprintf("_0x%02x",page);
1952 }
1953 bool quickIndex = documentedClassMembers[hl]>maxItemsBeforeQuickIndex;
1954
1955 ol.startFile(fileName+extension,0,title);
1956 ol.startQuickIndices();
1957 if (!disableIndex)
1958 {
1959 ol.writeQuickLinks(TRUE,HLI_Functions);
1960 }
1961 startQuickIndexList(ol);
1962
1963 // index item for global member list
1964 startQuickIndexItem(ol,
1965 getCmhlInfo(0)->fname+Doxygen::htmlFileExtension,hl==CMHL_All,TRUE,first);
1966 ol.writeString(fixSpaces(getCmhlInfo(0)->title));
1967 endQuickIndexItem(ol);
1968
1969 // index items per category member lists
1970 int i;
1971 for (i=1;i<CMHL_Total;i++)
1972 {
1973 if (documentedClassMembers[i]>0)
1974 {
1975 startQuickIndexItem(ol,getCmhlInfo(i)->fname+Doxygen::htmlFileExtension,hl==i,TRUE,first);
1976 ol.writeString(fixSpaces(getCmhlInfo(i)->title));
1977 //printf("multiPageIndex=%d first=%d fileName=%s file=%s title=%s\n",
1978 // multiPageIndex,first,fileName.data(),getCmhlInfo(i)->fname,getCmhlInfo(i)->title.data());
1979 endQuickIndexItem(ol);
1980 }
1981 }
1982
1983 endQuickIndexList(ol);
1984
1985 // quick alphabetical index
1986 if (quickIndex)
1987 {
1988 writeQuickMemberIndex(ol,g_memberIndexLetterUsed[hl],page,
1989 getCmhlInfo(hl)->fname,multiPageIndex);
1990 }
1991 ol.endQuickIndices();
1992
1993 if (generateTreeView)
1994 {
1995 ol.writeSplitBar(getCmhlInfo(0)->fname);
1996 }
1997
1998 ol.startContents();
1999
2000 if (hl==CMHL_All)
2001 {
2002 ol.startTextBlock();
2003 ol.parseText(lne->intro());
2004 ol.endTextBlock();
2005 }
2006 else
2007 {
2008 // hack to work around a mozilla bug, which refuses to switch to
2009 // normal lists otherwise
2010 ol.writeString("&#160;");
2011 }
2012 //ol.newParagraph(); // FIXME:PARA
2013 writeMemberList(ol,quickIndex,
2014 multiPageIndex?page:-1,
2015 g_memberIndexLetterUsed[hl],
2016 Definition::TypeClass);
2017 endFile(ol);
2018 first=FALSE;
2019 }
2020 }
2021
2022 ol.popGeneratorState();
2023}
2024
2025void writeClassMemberIndex(OutputList &ol)
2026{
2027 //bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
2028 writeClassMemberIndexFiltered(ol,CMHL_All);
2029 writeClassMemberIndexFiltered(ol,CMHL_Functions);
2030 writeClassMemberIndexFiltered(ol,CMHL_Variables);
2031 writeClassMemberIndexFiltered(ol,CMHL_Typedefs);
2032 writeClassMemberIndexFiltered(ol,CMHL_Enums);
2033 writeClassMemberIndexFiltered(ol,CMHL_EnumValues);
2034 writeClassMemberIndexFiltered(ol,CMHL_Properties);
2035 writeClassMemberIndexFiltered(ol,CMHL_Events);
2036 writeClassMemberIndexFiltered(ol,CMHL_Related);
2037
2038 if (documentedClassMembers[CMHL_All]>0)
2039 {
2040 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassMembers);
2041 Doxygen::indexList.addContentsItem(FALSE,lne->title(),0,"functions",0);
2042 }
2043}
2044
2045//----------------------------------------------------------------------------
2046
2047struct FmhlInfo
2048{
2049 FmhlInfo(const char *fn,const char *t) : fname(fn), title(t) {}
2050 const char *fname;
2051 QCString title;
2052};
2053
2054static const FmhlInfo *getFmhlInfo(int hl)
2055{
2056 static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
2057 static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
2058 static FmhlInfo fmhlInfo[] =
2059 {
2060 FmhlInfo("globals", theTranslator->trAll()),
2061 FmhlInfo("globals_func",
2062 fortranOpt ? theTranslator->trSubprograms() :
2063 vhdlOpt ? VhdlDocGen::trFunctionAndProc() :
2064 theTranslator->trFunctions()),
2065 FmhlInfo("globals_vars",theTranslator->trVariables()),
2066 FmhlInfo("globals_type",theTranslator->trTypedefs()),
2067 FmhlInfo("globals_enum",theTranslator->trEnumerations()),
2068 FmhlInfo("globals_eval",theTranslator->trEnumerationValues()),
2069 FmhlInfo("globals_defs",theTranslator->trDefines())
2070 };
2071 return &fmhlInfo[hl];
2072}
2073
2074static void writeFileMemberIndexFiltered(OutputList &ol, FileMemberHighlight hl)
2075{
2076 if (documentedFileMembers[hl]==0) return;
2077
2078 static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
2079 //static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
2080 static bool disableIndex = Config_getBool("DISABLE_INDEX");
2081
2082 bool multiPageIndex=FALSE;
2083 int numPages=1;
2084 if (documentedFileMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX)
2085 {
2086 multiPageIndex=TRUE;
2087 numPages=127;
2088 }
2089
2090 ol.pushGeneratorState();
2091 ol.disableAllBut(OutputGenerator::Html);
2092
2093 QCString extension=Doxygen::htmlFileExtension;
2094 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::FileGlobals);
2095 QCString title = lne->title();
2096
2097 int page;
2098 bool first=TRUE;
2099 for (page=0;page<numPages;page++)
2100 {
2101 if (!multiPageIndex || g_fileIndexLetterUsed[hl][page].count()>0)
2102 {
2103 QCString fileName = getFmhlInfo(hl)->fname;
2104 if (multiPageIndex && !first)
2105 {
2106 fileName+=QCString().sprintf("_0x%02x",page);
2107 }
2108 bool quickIndex = documentedFileMembers[hl]>maxItemsBeforeQuickIndex;
2109
2110 ol.startFile(fileName+extension,0,title);
2111 ol.startQuickIndices();
2112 if (!disableIndex)
2113 {
2114 ol.writeQuickLinks(TRUE,HLI_Globals);
2115 }
2116 startQuickIndexList(ol);
2117
2118 // index item for all member lists
2119 startQuickIndexItem(ol,
2120 getFmhlInfo(0)->fname+Doxygen::htmlFileExtension,hl==FMHL_All,TRUE,first);
2121 ol.writeString(fixSpaces(getFmhlInfo(0)->title));
2122 endQuickIndexItem(ol);
2123
2124 int i;
2125 // index items for per category member lists
2126 for (i=1;i<FMHL_Total;i++)
2127 {
2128 if (documentedFileMembers[i]>0)
2129 {
2130 startQuickIndexItem(ol,
2131 getFmhlInfo(i)->fname+Doxygen::htmlFileExtension,hl==i,TRUE,first);
2132 ol.writeString(fixSpaces(getFmhlInfo(i)->title));
2133 endQuickIndexItem(ol);
2134 }
2135 }
2136
2137 endQuickIndexList(ol);
2138
2139 if (quickIndex)
2140 {
2141 writeQuickMemberIndex(ol,g_fileIndexLetterUsed[hl],page,
2142 getFmhlInfo(hl)->fname,multiPageIndex);
2143 }
2144 ol.endQuickIndices();
2145
2146 if (generateTreeView)
2147 {
2148 ol.writeSplitBar(getFmhlInfo(0)->fname);
2149 }
2150
2151 ol.startContents();
2152
2153 if (hl==FMHL_All)
2154 {
2155 ol.startTextBlock();
2156 ol.parseText(lne->intro());
2157 ol.endTextBlock();
2158 }
2159 else
2160 {
2161 // hack to work around a mozilla bug, which refuses to switch to
2162 // normal lists otherwise
2163 ol.writeString("&#160;");
2164 }
2165 //ol.newParagraph(); // FIXME:PARA
2166 //writeFileMemberList(ol,quickIndex,hl,page);
2167 writeMemberList(ol,quickIndex,
2168 multiPageIndex?page:-1,
2169 g_fileIndexLetterUsed[hl],
2170 Definition::TypeFile);
2171 endFile(ol);
2172 first=FALSE;
2173 }
2174 }
2175 ol.popGeneratorState();
2176}
2177
2178void writeFileMemberIndex(OutputList &ol)
2179{
2180 writeFileMemberIndexFiltered(ol,FMHL_All);
2181 writeFileMemberIndexFiltered(ol,FMHL_Functions);
2182 writeFileMemberIndexFiltered(ol,FMHL_Variables);
2183 writeFileMemberIndexFiltered(ol,FMHL_Typedefs);
2184 writeFileMemberIndexFiltered(ol,FMHL_Enums);
2185 writeFileMemberIndexFiltered(ol,FMHL_EnumValues);
2186 writeFileMemberIndexFiltered(ol,FMHL_Defines);
2187
2188 if (documentedFileMembers[FMHL_All]>0)
2189 {
2190 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::FileGlobals);
2191 Doxygen::indexList.addContentsItem(FALSE,lne->title(),0,"globals",0);
2192 }
2193}
2194
2195//----------------------------------------------------------------------------
2196
2197struct NmhlInfo
2198{
2199 NmhlInfo(const char *fn,const char *t) : fname(fn), title(t) {}
2200 const char *fname;
2201 QCString title;
2202};
2203
2204static const NmhlInfo *getNmhlInfo(int hl)
2205{
2206 static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
2207 static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
2208 static NmhlInfo nmhlInfo[] =
2209 {
2210 NmhlInfo("namespacemembers", theTranslator->trAll()),
2211 NmhlInfo("namespacemembers_func",
2212 fortranOpt ? theTranslator->trSubprograms() :
2213 vhdlOpt ? VhdlDocGen::trFunctionAndProc() :
2214 theTranslator->trFunctions()),
2215 NmhlInfo("namespacemembers_vars",theTranslator->trVariables()),
2216 NmhlInfo("namespacemembers_type",theTranslator->trTypedefs()),
2217 NmhlInfo("namespacemembers_enum",theTranslator->trEnumerations()),
2218 NmhlInfo("namespacemembers_eval",theTranslator->trEnumerationValues())
2219 };
2220 return &nmhlInfo[hl];
2221}
2222
2223//----------------------------------------------------------------------------
2224
2225static void writeNamespaceMemberIndexFiltered(OutputList &ol,
2226 NamespaceMemberHighlight hl)
2227{
2228 if (documentedNamespaceMembers[hl]==0) return;
2229
2230 static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
2231 static bool disableIndex = Config_getBool("DISABLE_INDEX");
2232
2233 bool multiPageIndex=FALSE;
2234 int numPages=1;
2235 if (documentedNamespaceMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX)
2236 {
2237 multiPageIndex=TRUE;
2238 numPages=127;
2239 }
2240
2241 ol.pushGeneratorState();
2242 ol.disableAllBut(OutputGenerator::Html);
2243
2244 QCString extension=Doxygen::htmlFileExtension;
2245 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::NamespaceMembers);
2246 QCString title = lne->title();
2247
2248 int page;
2249 bool first=TRUE;
2250 for (page=0;page<numPages;page++)
2251 {
2252 if (!multiPageIndex || g_namespaceIndexLetterUsed[hl][page].count()>0)
2253 {
2254 QCString fileName = getNmhlInfo(hl)->fname;
2255 if (multiPageIndex && !first)
2256 {
2257 fileName+=QCString().sprintf("_0x%02x",page);
2258 }
2259 bool quickIndex = documentedNamespaceMembers[hl]>maxItemsBeforeQuickIndex;
2260
2261 ol.startFile(fileName+extension,0,title);
2262 ol.startQuickIndices();
2263 if (!disableIndex)
2264 {
2265 ol.writeQuickLinks(TRUE,HLI_NamespaceMembers);
2266 }
2267 startQuickIndexList(ol);
2268
2269 startQuickIndexItem(ol,
2270 getNmhlInfo(0)->fname+Doxygen::htmlFileExtension,hl==NMHL_All,TRUE,first);
2271 ol.writeString(fixSpaces(getNmhlInfo(0)->title));
2272 endQuickIndexItem(ol);
2273
2274 int i;
2275 for (i=1;i<NMHL_Total;i++)
2276 {
2277 if (documentedNamespaceMembers[i]>0)
2278 {
2279 startQuickIndexItem(ol,
2280 getNmhlInfo(i)->fname+Doxygen::htmlFileExtension,hl==i,TRUE,first);
2281 ol.writeString(fixSpaces(getNmhlInfo(i)->title));
2282 endQuickIndexItem(ol);
2283 }
2284 }
2285
2286 endQuickIndexList(ol);
2287
2288 if (quickIndex)
2289 {
2290 writeQuickMemberIndex(ol,g_namespaceIndexLetterUsed[hl],page,
2291 getNmhlInfo(hl)->fname,multiPageIndex);
2292 }
2293
2294 ol.endQuickIndices();
2295
2296 if (generateTreeView)
2297 {
2298 ol.writeSplitBar(getNmhlInfo(0)->fname);
2299 }
2300
2301 ol.startContents();
2302
2303 if (hl==NMHL_All)
2304 {
2305 ol.startTextBlock();
2306 ol.parseText(lne->intro());
2307 ol.endTextBlock();
2308 }
2309 else
2310 {
2311 // hack to work around a mozilla bug, which refuses to switch to
2312 // normal lists otherwise
2313 ol.writeString("&#160;");
2314 }
2315 //ol.newParagraph(); // FIXME:PARA
2316
2317 //writeNamespaceMemberList(ol,quickIndex,hl,page);
2318 writeMemberList(ol,quickIndex,
2319 multiPageIndex?page:-1,
2320 g_namespaceIndexLetterUsed[hl],
2321 Definition::TypeNamespace);
2322 endFile(ol);
2323 }
2324 }
2325 ol.popGeneratorState();
2326}
2327
2328void writeNamespaceMemberIndex(OutputList &ol)
2329{
2330 //bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
2331 writeNamespaceMemberIndexFiltered(ol,NMHL_All);
2332 writeNamespaceMemberIndexFiltered(ol,NMHL_Functions);
2333 writeNamespaceMemberIndexFiltered(ol,NMHL_Variables);
2334 writeNamespaceMemberIndexFiltered(ol,NMHL_Typedefs);
2335 writeNamespaceMemberIndexFiltered(ol,NMHL_Enums);
2336 writeNamespaceMemberIndexFiltered(ol,NMHL_EnumValues);
2337
2338 if (documentedNamespaceMembers[NMHL_All]>0)
2339 {
2340 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::NamespaceMembers);
2341 Doxygen::indexList.addContentsItem(FALSE,lne->title(),0,"namespacemembers",0);
2342 }
2343}
2344
2345//----------------------------------------------------------------------------
2346
2347#define NUM_SEARCH_INDICES 13
2348#define SEARCH_INDEX_ALL 0
2349#define SEARCH_INDEX_CLASSES 1
2350#define SEARCH_INDEX_NAMESPACES 2
2351#define SEARCH_INDEX_FILES 3
2352#define SEARCH_INDEX_FUNCTIONS 4
2353#define SEARCH_INDEX_VARIABLES 5
2354#define SEARCH_INDEX_TYPEDEFS 6
2355#define SEARCH_INDEX_ENUMS 7
2356#define SEARCH_INDEX_ENUMVALUES 8
2357#define SEARCH_INDEX_PROPERTIES 9
2358#define SEARCH_INDEX_EVENTS 10
2359#define SEARCH_INDEX_RELATED 11
2360#define SEARCH_INDEX_DEFINES 12
2361
2362class SearchIndexList : public SDict< QList<Definition> >
2363{
2364 public:
2365 SearchIndexList(int size=17) : SDict< QList<Definition> >(size,FALSE)
2366 {
2367 setAutoDelete(TRUE);
2368 }
2369 ~SearchIndexList() {}
2370 void append(Definition *d)
2371 {
2372 QList<Definition> *l = find(d->name());
2373 if (l==0)
2374 {
2375 l=new QList<Definition>;
2376 SDict< QList<Definition> >::append(d->name(),l);
2377 }
2378 l->append(d);
2379 }
2380 int compareItems(GCI item1, GCI item2)
2381 {
2382 QList<Definition> *md1=(QList<Definition> *)item1;
2383 QList<Definition> *md2=(QList<Definition> *)item2;
2384 QCString n1 = md1->first()->localName();
2385 QCString n2 = md2->first()->localName();
2386 return stricmp(n1.data(),n2.data());
2387 }
2388};
2389
2390static void addMemberToSearchIndex(
2391 SearchIndexList symbols[NUM_SEARCH_INDICES][MEMBER_INDEX_ENTRIES],
2392 int symbolCount[NUM_SEARCH_INDICES],
2393 MemberDef *md)
2394{
2395 static bool hideFriendCompounds = Config_getBool("HIDE_FRIEND_COMPOUNDS");
2396 bool isLinkable = md->isLinkable();
2397 ClassDef *cd=0;
2398 NamespaceDef *nd=0;
2399 FileDef *fd=0;
2400 if (isLinkable &&
2401 (cd=md->getClassDef()) &&
2402 cd->isLinkable() &&
2403 cd->templateMaster()==0)
2404 {
2405 QCString n = md->name();
2406 uchar charCode = (uchar)n.at(0);
2407 uint letter = charCode<128 ? tolower(charCode) : charCode;
2408 if (!n.isEmpty())
2409 {
2410 bool isFriendToHide = hideFriendCompounds &&
2411 (QCString(md->typeString())=="friend class" ||
2412 QCString(md->typeString())=="friend struct" ||
2413 QCString(md->typeString())=="friend union");
2414 if (!(md->isFriend() && isFriendToHide))
2415 {
2416 symbols[SEARCH_INDEX_ALL][letter].append(md);
2417 symbolCount[SEARCH_INDEX_ALL]++;
2418 }
2419 if (md->isFunction() || md->isSlot() || md->isSignal())
2420 {
2421 symbols[SEARCH_INDEX_FUNCTIONS][letter].append(md);
2422 symbolCount[SEARCH_INDEX_FUNCTIONS]++;
2423 }
2424 else if (md->isVariable())
2425 {
2426 symbols[SEARCH_INDEX_VARIABLES][letter].append(md);
2427 symbolCount[SEARCH_INDEX_VARIABLES]++;
2428 }
2429 else if (md->isTypedef())
2430 {
2431 symbols[SEARCH_INDEX_TYPEDEFS][letter].append(md);
2432 symbolCount[SEARCH_INDEX_TYPEDEFS]++;
2433 }
2434 else if (md->isEnumerate())
2435 {
2436 symbols[SEARCH_INDEX_ENUMS][letter].append(md);
2437 symbolCount[SEARCH_INDEX_ENUMS]++;
2438 }
2439 else if (md->isEnumValue())
2440 {
2441 symbols[SEARCH_INDEX_ENUMVALUES][letter].append(md);
2442 symbolCount[SEARCH_INDEX_ENUMVALUES]++;
2443 }
2444 else if (md->isProperty())
2445 {
2446 symbols[SEARCH_INDEX_PROPERTIES][letter].append(md);
2447 symbolCount[SEARCH_INDEX_PROPERTIES]++;
2448 }
2449 else if (md->isEvent())
2450 {
2451 symbols[SEARCH_INDEX_EVENTS][letter].append(md);
2452 symbolCount[SEARCH_INDEX_EVENTS]++;
2453 }
2454 else if (md->isRelated() || md->isForeign() ||
2455 (md->isFriend() && !isFriendToHide))
2456 {
2457 symbols[SEARCH_INDEX_RELATED][letter].append(md);
2458 symbolCount[SEARCH_INDEX_RELATED]++;
2459 }
2460 }
2461 }
2462 else if (isLinkable &&
2463 (((nd=md->getNamespaceDef()) && nd->isLinkable()) ||
2464 ((fd=md->getFileDef()) && fd->isLinkable())
2465 )
2466 )
2467 {
2468 QCString n = md->name();
2469 uchar charCode = (uchar)n.at(0);
2470 uint letter = charCode<128 ? tolower(charCode) : charCode;
2471 if (!n.isEmpty())
2472 {
2473 symbols[SEARCH_INDEX_ALL][letter].append(md);
2474 symbolCount[SEARCH_INDEX_ALL]++;
2475
2476 if (md->isFunction())
2477 {
2478 symbols[SEARCH_INDEX_FUNCTIONS][letter].append(md);
2479 symbolCount[SEARCH_INDEX_FUNCTIONS]++;
2480 }
2481 else if (md->isVariable())
2482 {
2483 symbols[SEARCH_INDEX_VARIABLES][letter].append(md);
2484 symbolCount[SEARCH_INDEX_VARIABLES]++;
2485 }
2486 else if (md->isTypedef())
2487 {
2488 symbols[SEARCH_INDEX_TYPEDEFS][letter].append(md);
2489 symbolCount[SEARCH_INDEX_TYPEDEFS]++;
2490 }
2491 else if (md->isEnumerate())
2492 {
2493 symbols[SEARCH_INDEX_ENUMS][letter].append(md);
2494 symbolCount[SEARCH_INDEX_ENUMS]++;
2495 }
2496 else if (md->isEnumValue())
2497 {
2498 symbols[SEARCH_INDEX_ENUMVALUES][letter].append(md);
2499 symbolCount[SEARCH_INDEX_ENUMVALUES]++;
2500 }
2501 else if (md->isDefine())
2502 {
2503 symbols[SEARCH_INDEX_DEFINES][letter].append(md);
2504 symbolCount[SEARCH_INDEX_DEFINES]++;
2505 }
2506 }
2507 }
2508}
2509
2510static QCString searchId(const QCString &s)
2511{
2512 int c;
2513 uint i;
2514 QCString result;
2515 for (i=0;i<s.length();i++)
2516 {
2517 c=s.at(i);
2518 if ((c>='0' && c<='9') || (c>='A' && c<='Z') || (c>='a' && c<='z'))
2519 {
2520 result+=(char)tolower(c);
2521 }
2522 else
2523 {
2524 char val[4];
2525 sprintf(val,"_%02x",(uchar)c);
2526 result+=val;
2527 }
2528 }
2529 return result;
2530}
2531
2532static int g_searchIndexCount[NUM_SEARCH_INDICES];
2533static SearchIndexList g_searchIndexSymbols[NUM_SEARCH_INDICES][MEMBER_INDEX_ENTRIES];
2534static const char *g_searchIndexName[NUM_SEARCH_INDICES] =
2535{
2536 "all",
2537 "classes",
2538 "namespaces",
2539 "files",
2540 "functions",
2541 "variables",
2542 "typedefs",
2543 "enums",
2544 "enumvalues",
2545 "properties",
2546 "events",
2547 "related",
2548 "defines"
2549};
2550
2551
2552class SearchIndexCategoryMapping
2553{
2554 public:
2555 SearchIndexCategoryMapping()
2556 {
2557 categoryLabel[SEARCH_INDEX_ALL] = theTranslator->trAll();
2558 categoryLabel[SEARCH_INDEX_CLASSES] = theTranslator->trClasses();
2559 categoryLabel[SEARCH_INDEX_NAMESPACES] = theTranslator->trNamespace(TRUE,FALSE);
2560 categoryLabel[SEARCH_INDEX_FILES] = theTranslator->trFile(TRUE,FALSE);
2561 categoryLabel[SEARCH_INDEX_FUNCTIONS] = theTranslator->trFunctions();
2562 categoryLabel[SEARCH_INDEX_VARIABLES] = theTranslator->trVariables();
2563 categoryLabel[SEARCH_INDEX_TYPEDEFS] = theTranslator->trTypedefs();
2564 categoryLabel[SEARCH_INDEX_ENUMS] = theTranslator->trEnumerations();
2565 categoryLabel[SEARCH_INDEX_ENUMVALUES] = theTranslator->trEnumerationValues();
2566 categoryLabel[SEARCH_INDEX_PROPERTIES] = theTranslator->trProperties();
2567 categoryLabel[SEARCH_INDEX_EVENTS] = theTranslator->trEvents();
2568 categoryLabel[SEARCH_INDEX_RELATED] = theTranslator->trFriends();
2569 categoryLabel[SEARCH_INDEX_DEFINES] = theTranslator->trDefines();
2570 }
2571 QCString categoryLabel[NUM_SEARCH_INDICES];
2572};
2573
2574void writeJavascriptSearchIndex()
2575{
2576 if (!Config_getBool("GENERATE_HTML")) return;
2577 //static bool treeView = Config_getBool("GENERATE_TREEVIEW");
2578
2579 ClassSDict::Iterator cli(*Doxygen::classSDict);
2580 ClassDef *cd;
2581 for (;(cd=cli.current());++cli)
2582 {
2583 uchar charCode = (uchar)cd->localName().at(0);
2584 uint letter = charCode<128 ? tolower(charCode) : charCode;
2585 if (cd->isLinkable() && isId(letter))
2586 {
2587 g_searchIndexSymbols[SEARCH_INDEX_ALL][letter].append(cd);
2588 g_searchIndexSymbols[SEARCH_INDEX_CLASSES][letter].append(cd);
2589 g_searchIndexCount[SEARCH_INDEX_ALL]++;
2590 g_searchIndexCount[SEARCH_INDEX_CLASSES]++;
2591 }
2592 }
2593 NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
2594 NamespaceDef *nd;
2595 for (;(nd=nli.current());++nli)
2596 {
2597 uchar charCode = (uchar)nd->name().at(0);
2598 uint letter = charCode<128 ? tolower(charCode) : charCode;
2599 if (nd->isLinkable() && isId(letter))
2600 {
2601 g_searchIndexSymbols[SEARCH_INDEX_ALL][letter].append(nd);
2602 g_searchIndexSymbols[SEARCH_INDEX_NAMESPACES][letter].append(nd);
2603 g_searchIndexCount[SEARCH_INDEX_ALL]++;
2604 g_searchIndexCount[SEARCH_INDEX_NAMESPACES]++;
2605 }
2606 }
2607 FileNameListIterator fnli(*Doxygen::inputNameList);
2608 FileName *fn;
2609 for (;(fn=fnli.current());++fnli)
2610 {
2611 FileNameIterator fni(*fn);
2612 FileDef *fd;
2613 for (;(fd=fni.current());++fni)
2614 {
2615 uchar charCode = (uchar)fd->name().at(0);
2616 uint letter = charCode<128 ? tolower(charCode) : charCode;
2617 if (fd->isLinkable() && isId(letter))
2618 {
2619 g_searchIndexSymbols[SEARCH_INDEX_ALL][letter].append(fd);
2620 g_searchIndexSymbols[SEARCH_INDEX_FILES][letter].append(fd);
2621 g_searchIndexCount[SEARCH_INDEX_ALL]++;
2622 g_searchIndexCount[SEARCH_INDEX_FILES]++;
2623 }
2624 }
2625 }
2626 {
2627 MemberNameSDict::Iterator mnli(*Doxygen::memberNameSDict);
2628 MemberName *mn;
2629 // for each member name
2630 for (mnli.toFirst();(mn=mnli.current());++mnli)
2631 {
2632 MemberDef *md;
2633 MemberNameIterator mni(*mn);
2634 // for each member definition
2635 for (mni.toFirst();(md=mni.current());++mni)
2636 {
2637 addMemberToSearchIndex(g_searchIndexSymbols,g_searchIndexCount,md);
2638 }
2639 }
2640 }
2641 {
2642 MemberNameSDict::Iterator fnli(*Doxygen::functionNameSDict);
2643 MemberName *mn;
2644 // for each member name
2645 for (fnli.toFirst();(mn=fnli.current());++fnli)
2646 {
2647 MemberDef *md;
2648 MemberNameIterator mni(*mn);
2649 // for each member definition
2650 for (mni.toFirst();(md=mni.current());++mni)
2651 {
2652 addMemberToSearchIndex(g_searchIndexSymbols,g_searchIndexCount,md);
2653 }
2654 }
2655 }
2656
2657 int i,p;
2658 for (i=0;i<NUM_SEARCH_INDICES;i++)
2659 {
2660 for (p=0;p<MEMBER_INDEX_ENTRIES;p++)
2661 {
2662 if (g_searchIndexSymbols[i][p].count()>0)
2663 {
2664 g_searchIndexSymbols[i][p].sort();
2665 }
2666 }
2667 }
2668
2669 QCString searchDirName = Config_getString("HTML_OUTPUT")+"/search";
2670
2671 for (i=0;i<NUM_SEARCH_INDICES;i++)
2672 {
2673 for (p=0;p<MEMBER_INDEX_ENTRIES;p++)
2674 {
2675 if (g_searchIndexSymbols[i][p].count()>0)
2676 {
2677 QCString fileName;
2678 fileName.sprintf("/%s_%02x.html",g_searchIndexName[i],p);
2679 fileName.prepend(searchDirName);
2680 QFile outFile(fileName);
2681 if (outFile.open(IO_WriteOnly))
2682 {
2683 FTextStream t(&outFile);
2684 t << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\""
2685 " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" << endl;
2686 t << "<html><head><title></title>" << endl;
2687 t << "<meta http-equiv=\"Content-Type\" content=\"text/xhtml;charset=UTF-8\"/>" << endl;
2688 t << "<link rel=\"stylesheet\" type=\"text/css\" href=\"search.css\"/>" << endl;
2689 t << "<script type=\"text/javascript\" src=\"search.js\"></script>" << endl;
2690 t << "</head>" << endl;
2691 t << "<body class=\"SRPage\">" << endl;
2692 t << "<div id=\"SRIndex\">" << endl;
2693 t << "<div class=\"SRStatus\" id=\"Loading\">" << theTranslator->trLoading() << "</div>" << endl;
2694
2695 SDict<QList<Definition> >::Iterator li(g_searchIndexSymbols[i][p]);
2696 QList<Definition> *dl;
2697 int itemCount=0;
2698 for (li.toFirst();(dl=li.current());++li)
2699 {
2700 Definition *d = dl->first();
2701 QCString id = d->localName();
2702 t << "<div class=\"SRResult\" id=\"SR_"
2703 << searchId(d->localName()) << "\">" << endl;
2704 t << " <div class=\"SREntry\">\n";
2705 if (dl->count()==1) // item with a unique name
2706 {
2707 MemberDef *md = 0;
2708 bool isMemberDef = d->definitionType()==Definition::TypeMember;
2709 if (isMemberDef) md = (MemberDef*)d;
2710 t << " <a id=\"Item" << itemCount << "\" "
2711 << "onkeydown=\""
2712 << "return searchResults.Nav(event," << itemCount << ")\" "
2713 << "onkeypress=\""
2714 << "return searchResults.Nav(event," << itemCount << ")\" "
2715 << "onkeyup=\""
2716 << "return searchResults.Nav(event," << itemCount << ")\" "
2717 << "class=\"SRSymbol\" ";
2718 t << externalLinkTarget() << "href=\"" << externalRef("../",d->getReference(),TRUE);
2719 t << d->getOutputFileBase() << Doxygen::htmlFileExtension;
2720 if (isMemberDef)
2721 {
2722 t << "#" << ((MemberDef *)d)->anchor();
2723 }
2724 t << "\"";
2725 static bool extLinksInWindow = Config_getBool("EXT_LINKS_IN_WINDOW");
2726 if (!extLinksInWindow || d->getReference().isEmpty())
2727 {
2728 t << " target=\"";
2729 /*if (treeView) t << "basefrm"; else*/ t << "_parent";
2730 t << "\"";
2731 }
2732 t << ">";
2733 t << convertToXML(d->localName());
2734 t << "</a>" << endl;
2735 if (d->getOuterScope()!=Doxygen::globalScope)
2736 {
2737 t << " <span class=\"SRScope\">"
2738 << convertToXML(d->getOuterScope()->name())
2739 << "</span>" << endl;
2740 }
2741 else if (isMemberDef)
2742 {
2743 FileDef *fd = ((MemberDef *)d)->getBodyDef();
2744 if (fd==0) fd = ((MemberDef *)d)->getFileDef();
2745 if (fd)
2746 {
2747 t << " <span class=\"SRScope\">"
2748 << convertToXML(fd->localName())
2749 << "</span>" << endl;
2750 }
2751 }
2752 }
2753 else // multiple items with the same name
2754 {
2755 t << " <a id=\"Item" << itemCount << "\" "
2756 << "onkeydown=\""
2757 << "return searchResults.Nav(event," << itemCount << ")\" "
2758 << "onkeypress=\""
2759 << "return searchResults.Nav(event," << itemCount << ")\" "
2760 << "onkeyup=\""
2761 << "return searchResults.Nav(event," << itemCount << ")\" "
2762 << "class=\"SRSymbol\" "
2763 << "href=\"javascript:searchResults.Toggle('SR_"
2764 << searchId(d->localName()) << "')\">"
2765 << convertToXML(d->localName()) << "</a>" << endl;
2766 t << " <div class=\"SRChildren\">" << endl;
2767
2768 QListIterator<Definition> di(*dl);
2769 bool overloadedFunction = FALSE;
2770 Definition *prevScope = 0;
2771 int childCount=0;
2772 for (di.toFirst();(d=di.current());)
2773 {
2774 ++di;
2775 Definition *scope = d->getOuterScope();
2776 Definition *next = di.current();
2777 Definition *nextScope = 0;
2778 MemberDef *md = 0;
2779 bool isMemberDef = d->definitionType()==Definition::TypeMember;
2780 if (isMemberDef) md = (MemberDef*)d;
2781 if (next) nextScope = next->getOuterScope();
2782
2783 t << " <a id=\"Item" << itemCount << "_c"
2784 << childCount << "\" "
2785 << "onkeydown=\""
2786 << "return searchResults.NavChild(event,"
2787 << itemCount << "," << childCount << ")\" "
2788 << "onkeypress=\""
2789 << "return searchResults.NavChild(event,"
2790 << itemCount << "," << childCount << ")\" "
2791 << "onkeyup=\""
2792 << "return searchResults.NavChild(event,"
2793 << itemCount << "," << childCount << ")\" "
2794 << "class=\"SRScope\" ";
2795 if (!d->getReference().isEmpty())
2796 {
2797 t << externalLinkTarget() << externalRef("../",d->getReference(),FALSE);
2798 }
2799 t << "href=\"" << externalRef("../",d->getReference(),TRUE);
2800 t << d->getOutputFileBase() << Doxygen::htmlFileExtension;
2801 if (isMemberDef)
2802 {
2803 t << "#" << ((MemberDef *)d)->anchor();
2804 }
2805 t << "\"";
2806 static bool extLinksInWindow = Config_getBool("EXT_LINKS_IN_WINDOW");
2807 if (!extLinksInWindow || d->getReference().isEmpty())
2808 {
2809 t << " target=\"";
2810 /*if (treeView) t << "basefrm"; else*/ t << "_parent";
2811 t << "\"";
2812 }
2813 t << ">";
2814 bool found=FALSE;
2815 overloadedFunction = ((prevScope!=0 && scope==prevScope) ||
2816 (scope && scope==nextScope)
2817 ) && md &&
2818 (md->isFunction() || md->isSlot());
2819 QCString prefix;
2820 if (md) prefix=convertToXML(md->localName());
2821 if (overloadedFunction) // overloaded member function
2822 {
2823 prefix+=convertToXML(md->argsString());
2824 // show argument list to disambiguate overloaded functions
2825 }
2826 else if (md) // unique member function
2827 {
2828 prefix+="()"; // only to show it is a function
2829 }
2830 if (d->definitionType()==Definition::TypeClass)
2831 {
2832 t << convertToXML(((ClassDef*)d)->displayName());
2833 found = TRUE;
2834 }
2835 else if (d->definitionType()==Definition::TypeNamespace)
2836 {
2837 t << convertToXML(((NamespaceDef*)d)->displayName());
2838 found = TRUE;
2839 }
2840 else if (scope==0 || scope==Doxygen::globalScope) // in global scope
2841 {
2842 if (md)
2843 {
2844 FileDef *fd = md->getBodyDef();
2845 if (fd==0) fd = md->getFileDef();
2846 if (fd)
2847 {
2848 if (!prefix.isEmpty()) prefix+=":&#160;";
2849 t << prefix << convertToXML(fd->localName());
2850 found = TRUE;
2851 }
2852 }
2853 }
2854 else if (md && (md->getClassDef() || md->getNamespaceDef()))
2855 // member in class or namespace scope
2856 {
2857 static bool optimizeOutputJava = Config_getBool("OPTIMIZE_OUTPUT_JAVA");
2858 t << convertToXML(d->getOuterScope()->qualifiedName()) << (optimizeOutputJava ? "." : "::");
2859 t << prefix;
2860 found = TRUE;
2861 }
2862 else if (scope) // some thing else? -> show scope
2863 {
2864 t << prefix << convertToXML(scope->name());
2865 found = TRUE;
2866 }
2867 if (!found) // fallback
2868 {
2869 t << prefix << "("+theTranslator->trGlobalNamespace()+")";
2870 }
2871 t << "</a>" << endl;
2872 prevScope = scope;
2873 childCount++;
2874 }
2875 t << " </div>" << endl; // SRChildren
2876 }
2877 t << " </div>" << endl; // SREntry
2878 t << "</div>" << endl; // SRResult
2879 itemCount++;
2880 }
2881 t << "<div class=\"SRStatus\" id=\"Searching\">"
2882 << theTranslator->trSearching() << "</div>" << endl;
2883 t << "<div class=\"SRStatus\" id=\"NoMatches\">"
2884 << theTranslator->trNoMatches() << "</div>" << endl;
2885
2886 t << "<script type=\"text/javascript\"><!--" << endl;
2887 t << "document.getElementById(\"Loading\").style.display=\"none\";" << endl;
2888 t << "document.getElementById(\"NoMatches\").style.display=\"none\";" << endl;
2889 t << "var searchResults = new SearchResults(\"searchResults\");" << endl;
2890 t << "searchResults.Search();" << endl;
2891 t << "--></script>" << endl;
2892
2893 t << "</div>" << endl; // SRIndex
2894
2895 t << "</body>" << endl;
2896 t << "</html>" << endl;
2897
2898 }
2899 else
2900 {
2901 err("Failed to open file '%s' for writing...\n",fileName.data());
2902 }
2903 }
2904 }
2905 }
2906 //ol.popGeneratorState();
2907
2908 {
2909 QFile f(searchDirName+"/search.js");
2910 if (f.open(IO_WriteOnly))
2911 {
2912 FTextStream t(&f);
2913 t << "// Search script generated by doxygen" << endl;
2914 t << "// Copyright (C) 2009 by Dimitri van Heesch." << endl << endl;
2915 t << "// The code in this file is loosly based on main.js, part of Natural Docs," << endl;
2916 t << "// which is Copyright (C) 2003-2008 Greg Valure" << endl;
2917 t << "// Natural Docs is licensed under the GPL." << endl << endl;
2918 t << "var indexSectionsWithContent =" << endl;
2919 t << "{" << endl;
2920 bool first=TRUE;
2921 int j=0;
2922 for (i=0;i<NUM_SEARCH_INDICES;i++)
2923 {
2924 if (g_searchIndexCount[i]>0)
2925 {
2926 if (!first) t << "," << endl;
2927 t << " " << j << ": \"";
2928 for (p=0;p<MEMBER_INDEX_ENTRIES;p++)
2929 {
2930 t << (g_searchIndexSymbols[i][p].count()>0 ? "1" : "0");
2931 }
2932 t << "\"";
2933 first=FALSE;
2934 j++;
2935 }
2936 }
2937 if (!first) t << "\n";
2938 t << "};" << endl << endl;
2939 t << "var indexSectionNames =" << endl;
2940 t << "{" << endl;
2941 first=TRUE;
2942 j=0;
2943 for (i=0;i<NUM_SEARCH_INDICES;i++)
2944 {
2945 if (g_searchIndexCount[i]>0)
2946 {
2947 if (!first) t << "," << endl;
2948 t << " " << j << ": \"" << g_searchIndexName[i] << "\"";
2949 first=FALSE;
2950 j++;
2951 }
2952 }
2953 if (!first) t << "\n";
2954 t << "};" << endl << endl;
2955 t << search_script;
2956 }
2957 }
2958 {
2959 QFile f(searchDirName+"/nomatches.html");
2960 if (f.open(IO_WriteOnly))
2961 {
2962 FTextStream t(&f);
2963 t << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" "
2964 "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" << endl;
2965 t << "<html><head><title></title>" << endl;
2966 t << "<meta http-equiv=\"Content-Type\" content=\"text/xhtml;charset=UTF-8\"/>" << endl;
2967 t << "<link rel=\"stylesheet\" type=\"text/css\" href=\"search.css\"/>" << endl;
2968 t << "<script type=\"text/javascript\" src=\"search.js\"></script>" << endl;
2969 t << "</head>" << endl;
2970 t << "<body class=\"SRPage\">" << endl;
2971 t << "<div id=\"SRIndex\">" << endl;
2972 t << "<div class=\"SRStatus\" id=\"NoMatches\">"
2973 << theTranslator->trNoMatches() << "</div>" << endl;
2974 t << "</div>" << endl;
2975 t << "</body>" << endl;
2976 t << "</html>" << endl;
2977 }
2978 }
2979 Doxygen::indexList.addStyleSheetFile("search/search.js");
2980}
2981
2982void writeSearchCategories(FTextStream &t)
2983{
2984 static SearchIndexCategoryMapping map;
2985 int i,j=0;
2986 for (i=0;i<NUM_SEARCH_INDICES;i++)
2987 {
2988 if (g_searchIndexCount[i]>0)
2989 {
2990 t << "<a class=\"SelectItem\" href=\"javascript:void(0)\" "
2991 << "onclick=\"searchBox.OnSelectItem(" << j << ")\">"
2992 << "<span class=\"SelectionMark\">&#160;</span>"
2993 << convertToXML(map.categoryLabel[i])
2994 << "</a>";
2995 j++;
2996 }
2997 }
2998}
2999
3000//----------------------------------------------------------------------------
3001
3002void writeExampleIndex(OutputList &ol)
3003{
3004 if (Doxygen::exampleSDict->count()==0) return;
3005 ol.pushGeneratorState();
3006 ol.disable(OutputGenerator::Man);
3007 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Examples);
3008 QCString title = lne->title();
3009 startFile(ol,"examples",0,title,HLI_Examples);
3010 startTitle(ol,0);
3011 ol.parseText(title);
3012 endTitle(ol,0,0);
3013 ol.startContents();
3014 ol.startTextBlock();
3015 Doxygen::indexList.addContentsItem(TRUE,title,0,"examples",0);
3016 Doxygen::indexList.incContentsDepth();
3017 ol.parseText(lne->intro());
3018 ol.endTextBlock();
3019 ol.startItemList();
3020 PageSDict::Iterator pdi(*Doxygen::exampleSDict);
3021 PageDef *pd=0;
3022 for (pdi.toFirst();(pd=pdi.current());++pdi)
3023 {
3024 ol.startItemListItem();
3025 QCString n=pd->getOutputFileBase();
3026 if (!pd->title().isEmpty())
3027 {
3028 ol.writeObjectLink(0,n,0,pd->title());
3029 Doxygen::indexList.addContentsItem(FALSE,filterTitle(pd->title()),pd->getReference(),n,0);
3030 }
3031 else
3032 {
3033 ol.writeObjectLink(0,n,0,pd->name());
3034 Doxygen::indexList.addContentsItem(FALSE,pd->name(),pd->getReference(),n,0);
3035 }
3036 ol.endItemListItem();
3037 ol.writeString("\n");
3038 }
3039 ol.endItemList();
3040 Doxygen::indexList.decContentsDepth();
3041 endFile(ol);
3042 ol.popGeneratorState();
3043}
3044
3045
3046//----------------------------------------------------------------------------
3047
3048template<typename T>
3049bool writeMemberNavIndex(FTextStream &t,
3050 int indent,
3051 int n,
3052 int documentedMembers[],
3053 MemberIndexList indexLetterUsed[][MEMBER_INDEX_ENTRIES],
3054 const T *(*getInfo)(int),
3055 bool &first
3056 )
3057
3058{
3059 bool found=FALSE;
3060 QCString indentStr;
3061 indentStr.fill(' ',indent*2);
3062 // index items per category member lists
3063 int i;
3064 for (i=0;i<n;i++)
3065 {
3066 bool hasIndex = documentedMembers[i]>0;
3067 bool quickIndex = documentedMembers[i]>maxItemsBeforeQuickIndex;
3068 bool multiIndexPage = documentedMembers[i]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX;
3069 if (hasIndex)
3070 {
3071 // terminate previous entry
3072 if (!first) t << "," << endl;
3073 first = FALSE;
3074
3075 // start entry
3076 if (!found)
3077 {
3078 t << "[" << endl;
3079 }
3080 found = TRUE;
3081
3082 t << indentStr << " [ ";
3083 t << "\"" << fixSpaces(getInfo(i)->title) << "\", ";
3084 t << "\"" << getInfo(i)->fname << Doxygen::htmlFileExtension << "\", ";
3085 bool firstPage=TRUE;
3086 if (quickIndex)
3087 {
3088 t << "[ " << endl;
3089 int j;
3090 for (j=33;j<127;j++)
3091 {
3092 if (indexLetterUsed[i][j].count()>0)
3093 {
3094 if (!firstPage) t << "," << endl;
3095 QCString fullName = getInfo(i)->fname;
3096 QCString extension = Doxygen::htmlFileExtension;
3097 QCString anchor;
3098 if (firstPage || !multiIndexPage)
3099 anchor=fullName+extension+"#index_";
3100 else
3101 anchor=fullName+QCString().sprintf("_0x%02x",j)+extension+"#index_";
3102 char is[2];is[0]=(char)j;is[1]='\0';
3103 QCString ci = letterToLabel((char)j);
3104 t << indentStr << " [ ";
3105 t << "\"" << is << "\", ";
3106 t << "\"" << anchor << ci << "\", null ]";
3107 firstPage=FALSE;
3108 }
3109 }
3110 t << endl << indentStr << " ] ]";
3111 }
3112 else
3113 {
3114 t << "null" << " ]";
3115 }
3116 }
3117 }
3118 return found;
3119}
3120
3121//----------------------------------------------------------------------------
3122
3123bool writeFullNavIndex(FTextStream &t, LayoutNavEntry *root,int indent,bool &first)
3124{
3125 static struct NavEntryCountMap
3126 {
3127 LayoutNavEntry::Kind kind;
3128 bool hasItems;
3129 } navEntryCountMap[] =
3130 {
3131 { LayoutNavEntry::MainPage, TRUE },
3132 { LayoutNavEntry::Pages, indexedPages>0 },
3133 { LayoutNavEntry::Modules, documentedGroups>0 },
3134 { LayoutNavEntry::Namespaces, documentedNamespaces>0 },
3135 { LayoutNavEntry::NamespaceMembers, documentedNamespaceMembers[NMHL_All]>0 },
3136 { LayoutNavEntry::Classes, annotatedClasses>0 },
3137 { LayoutNavEntry::ClassAnnotated, annotatedClasses>0 },
3138 { LayoutNavEntry::ClassHierarchy, hierarchyClasses>0 },
3139 { LayoutNavEntry::ClassMembers, documentedClassMembers[CMHL_All]>0 },
3140 { LayoutNavEntry::Files, documentedFiles>0 },
3141 { LayoutNavEntry::FileGlobals, documentedFileMembers[FMHL_All]>0 },
3142 { LayoutNavEntry::Dirs, documentedDirs>0 },
3143 { LayoutNavEntry::Examples, Doxygen::exampleSDict->count()>0 }
3144 };
3145
3146 QCString indentStr;
3147 indentStr.fill(' ',indent*2);
3148 bool found=FALSE;
3149 if (root->children().count()>0)
3150 {
3151 QListIterator<LayoutNavEntry> li(root->children());
3152 LayoutNavEntry *entry;
3153 for (li.toFirst();(entry=li.current());++li)
3154 {
3155 if (navEntryCountMap[entry->kind()].hasItems && entry->visible())
3156 {
3157 // terminate previous entry
3158 if (!first) t << "," << endl;
3159 first = FALSE;
3160
3161 // start entry
3162 if (!found)
3163 {
3164 t << "[" << endl;
3165 }
3166 found = TRUE;
3167
3168 bool emptySection=TRUE;
3169 t << indentStr << " [ ";
3170 t << "\"" << fixSpaces(entry->title()) << "\", ";
3171 t << "\"" << entry->baseFile() << Doxygen::htmlFileExtension << "\", ";
3172
3173 // write children (if any)
3174 bool firstChild=TRUE;
3175 if (entry->kind()==LayoutNavEntry::ClassMembers)
3176 {
3177 emptySection = !writeMemberNavIndex(t,indent+1,CMHL_Total,documentedClassMembers,g_memberIndexLetterUsed,&getCmhlInfo,firstChild);
3178 }
3179 else if (entry->kind()==LayoutNavEntry::NamespaceMembers)
3180 {
3181 emptySection = !writeMemberNavIndex(t,indent+1,NMHL_Total,documentedNamespaceMembers,g_namespaceIndexLetterUsed,&getNmhlInfo,firstChild);
3182 }
3183 else if (entry->kind()==LayoutNavEntry::FileGlobals)
3184 {
3185 emptySection = !writeMemberNavIndex(t,indent+1,FMHL_Total,documentedFileMembers,g_fileIndexLetterUsed,&getFmhlInfo,firstChild);
3186 }
3187 else
3188 {
3189 emptySection = !writeFullNavIndex(t,entry,indent+1,firstChild);
3190 }
3191 // end entry
3192 if (emptySection) // entry without children
3193 t << "null ]";
3194 else // entry with children
3195 t << endl << indentStr << " ] ]";
3196 }
3197 }
3198 }
3199 return found;
3200}
3201
3202//----------------------------------------------------------------------------
3203
3204void countRelatedPages(int &docPages,int &indexPages)
3205{
3206 docPages=indexPages=0;
3207 PageSDict::Iterator pdi(*Doxygen::pageSDict);
3208 PageDef *pd=0;
3209 for (pdi.toFirst();(pd=pdi.current());++pdi)
3210 {
3211 if ( pd->visibleInIndex())
3212 {
3213 indexPages++;
3214 }
3215 if ( pd->documentedPage())
3216 {
3217 docPages++;
3218 }
3219 }
3220}
3221
3222//----------------------------------------------------------------------------
3223
3224static void writeSubPages(PageDef *pd)
3225{
3226 //printf("Write subpages(%s #=%d)\n",pd->name().data(),pd->getSubPages() ? pd->getSubPages()->count() : 0 );
3227 Doxygen::indexList.incContentsDepth();
3228
3229 PageSDict *subPages = pd->getSubPages();
3230 if (subPages)
3231 {
3232 PageSDict::Iterator pi(*subPages);
3233 PageDef *subPage;
3234 for (pi.toFirst();(subPage=pi.current());++pi)
3235 {
3236 QCString pageTitle;
3237
3238 if (subPage->title().isEmpty())
3239 pageTitle=subPage->name();
3240 else
3241 pageTitle=subPage->title();
3242
3243 bool hasSubPages = subPage->hasSubPages();
3244
3245 Doxygen::indexList.addContentsItem(hasSubPages,pageTitle,subPage->getReference(),subPage->getOutputFileBase(),0);
3246 writeSubPages(subPage);
3247 }
3248 }
3249 Doxygen::indexList.decContentsDepth();
3250
3251}
3252
3253void writePageIndex(OutputList &ol)
3254{
3255 if (indexedPages==0) return;
3256 ol.pushGeneratorState();
3257 ol.disableAllBut(OutputGenerator::Html);
3258 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Pages);
3259 QCString title = lne->title();
3260 startFile(ol,"pages",0,title,HLI_Pages);
3261 startTitle(ol,0);
3262 //if (!Config_getString("PROJECT_NAME").isEmpty())
3263 //{
3264 // title.prepend(Config_getString("PROJECT_NAME")+" ");
3265 //}
3266 ol.parseText(title);
3267 endTitle(ol,0,0);
3268 ol.startContents();
3269 ol.startTextBlock();
3270 Doxygen::indexList.addContentsItem(TRUE,title,0,"pages",0);
3271 Doxygen::indexList.incContentsDepth();
3272 ol.parseText(lne->intro());
3273 ol.endTextBlock();
3274 startIndexHierarchy(ol,0);
3275 PageSDict::Iterator pdi(*Doxygen::pageSDict);
3276 PageDef *pd=0;
3277 for (pdi.toFirst();(pd=pdi.current());++pdi)
3278 {
3279 if ( pd->visibleInIndex())
3280 {
3281 QCString pageTitle;
3282
3283 if (pd->title().isEmpty())
3284 pageTitle=pd->name();
3285 else
3286 pageTitle=pd->title();
3287
3288 bool hasSubPages = pd->hasSubPages();
3289
3290 ol.startIndexListItem();
3291 ol.startIndexItem(pd->getReference(),pd->getOutputFileBase());
3292 ol.parseText(pageTitle);
3293 ol.endIndexItem(pd->getReference(),pd->getOutputFileBase());
3294 if (pd->isReference())
3295 {
3296 ol.startTypewriter();
3297 ol.docify(" [external]");
3298 ol.endTypewriter();
3299 }
3300 ol.writeString("\n");
3301 Doxygen::indexList.addContentsItem(hasSubPages,filterTitle(pageTitle),pd->getReference(),pd->getOutputFileBase(),0);
3302 writeSubPages(pd);
3303 ol.endIndexListItem();
3304 }
3305 }
3306 endIndexHierarchy(ol,0);
3307 Doxygen::indexList.decContentsDepth();
3308 endFile(ol);
3309 ol.popGeneratorState();
3310}
3311
3312//----------------------------------------------------------------------------
3313
3314int countGroups()
3315{
3316 int count=0;
3317 GroupSDict::Iterator gli(*Doxygen::groupSDict);
3318 GroupDef *gd;
3319 for (gli.toFirst();(gd=gli.current());++gli)
3320 {
3321 if (!gd->isReference())
3322 {
3323 gd->visited=FALSE;
3324 count++;
3325 }
3326 }
3327 return count;
3328}
3329
3330//----------------------------------------------------------------------------
3331
3332int countDirs()
3333{
3334 int count=0;
3335 SDict<DirDef>::Iterator dli(*Doxygen::directories);
3336 DirDef *dd;
3337 for (dli.toFirst();(dd=dli.current());++dli)
3338 {
3339 if (dd->isLinkableInProject())
3340 {
3341 dd->visited=FALSE;
3342 count++;
3343 }
3344 }
3345 return count;
3346}
3347
3348
3349//----------------------------------------------------------------------------
3350
3351void writeGraphInfo(OutputList &ol)
3352{
3353 if (!Config_getBool("HAVE_DOT") || !Config_getBool("GENERATE_HTML")) return;
3354 ol.pushGeneratorState();
3355 ol.disableAllBut(OutputGenerator::Html);
3356 generateGraphLegend(Config_getString("HTML_OUTPUT"));
3357 startFile(ol,"graph_legend",0,theTranslator->trLegendTitle().data());
3358 startTitle(ol,0);
3359 ol.parseText(theTranslator->trLegendTitle());
3360 endTitle(ol,0,0);
3361 ol.startContents();
3362 bool &stripCommentsStateRef = Config_getBool("STRIP_CODE_COMMENTS");
3363 bool oldStripCommentsState = stripCommentsStateRef;
3364 // temporarily disable the stripping of comments for our own code example!
3365 stripCommentsStateRef = FALSE;
3366 QCString legendDocs = theTranslator->trLegendDocs();
3367 int s = legendDocs.find("<center>");
3368 int e = legendDocs.find("</center>");
3369 if (Config_getEnum("DOT_IMAGE_FORMAT")=="svg" && s!=-1 && e!=-1)
3370 {
3371 legendDocs = legendDocs.left(s+8) + "[!-- SVG 0 --]\n" + legendDocs.mid(e);
3372 //printf("legendDocs=%s\n",legendDocs.data());
3373 }
3374 ol.parseDoc("graph_legend",1,0,0,legendDocs,FALSE,FALSE);
3375 stripCommentsStateRef = oldStripCommentsState;
3376 endFile(ol);
3377 ol.popGeneratorState();
3378}
3379
3380void writeGroupIndexItem(GroupDef *gd,MemberList *ml,const QCString &title)
3381{
3382 if (ml && ml->count()>0)
3383 {
3384 bool first=TRUE;
3385 MemberDef *md=ml->first();
3386 while (md)
3387 {
3388 if (md->isDetailedSectionVisible(TRUE,FALSE))
3389 {
3390 if (first)
3391 {
3392 first=FALSE;
3393 Doxygen::indexList.addContentsItem(TRUE, convertToHtml(title,TRUE), gd->getReference(), gd->getOutputFileBase(), 0);
3394 Doxygen::indexList.incContentsDepth();
3395 }
3396 Doxygen::indexList.addContentsItem(FALSE,md->name(),md->getReference(),md->getOutputFileBase(),md->anchor());
3397 }
3398 md=ml->next();
3399 }
3400
3401 if (!first)
3402 {
3403 Doxygen::indexList.decContentsDepth();
3404 }
3405 }
3406}
3407
3408//----------------------------------------------------------------------------
3409/*!
3410 * write groups as hierarchical trees
3411 */
3412void writeGroupTreeNode(OutputList &ol, GroupDef *gd, int level, FTVHelp* ftv)
3413{
3414 bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
3415 bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
3416 if (level>20)
3417 {
3418 warn(gd->getDefFileName(),gd->getDefLine(),
3419 "warning: maximum nesting level exceeded for group %s: check for possible recursive group relation!\n",gd->name().data()
3420 );
3421 return;
3422 }
3423
3424 /* Some groups should appear twice under different parent-groups.
3425 * That is why we should not check if it was visited
3426 */
3427 if (/*!gd->visited &&*/ (!gd->isASubGroup() || level>0) &&
3428 (!gd->isReference() || Config_getBool("EXTERNAL_GROUPS")) // hide external groups by default
3429 )
3430 {
3431 //printf("gd->name()=%s #members=%d\n",gd->name().data(),gd->countMembers());
3432 // write group info
3433 bool hasSubGroups = gd->groupList->count()>0;
3434 bool hasSubPages = gd->pageDict->count()>0;
3435 int numSubItems = 0;
3436 if ( Config_getBool("TOC_EXPAND"))
3437 {
3438 QListIterator<MemberList> mli(gd->getMemberLists());
3439 MemberList *ml;
3440 for (mli.toFirst();(ml=mli.current());++mli)
3441 {
3442 if (ml->listType()&MemberList::documentationLists)
3443 {
3444 numSubItems += ml->count();
3445 }
3446 }
3447 numSubItems += gd->namespaceSDict->count();
3448 numSubItems += gd->classSDict->count();
3449 numSubItems += gd->fileList->count();
3450 numSubItems += gd->exampleDict->count();
3451 }
3452
3453 bool isDir = hasSubGroups || hasSubPages || numSubItems>0;
3454 //printf("gd=`%s': pageDict=%d\n",gd->name().data(),gd->pageDict->count());
3455 Doxygen::indexList.addContentsItem(isDir,gd->groupTitle(),gd->getReference(),gd->getOutputFileBase(),0);
3456 Doxygen::indexList.incContentsDepth();
3457 if (ftv)
3458 {
3459 ftv->addContentsItem(isDir,gd->groupTitle(),gd->getReference(),gd->getOutputFileBase(),0);
3460 ftv->incContentsDepth();
3461 }
3462
3463 //ol.writeListItem();
3464 //ol.startTextLink(gd->getOutputFileBase(),0);
3465 //parseText(ol,gd->groupTitle());
3466 //ol.endTextLink();
3467
3468 ol.startIndexListItem();
3469 ol.startIndexItem(gd->getReference(),gd->getOutputFileBase());
3470 ol.parseText(gd->groupTitle());
3471 ol.endIndexItem(gd->getReference(),gd->getOutputFileBase());
3472 if (gd->isReference())
3473 {
3474 ol.startTypewriter();
3475 ol.docify(" [external]");
3476 ol.endTypewriter();
3477 }
3478
3479
3480 // write pages
3481 PageSDict::Iterator pli(*gd->pageDict);
3482 PageDef *pd = 0;
3483 for (pli.toFirst();(pd=pli.current());++pli)
3484 {
3485 SectionInfo *si=0;
3486 if (!pd->name().isEmpty()) si=Doxygen::sectionDict[pd->name()];
3487 Doxygen::indexList.addContentsItem(FALSE,
3488 convertToHtml(pd->title(),TRUE),
3489 gd->getReference(),
3490 gd->getOutputFileBase(),
3491 si ? si->label.data() : 0);
3492 }
3493
3494 // write subgroups
3495 if (hasSubGroups)
3496 {
3497 startIndexHierarchy(ol,level+1);
3498 if (Config_getBool("SORT_GROUP_NAMES"))
3499 gd->groupList->sort();
3500 QListIterator<GroupDef> gli(*gd->groupList);
3501 GroupDef *subgd = 0;
3502 for (gli.toFirst();(subgd=gli.current());++gli)
3503 {
3504 writeGroupTreeNode(ol,subgd,level+1,ftv);
3505 }
3506 endIndexHierarchy(ol,level+1);
3507 }
3508
3509
3510 if (Config_getBool("TOC_EXPAND"))
3511 {
3512 writeGroupIndexItem(gd,gd->getMemberList(MemberList::docDefineMembers),
3513 theTranslator->trDefines());
3514 writeGroupIndexItem(gd,gd->getMemberList(MemberList::docTypedefMembers),
3515 theTranslator->trTypedefs());
3516 writeGroupIndexItem(gd,gd->getMemberList(MemberList::docEnumMembers),
3517 theTranslator->trEnumerations());
3518 writeGroupIndexItem(gd,gd->getMemberList(MemberList::docFuncMembers),
3519 fortranOpt ? theTranslator->trSubprograms() :
3520 vhdlOpt ? VhdlDocGen::trFunctionAndProc() :
3521 theTranslator->trFunctions()
3522 );
3523 writeGroupIndexItem(gd,gd->getMemberList(MemberList::docVarMembers),
3524 theTranslator->trVariables());
3525 writeGroupIndexItem(gd,gd->getMemberList(MemberList::docProtoMembers),
3526 theTranslator->trFuncProtos());
3527
3528 // write namespaces
3529 NamespaceSDict *namespaceSDict=gd->namespaceSDict;
3530 if (namespaceSDict->count()>0)
3531 {
3532 Doxygen::indexList.addContentsItem(TRUE,convertToHtml(fortranOpt?theTranslator->trModules():theTranslator->trNamespaces(),TRUE),gd->getReference(), gd->getOutputFileBase(), 0);
3533 Doxygen::indexList.incContentsDepth();
3534
3535 NamespaceSDict::Iterator ni(*namespaceSDict);
3536 NamespaceDef *nsd;
3537 for (ni.toFirst();(nsd=ni.current());++ni)
3538 {
3539 Doxygen::indexList.addContentsItem(FALSE, convertToHtml(nsd->name(),TRUE), nsd->getReference(), nsd->getOutputFileBase(), 0);
3540 }
3541 Doxygen::indexList.decContentsDepth();
3542 }
3543
3544 // write classes
3545 if (gd->classSDict->count()>0)
3546 {
3547 Doxygen::indexList.addContentsItem(TRUE,convertToHtml(fortranOpt?theTranslator->trDataTypes():theTranslator->trClasses(),TRUE), gd->getReference(), gd->getOutputFileBase(), 0);
3548 Doxygen::indexList.incContentsDepth();
3549
3550 ClassDef *cd;
3551 ClassSDict::Iterator cdi(*gd->classSDict);
3552 for (cdi.toFirst();(cd=cdi.current());++cdi)
3553 {
3554 if (cd->isLinkable())
3555 {
3556 //printf("node: Has children %s\n",cd->name().data());
3557 Doxygen::indexList.addContentsItem(FALSE,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor());
3558 }
3559 }
3560
3561 //writeClassTree(gd->classSDict,1);
3562 Doxygen::indexList.decContentsDepth();
3563 }
3564
3565 // write file list
3566 FileList *fileList=gd->fileList;
3567 if (fileList->count()>0)
3568 {
3569 Doxygen::indexList.addContentsItem(TRUE,
3570 theTranslator->trFile(TRUE,FALSE),
3571 gd->getReference(),
3572 gd->getOutputFileBase(), 0);
3573 Doxygen::indexList.incContentsDepth();
3574
3575 FileDef *fd=fileList->first();
3576 while (fd)
3577 {
3578 Doxygen::indexList.addContentsItem(FALSE, convertToHtml(fd->name(),TRUE),fd->getReference(), fd->getOutputFileBase(), 0);
3579 fd=fileList->next();
3580 }
3581 Doxygen::indexList.decContentsDepth();
3582 }
3583
3584 // write examples
3585 if (gd->exampleDict->count()>0)
3586 {
3587 Doxygen::indexList.addContentsItem(TRUE, convertToHtml(theTranslator->trExamples(),TRUE),gd->getReference(), gd->getOutputFileBase(), 0);
3588 Doxygen::indexList.incContentsDepth();
3589
3590 PageSDict::Iterator eli(*(gd->exampleDict));
3591 PageDef *pd=eli.toFirst();
3592 while (pd)
3593 {
3594 Doxygen::indexList.addContentsItem(FALSE,pd->name(),pd->getReference(),pd->getOutputFileBase(),0);
3595 pd=++eli;
3596 }
3597
3598 Doxygen::indexList.decContentsDepth();
3599 }
3600 }
3601 ol.endIndexListItem();
3602
3603 Doxygen::indexList.decContentsDepth();
3604 if (ftv)
3605 ftv->decContentsDepth();
3606 //gd->visited=TRUE;
3607 }
3608}
3609
3610void writeGroupHierarchy(OutputList &ol, FTVHelp* ftv)
3611{
3612 if (ftv)
3613 {
3614 ol.pushGeneratorState();
3615 ol.disable(OutputGenerator::Html);
3616 }
3617 startIndexHierarchy(ol,0);
3618 if (Config_getBool("SORT_GROUP_NAMES"))
3619 Doxygen::groupSDict->sort();
3620 GroupSDict::Iterator gli(*Doxygen::groupSDict);
3621 GroupDef *gd;
3622 for (gli.toFirst();(gd=gli.current());++gli)
3623 {
3624 writeGroupTreeNode(ol,gd,0,ftv);
3625 }
3626 endIndexHierarchy(ol,0);
3627 if (ftv)
3628 {
3629 ol.popGeneratorState();
3630 }
3631}
3632
3633//----------------------------------------------------------------------------
3634void writeDirTreeNode(OutputList &ol, DirDef *dd, int level, FTVHelp* ftv)
3635{
3636 if (level>20)
3637 {
3638 warn(dd->getDefFileName(),dd->getDefLine(),
3639 "warning: maximum nesting level exceeded for directory %s: "
3640 "check for possible recursive directory relation!\n",dd->name().data()
3641 );
3642 return;
3643 }
3644
3645 static bool tocExpand = Config_getBool("TOC_EXPAND");
3646 bool isDir = dd->subDirs().count()>0 || // there are subdirs
3647 (tocExpand && // or toc expand and
3648 dd->getFiles() && dd->getFiles()->count()>0 // there are files
3649 );
3650 //printf("gd=`%s': pageDict=%d\n",gd->name().data(),gd->pageDict->count());
3651 Doxygen::indexList.addContentsItem(isDir,dd->shortName(),dd->getReference(),dd->getOutputFileBase(),0);
3652 Doxygen::indexList.incContentsDepth();
3653 if (ftv)
3654 {
3655 ftv->addContentsItem(isDir,dd->shortName(),dd->getReference(),dd->getOutputFileBase(),0);
3656 ftv->incContentsDepth();
3657 }
3658
3659 ol.startIndexListItem();
3660 ol.startIndexItem(dd->getReference(),dd->getOutputFileBase());
3661 ol.parseText(dd->shortName());
3662 ol.endIndexItem(dd->getReference(),dd->getOutputFileBase());
3663 if (dd->isReference())
3664 {
3665 ol.startTypewriter();
3666 ol.docify(" [external]");
3667 ol.endTypewriter();
3668 }
3669
3670 // write sub directories
3671 if (dd->subDirs().count()>0)
3672 {
3673 startIndexHierarchy(ol,level+1);
3674 QListIterator<DirDef> dli(dd->subDirs());
3675 DirDef *subdd = 0;
3676 for (dli.toFirst();(subdd=dli.current());++dli)
3677 {
3678 writeDirTreeNode(ol,subdd,level+1,ftv);
3679 }
3680 endIndexHierarchy(ol,level+1);
3681 }
3682
3683 if (tocExpand)
3684 {
3685 // write files of this directory
3686 FileList *fileList=dd->getFiles();
3687 if (fileList && fileList->count()>0)
3688 {
3689 FileDef *fd=fileList->first();
3690 while (fd)
3691 {
3692 Doxygen::indexList.addContentsItem(FALSE, convertToHtml(fd->name(),TRUE),fd->getReference(), fd->getOutputFileBase(), 0);
3693 fd=fileList->next();
3694 }
3695 }
3696 }
3697 ol.endIndexListItem();
3698
3699 Doxygen::indexList.decContentsDepth();
3700 if (ftv)
3701 ftv->decContentsDepth();
3702}
3703
3704void writeDirHierarchy(OutputList &ol, FTVHelp* ftv)
3705{
3706 if (ftv)
3707 {
3708 ol.pushGeneratorState();
3709 ol.disable(OutputGenerator::Html);
3710 }
3711 startIndexHierarchy(ol,0);
3712 SDict<DirDef>::Iterator dli(*Doxygen::directories);
3713 DirDef *dd;
3714 for (dli.toFirst();(dd=dli.current());++dli)
3715 {
3716 if (dd->getOuterScope()==Doxygen::globalScope) writeDirTreeNode(ol,dd,0,ftv);
3717 }
3718 endIndexHierarchy(ol,0);
3719 if (ftv)
3720 ol.popGeneratorState();
3721}
3722
3723//----------------------------------------------------------------------------
3724
3725void writeGroupIndex(OutputList &ol)
3726{
3727 if (documentedGroups==0) return;
3728 ol.pushGeneratorState();
3729 ol.disable(OutputGenerator::Man);
3730 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Modules);
3731 QCString title = lne->title();
3732 startFile(ol,"modules",0,title,HLI_Modules);
3733 startTitle(ol,0);
3734 //QCString title = theTranslator->trModules();
3735 //if (!Config_getString("PROJECT_NAME").isEmpty())
3736 //{
3737 // title.prepend(Config_getString("PROJECT_NAME")+" ");
3738 //}
3739 ol.parseText(title);
3740 endTitle(ol,0,0);
3741 ol.startContents();
3742 ol.startTextBlock();
3743 Doxygen::indexList.addContentsItem(TRUE,title,0,"modules",0);
3744 Doxygen::indexList.incContentsDepth();
3745 ol.parseText(lne->intro());
3746 ol.endTextBlock();
3747
3748 FTVHelp* ftv = 0;
3749 bool treeView=Config_getBool("USE_INLINE_TREES");
3750 if (treeView)
3751 {
3752 ftv = new FTVHelp(FALSE);
3753 }
3754
3755 writeGroupHierarchy(ol,ftv);
3756
3757 Doxygen::indexList.decContentsDepth();
3758 if (ftv)
3759 {
3760 QGString outStr;
3761 FTextStream t(&outStr);
3762 ftv->generateTreeViewInline(t);
3763 ol.pushGeneratorState();
3764 ol.disableAllBut(OutputGenerator::Html);
3765 ol.writeString(outStr);
3766 ol.popGeneratorState();
3767 delete ftv;
3768 }
3769 endFile(ol);
3770 ol.popGeneratorState();
3771}
3772
3773//----------------------------------------------------------------------------
3774
3775void writeDirIndex(OutputList &ol)
3776{
3777 if (documentedDirs==0) return;
3778 ol.pushGeneratorState();
3779 ol.disable(OutputGenerator::Man);
3780 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Dirs);
3781 QCString title = lne->title();
3782 startFile(ol,"dirs",0,title,HLI_Directories);
3783 startTitle(ol,0);
3784 //if (!Config_getString("PROJECT_NAME").isEmpty())
3785 //{
3786 // title.prepend(Config_getString("PROJECT_NAME")+" ");
3787 //}
3788 ol.parseText(title);
3789 endTitle(ol,0,0);
3790 ol.startContents();
3791 ol.startTextBlock();
3792 Doxygen::indexList.addContentsItem(TRUE,title,0,"dirs",0);
3793 Doxygen::indexList.incContentsDepth();
3794 ol.parseText(lne->intro());
3795 ol.endTextBlock();
3796
3797 FTVHelp* ftv = 0;
3798 bool treeView=Config_getBool("USE_INLINE_TREES");
3799 if (treeView)
3800 {
3801 ftv = new FTVHelp(FALSE);
3802 }
3803
3804 writeDirHierarchy(ol,ftv);
3805
3806 if (ftv)
3807 {
3808 QGString outStr;
3809 FTextStream t(&outStr);
3810 ftv->generateTreeViewInline(t);
3811 ol.pushGeneratorState();
3812 ol.disableAllBut(OutputGenerator::Html);
3813 ol.writeString(outStr);
3814 ol.popGeneratorState();
3815 delete ftv;
3816 }
3817 Doxygen::indexList.decContentsDepth();
3818 endFile(ol);
3819 ol.popGeneratorState();
3820}
3821
3822//----------------------------------------------------------------------------
3823
3824static bool mainPageHasTitle()
3825{
3826 if (Doxygen::mainPage==0) return FALSE;
3827 if (Doxygen::mainPage->title().isEmpty()) return FALSE;
3828 if (Doxygen::mainPage->title().lower()=="notitle") return FALSE;
3829 return TRUE;
3830}
3831
3832//----------------------------------------------------------------------------
3833
3834void writeIndex(OutputList &ol)
3835{
3836 static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
3837 static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
3838 // save old generator state
3839 ol.pushGeneratorState();
3840
3841 QCString projPrefix;
3842 if (!Config_getString("PROJECT_NAME").isEmpty())
3843 {
3844 projPrefix=Config_getString("PROJECT_NAME")+" ";
3845 }
3846
3847#if 0
3848 {
3849 QFile f(Config_getString("HTML_OUTPUT")+"/navindex.js");
3850 if (f.open(IO_WriteOnly))
3851 {
3852 FTextStream t(&f);
3853 t << "var NAVINDEX =" << endl;
3854 LayoutNavEntry *layout = LayoutDocManager::instance().rootNavEntry();
3855 bool first=TRUE;
3856 writeFullNavIndex(t,layout,0,first);
3857 t << endl << "];" << endl;
3858 t << endl << navindex_script;
3859 }
3860 }
3861#endif
3862
3863 //--------------------------------------------------------------------
3864 // write HTML index
3865 //--------------------------------------------------------------------
3866 ol.disableAllBut(OutputGenerator::Html);
3867
3868 QCString defFileName =
3869 Doxygen::mainPage ? Doxygen::mainPage->getDefFileName().data() : "[generated]";
3870 int defLine =
3871 Doxygen::mainPage ? Doxygen::mainPage->getDefLine() : -1;
3872
3873 QCString title;
3874 if (!mainPageHasTitle())
3875 {
3876 title = theTranslator->trMainPage();
3877 }
3878 else
3879 {
3880 title = filterTitle(Doxygen::mainPage->title());
3881 }
3882
3883 static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
3884 //QCString indexName=Config_getBool("GENERATE_TREEVIEW")?"main":"index";
3885 QCString indexName="index";
3886 ol.startFile(indexName,0,title);
3887
3888 if (Doxygen::mainPage)
3889 {
3890 Doxygen::indexList.addContentsItem(Doxygen::mainPage->hasSubPages(),title,0,indexName,0);
3891
3892 if (Doxygen::mainPage->hasSubPages())
3893 {
3894 writeSubPages(Doxygen::mainPage);
3895 }
3896 }
3897
3898 ol.startQuickIndices();
3899 if (!Config_getBool("DISABLE_INDEX"))
3900 {
3901 ol.writeQuickLinks(TRUE,HLI_Main);
3902 }
3903 ol.endQuickIndices();
3904 if (generateTreeView)
3905 {
3906 ol.writeSplitBar(indexName);
3907 }
3908 bool headerWritten=FALSE;
3909 if (Doxygen::mainPage && !Doxygen::mainPage->title().isEmpty())
3910 {
3911 if (Doxygen::mainPage->title().lower()!="notitle")
3912 {
3913 ol.startHeaderSection();
3914 ol.startTitleHead(0);
3915 ol.parseDoc(Doxygen::mainPage->docFile(),Doxygen::mainPage->docLine(),
3916 Doxygen::mainPage,0,Doxygen::mainPage->title(),
3917 TRUE,FALSE,0,TRUE,FALSE);
3918 headerWritten = TRUE;
3919 }
3920 }
3921 else
3922 {
3923 if (!Config_getString("PROJECT_NAME").isEmpty())
3924 {
3925 ol.startHeaderSection();
3926 ol.startTitleHead(0);
3927 ol.parseText(projPrefix+theTranslator->trDocumentation());
3928 headerWritten = TRUE;
3929 }
3930 }
3931 if (headerWritten)
3932 {
3933 ol.endTitleHead(0,0);
3934 ol.endHeaderSection();
3935 }
3936 ol.startContents();
3937#if 0
3938 // ol.newParagraph(); // FIXME:PARA
3939 if (!Config_getString("PROJECT_NUMBER").isEmpty())
3940 {
3941 ol.startProjectNumber();
3942 ol.parseDoc(defFileName,defLine,
3943 Doxygen::mainPage,0,
3944 Config_getString("PROJECT_NUMBER"),
3945 TRUE,FALSE,0,
3946 TRUE,FALSE);
3947 ol.endProjectNumber();
3948 }
3949#endif
3950 if (Config_getBool("DISABLE_INDEX") && Doxygen::mainPage==0)
3951 {
3952 ol.writeQuickLinks(FALSE,HLI_Main);
3953 }
3954
3955 if (Doxygen::mainPage)
3956 {
3957 Doxygen::insideMainPage=TRUE;
3958 ol.startTextBlock();
3959 ol.parseDoc(defFileName,defLine,Doxygen::mainPage,0,
3960 Doxygen::mainPage->documentation(),TRUE,FALSE
3961 /*,Doxygen::mainPage->sectionDict*/);
3962 ol.endTextBlock();
3963
3964 if (!Config_getString("GENERATE_TAGFILE").isEmpty())
3965 {
3966 Doxygen::tagFile << " <compound kind=\"page\">" << endl
3967 << " <name>"
3968 << convertToXML(Doxygen::mainPage->name())
3969 << "</name>" << endl
3970 << " <title>"
3971 << convertToXML(Doxygen::mainPage->title())
3972 << "</title>" << endl
3973 << " <filename>"
3974 << convertToXML(Doxygen::mainPage->getOutputFileBase())
3975 << "</filename>" << endl;
3976
3977 Doxygen::mainPage->writeDocAnchorsToTagFile();
3978 Doxygen::tagFile << " </compound>" << endl;
3979 }
3980 Doxygen::insideMainPage=FALSE;
3981 }
3982
3983 endFile(ol);
3984 ol.disable(OutputGenerator::Html);
3985
3986 //--------------------------------------------------------------------
3987 // write LaTeX/RTF index
3988 //--------------------------------------------------------------------
3989 ol.enable(OutputGenerator::Latex);
3990 ol.enable(OutputGenerator::RTF);
3991
3992 ol.startFile("refman",0,0);
3993 ol.startIndexSection(isTitlePageStart);
3994 if (!Config_getString("LATEX_HEADER").isEmpty())
3995 {
3996 ol.disable(OutputGenerator::Latex);
3997 }
3998
3999 if (projPrefix.isEmpty())
4000 {
4001 ol.parseText(theTranslator->trReferenceManual());
4002 }
4003 else
4004 {
4005 ol.parseText(projPrefix);
4006 }
4007
4008 if (!Config_getString("PROJECT_NUMBER").isEmpty())
4009 {
4010 ol.startProjectNumber();
4011 ol.parseDoc(defFileName,defLine,Doxygen::mainPage,0,Config_getString("PROJECT_NUMBER"),FALSE,FALSE);
4012 ol.endProjectNumber();
4013 }
4014 ol.endIndexSection(isTitlePageStart);
4015 ol.startIndexSection(isTitlePageAuthor);
4016 ol.parseText(theTranslator->trGeneratedBy());
4017 ol.endIndexSection(isTitlePageAuthor);
4018 ol.enable(OutputGenerator::Latex);
4019
4020 ol.lastIndexPage();
4021 if (Doxygen::mainPage)
4022 {
4023 ol.startIndexSection(isMainPage);
4024 if (mainPageHasTitle())
4025 {
4026 ol.parseText(Doxygen::mainPage->title());
4027 }
4028 else
4029 {
4030 ol.parseText(/*projPrefix+*/theTranslator->trMainPage());
4031 }
4032 ol.endIndexSection(isMainPage);
4033 }
4034 if (documentedPages>0)
4035 {
4036 //ol.parseText(projPrefix+theTranslator->trPageDocumentation());
4037 //ol.endIndexSection(isPageDocumentation);
4038 PageSDict::Iterator pdi(*Doxygen::pageSDict);
4039 PageDef *pd=pdi.toFirst();
4040 bool first=Doxygen::mainPage==0;
4041 for (pdi.toFirst();(pd=pdi.current());++pdi)
4042 {
4043 if (!pd->getGroupDef() && !pd->isReference() &&
4044 (!pd->hasParentPage() || // not inside other page
4045 (Doxygen::mainPage==pd->getOuterScope())) // or inside main page
4046 )
4047 {
4048 QCString title = pd->title();
4049 if (title.isEmpty()) title=pd->name();
4050 ol.startIndexSection(isPageDocumentation);
4051 ol.parseText(title);
4052 ol.endIndexSection(isPageDocumentation);
4053 ol.pushGeneratorState(); // write TOC title (RTF only)
4054 ol.disableAllBut(OutputGenerator::RTF);
4055 ol.startIndexSection(isPageDocumentation2);
4056 ol.parseText(title);
4057 ol.endIndexSection(isPageDocumentation2);
4058 ol.popGeneratorState();
4059 ol.writeAnchor(0,pd->name());
4060
4061 ol.writePageLink(pd->getOutputFileBase(),first);
4062 first=FALSE;
4063 }
4064 }
4065 }
4066
4067 if (!Config_getBool("LATEX_HIDE_INDICES"))
4068 {
4069 //if (indexedPages>0)
4070 //{
4071 // ol.startIndexSection(isPageIndex);
4072 // ol.parseText(/*projPrefix+*/ theTranslator->trPageIndex());
4073 // ol.endIndexSection(isPageIndex);
4074 //}
4075 if (documentedGroups>0)
4076 {
4077 ol.startIndexSection(isModuleIndex);
4078 ol.parseText(/*projPrefix+*/ theTranslator->trModuleIndex());
4079 ol.endIndexSection(isModuleIndex);
4080 }
4081 if (Config_getBool("SHOW_DIRECTORIES") && documentedDirs>0)
4082 {
4083 ol.startIndexSection(isDirIndex);
4084 ol.parseText(/*projPrefix+*/ theTranslator->trDirIndex());
4085 ol.endIndexSection(isDirIndex);
4086 }
4087 if (documentedNamespaces>0)
4088 {
4089 ol.startIndexSection(isNamespaceIndex);
4090 ol.parseText(/*projPrefix+*/(fortranOpt?theTranslator->trModulesIndex():theTranslator->trNamespaceIndex()));
4091 ol.endIndexSection(isNamespaceIndex);
4092 }
4093 if (hierarchyClasses>0)
4094 {
4095 ol.startIndexSection(isClassHierarchyIndex);
4096 ol.parseText(/*projPrefix+*/
4097 (fortranOpt ? theTranslator->trCompoundIndexFortran() :
4098 vhdlOpt ? VhdlDocGen::trDesignUnitIndex() :
4099 theTranslator->trCompoundIndex()
4100 ));
4101 ol.endIndexSection(isClassHierarchyIndex);
4102 }
4103 if (annotatedClassesPrinted>0)
4104 {
4105 ol.startIndexSection(isCompoundIndex);
4106 ol.parseText(/*projPrefix+*/
4107 (fortranOpt ? theTranslator->trCompoundIndexFortran() :
4108 vhdlOpt ? VhdlDocGen::trDesignUnitIndex() :
4109 theTranslator->trCompoundIndex()
4110 ));
4111 ol.endIndexSection(isCompoundIndex);
4112 }
4113 if (documentedFiles>0)
4114 {
4115 ol.startIndexSection(isFileIndex);
4116 ol.parseText(/*projPrefix+*/theTranslator->trFileIndex());
4117 ol.endIndexSection(isFileIndex);
4118 }
4119 }
4120 if (documentedGroups>0)
4121 {
4122 ol.startIndexSection(isModuleDocumentation);
4123 ol.parseText(/*projPrefix+*/theTranslator->trModuleDocumentation());
4124 ol.endIndexSection(isModuleDocumentation);
4125 }
4126 if (Config_getBool("SHOW_DIRECTORIES") && documentedDirs>0)
4127 {
4128 ol.startIndexSection(isDirDocumentation);
4129 ol.parseText(/*projPrefix+*/theTranslator->trDirDocumentation());
4130 ol.endIndexSection(isDirDocumentation);
4131 }
4132 if (documentedNamespaces>0)
4133 {
4134 ol.startIndexSection(isNamespaceDocumentation);
4135 ol.parseText(/*projPrefix+*/(fortranOpt?theTranslator->trModuleDocumentation():theTranslator->trNamespaceDocumentation()));
4136 ol.endIndexSection(isNamespaceDocumentation);
4137 }
4138 if (annotatedClasses>0)
4139 {
4140 ol.startIndexSection(isClassDocumentation);
4141 ol.parseText(/*projPrefix+*/(fortranOpt?theTranslator->trTypeDocumentation():theTranslator->trClassDocumentation()));
4142 ol.endIndexSection(isClassDocumentation);
4143 }
4144 if (documentedFiles>0)
4145 {
4146 ol.startIndexSection(isFileDocumentation);
4147 ol.parseText(/*projPrefix+*/theTranslator->trFileDocumentation());
4148 ol.endIndexSection(isFileDocumentation);
4149 }
4150 if (Doxygen::exampleSDict->count()>0)
4151 {
4152 ol.startIndexSection(isExampleDocumentation);
4153 ol.parseText(/*projPrefix+*/theTranslator->trExampleDocumentation());
4154 ol.endIndexSection(isExampleDocumentation);
4155 }
4156 ol.endIndexSection(isEndIndex);
4157 endFile(ol);
4158
4159 if (Doxygen::mainPage)
4160 {
4161 Doxygen::insideMainPage=TRUE;
4162 ol.disable(OutputGenerator::Man);
4163 startFile(ol,Doxygen::mainPage->name(),0,Doxygen::mainPage->title());
4164 ol.startContents();
4165 ol.startTextBlock();
4166 ol.parseDoc(defFileName,defLine,Doxygen::mainPage,0,
4167 Doxygen::mainPage->documentation(),FALSE,FALSE
4168 );
4169 ol.endTextBlock();
4170 endFile(ol);
4171 ol.enable(OutputGenerator::Man);
4172 Doxygen::insideMainPage=FALSE;
4173 }
4174
4175 ol.popGeneratorState();
4176}
4177
4178
4179
4180

Archive Download this file

Revision: 1322