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