1 /******************************************************************************
3 * $Id: index.cpp,v 1.63 2001/03/19 19:27:40 root Exp $
5 * Copyright (C) 1997-2012 by Dimitri van Heesch.
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.
13 * Documents produced by Doxygen are derivative works derived from the
14 * input used in their production; they are not affected by this license.
19 * @brief This file contains functions for the various index pages.
24 #include <qtextstream.h>
25 #include <qdatetime.h>
34 #include "outputlist.h"
44 #include "vhdldocgen.h"
47 #define MAX_ITEMS_BEFORE_MULTIPAGE_INDEX 200
48 #define MAX_ITEMS_BEFORE_QUICK_INDEX 30
52 int annotatedClassesPrinted;
56 int documentedNamespaces;
58 int documentedClassMembers[CMHL_Total];
59 int documentedFileMembers[FMHL_Total];
60 int documentedNamespaceMembers[NMHL_Total];
61 int documentedHtmlFiles;
65 static int countClassHierarchy();
66 static void countFiles(int &htmlFiles,int &files);
67 static int countGroups();
68 static int countDirs();
69 static int countNamespaces();
70 static int countAnnotatedClasses(int *cp);
71 static void countRelatedPages(int &docPages,int &indexPages);
73 void countDataStructures()
75 annotatedClasses = countAnnotatedClasses(&annotatedClassesPrinted); // "classes" + "annotated"
76 hierarchyClasses = countClassHierarchy(); // "hierarchy"
77 countFiles(documentedHtmlFiles,documentedFiles); // "files"
78 countRelatedPages(documentedPages,indexedPages); // "pages"
79 documentedGroups = countGroups(); // "modules"
80 documentedNamespaces = countNamespaces(); // "namespaces"
81 documentedDirs = countDirs(); // "dirs"
87 static void startIndexHierarchy(OutputList &ol,int level)
89 ol.pushGeneratorState();
90 ol.disable(OutputGenerator::Man);
91 ol.disable(OutputGenerator::Html);
92 if (level<6) ol.startIndexList();
94 ol.disable(OutputGenerator::Latex);
95 ol.disable(OutputGenerator::RTF);
97 ol.popGeneratorState();
100 static void endIndexHierarchy(OutputList &ol,int level)
102 ol.pushGeneratorState();
103 ol.disable(OutputGenerator::Man);
104 ol.disable(OutputGenerator::Html);
105 if (level<6) ol.endIndexList();
107 ol.disable(OutputGenerator::Latex);
108 ol.disable(OutputGenerator::RTF);
110 ol.popGeneratorState();
113 //----------------------------------------------------------------------------
115 class MemberIndexList : public QList<MemberDef>
118 MemberIndexList() : QList<MemberDef>() {}
119 ~MemberIndexList() {}
120 int compareItems(GCI item1, GCI item2)
122 MemberDef *md1=(MemberDef *)item1;
123 MemberDef *md2=(MemberDef *)item2;
124 return stricmp(md1->name(),md2->name());
128 #define MEMBER_INDEX_ENTRIES 256
130 static MemberIndexList g_memberIndexLetterUsed[CMHL_Total][MEMBER_INDEX_ENTRIES];
131 static MemberIndexList g_fileIndexLetterUsed[FMHL_Total][MEMBER_INDEX_ENTRIES];
132 static MemberIndexList g_namespaceIndexLetterUsed[NMHL_Total][MEMBER_INDEX_ENTRIES];
134 //static bool g_classIndexLetterUsed[CHL_Total][256];
136 const int maxItemsBeforeQuickIndex = MAX_ITEMS_BEFORE_QUICK_INDEX;
138 //----------------------------------------------------------------------------
140 //----------------------------------------------------------------------------
142 static void startQuickIndexList(OutputList &ol,bool letterTabs=FALSE)
144 bool fancyTabs = TRUE;
149 ol.writeString(" <div id=\"navrow4\" class=\"tabs3\">\n");
153 ol.writeString(" <div id=\"navrow3\" class=\"tabs2\">\n");
155 ol.writeString(" <ul class=\"tablist\">\n");
159 ol.writeString(" <div class=\"qindex\">");
163 static void endQuickIndexList(OutputList &ol)
165 bool fancyTabs = TRUE;
168 ol.writeString(" </ul>\n");
170 ol.writeString(" </div>\n");
173 static void startQuickIndexItem(OutputList &ol,const char *l,
174 bool hl,bool compact,bool &first)
176 bool fancyTabs = TRUE;
177 if (!first && compact && !fancyTabs) ol.writeString(" | ");
181 ol.writeString(" <li");
182 if (hl) ol.writeString(" class=\"current\"");
183 ol.writeString("><a ");
187 if (!compact) ol.writeString("<li>");
190 ol.writeString("<a class=\"qindexHL\" ");
194 ol.writeString("<a class=\"qindex\" ");
197 ol.writeString("href=\"");
199 ol.writeString("\">");
202 ol.writeString("<span>");
206 static void endQuickIndexItem(OutputList &ol)
209 if (fancyTabs) ol.writeString("</span>");
210 ol.writeString("</a>");
211 if (fancyTabs) ol.writeString("</li>\n");
214 // don't make this static as it is called from a template function and some
215 // old compilers don't support calls to static functions from a template.
216 QCString fixSpaces(const QCString &s)
218 return substitute(s," "," ");
221 void startTitle(OutputList &ol,const char *fileName,Definition *def)
223 ol.startHeaderSection();
224 if (def) def->writeSummaryLinks(ol);
225 ol.startTitleHead(fileName);
226 ol.pushGeneratorState();
227 ol.disable(OutputGenerator::Man);
230 void endTitle(OutputList &ol,const char *fileName,const char *name)
232 ol.popGeneratorState();
233 ol.endTitleHead(fileName,name);
234 ol.endHeaderSection();
237 void startFile(OutputList &ol,const char *name,const char *manName,
238 const char *title,HighlightedItem hli,bool additionalIndices,
239 const char *altSidebarName)
241 static bool disableIndex = Config_getBool("DISABLE_INDEX");
242 ol.startFile(name,manName,title);
243 ol.startQuickIndices();
246 ol.writeQuickLinks(TRUE,hli,name);
248 if (!additionalIndices)
250 ol.endQuickIndices();
252 ol.writeSplitBar(altSidebarName ? altSidebarName : name);
253 ol.writeSearchInfo();
256 void endFile(OutputList &ol,bool skipNavIndex,bool skipEndContents,
257 const QCString &navPath)
259 static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
260 ol.pushGeneratorState();
261 ol.disableAllBut(OutputGenerator::Html);
264 if (!skipEndContents) ol.endContents();
265 if (generateTreeView)
267 ol.writeString("</div><!-- doc-content -->\n");
270 ol.writeFooter(navPath); // write the footer
271 ol.popGeneratorState();
275 void endFileWithNavPath(Definition *d,OutputList &ol)
277 static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
279 if (generateTreeView)
281 ol.pushGeneratorState();
282 ol.disableAllBut(OutputGenerator::Html);
283 ol.writeString("</div><!-- doc-content -->\n");
284 ol.popGeneratorState();
285 navPath = d->navigationPathAsString();
287 endFile(ol,generateTreeView,TRUE,navPath);
290 //----------------------------------------------------------------------
292 void addMembersToIndex(T *def,LayoutDocManager::LayoutPart part,
293 const QCString &name,const QCString &anchor,
294 bool addToIndex=TRUE,bool preventSeparateIndex=FALSE)
296 bool hasMembers = def->getMemberLists().count()>0 || def->getMemberGroupSDict()!=0;
297 Doxygen::indexList.addContentsItem(hasMembers,name,
298 def->getReference(),def->getOutputFileBase(),anchor,
299 hasMembers && !preventSeparateIndex,
303 ClassSDict *classes = def->getClassSDict();
307 ClassSDict::Iterator it(*classes);
308 for (;(cd=it.current());++it)
310 if (cd->isLinkable()) numClasses++;
313 //printf("addMembersToIndex(def=%s hasMembers=%d numClasses=%d)\n",def->name().data(),hasMembers,numClasses);
314 if (hasMembers || numClasses>0)
316 Doxygen::indexList.incContentsDepth();
317 QListIterator<LayoutDocEntry> eli(LayoutDocManager::instance().docEntries(part));
319 for (eli.toFirst();(lde=eli.current());++eli)
321 if (lde->kind()==LayoutDocEntry::MemberDef)
323 LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde;
324 MemberList *ml = def->getMemberList(lmd->type);
327 MemberListIterator mi(*ml);
329 for (mi.toFirst();(md=mi.current());++mi)
331 LockingPtr<MemberList> enumList = md->enumFieldList();
332 bool isDir = enumList!=0 && md->isEnumerate();
333 bool isAnonymous = md->name().find('@')!=-1;
336 if (md->getOuterScope()==def)
338 Doxygen::indexList.addContentsItem(isDir,
339 md->name(),md->getReference(),md->getOutputFileBase(),md->anchor(),FALSE,addToIndex);
341 else // inherited member
343 Doxygen::indexList.addContentsItem(isDir,
344 md->name(),def->getReference(),def->getOutputFileBase(),md->anchor(),FALSE,addToIndex);
351 Doxygen::indexList.incContentsDepth();
353 MemberListIterator emli(*enumList);
355 for (emli.toFirst();(emd=emli.current());++emli)
357 if (emd->getOuterScope()==def)
359 Doxygen::indexList.addContentsItem(FALSE,
360 emd->name(),emd->getReference(),emd->getOutputFileBase(),emd->anchor(),FALSE,addToIndex);
362 else // inherited member
364 Doxygen::indexList.addContentsItem(FALSE,
365 emd->name(),def->getReference(),def->getOutputFileBase(),emd->anchor(),FALSE,addToIndex);
370 Doxygen::indexList.decContentsDepth();
376 else if (lde->kind()==LayoutDocEntry::NamespaceClasses ||
377 lde->kind()==LayoutDocEntry::FileClasses ||
378 lde->kind()==LayoutDocEntry::ClassNestedClasses
384 ClassSDict::Iterator it(*classes);
385 for (;(cd=it.current());++it)
387 if (cd->isLinkable() && (cd->partOfGroups()==0 || def->definitionType()==Definition::TypeGroup))
389 bool isNestedClass = def->definitionType()==Definition::TypeClass;
390 addMembersToIndex(cd,LayoutDocManager::Class,cd->displayName(FALSE),cd->anchor(),
391 addToIndex && isNestedClass,
392 preventSeparateIndex || cd->isEmbeddedInOuterScope());
399 Doxygen::indexList.decContentsDepth();
403 //----------------------------------------------------------------------------
405 static bool classHasVisibleChildren(ClassDef *cd)
409 if (cd->getLanguage()==SrcLangExt_VHDL) // reverse baseClass/subClass relation
411 if (cd->baseClasses()==0) return FALSE;
412 bcl=cd->baseClasses();
416 if (cd->subClasses()==0) return FALSE;
417 bcl=cd->subClasses();
420 BaseClassListIterator bcli(*bcl);
421 for ( ; bcli.current() ; ++bcli)
423 if (bcli.current()->classDef->isVisibleInHierarchy())
431 //----------------------------------------------------------------------------
432 /*! Generates HTML Help tree of classes */
434 static void writeClassTree(OutputList &ol,BaseClassList *bcl,bool hideSuper,int level,FTVHelp* ftv,bool addToIndex)
437 BaseClassListIterator bcli(*bcl);
439 for ( ; bcli.current() ; ++bcli)
441 ClassDef *cd=bcli.current()->classDef;
442 if (cd->getLanguage()==SrcLangExt_VHDL && (VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS)
448 if (cd->getLanguage()==SrcLangExt_VHDL)
450 b=hasVisibleRoot(cd->subClasses());
454 b=hasVisibleRoot(cd->baseClasses());
457 if (cd->isVisibleInHierarchy() && b) // hasVisibleRoot(cd->baseClasses()))
461 startIndexHierarchy(ol,level);
464 Doxygen::indexList.incContentsDepth();
468 ftv->incContentsDepth();
472 ol.startIndexListItem();
473 //printf("Passed...\n");
474 bool hasChildren = !cd->visited && !hideSuper && classHasVisibleChildren(cd);
475 //printf("tree4: Has children %s: %d\n",cd->name().data(),hasChildren);
476 if (cd->isLinkable())
478 //printf("Writing class %s\n",cd->displayName().data());
479 ol.startIndexItem(cd->getReference(),cd->getOutputFileBase());
480 ol.parseText(cd->displayName());
481 ol.endIndexItem(cd->getReference(),cd->getOutputFileBase());
482 if (cd->isReference())
484 ol.startTypewriter();
485 ol.docify(" [external]");
490 Doxygen::indexList.addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor());
494 if (cd->getLanguage()==SrcLangExt_VHDL)
496 ftv->addContentsItem(hasChildren,bcli.current()->usedName,cd->getReference(),cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE,cd);
500 ftv->addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE,cd);
506 ol.startIndexItem(0,0);
507 ol.parseText(cd->name());
508 ol.endIndexItem(0,0);
511 Doxygen::indexList.addContentsItem(hasChildren,cd->displayName(),0,0,0);
515 ftv->addContentsItem(hasChildren,cd->displayName(),0,0,0,FALSE,FALSE,cd);
520 //printf("Class %s at %p visited=%d\n",cd->name().data(),cd,cd->visited);
521 bool wasVisited=cd->visited;
523 if (cd->getLanguage()==SrcLangExt_VHDL)
525 writeClassTree(ol,cd->baseClasses(),wasVisited,level+1,ftv,addToIndex);
529 writeClassTree(ol,cd->subClasses(),wasVisited,level+1,ftv,addToIndex);
532 ol.endIndexListItem();
537 endIndexHierarchy(ol,level);
540 Doxygen::indexList.decContentsDepth();
544 ftv->decContentsDepth();
549 //----------------------------------------------------------------------------
551 static bool classVisibleInIndex(ClassDef *cd)
553 static bool allExternals = Config_getBool("ALLEXTERNALS");
554 return (allExternals && cd->isLinkable()) || cd->isLinkableInProject();
557 //----------------------------------------------------------------------------
559 static bool dirHasVisibleChildren(DirDef *dd)
561 if (dd->hasDocumentation()) return TRUE;
563 QListIterator<FileDef> fli(*dd->getFiles());
565 for (fli.toFirst();(fd=fli.current());++fli)
568 if (fileVisibleInIndex(fd,genSourceFile))
578 QListIterator<DirDef> dli(dd->subDirs());
580 for (dli.toFirst();(subdd=dli.current());++dli)
582 if (dirHasVisibleChildren(subdd))
590 //----------------------------------------------------------------------------
591 static void writeDirTreeNode(OutputList &ol, DirDef *dd, int level, FTVHelp* ftv,bool addToIndex)
595 warn(dd->getDefFileName(),dd->getDefLine(),
596 "warning: maximum nesting level exceeded for directory %s: "
597 "check for possible recursive directory relation!\n",dd->name().data()
602 if (!dirHasVisibleChildren(dd))
607 static bool tocExpand = TRUE; //Config_getBool("TOC_EXPAND");
608 bool isDir = dd->subDirs().count()>0 || // there are subdirs
609 (tocExpand && // or toc expand and
610 dd->getFiles() && dd->getFiles()->count()>0 // there are files
612 //printf("gd=`%s': pageDict=%d\n",gd->name().data(),gd->pageDict->count());
615 Doxygen::indexList.addContentsItem(isDir,dd->shortName(),dd->getReference(),dd->getOutputFileBase(),0,TRUE,TRUE);
616 Doxygen::indexList.incContentsDepth();
620 ftv->addContentsItem(isDir,dd->shortName(),dd->getReference(),
621 dd->getOutputFileBase(),0,FALSE,TRUE,dd);
622 ftv->incContentsDepth();
625 ol.startIndexListItem();
626 ol.startIndexItem(dd->getReference(),dd->getOutputFileBase());
627 ol.parseText(dd->shortName());
628 ol.endIndexItem(dd->getReference(),dd->getOutputFileBase());
629 if (dd->isReference())
631 ol.startTypewriter();
632 ol.docify(" [external]");
636 // write sub directories
637 if (dd->subDirs().count()>0)
639 startIndexHierarchy(ol,level+1);
640 QListIterator<DirDef> dli(dd->subDirs());
642 for (dli.toFirst();(subdd=dli.current());++dli)
644 writeDirTreeNode(ol,subdd,level+1,ftv,addToIndex);
646 endIndexHierarchy(ol,level+1);
649 FileList *fileList=dd->getFiles();
651 if (fileList && fileList->count()>0)
653 FileDef *fd=fileList->first();
656 //static bool allExternals = Config_getBool("ALLEXTERNALS");
657 //if ((allExternals && fd->isLinkable()) || fd->isLinkableInProject())
662 if (fileVisibleInIndex(fd,genSourceFile))
666 else if (genSourceFile)
674 startIndexHierarchy(ol,level+1);
675 fd=fileList->first();
679 doc = fileVisibleInIndex(fd,src);
684 reference = fd->getReference();
685 outputBase = fd->getOutputFileBase();
689 ol.startIndexListItem();
690 ol.startIndexItem(reference,outputBase);
691 ol.parseText(fd->displayName());
692 ol.endIndexItem(reference,outputBase);
693 ol.endIndexListItem();
694 if (ftv && (src || doc))
696 ftv->addContentsItem(FALSE,
698 reference,outputBase,
704 endIndexHierarchy(ol,level+1);
708 if (tocExpand && addToIndex)
710 // write files of this directory
713 FileDef *fd=fileList->first();
716 //static bool allExternals = Config_getBool("ALLEXTERNALS");
717 //if ((allExternals && fd->isLinkable()) || fd->isLinkableInProject())
719 doc = fileVisibleInIndex(fd,src);
722 addMembersToIndex(fd,LayoutDocManager::File,fd->displayName(),QCString(),TRUE);
726 Doxygen::indexList.addContentsItem(
727 FALSE, convertToHtml(fd->name(),TRUE), 0,
728 fd->getSourceFileBase(), 0, FALSE, TRUE, fd);
734 ol.endIndexListItem();
738 Doxygen::indexList.decContentsDepth();
742 ftv->decContentsDepth();
746 static void writeDirHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex)
750 ol.pushGeneratorState();
751 ol.disable(OutputGenerator::Html);
753 static bool fullPathNames = Config_getBool("FULL_PATH_NAMES");
754 startIndexHierarchy(ol,0);
757 SDict<DirDef>::Iterator dli(*Doxygen::directories);
759 for (dli.toFirst();(dd=dli.current());++dli)
761 if (dd->getOuterScope()==Doxygen::globalScope)
763 writeDirTreeNode(ol,dd,0,ftv,addToIndex);
769 FileNameListIterator fnli(*Doxygen::inputNameList);
771 for (fnli.toFirst();(fn=fnli.current());++fnli)
773 FileNameIterator fni(*fn);
775 for (;(fd=fni.current());++fni)
777 static bool fullPathNames = Config_getBool("FULL_PATH_NAMES");
778 if (!fullPathNames || fd->getDirDef()==0) // top level file
781 doc = fileVisibleInIndex(fd,src);
782 QCString reference, outputBase;
785 reference = fd->getReference();
786 outputBase = fd->getOutputFileBase();
790 ftv->addContentsItem(FALSE,fd->displayName(),
791 reference, outputBase, 0,
798 addMembersToIndex(fd,LayoutDocManager::File,fd->displayName(),QCString(),TRUE);
802 Doxygen::indexList.addContentsItem(
803 FALSE, convertToHtml(fd->name(),TRUE), 0,
804 fd->getSourceFileBase(), 0, FALSE, TRUE, fd);
811 endIndexHierarchy(ol,0);
814 ol.popGeneratorState();
819 //----------------------------------------------------------------------------
821 static void writeClassTreeForList(OutputList &ol,ClassSDict *cl,bool &started,FTVHelp* ftv,bool addToIndex)
823 ClassSDict::Iterator cli(*cl);
824 for (;cli.current(); ++cli)
826 ClassDef *cd=cli.current();
827 //printf("class %s hasVisibleRoot=%d isVisibleInHierarchy=%d\n",
828 // cd->name().data(),
829 // hasVisibleRoot(cd->baseClasses()),
830 // cd->isVisibleInHierarchy()
833 if (cd->getLanguage()==SrcLangExt_VHDL)
835 if (!(VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS)
839 b=!hasVisibleRoot(cd->subClasses());
843 b=!hasVisibleRoot(cd->baseClasses());
846 if (b) //filter on root classes
848 if (cd->isVisibleInHierarchy()) // should it be visible
852 startIndexHierarchy(ol,0);
855 Doxygen::indexList.incContentsDepth();
859 ol.startIndexListItem();
860 bool hasChildren = !cd->visited && classHasVisibleChildren(cd);
861 //printf("list: Has children %s: %d\n",cd->name().data(),hasChildren);
862 if (cd->isLinkable())
864 //printf("Writing class %s isLinkable()=%d isLinkableInProject()=%d cd->templateMaster()=%p\n",
865 // cd->displayName().data(),cd->isLinkable(),cd->isLinkableInProject(),cd->templateMaster());
866 ol.startIndexItem(cd->getReference(),cd->getOutputFileBase());
867 ol.parseText(cd->displayName());
868 ol.endIndexItem(cd->getReference(),cd->getOutputFileBase());
869 if (cd->isReference())
871 ol.startTypewriter();
872 ol.docify(" [external]");
877 if (cd->getLanguage()!=SrcLangExt_VHDL) // prevents double insertion in Design Unit List
878 Doxygen::indexList.addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE);
882 ftv->addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE,cd);
887 ol.startIndexItem(0,0);
888 ol.parseText(cd->displayName());
889 ol.endIndexItem(0,0);
892 Doxygen::indexList.addContentsItem(hasChildren,cd->displayName(),0,0,0,FALSE,FALSE);
896 ftv->addContentsItem(hasChildren,cd->displayName(),0,0,0,FALSE,FALSE,cd);
899 if (cd->getLanguage()==SrcLangExt_VHDL && hasChildren)
901 writeClassTree(ol,cd->baseClasses(),cd->visited,1,ftv,addToIndex);
904 else if (hasChildren)
906 writeClassTree(ol,cd->subClasses(),cd->visited,1,ftv,addToIndex);
909 ol.endIndexListItem();
915 static void writeClassHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex)
917 initClassHierarchy(Doxygen::classSDict);
918 initClassHierarchy(Doxygen::hiddenClasses);
921 ol.pushGeneratorState();
922 ol.disable(OutputGenerator::Html);
925 writeClassTreeForList(ol,Doxygen::classSDict,started,ftv,addToIndex);
926 writeClassTreeForList(ol,Doxygen::hiddenClasses,started,ftv,addToIndex);
929 endIndexHierarchy(ol,0);
932 Doxygen::indexList.decContentsDepth();
937 ol.popGeneratorState();
941 //----------------------------------------------------------------------------
943 static int countClassesInTreeList(const ClassSDict &cl)
946 ClassSDict::Iterator cli(cl);
947 for (;cli.current(); ++cli)
949 ClassDef *cd=cli.current();
950 if (!hasVisibleRoot(cd->baseClasses())) // filter on root classes
952 if (cd->isVisibleInHierarchy()) // should it be visible
954 if (cd->subClasses()) // should have sub classes
964 static int countClassHierarchy()
967 initClassHierarchy(Doxygen::classSDict);
968 initClassHierarchy(Doxygen::hiddenClasses);
969 count+=countClassesInTreeList(*Doxygen::classSDict);
970 count+=countClassesInTreeList(*Doxygen::hiddenClasses);
974 //----------------------------------------------------------------------------
976 static void writeHierarchicalIndex(OutputList &ol)
978 if (hierarchyClasses==0) return;
979 ol.pushGeneratorState();
981 ol.disable(OutputGenerator::Man);
983 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassHierarchy);
984 QCString title = lne ? lne->title() : theTranslator->trClassHierarchy();
985 bool addToIndex = lne==0 || lne->visible();
987 startFile(ol,"hierarchy",0, title, HLI_Hierarchy);
994 if (Config_getBool("HAVE_DOT") && Config_getBool("GRAPHICAL_HIERARCHY"))
996 ol.disable(OutputGenerator::Latex);
997 ol.disable(OutputGenerator::RTF);
999 ol.startTextLink("inherits",0);
1000 ol.parseText(theTranslator->trGotoGraphicalHierarchy());
1003 ol.enable(OutputGenerator::Latex);
1004 ol.enable(OutputGenerator::RTF);
1006 ol.parseText(lne ? lne->intro() : theTranslator->trClassHierarchyDescription());
1010 // Static class hierarchy for Latex/RTF
1012 ol.pushGeneratorState();
1014 ol.disable(OutputGenerator::Html);
1015 Doxygen::indexList.disable();
1017 writeClassHierarchy(ol,0,addToIndex);
1019 Doxygen::indexList.enable();
1020 ol.popGeneratorState();
1024 // Dynamic class hierarchical index for HTML
1026 ol.pushGeneratorState();
1028 ol.disableAllBut(OutputGenerator::Html);
1033 Doxygen::indexList.addContentsItem(TRUE,title,0,"hierarchy",0,TRUE,TRUE);
1035 FTVHelp* ftv = new FTVHelp(FALSE);
1036 writeClassHierarchy(ol,ftv,addToIndex);
1038 FTextStream t(&outStr);
1039 ftv->generateTreeViewInline(t);
1040 ol.pushGeneratorState();
1041 ol.disableAllBut(OutputGenerator::Html);
1042 ol.writeString(outStr);
1043 ol.popGeneratorState();
1046 ol.popGeneratorState();
1051 ol.popGeneratorState();
1055 //----------------------------------------------------------------------------
1057 static void writeGraphicalClassHierarchy(OutputList &ol)
1059 if (hierarchyClasses==0) return;
1060 ol.disableAllBut(OutputGenerator::Html);
1061 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassHierarchy);
1062 QCString title = lne ? lne->title() : theTranslator->trClassHierarchy();
1063 startFile(ol,"inherits",0,title,HLI_Hierarchy,FALSE,"hierarchy");
1065 ol.parseText(title);
1068 ol.startTextBlock();
1069 ol.startParagraph();
1070 ol.startTextLink("hierarchy",0);
1071 ol.parseText(theTranslator->trGotoTextualHierarchy());
1075 DotGfxHierarchyTable g;
1076 ol.writeGraphicalHierarchy(g);
1081 //----------------------------------------------------------------------------
1083 static void countFiles(int &htmlFiles,int &files)
1087 FileNameListIterator fnli(*Doxygen::inputNameList);
1089 for (;(fn=fnli.current());++fnli)
1091 FileNameIterator fni(*fn);
1093 for (;(fd=fni.current());++fni)
1096 doc = fileVisibleInIndex(fd,src);
1109 //----------------------------------------------------------------------------
1111 static void writeFileIndex(OutputList &ol)
1113 if (documentedHtmlFiles==0) return;
1115 ol.pushGeneratorState();
1116 ol.disable(OutputGenerator::Man);
1117 if (documentedFiles==0) ol.disableAllBut(OutputGenerator::Html);
1119 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::FileList);
1120 if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Files); // fall back
1121 QCString title = lne ? lne->title() : theTranslator->trFileList();
1122 bool addToIndex = lne==0 || lne->visible();
1124 startFile(ol,"files",0,title,HLI_Files);
1126 //if (!Config_getString("PROJECT_NAME").isEmpty())
1128 // title.prepend(Config_getString("PROJECT_NAME")+" ");
1130 ol.parseText(title);
1133 ol.startTextBlock();
1137 Doxygen::indexList.addContentsItem(TRUE,title,0,"files",0,TRUE,TRUE);
1138 Doxygen::indexList.incContentsDepth();
1141 ol.parseText(lne ? lne->intro() : theTranslator->trFileListDescription(Config_getBool("EXTRACT_ALL")));
1149 ol.pushGeneratorState();
1150 ol.disable(OutputGenerator::Html);
1152 OutputNameDict outputNameDict(1009);
1153 OutputNameList outputNameList;
1154 outputNameList.setAutoDelete(TRUE);
1156 if (Config_getBool("FULL_PATH_NAMES"))
1158 // re-sort input files in (dir,file) output order instead of (file,dir) input order
1159 FileName *fn=Doxygen::inputNameList->first();
1162 FileDef *fd=fn->first();
1165 QCString path=fd->getPath();
1166 if (path.isEmpty()) path="[external]";
1167 FileList *fl = outputNameDict.find(path);
1171 //printf("+ inserting %s---%s\n",fd->getPath().data(),fd->name().data());
1175 //printf("o inserting %s---%s\n",fd->getPath().data(),fd->name().data());
1176 fl = new FileList(path);
1178 outputNameList.inSort(fl);
1179 outputNameDict.insert(path,fl);
1183 fn=Doxygen::inputNameList->next();
1187 ol.startIndexList();
1189 if (Config_getBool("FULL_PATH_NAMES"))
1191 fl = outputNameList.first();
1195 fl = Doxygen::inputNameList->first();
1199 FileDef *fd=fl->first();
1202 //printf("Found filedef %s\n",fd->name().data());
1203 bool doc = fd->isLinkableInProject();
1204 bool src = fd->generateSourceFile();
1205 bool nameOk = !fd->isDocumentationFile();
1206 if (nameOk && (doc || src) &&
1210 if (Config_getBool("FULL_PATH_NAMES"))
1212 path=stripFromPath(fd->getPath().copy());
1214 QCString fullName=fd->name();
1215 if (!path.isEmpty())
1217 if (path.at(path.length()-1)!='/') fullName.prepend("/");
1218 fullName.prepend(path);
1225 ol.writeObjectLink(0,fd->getOutputFileBase(),0,fd->name());
1228 // addMembersToIndex(fd,LayoutDocManager::File,fullName,QCString());
1234 ol.docify(fd->name());
1238 // Doxygen::indexList.addContentsItem(FALSE,fullName,0,0,0);
1243 ol.pushGeneratorState();
1244 ol.disableAllBut(OutputGenerator::Html);
1246 ol.startTextLink(fd->includeName(),0);
1248 ol.parseText(theTranslator->trCode());
1251 ol.popGeneratorState();
1254 bool hasBrief = !fd->briefDescription().isEmpty();
1255 ol.startIndexValue(hasBrief);
1260 fd->briefFile(),fd->briefLine(),
1262 fd->briefDescription(TRUE),
1263 FALSE, // index words
1266 TRUE, // single line
1267 TRUE // link from index
1271 ol.endIndexValue(fd->getOutputFileBase(),hasBrief);
1272 //ol.popGeneratorState();
1273 // --------------------------------------------------------
1277 if (Config_getBool("FULL_PATH_NAMES"))
1279 fl=outputNameList.next();
1283 fl=Doxygen::inputNameList->next();
1289 ol.popGeneratorState();
1292 // Hierarchical file index for HTML
1294 ol.pushGeneratorState();
1295 ol.disableAllBut(OutputGenerator::Html);
1297 FTVHelp* ftv = new FTVHelp(FALSE);
1298 writeDirHierarchy(ol,ftv,addToIndex);
1300 FTextStream t(&outStr);
1301 ftv->generateTreeViewInline(t);
1302 ol.writeString(outStr);
1305 ol.popGeneratorState();
1310 Doxygen::indexList.decContentsDepth();
1314 ol.popGeneratorState();
1317 //----------------------------------------------------------------------------
1318 static int countNamespaces()
1321 NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
1323 for (;(nd=nli.current());++nli)
1325 if (nd->isLinkableInProject()) count++;
1330 //----------------------------------------------------------------------------
1332 void writeClassTree(ClassSDict *clDict,FTVHelp *ftv,bool addToIndex,bool globalOnly)
1336 ClassSDict::Iterator cli(*clDict);
1338 for (;(cd=cli.current());++cli)
1340 if (cd->getLanguage()==SrcLangExt_VHDL)
1342 if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKAGECLASS ||
1343 (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS
1348 if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ARCHITECTURECLASS)
1350 QCString n=cd->name();
1351 cd->setClassName(n.data());
1356 cd->getOuterScope()==0 ||
1357 cd->getOuterScope()==Doxygen::globalScope
1361 if (cd->getClassSDict())
1363 ClassSDict::Iterator ccit(*cd->getClassSDict());
1365 for (;(ccd=ccit.current());++ccit)
1367 if (ccd->isLinkableInProject() && ccd->templateMaster()==0)
1373 if (classVisibleInIndex(cd) && cd->templateMaster()==0)
1375 ftv->addContentsItem(count>0,cd->displayName(FALSE),cd->getReference(),
1376 cd->getOutputFileBase(),cd->anchor(),FALSE,TRUE,cd);
1378 cd->partOfGroups()==0 &&
1379 (cd->getOuterScope()==0 ||
1380 cd->getOuterScope()->definitionType()!=Definition::TypeClass
1384 addMembersToIndex(cd,LayoutDocManager::Class,cd->displayName(FALSE),cd->anchor());
1388 ftv->incContentsDepth();
1389 writeClassTree(cd->getClassSDict(),ftv,addToIndex,FALSE);
1390 ftv->decContentsDepth();
1398 static bool containsVisibleChild(NamespaceDef *nd,bool includeClasses)
1400 if (nd->getNamespaceSDict())
1402 NamespaceSDict::Iterator cnli(*nd->getNamespaceSDict());
1404 for (cnli.toFirst();(cnd=cnli.current());++cnli)
1406 if (cnd->isLinkable() && cnd->localName().find('@')==-1)
1410 else if (containsVisibleChild(cnd,includeClasses))
1416 if (includeClasses && nd->getClassSDict())
1418 ClassSDict::Iterator cli(*nd->getClassSDict());
1420 for (;(cd=cli.current());++cli)
1422 if (cd->isLinkableInProject() && cd->templateMaster()==0)
1431 static void writeNamespaceTree(NamespaceSDict *nsDict,FTVHelp *ftv,
1432 bool rootOnly,bool showClasses,bool addToIndex)
1436 NamespaceSDict::Iterator nli(*nsDict);
1438 for (nli.toFirst();(nd=nli.current());++nli)
1440 if (nd->localName().find('@')==-1 &&
1441 (!rootOnly || nd->getOuterScope()==Doxygen::globalScope))
1444 bool hasChildren = containsVisibleChild(nd,showClasses);
1448 if (nd->isLinkableInProject())
1450 ref = nd->getReference();
1451 file = nd->getOutputFileBase();
1452 if (nd->getLanguage()==SrcLangExt_VHDL) // UGLY HACK
1454 file=file.replace(0,strlen("namespace"),"class");
1458 if (nd->isLinkable() || hasChildren)
1460 ftv->addContentsItem(hasChildren,nd->localName(),ref,file,0,FALSE,TRUE,nd);
1464 Doxygen::indexList.addContentsItem(hasChildren,nd->localName(),ref,file,QCString(),
1465 hasChildren && !file.isEmpty(),addToIndex);
1468 //printf("*** writeNamespaceTree count=%d addToIndex=%d showClasses=%d classCount=%d\n",
1469 // count,addToIndex,showClasses,classCount);
1472 if (addToIndex) Doxygen::indexList.incContentsDepth();
1473 ftv->incContentsDepth();
1474 writeNamespaceTree(nd->getNamespaceSDict(),ftv,FALSE,showClasses,addToIndex);
1477 writeClassTree(nd->getClassSDict(),ftv,addToIndex,FALSE);
1479 ftv->decContentsDepth();
1480 if (addToIndex) Doxygen::indexList.decContentsDepth();
1489 static void writeNamespaceIndex(OutputList &ol)
1491 if (documentedNamespaces==0) return;
1492 ol.pushGeneratorState();
1493 ol.disable(OutputGenerator::Man);
1494 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::NamespaceList);
1495 if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Namespaces); // fall back
1496 QCString title = lne ? lne->title() : theTranslator->trNamespaceList();
1497 bool addToIndex = lne==0 || lne->visible();
1498 startFile(ol,"namespaces",0,title,HLI_Namespaces);
1500 ol.parseText(title);
1503 ol.startTextBlock();
1504 ol.parseText(lne ? lne->intro() : theTranslator->trNamespaceListDescription(Config_getBool("EXTRACT_ALL")));
1510 // Linear namespace index for Latex/RTF
1512 ol.pushGeneratorState();
1513 ol.disable(OutputGenerator::Html);
1515 NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
1517 for (nli.toFirst();(nd=nli.current());++nli)
1519 if (nd->isLinkableInProject())
1523 ol.startIndexList();
1526 //ol.writeStartAnnoItem("namespace",nd->getOutputFileBase(),0,nd->name());
1528 if (nd->getLanguage()==SrcLangExt_VHDL)
1530 ol.writeObjectLink(0, nd->getOutputFileBase().replace(0,strlen("namespace"),"class"),0,nd->displayName());
1534 ol.writeObjectLink(0,nd->getOutputFileBase(),0,nd->displayName());
1538 bool hasBrief = !nd->briefDescription().isEmpty();
1539 ol.startIndexValue(hasBrief);
1544 nd->briefFile(),nd->briefLine(),
1546 nd->briefDescription(TRUE),
1547 FALSE, // index words
1550 TRUE, // single line
1551 TRUE // link from index
1555 ol.endIndexValue(nd->getOutputFileBase(),hasBrief);
1559 if (!first) ol.endIndexList();
1561 ol.popGeneratorState();
1564 // Hierarchical namespace index for HTML
1566 ol.pushGeneratorState();
1567 ol.disableAllBut(OutputGenerator::Html);
1572 Doxygen::indexList.addContentsItem(TRUE,title,0,"namespaces",0,TRUE,TRUE);
1573 Doxygen::indexList.incContentsDepth();
1575 FTVHelp* ftv = new FTVHelp(FALSE);
1576 writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,FALSE,addToIndex);
1578 FTextStream t(&outStr);
1579 ftv->generateTreeViewInline(t);
1580 ol.writeString(outStr);
1584 Doxygen::indexList.decContentsDepth();
1588 ol.popGeneratorState();
1592 ol.popGeneratorState();
1595 //----------------------------------------------------------------------------
1597 static int countAnnotatedClasses(int *cp)
1601 ClassSDict::Iterator cli(*Doxygen::classSDict);
1603 for (;(cd=cli.current());++cli)
1605 if (cd->isLinkableInProject() && cd->templateMaster()==0)
1607 if (!cd->isEmbeddedInOuterScope())
1619 static void writeAnnotatedClassList(OutputList &ol)
1621 //LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassList);
1622 //bool addToIndex = lne==0 || lne->visible();
1624 ol.startIndexList();
1625 ClassSDict::Iterator cli(*Doxygen::classSDict);
1628 for (cli.toFirst();(cd=cli.current());++cli)
1630 if (cd->getLanguage()==SrcLangExt_VHDL &&
1631 ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKAGECLASS ||
1632 (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS)
1633 ) // no architecture
1638 ol.pushGeneratorState();
1639 if (cd->isEmbeddedInOuterScope())
1641 ol.disable(OutputGenerator::Latex);
1642 ol.disable(OutputGenerator::RTF);
1644 if (cd->isLinkableInProject() && cd->templateMaster()==0)
1646 QCString type=cd->compoundTypeString();
1648 if (cd->getLanguage()==SrcLangExt_VHDL)
1650 QCString prot= VhdlDocGen::getProtectionName((VhdlDocGen::VhdlClasses)cd->protection());
1651 ol.docify(prot.data());
1652 ol.writeString(" ");
1654 ol.writeObjectLink(0,cd->getOutputFileBase(),cd->anchor(),cd->displayName());
1656 bool hasBrief = !cd->briefDescription().isEmpty();
1657 ol.startIndexValue(hasBrief);
1661 cd->briefFile(),cd->briefLine(),
1663 cd->briefDescription(TRUE),
1664 FALSE, // indexWords
1667 TRUE, // single line
1668 TRUE // link from index
1671 ol.endIndexValue(cd->getOutputFileBase(),hasBrief);
1675 // addMembersToIndex(cd,LayoutDocManager::Class,cd->displayName(),cd->anchor());
1678 ol.popGeneratorState();
1683 static QCString letterToLabel(char startLetter)
1686 if (isId(startLetter))
1688 s[0]=startLetter; s[1]=0;
1692 const char hex[]="0123456789abcdef";
1695 s[2]=hex[startLetter>>4];
1696 s[3]=hex[startLetter&0xF];
1702 //----------------------------------------------------------------------------
1704 /** Special class list where sorting takes IGNORE_PREFIX into account. */
1705 class PrefixIgnoreClassList : public ClassList
1708 virtual int compareItems(GCI item1, GCI item2)
1710 ClassDef *c1=(ClassDef *)item1;
1711 ClassDef *c2=(ClassDef *)item2;
1713 QCString n1 = c1->className();
1714 QCString n2 = c2->className();
1715 return stricmp (n1.data()+getPrefixIndex(n1), n2.data()+getPrefixIndex(n2));
1719 /** Class representing a cell in the alphabetical class index. */
1720 class AlphaIndexTableCell
1723 AlphaIndexTableCell(int row,int col,uchar letter,ClassDef *cd) :
1724 m_letter(letter), m_class(cd), m_row(row), m_col(col)
1725 { //printf("AlphaIndexTableCell(%d,%d,%c,%s)\n",row,col,letter!=0 ? letter: '-',
1726 // cd!=(ClassDef*)0x8 ? cd->name().data() : "<null>");
1729 ClassDef *classDef() const { return m_class; }
1730 uchar letter() const { return m_letter; }
1731 int row() const { return m_row; }
1732 int column() const { return m_col; }
1741 /** Class representing a row in the alphabetical class index. */
1742 class AlphaIndexTableRows : public QList<AlphaIndexTableCell>
1745 AlphaIndexTableRows() { setAutoDelete(TRUE); }
1748 /** Iterator for the cells in a row of the alphabetical class index. */
1749 class AlphaIndexTableRowsIterator : public QListIterator<AlphaIndexTableCell>
1752 AlphaIndexTableRowsIterator(const AlphaIndexTableRows &list) :
1753 QListIterator<AlphaIndexTableCell>(list) {}
1756 /** Class representing the columns in the alphabetical class index. */
1757 class AlphaIndexTableColumns : public QList<AlphaIndexTableRows>
1760 AlphaIndexTableColumns() { setAutoDelete(TRUE); }
1763 // write an alphabetical index of all class with a header for each letter
1764 static void writeAlphabeticalClassList(OutputList &ol)
1766 // What starting letters are used
1767 bool indexLetterUsed[256];
1768 memset (indexLetterUsed, 0, sizeof (indexLetterUsed));
1770 // first count the number of headers
1771 ClassSDict::Iterator cli(*Doxygen::classSDict);
1775 for (;(cd=cli.current());++cli)
1777 if (cd->isLinkableInProject() && cd->templateMaster()==0)
1779 if (cd->getLanguage()==SrcLangExt_VHDL && !((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS ))// no architecture
1782 int index = getPrefixIndex(cd->className());
1783 //printf("name=%s index=%d %d\n",cd->className().data(),index,cd->protection());
1784 startLetter=toupper(cd->className().at(index))&0xFF;
1785 indexLetterUsed[startLetter] = true;
1789 // write quick link index (row of letters)
1790 QCString alphaLinks = "<div class=\"qindex\">";
1792 for (l=0; l<256; l++)
1794 if (indexLetterUsed[l])
1796 if (headerItems) alphaLinks += " | ";
1798 alphaLinks += (QCString)"<a class=\"qindex\" href=\"#letter_" +
1803 alphaLinks += "</div>\n";
1804 ol.writeString(alphaLinks);
1807 // the number of columns in the table
1808 const int columns = Config_getInt("COLS_IN_ALPHA_INDEX");
1811 int totalItems = headerItems*2 + annotatedClasses; // number of items in the table (headers span 2 items)
1812 int rows = (totalItems + columns - 1)/columns; // number of rows in the table
1814 //printf("headerItems=%d totalItems=%d columns=%d rows=%d itemsInLastRow=%d\n",
1815 // headerItems,totalItems,columns,rows,itemsInLastRow);
1817 // Keep a list of classes for each starting letter
1818 PrefixIgnoreClassList classesByLetter[256];
1819 AlphaIndexTableColumns tableColumns;
1821 // fill the columns with the class list (row elements in each column,
1822 // expect for the columns with number >= itemsInLastRow, which get one
1826 for (cli.toFirst();(cd=cli.current());++cli)
1828 if (cd->getLanguage()==SrcLangExt_VHDL && !((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS ))// no architecture
1831 if (cd->isLinkableInProject() && cd->templateMaster()==0)
1833 int index = getPrefixIndex(cd->className());
1834 startLetter=toupper(cd->className().at(index))&0xFF;
1835 // Do some sorting again, since the classes are sorted by name with
1836 // prefix, which should be ignored really.
1837 if (cd->getLanguage()==SrcLangExt_VHDL)
1839 if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS )// no architecture
1840 classesByLetter[startLetter].inSort(cd);
1843 classesByLetter[startLetter].inSort(cd);
1847 #define NEXT_ROW() \
1850 if (row>maxRows) maxRows=row; \
1851 if (row>=rows && col<columns) \
1855 tableRows = new AlphaIndexTableRows; \
1856 tableColumns.append(tableRows); \
1861 AlphaIndexTableRows *tableRows = new AlphaIndexTableRows;
1862 tableColumns.append(tableRows);
1863 int col=0,row=0,maxRows=0;
1864 for (l=0; l<256; l++)
1866 if (classesByLetter[l].count()>0)
1868 // add special header cell
1869 tableRows->append(new AlphaIndexTableCell(row,col,(uchar)l,(ClassDef*)0x8));
1871 tableRows->append(new AlphaIndexTableCell(row,col,0,(ClassDef*)0x8));
1873 tableRows->append(new AlphaIndexTableCell(row,col,0,classesByLetter[l].at(0)));
1876 for (i=1; i<(int)classesByLetter[l].count(); i++)
1879 tableRows->append(new AlphaIndexTableCell(row,col,0,classesByLetter[l].at(i)));
1886 // create row iterators for each column
1887 AlphaIndexTableRowsIterator **colIterators = new AlphaIndexTableRowsIterator*[columns];
1888 for (i=0;i<columns;i++)
1890 if (i<(int)tableColumns.count())
1892 colIterators[i] = new AlphaIndexTableRowsIterator(*tableColumns.at(i));
1894 else // empty column
1896 colIterators[i] = 0;
1900 ol.writeString("<table style=\"margin: 10px; white-space: nowrap;\" align=\"center\" width=\"95%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n");
1902 for (i=0;i<=maxRows;i++) // foreach table row
1904 //printf("writing row %d\n",i);
1905 //ol.nextTableRow();
1906 ol.writeString("<tr>");
1907 // the last column may contain less items then the others
1908 //int colsInRow = (i<rows-1) ? columns : itemsInLastRow;
1909 //printf("row [%d]\n",i);
1910 for (j=0;j<columns;j++) // foreach table column
1912 if (colIterators[j])
1914 AlphaIndexTableCell *cell = colIterators[j]->current();
1919 if (cell->letter()!=0)
1921 QCString s = letterToLabel(cell->letter());
1922 ol.writeString("<td rowspan=\"2\" valign=\"bottom\">");
1923 ol.writeString("<a name=\"letter_");
1925 ol.writeString("\"></a>");
1926 ol.writeString("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">"
1928 "<td><div class=\"ah\">  ");
1930 ol.writeString( "  </div>"
1935 else if (cell->classDef()!=(ClassDef*)0x8)
1937 cd = cell->classDef();
1938 ol.writeString("<td valign=\"top\">");
1939 QCString namesp,cname;
1940 //if (cd->getNamespaceDef()) namesp=cd->getNamespaceDef()->displayName();
1941 //QCString cname=cd->className();
1942 extractNamespaceName(cd->name(),cname,namesp);
1943 QCString nsDispName;
1944 SrcLangExt lang = cd->getLanguage();
1945 QCString sep = getLanguageSpecificSeparator(lang);
1948 nsDispName=substitute(namesp,"::",sep);
1949 cname=substitute(cname,"::",sep);
1956 ol.writeObjectLink(cd->getReference(),
1957 cd->getOutputFileBase(),cd->anchor(),cname);
1958 if (!namesp.isEmpty())
1961 NamespaceDef *nd = getResolvedNamespace(namesp);
1962 if (nd && nd->isLinkable())
1964 ol.writeObjectLink(nd->getReference(),
1965 nd->getOutputFileBase(),0,nsDispName);
1969 ol.docify(nsDispName);
1973 ol.writeNonBreakableSpace(3);
1975 ++(*colIterators[j]);
1976 if (cell->letter()!=0 || cell->classDef()!=(ClassDef*)0x8)
1978 ol.writeString("</td>");
1984 ol.writeString("<td></td>");
1988 ol.writeString("</tr>\n");
1990 ol.writeString("</table>\n");
1992 ol.writeString(alphaLinks);
1994 // release the temporary memory
1995 for (i=0;i<columns;i++)
1997 delete colIterators[i];
1999 delete[] colIterators;
2002 //----------------------------------------------------------------------------
2004 static void writeAlphabeticalIndex(OutputList &ol)
2006 if (annotatedClasses==0) return;
2007 ol.pushGeneratorState();
2008 ol.disableAllBut(OutputGenerator::Html);
2009 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassIndex);
2010 QCString title = lne ? lne->title() : theTranslator->trCompoundIndex();
2011 bool addToIndex = lne==0 || lne->visible();
2013 startFile(ol,"classes",0,title,HLI_Classes);
2016 ol.parseText(title);
2021 Doxygen::indexList.addContentsItem(FALSE,title,0,"classes",0,FALSE,TRUE);
2025 writeAlphabeticalClassList(ol);
2026 endFile(ol); // contains ol.endContents()
2028 ol.popGeneratorState();
2031 //----------------------------------------------------------------------------
2033 static void writeAnnotatedIndex(OutputList &ol)
2035 //printf("writeAnnotatedIndex: count=%d printed=%d\n",
2036 // annotatedClasses,annotatedClassesPrinted);
2037 if (annotatedClasses==0) return;
2039 ol.pushGeneratorState();
2040 ol.disable(OutputGenerator::Man);
2041 if (annotatedClassesPrinted==0)
2043 ol.disable(OutputGenerator::Latex);
2044 ol.disable(OutputGenerator::RTF);
2046 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassList);
2047 if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Classes); // fall back
2048 QCString title = lne ? lne->title() : theTranslator->trCompoundList();
2049 bool addToIndex = lne==0 || lne->visible();
2051 if (Config_getBool("OPTIMIZE_OUTPUT_VHDL"))
2053 VhdlDocGen::findConstraintFile(lne);
2056 startFile(ol,"annotated",0,title,HLI_Annotated);
2059 ol.parseText(title);
2064 ol.startTextBlock();
2065 ol.parseText(lne ? lne->intro() : theTranslator->trCompoundListDescription());
2069 // Linear class index for Latex/RTF
2071 ol.pushGeneratorState();
2072 ol.disable(OutputGenerator::Html);
2073 Doxygen::indexList.disable();
2075 writeAnnotatedClassList(ol);
2077 Doxygen::indexList.enable();
2078 ol.popGeneratorState();
2081 // Hierarchical class index for HTML
2083 ol.pushGeneratorState();
2084 ol.disableAllBut(OutputGenerator::Html);
2089 Doxygen::indexList.addContentsItem(TRUE,title,0,"annotated",0,TRUE,TRUE);
2090 Doxygen::indexList.incContentsDepth();
2092 FTVHelp* ftv = new FTVHelp(FALSE);
2093 writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,TRUE,addToIndex);
2094 writeClassTree(Doxygen::classSDict,ftv,addToIndex,TRUE);
2096 FTextStream t(&outStr);
2097 ftv->generateTreeViewInline(t);
2098 ol.writeString(outStr);
2102 Doxygen::indexList.decContentsDepth();
2106 ol.popGeneratorState();
2109 endFile(ol); // contains ol.endContents()
2110 ol.popGeneratorState();
2113 //----------------------------------------------------------------------------
2114 static void writeClassLinkForMember(OutputList &ol,MemberDef *md,const char *separator,
2115 QCString &prevClassName)
2117 ClassDef *cd=md->getClassDef();
2118 if ( cd && prevClassName!=cd->displayName())
2120 ol.docify(separator);
2121 ol.writeObjectLink(md->getReference(),md->getOutputFileBase(),md->anchor(),
2123 ol.writeString("\n");
2124 prevClassName = cd->displayName();
2128 static void writeFileLinkForMember(OutputList &ol,MemberDef *md,const char *separator,
2129 QCString &prevFileName)
2131 FileDef *fd=md->getFileDef();
2132 if (fd && prevFileName!=fd->name())
2134 ol.docify(separator);
2135 ol.writeObjectLink(md->getReference(),md->getOutputFileBase(),md->anchor(),
2137 ol.writeString("\n");
2138 prevFileName = fd->name();
2142 static void writeNamespaceLinkForMember(OutputList &ol,MemberDef *md,const char *separator,
2143 QCString &prevNamespaceName)
2145 NamespaceDef *nd=md->getNamespaceDef();
2146 if (nd && prevNamespaceName!=nd->name())
2148 ol.docify(separator);
2149 ol.writeObjectLink(md->getReference(),md->getOutputFileBase(),md->anchor(),
2151 ol.writeString("\n");
2152 prevNamespaceName = nd->name();
2156 static void writeMemberList(OutputList &ol,bool useSections,int page,
2157 MemberIndexList memberLists[MEMBER_INDEX_ENTRIES],
2158 DefinitionIntf::DefType type)
2161 // page==-1 => write all member indices to one page (used when total members is small)
2162 // page!=-1 => write all member for this page only (used when total member is large)
2163 int startIndex = page==-1 ? 0 : page;
2164 int endIndex = page==-1 ? MEMBER_INDEX_ENTRIES-1 : page;
2165 ASSERT((int)type<3);
2167 typedef void (*writeLinkForMember_t)(OutputList &ol,MemberDef *md,const char *separator,
2168 QCString &prevNamespaceName);
2170 // each index tab has its own write function
2171 static writeLinkForMember_t writeLinkForMemberMap[3] =
2173 &writeClassLinkForMember,
2174 &writeFileLinkForMember,
2175 &writeNamespaceLinkForMember
2178 QCString prevDefName;
2180 bool firstSection=TRUE;
2181 bool firstItem=TRUE;
2182 for (pi=startIndex; pi<=endIndex; pi++) // page==-1 => pi=[0..127], page!=-1 => pi=page
2184 MemberIndexList *ml = &memberLists[pi];
2185 if (ml->count()==0) continue;
2187 QListIterator<MemberDef> mli(*ml);
2189 for (mli.toFirst();(md=mli.current());++mli)
2192 bool isFunc=!md->isObjCMethod() &&
2193 (md->isFunction() || md->isSlot() || md->isSignal());
2194 QCString name=md->name();
2195 int startIndex = getPrefixIndex(name);
2196 if (QCString(name.data()+startIndex)!=prevName) // new entry
2198 if ((prevName.isEmpty() ||
2199 tolower(name.at(startIndex))!=tolower(prevName.at(0))) &&
2200 useSections) // new section
2202 if (!firstItem) ol.endItemListItem();
2203 if (!firstSection) ol.endItemList();
2205 cl[0] = tolower(name.at(startIndex));
2207 QCString cs = letterToLabel(cl[0]);
2208 QCString anchor=(QCString)"index_"+cs;
2209 QCString title=(QCString)"- "+cl+" -";
2210 ol.startSection(anchor,title,SectionInfo::Subsection);
2212 ol.endSection(anchor,SectionInfo::Subsection);
2217 else if (!useSections && first)
2224 if (!firstItem) ol.endItemListItem();
2225 ol.startItemListItem();
2228 if (isFunc) ol.docify("()");
2229 ol.writeString("\n");
2234 prevName = name.data()+startIndex;
2239 // link to class for other members with the same name
2241 // write the link for the specific list type
2242 writeLinkForMemberMap[(int)type](ol,md,sep,prevDefName);
2245 if (!firstItem) ol.endItemListItem();
2249 //----------------------------------------------------------------------------
2251 void initClassMemberIndices()
2255 for (j=0;j<CMHL_Total;j++)
2257 documentedClassMembers[j]=0;
2258 for (i=0;i<MEMBER_INDEX_ENTRIES;i++)
2260 g_memberIndexLetterUsed[j][i].clear();
2265 void addClassMemberNameToIndex(MemberDef *md)
2267 static bool hideFriendCompounds = Config_getBool("HIDE_FRIEND_COMPOUNDS");
2272 if (md->isLinkableInProject() &&
2273 (cd=md->getClassDef()) &&
2274 cd->isLinkableInProject() &&
2275 cd->templateMaster()==0)
2277 QCString n = md->name();
2278 int index = getPrefixIndex(n);
2279 uchar charCode = (uchar)n.at(index);
2280 uint letter = charCode<128 ? tolower(charCode) : charCode;
2283 bool isFriendToHide = hideFriendCompounds &&
2284 (QCString(md->typeString())=="friend class" ||
2285 QCString(md->typeString())=="friend struct" ||
2286 QCString(md->typeString())=="friend union");
2287 if (!(md->isFriend() && isFriendToHide))
2289 g_memberIndexLetterUsed[CMHL_All][letter].append(md);
2290 documentedClassMembers[CMHL_All]++;
2292 if (md->isFunction() || md->isSlot() || md->isSignal())
2294 g_memberIndexLetterUsed[CMHL_Functions][letter].append(md);
2295 documentedClassMembers[CMHL_Functions]++;
2297 else if (md->isVariable())
2299 g_memberIndexLetterUsed[CMHL_Variables][letter].append(md);
2300 documentedClassMembers[CMHL_Variables]++;
2302 else if (md->isTypedef())
2304 g_memberIndexLetterUsed[CMHL_Typedefs][letter].append(md);
2305 documentedClassMembers[CMHL_Typedefs]++;
2307 else if (md->isEnumerate())
2309 g_memberIndexLetterUsed[CMHL_Enums][letter].append(md);
2310 documentedClassMembers[CMHL_Enums]++;
2312 else if (md->isEnumValue())
2314 g_memberIndexLetterUsed[CMHL_EnumValues][letter].append(md);
2315 documentedClassMembers[CMHL_EnumValues]++;
2317 else if (md->isProperty())
2319 g_memberIndexLetterUsed[CMHL_Properties][letter].append(md);
2320 documentedClassMembers[CMHL_Properties]++;
2322 else if (md->isEvent())
2324 g_memberIndexLetterUsed[CMHL_Events][letter].append(md);
2325 documentedClassMembers[CMHL_Events]++;
2327 else if (md->isRelated() || md->isForeign() ||
2328 (md->isFriend() && !isFriendToHide))
2330 g_memberIndexLetterUsed[CMHL_Related][letter].append(md);
2331 documentedClassMembers[CMHL_Related]++;
2337 //----------------------------------------------------------------------------
2339 void initNamespaceMemberIndices()
2343 for (j=0;j<NMHL_Total;j++)
2345 documentedNamespaceMembers[j]=0;
2346 for (i=0;i<MEMBER_INDEX_ENTRIES;i++)
2348 g_namespaceIndexLetterUsed[j][i].clear();
2353 void addNamespaceMemberNameToIndex(MemberDef *md)
2355 NamespaceDef *nd=md->getNamespaceDef();
2356 if (nd && nd->isLinkableInProject() && md->isLinkableInProject())
2358 QCString n = md->name();
2359 int index = getPrefixIndex(n);
2360 uchar charCode = (uchar)n.at(index);
2361 uint letter = charCode<128 ? tolower(charCode) : charCode;
2364 g_namespaceIndexLetterUsed[NMHL_All][letter].append(md);
2365 documentedNamespaceMembers[NMHL_All]++;
2367 if (md->isFunction())
2369 g_namespaceIndexLetterUsed[NMHL_Functions][letter].append(md);
2370 documentedNamespaceMembers[NMHL_Functions]++;
2372 else if (md->isVariable())
2374 g_namespaceIndexLetterUsed[NMHL_Variables][letter].append(md);
2375 documentedNamespaceMembers[NMHL_Variables]++;
2377 else if (md->isTypedef())
2379 g_namespaceIndexLetterUsed[NMHL_Typedefs][letter].append(md);
2380 documentedNamespaceMembers[NMHL_Typedefs]++;
2382 else if (md->isEnumerate())
2384 g_namespaceIndexLetterUsed[NMHL_Enums][letter].append(md);
2385 documentedNamespaceMembers[NMHL_Enums]++;
2387 else if (md->isEnumValue())
2389 g_namespaceIndexLetterUsed[NMHL_EnumValues][letter].append(md);
2390 documentedNamespaceMembers[NMHL_EnumValues]++;
2396 //----------------------------------------------------------------------------
2398 void initFileMemberIndices()
2402 for (j=0;j<NMHL_Total;j++)
2404 documentedFileMembers[j]=0;
2405 for (i=0;i<MEMBER_INDEX_ENTRIES;i++)
2407 g_fileIndexLetterUsed[j][i].clear();
2412 void addFileMemberNameToIndex(MemberDef *md)
2414 FileDef *fd=md->getFileDef();
2415 if (fd && fd->isLinkableInProject() && md->isLinkableInProject())
2417 QCString n = md->name();
2418 int index = getPrefixIndex(n);
2419 uchar charCode = (uchar)n.at(index);
2420 uint letter = charCode<128 ? tolower(charCode) : charCode;
2423 g_fileIndexLetterUsed[FMHL_All][letter].append(md);
2424 documentedFileMembers[FMHL_All]++;
2426 if (md->isFunction())
2428 g_fileIndexLetterUsed[FMHL_Functions][letter].append(md);
2429 documentedFileMembers[FMHL_Functions]++;
2431 else if (md->isVariable())
2433 g_fileIndexLetterUsed[FMHL_Variables][letter].append(md);
2434 documentedFileMembers[FMHL_Variables]++;
2436 else if (md->isTypedef())
2438 g_fileIndexLetterUsed[FMHL_Typedefs][letter].append(md);
2439 documentedFileMembers[FMHL_Typedefs]++;
2441 else if (md->isEnumerate())
2443 g_fileIndexLetterUsed[FMHL_Enums][letter].append(md);
2444 documentedFileMembers[FMHL_Enums]++;
2446 else if (md->isEnumValue())
2448 g_fileIndexLetterUsed[FMHL_EnumValues][letter].append(md);
2449 documentedFileMembers[FMHL_EnumValues]++;
2451 else if (md->isDefine())
2453 g_fileIndexLetterUsed[FMHL_Defines][letter].append(md);
2454 documentedFileMembers[FMHL_Defines]++;
2460 //----------------------------------------------------------------------------
2462 static void writeQuickMemberIndex(OutputList &ol,
2463 MemberIndexList charUsed[MEMBER_INDEX_ENTRIES],int page,
2464 QCString fullName,bool multiPage)
2468 startQuickIndexList(ol,TRUE);
2469 for (i=33;i<127;i++)
2471 char is[2];is[0]=(char)i;is[1]='\0';
2472 QCString ci = letterToLabel((char)i);
2473 if (charUsed[i].count()>0)
2476 QCString extension=Doxygen::htmlFileExtension;
2480 anchor=fullName+extension+"#index_";
2482 anchor=fullName+QCString().sprintf("_0x%02x",i)+extension+"#index_";
2483 startQuickIndexItem(ol,anchor+ci,i==page,TRUE,first);
2485 endQuickIndexItem(ol);
2489 endQuickIndexList(ol);
2492 //----------------------------------------------------------------------------
2494 /** Helper class representing a class member in the navigation menu. */
2497 CmhlInfo(const char *fn,const char *t) : fname(fn), title(t) {}
2502 static const CmhlInfo *getCmhlInfo(int hl)
2504 static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
2505 static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
2506 static CmhlInfo cmhlInfo[] =
2508 CmhlInfo("functions", theTranslator->trAll()),
2509 CmhlInfo("functions_func",
2510 fortranOpt ? theTranslator->trSubprograms() :
2511 vhdlOpt ? VhdlDocGen::trFunctionAndProc() :
2512 theTranslator->trFunctions()),
2513 CmhlInfo("functions_vars",theTranslator->trVariables()),
2514 CmhlInfo("functions_type",theTranslator->trTypedefs()),
2515 CmhlInfo("functions_enum",theTranslator->trEnumerations()),
2516 CmhlInfo("functions_eval",theTranslator->trEnumerationValues()),
2517 CmhlInfo("functions_prop",theTranslator->trProperties()),
2518 CmhlInfo("functions_evnt",theTranslator->trEvents()),
2519 CmhlInfo("functions_rela",theTranslator->trRelatedFunctions())
2521 return &cmhlInfo[hl];
2524 static void writeClassMemberIndexFiltered(OutputList &ol, ClassMemberHighlight hl)
2526 if (documentedClassMembers[hl]==0) return;
2528 static bool disableIndex = Config_getBool("DISABLE_INDEX");
2530 bool multiPageIndex=FALSE;
2532 if (documentedClassMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX)
2534 multiPageIndex=TRUE;
2538 ol.pushGeneratorState();
2539 ol.disableAllBut(OutputGenerator::Html);
2541 QCString extension=Doxygen::htmlFileExtension;
2542 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassMembers);
2543 QCString title = lne ? lne->title() : theTranslator->trCompoundMembers();
2544 if (hl!=CMHL_All) title+=(QCString)" - "+getCmhlInfo(hl)->title;
2545 bool addToIndex = lne==0 || lne->visible();
2549 Doxygen::indexList.addContentsItem(multiPageIndex,getCmhlInfo(hl)->title,0,
2550 getCmhlInfo(hl)->fname,0,multiPageIndex,TRUE);
2551 if (multiPageIndex) Doxygen::indexList.incContentsDepth();
2556 for (page=0;page<numPages;page++)
2558 if (!multiPageIndex || g_memberIndexLetterUsed[hl][page].count()>0)
2560 QCString fileName = getCmhlInfo(hl)->fname;
2565 fileName+=QCString().sprintf("_0x%02x",page);
2572 Doxygen::indexList.addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE);
2575 bool quickIndex = documentedClassMembers[hl]>maxItemsBeforeQuickIndex;
2577 ol.startFile(fileName+extension,0,title);
2578 ol.startQuickIndices();
2581 ol.writeQuickLinks(TRUE,HLI_Functions,0);
2582 startQuickIndexList(ol);
2584 // index item for global member list
2585 startQuickIndexItem(ol,
2586 getCmhlInfo(0)->fname+Doxygen::htmlFileExtension,hl==CMHL_All,TRUE,first);
2587 ol.writeString(fixSpaces(getCmhlInfo(0)->title));
2588 endQuickIndexItem(ol);
2591 // index items per category member lists
2592 for (i=1;i<CMHL_Total;i++)
2594 if (documentedClassMembers[i]>0)
2596 startQuickIndexItem(ol,getCmhlInfo(i)->fname+Doxygen::htmlFileExtension,hl==i,TRUE,first);
2597 ol.writeString(fixSpaces(getCmhlInfo(i)->title));
2598 //printf("multiPageIndex=%d first=%d fileName=%s file=%s title=%s\n",
2599 // multiPageIndex,first,fileName.data(),getCmhlInfo(i)->fname,getCmhlInfo(i)->title.data());
2600 endQuickIndexItem(ol);
2604 endQuickIndexList(ol);
2606 // quick alphabetical index
2609 writeQuickMemberIndex(ol,g_memberIndexLetterUsed[hl],page,
2610 getCmhlInfo(hl)->fname,multiPageIndex);
2613 ol.endQuickIndices();
2614 ol.writeSplitBar(fileName);
2615 ol.writeSearchInfo();
2621 ol.startTextBlock();
2622 ol.parseText(lne ? lne->intro() : theTranslator->trCompoundMembersDescription(Config_getBool("EXTRACT_ALL")));
2627 // hack to work around a mozilla bug, which refuses to switch to
2628 // normal lists otherwise
2629 ol.writeString(" ");
2631 //ol.newParagraph(); // FIXME:PARA
2632 writeMemberList(ol,quickIndex,
2633 multiPageIndex?page:-1,
2634 g_memberIndexLetterUsed[hl],
2635 Definition::TypeClass);
2641 if (multiPageIndex && addToIndex) Doxygen::indexList.decContentsDepth();
2643 ol.popGeneratorState();
2646 static void writeClassMemberIndex(OutputList &ol)
2648 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassMembers);
2649 bool addToIndex = lne==0 || lne->visible();
2651 if (documentedClassMembers[CMHL_All]>0 && addToIndex)
2653 Doxygen::indexList.addContentsItem(TRUE,lne ? lne->title() : theTranslator->trCompoundMembers(),0,"functions",0);
2654 Doxygen::indexList.incContentsDepth();
2656 writeClassMemberIndexFiltered(ol,CMHL_All);
2657 writeClassMemberIndexFiltered(ol,CMHL_Functions);
2658 writeClassMemberIndexFiltered(ol,CMHL_Variables);
2659 writeClassMemberIndexFiltered(ol,CMHL_Typedefs);
2660 writeClassMemberIndexFiltered(ol,CMHL_Enums);
2661 writeClassMemberIndexFiltered(ol,CMHL_EnumValues);
2662 writeClassMemberIndexFiltered(ol,CMHL_Properties);
2663 writeClassMemberIndexFiltered(ol,CMHL_Events);
2664 writeClassMemberIndexFiltered(ol,CMHL_Related);
2665 if (documentedClassMembers[CMHL_All]>0 && addToIndex)
2667 Doxygen::indexList.decContentsDepth();
2672 //----------------------------------------------------------------------------
2674 /** Helper class representing a file member in the navigation menu. */
2677 FmhlInfo(const char *fn,const char *t) : fname(fn), title(t) {}
2682 static const FmhlInfo *getFmhlInfo(int hl)
2684 static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
2685 static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
2686 static FmhlInfo fmhlInfo[] =
2688 FmhlInfo("globals", theTranslator->trAll()),
2689 FmhlInfo("globals_func",
2690 fortranOpt ? theTranslator->trSubprograms() :
2691 vhdlOpt ? VhdlDocGen::trFunctionAndProc() :
2692 theTranslator->trFunctions()),
2693 FmhlInfo("globals_vars",theTranslator->trVariables()),
2694 FmhlInfo("globals_type",theTranslator->trTypedefs()),
2695 FmhlInfo("globals_enum",theTranslator->trEnumerations()),
2696 FmhlInfo("globals_eval",theTranslator->trEnumerationValues()),
2697 FmhlInfo("globals_defs",theTranslator->trDefines())
2699 return &fmhlInfo[hl];
2702 static void writeFileMemberIndexFiltered(OutputList &ol, FileMemberHighlight hl)
2704 if (documentedFileMembers[hl]==0) return;
2706 static bool disableIndex = Config_getBool("DISABLE_INDEX");
2708 bool multiPageIndex=FALSE;
2710 if (documentedFileMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX)
2712 multiPageIndex=TRUE;
2716 ol.pushGeneratorState();
2717 ol.disableAllBut(OutputGenerator::Html);
2719 QCString extension=Doxygen::htmlFileExtension;
2720 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::FileGlobals);
2721 QCString title = lne ? lne->title() : theTranslator->trFileMembers();
2722 bool addToIndex = lne==0 || lne->visible();
2726 Doxygen::indexList.addContentsItem(multiPageIndex,getFmhlInfo(hl)->title,0,
2727 getFmhlInfo(hl)->fname,0,multiPageIndex,TRUE);
2728 if (multiPageIndex) Doxygen::indexList.incContentsDepth();
2733 for (page=0;page<numPages;page++)
2735 if (!multiPageIndex || g_fileIndexLetterUsed[hl][page].count()>0)
2737 QCString fileName = getFmhlInfo(hl)->fname;
2742 fileName+=QCString().sprintf("_0x%02x",page);
2749 Doxygen::indexList.addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE);
2752 bool quickIndex = documentedFileMembers[hl]>maxItemsBeforeQuickIndex;
2754 ol.startFile(fileName+extension,0,title);
2755 ol.startQuickIndices();
2758 ol.writeQuickLinks(TRUE,HLI_Globals,0);
2759 startQuickIndexList(ol);
2761 // index item for all file member lists
2762 startQuickIndexItem(ol,
2763 getFmhlInfo(0)->fname+Doxygen::htmlFileExtension,hl==FMHL_All,TRUE,first);
2764 ol.writeString(fixSpaces(getFmhlInfo(0)->title));
2765 endQuickIndexItem(ol);
2768 // index items for per category member lists
2769 for (i=1;i<FMHL_Total;i++)
2771 if (documentedFileMembers[i]>0)
2773 startQuickIndexItem(ol,
2774 getFmhlInfo(i)->fname+Doxygen::htmlFileExtension,hl==i,TRUE,first);
2775 ol.writeString(fixSpaces(getFmhlInfo(i)->title));
2776 endQuickIndexItem(ol);
2780 endQuickIndexList(ol);
2784 writeQuickMemberIndex(ol,g_fileIndexLetterUsed[hl],page,
2785 getFmhlInfo(hl)->fname,multiPageIndex);
2788 ol.endQuickIndices();
2789 ol.writeSplitBar(fileName);
2790 ol.writeSearchInfo();
2796 ol.startTextBlock();
2797 ol.parseText(lne ? lne->intro() : theTranslator->trFileMembersDescription(Config_getBool("EXTRACT_ALL")));
2802 // hack to work around a mozilla bug, which refuses to switch to
2803 // normal lists otherwise
2804 ol.writeString(" ");
2806 //ol.newParagraph(); // FIXME:PARA
2807 //writeFileMemberList(ol,quickIndex,hl,page);
2808 writeMemberList(ol,quickIndex,
2809 multiPageIndex?page:-1,
2810 g_fileIndexLetterUsed[hl],
2811 Definition::TypeFile);
2816 if (multiPageIndex && addToIndex) Doxygen::indexList.decContentsDepth();
2817 ol.popGeneratorState();
2820 static void writeFileMemberIndex(OutputList &ol)
2822 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::FileGlobals);
2823 bool addToIndex = lne==0 || lne->visible();
2824 if (documentedFileMembers[FMHL_All]>0 && addToIndex)
2826 Doxygen::indexList.addContentsItem(FALSE,lne ? lne->title() : theTranslator->trFileMembers(),0,"globals",0);
2827 Doxygen::indexList.incContentsDepth();
2829 writeFileMemberIndexFiltered(ol,FMHL_All);
2830 writeFileMemberIndexFiltered(ol,FMHL_Functions);
2831 writeFileMemberIndexFiltered(ol,FMHL_Variables);
2832 writeFileMemberIndexFiltered(ol,FMHL_Typedefs);
2833 writeFileMemberIndexFiltered(ol,FMHL_Enums);
2834 writeFileMemberIndexFiltered(ol,FMHL_EnumValues);
2835 writeFileMemberIndexFiltered(ol,FMHL_Defines);
2836 if (documentedFileMembers[FMHL_All]>0 && addToIndex)
2838 Doxygen::indexList.decContentsDepth();
2843 //----------------------------------------------------------------------------
2845 /** Helper class representing a namespace member in the navigation menu. */
2848 NmhlInfo(const char *fn,const char *t) : fname(fn), title(t) {}
2853 static const NmhlInfo *getNmhlInfo(int hl)
2855 static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
2856 static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
2857 static NmhlInfo nmhlInfo[] =
2859 NmhlInfo("namespacemembers", theTranslator->trAll()),
2860 NmhlInfo("namespacemembers_func",
2861 fortranOpt ? theTranslator->trSubprograms() :
2862 vhdlOpt ? VhdlDocGen::trFunctionAndProc() :
2863 theTranslator->trFunctions()),
2864 NmhlInfo("namespacemembers_vars",theTranslator->trVariables()),
2865 NmhlInfo("namespacemembers_type",theTranslator->trTypedefs()),
2866 NmhlInfo("namespacemembers_enum",theTranslator->trEnumerations()),
2867 NmhlInfo("namespacemembers_eval",theTranslator->trEnumerationValues())
2869 return &nmhlInfo[hl];
2872 //----------------------------------------------------------------------------
2874 static void writeNamespaceMemberIndexFiltered(OutputList &ol,
2875 NamespaceMemberHighlight hl)
2877 if (documentedNamespaceMembers[hl]==0) return;
2879 static bool disableIndex = Config_getBool("DISABLE_INDEX");
2882 bool multiPageIndex=FALSE;
2884 if (documentedNamespaceMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX)
2886 multiPageIndex=TRUE;
2890 ol.pushGeneratorState();
2891 ol.disableAllBut(OutputGenerator::Html);
2893 QCString extension=Doxygen::htmlFileExtension;
2894 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::NamespaceMembers);
2895 QCString title = lne ? lne->title() : theTranslator->trNamespaceMembers();
2896 bool addToIndex = lne==0 || lne->visible();
2900 Doxygen::indexList.addContentsItem(multiPageIndex,getNmhlInfo(hl)->title,0,
2901 getNmhlInfo(hl)->fname,0,multiPageIndex,TRUE);
2902 if (multiPageIndex) Doxygen::indexList.incContentsDepth();
2907 for (page=0;page<numPages;page++)
2909 if (!multiPageIndex || g_namespaceIndexLetterUsed[hl][page].count()>0)
2911 QCString fileName = getNmhlInfo(hl)->fname;
2916 fileName+=QCString().sprintf("_0x%02x",page);
2923 Doxygen::indexList.addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE);
2926 bool quickIndex = documentedNamespaceMembers[hl]>maxItemsBeforeQuickIndex;
2928 ol.startFile(fileName+extension,0,title);
2929 ol.startQuickIndices();
2932 ol.writeQuickLinks(TRUE,HLI_NamespaceMembers,0);
2933 startQuickIndexList(ol);
2935 // index item for all namespace member lists
2936 startQuickIndexItem(ol,
2937 getNmhlInfo(0)->fname+Doxygen::htmlFileExtension,hl==NMHL_All,TRUE,first);
2938 ol.writeString(fixSpaces(getNmhlInfo(0)->title));
2939 endQuickIndexItem(ol);
2942 // index items per category member lists
2943 for (i=1;i<NMHL_Total;i++)
2945 if (documentedNamespaceMembers[i]>0)
2947 startQuickIndexItem(ol,
2948 getNmhlInfo(i)->fname+Doxygen::htmlFileExtension,hl==i,TRUE,first);
2949 ol.writeString(fixSpaces(getNmhlInfo(i)->title));
2950 endQuickIndexItem(ol);
2954 endQuickIndexList(ol);
2958 writeQuickMemberIndex(ol,g_namespaceIndexLetterUsed[hl],page,
2959 getNmhlInfo(hl)->fname,multiPageIndex);
2963 ol.endQuickIndices();
2964 ol.writeSplitBar(fileName);
2965 ol.writeSearchInfo();
2971 ol.startTextBlock();
2972 ol.parseText(lne ? lne->intro() : theTranslator->trNamespaceMemberDescription(Config_getBool("EXTRACT_ALL")));
2977 // hack to work around a mozilla bug, which refuses to switch to
2978 // normal lists otherwise
2979 ol.writeString(" ");
2981 //ol.newParagraph(); // FIXME:PARA
2983 //writeNamespaceMemberList(ol,quickIndex,hl,page);
2984 writeMemberList(ol,quickIndex,
2985 multiPageIndex?page:-1,
2986 g_namespaceIndexLetterUsed[hl],
2987 Definition::TypeNamespace);
2991 if (multiPageIndex && addToIndex) Doxygen::indexList.decContentsDepth();
2992 ol.popGeneratorState();
2995 static void writeNamespaceMemberIndex(OutputList &ol)
2997 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::NamespaceMembers);
2998 bool addToIndex = lne==0 || lne->visible();
2999 if (documentedNamespaceMembers[NMHL_All]>0 && addToIndex)
3001 Doxygen::indexList.addContentsItem(FALSE,lne ? lne->title() : theTranslator->trNamespaceMembers(),0,"namespacemembers",0);
3002 Doxygen::indexList.incContentsDepth();
3004 //bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
3005 writeNamespaceMemberIndexFiltered(ol,NMHL_All);
3006 writeNamespaceMemberIndexFiltered(ol,NMHL_Functions);
3007 writeNamespaceMemberIndexFiltered(ol,NMHL_Variables);
3008 writeNamespaceMemberIndexFiltered(ol,NMHL_Typedefs);
3009 writeNamespaceMemberIndexFiltered(ol,NMHL_Enums);
3010 writeNamespaceMemberIndexFiltered(ol,NMHL_EnumValues);
3011 if (documentedNamespaceMembers[NMHL_All]>0 && addToIndex)
3013 Doxygen::indexList.decContentsDepth();
3018 //----------------------------------------------------------------------------
3020 //----------------------------------------------------------------------------
3022 static void writeExampleIndex(OutputList &ol)
3024 if (Doxygen::exampleSDict->count()==0) return;
3025 ol.pushGeneratorState();
3026 ol.disable(OutputGenerator::Man);
3027 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Examples);
3028 QCString title = lne ? lne->title() : theTranslator->trExamples();
3029 bool addToIndex = lne==0 || lne->visible();
3031 startFile(ol,"examples",0,title,HLI_Examples);
3034 ol.parseText(title);
3041 Doxygen::indexList.addContentsItem(TRUE,title,0,"examples",0,TRUE,TRUE);
3042 Doxygen::indexList.incContentsDepth();
3045 ol.startTextBlock();
3046 ol.parseText(lne ? lne->intro() : theTranslator->trExamplesDescription());
3050 PageSDict::Iterator pdi(*Doxygen::exampleSDict);
3052 for (pdi.toFirst();(pd=pdi.current());++pdi)
3054 ol.startItemListItem();
3055 QCString n=pd->getOutputFileBase();
3056 if (!pd->title().isEmpty())
3058 ol.writeObjectLink(0,n,0,pd->title());
3061 Doxygen::indexList.addContentsItem(FALSE,filterTitle(pd->title()),pd->getReference(),n,0,FALSE,TRUE);
3066 ol.writeObjectLink(0,n,0,pd->name());
3069 Doxygen::indexList.addContentsItem(FALSE,pd->name(),pd->getReference(),n,0,FALSE,TRUE);
3072 ol.endItemListItem();
3073 ol.writeString("\n");
3079 Doxygen::indexList.decContentsDepth();
3082 ol.popGeneratorState();
3086 //----------------------------------------------------------------------------
3088 template<typename T>
3089 bool writeMemberNavIndex(FTextStream &t,
3092 int documentedMembers[],
3093 MemberIndexList indexLetterUsed[][MEMBER_INDEX_ENTRIES],
3094 const T *(*getInfo)(int),
3101 indentStr.fill(' ',indent*2);
3102 // index items per category member lists
3106 bool hasIndex = documentedMembers[i]>0;
3107 bool quickIndex = documentedMembers[i]>maxItemsBeforeQuickIndex;
3108 bool multiIndexPage = documentedMembers[i]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX;
3111 // terminate previous entry
3112 if (!first) t << "," << endl;
3122 t << indentStr << " [ ";
3123 t << "\"" << fixSpaces(getInfo(i)->title) << "\", ";
3124 t << "\"" << getInfo(i)->fname << Doxygen::htmlFileExtension << "\", ";
3125 bool firstPage=TRUE;
3130 for (j=33;j<127;j++)
3132 if (indexLetterUsed[i][j].count()>0)
3134 if (!firstPage) t << "," << endl;
3135 QCString fullName = getInfo(i)->fname;
3136 QCString extension = Doxygen::htmlFileExtension;
3138 if (firstPage || !multiIndexPage)
3139 anchor=fullName+extension+"#index_";
3141 anchor=fullName+QCString().sprintf("_0x%02x",j)+extension+"#index_";
3142 char is[2];is[0]=(char)j;is[1]='\0';
3143 QCString ci = letterToLabel((char)j);
3144 t << indentStr << " [ ";
3145 t << "\"" << is << "\", ";
3146 t << "\"" << anchor << ci << "\", null ]";
3150 t << endl << indentStr << " ] ]";
3154 t << "null" << " ]";
3161 //----------------------------------------------------------------------------
3164 static bool writeFullNavIndex(FTextStream &t, LayoutNavEntry *root,int indent,bool &first)
3166 static struct NavEntryCountMap
3168 LayoutNavEntry::Kind kind;
3170 } navEntryCountMap[] =
3172 { LayoutNavEntry::MainPage, TRUE },
3173 { LayoutNavEntry::Pages, indexedPages>0 },
3174 { LayoutNavEntry::Modules, documentedGroups>0 },
3175 { LayoutNavEntry::Namespaces, documentedNamespaces>0 },
3176 { LayoutNavEntry::NamespaceList, documentedNamespaces>0 },
3177 { LayoutNavEntry::NamespaceMembers, documentedNamespaceMembers[NMHL_All]>0 },
3178 { LayoutNavEntry::Classes, annotatedClasses>0 },
3179 { LayoutNavEntry::ClassList, annotatedClasses>0 },
3180 { LayoutNavEntry::ClassIndex, annotatedClasses>0 },
3181 { LayoutNavEntry::ClassHierarchy, hierarchyClasses>0 },
3182 { LayoutNavEntry::ClassMembers, documentedClassMembers[CMHL_All]>0 },
3183 { LayoutNavEntry::Files, documentedFiles>0 },
3184 { LayoutNavEntry::FileList, documentedFiles>0 },
3185 { LayoutNavEntry::FileGlobals, documentedFileMembers[FMHL_All]>0 },
3186 //{ LayoutNavEntry::Dirs, documentedDirs>0 },
3187 { LayoutNavEntry::Examples, Doxygen::exampleSDict->count()>0 }
3191 indentStr.fill(' ',indent*2);
3193 if (root->children().count()>0)
3195 QListIterator<LayoutNavEntry> li(root->children());
3196 LayoutNavEntry *entry;
3197 for (li.toFirst();(entry=li.current());++li)
3199 if (navEntryCountMap[entry->kind()].hasItems && entry->visible())
3201 // terminate previous entry
3202 if (!first) t << "," << endl;
3212 bool emptySection=TRUE;
3213 t << indentStr << " [ ";
3214 t << "\"" << fixSpaces(entry->title()) << "\", ";
3215 t << "\"" << entry->baseFile() << Doxygen::htmlFileExtension << "\", ";
3217 // write children (if any)
3218 bool firstChild=TRUE;
3219 if (entry->kind()==LayoutNavEntry::ClassMembers)
3221 emptySection = !writeMemberNavIndex(t,indent+1,CMHL_Total,documentedClassMembers,g_memberIndexLetterUsed,&getCmhlInfo,firstChild);
3223 else if (entry->kind()==LayoutNavEntry::NamespaceMembers)
3225 emptySection = !writeMemberNavIndex(t,indent+1,NMHL_Total,documentedNamespaceMembers,g_namespaceIndexLetterUsed,&getNmhlInfo,firstChild);
3227 else if (entry->kind()==LayoutNavEntry::FileGlobals)
3229 emptySection = !writeMemberNavIndex(t,indent+1,FMHL_Total,documentedFileMembers,g_fileIndexLetterUsed,&getFmhlInfo,firstChild);
3233 emptySection = !writeFullNavIndex(t,entry,indent+1,firstChild);
3236 if (emptySection) // entry without children
3238 else // entry with children
3239 t << endl << indentStr << " ] ]";
3247 //----------------------------------------------------------------------------
3249 static void countRelatedPages(int &docPages,int &indexPages)
3251 docPages=indexPages=0;
3252 PageSDict::Iterator pdi(*Doxygen::pageSDict);
3254 for (pdi.toFirst();(pd=pdi.current());++pdi)
3256 if ( pd->visibleInIndex())
3260 if ( pd->documentedPage())
3267 //----------------------------------------------------------------------------
3269 static void writePages(PageDef *pd,FTVHelp *ftv)
3271 //printf("writePages()=%s pd=%p mainpage=%p\n",pd->name().data(),pd,Doxygen::mainPage);
3272 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Pages);
3273 bool addToIndex = lne==0 || lne->visible();
3274 if (!addToIndex) return;
3276 bool hasSubPages = pd->hasSubPages();
3277 bool hasSections = pd->hasSections();
3279 if (pd->visibleInIndex())
3283 if (pd->title().isEmpty())
3284 pageTitle=pd->name();
3286 pageTitle=pd->title();
3290 //printf("*** adding %s\n",pageTitle.data());
3291 ftv->addContentsItem(
3292 hasSubPages,pageTitle,
3293 pd->getReference(),pd->getOutputFileBase(),
3294 0,hasSubPages,TRUE,pd);
3296 if (addToIndex && pd!=Doxygen::mainPage)
3298 Doxygen::indexList.addContentsItem(
3299 hasSubPages,pageTitle,
3300 pd->getReference(),pd->getOutputFileBase(),
3301 0,hasSubPages,TRUE);
3304 if (hasSubPages && ftv) ftv->incContentsDepth();
3305 if ((hasSections || hasSubPages) && pd!=Doxygen::mainPage)
3307 Doxygen::indexList.incContentsDepth();
3311 pd->addSectionsToIndex();
3313 PageSDict *subPages = pd->getSubPages();
3316 PageSDict::Iterator pi(*subPages);
3318 for (pi.toFirst();(subPage=pi.current());++pi)
3320 writePages(subPage,ftv);
3323 if (hasSubPages && ftv) ftv->decContentsDepth();
3324 if ((hasSections || hasSubPages) && pd!=Doxygen::mainPage)
3326 Doxygen::indexList.decContentsDepth();
3328 //printf("end writePages()=%s\n",pd->title().data());
3332 static void writePageIndex(OutputList &ol)
3334 if (indexedPages==0) return;
3335 ol.pushGeneratorState();
3336 ol.disableAllBut(OutputGenerator::Html);
3337 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Pages);
3338 QCString title = lne ? lne->title() : theTranslator->trRelatedPages();
3339 startFile(ol,"pages",0,title,HLI_Pages);
3341 ol.parseText(title);
3344 ol.startTextBlock();
3345 ol.parseText(lne ? lne->intro() : theTranslator->trRelatedPagesDescription());
3349 FTVHelp* ftv = new FTVHelp(FALSE);
3350 PageSDict::Iterator pdi(*Doxygen::pageSDict);
3352 for (pdi.toFirst();(pd=pdi.current());++pdi)
3354 if (pd->getOuterScope()==0 ||
3355 pd->getOuterScope()->definitionType()!=Definition::TypePage
3362 FTextStream t(&outStr);
3363 ftv->generateTreeViewInline(t);
3364 ol.writeString(outStr);
3368 // ol.popGeneratorState();
3372 ol.popGeneratorState();
3375 //----------------------------------------------------------------------------
3377 static int countGroups()
3380 GroupSDict::Iterator gli(*Doxygen::groupSDict);
3382 for (gli.toFirst();(gd=gli.current());++gli)
3384 if (!gd->isReference())
3393 //----------------------------------------------------------------------------
3395 static int countDirs()
3398 SDict<DirDef>::Iterator dli(*Doxygen::directories);
3400 for (dli.toFirst();(dd=dli.current());++dli)
3402 if (dd->isLinkableInProject())
3412 //----------------------------------------------------------------------------
3414 void writeGraphInfo(OutputList &ol)
3416 if (!Config_getBool("HAVE_DOT") || !Config_getBool("GENERATE_HTML")) return;
3417 ol.pushGeneratorState();
3418 ol.disableAllBut(OutputGenerator::Html);
3419 generateGraphLegend(Config_getString("HTML_OUTPUT"));
3420 startFile(ol,"graph_legend",0,theTranslator->trLegendTitle().data());
3422 ol.parseText(theTranslator->trLegendTitle());
3425 bool &stripCommentsStateRef = Config_getBool("STRIP_CODE_COMMENTS");
3426 bool oldStripCommentsState = stripCommentsStateRef;
3427 // temporarily disable the stripping of comments for our own code example!
3428 stripCommentsStateRef = FALSE;
3429 QCString legendDocs = theTranslator->trLegendDocs();
3430 int s = legendDocs.find("<center>");
3431 int e = legendDocs.find("</center>");
3432 if (Config_getEnum("DOT_IMAGE_FORMAT")=="svg" && s!=-1 && e!=-1)
3434 legendDocs = legendDocs.left(s+8) + "[!-- SVG 0 --]\n" + legendDocs.mid(e);
3435 //printf("legendDocs=%s\n",legendDocs.data());
3437 FileDef fd("","graph_legend");
3438 ol.parseDoc("graph_legend",1,&fd,0,legendDocs,FALSE,FALSE);
3439 stripCommentsStateRef = oldStripCommentsState;
3441 ol.popGeneratorState();
3446 //----------------------------------------------------------------------------
3448 * write groups as hierarchical trees
3450 static void writeGroupTreeNode(OutputList &ol, GroupDef *gd, int level, FTVHelp* ftv, bool addToIndex)
3452 //bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
3453 //bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
3456 warn(gd->getDefFileName(),gd->getDefLine(),
3457 "warning: maximum nesting level exceeded for group %s: check for possible recursive group relation!\n",gd->name().data()
3462 /* Some groups should appear twice under different parent-groups.
3463 * That is why we should not check if it was visited
3465 if (/*!gd->visited &&*/ (!gd->isASubGroup() || level>0) &&
3467 (!gd->isReference() || Config_getBool("EXTERNAL_GROUPS")) // hide external groups by default
3470 //printf("gd->name()=%s #members=%d\n",gd->name().data(),gd->countMembers());
3472 bool hasSubGroups = gd->getSubGroups()->count()>0;
3473 bool hasSubPages = gd->getPages()->count()>0;
3474 int numSubItems = 0;
3475 if (1 /*Config_getBool("TOC_EXPAND")*/)
3477 QListIterator<MemberList> mli(gd->getMemberLists());
3479 for (mli.toFirst();(ml=mli.current());++mli)
3481 if (ml->listType()&MemberList::documentationLists)
3483 numSubItems += ml->count();
3486 numSubItems += gd->getNamespaces()->count();
3487 numSubItems += gd->getClasses()->count();
3488 numSubItems += gd->getFiles()->count();
3489 numSubItems += gd->getDirs()->count();
3490 numSubItems += gd->getPages()->count();
3493 bool isDir = hasSubGroups || hasSubPages || numSubItems>0;
3494 //printf("gd=`%s': pageDict=%d\n",gd->name().data(),gd->pageDict->count());
3497 Doxygen::indexList.addContentsItem(isDir,gd->groupTitle(),gd->getReference(),gd->getOutputFileBase(),0,isDir,TRUE);
3498 Doxygen::indexList.incContentsDepth();
3502 ftv->addContentsItem(hasSubGroups,gd->groupTitle(),
3503 gd->getReference(),gd->getOutputFileBase(),0,
3505 ftv->incContentsDepth();
3508 //ol.writeListItem();
3509 //ol.startTextLink(gd->getOutputFileBase(),0);
3510 //parseText(ol,gd->groupTitle());
3513 ol.startIndexListItem();
3514 ol.startIndexItem(gd->getReference(),gd->getOutputFileBase());
3515 ol.parseText(gd->groupTitle());
3516 ol.endIndexItem(gd->getReference(),gd->getOutputFileBase());
3517 if (gd->isReference())
3519 ol.startTypewriter();
3520 ol.docify(" [external]");
3524 QListIterator<LayoutDocEntry> eli(LayoutDocManager::instance().docEntries(LayoutDocManager::Group));
3525 LayoutDocEntry *lde;
3526 for (eli.toFirst();(lde=eli.current());++eli)
3528 if (lde->kind()==LayoutDocEntry::MemberDef && addToIndex)
3530 LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde;
3531 MemberList *ml = gd->getMemberList(lmd->type);
3534 MemberListIterator mi(*ml);
3536 for (mi.toFirst();(md=mi.current());++mi)
3538 LockingPtr<MemberList> enumList = md->enumFieldList();
3539 bool isDir = enumList!=0 && md->isEnumerate();
3540 if (md->isVisible() && md->name().find('@')==-1)
3542 Doxygen::indexList.addContentsItem(isDir,
3543 md->name(),md->getReference(),
3544 md->getOutputFileBase(),md->anchor(),FALSE,addToIndex);
3548 Doxygen::indexList.incContentsDepth();
3549 MemberListIterator emli(*enumList);
3551 for (emli.toFirst();(emd=emli.current());++emli)
3553 if (emd->isVisible())
3555 Doxygen::indexList.addContentsItem(FALSE,
3556 emd->name(),emd->getReference(),emd->getOutputFileBase(),
3557 emd->anchor(),FALSE,addToIndex);
3560 Doxygen::indexList.decContentsDepth();
3565 else if (lde->kind()==LayoutDocEntry::GroupClasses && addToIndex)
3567 ClassSDict::Iterator it(*gd->getClasses());
3569 for (;(cd=it.current());++it)
3571 //bool nestedClassInSameGroup =
3572 // cd->getOuterScope() && cd->getOuterScope()->definitionType()==Definition::TypeClass &&
3573 // cd->getOuterScope()->partOfGroups()!=0 && cd->getOuterScope()->partOfGroups()->contains(gd);
3574 //printf("===== GroupClasses: %s visible=%d nestedClassInSameGroup=%d\n",cd->name().data(),cd->isVisible(),nestedClassInSameGroup);
3575 if (cd->isVisible() /*&& !nestedClassInSameGroup*/)
3577 //if (cd->isEmbeddedInOuterScope())
3579 //printf("add class & members %d\n",addToIndex);
3580 addMembersToIndex(cd,LayoutDocManager::Class,cd->displayName(FALSE),cd->anchor(),addToIndex,TRUE);
3582 //else // only index the class, not its members
3584 // printf("%s: add class only\n",cd->name().data());
3585 // Doxygen::indexList.addContentsItem(FALSE,
3586 // cd->displayName(TRUE),cd->getReference(),
3587 // cd->getOutputFileBase(),cd->anchor(),addToIndex,TRUE);
3592 else if (lde->kind()==LayoutDocEntry::GroupNamespaces && addToIndex)
3594 NamespaceSDict::Iterator it(*gd->getNamespaces());
3596 for (;(nd=it.current());++it)
3598 if (nd->isVisible())
3600 Doxygen::indexList.addContentsItem(FALSE,
3601 nd->localName(),nd->getReference(),
3602 nd->getOutputFileBase(),0,FALSE,FALSE);
3606 else if (lde->kind()==LayoutDocEntry::GroupFiles && addToIndex)
3608 QListIterator<FileDef> it(*gd->getFiles());
3610 for (;(fd=it.current());++it)
3612 if (fd->isVisible())
3614 Doxygen::indexList.addContentsItem(FALSE,
3615 fd->displayName(),fd->getReference(),
3616 fd->getOutputFileBase(),0,FALSE,FALSE);
3620 else if (lde->kind()==LayoutDocEntry::GroupDirs && addToIndex)
3622 QListIterator<DirDef> it(*gd->getDirs());
3624 for (;(dd=it.current());++it)
3626 if (dd->isVisible())
3628 Doxygen::indexList.addContentsItem(FALSE,
3629 dd->shortName(),dd->getReference(),
3630 dd->getOutputFileBase(),0,FALSE,FALSE);
3634 else if (lde->kind()==LayoutDocEntry::GroupPageDocs && addToIndex)
3636 SDict<PageDef>::Iterator it(*gd->getPages());
3638 for (;(pd=it.current());++it)
3641 if (!pd->name().isEmpty()) si=Doxygen::sectionDict[pd->name()];
3642 bool hasSubPages = pd->hasSubPages();
3643 bool hasSections = pd->hasSections();
3644 Doxygen::indexList.addContentsItem(
3645 hasSubPages || hasSections,
3646 convertToHtml(pd->title(),TRUE),
3648 gd->getOutputFileBase(),
3649 si ? si->label.data() : 0,
3650 hasSubPages || hasSections,
3651 TRUE); // addToNavIndex
3652 if (hasSections || hasSubPages)
3654 Doxygen::indexList.incContentsDepth();
3658 pd->addSectionsToIndex();
3661 if (hasSections || hasSubPages)
3663 Doxygen::indexList.decContentsDepth();
3667 else if (lde->kind()==LayoutDocEntry::GroupNestedGroups)
3669 if (gd->getSubGroups()->count()>0)
3671 startIndexHierarchy(ol,level+1);
3672 if (Config_getBool("SORT_GROUP_NAMES")) gd->sortSubGroups();
3673 QListIterator<GroupDef> gli(*gd->getSubGroups());
3674 GroupDef *subgd = 0;
3675 for (gli.toFirst();(subgd=gli.current());++gli)
3677 writeGroupTreeNode(ol,subgd,level+1,ftv,addToIndex);
3679 endIndexHierarchy(ol,level+1);
3684 ol.endIndexListItem();
3688 Doxygen::indexList.decContentsDepth();
3692 ftv->decContentsDepth();
3698 static void writeGroupHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex)
3702 ol.pushGeneratorState();
3703 ol.disable(OutputGenerator::Html);
3705 startIndexHierarchy(ol,0);
3706 if (Config_getBool("SORT_GROUP_NAMES"))
3708 Doxygen::groupSDict->sort();
3710 GroupSDict::Iterator gli(*Doxygen::groupSDict);
3712 for (gli.toFirst();(gd=gli.current());++gli)
3714 writeGroupTreeNode(ol,gd,0,ftv,addToIndex);
3716 endIndexHierarchy(ol,0);
3719 ol.popGeneratorState();
3724 static void writeGroupTree(GroupDef *gd,FTVHelp *ftv,int level,bool addToIndex)
3726 static bool externalGroups = Config_getBool("EXTERNAL_GROUPS");
3727 /* Some groups should appear twice under different parent-groups.
3728 * That is why we should not check if it was visited
3730 if ((!gd->isASubGroup() || level>0) &&
3732 (!gd->isReference() || externalGroups) // hide external groups by default
3737 ftv->addContentsItem(hasSubGroups,gd->groupTitle(),gd->getReference(),gd->getOutputFileBase(),0);
3738 ftv->incContentsDepth();
3742 ftv->decContentsDepth();
3747 static void writeGroupTree(FTVHelp *ftv,bool addToIndex)
3749 GroupSDict::Iterator gli(*Doxygen::groupSDict);
3751 for (gli.toFirst();(gd=gli.current());++gli)
3753 writeGroupTree(gd,ftv,0,addToIndex);
3758 //----------------------------------------------------------------------------
3760 static void writeGroupIndex(OutputList &ol)
3762 if (documentedGroups==0) return;
3763 ol.pushGeneratorState();
3765 ol.disable(OutputGenerator::Man);
3766 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Modules);
3767 QCString title = lne ? lne->title() : theTranslator->trModules();
3768 bool addToIndex = lne==0 || lne->visible();
3770 startFile(ol,"modules",0,title,HLI_Modules);
3772 ol.parseText(title);
3775 ol.startTextBlock();
3776 ol.parseText(lne ? lne->intro() : theTranslator->trModulesDescription());
3780 // Normal group index for Latex/RTF
3783 ol.pushGeneratorState();
3784 ol.disable(OutputGenerator::Html);
3785 Doxygen::indexList.disable();
3787 writeGroupHierarchy(ol,0,FALSE);
3789 Doxygen::indexList.enable();
3790 ol.popGeneratorState();
3794 // interactive group index for HTML
3797 ol.pushGeneratorState();
3798 ol.disableAllBut(OutputGenerator::Html);
3803 Doxygen::indexList.addContentsItem(TRUE,title,0,"modules",0,TRUE,TRUE);
3804 Doxygen::indexList.incContentsDepth();
3806 FTVHelp* ftv = new FTVHelp(FALSE);
3807 writeGroupHierarchy(ol,ftv,addToIndex);
3809 FTextStream t(&outStr);
3810 ftv->generateTreeViewInline(t);
3811 ol.disableAllBut(OutputGenerator::Html);
3812 ol.writeString(outStr);
3816 Doxygen::indexList.decContentsDepth();
3819 ol.popGeneratorState();
3823 ol.popGeneratorState();
3827 //----------------------------------------------------------------------------
3830 static void writeDirIndex(OutputList &ol)
3832 if (documentedDirs==0) return;
3833 ol.pushGeneratorState();
3834 ol.disable(OutputGenerator::Man);
3835 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Dirs);
3836 QCString title = lne ? lne->title() : theTranslator->trDirectories();
3837 bool addToIndex=FALSE; //lne==0 || lne->visible();
3839 startFile(ol,"dirs",0,title,HLI_Directories);
3841 ol.parseText(title);
3844 ol.startTextBlock();
3848 Doxygen::indexList.addContentsItem(TRUE,title,0,"dirs",0,TRUE,TRUE);
3849 Doxygen::indexList.incContentsDepth();
3851 ol.parseText(lne ? lne->intro() : theTranslator->trDirDescription());
3855 bool treeView=Config_getBool("USE_INLINE_TREES");
3858 ftv = new FTVHelp(FALSE);
3861 writeDirHierarchy(ol,ftv,addToIndex);
3866 FTextStream t(&outStr);
3867 ftv->generateTreeViewInline(t);
3868 ol.pushGeneratorState();
3869 ol.disableAllBut(OutputGenerator::Html);
3870 ol.writeString(outStr);
3871 ol.popGeneratorState();
3876 Doxygen::indexList.decContentsDepth();
3879 ol.popGeneratorState();
3883 //----------------------------------------------------------------------------
3885 static void writeUserGroupStubPage(OutputList &ol,LayoutNavEntry *lne)
3887 ol.pushGeneratorState();
3888 ol.disableAllBut(OutputGenerator::Html);
3889 startFile(ol,lne->baseFile(),0,lne->title(),HLI_UserGroup);
3891 ol.parseText(lne->title());
3893 QListIterator<LayoutNavEntry> li(lne->children());
3894 LayoutNavEntry *entry;
3896 for (li.toFirst();(entry=li.current());++li)
3898 if (entry->visible()) count++;
3902 ol.writeString("<ul>\n");
3903 for (li.toFirst();(entry=li.current());++li)
3905 if (entry->visible())
3907 ol.writeString("<li><a href=\""+entry->url()+"\"><span>"+
3908 fixSpaces(entry->title())+"</span></a></li>\n");
3911 ol.writeString("</ul>\n");
3914 ol.popGeneratorState();
3917 //----------------------------------------------------------------------------
3919 static bool mainPageHasTitle()
3921 if (Doxygen::mainPage==0) return FALSE;
3922 if (Doxygen::mainPage->title().isEmpty()) return FALSE;
3923 if (Doxygen::mainPage->title().lower()=="notitle") return FALSE;
3927 //----------------------------------------------------------------------------
3929 static void writeIndex(OutputList &ol)
3931 static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
3932 static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
3933 // save old generator state
3934 ol.pushGeneratorState();
3936 QCString projPrefix;
3937 if (!Config_getString("PROJECT_NAME").isEmpty())
3939 projPrefix=Config_getString("PROJECT_NAME")+" ";
3942 //--------------------------------------------------------------------
3944 //--------------------------------------------------------------------
3945 ol.disableAllBut(OutputGenerator::Html);
3947 QCString defFileName =
3948 Doxygen::mainPage ? Doxygen::mainPage->docFile().data() : "[generated]";
3950 Doxygen::mainPage ? Doxygen::mainPage->docLine() : -1;
3953 if (!mainPageHasTitle())
3955 title = theTranslator->trMainPage();
3959 title = filterTitle(Doxygen::mainPage->title());
3962 QCString indexName="index";
3963 ol.startFile(indexName,0,title);
3965 if (Doxygen::mainPage)
3967 if (/*Doxygen::mainPage->hasSubPages() || */
3968 (!Config_getString("PROJECT_NAME").isEmpty() && mainPageHasTitle())
3969 ) // to avoid duplicate entries in the treeview
3971 Doxygen::indexList.addContentsItem(Doxygen::mainPage->hasSubPages(),title,0,indexName,0,Doxygen::mainPage->hasSubPages(),TRUE);
3973 if (Doxygen::mainPage->hasSubPages())
3975 writePages(Doxygen::mainPage,0);
3979 ol.startQuickIndices();
3980 if (!Config_getBool("DISABLE_INDEX"))
3982 ol.writeQuickLinks(TRUE,HLI_Main,0);
3984 ol.endQuickIndices();
3985 ol.writeSplitBar(indexName);
3986 ol.writeSearchInfo();
3987 bool headerWritten=FALSE;
3988 if (Doxygen::mainPage && !Doxygen::mainPage->title().isEmpty())
3990 if (Doxygen::mainPage->title().lower()!="notitle")
3992 ol.startHeaderSection();
3993 ol.startTitleHead(0);
3994 ol.parseDoc(Doxygen::mainPage->docFile(),Doxygen::mainPage->docLine(),
3995 Doxygen::mainPage,0,Doxygen::mainPage->title(),
3996 TRUE,FALSE,0,TRUE,FALSE);
3997 headerWritten = TRUE;
4002 if (!Config_getString("PROJECT_NAME").isEmpty())
4004 ol.startHeaderSection();
4005 ol.startTitleHead(0);
4006 ol.parseText(projPrefix+theTranslator->trDocumentation());
4007 headerWritten = TRUE;
4012 ol.endTitleHead(0,0);
4013 ol.endHeaderSection();
4017 if (Config_getBool("DISABLE_INDEX") && Doxygen::mainPage==0)
4019 ol.writeQuickLinks(FALSE,HLI_Main,0);
4022 if (Doxygen::mainPage)
4024 Doxygen::insideMainPage=TRUE;
4025 if (Doxygen::mainPage->showToc() && Doxygen::mainPage->hasSections())
4027 Doxygen::mainPage->writeToc(ol);
4030 ol.startTextBlock();
4031 ol.parseDoc(defFileName,defLine,Doxygen::mainPage,0,
4032 Doxygen::mainPage->documentation(),TRUE,FALSE
4033 /*,Doxygen::mainPage->sectionDict*/);
4036 Doxygen::insideMainPage=FALSE;
4040 ol.disable(OutputGenerator::Html);
4042 //--------------------------------------------------------------------
4043 // write LaTeX/RTF index
4044 //--------------------------------------------------------------------
4045 ol.enable(OutputGenerator::Latex);
4046 ol.enable(OutputGenerator::RTF);
4048 ol.startFile("refman",0,0);
4049 ol.startIndexSection(isTitlePageStart);
4050 if (!Config_getString("LATEX_HEADER").isEmpty())
4052 ol.disable(OutputGenerator::Latex);
4055 if (projPrefix.isEmpty())
4057 ol.parseText(theTranslator->trReferenceManual());
4061 ol.parseText(projPrefix);
4064 if (!Config_getString("PROJECT_NUMBER").isEmpty())
4066 ol.startProjectNumber();
4067 ol.parseDoc(defFileName,defLine,Doxygen::mainPage,0,Config_getString("PROJECT_NUMBER"),FALSE,FALSE);
4068 ol.endProjectNumber();
4070 ol.endIndexSection(isTitlePageStart);
4071 ol.startIndexSection(isTitlePageAuthor);
4072 ol.parseText(theTranslator->trGeneratedBy());
4073 ol.endIndexSection(isTitlePageAuthor);
4074 ol.enable(OutputGenerator::Latex);
4077 if (Doxygen::mainPage)
4079 ol.startIndexSection(isMainPage);
4080 if (mainPageHasTitle())
4082 ol.parseText(Doxygen::mainPage->title());
4086 ol.parseText(/*projPrefix+*/theTranslator->trMainPage());
4088 ol.endIndexSection(isMainPage);
4090 if (documentedPages>0)
4092 //ol.parseText(projPrefix+theTranslator->trPageDocumentation());
4093 //ol.endIndexSection(isPageDocumentation);
4094 PageSDict::Iterator pdi(*Doxygen::pageSDict);
4095 PageDef *pd=pdi.toFirst();
4096 bool first=Doxygen::mainPage==0;
4097 for (pdi.toFirst();(pd=pdi.current());++pdi)
4099 if (!pd->getGroupDef() && !pd->isReference() &&
4100 (!pd->hasParentPage() || // not inside other page
4101 (Doxygen::mainPage==pd->getOuterScope())) // or inside main page
4104 bool isCitationPage = pd->name()=="citelist";
4107 // For LaTeX the bibliograph is already written by \bibliography
4108 ol.pushGeneratorState();
4109 ol.disable(OutputGenerator::Latex);
4111 QCString title = pd->title();
4112 if (title.isEmpty()) title=pd->name();
4113 ol.startIndexSection(isPageDocumentation);
4114 ol.parseText(title);
4115 ol.endIndexSection(isPageDocumentation);
4116 ol.pushGeneratorState(); // write TOC title (RTF only)
4117 ol.disableAllBut(OutputGenerator::RTF);
4118 ol.startIndexSection(isPageDocumentation2);
4119 ol.parseText(title);
4120 ol.endIndexSection(isPageDocumentation2);
4121 ol.popGeneratorState();
4122 ol.writeAnchor(0,pd->name());
4124 ol.writePageLink(pd->getOutputFileBase(),first);
4129 ol.popGeneratorState();
4135 if (!Config_getBool("LATEX_HIDE_INDICES"))
4137 //if (indexedPages>0)
4139 // ol.startIndexSection(isPageIndex);
4140 // ol.parseText(/*projPrefix+*/ theTranslator->trPageIndex());
4141 // ol.endIndexSection(isPageIndex);
4143 if (documentedGroups>0)
4145 ol.startIndexSection(isModuleIndex);
4146 ol.parseText(/*projPrefix+*/ theTranslator->trModuleIndex());
4147 ol.endIndexSection(isModuleIndex);
4149 if (documentedNamespaces>0)
4151 ol.startIndexSection(isNamespaceIndex);
4152 ol.parseText(/*projPrefix+*/(fortranOpt?theTranslator->trModulesIndex():theTranslator->trNamespaceIndex()));
4153 ol.endIndexSection(isNamespaceIndex);
4155 if (hierarchyClasses>0)
4157 ol.startIndexSection(isClassHierarchyIndex);
4158 ol.parseText(/*projPrefix+*/
4159 (fortranOpt ? theTranslator->trCompoundIndexFortran() :
4160 vhdlOpt ? VhdlDocGen::trDesignUnitIndex() :
4161 theTranslator->trHierarchicalIndex()
4163 ol.endIndexSection(isClassHierarchyIndex);
4165 if (annotatedClassesPrinted>0)
4167 ol.startIndexSection(isCompoundIndex);
4168 ol.parseText(/*projPrefix+*/
4169 (fortranOpt ? theTranslator->trCompoundIndexFortran() :
4170 vhdlOpt ? VhdlDocGen::trDesignUnitIndex() :
4171 theTranslator->trCompoundIndex()
4173 ol.endIndexSection(isCompoundIndex);
4175 if (documentedFiles>0)
4177 ol.startIndexSection(isFileIndex);
4178 ol.parseText(/*projPrefix+*/theTranslator->trFileIndex());
4179 ol.endIndexSection(isFileIndex);
4182 if (documentedGroups>0)
4184 ol.startIndexSection(isModuleDocumentation);
4185 ol.parseText(/*projPrefix+*/theTranslator->trModuleDocumentation());
4186 ol.endIndexSection(isModuleDocumentation);
4188 if (documentedNamespaces>0)
4190 ol.startIndexSection(isNamespaceDocumentation);
4191 ol.parseText(/*projPrefix+*/(fortranOpt?theTranslator->trModuleDocumentation():theTranslator->trNamespaceDocumentation()));
4192 ol.endIndexSection(isNamespaceDocumentation);
4194 if (annotatedClassesPrinted>0)
4196 ol.startIndexSection(isClassDocumentation);
4197 ol.parseText(/*projPrefix+*/(fortranOpt?theTranslator->trTypeDocumentation():theTranslator->trClassDocumentation()));
4198 ol.endIndexSection(isClassDocumentation);
4200 if (documentedFiles>0)
4202 ol.startIndexSection(isFileDocumentation);
4203 ol.parseText(/*projPrefix+*/theTranslator->trFileDocumentation());
4204 ol.endIndexSection(isFileDocumentation);
4206 if (Doxygen::exampleSDict->count()>0)
4208 ol.startIndexSection(isExampleDocumentation);
4209 ol.parseText(/*projPrefix+*/theTranslator->trExampleDocumentation());
4210 ol.endIndexSection(isExampleDocumentation);
4212 ol.endIndexSection(isEndIndex);
4215 if (Doxygen::mainPage)
4217 Doxygen::insideMainPage=TRUE;
4218 ol.disable(OutputGenerator::Man);
4219 startFile(ol,Doxygen::mainPage->name(),0,Doxygen::mainPage->title());
4221 ol.startTextBlock();
4222 ol.parseDoc(defFileName,defLine,Doxygen::mainPage,0,
4223 Doxygen::mainPage->documentation(),FALSE,FALSE
4227 ol.enable(OutputGenerator::Man);
4228 Doxygen::insideMainPage=FALSE;
4231 ol.popGeneratorState();
4234 static QArray<bool> indexWritten;
4236 static void writeIndexHierarchyEntries(OutputList &ol,const QList<LayoutNavEntry> &entries)
4238 QListIterator<LayoutNavEntry> li(entries);
4239 LayoutNavEntry *lne;
4240 for (li.toFirst();(lne=li.current());++li)
4242 LayoutNavEntry::Kind kind = lne->kind();
4243 uint index = (uint)kind;
4244 if (index>=indexWritten.size())
4247 uint oldSize = indexWritten.size();
4248 uint newSize = index+1;
4249 indexWritten.resize(newSize);
4250 for (i=oldSize;i<newSize;i++) indexWritten.at(i)=FALSE;
4252 //printf("starting %s kind=%d\n",lne->title().data(),lne->kind());
4253 bool addToIndex=lne==0 || lne->visible();
4254 bool needsClosing=FALSE;
4255 if (!indexWritten.at(index))
4259 case LayoutNavEntry::MainPage:
4260 msg("Generating index page...\n");
4263 case LayoutNavEntry::Pages:
4264 msg("Generating page index...\n");
4267 case LayoutNavEntry::Modules:
4268 msg("Generating module index...\n");
4269 writeGroupIndex(ol);
4271 case LayoutNavEntry::Namespaces:
4273 static bool showNamespaces = Config_getBool("SHOW_NAMESPACES");
4276 if (documentedNamespaces>0 && addToIndex)
4278 Doxygen::indexList.addContentsItem(TRUE,lne->title(),0,0,0);
4279 Doxygen::indexList.incContentsDepth();
4282 if (LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Namespaces)!=lne) // for backward compatibility with old layout file
4284 msg("Generating namespace index...\n");
4285 writeNamespaceIndex(ol);
4290 case LayoutNavEntry::NamespaceList:
4292 static bool showNamespaces = Config_getBool("SHOW_NAMESPACES");
4295 msg("Generating namespace index...\n");
4296 writeNamespaceIndex(ol);
4300 case LayoutNavEntry::NamespaceMembers:
4301 msg("Generating namespace member index...\n");
4302 writeNamespaceMemberIndex(ol);
4304 case LayoutNavEntry::Classes:
4305 if (annotatedClasses>0 && addToIndex)
4307 Doxygen::indexList.addContentsItem(TRUE,lne->title(),0,0,0);
4308 Doxygen::indexList.incContentsDepth();
4311 if (LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Classes)!=lne) // for backward compatibility with old layout file
4313 msg("Generating annotated compound index...\n");
4314 writeAnnotatedIndex(ol);
4317 case LayoutNavEntry::ClassList:
4318 msg("Generating annotated compound index...\n");
4319 writeAnnotatedIndex(ol);
4321 case LayoutNavEntry::ClassIndex:
4322 msg("Generating alphabetical compound index...\n");
4323 writeAlphabeticalIndex(ol);
4325 case LayoutNavEntry::ClassHierarchy:
4326 msg("Generating hierarchical class index...\n");
4327 writeHierarchicalIndex(ol);
4328 if (Config_getBool("HAVE_DOT") && Config_getBool("GRAPHICAL_HIERARCHY"))
4330 msg("Generating graphical class hierarchy...\n");
4331 writeGraphicalClassHierarchy(ol);
4334 case LayoutNavEntry::ClassMembers:
4335 msg("Generating member index...\n");
4336 writeClassMemberIndex(ol);
4338 case LayoutNavEntry::Files:
4340 static bool showFiles = Config_getBool("SHOW_FILES");
4343 if (documentedHtmlFiles>0 && addToIndex)
4345 Doxygen::indexList.addContentsItem(TRUE,lne->title(),0,0,0);
4346 Doxygen::indexList.incContentsDepth();
4349 if (LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Files)!=lne) // for backward compatibility with old layout file
4351 msg("Generating file index...\n");
4357 case LayoutNavEntry::FileList:
4359 static bool showFiles = Config_getBool("SHOW_FILES");
4362 msg("Generating file index...\n");
4367 case LayoutNavEntry::FileGlobals:
4368 msg("Generating file member index...\n");
4369 writeFileMemberIndex(ol);
4371 case LayoutNavEntry::Examples:
4372 msg("Generating example index...\n");
4373 writeExampleIndex(ol);
4375 case LayoutNavEntry::User:
4377 // prepend a ! or ^ marker to the URL to avoid tampering with it
4378 QCString url = correctURL(lne->url(),"!"); // add ! to relative URL
4379 if (!url.isEmpty() && url.at(0)!='!') // absolute URL
4381 url.prepend("^"); // prepend ^ to absolute URL
4383 bool isRef = lne->baseFile().left(4)=="@ref" || lne->baseFile().left(4)=="\\ref";
4384 Doxygen::indexList.addContentsItem(TRUE,lne->title(),0,url,0,FALSE,isRef);
4387 case LayoutNavEntry::UserGroup:
4390 Doxygen::indexList.addContentsItem(TRUE,lne->title(),0,lne->baseFile(),0,TRUE,TRUE);
4391 Doxygen::indexList.incContentsDepth();
4394 writeUserGroupStubPage(ol,lne);
4397 if (kind!=LayoutNavEntry::User && kind!=LayoutNavEntry::UserGroup) // User entry may appear multiple times
4399 indexWritten.at(index)=TRUE;
4402 writeIndexHierarchyEntries(ol,lne->children());
4407 case LayoutNavEntry::Namespaces:
4408 case LayoutNavEntry::Classes:
4409 case LayoutNavEntry::Files:
4410 case LayoutNavEntry::UserGroup:
4411 Doxygen::indexList.decContentsDepth();
4417 //printf("ending %s kind=%d\n",lne->title().data(),lne->kind());
4421 void writeIndexHierarchy(OutputList &ol)
4423 LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry();
4426 writeIndexHierarchyEntries(ol,lne->children());