index.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  * $Id: index.cpp,v 1.63 2001/03/19 19:27:40 root Exp $
00004  *
00005  * Copyright (C) 1997-2008 by Dimitri van Heesch.
00006  *
00007  * Permission to use, copy, modify, and distribute this software and its
00008  * documentation under the terms of the GNU General Public License is hereby 
00009  * granted. No representations are made about the suitability of this software 
00010  * for any purpose. It is provided "as is" without express or implied warranty.
00011  * See the GNU General Public License for more details.
00012  *
00013  * Documents produced by Doxygen are derivative works derived from the
00014  * input used in their production; they are not affected by this license.
00015  *
00016  */
00017 
00022 #include <stdlib.h>
00023 
00024 #include <qtextstream.h>
00025 #include <qdatetime.h>
00026 #include <qdir.h>
00027 #include <qregexp.h>
00028 
00029 #include "message.h"
00030 #include "index.h"
00031 #include "doxygen.h"
00032 #include "config.h"
00033 #include "filedef.h"
00034 #include "outputlist.h"
00035 #include "util.h"
00036 #include "groupdef.h"
00037 #include "language.h"
00038 #include "htmlhelp.h"
00039 #include "ftvhelp.h"
00040 #include "dot.h"
00041 #include "pagedef.h"
00042 #include "dirdef.h"
00043 #include "vhdldocgen.h"
00044 
00045 #define MAX_ITEMS_BEFORE_MULTIPAGE_INDEX 200
00046 #define MAX_ITEMS_BEFORE_QUICK_INDEX 30
00047 
00048 int annotatedClasses;
00049 int hierarchyClasses;
00050 int documentedFiles;
00051 int documentedGroups;
00052 int documentedNamespaces;
00053 int indexedPages;
00054 int documentedClassMembers[CMHL_Total];
00055 int documentedFileMembers[FMHL_Total];
00056 int documentedNamespaceMembers[NMHL_Total];
00057 int documentedHtmlFiles;
00058 int documentedPages;
00059 int documentedDirs;
00060 
00061 int countClassHierarchy();
00062 int countClassMembers(int filter=CMHL_All);
00063 int countFileMembers(int filter=FMHL_All);
00064 void countFiles(int &htmlFiles,int &files);
00065 int countGroups();
00066 int countDirs();
00067 int countNamespaces();
00068 int countAnnotatedClasses();
00069 int countNamespaceMembers(int filter=NMHL_All);
00070 int countIncludeFiles();
00071 void countRelatedPages(int &docPages,int &indexPages);
00072 
00073 void countDataStructures()
00074 {
00075   annotatedClasses           = countAnnotatedClasses();
00076   hierarchyClasses           = countClassHierarchy();
00077   countFiles(documentedHtmlFiles,documentedFiles);
00078   countRelatedPages(documentedPages,indexedPages);
00079   documentedGroups           = countGroups();
00080   documentedNamespaces       = countNamespaces();
00081   documentedDirs             = countDirs();
00082 }
00083 
00084 static void startIndexHierarchy(OutputList &ol,int level)
00085 {
00086   ol.pushGeneratorState();
00087   ol.disable(OutputGenerator::Man);
00088   ol.disable(OutputGenerator::Html);
00089   if (level<6) ol.startIndexList();
00090   ol.enableAll();
00091   ol.disable(OutputGenerator::Latex);
00092   ol.disable(OutputGenerator::RTF);
00093   ol.startItemList();
00094   ol.popGeneratorState();
00095 }
00096 
00097 static void endIndexHierarchy(OutputList &ol,int level)
00098 {
00099   ol.pushGeneratorState();
00100   ol.disable(OutputGenerator::Man);
00101   ol.disable(OutputGenerator::Html);
00102   if (level<6) ol.endIndexList();
00103   ol.enableAll();
00104   ol.disable(OutputGenerator::Latex);
00105   ol.disable(OutputGenerator::RTF);
00106   ol.endItemList();
00107   ol.popGeneratorState();
00108 }
00109 
00110 //----------------------------------------------------------------------------
00111 
00112 class MemberIndexList : public QList<MemberDef>
00113 {
00114   public:
00115     MemberIndexList() : QList<MemberDef>() {}
00116     ~MemberIndexList() {}
00117     int compareItems(GCI item1, GCI item2)
00118     {
00119       MemberDef *md1=(MemberDef *)item1;
00120       MemberDef *md2=(MemberDef *)item2;
00121       return stricmp(md1->name(),md2->name());
00122     }
00123 };
00124 
00125 #define MEMBER_INDEX_ENTRIES 128
00126 
00127 static MemberIndexList g_memberIndexLetterUsed[CMHL_Total][MEMBER_INDEX_ENTRIES];
00128 static MemberIndexList g_fileIndexLetterUsed[FMHL_Total][MEMBER_INDEX_ENTRIES];
00129 static MemberIndexList g_namespaceIndexLetterUsed[NMHL_Total][MEMBER_INDEX_ENTRIES];
00130 
00131 static bool g_classIndexLetterUsed[CHL_Total][256];
00132 
00133 const int maxItemsBeforeQuickIndex = MAX_ITEMS_BEFORE_QUICK_INDEX;
00134 
00135 //----------------------------------------------------------------------------
00136 
00137 // strips w from s iff s starts with w
00138 bool stripWord(QCString &s,QCString w)
00139 {
00140   bool success=FALSE;
00141   if (s.left(w.length())==w) 
00142   {
00143     success=TRUE;
00144     s=s.right(s.length()-w.length());
00145   }
00146   return success;
00147 }
00148 
00149 //----------------------------------------------------------------------------
00150 // some quasi intelligent brief description abbreviator :^)
00151 QCString abbreviate(const char *s,const char *name)
00152 {
00153   QCString scopelessName=name;
00154   int i=scopelessName.findRev("::");
00155   if (i!=-1) scopelessName=scopelessName.mid(i+2);
00156   QCString result=s;
00157   result=result.stripWhiteSpace();
00158   // strip trailing .
00159   if (!result.isEmpty() && result.at(result.length()-1)=='.') 
00160     result=result.left(result.length()-1);
00161 
00162   // strip any predefined prefix
00163   QStrList &briefDescAbbrev = Config_getList("ABBREVIATE_BRIEF");
00164   const char *p = briefDescAbbrev.first();
00165   while (p)
00166   {
00167     QCString s = p;
00168     s.replace(QRegExp("\\$name"), scopelessName);  // replace $name with entity name
00169     s += " ";
00170     stripWord(result,s);
00171     p = briefDescAbbrev.next();
00172   }
00173 
00174   // capitalize first word
00175   if (!result.isEmpty())
00176   {
00177     int c=result[0];
00178     if (c>='a' && c<='z') c+='A'-'a';
00179     result[0]=c;
00180   }
00181   return result;
00182 }
00183 
00184 //----------------------------------------------------------------------------
00185 
00186 static void startQuickIndexList(OutputList &ol)
00187 {
00188   bool fancyTabs = TRUE;
00189   if (fancyTabs)
00190   {
00191     ol.writeString("  <div class=\"tabs\">\n"); 
00192     ol.writeString("    <ul>\n"); 
00193   }
00194   else
00195   {
00196     ol.writeString("  <div class=\"qindex\">"); 
00197   }
00198 }
00199 
00200 static void endQuickIndexList(OutputList &ol)
00201 {
00202   bool fancyTabs = TRUE;
00203   if (fancyTabs)
00204   {
00205     ol.writeString("    </ul>\n");
00206   }
00207   ol.writeString("  </div>\n");
00208 }
00209 
00210 static void startQuickIndexItem(OutputList &ol,const char *l,
00211                                 bool hl,bool compact,bool &first)
00212 {
00213   bool fancyTabs = TRUE;
00214   if (!first && compact && !fancyTabs) ol.writeString(" | ");
00215   first=FALSE;
00216   if (fancyTabs)
00217   {
00218     ol.writeString("      <li"); 
00219     if (hl) ol.writeString(" class=\"current\"");
00220     ol.writeString("><a ");
00221   }
00222   else
00223   {
00224     if (!compact) ol.writeString("<li>");
00225     if (hl && compact)
00226     {
00227       ol.writeString("<a class=\"qindexHL\" ");
00228     }
00229     else
00230     {
00231       ol.writeString("<a class=\"qindex\" ");
00232     }
00233   }
00234   ol.writeString("href=\""); 
00235   ol.writeString(l);
00236   ol.writeString("\">");
00237   if (fancyTabs)
00238   {
00239     ol.writeString("<span>");
00240   }
00241 }
00242 
00243 static void endQuickIndexItem(OutputList &ol)
00244 {
00245   bool fancyTabs=TRUE;
00246   if (fancyTabs) ol.writeString("</span>");
00247   ol.writeString("</a>");
00248   if (fancyTabs) ol.writeString("</li>\n");
00249 }
00250 
00251 
00252 static QCString fixSpaces(const QCString &s)
00253 {
00254   return substitute(s," ","&nbsp;");
00255 }
00256 
00257 
00258 void startTitle(OutputList &ol,const char *fileName)
00259 {
00260   ol.startTitleHead(fileName);
00261   ol.pushGeneratorState();
00262   ol.disable(OutputGenerator::Man);
00263 }
00264 
00265 void endTitle(OutputList &ol,const char *fileName,const char *name)
00266 {
00267   ol.popGeneratorState();
00268   ol.endTitleHead(fileName,name);
00269 }
00270 
00271 void startFile(OutputList &ol,const char *name,const char *manName,
00272                const char *title,HighlightedItem hli,bool additionalIndices)
00273 {
00274   ol.startFile(name,manName,title);
00275   if (!Config_getBool("DISABLE_INDEX")) 
00276   {
00277     ol.startQuickIndices();
00278     ol.writeQuickLinks(TRUE,hli);
00279     if (!additionalIndices)
00280     {
00281       ol.endQuickIndices();
00282       ol.startContents();
00283     }
00284   }
00285   else
00286   {
00287     if (!additionalIndices)
00288     {
00289       ol.startContents();
00290     }
00291   }
00292 }
00293 
00294 void endFile(OutputList &ol,bool)
00295 {
00296   ol.endContents();
00297   ol.pushGeneratorState();
00298   ol.disableAllBut(OutputGenerator::Html);
00299   ol.writeFooter(); // write the footer
00300   ol.popGeneratorState();
00301   ol.endFile();
00302 }
00303 
00304 //----------------------------------------------------------------------------
00305 
00306 static bool classHasVisibleChildren(ClassDef *cd)
00307 {
00308   if (cd->subClasses()==0) return FALSE;
00309   BaseClassList *bcl=cd->subClasses();
00310   BaseClassListIterator bcli(*bcl);
00311   for ( ; bcli.current() ; ++bcli)
00312   {
00313     if (bcli.current()->classDef->isVisibleInHierarchy())
00314     {
00315       return TRUE;
00316     }
00317   }
00318   return FALSE;
00319 }
00320 
00321 void writeClassTree(OutputList &ol,BaseClassList *bcl,bool hideSuper,int level)
00322 {
00323   if (bcl==0) return;
00324   BaseClassListIterator bcli(*bcl);
00325   bool started=FALSE;
00326   for ( ; bcli.current() ; ++bcli)
00327   {
00328     ClassDef *cd=bcli.current()->classDef;
00329     if (cd->isVisibleInHierarchy() && hasVisibleRoot(cd->baseClasses()))
00330     {
00331       if (!started)
00332       {
00333         startIndexHierarchy(ol,level);
00334         Doxygen::indexList.incContentsDepth();
00335         started=TRUE;
00336       }
00337       //printf("Passed...\n");
00338       bool hasChildren = !cd->visited && !hideSuper && classHasVisibleChildren(cd);
00339       //printf("tree4: Has children %s: %d\n",cd->name().data(),hasChildren);
00340       if (cd->isLinkable())
00341       {
00342         //printf("Writing class %s\n",cd->displayName().data());
00343         ol.startIndexItem(cd->getReference(),cd->getOutputFileBase());
00344         ol.parseText(cd->displayName());
00345         ol.endIndexItem(cd->getReference(),cd->getOutputFileBase());
00346         if (cd->isReference()) 
00347         { 
00348           ol.startTypewriter(); 
00349           ol.docify(" [external]");
00350           ol.endTypewriter();
00351         }
00352         Doxygen::indexList.addContentsItem(hasChildren,
00353                                            cd->displayName(),
00354                                            cd->getReference(),
00355                                            cd->getOutputFileBase(),
00356                                            0);
00357       }
00358       else
00359       {
00360         ol.startIndexItem(0,0);
00361         ol.parseText(cd->name());
00362         ol.endIndexItem(0,0);
00363         Doxygen::indexList.addContentsItem(hasChildren,cd->displayName(),0,0,0);
00364       }
00365       if (hasChildren)
00366       {
00367         //printf("Class %s at %p visited=%d\n",cd->name().data(),cd,cd->visited);
00368         bool wasVisited=cd->visited;
00369         cd->visited=TRUE;
00370         writeClassTree(ol,cd->subClasses(),wasVisited,level+1);
00371       }
00372     }
00373   }
00374   if (started) 
00375   {
00376     endIndexHierarchy(ol,level);
00377     Doxygen::indexList.decContentsDepth();
00378   }
00379 }
00380 
00381 
00382 //----------------------------------------------------------------------------
00385 void writeClassTree(BaseClassList *cl,int level)
00386 {
00387   if (cl==0) return;
00388   BaseClassListIterator cli(*cl);
00389   bool started=FALSE;
00390   for ( ; cli.current() ; ++cli)
00391   {
00392     ClassDef *cd=cli.current()->classDef;
00393     if (cd->isVisibleInHierarchy() && hasVisibleRoot(cd->baseClasses()))
00394     //if (cd->isVisibleInHierarchy() && !cd->visited)
00395     {
00396       if (!started)
00397       {
00398         Doxygen::indexList.incContentsDepth();
00399         started=TRUE;
00400       }
00401       bool hasChildren = !cd->visited && classHasVisibleChildren(cd);
00402       //printf("tree2: Has children %s: %d\n",cd->name().data(),hasChildren);
00403       if (cd->isLinkable())
00404       {
00405         Doxygen::indexList.addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),0);
00406       }
00407       if (hasChildren)
00408       {
00409         writeClassTree(cd->subClasses(),level+1);
00410       }
00411       cd->visited=TRUE;
00412     }
00413   }
00414   if (started) 
00415   {
00416     Doxygen::indexList.decContentsDepth();
00417   }
00418 }
00419 
00420 //----------------------------------------------------------------------------
00423 void writeClassTreeNode(ClassDef *cd,bool &started,int level)
00424 {
00425   //printf("writeClassTreeNode(%s) visited=%d\n",cd->name().data(),cd->visited);
00426   if (cd->isVisibleInHierarchy() && !cd->visited)
00427   {
00428     if (!started)
00429     {
00430       started=TRUE;
00431     }
00432     bool hasChildren = classHasVisibleChildren(cd);
00433     //printf("node: Has children %s: %d\n",cd->name().data(),hasChildren);
00434     if (cd->isLinkable())
00435     {
00436       Doxygen::indexList.addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),0);
00437     }
00438     if (hasChildren)
00439     {
00440       writeClassTree(cd->subClasses(),level+1);
00441     }
00442     cd->visited=TRUE;
00443   }
00444 }
00445 
00446 void writeClassTree(ClassList *cl,int level)
00447 {
00448   if (cl==0) return;
00449   ClassListIterator cli(*cl);
00450   bool started=FALSE;
00451   for ( cli.toFirst() ; cli.current() ; ++cli)
00452   {
00453     cli.current()->visited=FALSE;
00454   }
00455   for ( cli.toFirst() ; cli.current() ; ++cli)
00456   {
00457     writeClassTreeNode(cli.current(),started,level);
00458   }
00459 }
00460 
00461 void writeClassTree(ClassSDict *d,int level)
00462 {
00463   if (d==0) return;
00464   ClassSDict::Iterator cli(*d);
00465   bool started=FALSE;
00466   for ( cli.toFirst() ; cli.current() ; ++cli)
00467   {
00468     cli.current()->visited=FALSE;
00469   }
00470   for ( cli.toFirst() ; cli.current() ; ++cli)
00471   {
00472     writeClassTreeNode(cli.current(),started,level);
00473   }
00474 }
00475 
00476 //----------------------------------------------------------------------------
00477 
00478 static void writeClassTreeForList(OutputList &ol,ClassSDict *cl,bool &started)
00479 {
00480   ClassSDict::Iterator cli(*cl);
00481   for (;cli.current(); ++cli)
00482   {
00483     ClassDef *cd=cli.current();
00484     //printf("class %s hasVisibleRoot=%d isVisibleInHierarchy=%d\n",
00485     //             cd->name().data(),
00486     //              hasVisibleRoot(cd->baseClasses()),
00487     //              cd->isVisibleInHierarchy()
00488     //      );
00489     if (!hasVisibleRoot(cd->baseClasses())) // filter on root classes
00490     {
00491       if (cd->isVisibleInHierarchy()) // should it be visible
00492       {
00493         if (!started)
00494         {
00495           startIndexHierarchy(ol,0);
00496           Doxygen::indexList.incContentsDepth();
00497           started=TRUE;
00498         }
00499         bool hasChildren = !cd->visited && classHasVisibleChildren(cd); 
00500         //printf("list: Has children %s: %d\n",cd->name().data(),hasChildren);
00501         if (cd->isLinkable())
00502         {
00503           //printf("Writing class %s isLinkable()=%d isLinkableInProject()=%d cd->templateMaster()=%p\n",
00504           //    cd->displayName().data(),cd->isLinkable(),cd->isLinkableInProject(),cd->templateMaster());
00505           ol.startIndexItem(cd->getReference(),cd->getOutputFileBase());
00506           ol.parseText(cd->displayName());
00507           ol.endIndexItem(cd->getReference(),cd->getOutputFileBase());
00508           if (cd->isReference()) 
00509           {
00510             ol.startTypewriter(); 
00511             ol.docify(" [external]");
00512             ol.endTypewriter();
00513           }
00514           Doxygen::indexList.addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),0);
00515         }
00516         else
00517         {
00518           ol.startIndexItem(0,0);
00519           ol.parseText(cd->displayName());
00520           ol.endIndexItem(0,0);
00521           Doxygen::indexList.addContentsItem(hasChildren,cd->displayName(),0,0,0);
00522         }
00523         if (hasChildren) 
00524         {
00525           writeClassTree(ol,cd->subClasses(),cd->visited,1);
00526           cd->visited=TRUE;
00527         }
00528       }
00529     }
00530   }
00531 }
00532 
00533 void writeClassHierarchy(OutputList &ol)
00534 {
00535   initClassHierarchy(Doxygen::classSDict);
00536   initClassHierarchy(Doxygen::hiddenClasses);
00537 
00538   bool started=FALSE;
00539   writeClassTreeForList(ol,Doxygen::classSDict,started);
00540   writeClassTreeForList(ol,Doxygen::hiddenClasses,started);
00541   if (started) 
00542   {
00543     endIndexHierarchy(ol,0);
00544     Doxygen::indexList.decContentsDepth();
00545   }
00546 }
00547 
00548 //----------------------------------------------------------------------------
00549 
00550 static int countClassesInTreeList(const ClassSDict &cl)
00551 {
00552   int count=0;
00553   ClassSDict::Iterator cli(cl);
00554   for (;cli.current(); ++cli)
00555   {
00556     ClassDef *cd=cli.current();
00557     if (!hasVisibleRoot(cd->baseClasses())) // filter on root classes
00558     {
00559       if (cd->isVisibleInHierarchy()) // should it be visible
00560       {
00561         if (cd->subClasses()) // should have sub classes
00562         {
00563           count++;
00564         }
00565       }
00566     }
00567   }
00568   return count;
00569 }
00570 
00571 int countClassHierarchy()
00572 {
00573   int count=0;
00574   initClassHierarchy(Doxygen::classSDict);
00575   initClassHierarchy(Doxygen::hiddenClasses);
00576   count+=countClassesInTreeList(*Doxygen::classSDict);
00577   count+=countClassesInTreeList(*Doxygen::hiddenClasses);
00578   return count;
00579 }
00580 
00581 //----------------------------------------------------------------------------
00582 
00583 void writeHierarchicalIndex(OutputList &ol)
00584 {
00585   bool vhdlOpt=Config_getBool("OPTIMIZE_OUTPUT_VHDL");
00586   if (hierarchyClasses==0) return;
00587   ol.pushGeneratorState();
00588   ol.disable(OutputGenerator::Man);
00589   startFile(ol,"hierarchy",0, theTranslator->trHierarchicalIndex().data(), 
00590             HLI_Hierarchy);
00591   startTitle(ol,0);
00592   QCString title = theTranslator->trClassHierarchy();
00593   if (vhdlOpt) title = VhdlDocGen::trDesignUnitHierarchy();
00594   //if (!Config_getString("PROJECT_NAME").isEmpty()) 
00595   //{
00596   //  title.prepend(Config_getString("PROJECT_NAME")+" ");
00597   //}
00598   ol.parseText(title);
00599   endTitle(ol,0,0);
00600   ol.startTextBlock();
00601   Doxygen::indexList.addContentsItem(TRUE,title,0,"hierarchy",0); 
00602   if (Config_getBool("HAVE_DOT") && Config_getBool("GRAPHICAL_HIERARCHY"))
00603   {
00604     ol.disable(OutputGenerator::Latex);
00605     ol.disable(OutputGenerator::RTF);
00606     ol.startTextLink("inherits",0);
00607     ol.parseText(theTranslator->trGotoGraphicalHierarchy());
00608     ol.endTextLink();
00609     ol.newParagraph();
00610     ol.enable(OutputGenerator::Latex);
00611     ol.enable(OutputGenerator::RTF);
00612   }
00613   ol.parseText(theTranslator->trClassHierarchyDescription());
00614   ol.endTextBlock();
00615   writeClassHierarchy(ol);
00616   endFile(ol);
00617   ol.popGeneratorState();
00618 }
00619 
00620 //----------------------------------------------------------------------------
00621 
00622 void writeGraphicalClassHierarchy(OutputList &ol)
00623 {
00624   if (hierarchyClasses==0) return;
00625   ol.disableAllBut(OutputGenerator::Html);
00626   QCString title = theTranslator->trGraphicalHierarchy();
00627   startFile(ol,"inherits",0,title.data(),HLI_Hierarchy);
00628   startTitle(ol,0);
00629   //if (!Config_getString("PROJECT_NAME").isEmpty()) 
00630   //{
00631   //  title.prepend(Config_getString("PROJECT_NAME")+" ");
00632   //}
00633   ol.parseText(title);
00634   endTitle(ol,0,0);
00635   ol.startTextBlock();
00636   Doxygen::indexList.addContentsItem(FALSE,theTranslator->trGraphicalHierarchy(),0,"inherits",0); 
00637   ol.startTextLink("hierarchy",0);
00638   ol.parseText(theTranslator->trGotoTextualHierarchy());
00639   ol.endTextLink();
00640   ol.newParagraph();
00641   //parseText(ol,theTranslator->trClassHierarchyDescription());
00642   //ol.newParagraph();
00643   ol.endTextBlock();
00644   DotGfxHierarchyTable g;
00645   ol.writeGraphicalHierarchy(g);
00646   endFile(ol);
00647   ol.enableAll();
00648 }
00649 
00650 //----------------------------------------------------------------------------
00651 
00652 void countFiles(int &htmlFiles,int &files)
00653 {
00654   htmlFiles=0;
00655   files=0;
00656   FileNameListIterator fnli(*Doxygen::inputNameList);
00657   FileName *fn;
00658   for (;(fn=fnli.current());++fnli)
00659   {
00660     FileNameIterator fni(*fn);
00661     FileDef *fd;
00662     for (;(fd=fni.current());++fni)
00663     {
00664       bool doc = fd->isLinkableInProject();
00665       bool src = fd->generateSourceFile();
00666       bool nameOk = !fd->isDocumentationFile();
00667       if (nameOk)
00668       {
00669         if (doc || src)
00670         {
00671           htmlFiles++;
00672         }
00673         if (doc)
00674         {
00675           files++;
00676         }
00677       }
00678     }
00679   }
00680 }
00681 
00682 //----------------------------------------------------------------------------
00683 
00684 void writeFileIndex(OutputList &ol)
00685 {
00686   if (documentedHtmlFiles==0) return;
00687   ol.pushGeneratorState();
00688   ol.disable(OutputGenerator::Man);
00689   if (documentedFiles==0) ol.disableAllBut(OutputGenerator::Html);
00690   startFile(ol,"files",0,theTranslator->trFileIndex().data(),HLI_Files);
00691   startTitle(ol,0);
00692   QCString title = theTranslator->trFileList();
00693   //if (!Config_getString("PROJECT_NAME").isEmpty()) 
00694   //{
00695   //  title.prepend(Config_getString("PROJECT_NAME")+" ");
00696   //}
00697   ol.parseText(title);
00698   endTitle(ol,0,0);
00699   ol.startTextBlock();
00700   Doxygen::indexList.addContentsItem(TRUE,theTranslator->trFileList(),0,"files",0); 
00701   Doxygen::indexList.incContentsDepth();
00702   ol.parseText(theTranslator->trFileListDescription(Config_getBool("EXTRACT_ALL")));
00703   ol.endTextBlock();
00704 
00705   OutputNameDict outputNameDict(1009);
00706   OutputNameList outputNameList;
00707   outputNameList.setAutoDelete(TRUE);
00708   
00709   if (Config_getBool("FULL_PATH_NAMES"))
00710   {
00711     // re-sort input files in (dir,file) output order instead of (file,dir) input order 
00712     FileName *fn=Doxygen::inputNameList->first();
00713     while (fn)
00714     {
00715       FileDef *fd=fn->first();
00716       while (fd)
00717       {
00718         QCString path=fd->getPath();
00719         if (path.isEmpty()) path="[external]";
00720         FileList *fl = outputNameDict.find(path);
00721         if (fl)
00722         {
00723           fl->inSort(fd);
00724           //printf("+ inserting %s---%s\n",fd->getPath().data(),fd->name().data());
00725         }
00726         else
00727         {
00728           //printf("o inserting %s---%s\n",fd->getPath().data(),fd->name().data());
00729           fl = new FileList(path);
00730           fl->inSort(fd);
00731           outputNameList.inSort(fl);
00732           outputNameDict.insert(path,fl);
00733         }
00734         fd=fn->next();
00735       }
00736       fn=Doxygen::inputNameList->next();
00737     }
00738   }
00739   
00740   ol.startIndexList();
00741   FileList *fl=0;
00742   if (Config_getBool("FULL_PATH_NAMES"))
00743   {
00744     fl = outputNameList.first();
00745   }
00746   else
00747   {
00748     fl = Doxygen::inputNameList->first();
00749   }
00750   while (fl)
00751   {
00752     FileDef *fd=fl->first();
00753     while (fd)
00754     {
00755       //printf("Found filedef %s\n",fd->name().data());
00756       bool doc = fd->isLinkableInProject();
00757       bool src = fd->generateSourceFile();
00758       bool nameOk = !fd->isDocumentationFile();
00759       if (nameOk && (doc || src) && 
00760               !fd->isReference())
00761       {
00762         QCString path;
00763         if (Config_getBool("FULL_PATH_NAMES")) 
00764         {
00765           path=stripFromPath(fd->getPath().copy());
00766         }
00767         QCString fullName=fd->name();
00768         if (!path.isEmpty()) 
00769         {
00770           if (path.at(path.length()-1)!='/') fullName.prepend("/");
00771           fullName.prepend(path);
00772         }
00773 
00774         ol.startIndexKey();
00775         ol.docify(path);
00776         if (doc)
00777         {
00778           ol.writeObjectLink(0,fd->getOutputFileBase(),0,fd->name());
00779           Doxygen::indexList.addContentsItem(FALSE,fullName,fd->getReference(),fd->getOutputFileBase(),0);
00780         }
00781         else
00782         {
00783           ol.startBold();
00784           ol.docify(fd->name());
00785           ol.endBold();
00786           Doxygen::indexList.addContentsItem(FALSE,fullName,0,0,0);
00787         }
00788         if (src)
00789         {
00790           ol.pushGeneratorState();
00791           ol.disableAllBut(OutputGenerator::Html);
00792           ol.docify(" ");
00793           ol.startTextLink(fd->includeName(),0);
00794           ol.docify("[");
00795           ol.parseText(theTranslator->trCode());
00796           ol.docify("]");
00797           ol.endTextLink();
00798           ol.popGeneratorState();
00799         }
00800         ol.endIndexKey();
00801         bool hasBrief = !fd->briefDescription().isEmpty();
00802         ol.startIndexValue(hasBrief);
00803         if (hasBrief)
00804         {
00805           //ol.docify(" (");
00806           ol.parseDoc(
00807               fd->briefFile(),fd->briefLine(),
00808               fd,0,
00809               abbreviate(fd->briefDescription(),fd->name()),
00810               FALSE, // index words
00811               FALSE, // isExample
00812               0,     // example name
00813               TRUE,  // single line
00814               TRUE   // link from index
00815              );
00816           //ol.docify(")");
00817         }
00818         ol.endIndexValue(fd->getOutputFileBase(),hasBrief);
00819         //ol.popGeneratorState();
00820         // --------------------------------------------------------
00821       }
00822       fd=fl->next();
00823     }
00824     if (Config_getBool("FULL_PATH_NAMES"))
00825     {
00826       fl=outputNameList.next();
00827     }
00828     else
00829     {
00830       fl=Doxygen::inputNameList->next();
00831     }
00832   }
00833   ol.endIndexList();
00834   Doxygen::indexList.decContentsDepth();
00835   endFile(ol);
00836   ol.popGeneratorState();
00837 }
00838 
00839 //----------------------------------------------------------------------------
00840 int countNamespaces()
00841 {
00842   int count=0;
00843   NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
00844   NamespaceDef *nd;
00845   for (;(nd=nli.current());++nli)
00846   {
00847     if (nd->isLinkableInProject()) count++;
00848   }
00849   return count;
00850 }
00851 
00852 //----------------------------------------------------------------------------
00853 
00854 void writeNamespaceIndex(OutputList &ol)
00855 {
00856   bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
00857   if (documentedNamespaces==0) return;
00858   ol.pushGeneratorState();
00859   ol.disable(OutputGenerator::Man);
00860   QCString title;
00861   if (Config_getBool("OPTIMIZE_OUTPUT_JAVA"))
00862   {
00863     startFile(ol,"namespaces",0,theTranslator->trPackageList().data(),HLI_Namespaces);
00864     title = theTranslator->trPackageList();
00865   }
00866   else if (fortranOpt)
00867   {
00868     startFile(ol,"namespaces",0,theTranslator->trModulesIndex().data(),HLI_Namespaces);
00869     title = theTranslator->trModulesList();
00870   }
00871   else
00872   {
00873     startFile(ol,"namespaces",0,theTranslator->trNamespaceIndex().data(),HLI_Namespaces);
00874     title = theTranslator->trNamespaceList();
00875   }
00876   startTitle(ol,0);
00877   QCString longTitle = title;
00878   //if (!Config_getString("PROJECT_NAME").isEmpty()) 
00879   //{
00880   //  longTitle.prepend(Config_getString("PROJECT_NAME")+" ");
00881   //}
00882   ol.parseText(longTitle);
00883   endTitle(ol,0,0);
00884   ol.startTextBlock();
00885   Doxygen::indexList.addContentsItem(TRUE,title,0,"namespaces",0); 
00886   Doxygen::indexList.incContentsDepth();
00887   //ol.newParagraph();
00888   if (Config_getBool("OPTIMIZE_OUTPUT_JAVA"))
00889   {
00890     ol.parseText(theTranslator->trPackageListDescription());
00891   }
00892   else if (fortranOpt)
00893   {
00894     ol.parseText(theTranslator->trModulesListDescription(Config_getBool("EXTRACT_ALL")));
00895   }
00896   else
00897   {
00898     ol.parseText(theTranslator->trNamespaceListDescription(Config_getBool("EXTRACT_ALL")));
00899   }
00900   //ol.newParagraph();
00901   ol.endTextBlock();
00902 
00903   bool first=TRUE;
00904 
00905   NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
00906   NamespaceDef *nd;
00907   for (nli.toFirst();(nd=nli.current());++nli)
00908   {
00909     if (nd->isLinkableInProject())
00910     {
00911       if (first)
00912       {
00913         ol.startIndexList();
00914         first=FALSE;
00915       }
00916       //ol.writeStartAnnoItem("namespace",nd->getOutputFileBase(),0,nd->name());
00917       ol.startIndexKey();
00918       ol.writeObjectLink(0,nd->getOutputFileBase(),0,nd->displayName());
00919       ol.endIndexKey();
00920       bool hasBrief = !nd->briefDescription().isEmpty();
00921       ol.startIndexValue(hasBrief);
00922       if (hasBrief)
00923       {
00924         //ol.docify(" (");
00925         ol.parseDoc(
00926                  nd->briefFile(),nd->briefLine(),
00927                  nd,0,
00928                  abbreviate(nd->briefDescription(),nd->displayName()),
00929                  FALSE, // index words
00930                  FALSE, // isExample
00931                  0,     // example name
00932                  TRUE,  // single line
00933                  TRUE   // link from index
00934                 );
00935         //ol.docify(")");
00936       }
00937       ol.endIndexValue(nd->getOutputFileBase(),hasBrief);
00938       //ol.writeEndAnnoItem(nd->getOutputFileBase());
00939       Doxygen::indexList.addContentsItem(FALSE,nd->displayName(),nd->getReference(),nd->getOutputFileBase(),0);
00940     }
00941   }
00942   if (!first) ol.endIndexList();
00943   Doxygen::indexList.decContentsDepth();
00944   endFile(ol);
00945   ol.popGeneratorState();
00946 }
00947 
00948 //----------------------------------------------------------------------------
00949 
00950 int countAnnotatedClasses()
00951 {
00952   int count=0;
00953   //ClassDef *cd=Doxygen::classList.first();
00954   ClassSDict::Iterator cli(*Doxygen::classSDict);
00955   ClassDef *cd;
00956   for (;(cd=cli.current());++cli)
00957   {
00958     if (cd->isLinkableInProject() && cd->templateMaster()==0) 
00959     { 
00960       //printf("Annotated class %s\n",cd->name().data()); 
00961       count++; 
00962     }
00963   }
00964   return count;
00965 }
00966 
00967 //----------------------------------------------------------------------
00968 
00969 void writeAnnotatedClassList(OutputList &ol)
00970 {
00971   ol.startIndexList(); 
00972   ClassSDict::Iterator cli(*Doxygen::classSDict);
00973   ClassDef *cd;
00974   
00975   // clear index
00976   int x,y;
00977   for (y=0;y<CHL_Total;y++)
00978   {
00979     for (x=0;x<256;x++)
00980     {
00981       g_classIndexLetterUsed[y][x]=FALSE;
00982     }
00983   }
00984   
00985   // see which elements are in use
00986   for (cli.toFirst();(cd=cli.current());++cli)
00987   {
00988     if (cd->isLinkableInProject() && cd->templateMaster()==0)
00989     {
00990       QCString dispName = cd->displayName();
00991       int c = dispName.at(getPrefixIndex(dispName));
00992       g_classIndexLetterUsed[CHL_All][c]=TRUE;
00993       switch(cd->compoundType())
00994       {
00995         case ClassDef::Class:
00996           g_classIndexLetterUsed[CHL_Classes][c]=TRUE;
00997           break;
00998         case ClassDef::Struct:
00999           g_classIndexLetterUsed[CHL_Structs][c]=TRUE;
01000           break;
01001         case ClassDef::Union:
01002           g_classIndexLetterUsed[CHL_Unions][c]=TRUE;
01003           break;
01004         case ClassDef::Interface:
01005           g_classIndexLetterUsed[CHL_Interfaces][c]=TRUE;
01006           break;
01007         case ClassDef::Protocol:
01008           g_classIndexLetterUsed[CHL_Protocols][c]=TRUE;
01009           break;
01010         case ClassDef::Category:
01011           g_classIndexLetterUsed[CHL_Categories][c]=TRUE;
01012           break;
01013         case ClassDef::Exception:
01014           g_classIndexLetterUsed[CHL_Exceptions][c]=TRUE;
01015           break;
01016 
01017       }
01018     }
01019   }
01020   
01021   for (cli.toFirst();(cd=cli.current());++cli)
01022   {
01023     if (cd->isLinkableInProject() && cd->templateMaster()==0)
01024     {
01025       QCString type=cd->compoundTypeString();
01026       ol.startIndexKey();
01027       ol.writeObjectLink(0,cd->getOutputFileBase(),0,cd->displayName());
01028       ol.endIndexKey();
01029       bool hasBrief = !cd->briefDescription().isEmpty();
01030       ol.startIndexValue(hasBrief);
01031       if (hasBrief)
01032       {
01033         ol.parseDoc(
01034                  cd->briefFile(),cd->briefLine(),
01035                  cd,0,
01036                  abbreviate(cd->briefDescription(),cd->displayName()),
01037                  FALSE,  // indexWords
01038                  FALSE,  // isExample
01039                  0,     // example name
01040                  TRUE,  // single line
01041                  TRUE   // link from index
01042                 );
01043       }
01044       ol.endIndexValue(cd->getOutputFileBase(),hasBrief);
01045       //ol.writeEndAnnoItem(cd->getOutputFileBase());
01046       Doxygen::indexList.addContentsItem(FALSE,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),0);
01047     }
01048   }
01049   ol.endIndexList();
01050 }
01051 
01052 //----------------------------------------------------------------------------
01053 
01054 class PrefixIgnoreClassList : public ClassList
01055 {
01056 public:
01057   virtual int compareItems(GCI item1, GCI item2)
01058   {
01059     ClassDef *c1=(ClassDef *)item1;
01060     ClassDef *c2=(ClassDef *)item2;
01061 
01062     QCString n1 = c1->className();
01063     n1.remove (0, getPrefixIndex(n1));
01064     QCString n2 = c2->className();
01065     n2.remove (0, getPrefixIndex(n2));
01066     
01067     return stricmp (n1, n2);
01068   }
01069 };
01070 
01071 // write an alphabetical index of all class with a header for each letter
01072 void writeAlphabeticalClassList(OutputList &ol)
01073 {
01074   //ol.startAlphabeticalIndexList(); 
01075   // What starting letters are used
01076   bool indexLetterUsed[256];
01077   memset (indexLetterUsed, 0, sizeof (indexLetterUsed));
01078 
01079   // first count the number of headers
01080   ClassSDict::Iterator cli(*Doxygen::classSDict);
01081   ClassDef *cd;
01082   uint startLetter=0;
01083   int headerItems=0;
01084   for (;(cd=cli.current());++cli)
01085   {
01086     if (cd->isLinkableInProject() && cd->templateMaster()==0)
01087     {
01088       int index = getPrefixIndex(cd->className());
01089       //printf("name=%s index=%d\n",cd->className().data(),index);
01090       startLetter=toupper(cd->className().at(index));
01091       indexLetterUsed[startLetter] = true;
01092     }
01093   }
01094 
01095   QCString alphaLinks = "<p><div class=\"qindex\">";
01096   int l;
01097   for (l = 0; l < 256; l++)
01098   {
01099     if (indexLetterUsed[l])
01100     {
01101       if (headerItems) alphaLinks += "&nbsp;|&nbsp;";
01102       headerItems++;
01103       alphaLinks += (QCString)"<a class=\"qindex\" href=\"#letter_" + 
01104                     (char)l + "\">" + 
01105                     (char)l + "</a>";
01106     }
01107   }
01108 
01109   alphaLinks += "</div><p>\n";
01110   ol.writeString(alphaLinks);
01111 
01112   ol.writeString("<table align=\"center\" width=\"95%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n");
01113 
01114   // the number of columns in the table
01115   const int columns = Config_getInt("COLS_IN_ALPHA_INDEX");
01116 
01117   int i,j;
01118   int totalItems = headerItems + annotatedClasses;            // number of items in the table
01119   int rows = (totalItems + columns - 1)/columns;              // number of rows in the table
01120   int itemsInLastRow = (totalItems + columns -1)%columns + 1; // number of items in the last row
01121 
01122   //printf("headerItems=%d totalItems=%d columns=%d rows=%d itemsInLastRow=%d\n",
01123   //    headerItems,totalItems,columns,rows,itemsInLastRow);
01124 
01125   // Keep a list of classes for each starting letter
01126   PrefixIgnoreClassList classesByLetter[256];
01127 
01128   // fill the columns with the class list (row elements in each column,
01129   // expect for the columns with number >= itemsInLastRow, which get on
01130   // item less.
01131   //int icount=0;
01132   startLetter=0;
01133   for (cli.toFirst();(cd=cli.current());++cli)
01134   {
01135     if (cd->isLinkableInProject() && cd->templateMaster()==0)
01136     {
01137       int index = getPrefixIndex(cd->className());
01138       startLetter=toupper(cd->className().at(index));
01139       // Do some sorting again, since the classes are sorted by name with 
01140       // prefix, which should be ignored really.
01141       classesByLetter[startLetter].inSort (cd);
01142     }
01143   }
01144 
01145   // create one class list for each column 
01146   ClassList *colList = new ClassList[columns];
01147 
01148   // fill the columns with the class list (row elements in each column,
01149   // expect for the columns with number >= itemsInLastRow, which get on
01150   // item less.
01151   int col=0,row=0;
01152   //int icount=0;
01153   startLetter=0;
01154   for (l = 0; l < 256; l++)
01155   {
01156     if (!indexLetterUsed[l]) continue;
01157 
01158     // insert a new header using a dummy class pointer.
01159     colList[col].append((ClassDef *)8); // insert dummy for the header
01160     row++;
01161     if ( row >= rows + ((col<itemsInLastRow) ? 0 : -1)) 
01162     { 
01163       // if the header is the last item in the row, we add an extra
01164       // row to make it easier to find the text of the header (this
01165       // is then contained in the next cell)
01166       colList[col].append(classesByLetter[l].at (0)); 
01167       col++; 
01168       row=0; 
01169     }
01170     uint i;
01171     for (i = 0; i < classesByLetter[l].count(); i++)
01172     {
01173       // add the class definition to the correct column list
01174       colList[col].append (classesByLetter[l].at (i));
01175       row++;
01176       if ( row >= rows + ((col<itemsInLastRow) ? 0 : -1)) { col++; row=0; }
01177     }
01178   }
01179 
01180   // create iterators for each column
01181   ClassListIterator **colIterators = new ClassListIterator*[columns];
01182   for (i=0;i<columns;i++)
01183   {
01184     colIterators[i] = new ClassListIterator(colList[i]);
01185   }
01186 
01187   // generate table
01188   for (i=0;i<rows;i++) // foreach table row
01189   {
01190     //ol.nextTableRow();
01191     ol.writeString("<tr>");
01192     // the last column may contain less items then the others
01193     int colsInRow = (i<rows-1) ? columns : itemsInLastRow; 
01194     //printf("row [%d]\n",i);
01195     for (j=0;j<colsInRow;j++) // foreach table column
01196     {
01197       ol.writeString("<td>");
01198       ClassDef *cd = colIterators[j]->current();
01199       //printf("columns [%d] cd=%p\n",j,cd);
01200       if (cd==(ClassDef *)8) // the class pointer is really a header
01201       {
01202         cd=++(*colIterators[j]); // get the next item
01203         if (cd)
01204         {
01205           //printf("head ClassDef=%p %s\n",cd,cd ? cd->name().data() : "<none>");
01206           int index = getPrefixIndex(cd->className());
01207           startLetter=toupper(cd->className().at(index));
01208           char s[2]; s[0]=startLetter; s[1]=0;
01209           //ol.writeIndexHeading(s);
01210           ol.writeString("<a name=\"letter_");
01211           ol.writeString(s);
01212           ol.writeString("\"></a>");
01213           ol.writeString("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">"
01214                            "<tr>"
01215                              "<td><div class=\"ah\">&nbsp;&nbsp;"); 
01216           ol.writeString(s);
01217           ol.writeString(         "&nbsp;&nbsp;</div>"
01218                              "</td>"
01219                            "</tr>"
01220                          "</table>\n");
01221 
01222         }
01223       }
01224       else if (cd) // a real class, insert a link
01225       {
01226         QCString namesp,cname;
01227         //if (cd->getNamespaceDef()) namesp=cd->getNamespaceDef()->displayName();
01228         //QCString cname=cd->className();
01229         extractNamespaceName(cd->name(),cname,namesp);
01230         QCString nsDispName;
01231         if (Config_getBool("OPTIMIZE_OUTPUT_JAVA"))
01232         {
01233           nsDispName=substitute(namesp,"::",".");
01234         }
01235         else
01236         {
01237           nsDispName=namesp.copy();
01238         }
01239 
01240         ol.writeObjectLink(cd->getReference(),
01241                            cd->getOutputFileBase(),0,cname);
01242         if (!namesp.isEmpty())
01243         {
01244           ol.docify(" (");
01245           NamespaceDef *nd = getResolvedNamespace(namesp);
01246           if (nd && nd->isLinkable())
01247           {
01248             ol.writeObjectLink(nd->getReference(),
01249                            nd->getOutputFileBase(),0,nsDispName);
01250           }
01251           else
01252           {
01253             ol.docify(nsDispName);
01254           }
01255           ol.docify(")");
01256         }
01257         ol.writeNonBreakableSpace(3);
01258         //printf("item ClassDef=%p %s\n",cd,cd ? cd->name().data() : "<none>");
01259         ++(*colIterators[j]);
01260       }
01261       //ol.endTableColumn();
01262       ol.writeString("</td>");
01263       //if (j<colsInRow-1) ol.nextTableColumn();
01264     }
01265     //ol.endTableRow();
01266     ol.writeString("</tr>");
01267   }
01268   //ol.endAlphabeticalIndexList();
01269   ol.writeString("</table>");
01270   
01271   ol.writeString(alphaLinks);
01272 
01273   // release the temporary memory
01274   for (i=0;i<columns;i++)
01275   {
01276     delete colIterators[i];
01277   }
01278   delete[] colIterators;
01279   delete[] colList;
01280 }
01281 
01282 //----------------------------------------------------------------------------
01283 
01284 void writeAlphabeticalIndex(OutputList &ol)
01285 {
01286   bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
01287   bool vhdlOpt    = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
01288   if (annotatedClasses==0) return;
01289   ol.pushGeneratorState();
01290   ol.disableAllBut(OutputGenerator::Html);
01291   startFile(ol,"classes"+Doxygen::htmlFileExtension,0,theTranslator->trAlphabeticalList().data(),HLI_Classes); 
01292   startTitle(ol,0);
01293   ol.parseText(/*Config_getString("PROJECT_NAME")+" "+*/
01294                (fortranOpt ? theTranslator->trCompoundIndexFortran() :
01295                 vhdlOpt    ? VhdlDocGen::trDesignUnitIndex()             :
01296                              theTranslator->trCompoundIndex()
01297                ));
01298   endTitle(ol,0,0);
01299   writeAlphabeticalClassList(ol);
01300   endFile(ol);
01301   ol.popGeneratorState();
01302 }
01303 
01304 //----------------------------------------------------------------------------
01305 
01306 void writeAnnotatedIndex(OutputList &ol)
01307 {
01308   bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
01309   bool vhdlOpt    = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
01310   if (annotatedClasses==0) return;
01311   
01312   ol.pushGeneratorState();
01313   ol.disable(OutputGenerator::Man);
01314   QCString title = fortranOpt ? theTranslator->trCompoundListFortran() :
01315                    vhdlOpt    ? VhdlDocGen::trDesignUnitList()             :
01316                                 theTranslator->trCompoundList()        ;
01317   startFile(ol,"annotated",0,title.data(),HLI_Annotated);
01318   startTitle(ol,0);
01319   QCString longTitle = title;
01320   //if (!Config_getString("PROJECT_NAME").isEmpty()) 
01321   //{
01322   //  longTitle.prepend(Config_getString("PROJECT_NAME")+" ");
01323   //}
01324   ol.parseText(longTitle);
01325   endTitle(ol,0,0);
01326   ol.startTextBlock();
01327   Doxygen::indexList.addContentsItem(TRUE,title,0,"annotated",0); 
01328   Doxygen::indexList.incContentsDepth();
01329   QCString desc = fortranOpt ? theTranslator->trCompoundListDescriptionFortran() :
01330                   vhdlOpt    ? VhdlDocGen::trDesignUnitListDescription()             :
01331                                theTranslator->trCompoundListDescription()        ;
01332   ol.parseText(desc);
01333   ol.endTextBlock();
01334   writeAnnotatedClassList(ol);
01335   Doxygen::indexList.decContentsDepth();
01336   
01337   endFile(ol);
01338   ol.popGeneratorState();
01339 }
01340 
01341 //----------------------------------------------------------------------------
01342 static void writeClassLinkForMember(OutputList &ol,MemberDef *md,const char *separator,
01343                              QCString &prevClassName)
01344 {
01345   ClassDef *cd=md->getClassDef();
01346   if ( cd && prevClassName!=cd->displayName())
01347   {
01348     ol.docify(separator);
01349     ol.writeObjectLink(md->getReference(),md->getOutputFileBase(),md->anchor(),
01350         cd->displayName());
01351     ol.writeString("\n");
01352     prevClassName = cd->displayName();
01353   }
01354 }
01355 
01356 static void writeFileLinkForMember(OutputList &ol,MemberDef *md,const char *separator,
01357                              QCString &prevFileName)
01358 {
01359   FileDef *fd=md->getFileDef();
01360   if (fd && prevFileName!=fd->name())
01361   {
01362     ol.docify(separator);
01363     ol.writeObjectLink(md->getReference(),md->getOutputFileBase(),md->anchor(),
01364         fd->name());
01365     ol.writeString("\n");
01366     prevFileName = fd->name();
01367   }
01368 }
01369 
01370 static void writeNamespaceLinkForMember(OutputList &ol,MemberDef *md,const char *separator,
01371                              QCString &prevNamespaceName)
01372 {
01373   NamespaceDef *nd=md->getNamespaceDef();
01374   if (nd && prevNamespaceName!=nd->name())
01375   {
01376     ol.docify(separator);
01377     ol.writeObjectLink(md->getReference(),md->getOutputFileBase(),md->anchor(),
01378         nd->name());
01379     ol.writeString("\n");
01380     prevNamespaceName = nd->name();
01381   }
01382 }
01383 
01384 static void writeMemberList(OutputList &ol,bool useSections,int page,
01385                             MemberIndexList memberLists[MEMBER_INDEX_ENTRIES],
01386                             DefinitionIntf::DefType type)
01387 {
01388   int pi;
01389   // page==-1 => write all member indices to one page (used when total members is small)
01390   // page!=-1 => write all member for this page only (used when total member is large)
01391   int startIndex = page==-1 ? 0                      : page;
01392   int endIndex   = page==-1 ? MEMBER_INDEX_ENTRIES-1 : page;
01393   ASSERT((int)type<3);
01394 
01395   typedef void (*writeLinkForMember_t)(OutputList &ol,MemberDef *md,const char *separator,
01396                                    QCString &prevNamespaceName);
01397 
01398   // each index tab has its own write function
01399   static writeLinkForMember_t writeLinkForMemberMap[3] = 
01400   { 
01401     &writeClassLinkForMember, 
01402     &writeFileLinkForMember,
01403     &writeNamespaceLinkForMember
01404   };
01405   QCString prevName;
01406   QCString prevDefName;
01407   bool first=TRUE;
01408   bool firstSection=TRUE;
01409   for (pi=startIndex; pi<=endIndex; pi++) // page==-1 => pi=[0..127], page!=-1 => pi=page 
01410   {
01411     MemberIndexList *ml = &memberLists[pi];
01412     if (ml->count()==0) continue;
01413     ml->sort();
01414     QListIterator<MemberDef> mli(*ml);
01415     MemberDef *md;
01416     for (mli.toFirst();(md=mli.current());++mli)
01417     {
01418       char *sep;
01419       bool isFunc=!md->isObjCMethod() && 
01420         (md->isFunction() || md->isSlot() || md->isSignal()); 
01421       QCString name=md->name();
01422       int startIndex = getPrefixIndex(name);
01423       if (QCString(name.data()+startIndex)!=prevName) // new entry
01424       {
01425         if ((prevName.isEmpty() || 
01426             tolower(name.at(startIndex))!=tolower(prevName.at(0))) && 
01427             useSections) // new section
01428         {
01429           if (!firstSection) ol.endItemList();
01430           char cs[2];
01431           cs[0]=tolower(name.at(startIndex));cs[1]='\0';
01432           QCString anchor=(QCString)"index_"+cs;
01433           QCString title=(QCString)"- "+cs+" -";
01434           ol.startSection(anchor,title,SectionInfo::Subsection);
01435           ol.docify(title);
01436           ol.endSection(anchor,SectionInfo::Subsection);
01437           ol.startItemList();
01438           firstSection=FALSE;
01439         }
01440         else if (!useSections && first)
01441         {
01442           ol.startItemList();
01443           first=FALSE;
01444         }
01445 
01446         // member name
01447         ol.writeListItem();
01448         ol.docify(name);
01449         if (isFunc) ol.docify("()");
01450         ol.writeString("\n");
01451 
01452         // link to class
01453         prevDefName="";
01454         sep = ": ";
01455         prevName = name.data()+startIndex;
01456       }
01457       else // same entry
01458       {
01459         sep = ", ";
01460         // link to class for other members with the same name
01461       }
01462       // write the link for the specific list type
01463       writeLinkForMemberMap[(int)type](ol,md,sep,prevDefName);
01464     }
01465   }
01466   ol.endItemList();
01467 }
01468 
01469 //----------------------------------------------------------------------------
01470 
01471 void initClassMemberIndices()
01472 {
01473   int i=0;
01474   int j=0;
01475   for (j=0;j<CMHL_Total;j++)
01476   {
01477     documentedClassMembers[j]=0;
01478     for (i=0;i<MEMBER_INDEX_ENTRIES;i++) 
01479     {
01480       g_memberIndexLetterUsed[j][i].clear();
01481     }
01482   }
01483 }
01484 
01485 void addClassMemberNameToIndex(MemberDef *md)
01486 {
01487   static bool hideFriendCompounds = Config_getBool("HIDE_FRIEND_COMPOUNDS");
01488   static bool vhdlOpt = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
01489   ClassDef *cd=0;
01490 
01491   if (md->isLinkableInProject() && 
01492       (cd=md->getClassDef())    && 
01493       cd->isLinkableInProject() &&
01494       cd->templateMaster()==0)
01495   {
01496     if (vhdlOpt && (VhdlDocGen::isRecord(md) || VhdlDocGen::isUnit(md)))
01497     {
01498       VhdlDocGen::adjustRecordMember(md);
01499     }
01500     QCString n = md->name();
01501     int index = getPrefixIndex(n);
01502     int letter = tolower(n.at(index)) & 0x7f;
01503     if (!n.isEmpty()) 
01504     {
01505       bool isFriendToHide = hideFriendCompounds &&
01506         (QCString(md->typeString())=="friend class" || 
01507          QCString(md->typeString())=="friend struct" ||
01508          QCString(md->typeString())=="friend union");
01509       if (!(md->isFriend() && isFriendToHide))
01510       {
01511         g_memberIndexLetterUsed[CMHL_All][letter].append(md);
01512         documentedClassMembers[CMHL_All]++;
01513       }
01514       if (md->isFunction()  || md->isSlot() || md->isSignal())
01515       {
01516         g_memberIndexLetterUsed[CMHL_Functions][letter].append(md);
01517         documentedClassMembers[CMHL_Functions]++;
01518       } 
01519       else if (md->isVariable())
01520       {
01521         g_memberIndexLetterUsed[CMHL_Variables][letter].append(md);
01522         documentedClassMembers[CMHL_Variables]++;
01523       }
01524       else if (md->isTypedef())
01525       {
01526         g_memberIndexLetterUsed[CMHL_Typedefs][letter].append(md);
01527         documentedClassMembers[CMHL_Typedefs]++;
01528       }
01529       else if (md->isEnumerate())
01530       {
01531         g_memberIndexLetterUsed[CMHL_Enums][letter].append(md);
01532         documentedClassMembers[CMHL_Enums]++;
01533       }
01534       else if (md->isEnumValue())
01535       {
01536         g_memberIndexLetterUsed[CMHL_EnumValues][letter].append(md);
01537         documentedClassMembers[CMHL_EnumValues]++;
01538       }
01539       else if (md->isProperty())
01540       {
01541         g_memberIndexLetterUsed[CMHL_Properties][letter].append(md);
01542         documentedClassMembers[CMHL_Properties]++;
01543       }
01544       else if (md->isEvent())
01545       {
01546         g_memberIndexLetterUsed[CMHL_Events][letter].append(md);
01547         documentedClassMembers[CMHL_Events]++;
01548       }
01549       else if (md->isRelated() || (md->isFriend() && !isFriendToHide))
01550       {
01551         g_memberIndexLetterUsed[CMHL_Related][letter].append(md);
01552         documentedClassMembers[CMHL_Related]++;
01553       }
01554     }
01555   }
01556 }
01557 
01558 //----------------------------------------------------------------------------
01559 
01560 void initNamespaceMemberIndices()
01561 {
01562   int i=0;
01563   int j=0;
01564   for (j=0;j<NMHL_Total;j++)
01565   {
01566     documentedNamespaceMembers[j]=0;
01567     for (i=0;i<MEMBER_INDEX_ENTRIES;i++) 
01568     {
01569       g_namespaceIndexLetterUsed[j][i].clear();
01570     }
01571   }
01572 }
01573 
01574 void addNamespaceMemberNameToIndex(MemberDef *md)
01575 {
01576   NamespaceDef *nd=md->getNamespaceDef();
01577   if (nd && nd->isLinkableInProject() && md->isLinkableInProject())
01578   {
01579     QCString n = md->name();
01580     int index = getPrefixIndex(n);
01581     int letter = tolower(n.at(index));
01582     if (!n.isEmpty()) 
01583     {
01584       g_namespaceIndexLetterUsed[NMHL_All][letter].append(md);
01585       documentedNamespaceMembers[NMHL_All]++;
01586 
01587       if (md->isFunction()) 
01588       {
01589         g_namespaceIndexLetterUsed[NMHL_Functions][letter].append(md);
01590         documentedNamespaceMembers[NMHL_Functions]++;
01591       }
01592       else if (md->isVariable()) 
01593       {
01594         g_namespaceIndexLetterUsed[NMHL_Variables][letter].append(md);
01595         documentedNamespaceMembers[NMHL_Variables]++;
01596       }
01597       else if (md->isTypedef())
01598       {
01599         g_namespaceIndexLetterUsed[NMHL_Typedefs][letter].append(md);
01600         documentedNamespaceMembers[NMHL_Typedefs]++;
01601       }
01602       else if (md->isEnumerate())
01603       {
01604         g_namespaceIndexLetterUsed[NMHL_Enums][letter].append(md);
01605         documentedNamespaceMembers[NMHL_Enums]++;
01606       }
01607       else if (md->isEnumValue())
01608       {
01609         g_namespaceIndexLetterUsed[NMHL_EnumValues][letter].append(md);
01610         documentedNamespaceMembers[NMHL_EnumValues]++;
01611       }
01612     }
01613   }
01614 }
01615 
01616 //----------------------------------------------------------------------------
01617 
01618 void initFileMemberIndices()
01619 {
01620   int i=0;
01621   int j=0;
01622   for (j=0;j<NMHL_Total;j++)
01623   {
01624     documentedFileMembers[j]=0;
01625     for (i=0;i<MEMBER_INDEX_ENTRIES;i++) 
01626     {
01627       g_fileIndexLetterUsed[j][i].clear();
01628     }
01629   }
01630 }
01631 
01632 void addFileMemberNameToIndex(MemberDef *md)
01633 {
01634   FileDef *fd=md->getFileDef();
01635   if (fd && fd->isLinkableInProject() && md->isLinkableInProject())
01636   {
01637     QCString n = md->name();
01638     int index = getPrefixIndex(n);
01639     int letter = tolower(n.at(index));
01640     if (!n.isEmpty()) 
01641     {
01642       g_fileIndexLetterUsed[FMHL_All][letter].append(md);
01643       documentedFileMembers[FMHL_All]++;
01644 
01645       if (md->isFunction()) 
01646       {
01647         g_fileIndexLetterUsed[FMHL_Functions][letter].append(md);
01648         documentedFileMembers[FMHL_Functions]++;
01649       }
01650       else if (md->isVariable()) 
01651       {
01652         g_fileIndexLetterUsed[FMHL_Variables][letter].append(md);
01653         documentedFileMembers[FMHL_Variables]++;
01654       }
01655       else if (md->isTypedef())
01656       {
01657         g_fileIndexLetterUsed[FMHL_Typedefs][letter].append(md);
01658         documentedFileMembers[FMHL_Typedefs]++;
01659       }
01660       else if (md->isEnumerate())
01661       {
01662         g_fileIndexLetterUsed[FMHL_Enums][letter].append(md);
01663         documentedFileMembers[FMHL_Enums]++;
01664       }
01665       else if (md->isEnumValue())
01666       {
01667         g_fileIndexLetterUsed[FMHL_EnumValues][letter].append(md);
01668         documentedFileMembers[FMHL_EnumValues]++;
01669       }
01670       else if (md->isDefine())
01671       {
01672         g_fileIndexLetterUsed[FMHL_Defines][letter].append(md);
01673         documentedFileMembers[FMHL_Defines]++;
01674       }
01675     }
01676   }
01677 }
01678 
01679 //----------------------------------------------------------------------------
01680 
01681 void writeQuickMemberIndex(OutputList &ol,
01682     MemberIndexList charUsed[MEMBER_INDEX_ENTRIES],int page,
01683     QCString fullName,bool multiPage)
01684 {
01685   bool first=TRUE;
01686   int i;
01687   startQuickIndexList(ol);
01688   for (i=33;i<127;i++)
01689   {
01690     char is[2];is[0]=(char)i;is[1]='\0';
01691     if (charUsed[i].count()>0)
01692     {
01693       QCString anchor;
01694       QCString extension=Doxygen::htmlFileExtension;
01695       if (!multiPage)
01696         anchor="#index_";
01697       else if (first) 
01698         anchor=fullName+extension+"#index_";
01699       else 
01700         anchor=fullName+QCString().sprintf("_0x%02x",i)+extension+"#index_";
01701       startQuickIndexItem(ol,anchor+is,i==page,TRUE,first);
01702       ol.writeString(is);
01703       endQuickIndexItem(ol);
01704       first=FALSE;
01705     }
01706   }
01707   endQuickIndexList(ol);
01708   ol.newParagraph();
01709 }
01710 
01711 //----------------------------------------------------------------------------
01712 
01713 static void writeClassMemberIndexFiltered(OutputList &ol, ClassMemberHighlight hl)
01714 {
01715   if (documentedClassMembers[hl]==0) return;
01716   
01717   static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
01718   static bool vhdlOpt    = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
01719 
01720   bool multiPageIndex=FALSE;
01721   int numPages=1;
01722   if (documentedClassMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX)
01723   {
01724     multiPageIndex=TRUE;
01725     numPages=127;
01726   }
01727 
01728   struct CmhlInfo
01729   {
01730     CmhlInfo(const char *fn,const char *t) : fname(fn), title(t) {}
01731     const char *fname;
01732     QCString title;
01733   } cmhlInfo[] = 
01734   {
01735     CmhlInfo("functions",     theTranslator->trAll()),
01736     CmhlInfo("functions_func",
01737         fortranOpt ? theTranslator->trSubprograms() : 
01738         vhdlOpt    ? VhdlDocGen::trFunctionAndProc() :
01739                      theTranslator->trFunctions()),
01740     CmhlInfo("functions_vars",theTranslator->trVariables()),
01741     CmhlInfo("functions_type",theTranslator->trTypedefs()),
01742     CmhlInfo("functions_enum",theTranslator->trEnumerations()),
01743     CmhlInfo("functions_eval",theTranslator->trEnumerationValues()),
01744     CmhlInfo("functions_prop",theTranslator->trProperties()),
01745     CmhlInfo("functions_evnt",theTranslator->trEvents()),
01746     CmhlInfo("functions_rela",theTranslator->trRelatedFunctions())
01747   };
01748 
01749   ol.pushGeneratorState();
01750   ol.disableAllBut(OutputGenerator::Html);
01751 
01752   QCString extension=Doxygen::htmlFileExtension;
01753   QCString title = fortranOpt ? theTranslator->trCompoundMembersFortran() : 
01754                    vhdlOpt    ? VhdlDocGen::trDesignUnitMembers()             : 
01755                                 theTranslator->trCompoundMembers()        ;
01756   if (hl!=CMHL_All) title+=(QCString)" - "+cmhlInfo[hl].title;
01757 
01758   int page;
01759   bool first=TRUE;
01760   for (page=0;page<numPages;page++)
01761   {
01762     if (!multiPageIndex || g_memberIndexLetterUsed[hl][page].count()>0)
01763     {
01764       QCString fileName = cmhlInfo[hl].fname;
01765       if (multiPageIndex && !first)
01766       { 
01767         fileName+=QCString().sprintf("_0x%02x",page);
01768       }
01769       
01770       startFile(ol,fileName+extension,0,title,HLI_Functions,TRUE);
01771 
01772       startQuickIndexList(ol);
01773 
01774       // index item for global member list
01775       startQuickIndexItem(ol,
01776           cmhlInfo[0].fname+Doxygen::htmlFileExtension,hl==CMHL_All,TRUE,first);
01777       ol.writeString(fixSpaces(cmhlInfo[0].title));
01778       endQuickIndexItem(ol);
01779 
01780       // index items per category member lists
01781       int i;
01782       for (i=1;i<CMHL_Total;i++)
01783       {
01784         if (documentedClassMembers[i]>0)
01785         {
01786           startQuickIndexItem(ol,cmhlInfo[i].fname+Doxygen::htmlFileExtension,hl==i,TRUE,first);
01787           ol.writeString(fixSpaces(cmhlInfo[i].title));
01788           //printf("multiPageIndex=%d first=%d fileName=%s file=%s title=%s\n",
01789           //    multiPageIndex,first,fileName.data(),cmhlInfo[i].fname,cmhlInfo[i].title.data());
01790           endQuickIndexItem(ol);
01791         }
01792       }
01793 
01794       endQuickIndexList(ol);
01795 
01796       // quick alphabetical index
01797       bool quickIndex = documentedClassMembers[hl]>maxItemsBeforeQuickIndex;
01798       if (quickIndex)
01799       {
01800         writeQuickMemberIndex(ol,g_memberIndexLetterUsed[hl],page,
01801                               cmhlInfo[hl].fname,multiPageIndex);
01802       }
01803 
01804       ol.endQuickIndices();
01805       ol.startContents();
01806 
01807       if (hl==CMHL_All)
01808       {
01809         static bool extractAll = Config_getBool("EXTRACT_ALL");
01810         ol.parseText(fortranOpt ?  theTranslator->trCompoundMembersDescriptionFortran(extractAll) : 
01811                                    theTranslator->trCompoundMembersDescription(extractAll));
01812       }
01813       else
01814       {
01815         // hack to work around a mozilla bug, which refuses to switch to
01816         // normal lists otherwise
01817         ol.writeString("&nbsp;");
01818       }
01819       ol.newParagraph();
01820       writeMemberList(ol,quickIndex,
01821                       multiPageIndex?page:-1,
01822                       g_memberIndexLetterUsed[hl],
01823                       Definition::TypeClass);
01824       endFile(ol);
01825       first=FALSE;
01826     }
01827   }
01828   
01829   ol.popGeneratorState();
01830 }
01831 
01832 void writeClassMemberIndex(OutputList &ol)
01833 {
01834   bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
01835   writeClassMemberIndexFiltered(ol,CMHL_All);
01836   writeClassMemberIndexFiltered(ol,CMHL_Functions);
01837   writeClassMemberIndexFiltered(ol,CMHL_Variables);
01838   writeClassMemberIndexFiltered(ol,CMHL_Typedefs);
01839   writeClassMemberIndexFiltered(ol,CMHL_Enums);
01840   writeClassMemberIndexFiltered(ol,CMHL_EnumValues);
01841   writeClassMemberIndexFiltered(ol,CMHL_Properties);
01842   writeClassMemberIndexFiltered(ol,CMHL_Events);
01843   writeClassMemberIndexFiltered(ol,CMHL_Related);
01844 
01845   if (documentedClassMembers[CMHL_All]>0)
01846   {
01847     QCString title = fortranOpt?theTranslator->trCompoundMembersFortran():theTranslator->trCompoundMembers();
01848     Doxygen::indexList.addContentsItem(FALSE,title,0,"functions",0); 
01849   }
01850 }
01851 
01852 //----------------------------------------------------------------------------
01853 
01854 static void writeFileMemberIndexFiltered(OutputList &ol, FileMemberHighlight hl)
01855 {
01856   if (documentedFileMembers[hl]==0) return;
01857 
01858   bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
01859   bool vhdlOpt    = Config_getBool("OPTIMIZE_OUTPUT_VHDL");  
01860   bool multiPageIndex=FALSE;
01861   int numPages=1;
01862   if (documentedFileMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX)
01863   {
01864     multiPageIndex=TRUE;
01865     numPages=127;
01866   }
01867 
01868   struct FmhlInfo 
01869   {
01870     FmhlInfo(const char *fn,const char *t) : fname(fn), title(t) {}
01871     const char *fname;
01872     QCString title;
01873   } fmhlInfo[] = 
01874   {
01875     FmhlInfo("globals",     theTranslator->trAll()),
01876     FmhlInfo("globals_func",
01877          fortranOpt ? theTranslator->trSubprograms()  : 
01878          vhdlOpt    ? VhdlDocGen::trFunctionAndProc() : 
01879                       theTranslator->trFunctions()),
01880     FmhlInfo("globals_vars",theTranslator->trVariables()),
01881     FmhlInfo("globals_type",theTranslator->trTypedefs()),
01882     FmhlInfo("globals_enum",theTranslator->trEnumerations()),
01883     FmhlInfo("globals_eval",theTranslator->trEnumerationValues()),
01884     FmhlInfo("globals_defs",theTranslator->trDefines())
01885   };
01886 
01887   ol.pushGeneratorState();
01888   ol.disableAllBut(OutputGenerator::Html);
01889 
01890   QCString extension=Doxygen::htmlFileExtension;
01891   QCString title = fortranOpt?theTranslator->trCompoundMembersFortran():theTranslator->trCompoundMembers();
01892 
01893   int page;
01894   bool first=TRUE;
01895   for (page=0;page<numPages;page++)
01896   {
01897     if (!multiPageIndex || g_fileIndexLetterUsed[hl][page].count()>0)
01898     {
01899       QCString fileName = fmhlInfo[hl].fname;
01900       if (multiPageIndex && !first)
01901       {
01902         fileName+=QCString().sprintf("_0x%02x",page);
01903       }
01904       
01905       startFile(ol,fileName+extension,0,title.data(),HLI_Globals,TRUE);
01906 
01907       startQuickIndexList(ol);
01908 
01909       // index item for all member lists
01910       startQuickIndexItem(ol,
01911           fmhlInfo[0].fname+Doxygen::htmlFileExtension,hl==FMHL_All,TRUE,first);
01912       ol.writeString(fixSpaces(fmhlInfo[0].title));
01913       endQuickIndexItem(ol);
01914 
01915       int i;
01916       // index items for per category member lists
01917       for (i=1;i<FMHL_Total;i++)
01918       {
01919         if (documentedFileMembers[i]>0)
01920         {
01921           startQuickIndexItem(ol,
01922               fmhlInfo[i].fname+Doxygen::htmlFileExtension,hl==i,TRUE,first);
01923           ol.writeString(fixSpaces(fmhlInfo[i].title));
01924           endQuickIndexItem(ol);
01925         }
01926       }
01927 
01928       endQuickIndexList(ol);
01929 
01930       bool quickIndex = documentedFileMembers[hl]>maxItemsBeforeQuickIndex;
01931       if (quickIndex)
01932       {
01933         writeQuickMemberIndex(ol,g_fileIndexLetterUsed[hl],page,
01934                   fmhlInfo[hl].fname,multiPageIndex);
01935       }
01936 
01937       ol.endQuickIndices();
01938       ol.startContents();
01939 
01940       if (hl==FMHL_All)
01941       {
01942         ol.parseText(theTranslator->trFileMembersDescription(Config_getBool("EXTRACT_ALL")));
01943       }
01944       else
01945       {
01946         // hack to work around a mozilla bug, which refuses to switch to
01947         // normal lists otherwise
01948         ol.writeString("&nbsp;");
01949       }
01950       ol.newParagraph();
01951       //writeFileMemberList(ol,quickIndex,hl,page);
01952       writeMemberList(ol,quickIndex,
01953                       multiPageIndex?page:-1,
01954                       g_fileIndexLetterUsed[hl],
01955                       Definition::TypeFile);
01956       endFile(ol);
01957       first=FALSE;
01958     }
01959   }
01960   ol.popGeneratorState();
01961 }
01962 
01963 void writeFileMemberIndex(OutputList &ol)
01964 {
01965   writeFileMemberIndexFiltered(ol,FMHL_All);
01966   writeFileMemberIndexFiltered(ol,FMHL_Functions);
01967   writeFileMemberIndexFiltered(ol,FMHL_Variables);
01968   writeFileMemberIndexFiltered(ol,FMHL_Typedefs);
01969   writeFileMemberIndexFiltered(ol,FMHL_Enums);
01970   writeFileMemberIndexFiltered(ol,FMHL_EnumValues);
01971   writeFileMemberIndexFiltered(ol,FMHL_Defines);
01972 
01973   if (documentedFileMembers[FMHL_All]>0)
01974   {
01975     QCString title = theTranslator->trFileMembers();
01976     Doxygen::indexList.addContentsItem(FALSE,title,0,"globals",0); 
01977   }
01978 }
01979 
01980 
01981 //----------------------------------------------------------------------------
01982 
01983 static void writeNamespaceMemberIndexFiltered(OutputList &ol,
01984                                         NamespaceMemberHighlight hl)
01985 {
01986   if (documentedNamespaceMembers[hl]==0) return;
01987 
01988   bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
01989   bool vhdlOpt    = Config_getBool("OPTIMIZE_OUTPUT_VHDL");  
01990 
01991   bool multiPageIndex=FALSE;
01992   int numPages=1;
01993   if (documentedNamespaceMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX)
01994   {
01995     multiPageIndex=TRUE;
01996     numPages=127;
01997   }
01998 
01999   struct NmhlInfo
02000   {
02001     NmhlInfo(const char *fn,const char *t) : fname(fn), title(t) {}
02002     const char *fname;
02003     QCString title;
02004   } nmhlInfo[] = 
02005   {
02006     NmhlInfo("namespacemembers",     theTranslator->trAll()),
02007     NmhlInfo("namespacemembers_func",
02008         fortranOpt ? theTranslator->trSubprograms()  :
02009         vhdlOpt    ? VhdlDocGen::trFunctionAndProc() :
02010                      theTranslator->trFunctions()),
02011     NmhlInfo("namespacemembers_vars",theTranslator->trVariables()),
02012     NmhlInfo("namespacemembers_type",theTranslator->trTypedefs()),
02013     NmhlInfo("namespacemembers_enum",theTranslator->trEnumerations()),
02014     NmhlInfo("namespacemembers_eval",theTranslator->trEnumerationValues())
02015   };
02016 
02017   ol.pushGeneratorState();
02018   ol.disableAllBut(OutputGenerator::Html);
02019 
02020   QCString extension=Doxygen::htmlFileExtension;
02021   QCString title = fortranOpt?theTranslator->trCompoundMembersFortran():theTranslator->trCompoundMembers();
02022 
02023   int page;
02024   bool first=TRUE;
02025   for (page=0;page<numPages;page++)
02026   {
02027     if (!multiPageIndex || g_namespaceIndexLetterUsed[hl][page].count()>0)
02028     {
02029       QCString fileName = nmhlInfo[hl].fname;
02030       if (multiPageIndex && !first)
02031       {
02032         fileName+=QCString().sprintf("_0x%02x",page);
02033       }
02034       
02035       startFile(ol,fileName+extension,0,title,HLI_NamespaceMembers,TRUE);
02036 
02037       startQuickIndexList(ol);
02038 
02039       startQuickIndexItem(ol,
02040           nmhlInfo[0].fname+Doxygen::htmlFileExtension,hl==NMHL_All,TRUE,first);
02041       ol.writeString(fixSpaces(nmhlInfo[0].title));
02042       endQuickIndexItem(ol);
02043 
02044       int i;
02045       for (i=1;i<NMHL_Total;i++)
02046       {
02047         if (documentedNamespaceMembers[i]>0)
02048         {
02049           startQuickIndexItem(ol,
02050               nmhlInfo[i].fname+Doxygen::htmlFileExtension,hl==i,TRUE,first);
02051           ol.writeString(fixSpaces(nmhlInfo[i].title));
02052           endQuickIndexItem(ol);
02053         }
02054       }
02055 
02056       endQuickIndexList(ol);
02057 
02058       bool quickIndex = documentedNamespaceMembers[hl]>maxItemsBeforeQuickIndex;
02059       if (quickIndex)
02060       {
02061         writeQuickMemberIndex(ol,g_namespaceIndexLetterUsed[hl],page,
02062               nmhlInfo[hl].fname,multiPageIndex);
02063       }
02064 
02065       ol.endQuickIndices();
02066       ol.startContents();
02067 
02068       if (hl==NMHL_All)
02069       {
02070         ol.parseText(fortranOpt?theTranslator->trModulesMemberDescription(Config_getBool("EXTRACT_ALL")):theTranslator->trNamespaceMemberDescription(Config_getBool("EXTRACT_ALL")));
02071       }
02072       else
02073       {
02074         // hack to work around a mozilla bug, which refuses to switch to
02075         // normal lists otherwise
02076         ol.writeString("&nbsp;");
02077       }
02078       ol.newParagraph();
02079 
02080       //writeNamespaceMemberList(ol,quickIndex,hl,page);
02081       writeMemberList(ol,quickIndex,
02082                       multiPageIndex?page:-1,
02083                       g_namespaceIndexLetterUsed[hl],
02084                       Definition::TypeNamespace);
02085       endFile(ol);
02086     }
02087   }
02088   ol.popGeneratorState();
02089 }
02090 
02091 void writeNamespaceMemberIndex(OutputList &ol)
02092 {
02093   bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
02094   writeNamespaceMemberIndexFiltered(ol,NMHL_All);
02095   writeNamespaceMemberIndexFiltered(ol,NMHL_Functions);
02096   writeNamespaceMemberIndexFiltered(ol,NMHL_Variables);
02097   writeNamespaceMemberIndexFiltered(ol,NMHL_Typedefs);
02098   writeNamespaceMemberIndexFiltered(ol,NMHL_Enums);
02099   writeNamespaceMemberIndexFiltered(ol,NMHL_EnumValues);
02100 
02101   if (documentedNamespaceMembers[NMHL_All]>0)
02102   {
02103     QCString title = fortranOpt?theTranslator->trModulesMembers():theTranslator->trNamespaceMembers();
02104     Doxygen::indexList.addContentsItem(FALSE,title,0,"namespacemembers",0); 
02105   }
02106 }
02107 
02108 //----------------------------------------------------------------------------
02109 
02110 void writeExampleIndex(OutputList &ol)
02111 {
02112   if (Doxygen::exampleSDict->count()==0) return;
02113   ol.pushGeneratorState();
02114   ol.disable(OutputGenerator::Man);
02115   QCString title = theTranslator->trExamples();
02116   startFile(ol,"examples",0,title.data(),HLI_Examples);
02117   startTitle(ol,0);
02118   //if (!Config_getString("PROJECT_NAME").isEmpty()) 
02119   //{
02120   //  title.prepend(Config_getString("PROJECT_NAME")+" ");
02121   //}
02122   ol.parseText(title);
02123   endTitle(ol,0,0);
02124   ol.startTextBlock();
02125   Doxygen::indexList.addContentsItem(TRUE,theTranslator->trExamples(),0,"examples",0); 
02126   Doxygen::indexList.incContentsDepth();
02127   ol.parseText(theTranslator->trExamplesDescription());
02128   //ol.newParagraph();
02129   ol.endTextBlock();
02130   ol.startItemList();
02131   PageSDict::Iterator pdi(*Doxygen::exampleSDict);
02132   PageDef *pd=0;
02133   for (pdi.toFirst();(pd=pdi.current());++pdi)
02134   {
02135     ol.writeListItem();
02136     QCString n=pd->getOutputFileBase();
02137     if (!pd->title().isEmpty())
02138     {
02139       ol.writeObjectLink(0,n,0,pd->title());
02140       Doxygen::indexList.addContentsItem(FALSE,pd->title(),pd->getReference(),n,0);
02141     }
02142     else
02143     {
02144       ol.writeObjectLink(0,n,0,pd->name());
02145       Doxygen::indexList.addContentsItem(FALSE,pd->name(),pd->getReference(),n,0);
02146     }
02147     ol.writeString("\n");
02148   }
02149   ol.endItemList();
02150   Doxygen::indexList.decContentsDepth();
02151   endFile(ol);
02152   ol.popGeneratorState();
02153 }
02154 
02155 //----------------------------------------------------------------------------
02156 
02157 void countRelatedPages(int &docPages,int &indexPages)
02158 {
02159   docPages=indexPages=0;
02160   PageSDict::Iterator pdi(*Doxygen::pageSDict);
02161   PageDef *pd=0;
02162   for (pdi.toFirst();(pd=pdi.current());++pdi)
02163   {
02164     if ( pd->visibleInIndex())
02165     {
02166       indexPages++; 
02167     }
02168     if ( pd->documentedPage())
02169     {
02170       docPages++;
02171     }
02172   }
02173 }
02174 
02175 //----------------------------------------------------------------------------
02176 
02177 static void writeSubPages(PageDef *pd)
02178 {
02179   //printf("Write subpages(%s #=%d)\n",pd->name().data(),pd->getSubPages() ? pd->getSubPages()->count() : 0 );
02180   Doxygen::indexList.incContentsDepth();
02181 
02182   PageSDict *subPages = pd->getSubPages();
02183   if (subPages)
02184   {
02185     PageSDict::Iterator pi(*subPages);
02186     PageDef *subPage;
02187     for (pi.toFirst();(subPage=pi.current());++pi)
02188     {
02189       QCString pageTitle;
02190 
02191       if (subPage->title().isEmpty())
02192         pageTitle=subPage->name();
02193       else
02194         pageTitle=subPage->title();
02195 
02196       bool hasSubPages = subPage->hasSubPages();
02197 
02198       Doxygen::indexList.addContentsItem(hasSubPages,pageTitle,subPage->getReference(),subPage->getOutputFileBase(),0);
02199       writeSubPages(subPage);
02200     }
02201   }
02202   Doxygen::indexList.decContentsDepth();
02203 
02204 }
02205 
02206 void writePageIndex(OutputList &ol)
02207 {
02208   if (indexedPages==0) return;
02209   ol.pushGeneratorState();
02210   ol.disableAllBut(OutputGenerator::Html);
02211   startFile(ol,"pages",0,theTranslator->trPageIndex().data(),HLI_Pages);
02212   startTitle(ol,0);
02213   QCString title = theTranslator->trRelatedPages();
02214   //if (!Config_getString("PROJECT_NAME").isEmpty()) 
02215   //{
02216   //  title.prepend(Config_getString("PROJECT_NAME")+" ");
02217   //}
02218   ol.parseText(title);
02219   endTitle(ol,0,0);
02220   ol.startTextBlock();
02221   //Doxygen::indexList.addContentsItem(TRUE,theTranslator->trRelatedPages(),0,"pages",0); 
02222   //Doxygen::indexList.incContentsDepth();
02223   ol.parseText(theTranslator->trRelatedPagesDescription());
02224   ol.endTextBlock();
02225   startIndexHierarchy(ol,0);
02226   PageSDict::Iterator pdi(*Doxygen::pageSDict);
02227   PageDef *pd=0;
02228   for (pdi.toFirst();(pd=pdi.current());++pdi)
02229   {
02230     if ( pd->visibleInIndex())
02231     {
02232       QCString pageTitle;
02233 
02234       if (pd->title().isEmpty())
02235         pageTitle=pd->name();
02236       else
02237         pageTitle=pd->title();
02238 
02239       bool hasSubPages = pd->hasSubPages();
02240 
02241       ol.startIndexItem(pd->getReference(),pd->getOutputFileBase());
02242       ol.parseText(pageTitle);
02243       ol.endIndexItem(pd->getReference(),pd->getOutputFileBase());
02244       if (pd->isReference()) 
02245       { 
02246         ol.startTypewriter(); 
02247         ol.docify(" [external]");
02248         ol.endTypewriter();
02249       }
02250       ol.writeString("\n");
02251       Doxygen::indexList.addContentsItem(hasSubPages,pageTitle,pd->getReference(),pd->getOutputFileBase(),0);
02252       writeSubPages(pd);
02253     }
02254   }
02255   endIndexHierarchy(ol,0);
02256   //Doxygen::indexList.decContentsDepth();
02257   endFile(ol);
02258   ol.popGeneratorState();
02259 }
02260 
02261 //----------------------------------------------------------------------------
02262 
02263 int countGroups()
02264 {
02265   int count=0;
02266   GroupSDict::Iterator gli(*Doxygen::groupSDict);
02267   GroupDef *gd;
02268   for (gli.toFirst();(gd=gli.current());++gli)
02269   {
02270     if (!gd->isReference())
02271     {
02272       gd->visited=FALSE;
02273       count++;
02274     }
02275   }
02276   return count;
02277 }
02278 
02279 //----------------------------------------------------------------------------
02280 
02281 int countDirs()
02282 {
02283   int count=0;
02284   SDict<DirDef>::Iterator dli(*Doxygen::directories);
02285   DirDef *dd;
02286   for (dli.toFirst();(dd=dli.current());++dli)
02287   {
02288     if (dd->isLinkableInProject())
02289     {
02290       dd->visited=FALSE;
02291       count++;
02292     }
02293   }
02294   return count;
02295 }
02296 
02297 
02298 //----------------------------------------------------------------------------
02299 
02300 void writeGraphInfo(OutputList &ol)
02301 {
02302   if (!Config_getBool("HAVE_DOT") || !Config_getBool("GENERATE_HTML")) return;
02303   ol.pushGeneratorState();
02304   ol.disableAllBut(OutputGenerator::Html);
02305   generateGraphLegend(Config_getString("HTML_OUTPUT"));
02306   startFile(ol,"graph_legend",0,theTranslator->trLegendTitle().data());
02307   startTitle(ol,0);
02308   ol.parseText(theTranslator->trLegendTitle());
02309   endTitle(ol,0,0);
02310   bool oldStripCommentsState = Config_getBool("STRIP_CODE_COMMENTS");
02311   // temporarily disable the stripping of comments for our own code example!
02312   Config_getBool("STRIP_CODE_COMMENTS") = FALSE;
02313   ol.parseDoc("graph_legend",1,0,0,theTranslator->trLegendDocs(),FALSE,FALSE);
02314   Config_getBool("STRIP_CODE_COMMENTS") = oldStripCommentsState;
02315   endFile(ol);
02316   ol.popGeneratorState();
02317 }
02318 
02319 void writeGroupIndexItem(GroupDef *gd,MemberList *ml,const QCString &title)
02320 {
02321   if (ml && ml->count()>0)
02322   {
02323     bool first=TRUE;
02324     MemberDef *md=ml->first();
02325     while (md)
02326     {
02327       if (md->isDetailedSectionVisible(TRUE,FALSE))
02328       {
02329         if (first)
02330         {
02331           first=FALSE;
02332           Doxygen::indexList.addContentsItem(TRUE, convertToHtml(title,TRUE), gd->getReference(), gd->getOutputFileBase(), 0);
02333           Doxygen::indexList.incContentsDepth();
02334         }
02335         Doxygen::indexList.addContentsItem(FALSE,md->name(),md->getReference(),md->getOutputFileBase(),md->anchor()); 
02336       }
02337       md=ml->next();
02338     }
02339 
02340     if (!first)
02341     {
02342       Doxygen::indexList.decContentsDepth();
02343     }
02344   }
02345 }
02346 
02347 //----------------------------------------------------------------------------
02352 void writeGroupTreeNode(OutputList &ol, GroupDef *gd,int level)
02353 {
02354   bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
02355   bool vhdlOpt    = Config_getBool("OPTIMIZE_OUTPUT_VHDL");  
02356   if (level>20)
02357   {
02358     warn(gd->getDefFileName(),gd->getDefLine(),
02359         "Warning: maximum nesting level exceeded for group %s: check for possible recursive group relation!\n",gd->name().data()
02360         );
02361     return;
02362   }
02363 
02364   /* Some groups should appear twice under different parent-groups.
02365    * That is why we should not check if it was visited 
02366    */
02367   if ( (!gd->isASubGroup() || level>0) &&
02368       (!gd->isReference() || Config_getBool("EXTERNAL_GROUPS")) // hide external groups by default
02369      )
02370   {
02371     //printf("gd->name()=%s #members=%d\n",gd->name().data(),gd->countMembers());
02372     // write group info
02373     bool hasSubGroups = gd->groupList->count()>0;
02374     bool hasSubPages = gd->pageDict->count()>0;
02375     int numSubItems = 0;
02376     if ( Config_getBool("TOC_EXPAND"))
02377     {
02378       QListIterator<MemberList> mli(gd->getMemberLists());
02379       MemberList *ml;
02380       for (mli.toFirst();(ml=mli.current());++mli)
02381       {
02382         if (ml->listType()&MemberList::documentationLists)
02383         {
02384           numSubItems += ml->count();
02385         }
02386       }
02387       numSubItems += gd->namespaceSDict->count();
02388       numSubItems += gd->classSDict->count();
02389       numSubItems += gd->fileList->count();
02390       numSubItems += gd->exampleDict->count();
02391     }
02392 
02393     bool isDir = hasSubGroups || hasSubPages || numSubItems>0;
02394     //printf("gd=`%s': pageDict=%d\n",gd->name().data(),gd->pageDict->count());
02395     Doxygen::indexList.addContentsItem(isDir,gd->groupTitle(),gd->getReference(),gd->getOutputFileBase(),0); 
02396     Doxygen::indexList.incContentsDepth();
02397 
02398     //ol.writeListItem();
02399     //ol.startTextLink(gd->getOutputFileBase(),0);
02400     //parseText(ol,gd->groupTitle());
02401     //ol.endTextLink();
02402     
02403     ol.startIndexItem(gd->getReference(),gd->getOutputFileBase());
02404     ol.parseText(gd->groupTitle());
02405     ol.endIndexItem(gd->getReference(),gd->getOutputFileBase());
02406     if (gd->isReference()) 
02407     { 
02408       ol.startTypewriter(); 
02409       ol.docify(" [external]");
02410       ol.endTypewriter();
02411     }
02412     
02413     //ol.writeStartAnnoItem(0,gd->getOutputFileBase(),0,gd-);
02414     //parseText(ol,gd->groupTitle());
02415     //ol.writeEndAnnoItem(gd->getOutputFileBase());
02416 
02417     // write pages
02418     PageSDict::Iterator pli(*gd->pageDict);
02419     PageDef *pd = 0;
02420     for (pli.toFirst();(pd=pli.current());++pli)
02421     {
02422       SectionInfo *si=0;
02423       if (!pd->name().isEmpty()) si=Doxygen::sectionDict[pd->name()];
02424       Doxygen::indexList.addContentsItem(FALSE,
02425                                    convertToHtml(pd->title(),TRUE),
02426                                    gd->getReference(),
02427                                    gd->getOutputFileBase(),
02428                                    si ? si->label.data() : 0
02429                                   ); 
02430     }
02431 
02432     // write subgroups
02433     if (hasSubGroups)
02434     {
02435       startIndexHierarchy(ol,level+1);
02436       if (Config_getBool("SORT_GROUP_NAMES"))
02437         gd->groupList->sort();
02438       QListIterator<GroupDef> gli(*gd->groupList);
02439       GroupDef *subgd = 0;
02440       for (gli.toFirst();(subgd=gli.current());++gli)
02441       {
02442         writeGroupTreeNode(ol,subgd,level+1);
02443       }
02444       endIndexHierarchy(ol,level+1); 
02445     }
02446 
02447 
02448     if (Config_getBool("TOC_EXPAND"))
02449     {
02450        writeGroupIndexItem(gd,gd->getMemberList(MemberList::docDefineMembers),
02451                          theTranslator->trDefines());
02452        writeGroupIndexItem(gd,gd->getMemberList(MemberList::docTypedefMembers),
02453                          theTranslator->trTypedefs());
02454        writeGroupIndexItem(gd,gd->getMemberList(MemberList::docEnumMembers),
02455                          theTranslator->trEnumerations());
02456        writeGroupIndexItem(gd,gd->getMemberList(MemberList::docFuncMembers),
02457                            fortranOpt ? theTranslator->trSubprograms() :
02458                            vhdlOpt    ? VhdlDocGen::trFunctionAndProc() :
02459                                         theTranslator->trFunctions()
02460                           );
02461        writeGroupIndexItem(gd,gd->getMemberList(MemberList::docVarMembers),
02462                          theTranslator->trVariables());
02463        writeGroupIndexItem(gd,gd->getMemberList(MemberList::docProtoMembers),
02464                          theTranslator->trFuncProtos());
02465 
02466       // write namespaces
02467       NamespaceSDict *namespaceSDict=gd->namespaceSDict;
02468       if (namespaceSDict->count()>0)
02469       {
02470         Doxygen::indexList.addContentsItem(TRUE,convertToHtml(fortranOpt?theTranslator->trModules():theTranslator->trNamespaces(),TRUE),gd->getReference(), gd->getOutputFileBase(), 0);
02471         Doxygen::indexList.incContentsDepth();
02472 
02473         NamespaceSDict::Iterator ni(*namespaceSDict);
02474         NamespaceDef *nsd;
02475         for (ni.toFirst();(nsd=ni.current());++ni)
02476         {
02477           Doxygen::indexList.addContentsItem(FALSE, convertToHtml(nsd->name(),TRUE), nsd->getReference(), nsd->getOutputFileBase(), 0);
02478         }
02479         Doxygen::indexList.decContentsDepth();
02480       }
02481 
02482       // write classes
02483       if (gd->classSDict->count()>0)
02484       {
02485         Doxygen::indexList.addContentsItem(TRUE,convertToHtml(fortranOpt?theTranslator->trDataTypes():theTranslator->trClasses(),TRUE), gd->getReference(), gd->getOutputFileBase(), 0);
02486         Doxygen::indexList.incContentsDepth();
02487 
02488         ClassDef *cd;
02489         ClassSDict::Iterator cdi(*gd->classSDict);
02490         for (cdi.toFirst();(cd=cdi.current());++cdi)
02491         {
02492           if (cd->isLinkable())
02493           {
02494             //printf("node: Has children %s\n",cd->name().data());
02495             Doxygen::indexList.addContentsItem(FALSE,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),0);
02496           }
02497         }
02498 
02499         //writeClassTree(gd->classSDict,1);
02500         Doxygen::indexList.decContentsDepth();
02501       }
02502 
02503       // write file list
02504       FileList *fileList=gd->fileList;
02505       if (fileList->count()>0)
02506       {
02507         Doxygen::indexList.addContentsItem(TRUE, 
02508               theTranslator->trFile(TRUE,FALSE),
02509               gd->getReference(), 
02510               gd->getOutputFileBase(), 0);
02511         Doxygen::indexList.incContentsDepth();
02512 
02513         FileDef *fd=fileList->first();
02514         while (fd)
02515         {
02516           Doxygen::indexList.addContentsItem(FALSE, convertToHtml(fd->name(),TRUE),fd->getReference(), fd->getOutputFileBase(), 0);
02517           fd=fileList->next();
02518         }
02519         Doxygen::indexList.decContentsDepth();
02520       }
02521 
02522       // write examples
02523       if (gd->exampleDict->count()>0)
02524       {
02525         Doxygen::indexList.addContentsItem(TRUE, convertToHtml(theTranslator->trExamples(),TRUE),gd->getReference(), gd->getOutputFileBase(), 0);
02526         Doxygen::indexList.incContentsDepth();
02527 
02528         PageSDict::Iterator eli(*(gd->exampleDict));
02529         PageDef *pd=eli.toFirst();
02530         while (pd)
02531         {
02532           Doxygen::indexList.addContentsItem(FALSE,pd->name(),pd->getReference(),pd->getOutputFileBase(),0); 
02533           pd=++eli;
02534         }
02535 
02536         Doxygen::indexList.decContentsDepth();
02537       }
02538     }
02539     
02540     Doxygen::indexList.decContentsDepth();
02541     
02542     //gd->visited=TRUE;
02543   }
02544 }
02545 
02546 void writeGroupHierarchy(OutputList &ol)
02547 {
02548   startIndexHierarchy(ol,0);
02549   if (Config_getBool("SORT_GROUP_NAMES"))
02550     Doxygen::groupSDict->sort();
02551   GroupSDict::Iterator gli(*Doxygen::groupSDict);
02552   GroupDef *gd;
02553   for (gli.toFirst();(gd=gli.current());++gli)
02554   {
02555     writeGroupTreeNode(ol,gd,0);
02556   }
02557   endIndexHierarchy(ol,0); 
02558 }
02559 
02560 //----------------------------------------------------------------------------
02561 void writeDirTreeNode(OutputList &ol, DirDef *dd,int level)
02562 {
02563   if (level>20)
02564   {
02565     warn(dd->getDefFileName(),dd->getDefLine(),
02566         "Warning: maximum nesting level exceeded for directory %s: "
02567         "check for possible recursive directory relation!\n",dd->name().data()
02568         );
02569     return;
02570   }
02571 
02572   static bool tocExpand = Config_getBool("TOC_EXPAND");
02573   bool isDir = dd->subDirs().count()>0 || // there are subdirs
02574                (tocExpand &&              // or toc expand and
02575                 dd->getFiles() && dd->getFiles()->count()>0 // there are files
02576                );
02577   //printf("gd=`%s': pageDict=%d\n",gd->name().data(),gd->pageDict->count());
02578   Doxygen::indexList.addContentsItem(isDir,dd->shortName(),dd->getReference(),dd->getOutputFileBase(),0); 
02579   Doxygen::indexList.incContentsDepth();
02580 
02581   ol.startIndexItem(dd->getReference(),dd->getOutputFileBase());
02582   ol.parseText(dd->shortName());
02583   ol.endIndexItem(dd->getReference(),dd->getOutputFileBase());
02584   if (dd->isReference()) 
02585   { 
02586     ol.startTypewriter(); 
02587     ol.docify(" [external]");
02588     ol.endTypewriter();
02589   }
02590 
02591   // write sub directories
02592   if (dd->subDirs().count()>0)
02593   {
02594     startIndexHierarchy(ol,level+1);
02595     QListIterator<DirDef> dli(dd->subDirs());
02596     DirDef *subdd = 0;
02597     for (dli.toFirst();(subdd=dli.current());++dli)
02598     {
02599       writeDirTreeNode(ol,subdd,level+1);
02600     }
02601     endIndexHierarchy(ol,level+1); 
02602   }
02603 
02604   if (tocExpand)
02605   {
02606     // write files of this directory
02607     FileList *fileList=dd->getFiles();
02608     if (fileList && fileList->count()>0)
02609     {
02610       FileDef *fd=fileList->first();
02611       while (fd)
02612       {
02613         Doxygen::indexList.addContentsItem(FALSE, convertToHtml(fd->name(),TRUE),fd->getReference(), fd->getOutputFileBase(), 0);
02614         fd=fileList->next();
02615       }
02616     }
02617   }
02618 
02619   Doxygen::indexList.decContentsDepth();
02620 }
02621 
02622 void writeDirHierarchy(OutputList &ol)
02623 {
02624   startIndexHierarchy(ol,0);
02625   SDict<DirDef>::Iterator dli(*Doxygen::directories);
02626   DirDef *dd;
02627   for (dli.toFirst();(dd=dli.current());++dli)
02628   {
02629     if (dd->getOuterScope()==Doxygen::globalScope) writeDirTreeNode(ol,dd,0);
02630   }
02631   endIndexHierarchy(ol,0); 
02632 }
02633 
02634 //----------------------------------------------------------------------------
02635 
02636 void writeGroupIndex(OutputList &ol)
02637 {
02638   if (documentedGroups==0) return; 
02639   ol.pushGeneratorState(); 
02640   ol.disable(OutputGenerator::Man);
02641   startFile(ol,"modules",0,theTranslator->trModuleIndex().data(),HLI_Modules);
02642   startTitle(ol,0);
02643   QCString title = theTranslator->trModules();
02644   //if (!Config_getString("PROJECT_NAME").isEmpty()) 
02645   //{
02646   //  title.prepend(Config_getString("PROJECT_NAME")+" ");
02647   //}
02648   ol.parseText(title);
02649   endTitle(ol,0,0);
02650   ol.startTextBlock();
02651   Doxygen::indexList.addContentsItem(TRUE,theTranslator->trModules(),0,"modules",0); 
02652   Doxygen::indexList.incContentsDepth();
02653 
02654   ol.parseText(theTranslator->trModulesDescription());
02655   ol.endTextBlock();
02656   writeGroupHierarchy(ol);
02657   Doxygen::indexList.decContentsDepth();
02658   endFile(ol);
02659   ol.popGeneratorState();
02660 }
02661 
02662 //----------------------------------------------------------------------------
02663 
02664 void writeDirIndex(OutputList &ol)
02665 {
02666   if (documentedDirs==0) return; 
02667   ol.pushGeneratorState(); 
02668   ol.disable(OutputGenerator::Man);
02669   startFile(ol,"dirs",0,theTranslator->trDirIndex().data(),HLI_Directories);
02670   startTitle(ol,0);
02671   QCString title = theTranslator->trDirectories();
02672   //if (!Config_getString("PROJECT_NAME").isEmpty()) 
02673   //{
02674   //  title.prepend(Config_getString("PROJECT_NAME")+" ");
02675   //}
02676   ol.parseText(title);
02677   endTitle(ol,0,0);
02678   ol.startTextBlock();
02679   Doxygen::indexList.addContentsItem(TRUE,theTranslator->trDirIndex(),0,"dirs",0); 
02680   Doxygen::indexList.incContentsDepth();
02681   ol.parseText(theTranslator->trDirDescription());
02682   ol.endTextBlock();
02683 
02684   writeDirHierarchy(ol);
02685 
02686   Doxygen::indexList.decContentsDepth();
02687   endFile(ol);
02688   ol.popGeneratorState();
02689 }
02690 
02691 //----------------------------------------------------------------------------
02692 
02693 static bool mainPageHasTitle()
02694 {
02695   if (Doxygen::mainPage==0) return FALSE;
02696   if (Doxygen::mainPage->title().isEmpty()) return FALSE;
02697   if (Doxygen::mainPage->title().lower()=="notitle") return FALSE;
02698   return TRUE;
02699 }
02700 
02701 //----------------------------------------------------------------------------
02702 
02703 void writeIndex(OutputList &ol)
02704 {
02705   static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
02706   static bool vhdlOpt    = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
02707   // save old generator state
02708   ol.pushGeneratorState();
02709 
02710   QCString projPrefix;
02711   if (!Config_getString("PROJECT_NAME").isEmpty())
02712   {
02713     projPrefix=Config_getString("PROJECT_NAME")+" ";
02714   }
02715 
02716   //--------------------------------------------------------------------
02717   // write HTML index
02718   //--------------------------------------------------------------------
02719   ol.disableAllBut(OutputGenerator::Html);
02720 
02721   QCString defFileName = 
02722     Doxygen::mainPage ? Doxygen::mainPage->getDefFileName().data() : "[generated]";
02723   int defLine =
02724     Doxygen::mainPage ? Doxygen::mainPage->getDefLine() : -1;
02725 
02726   QCString title;
02727   if (!mainPageHasTitle())
02728   {
02729     title = theTranslator->trMainPage();
02730   }
02731   else 
02732   {
02733     title = substitute(Doxygen::mainPage->title(),"%","");
02734   }
02735 
02736   QCString indexName="index";
02737   if (Config_getBool("GENERATE_TREEVIEW")) indexName="main";
02738   ol.startFile(indexName,0,title);
02739   
02740   if (Doxygen::mainPage)
02741   {
02742     Doxygen::indexList.addContentsItem(Doxygen::mainPage->hasSubPages(),title,0,indexName,0); 
02743 
02744     if (Doxygen::mainPage->hasSubPages())
02745     {
02746       writeSubPages(Doxygen::mainPage);
02747     }
02748   }
02749 
02750   if (!Config_getBool("DISABLE_INDEX")) 
02751   {
02752     ol.startQuickIndices();
02753     ol.writeQuickLinks(TRUE,HLI_Main);
02754     ol.endQuickIndices();
02755   }
02756   ol.startContents();
02757   ol.startTitleHead(0);
02758   if (Doxygen::mainPage && !Doxygen::mainPage->title().isEmpty())
02759   {
02760     if (Doxygen::mainPage->title().lower()!="notitle")
02761     {
02762       ol.docify(Doxygen::mainPage->title());
02763     }
02764   }
02765   else
02766   {
02767     if (!Config_getString("PROJECT_NAME").isEmpty())
02768     {
02769       ol.parseText(projPrefix+theTranslator->trDocumentation());
02770     }
02771   }
02772   ol.endTitleHead(0,0);
02773   ol.newParagraph();
02774   if (!Config_getString("PROJECT_NUMBER").isEmpty())
02775   {
02776     ol.startProjectNumber();
02777     ol.parseDoc(defFileName,defLine,Doxygen::mainPage,0,Config_getString("PROJECT_NUMBER"),TRUE,FALSE);
02778     ol.endProjectNumber();
02779   }
02780   if (Config_getBool("DISABLE_INDEX") && Doxygen::mainPage==0) 
02781   {
02782     ol.writeQuickLinks(FALSE,HLI_Main);
02783   }
02784 
02785   if (Doxygen::mainPage)
02786   {
02787     Doxygen::insideMainPage=TRUE;
02788     ol.parseDoc(defFileName,defLine,Doxygen::mainPage,0,
02789                 Doxygen::mainPage->documentation(),TRUE,FALSE
02790                 /*,Doxygen::mainPage->sectionDict*/);
02791 
02792     if (!Config_getString("GENERATE_TAGFILE").isEmpty())
02793     {
02794        Doxygen::tagFile << "  <compound kind=\"page\">" << endl
02795                         << "    <name>"
02796                         << convertToXML(Doxygen::mainPage->name())
02797                         << "</name>" << endl
02798                         << "    <title>"
02799                         << convertToXML(Doxygen::mainPage->title())
02800                         << "</title>" << endl
02801                         << "    <filename>"
02802                         << convertToXML(Doxygen::mainPage->getOutputFileBase())
02803                         << "</filename>" << endl;
02804 
02805        Doxygen::mainPage->writeDocAnchorsToTagFile();
02806        Doxygen::tagFile << "  </compound>" << endl;
02807     }
02808     Doxygen::insideMainPage=FALSE;
02809   }
02810   
02811   endFile(ol);
02812   ol.disable(OutputGenerator::Html);
02813   
02814   //--------------------------------------------------------------------
02815   // write LaTeX/RTF index
02816   //--------------------------------------------------------------------
02817   ol.enable(OutputGenerator::Latex);
02818   ol.enable(OutputGenerator::RTF);
02819 
02820   ol.startFile("refman",0,0);
02821   ol.startIndexSection(isTitlePageStart);
02822   if (!Config_getString("LATEX_HEADER").isEmpty()) 
02823   {
02824     ol.disable(OutputGenerator::Latex);
02825   }
02826 
02827   if (projPrefix.isEmpty())
02828   {
02829     ol.parseText(theTranslator->trReferenceManual());
02830   }
02831   else
02832   {
02833     ol.parseText(projPrefix);
02834   }
02835 
02836   if (!Config_getString("PROJECT_NUMBER").isEmpty())
02837   {
02838     ol.startProjectNumber(); 
02839     ol.parseDoc(defFileName,defLine,Doxygen::mainPage,0,Config_getString("PROJECT_NUMBER"),FALSE,FALSE);
02840     ol.endProjectNumber();
02841   }
02842   ol.endIndexSection(isTitlePageStart);
02843   ol.startIndexSection(isTitlePageAuthor);
02844   ol.parseText(theTranslator->trGeneratedBy());
02845   ol.endIndexSection(isTitlePageAuthor);
02846   ol.enable(OutputGenerator::Latex);
02847 
02848   ol.lastIndexPage();
02849   if (Doxygen::mainPage)
02850   {
02851     ol.startIndexSection(isMainPage);
02852     if (mainPageHasTitle())
02853     {
02854       ol.parseDoc(defFileName,defLine,Doxygen::mainPage,0,Doxygen::mainPage->title(),FALSE,FALSE);
02855     }
02856     else
02857     {
02858       ol.parseText(/*projPrefix+*/theTranslator->trMainPage());
02859     }
02860     ol.endIndexSection(isMainPage);
02861   }
02862   if (documentedPages>0)
02863   {
02864     //ol.parseText(projPrefix+theTranslator->trPageDocumentation());
02865     //ol.endIndexSection(isPageDocumentation);
02866     PageSDict::Iterator pdi(*Doxygen::pageSDict);
02867     PageDef *pd=pdi.toFirst();
02868     bool first=Doxygen::mainPage==0;
02869     for (pdi.toFirst();(pd=pdi.current());++pdi)
02870     {
02871       if (!pd->getGroupDef() && !pd->isReference())
02872       {
02873         QCString title = pd->title();
02874         if (title.isEmpty()) title=pd->name();
02875         ol.startIndexSection(isPageDocumentation);
02876         ol.parseText(title);
02877         ol.endIndexSection(isPageDocumentation);
02878 
02879         ol.writePageLink(pd->getOutputFileBase(),first);
02880         first=FALSE;
02881       }
02882     }
02883   }
02884 
02885   if (!Config_getBool("LATEX_HIDE_INDICES"))
02886   {
02887     //if (indexedPages>0)
02888     //{
02889     //  ol.startIndexSection(isPageIndex);
02890     //  ol.parseText(/*projPrefix+*/ theTranslator->trPageIndex());
02891     //  ol.endIndexSection(isPageIndex);
02892     //}
02893     if (documentedGroups>0)
02894     {
02895       ol.startIndexSection(isModuleIndex);
02896       ol.parseText(/*projPrefix+*/ theTranslator->trModuleIndex());
02897       ol.endIndexSection(isModuleIndex);
02898     }
02899     if (Config_getBool("SHOW_DIRECTORIES") && documentedDirs>0)
02900     {
02901       ol.startIndexSection(isDirIndex);
02902       ol.parseText(/*projPrefix+*/ theTranslator->trDirIndex());
02903       ol.endIndexSection(isDirIndex);
02904     }
02905     if (documentedNamespaces>0)
02906     {
02907       ol.startIndexSection(isNamespaceIndex);
02908       ol.parseText(/*projPrefix+*/(fortranOpt?theTranslator->trModulesIndex():theTranslator->trNamespaceIndex()));
02909       ol.endIndexSection(isNamespaceIndex);
02910     }
02911     if (hierarchyClasses>0)
02912     {
02913       ol.startIndexSection(isClassHierarchyIndex);
02914       ol.parseText(/*projPrefix+*/
02915           (fortranOpt ? theTranslator->trCompoundIndexFortran() : 
02916            vhdlOpt    ? VhdlDocGen::trDesignUnitIndex()             :
02917                         theTranslator->trCompoundIndex()
02918           ));
02919       ol.endIndexSection(isClassHierarchyIndex);
02920     }
02921     if (annotatedClasses>0)
02922     {
02923       ol.startIndexSection(isCompoundIndex);
02924       ol.parseText(/*projPrefix+*/
02925           (vhdlOpt ? VhdlDocGen::trDesignUnitIndex() : 
02926                      theTranslator->trCompoundIndex()
02927           ));
02928       ol.endIndexSection(isCompoundIndex);
02929     }
02930     if (documentedFiles>0)
02931     {
02932       ol.startIndexSection(isFileIndex);
02933       ol.parseText(/*projPrefix+*/theTranslator->trFileIndex());
02934       ol.endIndexSection(isFileIndex);
02935     }
02936   }
02937   if (documentedGroups>0)
02938   {
02939     ol.startIndexSection(isModuleDocumentation);
02940     ol.parseText(/*projPrefix+*/theTranslator->trModuleDocumentation());
02941     ol.endIndexSection(isModuleDocumentation);
02942   }
02943   if (Config_getBool("SHOW_DIRECTORIES") && documentedDirs>0)
02944   {
02945     ol.startIndexSection(isDirDocumentation);
02946     ol.parseText(/*projPrefix+*/theTranslator->trDirDocumentation());
02947     ol.endIndexSection(isDirDocumentation);
02948   }
02949   if (documentedNamespaces>0)
02950   {
02951     ol.startIndexSection(isNamespaceDocumentation);
02952     ol.parseText(/*projPrefix+*/(fortranOpt?theTranslator->trModuleDocumentation():theTranslator->trNamespaceDocumentation()));
02953     ol.endIndexSection(isNamespaceDocumentation);
02954   }
02955   if (annotatedClasses>0)
02956   {
02957     ol.startIndexSection(isClassDocumentation);
02958     ol.parseText(/*projPrefix+*/(fortranOpt?theTranslator->trTypeDocumentation():theTranslator->trClassDocumentation()));
02959     ol.endIndexSection(isClassDocumentation);
02960   }
02961   if (documentedFiles>0)
02962   {
02963     ol.startIndexSection(isFileDocumentation);
02964     ol.parseText(/*projPrefix+*/theTranslator->trFileDocumentation());
02965     ol.endIndexSection(isFileDocumentation);
02966   }
02967   if (Doxygen::exampleSDict->count()>0)
02968   {
02969     ol.startIndexSection(isExampleDocumentation);
02970     ol.parseText(/*projPrefix+*/theTranslator->trExampleDocumentation());
02971     ol.endIndexSection(isExampleDocumentation);
02972   }
02973   ol.endIndexSection(isEndIndex);
02974   endFile(ol);
02975 
02976   if (Doxygen::mainPage)
02977   {
02978     Doxygen::insideMainPage=TRUE;
02979     ol.disable(OutputGenerator::Man);
02980     startFile(ol,Doxygen::mainPage->name(),0,Doxygen::mainPage->title());
02981     ol.startTextBlock();
02982     ol.parseDoc(defFileName,defLine,Doxygen::mainPage,0,
02983                 Doxygen::mainPage->documentation(),FALSE,FALSE
02984                );
02985     ol.endTextBlock();
02986     endFile(ol);
02987     ol.enable(OutputGenerator::Man);
02988     Doxygen::insideMainPage=FALSE;
02989   }
02990 
02991   ol.popGeneratorState();
02992 }
02993 
02994 
02995 



Generated on Mon Mar 31 10:58:39 2008 by  doxygen 1.5.1