/****************************************************************************** * * * * Copyright (C) 1997-2015 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its * documentation under the terms of the GNU General Public License is hereby * granted. No representations are made about the suitability of this software * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * * Documents produced by Doxygen are derivative works derived from the * input used in their production; they are not affected by this license. * */ /** @file * @brief This file contains functions for the various index pages. */ #include #include #include #include #include #include "message.h" #include "index.h" #include "doxygen.h" #include "config.h" #include "filedef.h" #include "outputlist.h" #include "util.h" #include "groupdef.h" #include "language.h" #include "htmlgen.h" #include "htmlhelp.h" #include "ftvhelp.h" #include "dot.h" #include "pagedef.h" #include "dirdef.h" #include "vhdldocgen.h" #include "layout.h" #include "memberlist.h" #include "classlist.h" #include "namespacedef.h" #include "filename.h" #define MAX_ITEMS_BEFORE_MULTIPAGE_INDEX 200 #define MAX_ITEMS_BEFORE_QUICK_INDEX 30 int annotatedClasses; int annotatedClassesPrinted; int hierarchyClasses; int documentedFiles; int documentedGroups; int documentedNamespaces; int indexedPages; int documentedClassMembers[CMHL_Total]; int documentedFileMembers[FMHL_Total]; int documentedNamespaceMembers[NMHL_Total]; int documentedHtmlFiles; int documentedPages; int documentedDirs; static int countClassHierarchy(); static void countFiles(int &htmlFiles,int &files); static int countGroups(); static int countDirs(); static int countNamespaces(); static int countAnnotatedClasses(int *cp); static void countRelatedPages(int &docPages,int &indexPages); void countDataStructures() { annotatedClasses = countAnnotatedClasses(&annotatedClassesPrinted); // "classes" + "annotated" hierarchyClasses = countClassHierarchy(); // "hierarchy" countFiles(documentedHtmlFiles,documentedFiles); // "files" countRelatedPages(documentedPages,indexedPages); // "pages" documentedGroups = countGroups(); // "modules" documentedNamespaces = countNamespaces(); // "namespaces" documentedDirs = countDirs(); // "dirs" // "globals" // "namespacemembers" // "functions" } static void startIndexHierarchy(OutputList &ol,int level) { ol.pushGeneratorState(); ol.disable(OutputGenerator::Man); ol.disable(OutputGenerator::Html); if (level<6) ol.startIndexList(); ol.enableAll(); ol.disable(OutputGenerator::Latex); ol.disable(OutputGenerator::RTF); ol.startItemList(); ol.popGeneratorState(); } static void endIndexHierarchy(OutputList &ol,int level) { ol.pushGeneratorState(); ol.disable(OutputGenerator::Man); ol.disable(OutputGenerator::Html); if (level<6) ol.endIndexList(); ol.enableAll(); ol.disable(OutputGenerator::Latex); ol.disable(OutputGenerator::RTF); ol.endItemList(); ol.popGeneratorState(); } //---------------------------------------------------------------------------- class MemberIndexList : public QList { public: typedef MemberDef ElementType; MemberIndexList(uint letter) : QList(), m_letter(letter) {} ~MemberIndexList() {} int compareValues(const MemberDef *md1, const MemberDef *md2) const { int result = qstricmp(md1->name(),md2->name()); if (result==0) { result = qstricmp(md1->qualifiedName(),md2->qualifiedName()); } return result; } uint letter() const { return m_letter; } private: uint m_letter; }; static LetterToIndexMap g_memberIndexLetterUsed[CMHL_Total]; static LetterToIndexMap g_fileIndexLetterUsed[FMHL_Total]; static LetterToIndexMap g_namespaceIndexLetterUsed[NMHL_Total]; const int maxItemsBeforeQuickIndex = MAX_ITEMS_BEFORE_QUICK_INDEX; //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- static void startQuickIndexList(OutputList &ol,bool letterTabs=FALSE) { bool fancyTabs = TRUE; if (fancyTabs) { if (letterTabs) { ol.writeString("
\n"); } else { ol.writeString("
\n"); } ol.writeString("
    \n"); } else { ol.writeString("
    "); } } static void endQuickIndexList(OutputList &ol) { bool fancyTabs = TRUE; if (fancyTabs) { ol.writeString("
\n"); } ol.writeString("
\n"); } static void startQuickIndexItem(OutputList &ol,const char *l, bool hl,bool compact,bool &first) { bool fancyTabs = TRUE; if (!first && compact && !fancyTabs) ol.writeString(" | "); first=FALSE; if (fancyTabs) { ol.writeString(" "); if (hl && compact) { ol.writeString(""); if (fancyTabs) { ol.writeString(""); } } static void endQuickIndexItem(OutputList &ol) { bool fancyTabs=TRUE; if (fancyTabs) ol.writeString(""); ol.writeString(""); if (fancyTabs) ol.writeString("\n"); } // don't make this static as it is called from a template function and some // old compilers don't support calls to static functions from a template. QCString fixSpaces(const QCString &s) { return substitute(s," "," "); } void startTitle(OutputList &ol,const char *fileName,Definition *def) { ol.startHeaderSection(); if (def) def->writeSummaryLinks(ol); ol.startTitleHead(fileName); ol.pushGeneratorState(); ol.disable(OutputGenerator::Man); } void endTitle(OutputList &ol,const char *fileName,const char *name) { ol.popGeneratorState(); ol.endTitleHead(fileName,name); ol.endHeaderSection(); } void startFile(OutputList &ol,const char *name,const char *manName, const char *title,HighlightedItem hli,bool additionalIndices, const char *altSidebarName) { static bool disableIndex = Config_getBool(DISABLE_INDEX); ol.startFile(name,manName,title); ol.startQuickIndices(); if (!disableIndex) { ol.writeQuickLinks(TRUE,hli,name); } if (!additionalIndices) { ol.endQuickIndices(); } ol.writeSplitBar(altSidebarName ? altSidebarName : name); ol.writeSearchInfo(); resetDotNodeNumbering(); } void endFile(OutputList &ol,bool skipNavIndex,bool skipEndContents, const QCString &navPath) { static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); if (!skipNavIndex) { if (!skipEndContents) ol.endContents(); if (generateTreeView) { ol.writeString("
\n"); } } ol.writeFooter(navPath); // write the footer ol.popGeneratorState(); ol.endFile(); } void endFileWithNavPath(Definition *d,OutputList &ol) { static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW); QCString navPath; if (generateTreeView) { ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); ol.writeString("\n"); ol.popGeneratorState(); navPath = d->navigationPathAsString(); } endFile(ol,generateTreeView,TRUE,navPath); } //---------------------------------------------------------------------- template void addMembersToIndex(T *def,LayoutDocManager::LayoutPart part, const QCString &name,const QCString &anchor, bool addToIndex=TRUE,bool preventSeparateIndex=FALSE) { bool hasMembers = def->getMemberLists().count()>0 || def->getMemberGroupSDict()!=0; Doxygen::indexList->addContentsItem(hasMembers,name, def->getReference(),def->getOutputFileBase(),anchor, hasMembers && !preventSeparateIndex, addToIndex, def); int numClasses=0; ClassSDict *classes = def->getClassSDict(); if (classes) { ClassDef *cd; ClassSDict::Iterator it(*classes); for (;(cd=it.current());++it) { if (cd->isLinkable()) numClasses++; } } //printf("addMembersToIndex(def=%s hasMembers=%d numClasses=%d)\n",def->name().data(),hasMembers,numClasses); if (hasMembers || numClasses>0) { Doxygen::indexList->incContentsDepth(); QListIterator eli(LayoutDocManager::instance().docEntries(part)); LayoutDocEntry *lde; for (eli.toFirst();(lde=eli.current());++eli) { if (lde->kind()==LayoutDocEntry::MemberDef) { LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde; MemberList *ml = def->getMemberList(lmd->type); if (ml) { MemberListIterator mi(*ml); MemberDef *md; for (mi.toFirst();(md=mi.current());++mi) { MemberList *enumList = md->enumFieldList(); bool isDir = enumList!=0 && md->isEnumerate(); bool isAnonymous = md->name().find('@')!=-1; static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS); static bool extractStatic = Config_getBool(EXTRACT_STATIC); if (!isAnonymous && (!hideUndocMembers || md->hasDocumentation()) && (!md->isStatic() || extractStatic) ) { if (md->getOuterScope()==def || md->getOuterScope()==Doxygen::globalScope) { Doxygen::indexList->addContentsItem(isDir, md->name(),md->getReference(),md->getOutputFileBase(),md->anchor(),FALSE,addToIndex); } else // inherited member { Doxygen::indexList->addContentsItem(isDir, md->name(),def->getReference(),def->getOutputFileBase(),md->anchor(),FALSE,addToIndex); } } if (isDir) { if (!isAnonymous) { Doxygen::indexList->incContentsDepth(); } MemberListIterator emli(*enumList); MemberDef *emd; for (emli.toFirst();(emd=emli.current());++emli) { if (!hideUndocMembers || emd->hasDocumentation()) { if (emd->getOuterScope()==def || emd->getOuterScope()==Doxygen::globalScope) { Doxygen::indexList->addContentsItem(FALSE, emd->name(),emd->getReference(),emd->getOutputFileBase(),emd->anchor(),FALSE,addToIndex); } else // inherited member { Doxygen::indexList->addContentsItem(FALSE, emd->name(),def->getReference(),def->getOutputFileBase(),emd->anchor(),FALSE,addToIndex); } } } if (!isAnonymous) { Doxygen::indexList->decContentsDepth(); } } } } } else if (lde->kind()==LayoutDocEntry::NamespaceClasses || lde->kind()==LayoutDocEntry::FileClasses || lde->kind()==LayoutDocEntry::ClassNestedClasses ) { if (classes) { ClassDef *cd; ClassSDict::Iterator it(*classes); for (;(cd=it.current());++it) { if (cd->isLinkable() && (cd->partOfGroups()==0 || def->definitionType()==Definition::TypeGroup)) { static bool inlineSimpleStructs = Config_getBool(INLINE_SIMPLE_STRUCTS); bool isNestedClass = def->definitionType()==Definition::TypeClass; addMembersToIndex(cd,LayoutDocManager::Class,cd->displayName(FALSE),cd->anchor(), addToIndex && (isNestedClass || (cd->isSimple() && inlineSimpleStructs)), preventSeparateIndex || cd->isEmbeddedInOuterScope()); } } } } } Doxygen::indexList->decContentsDepth(); } } //---------------------------------------------------------------------------- /*! Generates HTML Help tree of classes */ static void writeClassTree(OutputList &ol,const BaseClassList *bcl,bool hideSuper,int level,FTVHelp* ftv,bool addToIndex) { if (bcl==0) return; BaseClassListIterator bcli(*bcl); bool started=FALSE; for ( ; bcli.current() ; ++bcli) { ClassDef *cd=bcli.current()->classDef; if (cd->getLanguage()==SrcLangExt_VHDL && (VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS) { continue; } bool b; if (cd->getLanguage()==SrcLangExt_VHDL) { b=hasVisibleRoot(cd->subClasses()); } else { b=hasVisibleRoot(cd->baseClasses()); } if (cd->isVisibleInHierarchy() && b) // hasVisibleRoot(cd->baseClasses())) { if (!started) { startIndexHierarchy(ol,level); if (addToIndex) { Doxygen::indexList->incContentsDepth(); } if (ftv) { ftv->incContentsDepth(); } started=TRUE; } ol.startIndexListItem(); //printf("Passed...\n"); bool hasChildren = !cd->visited && !hideSuper && classHasVisibleChildren(cd); //printf("tree4: Has children %s: %d\n",cd->name().data(),hasChildren); if (cd->isLinkable()) { //printf("Writing class %s\n",cd->displayName().data()); ol.startIndexItem(cd->getReference(),cd->getOutputFileBase()); ol.parseText(cd->displayName()); ol.endIndexItem(cd->getReference(),cd->getOutputFileBase()); if (cd->isReference()) { ol.startTypewriter(); ol.docify(" [external]"); ol.endTypewriter(); } if (addToIndex) { Doxygen::indexList->addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor()); } if (ftv) { if (cd->getLanguage()==SrcLangExt_VHDL) { ftv->addContentsItem(hasChildren,bcli.current()->usedName,cd->getReference(),cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE,cd); } else { ftv->addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE,cd); } } } else { ol.startIndexItem(0,0); ol.parseText(cd->name()); ol.endIndexItem(0,0); if (addToIndex) { Doxygen::indexList->addContentsItem(hasChildren,cd->displayName(),0,0,0); } if (ftv) { ftv->addContentsItem(hasChildren,cd->displayName(),0,0,0,FALSE,FALSE,cd); } } if (hasChildren) { //printf("Class %s at %p visited=%d\n",cd->name().data(),cd,cd->visited); bool wasVisited=cd->visited; cd->visited=TRUE; if (cd->getLanguage()==SrcLangExt_VHDL) { writeClassTree(ol,cd->baseClasses(),wasVisited,level+1,ftv,addToIndex); } else { writeClassTree(ol,cd->subClasses(),wasVisited,level+1,ftv,addToIndex); } } ol.endIndexListItem(); } } if (started) { endIndexHierarchy(ol,level); if (addToIndex) { Doxygen::indexList->decContentsDepth(); } if (ftv) { ftv->decContentsDepth(); } } } //---------------------------------------------------------------------------- static bool dirHasVisibleChildren(DirDef *dd) { if (dd->hasDocumentation()) return TRUE; QListIterator fli(*dd->getFiles()); FileDef *fd; for (fli.toFirst();(fd=fli.current());++fli) { bool genSourceFile; if (fileVisibleInIndex(fd,genSourceFile)) { return TRUE; } if (genSourceFile) { return TRUE; } } QListIterator dli(dd->subDirs()); DirDef *subdd; for (dli.toFirst();(subdd=dli.current());++dli) { if (dirHasVisibleChildren(subdd)) { return TRUE; } } return FALSE; } //---------------------------------------------------------------------------- static void writeDirTreeNode(OutputList &ol, DirDef *dd, int level, FTVHelp* ftv,bool addToIndex) { if (level>20) { warn(dd->getDefFileName(),dd->getDefLine(), "maximum nesting level exceeded for directory %s: " "check for possible recursive directory relation!\n",dd->name().data() ); return; } if (!dirHasVisibleChildren(dd)) { return; } static bool tocExpand = TRUE; //Config_getBool(TOC_EXPAND); bool isDir = dd->subDirs().count()>0 || // there are subdirs (tocExpand && // or toc expand and dd->getFiles() && dd->getFiles()->count()>0 // there are files ); //printf("gd=`%s': pageDict=%d\n",gd->name().data(),gd->pageDict->count()); if (addToIndex) { Doxygen::indexList->addContentsItem(isDir,dd->shortName(),dd->getReference(),dd->getOutputFileBase(),0,TRUE,TRUE); Doxygen::indexList->incContentsDepth(); } if (ftv) { ftv->addContentsItem(isDir,dd->shortName(),dd->getReference(), dd->getOutputFileBase(),0,FALSE,TRUE,dd); ftv->incContentsDepth(); } ol.startIndexListItem(); ol.startIndexItem(dd->getReference(),dd->getOutputFileBase()); ol.parseText(dd->shortName()); ol.endIndexItem(dd->getReference(),dd->getOutputFileBase()); if (dd->isReference()) { ol.startTypewriter(); ol.docify(" [external]"); ol.endTypewriter(); } // write sub directories if (dd->subDirs().count()>0) { startIndexHierarchy(ol,level+1); QListIterator dli(dd->subDirs()); DirDef *subdd = 0; for (dli.toFirst();(subdd=dli.current());++dli) { writeDirTreeNode(ol,subdd,level+1,ftv,addToIndex); } endIndexHierarchy(ol,level+1); } FileList *fileList=dd->getFiles(); int fileCount=0; if (fileList && fileList->count()>0) { QListIterator it(*fileList); FileDef *fd; for (;(fd=it.current());++it) { //static bool allExternals = Config_getBool(ALLEXTERNALS); //if ((allExternals && fd->isLinkable()) || fd->isLinkableInProject()) //{ // fileCount++; //} bool genSourceFile; if (fileVisibleInIndex(fd,genSourceFile)) { fileCount++; } else if (genSourceFile) { fileCount++; } } if (fileCount>0) { startIndexHierarchy(ol,level+1); for (it.toFirst();(fd=it.current());++it) { bool doc,src; doc = fileVisibleInIndex(fd,src); QCString reference; QCString outputBase; if (doc) { reference = fd->getReference(); outputBase = fd->getOutputFileBase(); } if (doc || src) { ol.startIndexListItem(); ol.startIndexItem(reference,outputBase); ol.parseText(fd->displayName()); ol.endIndexItem(reference,outputBase); ol.endIndexListItem(); if (ftv && (src || doc)) { ftv->addContentsItem(FALSE, fd->displayName(), reference,outputBase, 0,FALSE,FALSE,fd); } } } endIndexHierarchy(ol,level+1); } } if (tocExpand && addToIndex) { // write files of this directory if (fileCount>0) { QListIterator it(*fileList); FileDef *fd; for (;(fd=it.current());++it) { //static bool allExternals = Config_getBool(ALLEXTERNALS); //if ((allExternals && fd->isLinkable()) || fd->isLinkableInProject()) bool doc,src; doc = fileVisibleInIndex(fd,src); if (doc) { addMembersToIndex(fd,LayoutDocManager::File,fd->displayName(),QCString(),TRUE); } else if (src) { Doxygen::indexList->addContentsItem( FALSE, convertToHtml(fd->name(),TRUE), 0, fd->getSourceFileBase(), 0, FALSE, TRUE, fd); } } } } ol.endIndexListItem(); if (addToIndex) { Doxygen::indexList->decContentsDepth(); } if (ftv) { ftv->decContentsDepth(); } } static void writeDirHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex) { if (ftv) { ol.pushGeneratorState(); ol.disable(OutputGenerator::Html); } static bool fullPathNames = Config_getBool(FULL_PATH_NAMES); startIndexHierarchy(ol,0); if (fullPathNames) { SDict::Iterator dli(*Doxygen::directories); DirDef *dd; for (dli.toFirst();(dd=dli.current());++dli) { if (dd->getOuterScope()==Doxygen::globalScope) { writeDirTreeNode(ol,dd,0,ftv,addToIndex); } } } if (ftv) { FileNameListIterator fnli(*Doxygen::inputNameList); FileName *fn; for (fnli.toFirst();(fn=fnli.current());++fnli) { FileNameIterator fni(*fn); FileDef *fd; for (;(fd=fni.current());++fni) { static bool fullPathNames = Config_getBool(FULL_PATH_NAMES); if (!fullPathNames || fd->getDirDef()==0) // top level file { bool doc,src; doc = fileVisibleInIndex(fd,src); QCString reference, outputBase; if (doc) { reference = fd->getReference(); outputBase = fd->getOutputFileBase(); } if (doc || src) { ftv->addContentsItem(FALSE,fd->displayName(), reference, outputBase, 0, FALSE,FALSE,fd); } if (addToIndex) { if (doc) { addMembersToIndex(fd,LayoutDocManager::File,fd->displayName(),QCString(),TRUE); } else if (src) { Doxygen::indexList->addContentsItem( FALSE, convertToHtml(fd->name(),TRUE), 0, fd->getSourceFileBase(), 0, FALSE, TRUE, fd); } } } } } } endIndexHierarchy(ol,0); if (ftv) { ol.popGeneratorState(); } } //---------------------------------------------------------------------------- static void writeClassTreeForList(OutputList &ol,ClassSDict *cl,bool &started,FTVHelp* ftv,bool addToIndex) { ClassSDict::Iterator cli(*cl); ClassDef *cd; for (;(cd=cli.current());++cli) { //printf("class %s hasVisibleRoot=%d isVisibleInHierarchy=%d\n", // cd->name().data(), // hasVisibleRoot(cd->baseClasses()), // cd->isVisibleInHierarchy() // ); bool b; if (cd->getLanguage()==SrcLangExt_VHDL) { if ((VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS) { continue; } b=!hasVisibleRoot(cd->subClasses()); } else { b=!hasVisibleRoot(cd->baseClasses()); } if (b) //filter on root classes { if (cd->isVisibleInHierarchy()) // should it be visible { if (!started) { startIndexHierarchy(ol,0); if (addToIndex) { Doxygen::indexList->incContentsDepth(); } started=TRUE; } ol.startIndexListItem(); bool hasChildren = !cd->visited && classHasVisibleChildren(cd); //printf("list: Has children %s: %d\n",cd->name().data(),hasChildren); if (cd->isLinkable()) { //printf("Writing class %s isLinkable()=%d isLinkableInProject()=%d cd->templateMaster()=%p\n", // cd->displayName().data(),cd->isLinkable(),cd->isLinkableInProject(),cd->templateMaster()); ol.startIndexItem(cd->getReference(),cd->getOutputFileBase()); ol.parseText(cd->displayName()); ol.endIndexItem(cd->getReference(),cd->getOutputFileBase()); if (cd->isReference()) { ol.startTypewriter(); ol.docify(" [external]"); ol.endTypewriter(); } if (addToIndex) { if (cd->getLanguage()!=SrcLangExt_VHDL) // prevents double insertion in Design Unit List Doxygen::indexList->addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE); } if (ftv) { ftv->addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE,cd); } } else { ol.startIndexItem(0,0); ol.parseText(cd->displayName()); ol.endIndexItem(0,0); if (addToIndex) { Doxygen::indexList->addContentsItem(hasChildren,cd->displayName(),0,0,0,FALSE,FALSE); } if (ftv) { ftv->addContentsItem(hasChildren,cd->displayName(),0,0,0,FALSE,FALSE,cd); } } if (cd->getLanguage()==SrcLangExt_VHDL && hasChildren) { writeClassTree(ol,cd->baseClasses(),cd->visited,1,ftv,addToIndex); cd->visited=TRUE; } else if (hasChildren) { writeClassTree(ol,cd->subClasses(),cd->visited,1,ftv,addToIndex); cd->visited=TRUE; } ol.endIndexListItem(); } } } } static void writeClassHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex) { initClassHierarchy(Doxygen::classSDict); initClassHierarchy(Doxygen::hiddenClasses); if (ftv) { ol.pushGeneratorState(); ol.disable(OutputGenerator::Html); } bool started=FALSE; writeClassTreeForList(ol,Doxygen::classSDict,started,ftv,addToIndex); writeClassTreeForList(ol,Doxygen::hiddenClasses,started,ftv,addToIndex); if (started) { endIndexHierarchy(ol,0); if (addToIndex) { Doxygen::indexList->decContentsDepth(); } } if (ftv) { ol.popGeneratorState(); } } //---------------------------------------------------------------------------- static int countClassesInTreeList(const ClassSDict &cl) { int count=0; ClassSDict::Iterator cli(cl); ClassDef *cd; for (;(cd=cli.current());++cli) { if (!hasVisibleRoot(cd->baseClasses())) // filter on root classes { if (cd->isVisibleInHierarchy()) // should it be visible { if (cd->subClasses()) // should have sub classes { count++; } } } } return count; } static int countClassHierarchy() { int count=0; initClassHierarchy(Doxygen::classSDict); initClassHierarchy(Doxygen::hiddenClasses); count+=countClassesInTreeList(*Doxygen::classSDict); count+=countClassesInTreeList(*Doxygen::hiddenClasses); return count; } //---------------------------------------------------------------------------- static void writeHierarchicalIndex(OutputList &ol) { if (hierarchyClasses==0) return; ol.pushGeneratorState(); //1.{ ol.disable(OutputGenerator::Man); LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassHierarchy); QCString title = lne ? lne->title() : theTranslator->trClassHierarchy(); bool addToIndex = lne==0 || lne->visible(); startFile(ol,"hierarchy",0, title, HLI_Hierarchy); startTitle(ol,0); ol.parseText(title); endTitle(ol,0,0); ol.startContents(); ol.startTextBlock(); if (Config_getBool(HAVE_DOT) && Config_getBool(GRAPHICAL_HIERARCHY)) { ol.disable(OutputGenerator::Latex); ol.disable(OutputGenerator::RTF); ol.startParagraph(); ol.startTextLink("inherits",0); ol.parseText(theTranslator->trGotoGraphicalHierarchy()); ol.endTextLink(); ol.endParagraph(); ol.enable(OutputGenerator::Latex); ol.enable(OutputGenerator::RTF); } ol.parseText(lne ? lne->intro() : theTranslator->trClassHierarchyDescription()); ol.endTextBlock(); // --------------- // Static class hierarchy for Latex/RTF // --------------- ol.pushGeneratorState(); //2.{ ol.disable(OutputGenerator::Html); Doxygen::indexList->disable(); writeClassHierarchy(ol,0,addToIndex); Doxygen::indexList->enable(); ol.popGeneratorState(); //2.} // --------------- // Dynamic class hierarchical index for HTML // --------------- ol.pushGeneratorState(); //2.{ ol.disableAllBut(OutputGenerator::Html); { if (addToIndex) { Doxygen::indexList->addContentsItem(TRUE,title,0,"hierarchy",0,TRUE,TRUE); } FTVHelp* ftv = new FTVHelp(FALSE); writeClassHierarchy(ol,ftv,addToIndex); QGString outStr; FTextStream t(&outStr); ftv->generateTreeViewInline(t); ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); ol.writeString(outStr); ol.popGeneratorState(); delete ftv; } ol.popGeneratorState(); //2.} // ------ endFile(ol); ol.popGeneratorState(); //1.} } //---------------------------------------------------------------------------- static void writeGraphicalClassHierarchy(OutputList &ol) { if (hierarchyClasses==0) return; ol.disableAllBut(OutputGenerator::Html); LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassHierarchy); QCString title = lne ? lne->title() : theTranslator->trClassHierarchy(); startFile(ol,"inherits",0,title,HLI_Hierarchy,FALSE,"hierarchy"); startTitle(ol,0); ol.parseText(title); endTitle(ol,0,0); ol.startContents(); ol.startTextBlock(); ol.startParagraph(); ol.startTextLink("hierarchy",0); ol.parseText(theTranslator->trGotoTextualHierarchy()); ol.endTextLink(); ol.endParagraph(); ol.endTextBlock(); DotGfxHierarchyTable g; ol.writeGraphicalHierarchy(g); endFile(ol); ol.enableAll(); } //---------------------------------------------------------------------------- static void countFiles(int &htmlFiles,int &files) { htmlFiles=0; files=0; FileNameListIterator fnli(*Doxygen::inputNameList); FileName *fn; for (;(fn=fnli.current());++fnli) { FileNameIterator fni(*fn); FileDef *fd; for (;(fd=fni.current());++fni) { bool doc,src; doc = fileVisibleInIndex(fd,src); if (doc || src) { htmlFiles++; } if (doc) { files++; } } } } static void writeSingleFileIndex(OutputList &ol,FileDef *fd) { //printf("Found filedef %s\n",fd->name().data()); bool doc = fd->isLinkableInProject(); bool src = fd->generateSourceFile(); bool nameOk = !fd->isDocumentationFile(); if (nameOk && (doc || src) && !fd->isReference()) { QCString path; if (Config_getBool(FULL_PATH_NAMES)) { path=stripFromPath(fd->getPath().copy()); } QCString fullName=fd->name(); if (!path.isEmpty()) { if (path.at(path.length()-1)!='/') fullName.prepend("/"); fullName.prepend(path); } ol.startIndexKey(); ol.docify(path); if (doc) { ol.writeObjectLink(0,fd->getOutputFileBase(),0,fd->name()); //if (addToIndex) //{ // addMembersToIndex(fd,LayoutDocManager::File,fullName,QCString()); //} } else { ol.startBold(); ol.docify(fd->name()); ol.endBold(); //if (addToIndex) //{ // Doxygen::indexList->addContentsItem(FALSE,fullName,0,0,0); //} } if (src) { ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); ol.docify(" "); ol.startTextLink(fd->includeName(),0); ol.docify("["); ol.parseText(theTranslator->trCode()); ol.docify("]"); ol.endTextLink(); ol.popGeneratorState(); } ol.endIndexKey(); bool hasBrief = !fd->briefDescription().isEmpty(); ol.startIndexValue(hasBrief); if (hasBrief) { //ol.docify(" ("); ol.generateDoc( fd->briefFile(),fd->briefLine(), fd,0, fd->briefDescription(TRUE), FALSE, // index words FALSE, // isExample 0, // example name TRUE, // single line TRUE // link from index ); //ol.docify(")"); } ol.endIndexValue(fd->getOutputFileBase(),hasBrief); //ol.popGeneratorState(); // -------------------------------------------------------- } } //---------------------------------------------------------------------------- static void writeFileIndex(OutputList &ol) { if (documentedHtmlFiles==0) return; ol.pushGeneratorState(); ol.disable(OutputGenerator::Man); if (documentedFiles==0) ol.disableAllBut(OutputGenerator::Html); LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::FileList); if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Files); // fall back QCString title = lne ? lne->title() : theTranslator->trFileList(); bool addToIndex = lne==0 || lne->visible(); startFile(ol,"files",0,title,HLI_Files); startTitle(ol,0); //if (!Config_getString(PROJECT_NAME).isEmpty()) //{ // title.prepend(Config_getString(PROJECT_NAME)+" "); //} ol.parseText(title); endTitle(ol,0,0); ol.startContents(); ol.startTextBlock(); if (addToIndex) { Doxygen::indexList->addContentsItem(TRUE,title,0,"files",0,TRUE,TRUE); Doxygen::indexList->incContentsDepth(); } ol.parseText(lne ? lne->intro() : theTranslator->trFileListDescription(Config_getBool(EXTRACT_ALL))); ol.endTextBlock(); // --------------- // Flat file index // --------------- // 1. { ol.pushGeneratorState(); ol.disable(OutputGenerator::Html); OutputNameDict outputNameDict(1009); OutputNameList outputNameList; outputNameList.setAutoDelete(TRUE); if (Config_getBool(FULL_PATH_NAMES)) { // re-sort input files in (dir,file) output order instead of (file,dir) input order FileNameListIterator fnli(*Doxygen::inputNameList); FileName *fn; for (fnli.toFirst();(fn=fnli.current());++fnli) { FileNameIterator fni(*fn); FileDef *fd; for (;(fd=fni.current());++fni) { QCString path=fd->getPath(); if (path.isEmpty()) path="[external]"; FileList *fl = outputNameDict.find(path); if (fl) { fl->append(fd); //printf("+ inserting %s---%s\n",fd->getPath().data(),fd->name().data()); } else { //printf("o inserting %s---%s\n",fd->getPath().data(),fd->name().data()); fl = new FileList(path); fl->append(fd); outputNameList.append(fl); outputNameDict.insert(path,fl); } } } } ol.startIndexList(); if (Config_getBool(FULL_PATH_NAMES)) { outputNameList.sort(); QListIterator fnli(outputNameList); FileList *fl; for (fnli.toFirst();(fl=fnli.current());++fnli) { fl->sort(); QListIterator it(*fl); FileDef *fd; for (;(fd=it.current());++it) { writeSingleFileIndex(ol,fd); } } } else { FileNameListIterator fnli(*Doxygen::inputNameList); FileName *fn; for (fnli.toFirst();(fn=fnli.current());++fnli) { FileNameIterator fni(*fn); FileDef *fd; for (;(fd=fni.current());++fni) { writeSingleFileIndex(ol,fd); } } } ol.endIndexList(); // 1. } ol.popGeneratorState(); // --------------- // Hierarchical file index for HTML // --------------- ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); FTVHelp* ftv = new FTVHelp(FALSE); writeDirHierarchy(ol,ftv,addToIndex); QGString outStr; FTextStream t(&outStr); ftv->generateTreeViewInline(t); ol.writeString(outStr); delete ftv; ol.popGeneratorState(); // ------ if (addToIndex) { Doxygen::indexList->decContentsDepth(); } endFile(ol); ol.popGeneratorState(); } //---------------------------------------------------------------------------- static int countNamespaces() { int count=0; NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); NamespaceDef *nd; for (;(nd=nli.current());++nli) { if (nd->isLinkableInProject()) count++; } return count; } //---------------------------------------------------------------------------- void writeClassTree(ClassSDict *clDict,FTVHelp *ftv,bool addToIndex,bool globalOnly) { if (clDict) { ClassSDict::Iterator cli(*clDict); ClassDef *cd; for (;(cd=cli.current());++cli) { if (cd->getLanguage()==SrcLangExt_VHDL) { if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKAGECLASS || (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS )// no architecture { continue; } if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ARCHITECTURECLASS) { QCString n=cd->name(); cd->setClassName(n.data()); } } if (!globalOnly || cd->getOuterScope()==0 || cd->getOuterScope()==Doxygen::globalScope ) { int count=0; if (cd->getClassSDict()) { ClassSDict::Iterator ccit(*cd->getClassSDict()); ClassDef *ccd; for (;(ccd=ccit.current());++ccit) { if (ccd->isLinkableInProject() && ccd->templateMaster()==0) { count++; } } } if (classVisibleInIndex(cd) && cd->templateMaster()==0) { ftv->addContentsItem(count>0,cd->displayName(FALSE),cd->getReference(), cd->getOutputFileBase(),cd->anchor(),FALSE,TRUE,cd); if (addToIndex && /*cd->partOfGroups()==0 &&*/ (cd->getOuterScope()==0 || cd->getOuterScope()->definitionType()!=Definition::TypeClass ) ) { addMembersToIndex(cd,LayoutDocManager::Class, cd->displayName(FALSE), cd->anchor(), cd->partOfGroups()==0 && !cd->isSimple()); } if (count>0) { ftv->incContentsDepth(); writeClassTree(cd->getClassSDict(),ftv,addToIndex,FALSE); ftv->decContentsDepth(); } } } } } } static void writeNamespaceTree(NamespaceSDict *nsDict,FTVHelp *ftv, bool rootOnly,bool showClasses,bool addToIndex) { if (nsDict) { NamespaceSDict::Iterator nli(*nsDict); NamespaceDef *nd; for (nli.toFirst();(nd=nli.current());++nli) { if (nd->localName().find('@')==-1 && (!rootOnly || nd->getOuterScope()==Doxygen::globalScope)) { bool hasChildren = namespaceHasVisibleChild(nd,showClasses); bool isLinkable = nd->isLinkableInProject(); QCString ref; QCString file; if (isLinkable) { ref = nd->getReference(); file = nd->getOutputFileBase(); if (nd->getLanguage()==SrcLangExt_VHDL) // UGLY HACK { file=file.replace(0,qstrlen("namespace"),"class"); } } if ((isLinkable && !showClasses) || hasChildren) { ftv->addContentsItem(hasChildren,nd->localName(),ref,file,0,FALSE,TRUE,nd); if (addToIndex) { Doxygen::indexList->addContentsItem(hasChildren,nd->localName(),ref,file,QCString(), hasChildren && !file.isEmpty(),addToIndex); } //printf("*** writeNamespaceTree count=%d addToIndex=%d showClasses=%d classCount=%d\n", // count,addToIndex,showClasses,classCount); if (hasChildren) { if (addToIndex) Doxygen::indexList->incContentsDepth(); ftv->incContentsDepth(); writeNamespaceTree(nd->getNamespaceSDict(),ftv,FALSE,showClasses,addToIndex); if (showClasses) { writeClassTree(nd->getClassSDict(),ftv,addToIndex,FALSE); } ftv->decContentsDepth(); if (addToIndex) Doxygen::indexList->decContentsDepth(); } } } } } } static void writeNamespaceIndex(OutputList &ol) { if (documentedNamespaces==0) return; ol.pushGeneratorState(); ol.disable(OutputGenerator::Man); LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::NamespaceList); if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Namespaces); // fall back QCString title = lne ? lne->title() : theTranslator->trNamespaceList(); bool addToIndex = lne==0 || lne->visible(); startFile(ol,"namespaces",0,title,HLI_Namespaces); startTitle(ol,0); ol.parseText(title); endTitle(ol,0,0); ol.startContents(); ol.startTextBlock(); ol.parseText(lne ? lne->intro() : theTranslator->trNamespaceListDescription(Config_getBool(EXTRACT_ALL))); ol.endTextBlock(); bool first=TRUE; // --------------- // Linear namespace index for Latex/RTF // --------------- ol.pushGeneratorState(); ol.disable(OutputGenerator::Html); NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict); NamespaceDef *nd; for (nli.toFirst();(nd=nli.current());++nli) { if (nd->isLinkableInProject()) { if (first) { ol.startIndexList(); first=FALSE; } //ol.writeStartAnnoItem("namespace",nd->getOutputFileBase(),0,nd->name()); ol.startIndexKey(); if (nd->getLanguage()==SrcLangExt_VHDL) { ol.writeObjectLink(0, nd->getOutputFileBase().replace(0,qstrlen("namespace"),"class"),0,nd->displayName()); } else { ol.writeObjectLink(0,nd->getOutputFileBase(),0,nd->displayName()); } ol.endIndexKey(); bool hasBrief = !nd->briefDescription().isEmpty(); ol.startIndexValue(hasBrief); if (hasBrief) { //ol.docify(" ("); ol.generateDoc( nd->briefFile(),nd->briefLine(), nd,0, nd->briefDescription(TRUE), FALSE, // index words FALSE, // isExample 0, // example name TRUE, // single line TRUE // link from index ); //ol.docify(")"); } ol.endIndexValue(nd->getOutputFileBase(),hasBrief); } } if (!first) ol.endIndexList(); ol.popGeneratorState(); // --------------- // Hierarchical namespace index for HTML // --------------- ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); { if (addToIndex) { Doxygen::indexList->addContentsItem(TRUE,title,0,"namespaces",0,TRUE,TRUE); Doxygen::indexList->incContentsDepth(); } FTVHelp* ftv = new FTVHelp(FALSE); writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,FALSE,addToIndex); QGString outStr; FTextStream t(&outStr); ftv->generateTreeViewInline(t); ol.writeString(outStr); delete ftv; if (addToIndex) { Doxygen::indexList->decContentsDepth(); } } ol.popGeneratorState(); // ------ endFile(ol); ol.popGeneratorState(); } //---------------------------------------------------------------------------- static int countAnnotatedClasses(int *cp) { int count=0; int countPrinted=0; ClassSDict::Iterator cli(*Doxygen::classSDict); ClassDef *cd; for (;(cd=cli.current());++cli) { if (cd->isLinkableInProject() && cd->templateMaster()==0) { if (!cd->isEmbeddedInOuterScope()) { countPrinted++; } count++; } } *cp = countPrinted; return count; } static void writeAnnotatedClassList(OutputList &ol) { //LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassList); //bool addToIndex = lne==0 || lne->visible(); ol.startIndexList(); ClassSDict::Iterator cli(*Doxygen::classSDict); ClassDef *cd; for (cli.toFirst();(cd=cli.current());++cli) { if (cd->getLanguage()==SrcLangExt_VHDL && ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKAGECLASS || (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS) ) // no architecture { continue; } ol.pushGeneratorState(); if (cd->isEmbeddedInOuterScope()) { ol.disable(OutputGenerator::Latex); ol.disable(OutputGenerator::RTF); } if (cd->isLinkableInProject() && cd->templateMaster()==0) { ol.startIndexKey(); if (cd->getLanguage()==SrcLangExt_VHDL) { QCString prot= VhdlDocGen::getProtectionName((VhdlDocGen::VhdlClasses)cd->protection()); ol.docify(prot.data()); ol.writeString(" "); } ol.writeObjectLink(0,cd->getOutputFileBase(),cd->anchor(),cd->displayName()); ol.endIndexKey(); bool hasBrief = !cd->briefDescription().isEmpty(); ol.startIndexValue(hasBrief); if (hasBrief) { ol.generateDoc( cd->briefFile(),cd->briefLine(), cd,0, cd->briefDescription(TRUE), FALSE, // indexWords FALSE, // isExample 0, // example name TRUE, // single line TRUE // link from index ); } ol.endIndexValue(cd->getOutputFileBase(),hasBrief); //if (addToIndex) //{ // addMembersToIndex(cd,LayoutDocManager::Class,cd->displayName(),cd->anchor()); //} } ol.popGeneratorState(); } ol.endIndexList(); } static QCString letterToLabel(uint startLetter) { char s[11]; // max 0x12345678 + '\0' if (isId(startLetter)) // printable ASCII character { s[0]=(char)startLetter; s[1]=0; } else { const char hex[]="0123456789abcdef"; int i=0; s[i++]='0'; s[i++]='x'; if (startLetter>(1<<24)) // 4 byte character { s[i++]=hex[(startLetter>>28)&0xf]; s[i++]=hex[(startLetter>>24)&0xf]; } if (startLetter>(1<<16)) // 3 byte character { s[i++]=hex[(startLetter>>20)&0xf]; s[i++]=hex[(startLetter>>16)&0xf]; } if (startLetter>(1<<8)) // 2 byte character { s[i++]=hex[(startLetter>>12)&0xf]; s[i++]=hex[(startLetter>>8)&0xf]; } // one byte character s[i++]=hex[(startLetter>>4)&0xf]; s[i++]=hex[(startLetter>>0)&0xf]; s[i++]=0; } return s; } //---------------------------------------------------------------------------- /** Special class list where sorting takes IGNORE_PREFIX into account. */ class PrefixIgnoreClassList : public ClassList { public: typedef ClassDef ElementType; PrefixIgnoreClassList(uint letter) : m_letter(letter) {} uint letter() const { return m_letter; } private: virtual int compareValue(const ClassDef *c1, const ClassDef *c2) const { QCString n1 = c1->className(); QCString n2 = c2->className(); return qstricmp (n1.data()+getPrefixIndex(n1), n2.data()+getPrefixIndex(n2)); } uint m_letter; }; /** Class representing a cell in the alphabetical class index. */ class AlphaIndexTableCell { public: AlphaIndexTableCell(int row,int col,uint letter,ClassDef *cd) : m_letter(letter), m_class(cd), m_row(row), m_col(col) { //printf("AlphaIndexTableCell(%d,%d,%c,%s)\n",row,col,letter!=0 ? letter: '-', // cd!=(ClassDef*)0x8 ? cd->name().data() : ""); } ClassDef *classDef() const { return m_class; } uint letter() const { return m_letter; } int row() const { return m_row; } int column() const { return m_col; } private: uint m_letter; ClassDef *m_class; int m_row; int m_col; }; /** Class representing a row in the alphabetical class index. */ class AlphaIndexTableRows : public QList { public: AlphaIndexTableRows() { setAutoDelete(TRUE); } }; /** Iterator for the cells in a row of the alphabetical class index. */ class AlphaIndexTableRowsIterator : public QListIterator { public: AlphaIndexTableRowsIterator(const AlphaIndexTableRows &list) : QListIterator(list) {} }; /** Class representing the columns in the alphabetical class index. */ class AlphaIndexTableColumns : public QList { public: AlphaIndexTableColumns() { setAutoDelete(TRUE); } }; class UsedIndexLetters : public SIntDict { public: UsedIndexLetters() : SIntDict(257) { setAutoDelete(TRUE); } void add(uint letter) { uint *v = find(letter); if (v==0) { append(letter,new uint(letter)); } } private: int compareValues( const uint *p1, const uint *p2) const { return (int)*p1 - (int)*p2; // subtracting is done by int not uint. } }; // write an alphabetical index of all class with a header for each letter static void writeAlphabeticalClassList(OutputList &ol) { // What starting letters are used UsedIndexLetters indexLettersUsed; // first count the number of headers ClassSDict::Iterator cli(*Doxygen::classSDict); ClassDef *cd; uint startLetter=0; int headerItems=0; for (;(cd=cli.current());++cli) { if (cd->isLinkableInProject() && cd->templateMaster()==0) { if (cd->getLanguage()==SrcLangExt_VHDL && !((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS ))// no architecture continue; int index = getPrefixIndex(cd->className()); //printf("name=%s index=%d %d\n",cd->className().data(),index,cd->protection()); startLetter=getUtf8CodeToLower(cd->className(),index); indexLettersUsed.add(startLetter); } } indexLettersUsed.sort(); // write quick link index (row of letters) QCString alphaLinks = "
"; SIntDict::Iterator it(indexLettersUsed); uint *pLetter; for (it.toFirst();(pLetter=it.current());++it) { if (headerItems) alphaLinks += " | "; headerItems++; QCString li = letterToLabel(*pLetter); QCString ls = QString(QChar(*pLetter)).utf8(); alphaLinks += (QCString)"" + ls + ""; } alphaLinks += "
\n"; ol.writeString(alphaLinks); // the number of columns in the table const int columns = Config_getInt(COLS_IN_ALPHA_INDEX); int i,j; int totalItems = headerItems*2 + annotatedClasses; // number of items in the table (headers span 2 items) int rows = (totalItems + columns - 1)/columns; // number of rows in the table //printf("headerItems=%d totalItems=%d columns=%d rows=%d itemsInLastRow=%d\n", // headerItems,totalItems,columns,rows,itemsInLastRow); // Keep a list of classes for each starting letter LetterToIndexMap classesByLetter; AlphaIndexTableColumns tableColumns; // fill the columns with the class list (row elements in each column, // expect for the columns with number >= itemsInLastRow, which get one // item less. //int icount=0; startLetter=0; for (cli.toFirst();(cd=cli.current());++cli) { if (cd->getLanguage()==SrcLangExt_VHDL && !((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS ))// no architecture continue; if (cd->isLinkableInProject() && cd->templateMaster()==0) { int index = getPrefixIndex(cd->className()); startLetter=getUtf8CodeToLower(cd->className(),index); // Do some sorting again, since the classes are sorted by name with // prefix, which should be ignored really. if (cd->getLanguage()==SrcLangExt_VHDL) { if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS )// no architecture { classesByLetter.append(startLetter,cd); } } else { classesByLetter.append(startLetter,cd); } } } #define NEXT_ROW() \ do \ { \ if (row>maxRows) maxRows=row; \ if (row>=rows && col::Iterator lit(classesByLetter); for (lit.toFirst();(cl=lit.current());++lit) { uint l = cl->letter(); // add special header cell tableRows->append(new AlphaIndexTableCell(row,col,l,(ClassDef*)0x8)); row++; tableRows->append(new AlphaIndexTableCell(row,col,0,(ClassDef*)0x8)); row++; ClassListIterator cit(*cl); cit.toFirst(); ClassDef *cd = cit.current(); ++cit; tableRows->append(new AlphaIndexTableCell(row,col,0,cd)); row++; NEXT_ROW(); for (;(cd=cit.current()); ++cit) { // add normal cell tableRows->append(new AlphaIndexTableCell(row,col,0,cd)); row++; NEXT_ROW(); } } // create row iterators for each column AlphaIndexTableRowsIterator **colIterators = new AlphaIndexTableRowsIterator*[columns]; for (i=0;i\n"); // generate table for (i=0;i<=maxRows;i++) // foreach table row { //printf("writing row %d\n",i); //ol.nextTableRow(); ol.writeString(""); // the last column may contain less items then the others //int colsInRow = (icurrent(); if (cell) { if (cell->row()==i) { if (cell->letter()!=0) { QCString s = letterToLabel(cell->letter()); ol.writeString(""); ol.writeString(""); ol.writeString("" "" "" "" "
  "); ol.writeString(QString(QChar(cell->letter())).utf8()); ol.writeString( "  
" "
\n"); } else if (cell->classDef()!=(ClassDef*)0x8) { cd = cell->classDef(); ol.writeString(""); QCString namesp,cname; //if (cd->getNamespaceDef()) namesp=cd->getNamespaceDef()->displayName(); //QCString cname=cd->className(); extractNamespaceName(cd->name(),cname,namesp); QCString nsDispName; SrcLangExt lang = cd->getLanguage(); QCString sep = getLanguageSpecificSeparator(lang); if (sep!="::") { nsDispName=substitute(namesp,"::",sep); cname=substitute(cname,"::",sep); } else { nsDispName=namesp; } ol.writeObjectLink(cd->getReference(), cd->getOutputFileBase(),cd->anchor(),cname); if (!namesp.isEmpty()) { ol.docify(" ("); NamespaceDef *nd = getResolvedNamespace(namesp); if (nd && nd->isLinkable()) { ol.writeObjectLink(nd->getReference(), nd->getOutputFileBase(),0,nsDispName); } else { ol.docify(nsDispName); } ol.docify(")"); } ol.writeNonBreakableSpace(3); } ++(*colIterators[j]); if (cell->letter()!=0 || cell->classDef()!=(ClassDef*)0x8) { ol.writeString(""); } } } else { ol.writeString(""); } } } ol.writeString("\n"); } ol.writeString("\n"); ol.writeString(alphaLinks); // release the temporary memory for (i=0;ifind(LayoutNavEntry::ClassIndex); QCString title = lne ? lne->title() : theTranslator->trCompoundIndex(); bool addToIndex = lne==0 || lne->visible(); startFile(ol,"classes",0,title,HLI_Classes); startTitle(ol,0); ol.parseText(title); endTitle(ol,0,0); if (addToIndex) { Doxygen::indexList->addContentsItem(FALSE,title,0,"classes",0,FALSE,TRUE); } ol.startContents(); writeAlphabeticalClassList(ol); endFile(ol); // contains ol.endContents() ol.popGeneratorState(); } //---------------------------------------------------------------------------- static void writeAnnotatedIndex(OutputList &ol) { //printf("writeAnnotatedIndex: count=%d printed=%d\n", // annotatedClasses,annotatedClassesPrinted); if (annotatedClasses==0) return; ol.pushGeneratorState(); ol.disable(OutputGenerator::Man); if (annotatedClassesPrinted==0) { ol.disable(OutputGenerator::Latex); ol.disable(OutputGenerator::RTF); } LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassList); if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Classes); // fall back QCString title = lne ? lne->title() : theTranslator->trCompoundList(); bool addToIndex = lne==0 || lne->visible(); startFile(ol,"annotated",0,title,HLI_Annotated); startTitle(ol,0); ol.parseText(title); endTitle(ol,0,0); ol.startContents(); ol.startTextBlock(); ol.parseText(lne ? lne->intro() : theTranslator->trCompoundListDescription()); ol.endTextBlock(); // --------------- // Linear class index for Latex/RTF // --------------- ol.pushGeneratorState(); ol.disable(OutputGenerator::Html); Doxygen::indexList->disable(); writeAnnotatedClassList(ol); Doxygen::indexList->enable(); ol.popGeneratorState(); // --------------- // Hierarchical class index for HTML // --------------- ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); { if (addToIndex) { Doxygen::indexList->addContentsItem(TRUE,title,0,"annotated",0,TRUE,TRUE); Doxygen::indexList->incContentsDepth(); } FTVHelp* ftv = new FTVHelp(FALSE); writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,TRUE,addToIndex); writeClassTree(Doxygen::classSDict,ftv,addToIndex,TRUE); QGString outStr; FTextStream t(&outStr); ftv->generateTreeViewInline(t); ol.writeString(outStr); delete ftv; if (addToIndex) { Doxygen::indexList->decContentsDepth(); } } ol.popGeneratorState(); // ------ endFile(ol); // contains ol.endContents() ol.popGeneratorState(); } //---------------------------------------------------------------------------- static void writeClassLinkForMember(OutputList &ol,MemberDef *md,const char *separator, QCString &prevClassName) { ClassDef *cd=md->getClassDef(); if ( cd && prevClassName!=cd->displayName()) { ol.docify(separator); ol.writeObjectLink(md->getReference(),md->getOutputFileBase(),md->anchor(), cd->displayName()); ol.writeString("\n"); prevClassName = cd->displayName(); } } static void writeFileLinkForMember(OutputList &ol,MemberDef *md,const char *separator, QCString &prevFileName) { FileDef *fd=md->getFileDef(); if (fd && prevFileName!=fd->name()) { ol.docify(separator); ol.writeObjectLink(md->getReference(),md->getOutputFileBase(),md->anchor(), fd->name()); ol.writeString("\n"); prevFileName = fd->name(); } } static void writeNamespaceLinkForMember(OutputList &ol,MemberDef *md,const char *separator, QCString &prevNamespaceName) { NamespaceDef *nd=md->getNamespaceDef(); if (nd && prevNamespaceName!=nd->displayName()) { ol.docify(separator); ol.writeObjectLink(md->getReference(),md->getOutputFileBase(),md->anchor(), nd->displayName()); ol.writeString("\n"); prevNamespaceName = nd->displayName(); } } static void writeMemberList(OutputList &ol,bool useSections,int page, const LetterToIndexMap &memberLists, DefinitionIntf::DefType type) { int index = (int)type; ASSERT(index<3); typedef void (*writeLinkForMember_t)(OutputList &ol,MemberDef *md,const char *separator, QCString &prevNamespaceName); // each index tab has its own write function static writeLinkForMember_t writeLinkForMemberMap[3] = { &writeClassLinkForMember, &writeFileLinkForMember, &writeNamespaceLinkForMember }; QCString prevName; QCString prevDefName; bool first=TRUE; bool firstSection=TRUE; bool firstItem=TRUE; MemberIndexList *ml; SIntDict::Iterator it(memberLists); for (it.toFirst();(ml=it.current());++it) { if (page!=-1) { ml = memberLists[page]; it.toLast(); } if (ml==0 || ml->count()==0) continue; ml->sort(); QListIterator mli(*ml); MemberDef *md; for (mli.toFirst();(md=mli.current());++mli) { const char *sep; bool isFunc=!md->isObjCMethod() && (md->isFunction() || md->isSlot() || md->isSignal()); QCString name=md->name(); int startIndex = getPrefixIndex(name); if (QCString(name.data()+startIndex)!=prevName) // new entry { if ((prevName.isEmpty() || tolower(name.at(startIndex))!=tolower(prevName.at(0))) && useSections) // new section { if (!firstItem) ol.endItemListItem(); if (!firstSection) ol.endItemList(); QCString cs = letterToLabel(ml->letter()); QCString cl = QString(QChar(ml->letter())).utf8(); QCString anchor=(QCString)"index_"+cs; QCString title=(QCString)"- "+cl+" -"; ol.startSection(anchor,title,SectionInfo::Subsection); ol.docify(title); ol.endSection(anchor,SectionInfo::Subsection); ol.startItemList(); firstSection=FALSE; firstItem=TRUE; } else if (!useSections && first) { ol.startItemList(); first=FALSE; } // member name if (!firstItem) ol.endItemListItem(); ol.startItemListItem(); firstItem=FALSE; ol.docify(name); if (isFunc) ol.docify("()"); ol.writeString("\n"); // link to class prevDefName=""; sep = ": "; prevName = name.data()+startIndex; } else // same entry { sep = ", "; // link to class for other members with the same name } if (index<3) { // write the link for the specific list type writeLinkForMemberMap[index](ol,md,sep,prevDefName); } } } if (!firstItem) ol.endItemListItem(); ol.endItemList(); } //---------------------------------------------------------------------------- void initClassMemberIndices() { int j=0; for (j=0;jisLinkableInProject() && (cd=md->getClassDef()) && cd->isLinkableInProject() && cd->templateMaster()==0) { QCString n = md->name(); int index = getPrefixIndex(n); uint letter = getUtf8CodeToLower(n,index); if (!n.isEmpty()) { bool isFriendToHide = hideFriendCompounds && (QCString(md->typeString())=="friend class" || QCString(md->typeString())=="friend struct" || QCString(md->typeString())=="friend union"); if (!(md->isFriend() && isFriendToHide) && (!md->isEnumValue() || (md->getEnumScope() && !md->getEnumScope()->isStrong())) ) { g_memberIndexLetterUsed[CMHL_All].append(letter,md); documentedClassMembers[CMHL_All]++; } if (md->isFunction() || md->isSlot() || md->isSignal()) { g_memberIndexLetterUsed[CMHL_Functions].append(letter,md); documentedClassMembers[CMHL_Functions]++; } else if (md->isVariable()) { g_memberIndexLetterUsed[CMHL_Variables].append(letter,md); documentedClassMembers[CMHL_Variables]++; } else if (md->isTypedef()) { g_memberIndexLetterUsed[CMHL_Typedefs].append(letter,md); documentedClassMembers[CMHL_Typedefs]++; } else if (md->isEnumerate()) { g_memberIndexLetterUsed[CMHL_Enums].append(letter,md); documentedClassMembers[CMHL_Enums]++; } else if (md->isEnumValue() && md->getEnumScope() && !md->getEnumScope()->isStrong()) { g_memberIndexLetterUsed[CMHL_EnumValues].append(letter,md); documentedClassMembers[CMHL_EnumValues]++; } else if (md->isProperty()) { g_memberIndexLetterUsed[CMHL_Properties].append(letter,md); documentedClassMembers[CMHL_Properties]++; } else if (md->isEvent()) { g_memberIndexLetterUsed[CMHL_Events].append(letter,md); documentedClassMembers[CMHL_Events]++; } else if (md->isRelated() || md->isForeign() || (md->isFriend() && !isFriendToHide)) { g_memberIndexLetterUsed[CMHL_Related].append(letter,md); documentedClassMembers[CMHL_Related]++; } } } } //---------------------------------------------------------------------------- void initNamespaceMemberIndices() { int j=0; for (j=0;jgetNamespaceDef(); if (nd && nd->isLinkableInProject() && md->isLinkableInProject()) { QCString n = md->name(); int index = getPrefixIndex(n); uint letter = getUtf8CodeToLower(n,index); if (!n.isEmpty()) { if (!md->isEnumValue() || (md->getEnumScope() && !md->getEnumScope()->isStrong())) { g_namespaceIndexLetterUsed[NMHL_All].append(letter,md); documentedNamespaceMembers[NMHL_All]++; } if (md->isFunction()) { g_namespaceIndexLetterUsed[NMHL_Functions].append(letter,md); documentedNamespaceMembers[NMHL_Functions]++; } else if (md->isVariable()) { g_namespaceIndexLetterUsed[NMHL_Variables].append(letter,md); documentedNamespaceMembers[NMHL_Variables]++; } else if (md->isTypedef()) { g_namespaceIndexLetterUsed[NMHL_Typedefs].append(letter,md); documentedNamespaceMembers[NMHL_Typedefs]++; } else if (md->isEnumerate()) { g_namespaceIndexLetterUsed[NMHL_Enums].append(letter,md); documentedNamespaceMembers[NMHL_Enums]++; } else if (md->isEnumValue() && md->getEnumScope() && !md->getEnumScope()->isStrong()) { g_namespaceIndexLetterUsed[NMHL_EnumValues].append(letter,md); documentedNamespaceMembers[NMHL_EnumValues]++; } } } } //---------------------------------------------------------------------------- void initFileMemberIndices() { int j=0; for (j=0;jgetFileDef(); if (fd && fd->isLinkableInProject() && md->isLinkableInProject()) { QCString n = md->name(); int index = getPrefixIndex(n); uint letter = getUtf8CodeToLower(n,index); if (!n.isEmpty()) { if (!md->isEnumValue() || (md->getEnumScope() && !md->getEnumScope()->isStrong())) { g_fileIndexLetterUsed[FMHL_All].append(letter,md); documentedFileMembers[FMHL_All]++; } if (md->isFunction()) { g_fileIndexLetterUsed[FMHL_Functions].append(letter,md); documentedFileMembers[FMHL_Functions]++; } else if (md->isVariable()) { g_fileIndexLetterUsed[FMHL_Variables].append(letter,md); documentedFileMembers[FMHL_Variables]++; } else if (md->isTypedef()) { g_fileIndexLetterUsed[FMHL_Typedefs].append(letter,md); documentedFileMembers[FMHL_Typedefs]++; } else if (md->isEnumerate()) { g_fileIndexLetterUsed[FMHL_Enums].append(letter,md); documentedFileMembers[FMHL_Enums]++; } else if (md->isEnumValue() && md->getEnumScope() && !md->getEnumScope()->isStrong()) { g_fileIndexLetterUsed[FMHL_EnumValues].append(letter,md); documentedFileMembers[FMHL_EnumValues]++; } else if (md->isDefine()) { g_fileIndexLetterUsed[FMHL_Defines].append(letter,md); documentedFileMembers[FMHL_Defines]++; } } } } //---------------------------------------------------------------------------- static void writeQuickMemberIndex(OutputList &ol, const LetterToIndexMap &charUsed,uint page, QCString fullName,bool multiPage) { bool first=TRUE; startQuickIndexList(ol,TRUE); SIntDict::Iterator it(charUsed); MemberIndexList *ml; for (it.toFirst();(ml=it.current());++it) { uint i = ml->letter(); QCString is = letterToLabel(i); QCString ci = QString(QChar(i)).utf8(); QCString anchor; QCString extension=Doxygen::htmlFileExtension; if (!multiPage) anchor="#index_"; else if (first) anchor=fullName+extension+"#index_"; else anchor=fullName+"_"+letterToLabel(i)+extension+"#index_"; startQuickIndexItem(ol,anchor+is,i==page,TRUE,first); ol.writeString(ci); endQuickIndexItem(ol); first=FALSE; } endQuickIndexList(ol); } //---------------------------------------------------------------------------- /** Helper class representing a class member in the navigation menu. */ struct CmhlInfo { CmhlInfo(const char *fn,const char *t) : fname(fn), title(t) {} const char *fname; QCString title; }; static const CmhlInfo *getCmhlInfo(int hl) { static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); static CmhlInfo cmhlInfo[] = { CmhlInfo("functions", theTranslator->trAll()), CmhlInfo("functions_func", fortranOpt ? theTranslator->trSubprograms() : vhdlOpt ? VhdlDocGen::trFunctionAndProc() : theTranslator->trFunctions()), CmhlInfo("functions_vars",theTranslator->trVariables()), CmhlInfo("functions_type",theTranslator->trTypedefs()), CmhlInfo("functions_enum",theTranslator->trEnumerations()), CmhlInfo("functions_eval",theTranslator->trEnumerationValues()), CmhlInfo("functions_prop",theTranslator->trProperties()), CmhlInfo("functions_evnt",theTranslator->trEvents()), CmhlInfo("functions_rela",theTranslator->trRelatedFunctions()) }; return &cmhlInfo[hl]; } static void writeClassMemberIndexFiltered(OutputList &ol, ClassMemberHighlight hl) { if (documentedClassMembers[hl]==0) return; static bool disableIndex = Config_getBool(DISABLE_INDEX); bool multiPageIndex=FALSE; if (documentedClassMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX) { multiPageIndex=TRUE; } ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); QCString extension=Doxygen::htmlFileExtension; LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassMembers); QCString title = lne ? lne->title() : theTranslator->trCompoundMembers(); if (hl!=CMHL_All) title+=(QCString)" - "+getCmhlInfo(hl)->title; bool addToIndex = lne==0 || lne->visible(); if (addToIndex) { Doxygen::indexList->addContentsItem(multiPageIndex,getCmhlInfo(hl)->title,0, getCmhlInfo(hl)->fname,0,multiPageIndex,TRUE); if (multiPageIndex) Doxygen::indexList->incContentsDepth(); } bool first=TRUE; SIntDict::Iterator it(g_memberIndexLetterUsed[hl]); MemberIndexList *ml; for (it.toFirst();(ml=it.current());++it) { uint page = ml->letter(); QCString fileName = getCmhlInfo(hl)->fname; if (multiPageIndex) { if (!first) { fileName+="_"+letterToLabel(page); } QCString cs = QString(QChar(page)).utf8(); if (addToIndex) { Doxygen::indexList->addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE); } } bool quickIndex = documentedClassMembers[hl]>maxItemsBeforeQuickIndex; ol.startFile(fileName+extension,0,title); ol.startQuickIndices(); if (!disableIndex) { ol.writeQuickLinks(TRUE,HLI_Functions,0); if (!Config_getBool(HTML_DYNAMIC_MENUS)) { startQuickIndexList(ol); // index item for global member list startQuickIndexItem(ol, getCmhlInfo(0)->fname+Doxygen::htmlFileExtension,hl==CMHL_All,TRUE,first); ol.writeString(fixSpaces(getCmhlInfo(0)->title)); endQuickIndexItem(ol); int i; // index items per category member lists for (i=1;i0) { startQuickIndexItem(ol,getCmhlInfo(i)->fname+Doxygen::htmlFileExtension,hl==i,TRUE,first); ol.writeString(fixSpaces(getCmhlInfo(i)->title)); //printf("multiPageIndex=%d first=%d fileName=%s file=%s title=%s\n", // multiPageIndex,first,fileName.data(),getCmhlInfo(i)->fname,getCmhlInfo(i)->title.data()); endQuickIndexItem(ol); } } endQuickIndexList(ol); // quick alphabetical index if (quickIndex) { writeQuickMemberIndex(ol,g_memberIndexLetterUsed[hl],page, getCmhlInfo(hl)->fname,multiPageIndex); } } } ol.endQuickIndices(); ol.writeSplitBar(fileName); ol.writeSearchInfo(); ol.startContents(); if (hl==CMHL_All) { ol.startTextBlock(); ol.parseText(lne ? lne->intro() : theTranslator->trCompoundMembersDescription(Config_getBool(EXTRACT_ALL))); ol.endTextBlock(); } else { // hack to work around a mozilla bug, which refuses to switch to // normal lists otherwise ol.writeString(" "); } writeMemberList(ol,quickIndex, multiPageIndex?page:-1, g_memberIndexLetterUsed[hl], Definition::TypeClass); endFile(ol); first=FALSE; } if (multiPageIndex && addToIndex) Doxygen::indexList->decContentsDepth(); ol.popGeneratorState(); } static void writeClassMemberIndex(OutputList &ol) { LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassMembers); bool addToIndex = lne==0 || lne->visible(); if (documentedClassMembers[CMHL_All]>0 && addToIndex) { Doxygen::indexList->addContentsItem(TRUE,lne ? lne->title() : theTranslator->trCompoundMembers(),0,"functions",0); Doxygen::indexList->incContentsDepth(); } writeClassMemberIndexFiltered(ol,CMHL_All); writeClassMemberIndexFiltered(ol,CMHL_Functions); writeClassMemberIndexFiltered(ol,CMHL_Variables); writeClassMemberIndexFiltered(ol,CMHL_Typedefs); writeClassMemberIndexFiltered(ol,CMHL_Enums); writeClassMemberIndexFiltered(ol,CMHL_EnumValues); writeClassMemberIndexFiltered(ol,CMHL_Properties); writeClassMemberIndexFiltered(ol,CMHL_Events); writeClassMemberIndexFiltered(ol,CMHL_Related); if (documentedClassMembers[CMHL_All]>0 && addToIndex) { Doxygen::indexList->decContentsDepth(); } } //---------------------------------------------------------------------------- /** Helper class representing a file member in the navigation menu. */ struct FmhlInfo { FmhlInfo(const char *fn,const char *t) : fname(fn), title(t) {} const char *fname; QCString title; }; static const FmhlInfo *getFmhlInfo(int hl) { static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); static FmhlInfo fmhlInfo[] = { FmhlInfo("globals", theTranslator->trAll()), FmhlInfo("globals_func", fortranOpt ? theTranslator->trSubprograms() : vhdlOpt ? VhdlDocGen::trFunctionAndProc() : theTranslator->trFunctions()), FmhlInfo("globals_vars",theTranslator->trVariables()), FmhlInfo("globals_type",theTranslator->trTypedefs()), FmhlInfo("globals_enum",theTranslator->trEnumerations()), FmhlInfo("globals_eval",theTranslator->trEnumerationValues()), FmhlInfo("globals_defs",theTranslator->trDefines()) }; return &fmhlInfo[hl]; } static void writeFileMemberIndexFiltered(OutputList &ol, FileMemberHighlight hl) { if (documentedFileMembers[hl]==0) return; static bool disableIndex = Config_getBool(DISABLE_INDEX); bool multiPageIndex=FALSE; if (documentedFileMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX) { multiPageIndex=TRUE; } ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); QCString extension=Doxygen::htmlFileExtension; LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::FileGlobals); QCString title = lne ? lne->title() : theTranslator->trFileMembers(); bool addToIndex = lne==0 || lne->visible(); if (addToIndex) { Doxygen::indexList->addContentsItem(multiPageIndex,getFmhlInfo(hl)->title,0, getFmhlInfo(hl)->fname,0,multiPageIndex,TRUE); if (multiPageIndex) Doxygen::indexList->incContentsDepth(); } bool first=TRUE; SIntDict::Iterator it(g_fileIndexLetterUsed[hl]); MemberIndexList *ml; for (it.toFirst();(ml=it.current());++it) { uint page = ml->letter(); QCString fileName = getFmhlInfo(hl)->fname; if (multiPageIndex) { if (!first) { fileName+="_"+letterToLabel(page); } QCString cs = QString(QChar(page)).utf8(); if (addToIndex) { Doxygen::indexList->addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE); } } bool quickIndex = documentedFileMembers[hl]>maxItemsBeforeQuickIndex; ol.startFile(fileName+extension,0,title); ol.startQuickIndices(); if (!disableIndex) { ol.writeQuickLinks(TRUE,HLI_Globals,0); if (!Config_getBool(HTML_DYNAMIC_MENUS)) { startQuickIndexList(ol); // index item for all file member lists startQuickIndexItem(ol, getFmhlInfo(0)->fname+Doxygen::htmlFileExtension,hl==FMHL_All,TRUE,first); ol.writeString(fixSpaces(getFmhlInfo(0)->title)); endQuickIndexItem(ol); int i; // index items for per category member lists for (i=1;i0) { startQuickIndexItem(ol, getFmhlInfo(i)->fname+Doxygen::htmlFileExtension,hl==i,TRUE,first); ol.writeString(fixSpaces(getFmhlInfo(i)->title)); endQuickIndexItem(ol); } } endQuickIndexList(ol); if (quickIndex) { writeQuickMemberIndex(ol,g_fileIndexLetterUsed[hl],page, getFmhlInfo(hl)->fname,multiPageIndex); } } } ol.endQuickIndices(); ol.writeSplitBar(fileName); ol.writeSearchInfo(); ol.startContents(); if (hl==FMHL_All) { ol.startTextBlock(); ol.parseText(lne ? lne->intro() : theTranslator->trFileMembersDescription(Config_getBool(EXTRACT_ALL))); ol.endTextBlock(); } else { // hack to work around a mozilla bug, which refuses to switch to // normal lists otherwise ol.writeString(" "); } writeMemberList(ol,quickIndex, multiPageIndex?page:-1, g_fileIndexLetterUsed[hl], Definition::TypeFile); endFile(ol); first=FALSE; } if (multiPageIndex && addToIndex) Doxygen::indexList->decContentsDepth(); ol.popGeneratorState(); } static void writeFileMemberIndex(OutputList &ol) { LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::FileGlobals); bool addToIndex = lne==0 || lne->visible(); if (documentedFileMembers[FMHL_All]>0 && addToIndex) { Doxygen::indexList->addContentsItem(FALSE,lne ? lne->title() : theTranslator->trFileMembers(),0,"globals",0); Doxygen::indexList->incContentsDepth(); } writeFileMemberIndexFiltered(ol,FMHL_All); writeFileMemberIndexFiltered(ol,FMHL_Functions); writeFileMemberIndexFiltered(ol,FMHL_Variables); writeFileMemberIndexFiltered(ol,FMHL_Typedefs); writeFileMemberIndexFiltered(ol,FMHL_Enums); writeFileMemberIndexFiltered(ol,FMHL_EnumValues); writeFileMemberIndexFiltered(ol,FMHL_Defines); if (documentedFileMembers[FMHL_All]>0 && addToIndex) { Doxygen::indexList->decContentsDepth(); } } //---------------------------------------------------------------------------- /** Helper class representing a namespace member in the navigation menu. */ struct NmhlInfo { NmhlInfo(const char *fn,const char *t) : fname(fn), title(t) {} const char *fname; QCString title; }; static const NmhlInfo *getNmhlInfo(int hl) { static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); static NmhlInfo nmhlInfo[] = { NmhlInfo("namespacemembers", theTranslator->trAll()), NmhlInfo("namespacemembers_func", fortranOpt ? theTranslator->trSubprograms() : vhdlOpt ? VhdlDocGen::trFunctionAndProc() : theTranslator->trFunctions()), NmhlInfo("namespacemembers_vars",theTranslator->trVariables()), NmhlInfo("namespacemembers_type",theTranslator->trTypedefs()), NmhlInfo("namespacemembers_enum",theTranslator->trEnumerations()), NmhlInfo("namespacemembers_eval",theTranslator->trEnumerationValues()) }; return &nmhlInfo[hl]; } //---------------------------------------------------------------------------- static void writeNamespaceMemberIndexFiltered(OutputList &ol, NamespaceMemberHighlight hl) { if (documentedNamespaceMembers[hl]==0) return; static bool disableIndex = Config_getBool(DISABLE_INDEX); bool multiPageIndex=FALSE; if (documentedNamespaceMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX) { multiPageIndex=TRUE; } ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); QCString extension=Doxygen::htmlFileExtension; LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::NamespaceMembers); QCString title = lne ? lne->title() : theTranslator->trNamespaceMembers(); bool addToIndex = lne==0 || lne->visible(); if (addToIndex) { Doxygen::indexList->addContentsItem(multiPageIndex,getNmhlInfo(hl)->title,0, getNmhlInfo(hl)->fname,0,multiPageIndex,TRUE); if (multiPageIndex) Doxygen::indexList->incContentsDepth(); } bool first=TRUE; SIntDict::Iterator it(g_namespaceIndexLetterUsed[hl]); MemberIndexList *ml; for (it.toFirst();(ml=it.current());++it) { uint page = ml->letter(); QCString fileName = getNmhlInfo(hl)->fname; if (multiPageIndex) { if (!first) { fileName+="_"+letterToLabel(page); } QCString cs = QString(QChar(page)).utf8(); if (addToIndex) { Doxygen::indexList->addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE); } } bool quickIndex = documentedNamespaceMembers[hl]>maxItemsBeforeQuickIndex; ol.startFile(fileName+extension,0,title); ol.startQuickIndices(); if (!disableIndex) { ol.writeQuickLinks(TRUE,HLI_NamespaceMembers,0); if (!Config_getBool(HTML_DYNAMIC_MENUS)) { startQuickIndexList(ol); // index item for all namespace member lists startQuickIndexItem(ol, getNmhlInfo(0)->fname+Doxygen::htmlFileExtension,hl==NMHL_All,TRUE,first); ol.writeString(fixSpaces(getNmhlInfo(0)->title)); endQuickIndexItem(ol); int i; // index items per category member lists for (i=1;i0) { startQuickIndexItem(ol, getNmhlInfo(i)->fname+Doxygen::htmlFileExtension,hl==i,TRUE,first); ol.writeString(fixSpaces(getNmhlInfo(i)->title)); endQuickIndexItem(ol); } } endQuickIndexList(ol); if (quickIndex) { writeQuickMemberIndex(ol,g_namespaceIndexLetterUsed[hl],page, getNmhlInfo(hl)->fname,multiPageIndex); } } } ol.endQuickIndices(); ol.writeSplitBar(fileName); ol.writeSearchInfo(); ol.startContents(); if (hl==NMHL_All) { ol.startTextBlock(); ol.parseText(lne ? lne->intro() : theTranslator->trNamespaceMemberDescription(Config_getBool(EXTRACT_ALL))); ol.endTextBlock(); } else { // hack to work around a mozilla bug, which refuses to switch to // normal lists otherwise ol.writeString(" "); } writeMemberList(ol,quickIndex, multiPageIndex?page:-1, g_namespaceIndexLetterUsed[hl], Definition::TypeNamespace); endFile(ol); first=FALSE; } if (multiPageIndex && addToIndex) Doxygen::indexList->decContentsDepth(); ol.popGeneratorState(); } static void writeNamespaceMemberIndex(OutputList &ol) { LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::NamespaceMembers); bool addToIndex = lne==0 || lne->visible(); if (documentedNamespaceMembers[NMHL_All]>0 && addToIndex) { Doxygen::indexList->addContentsItem(FALSE,lne ? lne->title() : theTranslator->trNamespaceMembers(),0,"namespacemembers",0); Doxygen::indexList->incContentsDepth(); } //bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); writeNamespaceMemberIndexFiltered(ol,NMHL_All); writeNamespaceMemberIndexFiltered(ol,NMHL_Functions); writeNamespaceMemberIndexFiltered(ol,NMHL_Variables); writeNamespaceMemberIndexFiltered(ol,NMHL_Typedefs); writeNamespaceMemberIndexFiltered(ol,NMHL_Enums); writeNamespaceMemberIndexFiltered(ol,NMHL_EnumValues); if (documentedNamespaceMembers[NMHL_All]>0 && addToIndex) { Doxygen::indexList->decContentsDepth(); } } //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- static void writeExampleIndex(OutputList &ol) { if (Doxygen::exampleSDict->count()==0) return; ol.pushGeneratorState(); ol.disable(OutputGenerator::Man); LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Examples); QCString title = lne ? lne->title() : theTranslator->trExamples(); bool addToIndex = lne==0 || lne->visible(); startFile(ol,"examples",0,title,HLI_Examples); startTitle(ol,0); ol.parseText(title); endTitle(ol,0,0); ol.startContents(); if (addToIndex) { Doxygen::indexList->addContentsItem(TRUE,title,0,"examples",0,TRUE,TRUE); Doxygen::indexList->incContentsDepth(); } ol.startTextBlock(); ol.parseText(lne ? lne->intro() : theTranslator->trExamplesDescription()); ol.endTextBlock(); ol.startItemList(); PageSDict::Iterator pdi(*Doxygen::exampleSDict); PageDef *pd=0; for (pdi.toFirst();(pd=pdi.current());++pdi) { ol.startItemListItem(); QCString n=pd->getOutputFileBase(); if (!pd->title().isEmpty()) { ol.writeObjectLink(0,n,0,pd->title()); if (addToIndex) { Doxygen::indexList->addContentsItem(FALSE,filterTitle(pd->title()),pd->getReference(),n,0,FALSE,TRUE); } } else { ol.writeObjectLink(0,n,0,pd->name()); if (addToIndex) { Doxygen::indexList->addContentsItem(FALSE,pd->name(),pd->getReference(),n,0,FALSE,TRUE); } } ol.endItemListItem(); ol.writeString("\n"); } ol.endItemList(); if (addToIndex) { Doxygen::indexList->decContentsDepth(); } endFile(ol); ol.popGeneratorState(); } //---------------------------------------------------------------------------- static void countRelatedPages(int &docPages,int &indexPages) { docPages=indexPages=0; PageSDict::Iterator pdi(*Doxygen::pageSDict); PageDef *pd=0; for (pdi.toFirst();(pd=pdi.current());++pdi) { if ( pd->visibleInIndex()) { indexPages++; } if ( pd->documentedPage()) { docPages++; } } } //---------------------------------------------------------------------------- static bool mainPageHasOwnTitle() { static QCString projectName = Config_getString(PROJECT_NAME); QCString title; if (Doxygen::mainPage) { title = filterTitle(Doxygen::mainPage->title()); } return !projectName.isEmpty() && mainPageHasTitle() && qstricmp(title,projectName)!=0; } static void writePages(PageDef *pd,FTVHelp *ftv) { //printf("writePages()=%s pd=%p mainpage=%p\n",pd->name().data(),pd,Doxygen::mainPage); LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Pages); bool addToIndex = lne==0 || lne->visible(); if (!addToIndex) return; bool hasSubPages = pd->hasSubPages(); bool hasSections = pd->hasSections(); if (pd->visibleInIndex()) { QCString pageTitle; if (pd->title().isEmpty()) pageTitle=pd->name(); else pageTitle=filterTitle(pd->title()); if (ftv) { //printf("*** adding %s hasSubPages=%d hasSections=%d\n",pageTitle.data(),hasSubPages,hasSections); ftv->addContentsItem( hasSubPages,pageTitle, pd->getReference(),pd->getOutputFileBase(), 0,hasSubPages,TRUE,pd); } if (addToIndex && pd!=Doxygen::mainPage) { Doxygen::indexList->addContentsItem( hasSubPages || hasSections,pageTitle, pd->getReference(),pd->getOutputFileBase(), 0,hasSubPages,TRUE); } } if (hasSubPages && ftv) ftv->incContentsDepth(); bool doIndent = (hasSections || hasSubPages) && (pd!=Doxygen::mainPage || mainPageHasOwnTitle()); if (doIndent) { Doxygen::indexList->incContentsDepth(); } if (hasSections) { pd->addSectionsToIndex(); } PageSDict *subPages = pd->getSubPages(); if (subPages) { PageSDict::Iterator pi(*subPages); PageDef *subPage; for (pi.toFirst();(subPage=pi.current());++pi) { writePages(subPage,ftv); } } if (hasSubPages && ftv) ftv->decContentsDepth(); if (doIndent) { Doxygen::indexList->decContentsDepth(); } //printf("end writePages()=%s\n",pd->title().data()); } //---------------------------------------------------------------------------- static void writePageIndex(OutputList &ol) { if (indexedPages==0) return; ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Pages); QCString title = lne ? lne->title() : theTranslator->trRelatedPages(); startFile(ol,"pages",0,title,HLI_Pages); startTitle(ol,0); ol.parseText(title); endTitle(ol,0,0); ol.startContents(); ol.startTextBlock(); ol.parseText(lne ? lne->intro() : theTranslator->trRelatedPagesDescription()); ol.endTextBlock(); { FTVHelp* ftv = new FTVHelp(FALSE); PageSDict::Iterator pdi(*Doxygen::pageSDict); PageDef *pd=0; for (pdi.toFirst();(pd=pdi.current());++pdi) { if ((pd->getOuterScope()==0 || pd->getOuterScope()->definitionType()!=Definition::TypePage) && // not a sub page !pd->isReference() // not an external page ) { writePages(pd,ftv); } } QGString outStr; FTextStream t(&outStr); ftv->generateTreeViewInline(t); ol.writeString(outStr); delete ftv; } // ol.popGeneratorState(); // ------ endFile(ol); ol.popGeneratorState(); } //---------------------------------------------------------------------------- static int countGroups() { int count=0; GroupSDict::Iterator gli(*Doxygen::groupSDict); GroupDef *gd; for (gli.toFirst();(gd=gli.current());++gli) { if (!gd->isReference()) { gd->visited=FALSE; count++; } } return count; } //---------------------------------------------------------------------------- static int countDirs() { int count=0; SDict::Iterator dli(*Doxygen::directories); DirDef *dd; for (dli.toFirst();(dd=dli.current());++dli) { if (dd->isLinkableInProject()) { dd->visited=FALSE; count++; } } return count; } //---------------------------------------------------------------------------- void writeGraphInfo(OutputList &ol) { if (!Config_getBool(HAVE_DOT) || !Config_getBool(GENERATE_HTML)) return; ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); generateGraphLegend(Config_getString(HTML_OUTPUT)); bool &stripCommentsStateRef = Config_getBool(STRIP_CODE_COMMENTS); bool oldStripCommentsState = stripCommentsStateRef; bool &createSubdirs = Config_getBool(CREATE_SUBDIRS); bool oldCreateSubdirs = createSubdirs; // temporarily disable the stripping of comments for our own code example! stripCommentsStateRef = FALSE; // temporarily disable create subdirs for linking to our example createSubdirs = FALSE; startFile(ol,"graph_legend",0,theTranslator->trLegendTitle().data()); startTitle(ol,0); ol.parseText(theTranslator->trLegendTitle()); endTitle(ol,0,0); ol.startContents(); QCString legendDocs = theTranslator->trLegendDocs(); int s = legendDocs.find("
"); int e = legendDocs.find("
"); QCString imgExt = getDotImageExtension(); if (imgExt=="svg" && s!=-1 && e!=-1) { legendDocs = legendDocs.left(s+8) + "[!-- SVG 0 --]\n" + legendDocs.mid(e); //printf("legendDocs=%s\n",legendDocs.data()); } FileDef fd("","graph_legend"); ol.generateDoc("graph_legend",1,&fd,0,legendDocs,FALSE,FALSE); // restore config settings stripCommentsStateRef = oldStripCommentsState; createSubdirs = oldCreateSubdirs; endFile(ol); ol.popGeneratorState(); } //---------------------------------------------------------------------------- /*! * write groups as hierarchical trees */ static void writeGroupTreeNode(OutputList &ol, GroupDef *gd, int level, FTVHelp* ftv, bool addToIndex) { //bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); //bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); if (level>20) { warn(gd->getDefFileName(),gd->getDefLine(), "maximum nesting level exceeded for group %s: check for possible recursive group relation!\n",gd->name().data() ); return; } /* Some groups should appear twice under different parent-groups. * That is why we should not check if it was visited */ if (/*!gd->visited &&*/ (!gd->isASubGroup() || level>0) && gd->isVisible() && (!gd->isReference() || Config_getBool(EXTERNAL_GROUPS)) // hide external groups by default ) { //printf("gd->name()=%s #members=%d\n",gd->name().data(),gd->countMembers()); // write group info bool hasSubGroups = gd->getSubGroups()->count()>0; bool hasSubPages = gd->getPages()->count()>0; int numSubItems = 0; if (1 /*Config_getBool(TOC_EXPAND)*/) { QListIterator mli(gd->getMemberLists()); MemberList *ml; for (mli.toFirst();(ml=mli.current());++mli) { if (ml->listType()&MemberListType_documentationLists) { numSubItems += ml->count(); } } numSubItems += gd->getNamespaces()->count(); numSubItems += gd->getClasses()->count(); numSubItems += gd->getFiles()->count(); numSubItems += gd->getDirs()->count(); numSubItems += gd->getPages()->count(); } bool isDir = hasSubGroups || hasSubPages || numSubItems>0; //printf("gd=`%s': pageDict=%d\n",gd->name().data(),gd->pageDict->count()); if (addToIndex) { Doxygen::indexList->addContentsItem(isDir,gd->groupTitle(),gd->getReference(),gd->getOutputFileBase(),0,isDir,TRUE); Doxygen::indexList->incContentsDepth(); } if (ftv) { ftv->addContentsItem(hasSubGroups,gd->groupTitle(), gd->getReference(),gd->getOutputFileBase(),0, FALSE,FALSE,gd); ftv->incContentsDepth(); } //ol.writeListItem(); //ol.startTextLink(gd->getOutputFileBase(),0); //parseText(ol,gd->groupTitle()); //ol.endTextLink(); ol.startIndexListItem(); ol.startIndexItem(gd->getReference(),gd->getOutputFileBase()); ol.parseText(gd->groupTitle()); ol.endIndexItem(gd->getReference(),gd->getOutputFileBase()); if (gd->isReference()) { ol.startTypewriter(); ol.docify(" [external]"); ol.endTypewriter(); } QListIterator eli(LayoutDocManager::instance().docEntries(LayoutDocManager::Group)); LayoutDocEntry *lde; for (eli.toFirst();(lde=eli.current());++eli) { if (lde->kind()==LayoutDocEntry::MemberDef && addToIndex) { LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde; MemberList *ml = gd->getMemberList(lmd->type); if (ml) { MemberListIterator mi(*ml); MemberDef *md; for (mi.toFirst();(md=mi.current());++mi) { MemberList *enumList = md->enumFieldList(); bool isDir = enumList!=0 && md->isEnumerate(); if (md->isVisible() && md->name().find('@')==-1) { Doxygen::indexList->addContentsItem(isDir, md->name(),md->getReference(), md->getOutputFileBase(),md->anchor(),FALSE,addToIndex); } if (isDir) { Doxygen::indexList->incContentsDepth(); MemberListIterator emli(*enumList); MemberDef *emd; for (emli.toFirst();(emd=emli.current());++emli) { if (emd->isVisible()) { Doxygen::indexList->addContentsItem(FALSE, emd->name(),emd->getReference(),emd->getOutputFileBase(), emd->anchor(),FALSE,addToIndex); } } Doxygen::indexList->decContentsDepth(); } } } } else if (lde->kind()==LayoutDocEntry::GroupClasses && addToIndex) { ClassSDict::Iterator it(*gd->getClasses()); ClassDef *cd; for (;(cd=it.current());++it) { //bool nestedClassInSameGroup = // cd->getOuterScope() && cd->getOuterScope()->definitionType()==Definition::TypeClass && // cd->getOuterScope()->partOfGroups()!=0 && cd->getOuterScope()->partOfGroups()->contains(gd); //printf("===== GroupClasses: %s visible=%d nestedClassInSameGroup=%d\n",cd->name().data(),cd->isVisible(),nestedClassInSameGroup); if (cd->isVisible() /*&& !nestedClassInSameGroup*/) { //if (cd->isEmbeddedInOuterScope()) //{ //printf("add class & members %d\n",addToIndex); addMembersToIndex(cd,LayoutDocManager::Class,cd->displayName(FALSE),cd->anchor(),addToIndex,TRUE); //} //else // only index the class, not its members //{ // printf("%s: add class only\n",cd->name().data()); // Doxygen::indexList->addContentsItem(FALSE, // cd->displayName(TRUE),cd->getReference(), // cd->getOutputFileBase(),cd->anchor(),addToIndex,TRUE); //} } } } else if (lde->kind()==LayoutDocEntry::GroupNamespaces && addToIndex) { NamespaceSDict::Iterator it(*gd->getNamespaces()); NamespaceDef *nd; for (;(nd=it.current());++it) { if (nd->isVisible()) { Doxygen::indexList->addContentsItem(FALSE, nd->localName(),nd->getReference(), nd->getOutputFileBase(),0,FALSE,FALSE); } } } else if (lde->kind()==LayoutDocEntry::GroupFiles && addToIndex) { QListIterator it(*gd->getFiles()); FileDef *fd; for (;(fd=it.current());++it) { if (fd->isVisible()) { Doxygen::indexList->addContentsItem(FALSE, fd->displayName(),fd->getReference(), fd->getOutputFileBase(),0,FALSE,FALSE); } } } else if (lde->kind()==LayoutDocEntry::GroupDirs && addToIndex) { QListIterator it(*gd->getDirs()); DirDef *dd; for (;(dd=it.current());++it) { if (dd->isVisible()) { Doxygen::indexList->addContentsItem(FALSE, dd->shortName(),dd->getReference(), dd->getOutputFileBase(),0,FALSE,FALSE); } } } else if (lde->kind()==LayoutDocEntry::GroupPageDocs && addToIndex) { SDict::Iterator it(*gd->getPages()); PageDef *pd; for (;(pd=it.current());++it) { SectionInfo *si=0; if (!pd->name().isEmpty()) si=Doxygen::sectionDict->find(pd->name()); bool hasSubPages = pd->hasSubPages(); bool hasSections = pd->hasSections(); Doxygen::indexList->addContentsItem( hasSubPages || hasSections, convertToHtml(pd->title(),TRUE), gd->getReference(), gd->getOutputFileBase(), si ? si->label.data() : 0, hasSubPages || hasSections, TRUE); // addToNavIndex if (hasSections || hasSubPages) { Doxygen::indexList->incContentsDepth(); } if (hasSections) { pd->addSectionsToIndex(); } writePages(pd,0); if (hasSections || hasSubPages) { Doxygen::indexList->decContentsDepth(); } } } else if (lde->kind()==LayoutDocEntry::GroupNestedGroups) { if (gd->getSubGroups()->count()>0) { startIndexHierarchy(ol,level+1); QListIterator gli(*gd->getSubGroups()); GroupDef *subgd = 0; for (gli.toFirst();(subgd=gli.current());++gli) { writeGroupTreeNode(ol,subgd,level+1,ftv,addToIndex); } endIndexHierarchy(ol,level+1); } } } ol.endIndexListItem(); if (addToIndex) { Doxygen::indexList->decContentsDepth(); } if (ftv) { ftv->decContentsDepth(); } //gd->visited=TRUE; } } static void writeGroupHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex) { if (ftv) { ol.pushGeneratorState(); ol.disable(OutputGenerator::Html); } startIndexHierarchy(ol,0); GroupSDict::Iterator gli(*Doxygen::groupSDict); GroupDef *gd; for (gli.toFirst();(gd=gli.current());++gli) { writeGroupTreeNode(ol,gd,0,ftv,addToIndex); } endIndexHierarchy(ol,0); if (ftv) { ol.popGeneratorState(); } } #if 0 static void writeGroupTree(GroupDef *gd,FTVHelp *ftv,int level,bool addToIndex) { static bool externalGroups = Config_getBool(EXTERNAL_GROUPS); /* Some groups should appear twice under different parent-groups. * That is why we should not check if it was visited */ if ((!gd->isASubGroup() || level>0) && gd->isVisible() && (!gd->isReference() || externalGroups) // hide external groups by default ) { if (ftv) { ftv->addContentsItem(hasSubGroups,gd->groupTitle(),gd->getReference(),gd->getOutputFileBase(),0); ftv->incContentsDepth(); } if (ftv) { ftv->decContentsDepth(); } } } static void writeGroupTree(FTVHelp *ftv,bool addToIndex) { GroupSDict::Iterator gli(*Doxygen::groupSDict); GroupDef *gd; for (gli.toFirst();(gd=gli.current());++gli) { writeGroupTree(gd,ftv,0,addToIndex); } } #endif //---------------------------------------------------------------------------- static void writeGroupIndex(OutputList &ol) { if (documentedGroups==0) return; ol.pushGeneratorState(); // 1.{ ol.disable(OutputGenerator::Man); LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Modules); QCString title = lne ? lne->title() : theTranslator->trModules(); bool addToIndex = lne==0 || lne->visible(); startFile(ol,"modules",0,title,HLI_Modules); startTitle(ol,0); ol.parseText(title); endTitle(ol,0,0); ol.startContents(); ol.startTextBlock(); ol.parseText(lne ? lne->intro() : theTranslator->trModulesDescription()); ol.endTextBlock(); // --------------- // Normal group index for Latex/RTF // --------------- // 2.{ ol.pushGeneratorState(); ol.disable(OutputGenerator::Html); Doxygen::indexList->disable(); writeGroupHierarchy(ol,0,FALSE); Doxygen::indexList->enable(); ol.popGeneratorState(); // 2.} // --------------- // interactive group index for HTML // --------------- // 2.{ ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); { if (addToIndex) { Doxygen::indexList->addContentsItem(TRUE,title,0,"modules",0,TRUE,TRUE); Doxygen::indexList->incContentsDepth(); } FTVHelp* ftv = new FTVHelp(FALSE); writeGroupHierarchy(ol,ftv,addToIndex); QGString outStr; FTextStream t(&outStr); ftv->generateTreeViewInline(t); ol.disableAllBut(OutputGenerator::Html); ol.writeString(outStr); delete ftv; if (addToIndex) { Doxygen::indexList->decContentsDepth(); } } ol.popGeneratorState(); // 2.} endFile(ol); ol.popGeneratorState(); // 1.} } //---------------------------------------------------------------------------- #if 0 static void writeDirIndex(OutputList &ol) { if (documentedDirs==0) return; ol.pushGeneratorState(); ol.disable(OutputGenerator::Man); LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Dirs); QCString title = lne ? lne->title() : theTranslator->trDirectories(); bool addToIndex=FALSE; //lne==0 || lne->visible(); startFile(ol,"dirs",0,title,HLI_Directories); startTitle(ol,0); ol.parseText(title); endTitle(ol,0,0); ol.startContents(); ol.startTextBlock(); if (addToIndex) { Doxygen::indexList->addContentsItem(TRUE,title,0,"dirs",0,TRUE,TRUE); Doxygen::indexList->incContentsDepth(); } ol.parseText(lne ? lne->intro() : theTranslator->trDirDescription()); ol.endTextBlock(); FTVHelp* ftv = 0; bool treeView=Config_getBool(USE_INLINE_TREES); if (treeView) { ftv = new FTVHelp(FALSE); } writeDirHierarchy(ol,ftv,addToIndex); if (ftv) { QGString outStr; FTextStream t(&outStr); ftv->generateTreeViewInline(t); ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); ol.writeString(outStr); ol.popGeneratorState(); delete ftv; } if (addToIndex) { Doxygen::indexList->decContentsDepth(); } endFile(ol); ol.popGeneratorState(); } #endif //---------------------------------------------------------------------------- static void writeUserGroupStubPage(OutputList &ol,LayoutNavEntry *lne) { if (lne->baseFile().left(9)=="usergroup") { ol.pushGeneratorState(); ol.disableAllBut(OutputGenerator::Html); startFile(ol,lne->baseFile(),0,lne->title(),HLI_UserGroup); startTitle(ol,0); ol.parseText(lne->title()); endTitle(ol,0,0); ol.startContents(); QListIterator li(lne->children()); LayoutNavEntry *entry; int count=0; for (li.toFirst();(entry=li.current());++li) { if (entry->visible()) count++; } if (count>0) { ol.writeString("\n"); } endFile(ol); ol.popGeneratorState(); } } //---------------------------------------------------------------------------- static void writeIndex(OutputList &ol) { static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN); static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL); static QCString projectName = Config_getString(PROJECT_NAME); // save old generator state ol.pushGeneratorState(); QCString projPrefix; if (!projectName.isEmpty()) { projPrefix=projectName+" "; } //-------------------------------------------------------------------- // write HTML index //-------------------------------------------------------------------- ol.disableAllBut(OutputGenerator::Html); QCString defFileName = Doxygen::mainPage ? Doxygen::mainPage->docFile().data() : "[generated]"; int defLine = Doxygen::mainPage ? Doxygen::mainPage->docLine() : -1; QCString title; if (!mainPageHasTitle()) { title = theTranslator->trMainPage(); } else if (Doxygen::mainPage) { title = filterTitle(Doxygen::mainPage->title()); } QCString indexName="index"; ol.startFile(indexName,0,title); if (Doxygen::mainPage) { if ( (!projectName.isEmpty() && mainPageHasTitle() && qstricmp(title,projectName)!=0) ) // to avoid duplicate entries in the treeview { Doxygen::indexList->addContentsItem(Doxygen::mainPage->hasSubPages(),title,0,indexName,0,Doxygen::mainPage->hasSubPages(),TRUE); } if (Doxygen::mainPage->hasSubPages() || Doxygen::mainPage->hasSections()) { writePages(Doxygen::mainPage,0); } } ol.startQuickIndices(); if (!Config_getBool(DISABLE_INDEX)) { ol.writeQuickLinks(TRUE,HLI_Main,0); } ol.endQuickIndices(); ol.writeSplitBar(indexName); ol.writeSearchInfo(); bool headerWritten=FALSE; if (Doxygen::mainPage && !Doxygen::mainPage->title().isEmpty()) { if (Doxygen::mainPage->title().lower()!="notitle") { ol.startHeaderSection(); ol.startTitleHead(0); ol.generateDoc(Doxygen::mainPage->docFile(),Doxygen::mainPage->docLine(), Doxygen::mainPage,0,Doxygen::mainPage->title(), TRUE,FALSE,0,TRUE,FALSE); headerWritten = TRUE; } } else { if (!projectName.isEmpty()) { ol.startHeaderSection(); ol.startTitleHead(0); ol.parseText(projPrefix+theTranslator->trDocumentation()); headerWritten = TRUE; } } if (headerWritten) { ol.endTitleHead(0,0); ol.endHeaderSection(); } ol.startContents(); if (Config_getBool(DISABLE_INDEX) && Doxygen::mainPage==0) { ol.writeQuickLinks(FALSE,HLI_Main,0); } if (Doxygen::mainPage) { Doxygen::insideMainPage=TRUE; if (Doxygen::mainPage->showToc() && Doxygen::mainPage->hasSections()) { Doxygen::mainPage->writeToc(ol); } ol.startTextBlock(); ol.generateDoc(defFileName,defLine,Doxygen::mainPage,0, Doxygen::mainPage->documentation(),TRUE,FALSE /*,Doxygen::mainPage->sectionDict*/); ol.endTextBlock(); Doxygen::insideMainPage=FALSE; } endFile(ol); ol.disable(OutputGenerator::Html); //-------------------------------------------------------------------- // write LaTeX/RTF index //-------------------------------------------------------------------- ol.enable(OutputGenerator::Latex); ol.enable(OutputGenerator::RTF); ol.startFile("refman",0,0); ol.startIndexSection(isTitlePageStart); if (!Config_getString(LATEX_HEADER).isEmpty()) { ol.disable(OutputGenerator::Latex); } if (projPrefix.isEmpty()) { ol.parseText(theTranslator->trReferenceManual()); } else { ol.parseText(projPrefix); } if (!Config_getString(PROJECT_NUMBER).isEmpty()) { ol.startProjectNumber(); ol.generateDoc(defFileName,defLine,Doxygen::mainPage,0,Config_getString(PROJECT_NUMBER),FALSE,FALSE); ol.endProjectNumber(); } ol.endIndexSection(isTitlePageStart); ol.startIndexSection(isTitlePageAuthor); ol.parseText(theTranslator->trGeneratedBy()); ol.endIndexSection(isTitlePageAuthor); ol.enable(OutputGenerator::Latex); ol.lastIndexPage(); if (Doxygen::mainPage) { ol.startIndexSection(isMainPage); if (mainPageHasTitle()) { ol.parseText(Doxygen::mainPage->title()); } else { ol.parseText(/*projPrefix+*/theTranslator->trMainPage()); } ol.endIndexSection(isMainPage); } if (documentedPages>0) { //ol.parseText(projPrefix+theTranslator->trPageDocumentation()); //ol.endIndexSection(isPageDocumentation); PageSDict::Iterator pdi(*Doxygen::pageSDict); PageDef *pd=pdi.toFirst(); bool first=Doxygen::mainPage==0; for (pdi.toFirst();(pd=pdi.current());++pdi) { if (!pd->getGroupDef() && !pd->isReference() && (!pd->hasParentPage() || // not inside other page (Doxygen::mainPage==pd->getOuterScope())) // or inside main page ) { bool isCitationPage = pd->name()=="citelist"; if (isCitationPage) { // For LaTeX the bibliograph is already written by \bibliography ol.pushGeneratorState(); ol.disable(OutputGenerator::Latex); } QCString title = pd->title(); if (title.isEmpty()) title=pd->name(); ol.startIndexSection(isPageDocumentation); ol.parseText(title); ol.endIndexSection(isPageDocumentation); ol.pushGeneratorState(); // write TOC title (RTF only) ol.disableAllBut(OutputGenerator::RTF); ol.startIndexSection(isPageDocumentation2); ol.parseText(title); ol.endIndexSection(isPageDocumentation2); ol.popGeneratorState(); ol.writeAnchor(0,pd->getOutputFileBase()); ol.writePageLink(pd->getOutputFileBase(),first); first=FALSE; if (isCitationPage) { ol.popGeneratorState(); } } } } if (!Config_getBool(LATEX_HIDE_INDICES)) { //if (indexedPages>0) //{ // ol.startIndexSection(isPageIndex); // ol.parseText(/*projPrefix+*/ theTranslator->trPageIndex()); // ol.endIndexSection(isPageIndex); //} if (documentedGroups>0) { ol.startIndexSection(isModuleIndex); ol.parseText(/*projPrefix+*/ theTranslator->trModuleIndex()); ol.endIndexSection(isModuleIndex); } if (documentedNamespaces>0) { ol.startIndexSection(isNamespaceIndex); ol.parseText(/*projPrefix+*/(fortranOpt?theTranslator->trModulesIndex():theTranslator->trNamespaceIndex())); ol.endIndexSection(isNamespaceIndex); } if (hierarchyClasses>0) { ol.startIndexSection(isClassHierarchyIndex); ol.parseText(/*projPrefix+*/ (fortranOpt ? theTranslator->trCompoundIndexFortran() : vhdlOpt ? VhdlDocGen::trDesignUnitIndex() : theTranslator->trHierarchicalIndex() )); ol.endIndexSection(isClassHierarchyIndex); } if (annotatedClassesPrinted>0) { ol.startIndexSection(isCompoundIndex); ol.parseText(/*projPrefix+*/ (fortranOpt ? theTranslator->trCompoundIndexFortran() : vhdlOpt ? VhdlDocGen::trDesignUnitIndex() : theTranslator->trCompoundIndex() )); ol.endIndexSection(isCompoundIndex); } if (documentedFiles>0) { ol.startIndexSection(isFileIndex); ol.parseText(/*projPrefix+*/theTranslator->trFileIndex()); ol.endIndexSection(isFileIndex); } } if (documentedGroups>0) { ol.startIndexSection(isModuleDocumentation); ol.parseText(/*projPrefix+*/theTranslator->trModuleDocumentation()); ol.endIndexSection(isModuleDocumentation); } if (documentedNamespaces>0) { ol.startIndexSection(isNamespaceDocumentation); ol.parseText(/*projPrefix+*/(fortranOpt?theTranslator->trModuleDocumentation():theTranslator->trNamespaceDocumentation())); ol.endIndexSection(isNamespaceDocumentation); } if (annotatedClassesPrinted>0) { ol.startIndexSection(isClassDocumentation); ol.parseText(/*projPrefix+*/(fortranOpt?theTranslator->trTypeDocumentation():theTranslator->trClassDocumentation())); ol.endIndexSection(isClassDocumentation); } if (documentedFiles>0) { ol.startIndexSection(isFileDocumentation); ol.parseText(/*projPrefix+*/theTranslator->trFileDocumentation()); ol.endIndexSection(isFileDocumentation); } if (Doxygen::exampleSDict->count()>0) { ol.startIndexSection(isExampleDocumentation); ol.parseText(/*projPrefix+*/theTranslator->trExampleDocumentation()); ol.endIndexSection(isExampleDocumentation); } ol.endIndexSection(isEndIndex); endFile(ol); if (Doxygen::mainPage) { Doxygen::insideMainPage=TRUE; ol.disable(OutputGenerator::Man); startFile(ol,Doxygen::mainPage->name(),0,Doxygen::mainPage->title()); ol.startContents(); ol.startTextBlock(); ol.generateDoc(defFileName,defLine,Doxygen::mainPage,0, Doxygen::mainPage->documentation(),FALSE,FALSE ); ol.endTextBlock(); endFile(ol); ol.enable(OutputGenerator::Man); Doxygen::insideMainPage=FALSE; } ol.popGeneratorState(); } static QArray indexWritten; static void writeIndexHierarchyEntries(OutputList &ol,const QList &entries) { QListIterator li(entries); LayoutNavEntry *lne; for (li.toFirst();(lne=li.current());++li) { LayoutNavEntry::Kind kind = lne->kind(); uint index = (uint)kind; if (index>=indexWritten.size()) { uint i; uint oldSize = indexWritten.size(); uint newSize = index+1; indexWritten.resize(newSize); for (i=oldSize;ititle().data(),lne->kind()); bool addToIndex=lne->visible(); bool needsClosing=FALSE; if (!indexWritten.at(index)) { switch(kind) { case LayoutNavEntry::MainPage: msg("Generating index page...\n"); writeIndex(ol); break; case LayoutNavEntry::Pages: msg("Generating page index...\n"); writePageIndex(ol); break; case LayoutNavEntry::Modules: msg("Generating module index...\n"); writeGroupIndex(ol); break; case LayoutNavEntry::Namespaces: { static bool showNamespaces = Config_getBool(SHOW_NAMESPACES); if (showNamespaces) { if (documentedNamespaces>0 && addToIndex) { Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,lne->baseFile(),0); Doxygen::indexList->incContentsDepth(); needsClosing=TRUE; } if (LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Namespaces)!=lne) // for backward compatibility with old layout file { msg("Generating namespace index...\n"); writeNamespaceIndex(ol); } } } break; case LayoutNavEntry::NamespaceList: { static bool showNamespaces = Config_getBool(SHOW_NAMESPACES); if (showNamespaces) { msg("Generating namespace index...\n"); writeNamespaceIndex(ol); } } break; case LayoutNavEntry::NamespaceMembers: msg("Generating namespace member index...\n"); writeNamespaceMemberIndex(ol); break; case LayoutNavEntry::Classes: if (annotatedClasses>0 && addToIndex) { Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,lne->baseFile(),0); Doxygen::indexList->incContentsDepth(); needsClosing=TRUE; } if (LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Classes)!=lne) // for backward compatibility with old layout file { msg("Generating annotated compound index...\n"); writeAnnotatedIndex(ol); } break; case LayoutNavEntry::ClassList: msg("Generating annotated compound index...\n"); writeAnnotatedIndex(ol); break; case LayoutNavEntry::ClassIndex: msg("Generating alphabetical compound index...\n"); writeAlphabeticalIndex(ol); break; case LayoutNavEntry::ClassHierarchy: msg("Generating hierarchical class index...\n"); writeHierarchicalIndex(ol); if (Config_getBool(HAVE_DOT) && Config_getBool(GRAPHICAL_HIERARCHY)) { msg("Generating graphical class hierarchy...\n"); writeGraphicalClassHierarchy(ol); } break; case LayoutNavEntry::ClassMembers: msg("Generating member index...\n"); writeClassMemberIndex(ol); break; case LayoutNavEntry::Files: { static bool showFiles = Config_getBool(SHOW_FILES); if (showFiles) { if (documentedHtmlFiles>0 && addToIndex) { Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,lne->baseFile(),0); Doxygen::indexList->incContentsDepth(); needsClosing=TRUE; } if (LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Files)!=lne) // for backward compatibility with old layout file { msg("Generating file index...\n"); writeFileIndex(ol); } } } break; case LayoutNavEntry::FileList: { static bool showFiles = Config_getBool(SHOW_FILES); if (showFiles) { msg("Generating file index...\n"); writeFileIndex(ol); } } break; case LayoutNavEntry::FileGlobals: msg("Generating file member index...\n"); writeFileMemberIndex(ol); break; case LayoutNavEntry::Examples: msg("Generating example index...\n"); writeExampleIndex(ol); break; case LayoutNavEntry::User: { // prepend a ! or ^ marker to the URL to avoid tampering with it QCString url = correctURL(lne->url(),"!"); // add ! to relative URL bool isRelative=url.at(0)=='!'; if (!url.isEmpty() && !isRelative) // absolute URL { url.prepend("^"); // prepend ^ to absolute URL } bool isRef = lne->baseFile().left(4)=="@ref" || lne->baseFile().left(4)=="\\ref"; Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,url,0,FALSE,isRef || isRelative); } break; case LayoutNavEntry::UserGroup: if (addToIndex) { QCString url = correctURL(lne->url(),"!"); // add ! to relative URL if (!url.isEmpty()) { if (url=="![none]") { Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,0,0,FALSE,FALSE); } else { bool isRelative=url.at(0)=='!'; if (!isRelative) // absolute URL { url.prepend("^"); // prepend ^ to absolute URL } bool isRef = lne->baseFile().left(4)=="@ref" || lne->baseFile().left(4)=="\\ref"; Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,url,0,FALSE,isRef || isRelative); } } else { Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,lne->baseFile(),0,TRUE,TRUE); } Doxygen::indexList->incContentsDepth(); needsClosing=TRUE; } writeUserGroupStubPage(ol,lne); break; } if (kind!=LayoutNavEntry::User && kind!=LayoutNavEntry::UserGroup) // User entry may appear multiple times { indexWritten.at(index)=TRUE; } } writeIndexHierarchyEntries(ol,lne->children()); if (needsClosing) { switch(kind) { case LayoutNavEntry::Namespaces: case LayoutNavEntry::Classes: case LayoutNavEntry::Files: case LayoutNavEntry::UserGroup: Doxygen::indexList->decContentsDepth(); break; default: break; } } //printf("ending %s kind=%d\n",lne->title().data(),lne->kind()); } } static bool quickLinkVisible(LayoutNavEntry::Kind kind) { static bool showFiles = Config_getBool(SHOW_FILES); static bool showNamespaces = Config_getBool(SHOW_NAMESPACES); switch (kind) { case LayoutNavEntry::MainPage: return TRUE; case LayoutNavEntry::User: return TRUE; case LayoutNavEntry::UserGroup: return TRUE; case LayoutNavEntry::Pages: return indexedPages>0; case LayoutNavEntry::Modules: return documentedGroups>0; case LayoutNavEntry::Namespaces: return documentedNamespaces>0 && showNamespaces; case LayoutNavEntry::NamespaceList: return documentedNamespaces>0 && showNamespaces; case LayoutNavEntry::NamespaceMembers: return documentedNamespaceMembers[NMHL_All]>0; case LayoutNavEntry::Classes: return annotatedClasses>0; case LayoutNavEntry::ClassList: return annotatedClasses>0; case LayoutNavEntry::ClassIndex: return annotatedClasses>0; case LayoutNavEntry::ClassHierarchy: return hierarchyClasses>0; case LayoutNavEntry::ClassMembers: return documentedClassMembers[CMHL_All]>0; case LayoutNavEntry::Files: return documentedHtmlFiles>0 && showFiles; case LayoutNavEntry::FileList: return documentedHtmlFiles>0 && showFiles; case LayoutNavEntry::FileGlobals: return documentedFileMembers[FMHL_All]>0; //case LayoutNavEntry::Dirs: return documentedDirs>0; case LayoutNavEntry::Examples: return Doxygen::exampleSDict->count()>0; } return FALSE; } template void renderMemberIndicesAsJs(FTextStream &t, int total,const int *numDocumented,const LetterToIndexMap *memberLists, const T *(*getInfo)(int hl)) { // index items per category member lists bool firstMember=TRUE; for (int i=0;i0) { t << ","; if (firstMember) { t << "children:["; firstMember=FALSE; } t << endl << "{text:\"" << convertToJSString(getInfo(i)->title) << "\",url:\"" << convertToJSString(getInfo(i)->fname+Doxygen::htmlFileExtension) << "\""; // Check if we have many members, then add sub entries per letter... // quick alphabetical index bool quickIndex = numDocumented[i]>maxItemsBeforeQuickIndex; if (quickIndex) { bool multiPageIndex=FALSE; if (numDocumented[i]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX) { multiPageIndex=TRUE; } t << ",children:[" << endl; bool firstLetter=TRUE; SIntDict::Iterator it(memberLists[i]); MemberIndexList *ml; for (it.toFirst();(ml=it.current());++it) { if (!firstLetter) t << "," << endl; uint letter = ml->letter(); QCString is = letterToLabel(letter); QCString ci = QString(QChar(letter)).utf8(); QCString anchor; QCString extension=Doxygen::htmlFileExtension; QCString fullName = getInfo(i)->fname; if (!multiPageIndex || firstLetter) anchor=fullName+extension+"#index_"; else // other pages of multi page index anchor=fullName+"_"+is+extension+"#index_"; t << "{text:\"" << convertToJSString(ci) << "\",url:\"" << convertToJSString(anchor+is) << "\"}"; firstLetter=FALSE; } t << "]"; } t << "}"; } } if (!firstMember) { t << "]"; } } static bool renderQuickLinksAsJs(FTextStream &t,LayoutNavEntry *root,bool first) { QListIterator li(root->children()); LayoutNavEntry *entry; int count=0; for (li.toFirst();(entry=li.current());++li) { if (entry->visible() && quickLinkVisible(entry->kind())) count++; } if (count>0) // at least one item is visible { bool firstChild = TRUE; if (!first) t << ","; t << "children:[" << endl; for (li.toFirst();(entry=li.current());++li) { if (entry->visible() && quickLinkVisible(entry->kind())) { if (!firstChild) t << "," << endl; firstChild=FALSE; QCString url = entry->url(); t << "{text:\"" << convertToJSString(entry->title()) << "\",url:\"" << convertToJSString(url) << "\""; bool hasChildren=FALSE; if (entry->kind()==LayoutNavEntry::NamespaceMembers) { renderMemberIndicesAsJs(t,NMHL_Total,documentedNamespaceMembers, g_namespaceIndexLetterUsed,getNmhlInfo); } else if (entry->kind()==LayoutNavEntry::ClassMembers) { renderMemberIndicesAsJs(t,CMHL_Total,documentedClassMembers, g_memberIndexLetterUsed,getCmhlInfo); } else if (entry->kind()==LayoutNavEntry::FileGlobals) { renderMemberIndicesAsJs(t,FMHL_Total,documentedFileMembers, g_fileIndexLetterUsed,getFmhlInfo); } else // recursive into child list { hasChildren = renderQuickLinksAsJs(t,entry,FALSE); } if (hasChildren) t << "]"; t << "}"; } } } return count>0; } static void writeMenuData() { if (!Config_getBool(GENERATE_HTML) || Config_getBool(DISABLE_INDEX)) return; QCString outputDir = Config_getBool(HTML_OUTPUT); QFile f(outputDir+"/menudata.js"); LayoutNavEntry *root = LayoutDocManager::instance().rootNavEntry(); if (f.open(IO_WriteOnly)) { FTextStream t(&f); t << "/*\n@ @licstart The following is the entire license notice for the\n" "JavaScript code in this file.\n\nCopyright (C) 1997-2017 by Dimitri van Heesch\n\n" "This program is free software; you can redistribute it and/or modify\n" "it under the terms of the GNU General Public License as published by\n" "the Free Software Foundation; either version 2 of the License, or\n" "(at your option) any later version.\n\n" "This program is distributed in the hope that it will be useful,\n" "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" " GNU General Public License for more details.\n\n" "You should have received a copy of the GNU General Public License along\n" "with this program; if not, write to the Free Software Foundation, Inc.,\n" "51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\n" "@licend The above is the entire license notice\n" "for the JavaScript code in this file\n" "*/\n"; t << "var menudata={"; bool hasChildren = renderQuickLinksAsJs(t,root,TRUE); if (hasChildren) t << "]"; t << "}" << endl; } } void writeIndexHierarchy(OutputList &ol) { writeMenuData(); LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry(); if (lne) { writeIndexHierarchyEntries(ol,lne->children()); } }