index.cpp 131 KB
Newer Older
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1 2
/******************************************************************************
 *
3
 * 
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4
 *
Dimitri van Heesch's avatar
Dimitri van Heesch committed
5
 * Copyright (C) 1997-2013 by Dimitri van Heesch.
Dimitri van Heesch's avatar
Dimitri van Heesch committed
6 7 8 9 10 11 12
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation under the terms of the GNU General Public License is hereby 
 * granted. No representations are made about the suitability of this software 
 * for any purpose. It is provided "as is" without express or implied warranty.
 * See the GNU General Public License for more details.
 *
Dimitri van Heesch's avatar
Dimitri van Heesch committed
13 14
 * Documents produced by Doxygen are derivative works derived from the
 * input used in their production; they are not affected by this license.
Dimitri van Heesch's avatar
Dimitri van Heesch committed
15 16 17
 *
 */

18 19 20 21
/** @file
 *  @brief This file contains functions for the various index pages.
 */

Dimitri van Heesch's avatar
Dimitri van Heesch committed
22 23
#include <stdlib.h>

24 25 26
#include <qtextstream.h>
#include <qdatetime.h>
#include <qdir.h>
27
#include <qregexp.h>
28

Dimitri van Heesch's avatar
Dimitri van Heesch committed
29 30 31 32 33 34 35 36 37
#include "message.h"
#include "index.h"
#include "doxygen.h"
#include "config.h"
#include "filedef.h"
#include "outputlist.h"
#include "util.h"
#include "groupdef.h"
#include "language.h"
38
#include "htmlgen.h"
39
#include "htmlhelp.h"
40
#include "ftvhelp.h"
Dimitri van Heesch's avatar
Dimitri van Heesch committed
41
#include "dot.h"
42
#include "pagedef.h"
43
#include "dirdef.h"
44
#include "vhdldocgen.h"
45
#include "layout.h"
46 47 48 49
#include "memberlist.h"
#include "classlist.h"
#include "namespacedef.h"
#include "filename.h"
Dimitri van Heesch's avatar
Dimitri van Heesch committed
50

51 52 53
#define MAX_ITEMS_BEFORE_MULTIPAGE_INDEX 200
#define MAX_ITEMS_BEFORE_QUICK_INDEX 30

54

55
int annotatedClasses;
Dimitri van Heesch's avatar
Dimitri van Heesch committed
56
int annotatedClassesPrinted;
57 58 59 60 61 62 63 64
int hierarchyClasses;
int documentedFiles;
int documentedGroups;
int documentedNamespaces;
int indexedPages;
int documentedClassMembers[CMHL_Total];
int documentedFileMembers[FMHL_Total];
int documentedNamespaceMembers[NMHL_Total];
65 66
int documentedHtmlFiles;
int documentedPages;
67
int documentedDirs;
68

69 70 71 72 73 74 75
static int countClassHierarchy();
static void countFiles(int &htmlFiles,int &files);
static int countGroups();
static int countDirs();
static int countNamespaces();
static int countAnnotatedClasses(int *cp);
static void countRelatedPages(int &docPages,int &indexPages);
76 77 78

void countDataStructures()
{
Dimitri van Heesch's avatar
Dimitri van Heesch committed
79
  annotatedClasses           = countAnnotatedClasses(&annotatedClassesPrinted); // "classes" + "annotated"
80 81 82 83 84 85 86 87 88
  hierarchyClasses           = countClassHierarchy();   // "hierarchy"
  countFiles(documentedHtmlFiles,documentedFiles);      // "files"
  countRelatedPages(documentedPages,indexedPages);      // "pages"
  documentedGroups           = countGroups();           // "modules"
  documentedNamespaces       = countNamespaces();       // "namespaces"
  documentedDirs             = countDirs();             // "dirs"
  // "globals"
  // "namespacemembers"
  // "functions"
89 90
}

Dimitri van Heesch's avatar
Dimitri van Heesch committed
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
static void startIndexHierarchy(OutputList &ol,int level)
{
  ol.pushGeneratorState();
  ol.disable(OutputGenerator::Man);
  ol.disable(OutputGenerator::Html);
  if (level<6) ol.startIndexList();
  ol.enableAll();
  ol.disable(OutputGenerator::Latex);
  ol.disable(OutputGenerator::RTF);
  ol.startItemList();
  ol.popGeneratorState();
}

static void endIndexHierarchy(OutputList &ol,int level)
{
  ol.pushGeneratorState();
  ol.disable(OutputGenerator::Man);
  ol.disable(OutputGenerator::Html);
  if (level<6) ol.endIndexList();
  ol.enableAll();
  ol.disable(OutputGenerator::Latex);
  ol.disable(OutputGenerator::RTF);
  ol.endItemList();
  ol.popGeneratorState();
}

Dimitri van Heesch's avatar
Dimitri van Heesch committed
117 118
//----------------------------------------------------------------------------

119 120 121 122 123
class MemberIndexList : public QList<MemberDef>
{
  public:
    MemberIndexList() : QList<MemberDef>() {}
    ~MemberIndexList() {}
124
    int compareItems(QCollection::Item item1, QCollection::Item item2)
125 126 127
    {
      MemberDef *md1=(MemberDef *)item1;
      MemberDef *md2=(MemberDef *)item2;
Dimitri van Heesch's avatar
Dimitri van Heesch committed
128
      return qstricmp(md1->name(),md2->name());
129 130 131
    }
};

132
#define MEMBER_INDEX_ENTRIES 256
133 134 135 136 137

static MemberIndexList g_memberIndexLetterUsed[CMHL_Total][MEMBER_INDEX_ENTRIES];
static MemberIndexList g_fileIndexLetterUsed[FMHL_Total][MEMBER_INDEX_ENTRIES];
static MemberIndexList g_namespaceIndexLetterUsed[NMHL_Total][MEMBER_INDEX_ENTRIES];

138
//static bool g_classIndexLetterUsed[CHL_Total][256];
Dimitri van Heesch's avatar
Dimitri van Heesch committed
139

140
const int maxItemsBeforeQuickIndex = MAX_ITEMS_BEFORE_QUICK_INDEX;
141

142 143
//----------------------------------------------------------------------------

Dimitri van Heesch's avatar
Dimitri van Heesch committed
144 145
//----------------------------------------------------------------------------

146
static void startQuickIndexList(OutputList &ol,bool letterTabs=FALSE)
147 148 149 150
{
  bool fancyTabs = TRUE;
  if (fancyTabs)
  {
151 152
    if (letterTabs)
    {
153
      ol.writeString("  <div id=\"navrow4\" class=\"tabs3\">\n"); 
154 155 156
    }
    else
    {
157
      ol.writeString("  <div id=\"navrow3\" class=\"tabs2\">\n"); 
158 159
    }
    ol.writeString("    <ul class=\"tablist\">\n"); 
160 161 162
  }
  else
  {
163
    ol.writeString("  <div class=\"qindex\">"); 
164 165 166 167 168 169 170 171
  }
}

static void endQuickIndexList(OutputList &ol)
{
  bool fancyTabs = TRUE;
  if (fancyTabs)
  {
172
    ol.writeString("    </ul>\n");
173
  }
174
  ol.writeString("  </div>\n");
175 176
}

177
static void startQuickIndexItem(OutputList &ol,const char *l,
178
                                bool hl,bool compact,bool &first)
179
{
180 181
  bool fancyTabs = TRUE;
  if (!first && compact && !fancyTabs) ol.writeString(" | ");
182
  first=FALSE;
183
  if (fancyTabs)
184
  {
185
    ol.writeString("      <li"); 
186
    if (hl) ol.writeString(" class=\"current\"");
187
    ol.writeString("><a ");
188
  }
189
  else
190
  {
191 192 193 194 195 196 197 198 199
    if (!compact) ol.writeString("<li>");
    if (hl && compact)
    {
      ol.writeString("<a class=\"qindexHL\" ");
    }
    else
    {
      ol.writeString("<a class=\"qindex\" ");
    }
200 201 202 203
  }
  ol.writeString("href=\""); 
  ol.writeString(l);
  ol.writeString("\">");
204 205 206 207
  if (fancyTabs)
  {
    ol.writeString("<span>");
  }
208 209 210 211
}

static void endQuickIndexItem(OutputList &ol)
{
212 213
  bool fancyTabs=TRUE;
  if (fancyTabs) ol.writeString("</span>");
214
  ol.writeString("</a>");
215
  if (fancyTabs) ol.writeString("</li>\n");
216 217
}

218 219 220
// don't make this static as it is called from a template function and some
// old compilers don't support calls to static functions from a template.
QCString fixSpaces(const QCString &s)
221
{
222
  return substitute(s," ","&#160;");
223 224
}

225
void startTitle(OutputList &ol,const char *fileName,Definition *def)
226
{
227 228
  ol.startHeaderSection();
  if (def) def->writeSummaryLinks(ol);
229
  ol.startTitleHead(fileName);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
230 231
  ol.pushGeneratorState();
  ol.disable(OutputGenerator::Man);
232 233 234 235
}

void endTitle(OutputList &ol,const char *fileName,const char *name)
{
Dimitri van Heesch's avatar
Dimitri van Heesch committed
236
  ol.popGeneratorState();
237
  ol.endTitleHead(fileName,name);
238
  ol.endHeaderSection();
239 240
}

241
void startFile(OutputList &ol,const char *name,const char *manName,
242 243
               const char *title,HighlightedItem hli,bool additionalIndices,
               const char *altSidebarName)
244
{
245
  static bool disableIndex     = Config_getBool("DISABLE_INDEX");
246
  ol.startFile(name,manName,title);
247 248
  ol.startQuickIndices();
  if (!disableIndex)
249
  {
250
    ol.writeQuickLinks(TRUE,hli,name);
251
  }
252
  if (!additionalIndices)
253
  {
254 255
    ol.endQuickIndices();
  }
256 257
  ol.writeSplitBar(altSidebarName ? altSidebarName : name);
  ol.writeSearchInfo();
258 259
}

260 261
void endFile(OutputList &ol,bool skipNavIndex,bool skipEndContents,
             const QCString &navPath)
262
{
263
  static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
264 265
  ol.pushGeneratorState();
  ol.disableAllBut(OutputGenerator::Html);
266 267
  if (!skipNavIndex)
  {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
268
    if (!skipEndContents) ol.endContents();
269 270
    if (generateTreeView)
    {
271
      ol.writeString("</div><!-- doc-content -->\n");
272 273
    }
  }
274
  ol.writeFooter(navPath); // write the footer
275 276 277 278
  ol.popGeneratorState();
  ol.endFile();
}

279 280 281
void endFileWithNavPath(Definition *d,OutputList &ol)
{
  static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
282
  QCString navPath;
283 284
  if (generateTreeView)
  {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
285 286
    ol.pushGeneratorState();
    ol.disableAllBut(OutputGenerator::Html);
287
    ol.writeString("</div><!-- doc-content -->\n");
Dimitri van Heesch's avatar
Dimitri van Heesch committed
288
    ol.popGeneratorState();
289
    navPath = d->navigationPathAsString();
290
  }
291
  endFile(ol,generateTreeView,TRUE,navPath);
292 293
}

294
//----------------------------------------------------------------------
Dimitri van Heesch's avatar
Dimitri van Heesch committed
295 296 297 298
template<class T> 
void addMembersToIndex(T *def,LayoutDocManager::LayoutPart part,
                       const QCString &name,const QCString &anchor,
                       bool addToIndex=TRUE,bool preventSeparateIndex=FALSE)
299 300
{
  bool hasMembers = def->getMemberLists().count()>0 || def->getMemberGroupSDict()!=0;
301
  Doxygen::indexList->addContentsItem(hasMembers,name,
Dimitri van Heesch's avatar
Dimitri van Heesch committed
302 303
                                     def->getReference(),def->getOutputFileBase(),anchor,
                                     hasMembers && !preventSeparateIndex,
Dimitri van Heesch's avatar
Dimitri van Heesch committed
304 305
                                     addToIndex,
                                     def);
306 307 308 309 310 311 312 313 314 315 316
  int numClasses=0;
  ClassSDict *classes = def->getClassSDict();
  if (classes)
  {
     ClassDef *cd;
     ClassSDict::Iterator it(*classes);
     for (;(cd=it.current());++it)
     {
       if (cd->isLinkable()) numClasses++;
     }
  }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
317
  //printf("addMembersToIndex(def=%s hasMembers=%d numClasses=%d)\n",def->name().data(),hasMembers,numClasses);
318
  if (hasMembers || numClasses>0)
319
  {
320
    Doxygen::indexList->incContentsDepth();
321 322 323 324 325 326 327 328 329 330 331 332 333 334
    QListIterator<LayoutDocEntry> eli(LayoutDocManager::instance().docEntries(part));
    LayoutDocEntry *lde;
    for (eli.toFirst();(lde=eli.current());++eli)
    {
      if (lde->kind()==LayoutDocEntry::MemberDef)
      {
        LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde;
        MemberList *ml = def->getMemberList(lmd->type);
        if (ml)
        {
          MemberListIterator mi(*ml);
          MemberDef *md;
          for (mi.toFirst();(md=mi.current());++mi)
          {
335
            MemberList *enumList = md->enumFieldList();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
336
            bool isDir = enumList!=0 && md->isEnumerate();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
337
            bool isAnonymous = md->name().find('@')!=-1;
338 339 340 341 342 343
            static bool hideUndocMembers = Config_getBool("HIDE_UNDOC_MEMBERS");
            static bool extractStatic = Config_getBool("EXTRACT_STATIC");
            if (!isAnonymous && 
                (!hideUndocMembers || md->hasDocumentation()) &&
                (!md->isStatic() || extractStatic)
               )
344
            {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
345 346
              if (md->getOuterScope()==def)
              {
347
                Doxygen::indexList->addContentsItem(isDir,
348
                  md->name(),md->getReference(),md->getOutputFileBase(),md->anchor(),FALSE,addToIndex);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
349 350 351
              }
              else // inherited member
              {
352
                Doxygen::indexList->addContentsItem(isDir,
Dimitri van Heesch's avatar
Dimitri van Heesch committed
353 354
                  md->name(),def->getReference(),def->getOutputFileBase(),md->anchor(),FALSE,addToIndex);
              }
355
            }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
356 357
            if (isDir)
            {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
358 359
              if (!isAnonymous)
              {
360
                Doxygen::indexList->incContentsDepth();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
361
              }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
362 363 364 365 366 367
              MemberListIterator emli(*enumList);
              MemberDef *emd;
              for (emli.toFirst();(emd=emli.current());++emli)
              {
                if (emd->getOuterScope()==def)
                {
368
                  Doxygen::indexList->addContentsItem(FALSE,
Dimitri van Heesch's avatar
Dimitri van Heesch committed
369 370 371 372
                      emd->name(),emd->getReference(),emd->getOutputFileBase(),emd->anchor(),FALSE,addToIndex);
                }
                else // inherited member
                {
373
                  Doxygen::indexList->addContentsItem(FALSE,
Dimitri van Heesch's avatar
Dimitri van Heesch committed
374 375 376
                      emd->name(),def->getReference(),def->getOutputFileBase(),emd->anchor(),FALSE,addToIndex);
                }
              }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
377 378
              if (!isAnonymous)
              {
379
                Doxygen::indexList->decContentsDepth();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
380
              }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
381
            }
382 383 384 385
          }
        }
      }
      else if (lde->kind()==LayoutDocEntry::NamespaceClasses || 
386 387 388
               lde->kind()==LayoutDocEntry::FileClasses || 
               lde->kind()==LayoutDocEntry::ClassNestedClasses
              )
389 390 391 392 393 394 395
      {
        if (classes)
        {
          ClassDef *cd;
          ClassSDict::Iterator it(*classes);
          for (;(cd=it.current());++it)
          {
396
            if (cd->isLinkable() && (cd->partOfGroups()==0 || def->definitionType()==Definition::TypeGroup))
397
            {
398
              bool isNestedClass = def->definitionType()==Definition::TypeClass;
Dimitri van Heesch's avatar
Dimitri van Heesch committed
399
              addMembersToIndex(cd,LayoutDocManager::Class,cd->displayName(FALSE),cd->anchor(),
400 401
                                addToIndex && isNestedClass,
                                preventSeparateIndex || cd->isEmbeddedInOuterScope());
402 403 404 405 406 407
            }
          }
        }
      }
    }

408
    Doxygen::indexList->decContentsDepth();
409 410 411
  }
}

412 413
//----------------------------------------------------------------------------

414 415
static bool classHasVisibleChildren(ClassDef *cd)
{
Dimitri van Heesch's avatar
Dimitri van Heesch committed
416 417
  BaseClassList *bcl;

Dimitri van Heesch's avatar
Dimitri van Heesch committed
418
  if (cd->getLanguage()==SrcLangExt_VHDL) // reverse baseClass/subClass relation
Dimitri van Heesch's avatar
Dimitri van Heesch committed
419 420 421 422 423 424 425 426 427 428
  {
    if (cd->baseClasses()==0) return FALSE;
    bcl=cd->baseClasses();
  }
  else 
  {
    if (cd->subClasses()==0) return FALSE;
    bcl=cd->subClasses();
  }

429 430 431 432 433 434 435 436 437 438 439
  BaseClassListIterator bcli(*bcl);
  for ( ; bcli.current() ; ++bcli)
  {
    if (bcli.current()->classDef->isVisibleInHierarchy())
    {
      return TRUE;
    }
  }
  return FALSE;
}

440 441 442 443
//----------------------------------------------------------------------------
/*! Generates HTML Help tree of classes */

static void writeClassTree(OutputList &ol,BaseClassList *bcl,bool hideSuper,int level,FTVHelp* ftv,bool addToIndex)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
444
{
445
  if (bcl==0) return;
Dimitri van Heesch's avatar
Dimitri van Heesch committed
446 447 448 449 450
  BaseClassListIterator bcli(*bcl);
  bool started=FALSE;
  for ( ; bcli.current() ; ++bcli)
  {
    ClassDef *cd=bcli.current()->classDef;
451 452 453 454 455
    if (cd->getLanguage()==SrcLangExt_VHDL && (VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS)
    {
      continue;
    }

Dimitri van Heesch's avatar
Dimitri van Heesch committed
456
    bool b;
Dimitri van Heesch's avatar
Dimitri van Heesch committed
457
    if (cd->getLanguage()==SrcLangExt_VHDL)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
458 459 460 461 462 463 464 465 466
    {
      b=hasVisibleRoot(cd->subClasses());
    }
    else
    {
      b=hasVisibleRoot(cd->baseClasses());
    }

    if (cd->isVisibleInHierarchy() && b) // hasVisibleRoot(cd->baseClasses()))
Dimitri van Heesch's avatar
Dimitri van Heesch committed
467 468 469
    {
      if (!started)
      {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
470
        startIndexHierarchy(ol,level);
471 472
        if (addToIndex)
        {
473
          Doxygen::indexList->incContentsDepth();
474
        }
475
        if (ftv)
476
        {
477
          ftv->incContentsDepth();
478
        }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
479 480
        started=TRUE;
      }
481
      ol.startIndexListItem();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
482
      //printf("Passed...\n");
483 484
      bool hasChildren = !cd->visited && !hideSuper && classHasVisibleChildren(cd);
      //printf("tree4: Has children %s: %d\n",cd->name().data(),hasChildren);
485
      if (cd->isLinkable())
Dimitri van Heesch's avatar
Dimitri van Heesch committed
486
      {
487
        //printf("Writing class %s\n",cd->displayName().data());
488 489 490
        ol.startIndexItem(cd->getReference(),cd->getOutputFileBase());
        ol.parseText(cd->displayName());
        ol.endIndexItem(cd->getReference(),cd->getOutputFileBase());
Dimitri van Heesch's avatar
Dimitri van Heesch committed
491 492 493 494 495 496
        if (cd->isReference()) 
        { 
          ol.startTypewriter(); 
          ol.docify(" [external]");
          ol.endTypewriter();
        }
497 498
        if (addToIndex)
        {
499
          Doxygen::indexList->addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor());
500
        }
501
        if (ftv)
502
        {
503 504 505 506 507 508 509 510
          if (cd->getLanguage()==SrcLangExt_VHDL)
          {
            ftv->addContentsItem(hasChildren,bcli.current()->usedName,cd->getReference(),cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE,cd);
          }
          else
          {
            ftv->addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE,cd);
          }
511
        }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
512 513 514
      }
      else
      {
515 516 517
        ol.startIndexItem(0,0);
        ol.parseText(cd->name());
        ol.endIndexItem(0,0);
518 519
        if (addToIndex)
        {
520
          Doxygen::indexList->addContentsItem(hasChildren,cd->displayName(),0,0,0);
521
        }
522
        if (ftv)
523
        {
524
          ftv->addContentsItem(hasChildren,cd->displayName(),0,0,0,FALSE,FALSE,cd);
525
        }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
526
      }
527
      if (hasChildren)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
528
      {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
529 530
        //printf("Class %s at %p visited=%d\n",cd->name().data(),cd,cd->visited);
        bool wasVisited=cd->visited;
Dimitri van Heesch's avatar
Dimitri van Heesch committed
531
        cd->visited=TRUE;
Dimitri van Heesch's avatar
Dimitri van Heesch committed
532
        if (cd->getLanguage()==SrcLangExt_VHDL)	
Dimitri van Heesch's avatar
Dimitri van Heesch committed
533
        {
534
          writeClassTree(ol,cd->baseClasses(),wasVisited,level+1,ftv,addToIndex);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
535 536 537
        }
        else       
        {
538
          writeClassTree(ol,cd->subClasses(),wasVisited,level+1,ftv,addToIndex);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
539
        }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
540
      }
541
      ol.endIndexListItem();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
542 543
    }
  }
544 545
  if (started) 
  {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
546
    endIndexHierarchy(ol,level);
547 548
    if (addToIndex)
    {
549
      Doxygen::indexList->decContentsDepth();
550
    }
551
    if (ftv)
552
    {
553
      ftv->decContentsDepth();
554 555 556 557
    }
  }
}

Dimitri van Heesch's avatar
Dimitri van Heesch committed
558 559
//----------------------------------------------------------------------------

Dimitri van Heesch's avatar
Dimitri van Heesch committed
560
static bool classVisibleInIndex(ClassDef *cd)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
561 562
{
  static bool allExternals = Config_getBool("ALLEXTERNALS");
Dimitri van Heesch's avatar
Dimitri van Heesch committed
563
  return (allExternals && cd->isLinkable()) || cd->isLinkableInProject();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
564 565
}

Dimitri van Heesch's avatar
Dimitri van Heesch committed
566 567 568
//----------------------------------------------------------------------------

static bool dirHasVisibleChildren(DirDef *dd)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
569
{
Dimitri van Heesch's avatar
Dimitri van Heesch committed
570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596
  if (dd->hasDocumentation()) return TRUE;

  QListIterator<FileDef> fli(*dd->getFiles());
  FileDef *fd;
  for (fli.toFirst();(fd=fli.current());++fli)
  {
    bool genSourceFile;
    if (fileVisibleInIndex(fd,genSourceFile))
    {
      return TRUE;
    }
    if (genSourceFile)
    {
      return TRUE;
    }
  }

  QListIterator<DirDef> dli(dd->subDirs());
  DirDef *subdd;
  for (dli.toFirst();(subdd=dli.current());++dli)
  {
    if (dirHasVisibleChildren(subdd))
    {
      return TRUE;
    }
  }
  return FALSE;
Dimitri van Heesch's avatar
Dimitri van Heesch committed
597 598
}

599 600 601 602 603 604
//----------------------------------------------------------------------------
static void writeDirTreeNode(OutputList &ol, DirDef *dd, int level, FTVHelp* ftv,bool addToIndex)
{
  if (level>20)
  {
    warn(dd->getDefFileName(),dd->getDefLine(),
605
        "maximum nesting level exceeded for directory %s: "
606 607 608 609 610
        "check for possible recursive directory relation!\n",dd->name().data()
        );
    return;
  }

Dimitri van Heesch's avatar
Dimitri van Heesch committed
611 612 613 614 615
  if (!dirHasVisibleChildren(dd))
  {
    return;
  }

616 617 618 619 620 621 622 623
  static bool tocExpand = TRUE; //Config_getBool("TOC_EXPAND");
  bool isDir = dd->subDirs().count()>0 || // there are subdirs
               (tocExpand &&              // or toc expand and
                dd->getFiles() && dd->getFiles()->count()>0 // there are files
               );
  //printf("gd=`%s': pageDict=%d\n",gd->name().data(),gd->pageDict->count());
  if (addToIndex)
  {
624 625
    Doxygen::indexList->addContentsItem(isDir,dd->shortName(),dd->getReference(),dd->getOutputFileBase(),0,TRUE,TRUE); 
    Doxygen::indexList->incContentsDepth();
626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664
  }
  if (ftv)
  {
    ftv->addContentsItem(isDir,dd->shortName(),dd->getReference(),
                         dd->getOutputFileBase(),0,FALSE,TRUE,dd); 
    ftv->incContentsDepth();
  }

  ol.startIndexListItem();
  ol.startIndexItem(dd->getReference(),dd->getOutputFileBase());
  ol.parseText(dd->shortName());
  ol.endIndexItem(dd->getReference(),dd->getOutputFileBase());
  if (dd->isReference()) 
  { 
    ol.startTypewriter(); 
    ol.docify(" [external]");
    ol.endTypewriter();
  }

  // write sub directories
  if (dd->subDirs().count()>0)
  {
    startIndexHierarchy(ol,level+1);
    QListIterator<DirDef> dli(dd->subDirs());
    DirDef *subdd = 0;
    for (dli.toFirst();(subdd=dli.current());++dli)
    {
      writeDirTreeNode(ol,subdd,level+1,ftv,addToIndex);
    }
    endIndexHierarchy(ol,level+1); 
  }

  FileList *fileList=dd->getFiles();
  int fileCount=0;
  if (fileList && fileList->count()>0)
  { 
    FileDef *fd=fileList->first();
    while (fd)
    {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
665 666 667 668 669 670 671 672 673 674 675
      //static bool allExternals = Config_getBool("ALLEXTERNALS");
      //if ((allExternals && fd->isLinkable()) || fd->isLinkableInProject())
      //{
      //  fileCount++;
      //}
      bool genSourceFile;
      if (fileVisibleInIndex(fd,genSourceFile))
      {
        fileCount++;
      }
      else if (genSourceFile)
676 677 678 679 680 681 682 683 684 685 686
      {
        fileCount++;
      }
      fd=fileList->next();
    }
    if (fileCount>0)
    {
      startIndexHierarchy(ol,level+1);
      fd=fileList->first();
      while (fd)
      {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
687 688
        bool doc,src;
        doc = fileVisibleInIndex(fd,src);
689 690 691 692 693 694 695
        QCString reference;
        QCString outputBase;
        if (doc) 
        {
          reference  = fd->getReference();
          outputBase = fd->getOutputFileBase();
        }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
696
        if (doc || src)
697 698
        {
          ol.startIndexListItem();
699
          ol.startIndexItem(reference,outputBase);
700
          ol.parseText(fd->displayName());
701
          ol.endIndexItem(reference,outputBase);
702
          ol.endIndexListItem();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
703
          if (ftv && (src || doc))
Dimitri van Heesch's avatar
Dimitri van Heesch committed
704 705 706
          {
            ftv->addContentsItem(FALSE,
                fd->displayName(),
707 708
                reference,outputBase,
                0,FALSE,FALSE,fd); 
Dimitri van Heesch's avatar
Dimitri van Heesch committed
709
          }
710 711 712 713 714 715 716 717 718 719 720 721 722 723 724
        }
        fd=fileList->next();
      }
      endIndexHierarchy(ol,level+1); 
    }
  }

  if (tocExpand && addToIndex)
  {
    // write files of this directory
    if (fileCount>0)
    {
      FileDef *fd=fileList->first();
      while (fd)
      {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
725 726 727 728 729 730 731 732 733
        //static bool allExternals = Config_getBool("ALLEXTERNALS");
        //if ((allExternals && fd->isLinkable()) || fd->isLinkableInProject())
        bool doc,src;
        doc = fileVisibleInIndex(fd,src);
        if (doc)
        {
          addMembersToIndex(fd,LayoutDocManager::File,fd->displayName(),QCString(),TRUE);
        }
        else if (src)
734
        {
735
          Doxygen::indexList->addContentsItem(
Dimitri van Heesch's avatar
Dimitri van Heesch committed
736 737
               FALSE, convertToHtml(fd->name(),TRUE), 0, 
               fd->getSourceFileBase(), 0, FALSE, TRUE, fd);
738 739 740 741 742 743 744 745 746
        }
        fd=fileList->next();
      }
    }
  }
  ol.endIndexListItem();

  if (addToIndex)
  {
747
    Doxygen::indexList->decContentsDepth();
748 749 750 751 752 753 754 755 756 757 758 759 760 761
  }
  if (ftv)
  {
    ftv->decContentsDepth();
  }
}

static void writeDirHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex)
{
  if (ftv)
  {
    ol.pushGeneratorState(); 
    ol.disable(OutputGenerator::Html);
  }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
762
  static bool fullPathNames = Config_getBool("FULL_PATH_NAMES");
763
  startIndexHierarchy(ol,0);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
764
  if (fullPathNames)
765
  {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
766 767 768
    SDict<DirDef>::Iterator dli(*Doxygen::directories);
    DirDef *dd;
    for (dli.toFirst();(dd=dli.current());++dli)
769
    {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
770 771 772 773
      if (dd->getOuterScope()==Doxygen::globalScope) 
      {
        writeDirTreeNode(ol,dd,0,ftv,addToIndex);
      }
774 775 776 777 778 779 780 781 782 783 784 785
    }
  }
  if (ftv)
  {
    FileNameListIterator fnli(*Doxygen::inputNameList); 
    FileName *fn;
    for (fnli.toFirst();(fn=fnli.current());++fnli)
    {
      FileNameIterator fni(*fn);
      FileDef *fd;
      for (;(fd=fni.current());++fni)
      {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
786
        static bool fullPathNames = Config_getBool("FULL_PATH_NAMES");
Dimitri van Heesch's avatar
Dimitri van Heesch committed
787
        if (!fullPathNames || fd->getDirDef()==0) // top level file
788
        {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
789 790
          bool doc,src;
          doc = fileVisibleInIndex(fd,src);
791
          QCString reference, outputBase;
Dimitri van Heesch's avatar
Dimitri van Heesch committed
792
          if (doc)
793
          {
794 795
            reference = fd->getReference();
            outputBase = fd->getOutputFileBase();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
796
          }
797 798 799 800 801 802
          if (doc || src)
          {
            ftv->addContentsItem(FALSE,fd->displayName(),          
                                 reference, outputBase, 0,         
                                 FALSE,FALSE,fd);
          }
803
          if (addToIndex)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
804
          {
805 806 807 808 809 810
            if (doc)
            {
              addMembersToIndex(fd,LayoutDocManager::File,fd->displayName(),QCString(),TRUE);
            }
            else if (src)
            {
811
              Doxygen::indexList->addContentsItem(
812 813 814
                  FALSE, convertToHtml(fd->name(),TRUE), 0, 
                  fd->getSourceFileBase(), 0, FALSE, TRUE, fd);
            }
815 816 817 818 819 820 821 822 823 824 825 826 827
          }
        }
      }
    }
  }
  endIndexHierarchy(ol,0); 
  if (ftv)
  {
    ol.popGeneratorState(); 
  }
}


Dimitri van Heesch's avatar
Dimitri van Heesch committed
828 829
//----------------------------------------------------------------------------

830
static void writeClassTreeForList(OutputList &ol,ClassSDict *cl,bool &started,FTVHelp* ftv,bool addToIndex)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
831
{
832
  ClassSDict::Iterator cli(*cl);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
833 834 835
  for (;cli.current(); ++cli)
  {
    ClassDef *cd=cli.current();
836 837 838 839 840
    //printf("class %s hasVisibleRoot=%d isVisibleInHierarchy=%d\n",
    //             cd->name().data(),
    //              hasVisibleRoot(cd->baseClasses()),
    //              cd->isVisibleInHierarchy()
    //      );
Dimitri van Heesch's avatar
Dimitri van Heesch committed
841
    bool b;
Dimitri van Heesch's avatar
Dimitri van Heesch committed
842
    if (cd->getLanguage()==SrcLangExt_VHDL)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
843
    {
844
      if (!(VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS)      
Dimitri van Heesch's avatar
Dimitri van Heesch committed
845 846 847 848 849 850 851 852 853 854 855
      {
        continue;
      }
      b=!hasVisibleRoot(cd->subClasses());
    }
    else
    {
      b=!hasVisibleRoot(cd->baseClasses());
    }

    if (b)  //filter on root classes
Dimitri van Heesch's avatar
Dimitri van Heesch committed
856
    {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
857
      if (cd->isVisibleInHierarchy()) // should it be visible
Dimitri van Heesch's avatar
Dimitri van Heesch committed
858 859 860
      {
        if (!started)
        {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
861
          startIndexHierarchy(ol,0);
862 863
          if (addToIndex)
          {
864
            Doxygen::indexList->incContentsDepth();
865
          }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
866 867
          started=TRUE;
        }
868
        ol.startIndexListItem();
869 870
        bool hasChildren = !cd->visited && classHasVisibleChildren(cd); 
        //printf("list: Has children %s: %d\n",cd->name().data(),hasChildren);
871
        if (cd->isLinkable())
Dimitri van Heesch's avatar
Dimitri van Heesch committed
872
        {
873 874
          //printf("Writing class %s isLinkable()=%d isLinkableInProject()=%d cd->templateMaster()=%p\n",
          //    cd->displayName().data(),cd->isLinkable(),cd->isLinkableInProject(),cd->templateMaster());
875 876 877
          ol.startIndexItem(cd->getReference(),cd->getOutputFileBase());
          ol.parseText(cd->displayName());
          ol.endIndexItem(cd->getReference(),cd->getOutputFileBase());
Dimitri van Heesch's avatar
Dimitri van Heesch committed
878 879 880 881 882 883
          if (cd->isReference()) 
          {
            ol.startTypewriter(); 
            ol.docify(" [external]");
            ol.endTypewriter();
          }
884 885
          if (addToIndex)
          {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
886
            if (cd->getLanguage()!=SrcLangExt_VHDL) // prevents double insertion in Design Unit List
887
            	  Doxygen::indexList->addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE);
888
          }
889
          if (ftv)
890
          {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
891
            ftv->addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE,cd); 
892
          }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
893 894 895
        }
        else
        {
896 897 898
          ol.startIndexItem(0,0);
          ol.parseText(cd->displayName());
          ol.endIndexItem(0,0);
899 900
          if (addToIndex)
          {
901
            Doxygen::indexList->addContentsItem(hasChildren,cd->displayName(),0,0,0,FALSE,FALSE);
902
          }
903
          if (ftv)
904
          {
905
            ftv->addContentsItem(hasChildren,cd->displayName(),0,0,0,FALSE,FALSE,cd); 
906
          }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
907
        }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
908
        if (cd->getLanguage()==SrcLangExt_VHDL && hasChildren) 
Dimitri van Heesch's avatar
Dimitri van Heesch committed
909
        {
910
          writeClassTree(ol,cd->baseClasses(),cd->visited,1,ftv,addToIndex);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
911 912 913
          cd->visited=TRUE;
        }
        else if (hasChildren)
914
        {
915
          writeClassTree(ol,cd->subClasses(),cd->visited,1,ftv,addToIndex);
916 917
          cd->visited=TRUE;
        }
918
        ol.endIndexListItem();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
919 920 921
      }
    }
  }
922 923
}

924
static void writeClassHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex)
925
{
926 927
  initClassHierarchy(Doxygen::classSDict);
  initClassHierarchy(Doxygen::hiddenClasses);
928 929 930 931 932
  if (ftv)
  {
    ol.pushGeneratorState(); 
    ol.disable(OutputGenerator::Html);
  }
933
  bool started=FALSE;
934 935
  writeClassTreeForList(ol,Doxygen::classSDict,started,ftv,addToIndex);
  writeClassTreeForList(ol,Doxygen::hiddenClasses,started,ftv,addToIndex);
936 937
  if (started) 
  {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
938
    endIndexHierarchy(ol,0);
939 940
    if (addToIndex)
    {
941
      Doxygen::indexList->decContentsDepth();
942
    }
943
  }
944
  if (ftv)
945
  {
946
    ol.popGeneratorState(); 
947
  }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
948 949 950 951
}

//----------------------------------------------------------------------------

952 953 954 955 956 957 958 959 960 961 962
static int countClassesInTreeList(const ClassSDict &cl)
{
  int count=0;
  ClassSDict::Iterator cli(cl);
  for (;cli.current(); ++cli)
  {
    ClassDef *cd=cli.current();
    if (!hasVisibleRoot(cd->baseClasses())) // filter on root classes
    {
      if (cd->isVisibleInHierarchy()) // should it be visible
      {
963
        if (cd->subClasses()) // should have sub classes
Dimitri van Heesch's avatar
Dimitri van Heesch committed
964 965 966
        {
          count++;
        }
967 968 969 970 971 972
      }
    }
  }
  return count;
}

973
static int countClassHierarchy()
Dimitri van Heesch's avatar
Dimitri van Heesch committed
974
{
975
  int count=0;
976 977 978 979
  initClassHierarchy(Doxygen::classSDict);
  initClassHierarchy(Doxygen::hiddenClasses);
  count+=countClassesInTreeList(*Doxygen::classSDict);
  count+=countClassesInTreeList(*Doxygen::hiddenClasses);
980
  return count;
Dimitri van Heesch's avatar
Dimitri van Heesch committed
981 982 983 984
}

//----------------------------------------------------------------------------

985
static void writeHierarchicalIndex(OutputList &ol)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
986 987
{
  if (hierarchyClasses==0) return;
Dimitri van Heesch's avatar
Dimitri van Heesch committed
988
  ol.pushGeneratorState();
989
  //1.{
Dimitri van Heesch's avatar
Dimitri van Heesch committed
990
  ol.disable(OutputGenerator::Man);
991

992
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassHierarchy);
993
  QCString title = lne ? lne->title() : theTranslator->trClassHierarchy();
994 995
  bool addToIndex = lne==0 || lne->visible();

996
  startFile(ol,"hierarchy",0, title, HLI_Hierarchy);
997
  startTitle(ol,0);
998
  ol.parseText(title);
999
  endTitle(ol,0,0);
1000
  ol.startContents();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1001
  ol.startTextBlock();
1002

1003
  if (Config_getBool("HAVE_DOT") && Config_getBool("GRAPHICAL_HIERARCHY"))
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1004 1005 1006
  {
    ol.disable(OutputGenerator::Latex);
    ol.disable(OutputGenerator::RTF);
1007
    ol.startParagraph();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1008
    ol.startTextLink("inherits",0);
1009
    ol.parseText(theTranslator->trGotoGraphicalHierarchy());
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1010
    ol.endTextLink();
1011
    ol.endParagraph();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1012 1013 1014
    ol.enable(OutputGenerator::Latex);
    ol.enable(OutputGenerator::RTF);
  }
1015
  ol.parseText(lne ? lne->intro() : theTranslator->trClassHierarchyDescription());
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1016
  ol.endTextBlock();
1017

1018 1019 1020 1021 1022 1023
  // ---------------
  // Static class hierarchy for Latex/RTF
  // ---------------
  ol.pushGeneratorState();
  //2.{
  ol.disable(OutputGenerator::Html);
1024
  Doxygen::indexList->disable();
1025

1026 1027
  writeClassHierarchy(ol,0,addToIndex);

1028
  Doxygen::indexList->enable();
1029 1030 1031 1032 1033 1034 1035 1036 1037
  ol.popGeneratorState();
  //2.}

  // ---------------
  // Dynamic class hierarchical index for HTML
  // ---------------
  ol.pushGeneratorState(); 
  //2.{
  ol.disableAllBut(OutputGenerator::Html);
1038 1039

  {
1040 1041
    if (addToIndex)
    {
1042
      Doxygen::indexList->addContentsItem(TRUE,title,0,"hierarchy",0,TRUE,TRUE); 
1043 1044 1045
    }
    FTVHelp* ftv = new FTVHelp(FALSE);
    writeClassHierarchy(ol,ftv,addToIndex);
1046 1047 1048
    QGString outStr;
    FTextStream t(&outStr);
    ftv->generateTreeViewInline(t);
1049 1050
    ol.pushGeneratorState(); 
    ol.disableAllBut(OutputGenerator::Html);
1051
    ol.writeString(outStr);
1052 1053 1054
    ol.popGeneratorState();
    delete ftv;
  }
1055 1056 1057 1058
  ol.popGeneratorState();
  //2.}
  // ------

Dimitri van Heesch's avatar
Dimitri van Heesch committed
1059
  endFile(ol);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1060
  ol.popGeneratorState();
1061
  //1.}
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1062 1063 1064 1065
}

//----------------------------------------------------------------------------

1066
static void writeGraphicalClassHierarchy(OutputList &ol)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1067 1068 1069
{
  if (hierarchyClasses==0) return;
  ol.disableAllBut(OutputGenerator::Html);
1070
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassHierarchy);
1071
  QCString title = lne ? lne->title() : theTranslator->trClassHierarchy();
1072
  startFile(ol,"inherits",0,title,HLI_Hierarchy,FALSE,"hierarchy");
1073
  startTitle(ol,0);
1074
  ol.parseText(title);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1075
  endTitle(ol,0,0);
1076
  ol.startContents();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1077
  ol.startTextBlock();
1078
  ol.startParagraph();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1079
  ol.startTextLink("hierarchy",0);
1080
  ol.parseText(theTranslator->trGotoTextualHierarchy());
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1081
  ol.endTextLink();
1082
  ol.endParagraph();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1083 1084 1085 1086 1087
  ol.endTextBlock();
  DotGfxHierarchyTable g;
  ol.writeGraphicalHierarchy(g);
  endFile(ol);
  ol.enableAll();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1088 1089 1090 1091
}

//----------------------------------------------------------------------------

1092
static void countFiles(int &htmlFiles,int &files)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1093
{
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1094 1095
  htmlFiles=0;
  files=0;
1096
  FileNameListIterator fnli(*Doxygen::inputNameList);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1097 1098 1099 1100 1101 1102 1103
  FileName *fn;
  for (;(fn=fnli.current());++fnli)
  {
    FileNameIterator fni(*fn);
    FileDef *fd;
    for (;(fd=fni.current());++fni)
    {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1104 1105 1106
      bool doc,src;
      doc = fileVisibleInIndex(fd,src);
      if (doc || src)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1107
      {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1108 1109 1110 1111 1112
        htmlFiles++;
      }
      if (doc)
      {
        files++;
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1113
      }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1114 1115 1116 1117 1118 1119
    }
  }
}

//----------------------------------------------------------------------------

1120
static void writeFileIndex(OutputList &ol)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1121
{
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1122
  if (documentedHtmlFiles==0) return;
1123

Dimitri van Heesch's avatar
Dimitri van Heesch committed
1124
  ol.pushGeneratorState();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1125
  ol.disable(OutputGenerator::Man);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1126
  if (documentedFiles==0) ol.disableAllBut(OutputGenerator::Html);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1127

1128 1129 1130
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::FileList);
  if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Files); // fall back
  QCString title = lne ? lne->title() : theTranslator->trFileList();
1131 1132
  bool addToIndex = lne==0 || lne->visible();

1133
  startFile(ol,"files",0,title,HLI_Files);
1134
  startTitle(ol,0);
1135 1136 1137 1138
  //if (!Config_getString("PROJECT_NAME").isEmpty()) 
  //{
  //  title.prepend(Config_getString("PROJECT_NAME")+" ");
  //}
1139
  ol.parseText(title);
1140
  endTitle(ol,0,0);
1141
  ol.startContents();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1142
  ol.startTextBlock();
1143 1144 1145

  if (addToIndex)
  {
1146 1147
    Doxygen::indexList->addContentsItem(TRUE,title,0,"files",0,TRUE,TRUE); 
    Doxygen::indexList->incContentsDepth();
1148 1149
  }

1150
  ol.parseText(lne ? lne->intro() : theTranslator->trFileListDescription(Config_getBool("EXTRACT_ALL")));
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1151
  ol.endTextBlock();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1152

1153 1154 1155 1156 1157 1158 1159 1160
  // ---------------
  // Flat file index
  // ---------------

  // 1. {
  ol.pushGeneratorState();
  ol.disable(OutputGenerator::Html);

1161 1162 1163 1164
  OutputNameDict outputNameDict(1009);
  OutputNameList outputNameList;
  outputNameList.setAutoDelete(TRUE);
  
1165
  if (Config_getBool("FULL_PATH_NAMES"))
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1166
  {
1167
    // re-sort input files in (dir,file) output order instead of (file,dir) input order 
1168
    FileName *fn=Doxygen::inputNameList->first();
1169
    while (fn)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1170
    {
1171 1172
      FileDef *fd=fn->first();
      while (fd)
1173
      {
1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190
        QCString path=fd->getPath();
        if (path.isEmpty()) path="[external]";
        FileList *fl = outputNameDict.find(path);
        if (fl)
        {
          fl->inSort(fd);
          //printf("+ inserting %s---%s\n",fd->getPath().data(),fd->name().data());
        }
        else
        {
          //printf("o inserting %s---%s\n",fd->getPath().data(),fd->name().data());
          fl = new FileList(path);
          fl->inSort(fd);
          outputNameList.inSort(fl);
          outputNameDict.insert(path,fl);
        }
        fd=fn->next();
1191
      }
1192
      fn=Doxygen::inputNameList->next();
1193 1194 1195 1196
    }
  }
  
  ol.startIndexList();
1197
  FileList *fl=0;
1198
  if (Config_getBool("FULL_PATH_NAMES"))
1199 1200 1201 1202 1203
  {
    fl = outputNameList.first();
  }
  else
  {
1204
    fl = Doxygen::inputNameList->first();
1205
  }
1206 1207 1208 1209 1210 1211
  while (fl)
  {
    FileDef *fd=fl->first();
    while (fd)
    {
      //printf("Found filedef %s\n",fd->name().data());
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1212
      bool doc = fd->isLinkableInProject();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1213
      bool src = fd->generateSourceFile();
1214
      bool nameOk = !fd->isDocumentationFile();
1215 1216
      if (nameOk && (doc || src) && 
              !fd->isReference())
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1217
      {
1218
        QCString path;
1219
        if (Config_getBool("FULL_PATH_NAMES")) 
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1220
        {
1221
          path=stripFromPath(fd->getPath().copy());
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1222
        }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1223
        QCString fullName=fd->name();
1224 1225 1226 1227 1228
        if (!path.isEmpty()) 
        {
          if (path.at(path.length()-1)!='/') fullName.prepend("/");
          fullName.prepend(path);
        }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1229

1230
        ol.startIndexKey();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1231 1232 1233 1234
        ol.docify(path);
        if (doc)
        {
          ol.writeObjectLink(0,fd->getOutputFileBase(),0,fd->name());
1235 1236 1237 1238
          //if (addToIndex)
          //{
          //  addMembersToIndex(fd,LayoutDocManager::File,fullName,QCString());
          //}
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1239 1240 1241
        }
        else
        {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1242 1243 1244
          ol.startBold();
          ol.docify(fd->name());
          ol.endBold();
1245 1246
          //if (addToIndex)
          //{
1247
          //  Doxygen::indexList->addContentsItem(FALSE,fullName,0,0,0);
1248
          //}
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1249
        }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1250 1251
        if (src)
        {
1252 1253
          ol.pushGeneratorState();
          ol.disableAllBut(OutputGenerator::Html);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1254 1255 1256
          ol.docify(" ");
          ol.startTextLink(fd->includeName(),0);
          ol.docify("[");
1257
          ol.parseText(theTranslator->trCode());
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1258 1259
          ol.docify("]");
          ol.endTextLink();
1260
          ol.popGeneratorState();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1261
        }
1262
        ol.endIndexKey();
1263 1264 1265
        bool hasBrief = !fd->briefDescription().isEmpty();
        ol.startIndexValue(hasBrief);
        if (hasBrief)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1266
        {
1267
          //ol.docify(" (");
1268
          ol.generateDoc(
1269
              fd->briefFile(),fd->briefLine(),
1270
              fd,0,
1271
              fd->briefDescription(TRUE),
1272
              FALSE, // index words
1273 1274
              FALSE, // isExample
              0,     // example name
1275 1276
              TRUE,  // single line
              TRUE   // link from index
1277
             );
1278
          //ol.docify(")");
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1279
        }
1280
        ol.endIndexValue(fd->getOutputFileBase(),hasBrief);
1281
        //ol.popGeneratorState();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1282
        // --------------------------------------------------------
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1283
      }
1284
      fd=fl->next();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1285
    }
1286
    if (Config_getBool("FULL_PATH_NAMES"))
1287 1288 1289 1290 1291
    {
      fl=outputNameList.next();
    }
    else
    {
1292
      fl=Doxygen::inputNameList->next();
1293
    }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1294 1295
  }
  ol.endIndexList();
1296

1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316
  // 1. }
  ol.popGeneratorState();

  // ---------------
  // Hierarchical file index for HTML
  // ---------------
  ol.pushGeneratorState(); 
  ol.disableAllBut(OutputGenerator::Html);

  FTVHelp* ftv = new FTVHelp(FALSE);
  writeDirHierarchy(ol,ftv,addToIndex);
  QGString outStr;
  FTextStream t(&outStr);
  ftv->generateTreeViewInline(t);
  ol.writeString(outStr);
  delete ftv;

  ol.popGeneratorState();
  // ------

1317 1318
  if (addToIndex)
  {
1319
    Doxygen::indexList->decContentsDepth();
1320 1321
  }

1322
  endFile(ol);
1323
  ol.popGeneratorState();
1324 1325
}

Dimitri van Heesch's avatar
Dimitri van Heesch committed
1326
//----------------------------------------------------------------------------
1327
static int countNamespaces()
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1328 1329
{
  int count=0;
1330
  NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1331 1332 1333
  NamespaceDef *nd;
  for (;(nd=nli.current());++nli)
  {
1334
    if (nd->isLinkableInProject()) count++;
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1335 1336 1337 1338 1339 1340
  }
  return count;
}

//----------------------------------------------------------------------------

1341 1342 1343 1344 1345 1346 1347 1348
void writeClassTree(ClassSDict *clDict,FTVHelp *ftv,bool addToIndex,bool globalOnly)
{
  if (clDict)
  {
    ClassSDict::Iterator cli(*clDict);
    ClassDef *cd;
    for (;(cd=cli.current());++cli)
    {
1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363
      if (cd->getLanguage()==SrcLangExt_VHDL) 
      {
        if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKAGECLASS || 
            (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS
           )// no architecture
        {
          continue;
        }
        if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ARCHITECTURECLASS)
        {
          QCString n=cd->name();
          cd->setClassName(n.data());
        }         
      }

1364
      if (!globalOnly || 
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1365 1366 1367
           cd->getOuterScope()==0 || 
           cd->getOuterScope()==Doxygen::globalScope 
         ) 
1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381
      {
        int count=0;
        if (cd->getClassSDict())
        {
          ClassSDict::Iterator ccit(*cd->getClassSDict());
          ClassDef *ccd;
          for (;(ccd=ccit.current());++ccit)
          {
            if (ccd->isLinkableInProject() && ccd->templateMaster()==0) 
            {
              count++;
            }
          }
        }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1382
        if (classVisibleInIndex(cd) && cd->templateMaster()==0) 
1383
        { 
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1384 1385
          ftv->addContentsItem(count>0,cd->displayName(FALSE),cd->getReference(),
              cd->getOutputFileBase(),cd->anchor(),FALSE,TRUE,cd); 
1386
          if (addToIndex && 
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1387
              /*cd->partOfGroups()==0 &&*/
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1388 1389 1390 1391
              (cd->getOuterScope()==0 || 
               cd->getOuterScope()->definitionType()!=Definition::TypeClass
              )
             )
1392
          {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1393
            addMembersToIndex(cd,LayoutDocManager::Class,cd->displayName(FALSE),cd->anchor(),cd->partOfGroups()==0);
1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406
          }
          if (count>0)
          {
            ftv->incContentsDepth();
            writeClassTree(cd->getClassSDict(),ftv,addToIndex,FALSE);
            ftv->decContentsDepth();
          }
        }
      }
    }
  }
}

Dimitri van Heesch's avatar
Dimitri van Heesch committed
1407 1408 1409 1410 1411 1412 1413 1414
static bool containsVisibleChild(NamespaceDef *nd,bool includeClasses)
{
  if (nd->getNamespaceSDict())
  {
    NamespaceSDict::Iterator cnli(*nd->getNamespaceSDict());
    NamespaceDef *cnd;
    for (cnli.toFirst();(cnd=cnli.current());++cnli)
    {
1415
      if (cnd->isLinkable() && cnd->localName().find('@')==-1)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439
      {
        return TRUE;
      }
      else if (containsVisibleChild(cnd,includeClasses))
      {
        return TRUE;
      }
    }
  }
  if (includeClasses && nd->getClassSDict())
  {
    ClassSDict::Iterator cli(*nd->getClassSDict());
    ClassDef *cd;
    for (;(cd=cli.current());++cli)
    {
      if (cd->isLinkableInProject() && cd->templateMaster()==0) 
      { 
        return TRUE;
      }
    }
  }
  return FALSE;
}

1440 1441 1442 1443 1444 1445 1446 1447 1448
static void writeNamespaceTree(NamespaceSDict *nsDict,FTVHelp *ftv,
                               bool rootOnly,bool showClasses,bool addToIndex)
{
  if (nsDict)
  {
    NamespaceSDict::Iterator nli(*nsDict);
    NamespaceDef *nd;
    for (nli.toFirst();(nd=nli.current());++nli)
    {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1449
      if (nd->localName().find('@')==-1 && 
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1450
          (!rootOnly || nd->getOuterScope()==Doxygen::globalScope))
1451 1452
      {

Dimitri van Heesch's avatar
Dimitri van Heesch committed
1453
        bool hasChildren = containsVisibleChild(nd,showClasses);
1454 1455
        bool isLinkable  = nd->isLinkableInProject();

Dimitri van Heesch's avatar
Dimitri van Heesch committed
1456 1457
        QCString ref; 
        QCString file; 
1458
        if (isLinkable)
1459
        {
1460
          ref  = nd->getReference();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1461 1462 1463
          file = nd->getOutputFileBase();
          if (nd->getLanguage()==SrcLangExt_VHDL) // UGLY HACK
          {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1464
            file=file.replace(0,qstrlen("namespace"),"class");
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1465
          }
1466
        }
1467

1468
        if (isLinkable || hasChildren)
1469
        {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1470
          ftv->addContentsItem(hasChildren,nd->localName(),ref,file,0,FALSE,TRUE,nd); 
1471

Dimitri van Heesch's avatar
Dimitri van Heesch committed
1472
          if (addToIndex)
1473
          {
1474
            Doxygen::indexList->addContentsItem(hasChildren,nd->localName(),ref,file,QCString(),
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1475 1476 1477 1478 1479 1480 1481
                hasChildren && !file.isEmpty(),addToIndex);
          }

          //printf("*** writeNamespaceTree count=%d addToIndex=%d showClasses=%d classCount=%d\n",
          //    count,addToIndex,showClasses,classCount);
          if (hasChildren)
          {
1482
            if (addToIndex) Doxygen::indexList->incContentsDepth();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1483 1484 1485 1486 1487 1488 1489
            ftv->incContentsDepth();
            writeNamespaceTree(nd->getNamespaceSDict(),ftv,FALSE,showClasses,addToIndex);
            if (showClasses) 
            {
              writeClassTree(nd->getClassSDict(),ftv,addToIndex,FALSE);
            }
            ftv->decContentsDepth();
1490
            if (addToIndex) Doxygen::indexList->decContentsDepth();
1491 1492 1493 1494 1495 1496 1497 1498
          }
        }
      }
    }
  }
}


1499
static void writeNamespaceIndex(OutputList &ol)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1500 1501
{
  if (documentedNamespaces==0) return;
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1502
  ol.pushGeneratorState();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1503
  ol.disable(OutputGenerator::Man);
1504 1505 1506
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::NamespaceList);
  if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Namespaces); // fall back
  QCString title = lne ? lne->title() : theTranslator->trNamespaceList();
1507
  bool addToIndex = lne==0 || lne->visible();
1508
  startFile(ol,"namespaces",0,title,HLI_Namespaces);
1509
  startTitle(ol,0);
1510
  ol.parseText(title);
1511
  endTitle(ol,0,0);
1512
  ol.startContents();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1513
  ol.startTextBlock();
1514
  ol.parseText(lne ? lne->intro() : theTranslator->trNamespaceListDescription(Config_getBool("EXTRACT_ALL")));
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1515
  ol.endTextBlock();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1516

Dimitri van Heesch's avatar
Dimitri van Heesch committed
1517
  bool first=TRUE;
1518

1519 1520 1521 1522 1523 1524
  // ---------------
  // Linear namespace index for Latex/RTF
  // ---------------
  ol.pushGeneratorState();
  ol.disable(OutputGenerator::Html);
  
1525
  NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
1526 1527
  NamespaceDef *nd;
  for (nli.toFirst();(nd=nli.current());++nli)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1528
  {
1529
    if (nd->isLinkableInProject())
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1530
    {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1531 1532 1533 1534 1535
      if (first)
      {
        ol.startIndexList();
        first=FALSE;
      }
1536 1537
      //ol.writeStartAnnoItem("namespace",nd->getOutputFileBase(),0,nd->name());
      ol.startIndexKey();
1538 1539
      if (nd->getLanguage()==SrcLangExt_VHDL)
      {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1540
        ol.writeObjectLink(0, nd->getOutputFileBase().replace(0,qstrlen("namespace"),"class"),0,nd->displayName());
1541 1542 1543 1544 1545
      }
      else
      {
        ol.writeObjectLink(0,nd->getOutputFileBase(),0,nd->displayName());
      }
1546
      ol.endIndexKey();
1547

1548 1549 1550
      bool hasBrief = !nd->briefDescription().isEmpty();
      ol.startIndexValue(hasBrief);
      if (hasBrief)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1551
      {
1552
        //ol.docify(" (");
1553
        ol.generateDoc(
1554
                 nd->briefFile(),nd->briefLine(),
1555
                 nd,0,
1556
                 nd->briefDescription(TRUE),
1557
                 FALSE, // index words
1558 1559 1560 1561
                 FALSE, // isExample
                 0,     // example name
                 TRUE,  // single line
                 TRUE   // link from index
1562
                );
1563
        //ol.docify(")");
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1564
      }
1565
      ol.endIndexValue(nd->getOutputFileBase(),hasBrief);
1566

Dimitri van Heesch's avatar
Dimitri van Heesch committed
1567 1568
    }
  }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1569
  if (!first) ol.endIndexList();
1570 1571 1572 1573 1574 1575 1576 1577 1578

  ol.popGeneratorState();

  // ---------------
  // Hierarchical namespace index for HTML
  // ---------------
  ol.pushGeneratorState(); 
  ol.disableAllBut(OutputGenerator::Html);

1579
  {
1580 1581
    if (addToIndex)
    {
1582 1583
      Doxygen::indexList->addContentsItem(TRUE,title,0,"namespaces",0,TRUE,TRUE); 
      Doxygen::indexList->incContentsDepth();
1584 1585
    }
    FTVHelp* ftv = new FTVHelp(FALSE);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1586
    writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,FALSE,addToIndex);
1587 1588 1589 1590 1591 1592 1593
    QGString outStr;
    FTextStream t(&outStr);
    ftv->generateTreeViewInline(t);
    ol.writeString(outStr);
    delete ftv;
    if (addToIndex)
    {
1594
      Doxygen::indexList->decContentsDepth();
1595
    }
1596
  }
1597 1598 1599 1600

  ol.popGeneratorState();
  // ------

Dimitri van Heesch's avatar
Dimitri van Heesch committed
1601
  endFile(ol);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1602
  ol.popGeneratorState();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1603 1604 1605 1606
}

//----------------------------------------------------------------------------

1607
static int countAnnotatedClasses(int *cp)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1608 1609
{
  int count=0;
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1610
  int countPrinted=0;
1611
  ClassSDict::Iterator cli(*Doxygen::classSDict);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1612 1613 1614
  ClassDef *cd;
  for (;(cd=cli.current());++cli)
  {
1615
    if (cd->isLinkableInProject() && cd->templateMaster()==0) 
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1616
    { 
1617
      if (!cd->isEmbeddedInOuterScope())
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1618 1619 1620
      {
        countPrinted++;
      }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1621 1622 1623
      count++; 
    }
  }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1624
  *cp = countPrinted;
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1625 1626 1627
  return count;
}

Dimitri van Heesch's avatar
Dimitri van Heesch committed
1628

1629
static void writeAnnotatedClassList(OutputList &ol)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1630
{
1631 1632
  //LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassList);
  //bool addToIndex = lne==0 || lne->visible();
1633

Dimitri van Heesch's avatar
Dimitri van Heesch committed
1634
  ol.startIndexList(); 
1635
  ClassSDict::Iterator cli(*Doxygen::classSDict);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1636
  ClassDef *cd;
1637 1638 1639
  
  for (cli.toFirst();(cd=cli.current());++cli)
  {
1640 1641 1642 1643 1644
    if (cd->getLanguage()==SrcLangExt_VHDL && 
        ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKAGECLASS || 
         (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS)
       ) // no architecture
    {
1645
      continue;
1646
    }
1647
 
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1648
    ol.pushGeneratorState();
1649
    if (cd->isEmbeddedInOuterScope())
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1650 1651 1652 1653
    {
      ol.disable(OutputGenerator::Latex);
      ol.disable(OutputGenerator::RTF);
    }
1654
    if (cd->isLinkableInProject() && cd->templateMaster()==0)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1655
    {
1656
      QCString type=cd->compoundTypeString();
1657
      ol.startIndexKey();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1658
      if (cd->getLanguage()==SrcLangExt_VHDL)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1659 1660 1661
      {
        QCString prot= VhdlDocGen::getProtectionName((VhdlDocGen::VhdlClasses)cd->protection());
        ol.docify(prot.data());
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1662
        ol.writeString(" ");
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1663
      }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1664
      ol.writeObjectLink(0,cd->getOutputFileBase(),cd->anchor(),cd->displayName());
1665
      ol.endIndexKey();
1666 1667 1668
      bool hasBrief = !cd->briefDescription().isEmpty();
      ol.startIndexValue(hasBrief);
      if (hasBrief)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1669
      {
1670
        ol.generateDoc(
1671
                 cd->briefFile(),cd->briefLine(),
1672
                 cd,0,
1673
                 cd->briefDescription(TRUE),
1674
                 FALSE,  // indexWords
1675 1676 1677 1678
                 FALSE,  // isExample
                 0,     // example name
                 TRUE,  // single line
                 TRUE   // link from index
1679
                );
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1680
      }
1681
      ol.endIndexValue(cd->getOutputFileBase(),hasBrief);
1682

1683 1684 1685 1686
      //if (addToIndex)
      //{
      //  addMembersToIndex(cd,LayoutDocManager::Class,cd->displayName(),cd->anchor());
      //}
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1687
    }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1688
    ol.popGeneratorState();
1689 1690 1691 1692
  }
  ol.endIndexList();
}

1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711
static QCString letterToLabel(char startLetter)
{
  QCString s(5); 
  if (isId(startLetter))
  {
    s[0]=startLetter; s[1]=0;
  }
  else
  {
    const char hex[]="0123456789abcdef";
    s[0]='0';
    s[1]='x';
    s[2]=hex[startLetter>>4];
    s[3]=hex[startLetter&0xF];
    s[4]=0;
  }
  return s;
}

1712 1713
//----------------------------------------------------------------------------

Dimitri van Heesch's avatar
Dimitri van Heesch committed
1714
/** Special class list where sorting takes IGNORE_PREFIX into account. */
1715 1716 1717
class PrefixIgnoreClassList : public ClassList
{
public:
1718
  virtual int compareItems(QCollection::Item item1, QCollection::Item item2)
1719 1720 1721 1722 1723 1724
  {
    ClassDef *c1=(ClassDef *)item1;
    ClassDef *c2=(ClassDef *)item2;

    QCString n1 = c1->className();
    QCString n2 = c2->className();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1725
    return qstricmp (n1.data()+getPrefixIndex(n1), n2.data()+getPrefixIndex(n2));
1726 1727 1728
  }
};

Dimitri van Heesch's avatar
Dimitri van Heesch committed
1729
/** Class representing a cell in the alphabetical class index. */
1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750
class AlphaIndexTableCell
{
  public:
    AlphaIndexTableCell(int row,int col,uchar letter,ClassDef *cd) : 
      m_letter(letter), m_class(cd), m_row(row), m_col(col) 
    { //printf("AlphaIndexTableCell(%d,%d,%c,%s)\n",row,col,letter!=0 ? letter: '-',
      //       cd!=(ClassDef*)0x8 ? cd->name().data() : "<null>"); 
    }

    ClassDef *classDef() const { return m_class; }
    uchar letter()       const { return m_letter; }
    int row()            const { return m_row; }
    int column()         const { return m_col; }

  private:
    uchar m_letter;
    ClassDef *m_class;
    int m_row;
    int m_col;
};

Dimitri van Heesch's avatar
Dimitri van Heesch committed
1751
/** Class representing a row in the alphabetical class index. */
1752 1753 1754 1755 1756 1757
class AlphaIndexTableRows : public QList<AlphaIndexTableCell>
{
  public:
    AlphaIndexTableRows() { setAutoDelete(TRUE); }
};

Dimitri van Heesch's avatar
Dimitri van Heesch committed
1758
/** Iterator for the cells in a row of the alphabetical class index. */
1759 1760 1761 1762 1763 1764 1765
class AlphaIndexTableRowsIterator : public QListIterator<AlphaIndexTableCell>
{
  public:
    AlphaIndexTableRowsIterator(const AlphaIndexTableRows &list) : 
      QListIterator<AlphaIndexTableCell>(list) {}
};

Dimitri van Heesch's avatar
Dimitri van Heesch committed
1766
/** Class representing the columns in the alphabetical class index. */
1767 1768 1769 1770 1771 1772
class AlphaIndexTableColumns : public QList<AlphaIndexTableRows>
{
  public:
    AlphaIndexTableColumns() { setAutoDelete(TRUE); }
};

1773
// write an alphabetical index of all class with a header for each letter
1774
static void writeAlphabeticalClassList(OutputList &ol)
1775
{
1776 1777 1778
  // What starting letters are used
  bool indexLetterUsed[256];
  memset (indexLetterUsed, 0, sizeof (indexLetterUsed));
1779 1780

  // first count the number of headers
1781
  ClassSDict::Iterator cli(*Doxygen::classSDict);
1782
  ClassDef *cd;
1783
  uint startLetter=0;
1784
  int headerItems=0;
1785
  for (;(cd=cli.current());++cli)
1786
  {
1787
    if (cd->isLinkableInProject() && cd->templateMaster()==0)
1788
    {
1789 1790 1791
      if (cd->getLanguage()==SrcLangExt_VHDL && !((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS ))// no architecture
        continue;
	     
1792
      int index = getPrefixIndex(cd->className());
1793
      //printf("name=%s index=%d %d\n",cd->className().data(),index,cd->protection());
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1794
      startLetter=toupper(cd->className().at(index))&0xFF;
1795 1796 1797 1798
      indexLetterUsed[startLetter] = true;
    }
  }

1799
  // write quick link index (row of letters)
1800
  QCString alphaLinks = "<div class=\"qindex\">";
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1801
  int l;
1802
  for (l=0; l<256; l++)
1803 1804 1805
  {
    if (indexLetterUsed[l])
    {
1806
      if (headerItems) alphaLinks += "&#160;|&#160;";
1807 1808 1809 1810
      headerItems++;
      alphaLinks += (QCString)"<a class=\"qindex\" href=\"#letter_" + 
                    (char)l + "\">" + 
                    (char)l + "</a>";
1811 1812
    }
  }
1813
  alphaLinks += "</div>\n";
1814 1815
  ol.writeString(alphaLinks);

1816 1817

  // the number of columns in the table
1818
  const int columns = Config_getInt("COLS_IN_ALPHA_INDEX");
1819 1820

  int i,j;
1821
  int totalItems = headerItems*2 + annotatedClasses;      // number of items in the table (headers span 2 items)
1822
  int rows = (totalItems + columns - 1)/columns;          // number of rows in the table
1823 1824 1825 1826

  //printf("headerItems=%d totalItems=%d columns=%d rows=%d itemsInLastRow=%d\n",
  //    headerItems,totalItems,columns,rows,itemsInLastRow);

1827 1828
  // Keep a list of classes for each starting letter
  PrefixIgnoreClassList classesByLetter[256];
1829
  AlphaIndexTableColumns tableColumns;
1830 1831

  // fill the columns with the class list (row elements in each column,
1832
  // expect for the columns with number >= itemsInLastRow, which get one
1833 1834 1835 1836
  // item less.
  //int icount=0;
  startLetter=0;
  for (cli.toFirst();(cd=cli.current());++cli)
1837
  {
1838 1839 1840
    if (cd->getLanguage()==SrcLangExt_VHDL && !((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS ))// no architecture
      continue;
    
1841
    if (cd->isLinkableInProject() && cd->templateMaster()==0)
1842
    {
1843
      int index = getPrefixIndex(cd->className());
1844
      startLetter=toupper(cd->className().at(index))&0xFF;
1845 1846
      // Do some sorting again, since the classes are sorted by name with 
      // prefix, which should be ignored really.
1847 1848 1849 1850 1851 1852
      if (cd->getLanguage()==SrcLangExt_VHDL)
      {
        if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS )// no architecture
          classesByLetter[startLetter].inSort(cd);
      }
      else
1853
      classesByLetter[startLetter].inSort(cd);
1854 1855 1856
    }
  }

1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881
  #define NEXT_ROW()                           \
    do                                         \
    {                                          \
      if (row>maxRows) maxRows=row;            \
      if (row>=rows && col<columns)            \
      {                                        \
        col++;                                 \
        row=0;                                 \
        tableRows = new AlphaIndexTableRows;   \
        tableColumns.append(tableRows);        \
      }                                        \
    }                                          \
    while(0)                                   \

  AlphaIndexTableRows *tableRows = new AlphaIndexTableRows;
  tableColumns.append(tableRows);
  int col=0,row=0,maxRows=0;
  for (l=0; l<256; l++)
  {
    if (classesByLetter[l].count()>0)
    {
      // add special header cell
      tableRows->append(new AlphaIndexTableCell(row,col,(uchar)l,(ClassDef*)0x8));
      row++;
      tableRows->append(new AlphaIndexTableCell(row,col,0,(ClassDef*)0x8));
1882
      row++;
1883 1884 1885 1886 1887 1888 1889 1890 1891 1892
      tableRows->append(new AlphaIndexTableCell(row,col,0,classesByLetter[l].at(0)));
      row++; 
      NEXT_ROW();
      for (i=1; i<(int)classesByLetter[l].count(); i++)
      {
        // add normal cell
        tableRows->append(new AlphaIndexTableCell(row,col,0,classesByLetter[l].at(i)));
        row++;
        NEXT_ROW();
      }
1893 1894
    }
  }
1895

1896 1897
  // create row iterators for each column
  AlphaIndexTableRowsIterator **colIterators = new AlphaIndexTableRowsIterator*[columns];
1898 1899
  for (i=0;i<columns;i++)
  {
1900 1901 1902 1903 1904 1905 1906 1907
    if (i<(int)tableColumns.count())
    {
      colIterators[i] = new AlphaIndexTableRowsIterator(*tableColumns.at(i));
    }
    else // empty column
    {
      colIterators[i] = 0;
    }
1908 1909
  }

1910
  ol.writeString("<table style=\"margin: 10px; white-space: nowrap;\" align=\"center\" width=\"95%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n");
1911
  // generate table
1912
  for (i=0;i<=maxRows;i++) // foreach table row
1913
  {
1914
    //printf("writing row %d\n",i);
1915 1916
    //ol.nextTableRow();
    ol.writeString("<tr>");
1917
    // the last column may contain less items then the others
1918
    //int colsInRow = (i<rows-1) ? columns : itemsInLastRow; 
1919
    //printf("row [%d]\n",i);
1920
    for (j=0;j<columns;j++) // foreach table column
1921
    {
1922
      if (colIterators[j])
1923
      {
1924 1925
        AlphaIndexTableCell *cell = colIterators[j]->current();
        if (cell)
1926
        {
1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953
          if (cell->row()==i)
          {
            if (cell->letter()!=0)
            {
              QCString s = letterToLabel(cell->letter());
              ol.writeString("<td rowspan=\"2\" valign=\"bottom\">");
              ol.writeString("<a name=\"letter_");
              ol.writeString(s);
              ol.writeString("\"></a>");
              ol.writeString("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">"
                  "<tr>"
                  "<td><div class=\"ah\">&#160;&#160;"); 
              ol.writeString(s);
              ol.writeString(         "&#160;&#160;</div>"
                  "</td>"
                  "</tr>"
                  "</table>\n");
            }
            else if (cell->classDef()!=(ClassDef*)0x8)
            {
              cd = cell->classDef();
              ol.writeString("<td valign=\"top\">");
              QCString namesp,cname;
              //if (cd->getNamespaceDef()) namesp=cd->getNamespaceDef()->displayName();
              //QCString cname=cd->className();
              extractNamespaceName(cd->name(),cname,namesp);
              QCString nsDispName;
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1954 1955 1956
              SrcLangExt lang = cd->getLanguage();
              QCString sep = getLanguageSpecificSeparator(lang);
              if (sep!="::")
1957
              {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1958
                nsDispName=substitute(namesp,"::",sep);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1959
                cname=substitute(cname,"::",sep);
1960 1961 1962
              }
              else
              {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1963
                nsDispName=namesp;
1964
              }
1965

1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990
              ol.writeObjectLink(cd->getReference(),
                  cd->getOutputFileBase(),cd->anchor(),cname);
              if (!namesp.isEmpty())
              {
                ol.docify(" (");
                NamespaceDef *nd = getResolvedNamespace(namesp);
                if (nd && nd->isLinkable())
                {
                  ol.writeObjectLink(nd->getReference(),
                      nd->getOutputFileBase(),0,nsDispName);
                }
                else
                {
                  ol.docify(nsDispName);
                }
                ol.docify(")");
              }
              ol.writeNonBreakableSpace(3);
            }
            ++(*colIterators[j]);
            if (cell->letter()!=0 || cell->classDef()!=(ClassDef*)0x8)
            {
              ol.writeString("</td>");
            }
          }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
1991 1992 1993
        }
        else
        {
1994
          ol.writeString("<td></td>");
1995
        }
1996 1997
      }
    }
1998
    ol.writeString("</tr>\n");
1999
  }
2000
  ol.writeString("</table>\n");
2001 2002
  
  ol.writeString(alphaLinks);
2003 2004 2005 2006 2007 2008 2009

  // release the temporary memory
  for (i=0;i<columns;i++)
  {
    delete colIterators[i];
  }
  delete[] colIterators;
2010 2011 2012 2013
}

//----------------------------------------------------------------------------

2014
static void writeAlphabeticalIndex(OutputList &ol)
2015 2016
{
  if (annotatedClasses==0) return;
2017 2018
  ol.pushGeneratorState();
  ol.disableAllBut(OutputGenerator::Html);
2019 2020
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassIndex);
  QCString title = lne ? lne->title() : theTranslator->trCompoundIndex();
2021 2022
  bool addToIndex = lne==0 || lne->visible();

2023
  startFile(ol,"classes",0,title,HLI_Classes); 
2024

2025
  startTitle(ol,0);
2026
  ol.parseText(title);
2027
  endTitle(ol,0,0);
2028

2029 2030
  if (addToIndex)
  {
2031
    Doxygen::indexList->addContentsItem(FALSE,title,0,"classes",0,FALSE,TRUE); 
2032 2033
  }

2034
  ol.startContents();
2035
  writeAlphabeticalClassList(ol);
2036
  endFile(ol); // contains ol.endContents()
2037

2038
  ol.popGeneratorState();
2039 2040 2041 2042
}

//----------------------------------------------------------------------------

2043
static void writeAnnotatedIndex(OutputList &ol)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2044
{
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2045 2046
  //printf("writeAnnotatedIndex: count=%d printed=%d\n",
  //    annotatedClasses,annotatedClassesPrinted);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2047 2048
  if (annotatedClasses==0) return;
  
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2049
  ol.pushGeneratorState();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2050
  ol.disable(OutputGenerator::Man);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2051 2052 2053 2054 2055
  if (annotatedClassesPrinted==0)
  {
    ol.disable(OutputGenerator::Latex);
    ol.disable(OutputGenerator::RTF);
  }
2056 2057 2058
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassList);
  if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Classes); // fall back
  QCString title = lne ? lne->title() : theTranslator->trCompoundList();
2059 2060 2061 2062 2063 2064 2065
  bool addToIndex = lne==0 || lne->visible();

  if (Config_getBool("OPTIMIZE_OUTPUT_VHDL")) 
  {
    VhdlDocGen::findConstraintFile(lne);
  }
  
2066
  startFile(ol,"annotated",0,title,HLI_Annotated);
2067

2068
  startTitle(ol,0);
2069
  ol.parseText(title);
2070
  endTitle(ol,0,0);
2071

2072
  ol.startContents();
2073

Dimitri van Heesch's avatar
Dimitri van Heesch committed
2074
  ol.startTextBlock();
2075
  ol.parseText(lne ? lne->intro() : theTranslator->trCompoundListDescription());
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2076
  ol.endTextBlock();
2077

2078 2079 2080 2081 2082
  // ---------------
  // Linear class index for Latex/RTF
  // ---------------
  ol.pushGeneratorState();
  ol.disable(OutputGenerator::Html);
2083
  Doxygen::indexList->disable();
2084

Dimitri van Heesch's avatar
Dimitri van Heesch committed
2085
  writeAnnotatedClassList(ol);
2086

2087
  Doxygen::indexList->enable();
2088 2089 2090 2091 2092 2093 2094 2095
  ol.popGeneratorState();

  // ---------------
  // Hierarchical class index for HTML
  // ---------------
  ol.pushGeneratorState(); 
  ol.disableAllBut(OutputGenerator::Html);

2096
  {
2097 2098
    if (addToIndex)
    {
2099 2100
      Doxygen::indexList->addContentsItem(TRUE,title,0,"annotated",0,TRUE,TRUE); 
      Doxygen::indexList->incContentsDepth();
2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111
    }
    FTVHelp* ftv = new FTVHelp(FALSE);
    writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,TRUE,addToIndex);
    writeClassTree(Doxygen::classSDict,ftv,addToIndex,TRUE);
    QGString outStr;
    FTextStream t(&outStr);
    ftv->generateTreeViewInline(t);
    ol.writeString(outStr);
    delete ftv;
    if (addToIndex)
    {
2112
      Doxygen::indexList->decContentsDepth();
2113
    }
2114
  }
2115 2116 2117

  ol.popGeneratorState();
  // ------
2118
  
2119
  endFile(ol); // contains ol.endContents()
2120 2121 2122 2123
  ol.popGeneratorState();
}

//----------------------------------------------------------------------------
2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136
static void writeClassLinkForMember(OutputList &ol,MemberDef *md,const char *separator,
                             QCString &prevClassName)
{
  ClassDef *cd=md->getClassDef();
  if ( cd && prevClassName!=cd->displayName())
  {
    ol.docify(separator);
    ol.writeObjectLink(md->getReference(),md->getOutputFileBase(),md->anchor(),
        cd->displayName());
    ol.writeString("\n");
    prevClassName = cd->displayName();
  }
}
2137

2138 2139
static void writeFileLinkForMember(OutputList &ol,MemberDef *md,const char *separator,
                             QCString &prevFileName)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2140
{
2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170
  FileDef *fd=md->getFileDef();
  if (fd && prevFileName!=fd->name())
  {
    ol.docify(separator);
    ol.writeObjectLink(md->getReference(),md->getOutputFileBase(),md->anchor(),
        fd->name());
    ol.writeString("\n");
    prevFileName = fd->name();
  }
}

static void writeNamespaceLinkForMember(OutputList &ol,MemberDef *md,const char *separator,
                             QCString &prevNamespaceName)
{
  NamespaceDef *nd=md->getNamespaceDef();
  if (nd && prevNamespaceName!=nd->name())
  {
    ol.docify(separator);
    ol.writeObjectLink(md->getReference(),md->getOutputFileBase(),md->anchor(),
        nd->name());
    ol.writeString("\n");
    prevNamespaceName = nd->name();
  }
}

static void writeMemberList(OutputList &ol,bool useSections,int page,
                            MemberIndexList memberLists[MEMBER_INDEX_ENTRIES],
                            DefinitionIntf::DefType type)
{
  int pi;
2171 2172
  // page==-1 => write all member indices to one page (used when total members is small)
  // page!=-1 => write all member for this page only (used when total member is large)
2173 2174 2175
  int startIndex = page==-1 ? 0                      : page;
  int endIndex   = page==-1 ? MEMBER_INDEX_ENTRIES-1 : page;
  ASSERT((int)type<3);
2176 2177 2178 2179 2180

  typedef void (*writeLinkForMember_t)(OutputList &ol,MemberDef *md,const char *separator,
                                   QCString &prevNamespaceName);

  // each index tab has its own write function
2181 2182 2183 2184 2185 2186 2187 2188 2189 2190
  static writeLinkForMember_t writeLinkForMemberMap[3] = 
  { 
    &writeClassLinkForMember, 
    &writeFileLinkForMember,
    &writeNamespaceLinkForMember
  };
  QCString prevName;
  QCString prevDefName;
  bool first=TRUE;
  bool firstSection=TRUE;
2191
  bool firstItem=TRUE;
2192 2193 2194 2195 2196 2197 2198 2199 2200
  for (pi=startIndex; pi<=endIndex; pi++) // page==-1 => pi=[0..127], page!=-1 => pi=page 
  {
    MemberIndexList *ml = &memberLists[pi];
    if (ml->count()==0) continue;
    ml->sort();
    QListIterator<MemberDef> mli(*ml);
    MemberDef *md;
    for (mli.toFirst();(md=mli.current());++mli)
    {
2201
      const char *sep;
2202 2203 2204
      bool isFunc=!md->isObjCMethod() && 
        (md->isFunction() || md->isSlot() || md->isSignal()); 
      QCString name=md->name();
2205 2206
      int startIndex = getPrefixIndex(name);
      if (QCString(name.data()+startIndex)!=prevName) // new entry
2207
      {
2208 2209 2210
        if ((prevName.isEmpty() || 
            tolower(name.at(startIndex))!=tolower(prevName.at(0))) && 
            useSections) // new section
2211
        {
2212
          if (!firstItem)    ol.endItemListItem();
2213
          if (!firstSection) ol.endItemList();
2214 2215 2216 2217
          char cl[2];
          cl[0] = tolower(name.at(startIndex));
          cl[1] = 0;
          QCString cs = letterToLabel(cl[0]);
2218
          QCString anchor=(QCString)"index_"+cs;
2219
          QCString title=(QCString)"- "+cl+" -";
2220 2221 2222 2223 2224
          ol.startSection(anchor,title,SectionInfo::Subsection);
          ol.docify(title);
          ol.endSection(anchor,SectionInfo::Subsection);
          ol.startItemList();
          firstSection=FALSE;
2225
          firstItem=TRUE;
2226 2227 2228 2229 2230 2231 2232 2233
        }
        else if (!useSections && first)
        {
          ol.startItemList();
          first=FALSE;
        }

        // member name
2234 2235 2236
        if (!firstItem) ol.endItemListItem();
        ol.startItemListItem();
        firstItem=FALSE;
2237 2238 2239 2240 2241 2242 2243
        ol.docify(name);
        if (isFunc) ol.docify("()");
        ol.writeString("\n");

        // link to class
        prevDefName="";
        sep = ": ";
2244
        prevName = name.data()+startIndex;
2245 2246 2247 2248 2249 2250
      }
      else // same entry
      {
        sep = ", ";
        // link to class for other members with the same name
      }
2251
      // write the link for the specific list type
2252 2253 2254
      writeLinkForMemberMap[(int)type](ol,md,sep,prevDefName);
    }
  }
2255
  if (!firstItem) ol.endItemListItem();
2256
  ol.endItemList();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2257 2258 2259 2260
}

//----------------------------------------------------------------------------

2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277
void initClassMemberIndices()
{
  int i=0;
  int j=0;
  for (j=0;j<CMHL_Total;j++)
  {
    documentedClassMembers[j]=0;
    for (i=0;i<MEMBER_INDEX_ENTRIES;i++) 
    {
      g_memberIndexLetterUsed[j][i].clear();
    }
  }
}

void addClassMemberNameToIndex(MemberDef *md)
{
  static bool hideFriendCompounds = Config_getBool("HIDE_FRIEND_COMPOUNDS");
2278 2279
  ClassDef *cd=0;

Dimitri van Heesch's avatar
Dimitri van Heesch committed
2280
 
2281
  
2282
  if (md->isLinkableInProject() && 
2283
      (cd=md->getClassDef())    && 
2284 2285 2286 2287
      cd->isLinkableInProject() &&
      cd->templateMaster()==0)
  {
    QCString n = md->name();
2288
    int index = getPrefixIndex(n);
2289 2290
    uchar charCode = (uchar)n.at(index);
    uint letter = charCode<128 ? tolower(charCode) : charCode;
2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336
    if (!n.isEmpty()) 
    {
      bool isFriendToHide = hideFriendCompounds &&
        (QCString(md->typeString())=="friend class" || 
         QCString(md->typeString())=="friend struct" ||
         QCString(md->typeString())=="friend union");
      if (!(md->isFriend() && isFriendToHide))
      {
        g_memberIndexLetterUsed[CMHL_All][letter].append(md);
        documentedClassMembers[CMHL_All]++;
      }
      if (md->isFunction()  || md->isSlot() || md->isSignal())
      {
        g_memberIndexLetterUsed[CMHL_Functions][letter].append(md);
        documentedClassMembers[CMHL_Functions]++;
      } 
      else if (md->isVariable())
      {
        g_memberIndexLetterUsed[CMHL_Variables][letter].append(md);
        documentedClassMembers[CMHL_Variables]++;
      }
      else if (md->isTypedef())
      {
        g_memberIndexLetterUsed[CMHL_Typedefs][letter].append(md);
        documentedClassMembers[CMHL_Typedefs]++;
      }
      else if (md->isEnumerate())
      {
        g_memberIndexLetterUsed[CMHL_Enums][letter].append(md);
        documentedClassMembers[CMHL_Enums]++;
      }
      else if (md->isEnumValue())
      {
        g_memberIndexLetterUsed[CMHL_EnumValues][letter].append(md);
        documentedClassMembers[CMHL_EnumValues]++;
      }
      else if (md->isProperty())
      {
        g_memberIndexLetterUsed[CMHL_Properties][letter].append(md);
        documentedClassMembers[CMHL_Properties]++;
      }
      else if (md->isEvent())
      {
        g_memberIndexLetterUsed[CMHL_Events][letter].append(md);
        documentedClassMembers[CMHL_Events]++;
      }
2337 2338
      else if (md->isRelated() || md->isForeign() ||
               (md->isFriend() && !isFriendToHide))
2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368
      {
        g_memberIndexLetterUsed[CMHL_Related][letter].append(md);
        documentedClassMembers[CMHL_Related]++;
      }
    }
  }
}

//----------------------------------------------------------------------------

void initNamespaceMemberIndices()
{
  int i=0;
  int j=0;
  for (j=0;j<NMHL_Total;j++)
  {
    documentedNamespaceMembers[j]=0;
    for (i=0;i<MEMBER_INDEX_ENTRIES;i++) 
    {
      g_namespaceIndexLetterUsed[j][i].clear();
    }
  }
}

void addNamespaceMemberNameToIndex(MemberDef *md)
{
  NamespaceDef *nd=md->getNamespaceDef();
  if (nd && nd->isLinkableInProject() && md->isLinkableInProject())
  {
    QCString n = md->name();
2369
    int index = getPrefixIndex(n);
2370 2371
    uchar charCode = (uchar)n.at(index);
    uint letter = charCode<128 ? tolower(charCode) : charCode;
2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405
    if (!n.isEmpty()) 
    {
      g_namespaceIndexLetterUsed[NMHL_All][letter].append(md);
      documentedNamespaceMembers[NMHL_All]++;

      if (md->isFunction()) 
      {
        g_namespaceIndexLetterUsed[NMHL_Functions][letter].append(md);
        documentedNamespaceMembers[NMHL_Functions]++;
      }
      else if (md->isVariable()) 
      {
        g_namespaceIndexLetterUsed[NMHL_Variables][letter].append(md);
        documentedNamespaceMembers[NMHL_Variables]++;
      }
      else if (md->isTypedef())
      {
        g_namespaceIndexLetterUsed[NMHL_Typedefs][letter].append(md);
        documentedNamespaceMembers[NMHL_Typedefs]++;
      }
      else if (md->isEnumerate())
      {
        g_namespaceIndexLetterUsed[NMHL_Enums][letter].append(md);
        documentedNamespaceMembers[NMHL_Enums]++;
      }
      else if (md->isEnumValue())
      {
        g_namespaceIndexLetterUsed[NMHL_EnumValues][letter].append(md);
        documentedNamespaceMembers[NMHL_EnumValues]++;
      }
    }
  }
}

Dimitri van Heesch's avatar
Dimitri van Heesch committed
2406 2407
//----------------------------------------------------------------------------

2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427
void initFileMemberIndices()
{
  int i=0;
  int j=0;
  for (j=0;j<NMHL_Total;j++)
  {
    documentedFileMembers[j]=0;
    for (i=0;i<MEMBER_INDEX_ENTRIES;i++) 
    {
      g_fileIndexLetterUsed[j][i].clear();
    }
  }
}

void addFileMemberNameToIndex(MemberDef *md)
{
  FileDef *fd=md->getFileDef();
  if (fd && fd->isLinkableInProject() && md->isLinkableInProject())
  {
    QCString n = md->name();
2428
    int index = getPrefixIndex(n);
2429 2430
    uchar charCode = (uchar)n.at(index);
    uint letter = charCode<128 ? tolower(charCode) : charCode;
2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471
    if (!n.isEmpty()) 
    {
      g_fileIndexLetterUsed[FMHL_All][letter].append(md);
      documentedFileMembers[FMHL_All]++;

      if (md->isFunction()) 
      {
        g_fileIndexLetterUsed[FMHL_Functions][letter].append(md);
        documentedFileMembers[FMHL_Functions]++;
      }
      else if (md->isVariable()) 
      {
        g_fileIndexLetterUsed[FMHL_Variables][letter].append(md);
        documentedFileMembers[FMHL_Variables]++;
      }
      else if (md->isTypedef())
      {
        g_fileIndexLetterUsed[FMHL_Typedefs][letter].append(md);
        documentedFileMembers[FMHL_Typedefs]++;
      }
      else if (md->isEnumerate())
      {
        g_fileIndexLetterUsed[FMHL_Enums][letter].append(md);
        documentedFileMembers[FMHL_Enums]++;
      }
      else if (md->isEnumValue())
      {
        g_fileIndexLetterUsed[FMHL_EnumValues][letter].append(md);
        documentedFileMembers[FMHL_EnumValues]++;
      }
      else if (md->isDefine())
      {
        g_fileIndexLetterUsed[FMHL_Defines][letter].append(md);
        documentedFileMembers[FMHL_Defines]++;
      }
    }
  }
}

//----------------------------------------------------------------------------

2472
static void writeQuickMemberIndex(OutputList &ol,
2473
    MemberIndexList charUsed[MEMBER_INDEX_ENTRIES],int page,
2474
    QCString fullName,bool multiPage)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2475 2476 2477
{
  bool first=TRUE;
  int i;
2478
  startQuickIndexList(ol,TRUE);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2479 2480 2481
  for (i=33;i<127;i++)
  {
    char is[2];is[0]=(char)i;is[1]='\0';
2482
    QCString ci = letterToLabel((char)i);
2483
    if (charUsed[i].count()>0)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2484
    {
2485 2486 2487 2488 2489 2490 2491 2492
      QCString anchor;
      QCString extension=Doxygen::htmlFileExtension;
      if (!multiPage)
        anchor="#index_";
      else if (first) 
        anchor=fullName+extension+"#index_";
      else 
        anchor=fullName+QCString().sprintf("_0x%02x",i)+extension+"#index_";
2493
      startQuickIndexItem(ol,anchor+ci,i==page,TRUE,first);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2494
      ol.writeString(is);
2495
      endQuickIndexItem(ol);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2496 2497 2498
      first=FALSE;
    }
  }
2499
  endQuickIndexList(ol);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2500 2501 2502 2503
}

//----------------------------------------------------------------------------

Dimitri van Heesch's avatar
Dimitri van Heesch committed
2504
/** Helper class representing a class member in the navigation menu. */
2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533
struct CmhlInfo
{
  CmhlInfo(const char *fn,const char *t) : fname(fn), title(t) {}
  const char *fname;
  QCString title;
};

static const CmhlInfo *getCmhlInfo(int hl)
{
  static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
  static bool vhdlOpt    = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
  static CmhlInfo cmhlInfo[] = 
  {
    CmhlInfo("functions",     theTranslator->trAll()),
    CmhlInfo("functions_func",
        fortranOpt ? theTranslator->trSubprograms() : 
        vhdlOpt    ? VhdlDocGen::trFunctionAndProc() :
                     theTranslator->trFunctions()),
    CmhlInfo("functions_vars",theTranslator->trVariables()),
    CmhlInfo("functions_type",theTranslator->trTypedefs()),
    CmhlInfo("functions_enum",theTranslator->trEnumerations()),
    CmhlInfo("functions_eval",theTranslator->trEnumerationValues()),
    CmhlInfo("functions_prop",theTranslator->trProperties()),
    CmhlInfo("functions_evnt",theTranslator->trEvents()),
    CmhlInfo("functions_rela",theTranslator->trRelatedFunctions())
  };
  return &cmhlInfo[hl];
}

Dimitri van Heesch's avatar
Dimitri van Heesch committed
2534
static void writeClassMemberIndexFiltered(OutputList &ol, ClassMemberHighlight hl)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2535
{
2536
  if (documentedClassMembers[hl]==0) return;
2537
  
2538
  static bool disableIndex     = Config_getBool("DISABLE_INDEX");
2539 2540 2541 2542 2543 2544 2545 2546 2547

  bool multiPageIndex=FALSE;
  int numPages=1;
  if (documentedClassMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX)
  {
    multiPageIndex=TRUE;
    numPages=127;
  }

Dimitri van Heesch's avatar
Dimitri van Heesch committed
2548 2549
  ol.pushGeneratorState();
  ol.disableAllBut(OutputGenerator::Html);
2550

2551
  QCString extension=Doxygen::htmlFileExtension;
2552
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassMembers);
2553
  QCString title = lne ? lne->title() : theTranslator->trCompoundMembers();
2554
  if (hl!=CMHL_All) title+=(QCString)" - "+getCmhlInfo(hl)->title;
2555
  bool addToIndex = lne==0 || lne->visible();
2556

2557 2558
  if (addToIndex)
  {
2559
    Doxygen::indexList->addContentsItem(multiPageIndex,getCmhlInfo(hl)->title,0,
2560
                                       getCmhlInfo(hl)->fname,0,multiPageIndex,TRUE);
2561
    if (multiPageIndex) Doxygen::indexList->incContentsDepth();
2562
  }
2563

2564
  int page;
2565
  bool first=TRUE;
2566
  for (page=0;page<numPages;page++)
2567
  {
2568
    if (!multiPageIndex || g_memberIndexLetterUsed[hl][page].count()>0)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2569
    {
2570
      QCString fileName = getCmhlInfo(hl)->fname;
2571
      if (multiPageIndex)
2572
      { 
2573 2574 2575 2576 2577 2578 2579
        if (!first)
        {
          fileName+=QCString().sprintf("_0x%02x",page);
        }
        char cs[2];
        cs[0]=page;
        cs[1]=0;
2580 2581
        if (addToIndex)
        {
2582
          Doxygen::indexList->addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE);
2583
        }
2584
      }
2585
      bool quickIndex = documentedClassMembers[hl]>maxItemsBeforeQuickIndex;
2586
      
2587 2588 2589 2590
      ol.startFile(fileName+extension,0,title);
      ol.startQuickIndices();
      if (!disableIndex)
      {
2591
        ol.writeQuickLinks(TRUE,HLI_Functions,0);
2592
        startQuickIndexList(ol);
2593

2594 2595 2596 2597 2598
        // index item for global member list
        startQuickIndexItem(ol,
            getCmhlInfo(0)->fname+Doxygen::htmlFileExtension,hl==CMHL_All,TRUE,first);
        ol.writeString(fixSpaces(getCmhlInfo(0)->title));
        endQuickIndexItem(ol);
2599

2600 2601 2602
        int i;
        // index items per category member lists
        for (i=1;i<CMHL_Total;i++)
2603
        {
2604 2605 2606 2607 2608 2609 2610 2611
          if (documentedClassMembers[i]>0)
          {
            startQuickIndexItem(ol,getCmhlInfo(i)->fname+Doxygen::htmlFileExtension,hl==i,TRUE,first);
            ol.writeString(fixSpaces(getCmhlInfo(i)->title));
            //printf("multiPageIndex=%d first=%d fileName=%s file=%s title=%s\n",
            //    multiPageIndex,first,fileName.data(),getCmhlInfo(i)->fname,getCmhlInfo(i)->title.data());
            endQuickIndexItem(ol);
          }
2612 2613
        }

2614
        endQuickIndexList(ol);
2615

2616 2617 2618 2619 2620 2621
        // quick alphabetical index
        if (quickIndex)
        {
          writeQuickMemberIndex(ol,g_memberIndexLetterUsed[hl],page,
              getCmhlInfo(hl)->fname,multiPageIndex);
        }
2622
      }
2623
      ol.endQuickIndices();
2624 2625
      ol.writeSplitBar(fileName);
      ol.writeSearchInfo();
2626

2627 2628
      ol.startContents();

2629 2630
      if (hl==CMHL_All)
      {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2631
        ol.startTextBlock();
2632
        ol.parseText(lne ? lne->intro() : theTranslator->trCompoundMembersDescription(Config_getBool("EXTRACT_ALL")));
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2633
        ol.endTextBlock();
2634
      }
2635 2636 2637 2638
      else
      {
        // hack to work around a mozilla bug, which refuses to switch to
        // normal lists otherwise
2639
        ol.writeString("&#160;");
2640
      }
2641
      //ol.newParagraph();  // FIXME:PARA
2642 2643 2644 2645
      writeMemberList(ol,quickIndex,
                      multiPageIndex?page:-1,
                      g_memberIndexLetterUsed[hl],
                      Definition::TypeClass);
2646 2647
      endFile(ol);
      first=FALSE;
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2648
    }
2649
  }
2650

2651
  if (multiPageIndex && addToIndex) Doxygen::indexList->decContentsDepth();
2652
  
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2653
  ol.popGeneratorState();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2654 2655
}

2656
static void writeClassMemberIndex(OutputList &ol)
2657
{
2658 2659 2660 2661
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassMembers);
  bool addToIndex = lne==0 || lne->visible();

  if (documentedClassMembers[CMHL_All]>0 && addToIndex)
2662
  {
2663 2664
    Doxygen::indexList->addContentsItem(TRUE,lne ? lne->title() : theTranslator->trCompoundMembers(),0,"functions",0); 
    Doxygen::indexList->incContentsDepth();
2665
  }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2666 2667 2668 2669 2670 2671 2672 2673 2674
  writeClassMemberIndexFiltered(ol,CMHL_All);
  writeClassMemberIndexFiltered(ol,CMHL_Functions);
  writeClassMemberIndexFiltered(ol,CMHL_Variables);
  writeClassMemberIndexFiltered(ol,CMHL_Typedefs);
  writeClassMemberIndexFiltered(ol,CMHL_Enums);
  writeClassMemberIndexFiltered(ol,CMHL_EnumValues);
  writeClassMemberIndexFiltered(ol,CMHL_Properties);
  writeClassMemberIndexFiltered(ol,CMHL_Events);
  writeClassMemberIndexFiltered(ol,CMHL_Related);
2675
  if (documentedClassMembers[CMHL_All]>0 && addToIndex)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2676
  {
2677
    Doxygen::indexList->decContentsDepth();
2678
  }
2679

2680 2681
}

Dimitri van Heesch's avatar
Dimitri van Heesch committed
2682 2683
//----------------------------------------------------------------------------

Dimitri van Heesch's avatar
Dimitri van Heesch committed
2684
/** Helper class representing a file member in the navigation menu. */
2685
struct FmhlInfo 
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2686
{
2687 2688 2689 2690
  FmhlInfo(const char *fn,const char *t) : fname(fn), title(t) {}
  const char *fname;
  QCString title;
};
2691

2692 2693 2694 2695 2696
static const FmhlInfo *getFmhlInfo(int hl)
{
  static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
  static bool vhdlOpt    = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
  static FmhlInfo fmhlInfo[] = 
2697
  {
2698
    FmhlInfo("globals",     theTranslator->trAll()),
2699 2700 2701 2702
    FmhlInfo("globals_func",
         fortranOpt ? theTranslator->trSubprograms()  : 
         vhdlOpt    ? VhdlDocGen::trFunctionAndProc() : 
                      theTranslator->trFunctions()),
2703 2704 2705 2706 2707
    FmhlInfo("globals_vars",theTranslator->trVariables()),
    FmhlInfo("globals_type",theTranslator->trTypedefs()),
    FmhlInfo("globals_enum",theTranslator->trEnumerations()),
    FmhlInfo("globals_eval",theTranslator->trEnumerationValues()),
    FmhlInfo("globals_defs",theTranslator->trDefines())
2708
  };
2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724
  return &fmhlInfo[hl];
}

static void writeFileMemberIndexFiltered(OutputList &ol, FileMemberHighlight hl)
{
  if (documentedFileMembers[hl]==0) return;

  static bool disableIndex     = Config_getBool("DISABLE_INDEX");

  bool multiPageIndex=FALSE;
  int numPages=1;
  if (documentedFileMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX)
  {
    multiPageIndex=TRUE;
    numPages=127;
  }
2725

2726 2727 2728 2729
  ol.pushGeneratorState();
  ol.disableAllBut(OutputGenerator::Html);

  QCString extension=Doxygen::htmlFileExtension;
2730
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::FileGlobals);
2731
  QCString title = lne ? lne->title() : theTranslator->trFileMembers();
2732
  bool addToIndex = lne==0 || lne->visible();
2733

2734 2735
  if (addToIndex)
  {
2736
    Doxygen::indexList->addContentsItem(multiPageIndex,getFmhlInfo(hl)->title,0,
2737
                                       getFmhlInfo(hl)->fname,0,multiPageIndex,TRUE);
2738
    if (multiPageIndex) Doxygen::indexList->incContentsDepth();
2739
  }
2740 2741 2742 2743

  int page;
  bool first=TRUE;
  for (page=0;page<numPages;page++)
2744
  {
2745
    if (!multiPageIndex || g_fileIndexLetterUsed[hl][page].count()>0)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2746
    {
2747
      QCString fileName = getFmhlInfo(hl)->fname;
2748
      if (multiPageIndex)
2749
      {
2750 2751 2752 2753 2754 2755 2756
        if (!first)
        {
          fileName+=QCString().sprintf("_0x%02x",page);
        }
        char cs[2];
        cs[0]=page;
        cs[1]=0;
2757 2758
        if (addToIndex)
        {
2759
          Doxygen::indexList->addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE);
2760
        }
2761
      }
2762
      bool quickIndex = documentedFileMembers[hl]>maxItemsBeforeQuickIndex;
2763
      
2764 2765 2766 2767
      ol.startFile(fileName+extension,0,title);
      ol.startQuickIndices();
      if (!disableIndex)
      {
2768
        ol.writeQuickLinks(TRUE,HLI_Globals,0);
2769
        startQuickIndexList(ol);
2770

2771 2772 2773 2774 2775
        // index item for all file member lists
        startQuickIndexItem(ol,
            getFmhlInfo(0)->fname+Doxygen::htmlFileExtension,hl==FMHL_All,TRUE,first);
        ol.writeString(fixSpaces(getFmhlInfo(0)->title));
        endQuickIndexItem(ol);
2776

2777 2778 2779
        int i;
        // index items for per category member lists
        for (i=1;i<FMHL_Total;i++)
2780
        {
2781 2782 2783 2784 2785 2786 2787
          if (documentedFileMembers[i]>0)
          {
            startQuickIndexItem(ol,
                getFmhlInfo(i)->fname+Doxygen::htmlFileExtension,hl==i,TRUE,first);
            ol.writeString(fixSpaces(getFmhlInfo(i)->title));
            endQuickIndexItem(ol);
          }
2788 2789
        }

2790
        endQuickIndexList(ol);
2791

2792 2793 2794 2795 2796
        if (quickIndex)
        {
          writeQuickMemberIndex(ol,g_fileIndexLetterUsed[hl],page,
              getFmhlInfo(hl)->fname,multiPageIndex);
        }
2797
      }
2798
      ol.endQuickIndices();
2799 2800
      ol.writeSplitBar(fileName);
      ol.writeSearchInfo();
2801

2802 2803
      ol.startContents();

2804 2805
      if (hl==FMHL_All)
      {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2806
        ol.startTextBlock();
2807
        ol.parseText(lne ? lne->intro() : theTranslator->trFileMembersDescription(Config_getBool("EXTRACT_ALL")));
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2808
        ol.endTextBlock();
2809
      }
2810 2811 2812 2813
      else
      {
        // hack to work around a mozilla bug, which refuses to switch to
        // normal lists otherwise
2814
        ol.writeString("&#160;");
2815
      }
2816
      //ol.newParagraph();  // FIXME:PARA
2817 2818
      //writeFileMemberList(ol,quickIndex,hl,page);
      writeMemberList(ol,quickIndex,
2819 2820 2821
          multiPageIndex?page:-1,
          g_fileIndexLetterUsed[hl],
          Definition::TypeFile);
2822 2823
      endFile(ol);
      first=FALSE;
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2824
    }
2825
  }
2826
  if (multiPageIndex && addToIndex) Doxygen::indexList->decContentsDepth();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2827
  ol.popGeneratorState();
2828 2829
}

2830
static void writeFileMemberIndex(OutputList &ol)
2831
{
2832 2833 2834
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::FileGlobals);
  bool addToIndex = lne==0 || lne->visible();
  if (documentedFileMembers[FMHL_All]>0 && addToIndex)
2835
  {
2836 2837
    Doxygen::indexList->addContentsItem(FALSE,lne ? lne->title() : theTranslator->trFileMembers(),0,"globals",0); 
    Doxygen::indexList->incContentsDepth();
2838
  }
2839 2840 2841 2842 2843 2844 2845
  writeFileMemberIndexFiltered(ol,FMHL_All);
  writeFileMemberIndexFiltered(ol,FMHL_Functions);
  writeFileMemberIndexFiltered(ol,FMHL_Variables);
  writeFileMemberIndexFiltered(ol,FMHL_Typedefs);
  writeFileMemberIndexFiltered(ol,FMHL_Enums);
  writeFileMemberIndexFiltered(ol,FMHL_EnumValues);
  writeFileMemberIndexFiltered(ol,FMHL_Defines);
2846
  if (documentedFileMembers[FMHL_All]>0 && addToIndex)
2847
  {
2848
    Doxygen::indexList->decContentsDepth();
2849
  }
2850

2851 2852
}

2853 2854
//----------------------------------------------------------------------------

Dimitri van Heesch's avatar
Dimitri van Heesch committed
2855
/** Helper class representing a namespace member in the navigation menu. */
2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880
struct NmhlInfo
{
  NmhlInfo(const char *fn,const char *t) : fname(fn), title(t) {}
  const char *fname;
  QCString title;
};

static const NmhlInfo *getNmhlInfo(int hl)
{
  static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
  static bool vhdlOpt    = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
  static NmhlInfo nmhlInfo[] = 
  {
    NmhlInfo("namespacemembers",     theTranslator->trAll()),
    NmhlInfo("namespacemembers_func",
        fortranOpt ? theTranslator->trSubprograms()  :
        vhdlOpt    ? VhdlDocGen::trFunctionAndProc() :
                     theTranslator->trFunctions()),
    NmhlInfo("namespacemembers_vars",theTranslator->trVariables()),
    NmhlInfo("namespacemembers_type",theTranslator->trTypedefs()),
    NmhlInfo("namespacemembers_enum",theTranslator->trEnumerations()),
    NmhlInfo("namespacemembers_eval",theTranslator->trEnumerationValues())
  };
  return &nmhlInfo[hl];
}
2881

2882 2883
//----------------------------------------------------------------------------

2884
static void writeNamespaceMemberIndexFiltered(OutputList &ol,
2885
                                        NamespaceMemberHighlight hl)
2886
{
2887 2888
  if (documentedNamespaceMembers[hl]==0) return;

2889
  static bool disableIndex     = Config_getBool("DISABLE_INDEX");
2890

2891

2892 2893 2894
  bool multiPageIndex=FALSE;
  int numPages=1;
  if (documentedNamespaceMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX)
2895
  {
2896 2897
    multiPageIndex=TRUE;
    numPages=127;
2898
  }
2899 2900 2901 2902 2903

  ol.pushGeneratorState();
  ol.disableAllBut(OutputGenerator::Html);

  QCString extension=Doxygen::htmlFileExtension;
2904
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::NamespaceMembers);
2905
  QCString title = lne ? lne->title() : theTranslator->trNamespaceMembers();
2906
  bool addToIndex = lne==0 || lne->visible();
2907

2908 2909
  if (addToIndex)
  {
2910
    Doxygen::indexList->addContentsItem(multiPageIndex,getNmhlInfo(hl)->title,0,
2911
                                       getNmhlInfo(hl)->fname,0,multiPageIndex,TRUE);
2912
    if (multiPageIndex) Doxygen::indexList->incContentsDepth();
2913
  }
2914 2915 2916 2917

  int page;
  bool first=TRUE;
  for (page=0;page<numPages;page++)
2918
  {
2919
    if (!multiPageIndex || g_namespaceIndexLetterUsed[hl][page].count()>0)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2920
    {
2921
      QCString fileName = getNmhlInfo(hl)->fname;
2922
      if (multiPageIndex)
2923
      {
2924 2925 2926 2927 2928 2929 2930
        if (!first)
        {
          fileName+=QCString().sprintf("_0x%02x",page);
        }
        char cs[2];
        cs[0]=page;
        cs[1]=0;
2931 2932
        if (addToIndex)
        {
2933
          Doxygen::indexList->addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE);
2934
        }
2935
      }
2936
      bool quickIndex = documentedNamespaceMembers[hl]>maxItemsBeforeQuickIndex;
2937
      
2938 2939 2940 2941
      ol.startFile(fileName+extension,0,title);
      ol.startQuickIndices();
      if (!disableIndex)
      {
2942
        ol.writeQuickLinks(TRUE,HLI_NamespaceMembers,0);
2943
        startQuickIndexList(ol);
2944

2945 2946 2947 2948 2949
        // index item for all namespace member lists
        startQuickIndexItem(ol,
            getNmhlInfo(0)->fname+Doxygen::htmlFileExtension,hl==NMHL_All,TRUE,first);
        ol.writeString(fixSpaces(getNmhlInfo(0)->title));
        endQuickIndexItem(ol);
2950

2951 2952 2953
        int i;
        // index items per category member lists
        for (i=1;i<NMHL_Total;i++)
2954
        {
2955 2956 2957 2958 2959 2960 2961
          if (documentedNamespaceMembers[i]>0)
          {
            startQuickIndexItem(ol,
                getNmhlInfo(i)->fname+Doxygen::htmlFileExtension,hl==i,TRUE,first);
            ol.writeString(fixSpaces(getNmhlInfo(i)->title));
            endQuickIndexItem(ol);
          }
2962 2963
        }

2964
        endQuickIndexList(ol);
2965

2966 2967 2968 2969 2970
        if (quickIndex)
        {
          writeQuickMemberIndex(ol,g_namespaceIndexLetterUsed[hl],page,
              getNmhlInfo(hl)->fname,multiPageIndex);
        }
2971

2972
      }
2973
      ol.endQuickIndices();
2974 2975
      ol.writeSplitBar(fileName);
      ol.writeSearchInfo();
2976

2977 2978
      ol.startContents();

2979 2980
      if (hl==NMHL_All)
      {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2981
        ol.startTextBlock();
2982
        ol.parseText(lne ? lne->intro() : theTranslator->trNamespaceMemberDescription(Config_getBool("EXTRACT_ALL")));
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2983
        ol.endTextBlock();
2984
      }
2985 2986 2987 2988
      else
      {
        // hack to work around a mozilla bug, which refuses to switch to
        // normal lists otherwise
2989
        ol.writeString("&#160;");
2990
      }
2991
      //ol.newParagraph(); // FIXME:PARA
2992

2993 2994 2995 2996 2997
      //writeNamespaceMemberList(ol,quickIndex,hl,page);
      writeMemberList(ol,quickIndex,
                      multiPageIndex?page:-1,
                      g_namespaceIndexLetterUsed[hl],
                      Definition::TypeNamespace);
2998
      endFile(ol);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
2999
    }
3000
  }
3001
  if (multiPageIndex && addToIndex) Doxygen::indexList->decContentsDepth();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3002
  ol.popGeneratorState();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3003 3004
}

3005
static void writeNamespaceMemberIndex(OutputList &ol)
3006
{
3007 3008 3009
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::NamespaceMembers);
  bool addToIndex = lne==0 || lne->visible();
  if (documentedNamespaceMembers[NMHL_All]>0 && addToIndex)
3010
  {
3011 3012
    Doxygen::indexList->addContentsItem(FALSE,lne ? lne->title() : theTranslator->trNamespaceMembers(),0,"namespacemembers",0); 
    Doxygen::indexList->incContentsDepth();
3013
  }
3014
  //bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
3015 3016 3017 3018 3019 3020
  writeNamespaceMemberIndexFiltered(ol,NMHL_All);
  writeNamespaceMemberIndexFiltered(ol,NMHL_Functions);
  writeNamespaceMemberIndexFiltered(ol,NMHL_Variables);
  writeNamespaceMemberIndexFiltered(ol,NMHL_Typedefs);
  writeNamespaceMemberIndexFiltered(ol,NMHL_Enums);
  writeNamespaceMemberIndexFiltered(ol,NMHL_EnumValues);
3021
  if (documentedNamespaceMembers[NMHL_All]>0 && addToIndex)
3022
  {
3023
    Doxygen::indexList->decContentsDepth();
3024
  }
3025

3026 3027
}

Dimitri van Heesch's avatar
Dimitri van Heesch committed
3028 3029
//----------------------------------------------------------------------------

3030 3031
//----------------------------------------------------------------------------

3032
static void writeExampleIndex(OutputList &ol)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3033
{
3034
  if (Doxygen::exampleSDict->count()==0) return;
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3035
  ol.pushGeneratorState();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3036
  ol.disable(OutputGenerator::Man);
3037
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Examples);
3038
  QCString title = lne ? lne->title() : theTranslator->trExamples();
3039 3040
  bool addToIndex = lne==0 || lne->visible();

3041
  startFile(ol,"examples",0,title,HLI_Examples);
3042

3043
  startTitle(ol,0);
3044
  ol.parseText(title);
3045
  endTitle(ol,0,0);
3046

3047
  ol.startContents();
3048 3049 3050

  if (addToIndex)
  {
3051 3052
    Doxygen::indexList->addContentsItem(TRUE,title,0,"examples",0,TRUE,TRUE); 
    Doxygen::indexList->incContentsDepth();
3053 3054
  }

Dimitri van Heesch's avatar
Dimitri van Heesch committed
3055
  ol.startTextBlock();
3056
  ol.parseText(lne ? lne->intro() : theTranslator->trExamplesDescription());
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3057
  ol.endTextBlock();
3058

3059
  ol.startItemList();
3060
  PageSDict::Iterator pdi(*Doxygen::exampleSDict);
3061 3062
  PageDef *pd=0;
  for (pdi.toFirst();(pd=pdi.current());++pdi)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3063
  {
3064
    ol.startItemListItem();
3065 3066
    QCString n=pd->getOutputFileBase();
    if (!pd->title().isEmpty())
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3067
    {
3068
      ol.writeObjectLink(0,n,0,pd->title());
3069 3070
      if (addToIndex)
      {
3071
        Doxygen::indexList->addContentsItem(FALSE,filterTitle(pd->title()),pd->getReference(),n,0,FALSE,TRUE);
3072
      }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3073 3074 3075
    }
    else
    {
3076
      ol.writeObjectLink(0,n,0,pd->name());
3077 3078
      if (addToIndex)
      {
3079
        Doxygen::indexList->addContentsItem(FALSE,pd->name(),pd->getReference(),n,0,FALSE,TRUE);
3080
      }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3081
    }
3082
    ol.endItemListItem();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3083 3084
    ol.writeString("\n");
  }
3085
  ol.endItemList();
3086 3087 3088

  if (addToIndex)
  {
3089
    Doxygen::indexList->decContentsDepth();
3090
  }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3091
  endFile(ol);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3092
  ol.popGeneratorState();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3093 3094
}

3095 3096 3097

//----------------------------------------------------------------------------

3098 3099 3100 3101 3102 3103 3104 3105 3106 3107
template<typename T>
bool writeMemberNavIndex(FTextStream &t,
                         int indent,
                         int n,
                         int documentedMembers[],
                         MemberIndexList indexLetterUsed[][MEMBER_INDEX_ENTRIES],
                         const T *(*getInfo)(int),
                         bool &first
                        )

3108
{
3109
  bool found=FALSE;
3110 3111
  QCString indentStr;
  indentStr.fill(' ',indent*2);
3112 3113 3114
  // index items per category member lists
  int i;
  for (i=0;i<n;i++)
3115
  {
3116 3117 3118 3119
    bool hasIndex       = documentedMembers[i]>0;
    bool quickIndex     = documentedMembers[i]>maxItemsBeforeQuickIndex;
    bool multiIndexPage = documentedMembers[i]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX;
    if (hasIndex)
3120
    {
3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140
      // terminate previous entry
      if (!first) t << "," << endl;
      first = FALSE;

      // start entry
      if (!found)
      {
        t << "[" << endl;
      }
      found = TRUE;

      t << indentStr << "  [ ";
      t << "\"" << fixSpaces(getInfo(i)->title) << "\", ";
      t << "\"" << getInfo(i)->fname << Doxygen::htmlFileExtension << "\", ";
      bool firstPage=TRUE;
      if (quickIndex)
      {
        t << "[ " << endl;
        int j;
        for (j=33;j<127;j++)
3141
        {
3142
          if (indexLetterUsed[i][j].count()>0)
3143
          {
3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157
            if (!firstPage) t << "," << endl;
            QCString fullName = getInfo(i)->fname;
            QCString extension = Doxygen::htmlFileExtension;
            QCString anchor;
            if (firstPage || !multiIndexPage) 
              anchor=fullName+extension+"#index_";
            else 
              anchor=fullName+QCString().sprintf("_0x%02x",j)+extension+"#index_";
            char is[2];is[0]=(char)j;is[1]='\0';
            QCString ci = letterToLabel((char)j);
            t << indentStr << "    [ ";
            t << "\"" << is << "\", ";
            t << "\"" << anchor << ci << "\", null ]";
            firstPage=FALSE;
3158 3159
          }
        }
3160
        t << endl << indentStr << "  ] ]";
3161
      }
3162
      else
3163
      {
3164
        t << "null" << " ]";
3165
      }
3166 3167 3168 3169 3170 3171 3172
    }
  }
  return found;
}

//----------------------------------------------------------------------------

3173
#if 0
3174
static bool writeFullNavIndex(FTextStream &t, LayoutNavEntry *root,int indent,bool &first)
3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185
{
  static struct NavEntryCountMap 
  {
    LayoutNavEntry::Kind kind;
    bool hasItems;
  } navEntryCountMap[] =
  {
    { LayoutNavEntry::MainPage,         TRUE                                   },
    { LayoutNavEntry::Pages,            indexedPages>0                         },
    { LayoutNavEntry::Modules,          documentedGroups>0                     },
    { LayoutNavEntry::Namespaces,       documentedNamespaces>0                 },
3186
    { LayoutNavEntry::NamespaceList,    documentedNamespaces>0                 },
3187 3188
    { LayoutNavEntry::NamespaceMembers, documentedNamespaceMembers[NMHL_All]>0 },
    { LayoutNavEntry::Classes,          annotatedClasses>0                     },
3189 3190
    { LayoutNavEntry::ClassList,        annotatedClasses>0                     },
    { LayoutNavEntry::ClassIndex,       annotatedClasses>0                     },
3191 3192 3193
    { LayoutNavEntry::ClassHierarchy,   hierarchyClasses>0                     },
    { LayoutNavEntry::ClassMembers,     documentedClassMembers[CMHL_All]>0     },
    { LayoutNavEntry::Files,            documentedFiles>0                      },
3194
    { LayoutNavEntry::FileList,         documentedFiles>0                      },
3195
    { LayoutNavEntry::FileGlobals,      documentedFileMembers[FMHL_All]>0      },
3196
    //{ LayoutNavEntry::Dirs,             documentedDirs>0                       },
3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209
    { LayoutNavEntry::Examples,         Doxygen::exampleSDict->count()>0       }
  };

  QCString indentStr;
  indentStr.fill(' ',indent*2);
  bool found=FALSE;
  if (root->children().count()>0)
  {
    QListIterator<LayoutNavEntry> li(root->children());
    LayoutNavEntry *entry;
    for (li.toFirst();(entry=li.current());++li)
    {
      if (navEntryCountMap[entry->kind()].hasItems && entry->visible())
3210
      {
3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249
        // terminate previous entry
        if (!first) t << "," << endl;
        first = FALSE;

        // start entry
        if (!found)
        {
          t << "[" << endl;
        }
        found = TRUE;

        bool emptySection=TRUE;
        t << indentStr << "  [ ";
        t << "\"" << fixSpaces(entry->title()) << "\", ";
        t << "\"" << entry->baseFile() << Doxygen::htmlFileExtension << "\", ";

        // write children (if any)
        bool firstChild=TRUE;
        if (entry->kind()==LayoutNavEntry::ClassMembers)
        {
          emptySection = !writeMemberNavIndex(t,indent+1,CMHL_Total,documentedClassMembers,g_memberIndexLetterUsed,&getCmhlInfo,firstChild);
        }
        else if (entry->kind()==LayoutNavEntry::NamespaceMembers)
        {
          emptySection = !writeMemberNavIndex(t,indent+1,NMHL_Total,documentedNamespaceMembers,g_namespaceIndexLetterUsed,&getNmhlInfo,firstChild);
        }
        else if (entry->kind()==LayoutNavEntry::FileGlobals)
        {
          emptySection = !writeMemberNavIndex(t,indent+1,FMHL_Total,documentedFileMembers,g_fileIndexLetterUsed,&getFmhlInfo,firstChild);
        }
        else
        {
          emptySection = !writeFullNavIndex(t,entry,indent+1,firstChild);
        }
        // end entry
        if (emptySection) // entry without children
          t << "null ]";
        else // entry with children
          t << endl << indentStr << "  ] ]";
3250 3251 3252
      }
    }
  }
3253
  return found;
3254
}
3255
#endif
3256

Dimitri van Heesch's avatar
Dimitri van Heesch committed
3257 3258
//----------------------------------------------------------------------------

3259
static void countRelatedPages(int &docPages,int &indexPages)
3260
{
3261
  docPages=indexPages=0;
3262
  PageSDict::Iterator pdi(*Doxygen::pageSDict);
3263 3264
  PageDef *pd=0;
  for (pdi.toFirst();(pd=pdi.current());++pdi)
3265
  {
3266
    if ( pd->visibleInIndex())
3267
    {
3268
      indexPages++; 
3269 3270 3271 3272
    }
    if ( pd->documentedPage())
    {
      docPages++;
3273
    }
3274 3275 3276 3277 3278
  }
}

//----------------------------------------------------------------------------

3279 3280 3281 3282 3283 3284 3285 3286 3287 3288
static bool mainPageHasTitle()
{
  if (Doxygen::mainPage==0) return FALSE;
  if (Doxygen::mainPage->title().isEmpty()) return FALSE;
  if (Doxygen::mainPage->title().lower()=="notitle") return FALSE;
  return TRUE;
}

//----------------------------------------------------------------------------

Dimitri van Heesch's avatar
Dimitri van Heesch committed
3289
static void writePages(PageDef *pd,FTVHelp *ftv)
3290
{
3291
  //printf("writePages()=%s pd=%p mainpage=%p\n",pd->name().data(),pd,Doxygen::mainPage);
3292 3293
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Pages);
  bool addToIndex = lne==0 || lne->visible();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315
  if (!addToIndex) return;

  bool hasSubPages = pd->hasSubPages();
  bool hasSections = pd->hasSections();

  if (pd->visibleInIndex())
  {
    QCString pageTitle;

    if (pd->title().isEmpty())
      pageTitle=pd->name();
    else
      pageTitle=pd->title();

    if (ftv)
    {
      //printf("*** adding %s\n",pageTitle.data());
      ftv->addContentsItem(
          hasSubPages,pageTitle,
          pd->getReference(),pd->getOutputFileBase(),
          0,hasSubPages,TRUE,pd); 
    }
3316
    if (addToIndex && pd!=Doxygen::mainPage)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3317
    {
3318
      Doxygen::indexList->addContentsItem(
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3319 3320 3321 3322 3323 3324
          hasSubPages,pageTitle,
          pd->getReference(),pd->getOutputFileBase(),
          0,hasSubPages,TRUE);
    }
  }
  if (hasSubPages && ftv) ftv->incContentsDepth();
3325 3326 3327
  bool doIndent = (hasSections || hasSubPages) &&  
                  (pd!=Doxygen::mainPage || mainPageHasTitle());
  if (doIndent)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3328
  {
3329
    Doxygen::indexList->incContentsDepth();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3330 3331 3332 3333 3334
  }
  if (hasSections)
  {
    pd->addSectionsToIndex();
  }
3335 3336 3337 3338 3339 3340 3341
  PageSDict *subPages = pd->getSubPages();
  if (subPages)
  {
    PageSDict::Iterator pi(*subPages);
    PageDef *subPage;
    for (pi.toFirst();(subPage=pi.current());++pi)
    {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3342
      writePages(subPage,ftv);
3343 3344
    }
  }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3345
  if (hasSubPages && ftv) ftv->decContentsDepth();
3346
  if (doIndent)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3347
  {
3348
    Doxygen::indexList->decContentsDepth();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3349 3350
  }
  //printf("end writePages()=%s\n",pd->title().data());
3351
}
3352

3353
//----------------------------------------------------------------------------
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3354

3355
static void writePageIndex(OutputList &ol)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3356
{
3357
  if (indexedPages==0) return;
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3358
  ol.pushGeneratorState();
3359
  ol.disableAllBut(OutputGenerator::Html);
3360
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Pages);
3361
  QCString title = lne ? lne->title() : theTranslator->trRelatedPages();
3362
  startFile(ol,"pages",0,title,HLI_Pages);
3363
  startTitle(ol,0);
3364
  ol.parseText(title);
3365
  endTitle(ol,0,0);
3366
  ol.startContents();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3367
  ol.startTextBlock();
3368
  ol.parseText(lne ? lne->intro() : theTranslator->trRelatedPagesDescription());
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3369
  ol.endTextBlock();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3370

Dimitri van Heesch's avatar
Dimitri van Heesch committed
3371
  {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3372 3373 3374 3375
    FTVHelp* ftv = new FTVHelp(FALSE);
    PageSDict::Iterator pdi(*Doxygen::pageSDict);
    PageDef *pd=0;
    for (pdi.toFirst();(pd=pdi.current());++pdi)
3376
    {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3377 3378 3379
      if (pd->getOuterScope()==0 || 
          pd->getOuterScope()->definitionType()!=Definition::TypePage
         )  // not a sub page
3380
      {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3381
        writePages(pd,ftv);
3382
      }
3383
    }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3384 3385 3386 3387 3388
    QGString outStr;
    FTextStream t(&outStr);
    ftv->generateTreeViewInline(t);
    ol.writeString(outStr);
    delete ftv;
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3389
  }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3390 3391 3392 3393

//  ol.popGeneratorState();
  // ------

Dimitri van Heesch's avatar
Dimitri van Heesch committed
3394
  endFile(ol);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3395
  ol.popGeneratorState();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3396 3397 3398 3399
}

//----------------------------------------------------------------------------

3400
static int countGroups()
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3401 3402
{
  int count=0;
3403
  GroupSDict::Iterator gli(*Doxygen::groupSDict);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3404
  GroupDef *gd;
3405
  for (gli.toFirst();(gd=gli.current());++gli)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3406
  {
3407 3408 3409 3410 3411
    if (!gd->isReference())
    {
      gd->visited=FALSE;
      count++;
    }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3412 3413 3414 3415
  }
  return count;
}

3416 3417
//----------------------------------------------------------------------------

3418
static int countDirs()
3419 3420
{
  int count=0;
3421
  SDict<DirDef>::Iterator dli(*Doxygen::directories);
3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433
  DirDef *dd;
  for (dli.toFirst();(dd=dli.current());++dli)
  {
    if (dd->isLinkableInProject())
    {
      dd->visited=FALSE;
      count++;
    }
  }
  return count;
}

3434 3435 3436 3437 3438

//----------------------------------------------------------------------------

void writeGraphInfo(OutputList &ol)
{
3439
  if (!Config_getBool("HAVE_DOT") || !Config_getBool("GENERATE_HTML")) return;
3440 3441
  ol.pushGeneratorState();
  ol.disableAllBut(OutputGenerator::Html);
3442
  generateGraphLegend(Config_getString("HTML_OUTPUT"));
3443
  startFile(ol,"graph_legend",0,theTranslator->trLegendTitle().data());
3444
  startTitle(ol,0);
3445
  ol.parseText(theTranslator->trLegendTitle());
3446
  endTitle(ol,0,0);
3447
  ol.startContents();
3448 3449
  bool &stripCommentsStateRef = Config_getBool("STRIP_CODE_COMMENTS");
  bool oldStripCommentsState = stripCommentsStateRef;
3450
  // temporarily disable the stripping of comments for our own code example!
3451
  stripCommentsStateRef = FALSE;
3452 3453 3454 3455 3456 3457 3458 3459
  QCString legendDocs = theTranslator->trLegendDocs();
  int s = legendDocs.find("<center>");
  int e = legendDocs.find("</center>");
  if (Config_getEnum("DOT_IMAGE_FORMAT")=="svg" && s!=-1 && e!=-1)
  {
    legendDocs = legendDocs.left(s+8) + "[!-- SVG 0 --]\n" + legendDocs.mid(e); 
    //printf("legendDocs=%s\n",legendDocs.data());
  }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3460
  FileDef fd("","graph_legend");
3461
  ol.generateDoc("graph_legend",1,&fd,0,legendDocs,FALSE,FALSE);
3462
  stripCommentsStateRef = oldStripCommentsState;
3463 3464 3465 3466
  endFile(ol);
  ol.popGeneratorState();
}

3467 3468


3469 3470
//----------------------------------------------------------------------------
/*!
3471
 * write groups as hierarchical trees
3472
 */
3473
static void writeGroupTreeNode(OutputList &ol, GroupDef *gd, int level, FTVHelp* ftv, bool addToIndex)
3474
{
3475 3476
  //bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
  //bool vhdlOpt    = Config_getBool("OPTIMIZE_OUTPUT_VHDL");  
3477 3478 3479
  if (level>20)
  {
    warn(gd->getDefFileName(),gd->getDefLine(),
3480
        "maximum nesting level exceeded for group %s: check for possible recursive group relation!\n",gd->name().data()
3481 3482 3483
        );
    return;
  }
3484

3485 3486 3487
  /* Some groups should appear twice under different parent-groups.
   * That is why we should not check if it was visited 
   */
3488
  if (/*!gd->visited &&*/ (!gd->isASubGroup() || level>0) &&
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3489
      gd->isVisible() &&
3490 3491
      (!gd->isReference() || Config_getBool("EXTERNAL_GROUPS")) // hide external groups by default
     )
3492 3493 3494
  {
    //printf("gd->name()=%s #members=%d\n",gd->name().data(),gd->countMembers());
    // write group info
3495 3496
    bool hasSubGroups = gd->getSubGroups()->count()>0;
    bool hasSubPages = gd->getPages()->count()>0;
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3497
    int numSubItems = 0;
3498
    if (1 /*Config_getBool("TOC_EXPAND")*/)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3499
    {
3500 3501 3502 3503
      QListIterator<MemberList> mli(gd->getMemberLists());
      MemberList *ml;
      for (mli.toFirst();(ml=mli.current());++mli)
      {
3504
        if (ml->listType()&MemberListType_documentationLists)
3505 3506 3507 3508
        {
          numSubItems += ml->count();
        }
      }
3509 3510 3511
      numSubItems += gd->getNamespaces()->count();
      numSubItems += gd->getClasses()->count();
      numSubItems += gd->getFiles()->count();
3512 3513
      numSubItems += gd->getDirs()->count();
      numSubItems += gd->getPages()->count();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3514 3515 3516
    }

    bool isDir = hasSubGroups || hasSubPages || numSubItems>0;
3517
    //printf("gd=`%s': pageDict=%d\n",gd->name().data(),gd->pageDict->count());
3518 3519
    if (addToIndex)
    {
3520 3521
      Doxygen::indexList->addContentsItem(isDir,gd->groupTitle(),gd->getReference(),gd->getOutputFileBase(),0,isDir,TRUE); 
      Doxygen::indexList->incContentsDepth();
3522
    }
3523 3524
    if (ftv)
    {
3525 3526 3527
      ftv->addContentsItem(hasSubGroups,gd->groupTitle(),
                           gd->getReference(),gd->getOutputFileBase(),0,
                           FALSE,FALSE,gd); 
3528 3529 3530
      ftv->incContentsDepth();
    }
    
3531 3532 3533 3534
    //ol.writeListItem();
    //ol.startTextLink(gd->getOutputFileBase(),0);
    //parseText(ol,gd->groupTitle());
    //ol.endTextLink();
3535

3536
    ol.startIndexListItem();
3537 3538 3539
    ol.startIndexItem(gd->getReference(),gd->getOutputFileBase());
    ol.parseText(gd->groupTitle());
    ol.endIndexItem(gd->getReference(),gd->getOutputFileBase());
3540 3541 3542 3543 3544 3545
    if (gd->isReference()) 
    { 
      ol.startTypewriter(); 
      ol.docify(" [external]");
      ol.endTypewriter();
    }
3546

3547 3548 3549
    QListIterator<LayoutDocEntry> eli(LayoutDocManager::instance().docEntries(LayoutDocManager::Group));
    LayoutDocEntry *lde;
    for (eli.toFirst();(lde=eli.current());++eli)
3550
    {
3551
      if (lde->kind()==LayoutDocEntry::MemberDef && addToIndex)
3552
      {
3553 3554 3555
        LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde;
        MemberList *ml = gd->getMemberList(lmd->type);
        if (ml)
3556
        {
3557 3558 3559 3560
          MemberListIterator mi(*ml);
          MemberDef *md;
          for (mi.toFirst();(md=mi.current());++mi)
          {
3561
            MemberList *enumList = md->enumFieldList();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3562
            bool isDir = enumList!=0 && md->isEnumerate();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3563
            if (md->isVisible() && md->name().find('@')==-1)
3564
            {
3565
              Doxygen::indexList->addContentsItem(isDir,
3566
                  md->name(),md->getReference(),
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3567 3568 3569 3570
                  md->getOutputFileBase(),md->anchor(),FALSE,addToIndex);
            }
            if (isDir)
            {
3571
              Doxygen::indexList->incContentsDepth();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3572 3573 3574 3575 3576 3577
              MemberListIterator emli(*enumList);
              MemberDef *emd;
              for (emli.toFirst();(emd=emli.current());++emli)
              {
                if (emd->isVisible())
                {
3578
                  Doxygen::indexList->addContentsItem(FALSE,
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3579 3580 3581 3582
                      emd->name(),emd->getReference(),emd->getOutputFileBase(),
                      emd->anchor(),FALSE,addToIndex);
                }
              }
3583
              Doxygen::indexList->decContentsDepth();
3584 3585
            }
          }
3586 3587
        }
      }
3588
      else if (lde->kind()==LayoutDocEntry::GroupClasses && addToIndex)
3589
      {
3590
        ClassSDict::Iterator it(*gd->getClasses());
3591
        ClassDef *cd;
3592 3593
        for (;(cd=it.current());++it)
        {
3594 3595 3596 3597 3598
          //bool nestedClassInSameGroup = 
          //    cd->getOuterScope() && cd->getOuterScope()->definitionType()==Definition::TypeClass &&
          //    cd->getOuterScope()->partOfGroups()!=0 && cd->getOuterScope()->partOfGroups()->contains(gd);
          //printf("===== GroupClasses: %s visible=%d nestedClassInSameGroup=%d\n",cd->name().data(),cd->isVisible(),nestedClassInSameGroup);
          if (cd->isVisible() /*&& !nestedClassInSameGroup*/)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3599
          {
3600 3601 3602
            //if (cd->isEmbeddedInOuterScope())
            //{
              //printf("add class & members %d\n",addToIndex);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3603
              addMembersToIndex(cd,LayoutDocManager::Class,cd->displayName(FALSE),cd->anchor(),addToIndex,TRUE);
3604 3605 3606 3607
            //}
            //else // only index the class, not its members
            //{
            //  printf("%s: add class only\n",cd->name().data());
3608
            //  Doxygen::indexList->addContentsItem(FALSE,
3609 3610 3611
            //    cd->displayName(TRUE),cd->getReference(),
            //    cd->getOutputFileBase(),cd->anchor(),addToIndex,TRUE);
            //}
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3612
          }
3613 3614 3615 3616 3617 3618 3619 3620
        }
      }
      else if (lde->kind()==LayoutDocEntry::GroupNamespaces && addToIndex)
      {
        NamespaceSDict::Iterator it(*gd->getNamespaces());
        NamespaceDef *nd;
        for (;(nd=it.current());++it)
        {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3621 3622
          if (nd->isVisible())
          {
3623
            Doxygen::indexList->addContentsItem(FALSE,
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3624 3625 3626
                nd->localName(),nd->getReference(),
                nd->getOutputFileBase(),0,FALSE,FALSE);
          }
3627 3628 3629 3630 3631 3632 3633 3634
        }
      }
      else if (lde->kind()==LayoutDocEntry::GroupFiles && addToIndex)
      {
        QListIterator<FileDef> it(*gd->getFiles());
        FileDef *fd;
        for (;(fd=it.current());++it)
        {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3635 3636
          if (fd->isVisible())
          {
3637
            Doxygen::indexList->addContentsItem(FALSE,
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3638 3639 3640
                fd->displayName(),fd->getReference(),
                fd->getOutputFileBase(),0,FALSE,FALSE);
          }
3641 3642 3643 3644
        }
      }
      else if (lde->kind()==LayoutDocEntry::GroupDirs && addToIndex)
      {
3645 3646 3647
        QListIterator<DirDef> it(*gd->getDirs());
        DirDef *dd;
        for (;(dd=it.current());++it)
3648
        {
3649
          if (dd->isVisible())
3650
          {
3651
            Doxygen::indexList->addContentsItem(FALSE,
3652 3653
                dd->shortName(),dd->getReference(),
                dd->getOutputFileBase(),0,FALSE,FALSE);
3654 3655
          }
        }
3656
      }
3657
      else if (lde->kind()==LayoutDocEntry::GroupPageDocs && addToIndex)
3658
      {
3659 3660 3661
        SDict<PageDef>::Iterator it(*gd->getPages());
        PageDef *pd;
        for (;(pd=it.current());++it)
3662
        {
3663
          SectionInfo *si=0;
3664
          if (!pd->name().isEmpty()) si=Doxygen::sectionDict->find(pd->name());
3665 3666
          bool hasSubPages = pd->hasSubPages();
          bool hasSections = pd->hasSections();
3667
          Doxygen::indexList->addContentsItem(
3668 3669 3670 3671 3672 3673 3674 3675 3676
              hasSubPages || hasSections,
              convertToHtml(pd->title(),TRUE),
              gd->getReference(),
              gd->getOutputFileBase(),
              si ? si->label.data() : 0,
              hasSubPages || hasSections,
              TRUE); // addToNavIndex
          if (hasSections || hasSubPages)
          {
3677
            Doxygen::indexList->incContentsDepth();
3678 3679 3680 3681 3682
          }
          if (hasSections)
          {
            pd->addSectionsToIndex();
          }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3683
          writePages(pd,0);
3684 3685
          if (hasSections || hasSubPages)
          {
3686
            Doxygen::indexList->decContentsDepth();
3687
          }
3688
        }
3689
      }
3690
      else if (lde->kind()==LayoutDocEntry::GroupNestedGroups)
3691
      {
3692
        if (gd->getSubGroups()->count()>0)
3693
        {
3694 3695 3696 3697 3698 3699 3700 3701 3702
          startIndexHierarchy(ol,level+1);
          if (Config_getBool("SORT_GROUP_NAMES")) gd->sortSubGroups();
          QListIterator<GroupDef> gli(*gd->getSubGroups());
          GroupDef *subgd = 0;
          for (gli.toFirst();(subgd=gli.current());++gli)
          {
            writeGroupTreeNode(ol,subgd,level+1,ftv,addToIndex);
          }
          endIndexHierarchy(ol,level+1); 
3703
        }
3704 3705
      }
    }
3706

3707
    ol.endIndexListItem();
3708
    
3709 3710
    if (addToIndex)
    {
3711
      Doxygen::indexList->decContentsDepth();
3712
    }
3713
    if (ftv)
3714
    {
3715
      ftv->decContentsDepth();
3716
    }
3717
    //gd->visited=TRUE;
3718 3719 3720
  }
}

3721
static void writeGroupHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex)
3722
{
3723 3724 3725 3726 3727
  if (ftv)
  {
    ol.pushGeneratorState(); 
    ol.disable(OutputGenerator::Html);
  }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3728
  startIndexHierarchy(ol,0);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3729
  if (Config_getBool("SORT_GROUP_NAMES"))
3730
  {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3731
    Doxygen::groupSDict->sort();
3732
  }
3733
  GroupSDict::Iterator gli(*Doxygen::groupSDict);
3734
  GroupDef *gd;
3735
  for (gli.toFirst();(gd=gli.current());++gli)
3736
  {
3737
    writeGroupTreeNode(ol,gd,0,ftv,addToIndex);
3738
  }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3739
  endIndexHierarchy(ol,0); 
3740
  if (ftv)
3741
  {
3742
    ol.popGeneratorState(); 
3743
  }
3744 3745
}

3746 3747
#if 0
static void writeGroupTree(GroupDef *gd,FTVHelp *ftv,int level,bool addToIndex)
3748
{
3749 3750 3751 3752 3753 3754 3755 3756
  static bool externalGroups = Config_getBool("EXTERNAL_GROUPS");
  /* Some groups should appear twice under different parent-groups.
   * That is why we should not check if it was visited 
   */
  if ((!gd->isASubGroup() || level>0) &&
      gd->isVisible() &&
      (!gd->isReference() || externalGroups) // hide external groups by default
     )
3757
  {
3758
    if (ftv)
3759
    {
3760 3761
      ftv->addContentsItem(hasSubGroups,gd->groupTitle(),gd->getReference(),gd->getOutputFileBase(),0); 
      ftv->incContentsDepth();
3762
    }
3763
    if (ftv)
3764
    {
3765
      ftv->decContentsDepth();
3766 3767 3768 3769
    }
  }
}

3770
static void writeGroupTree(FTVHelp *ftv,bool addToIndex)
3771
{
3772 3773 3774
  GroupSDict::Iterator gli(*Doxygen::groupSDict);
  GroupDef *gd;
  for (gli.toFirst();(gd=gli.current());++gli)
3775
  {
3776
    writeGroupTree(gd,ftv,0,addToIndex);
3777
  }
3778
}
3779
#endif
3780

Dimitri van Heesch's avatar
Dimitri van Heesch committed
3781 3782
//----------------------------------------------------------------------------

3783
static void writeGroupIndex(OutputList &ol)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3784 3785
{
  if (documentedGroups==0) return; 
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3786
  ol.pushGeneratorState(); 
3787
  // 1.{
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3788
  ol.disable(OutputGenerator::Man);
3789
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Modules);
3790
  QCString title = lne ? lne->title() : theTranslator->trModules();
3791 3792
  bool addToIndex = lne==0 || lne->visible();

3793
  startFile(ol,"modules",0,title,HLI_Modules);
3794
  startTitle(ol,0);
3795
  ol.parseText(title);
3796
  endTitle(ol,0,0);
3797
  ol.startContents();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3798
  ol.startTextBlock();
3799
  ol.parseText(lne ? lne->intro() : theTranslator->trModulesDescription());
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3800
  ol.endTextBlock();
3801

3802 3803 3804 3805 3806 3807
  // ---------------
  // Normal group index for Latex/RTF
  // ---------------
  // 2.{
  ol.pushGeneratorState();
  ol.disable(OutputGenerator::Html);
3808
  Doxygen::indexList->disable();
3809

3810 3811
  writeGroupHierarchy(ol,0,FALSE);

3812
  Doxygen::indexList->enable();
3813 3814 3815 3816 3817 3818 3819 3820 3821
  ol.popGeneratorState();
  // 2.}

  // ---------------
  // interactive group index for HTML
  // ---------------
  // 2.{
  ol.pushGeneratorState(); 
  ol.disableAllBut(OutputGenerator::Html);
3822 3823

  {
3824 3825
    if (addToIndex)
    {
3826 3827
      Doxygen::indexList->addContentsItem(TRUE,title,0,"modules",0,TRUE,TRUE); 
      Doxygen::indexList->incContentsDepth();
3828 3829 3830
    }
    FTVHelp* ftv = new FTVHelp(FALSE);
    writeGroupHierarchy(ol,ftv,addToIndex);
3831 3832 3833
    QGString outStr;
    FTextStream t(&outStr);
    ftv->generateTreeViewInline(t);
3834
    ol.disableAllBut(OutputGenerator::Html);
3835
    ol.writeString(outStr);
3836
    delete ftv;
3837 3838
    if (addToIndex)
    {
3839
      Doxygen::indexList->decContentsDepth();
3840
    }
3841
  }
3842 3843 3844
  ol.popGeneratorState();
  // 2.}

Dimitri van Heesch's avatar
Dimitri van Heesch committed
3845
  endFile(ol);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3846
  ol.popGeneratorState();
3847
  // 1.}
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3848 3849
}

3850 3851
//----------------------------------------------------------------------------

3852
#if 0
3853
static void writeDirIndex(OutputList &ol)
3854 3855 3856 3857
{
  if (documentedDirs==0) return; 
  ol.pushGeneratorState(); 
  ol.disable(OutputGenerator::Man);
3858
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Dirs);
3859
  QCString title = lne ? lne->title() : theTranslator->trDirectories();
3860
  bool addToIndex=FALSE; //lne==0 || lne->visible();
3861

3862
  startFile(ol,"dirs",0,title,HLI_Directories);
3863 3864 3865
  startTitle(ol,0);
  ol.parseText(title);
  endTitle(ol,0,0);
3866
  ol.startContents();
3867
  ol.startTextBlock();
3868 3869 3870

  if (addToIndex)
  {
3871 3872
    Doxygen::indexList->addContentsItem(TRUE,title,0,"dirs",0,TRUE,TRUE); 
    Doxygen::indexList->incContentsDepth();
3873
  }
3874
  ol.parseText(lne ? lne->intro() : theTranslator->trDirDescription());
3875 3876
  ol.endTextBlock();

3877 3878 3879
  FTVHelp* ftv = 0;
  bool treeView=Config_getBool("USE_INLINE_TREES");
  if (treeView)
3880 3881 3882
  {
    ftv = new FTVHelp(FALSE);
  }
3883

3884
  writeDirHierarchy(ol,ftv,addToIndex);
3885 3886 3887

  if (ftv)
  {
3888 3889 3890
    QGString outStr;
    FTextStream t(&outStr);
    ftv->generateTreeViewInline(t);
3891 3892
    ol.pushGeneratorState(); 
    ol.disableAllBut(OutputGenerator::Html);
3893
    ol.writeString(outStr);
3894 3895 3896
    ol.popGeneratorState();
    delete ftv;
  }
3897 3898
  if (addToIndex)
  {
3899
    Doxygen::indexList->decContentsDepth();
3900 3901 3902 3903
  }
  endFile(ol);
  ol.popGeneratorState();
}
3904
#endif
3905 3906 3907 3908 3909

//----------------------------------------------------------------------------

static void writeUserGroupStubPage(OutputList &ol,LayoutNavEntry *lne)
{
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3910
  if (lne->baseFile().left(9)=="usergroup")
3911
  {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3912 3913 3914 3915 3916 3917 3918 3919 3920 3921
    ol.pushGeneratorState();
    ol.disableAllBut(OutputGenerator::Html);
    startFile(ol,lne->baseFile(),0,lne->title(),HLI_UserGroup);
    startTitle(ol,0);
    ol.parseText(lne->title());
    endTitle(ol,0,0);
    ol.startContents();
    QListIterator<LayoutNavEntry> li(lne->children());
    LayoutNavEntry *entry;
    int count=0;
3922 3923
    for (li.toFirst();(entry=li.current());++li)
    {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3924 3925 3926 3927 3928 3929
      if (entry->visible()) count++;
    }
    if (count>0)
    {
      ol.writeString("<ul>\n");
      for (li.toFirst();(entry=li.current());++li)
3930
      {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3931 3932 3933 3934 3935
        if (entry->visible())
        {
          ol.writeString("<li><a href=\""+entry->url()+"\"><span>"+
              fixSpaces(entry->title())+"</span></a></li>\n");
        }
3936
      }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3937
      ol.writeString("</ul>\n");
3938
    }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3939 3940
    endFile(ol);
    ol.popGeneratorState();
3941
  }
3942 3943 3944 3945
}

//----------------------------------------------------------------------------

3946

3947
static void writeIndex(OutputList &ol)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3948
{
3949 3950
  static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
  static bool vhdlOpt    = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3951
  static QCString projectName = Config_getString("PROJECT_NAME");
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3952
  // save old generator state
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3953
  ol.pushGeneratorState();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3954

3955
  QCString projPrefix;
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3956
  if (!projectName.isEmpty())
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3957
  {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3958
    projPrefix=projectName+" ";
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3959
  }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3960 3961

  //--------------------------------------------------------------------
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3962
  // write HTML index
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3963
  //--------------------------------------------------------------------
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3964
  ol.disableAllBut(OutputGenerator::Html);
3965

3966
  QCString defFileName = 
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3967
    Doxygen::mainPage ? Doxygen::mainPage->docFile().data() : "[generated]";
3968
  int defLine =
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3969
    Doxygen::mainPage ? Doxygen::mainPage->docLine() : -1;
3970

Dimitri van Heesch's avatar
Dimitri van Heesch committed
3971
  QCString title;
3972
  if (!mainPageHasTitle())
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3973
  {
3974
    title = theTranslator->trMainPage();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3975
  }
3976
  else 
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3977
  {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3978
    title = filterTitle(Doxygen::mainPage->title());
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3979 3980
  }

3981
  QCString indexName="index";
3982
  ol.startFile(indexName,0,title);
3983
  
3984
  if (Doxygen::mainPage)
3985
  {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3986 3987
    if (
        (!projectName.isEmpty() && mainPageHasTitle() && qstricmp(title,projectName)!=0)
3988 3989
       ) // to avoid duplicate entries in the treeview
    {
3990
      Doxygen::indexList->addContentsItem(Doxygen::mainPage->hasSubPages(),title,0,indexName,0,Doxygen::mainPage->hasSubPages(),TRUE); 
3991
    }
3992
    if (Doxygen::mainPage->hasSubPages() || Doxygen::mainPage->hasSections())
3993
    {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3994
      writePages(Doxygen::mainPage,0);
3995
    }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
3996
  }
3997

3998
  ol.startQuickIndices();
3999 4000
  if (!Config_getBool("DISABLE_INDEX")) 
  {
4001
    ol.writeQuickLinks(TRUE,HLI_Main,0);
4002 4003
  }
  ol.endQuickIndices();
4004 4005
  ol.writeSplitBar(indexName);
  ol.writeSearchInfo();
4006
  bool headerWritten=FALSE;
4007
  if (Doxygen::mainPage && !Doxygen::mainPage->title().isEmpty())
4008
  {
4009 4010
    if (Doxygen::mainPage->title().lower()!="notitle")
    {
4011 4012
      ol.startHeaderSection();
      ol.startTitleHead(0);
4013
      ol.generateDoc(Doxygen::mainPage->docFile(),Doxygen::mainPage->docLine(),
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4014 4015
                  Doxygen::mainPage,0,Doxygen::mainPage->title(),
                  TRUE,FALSE,0,TRUE,FALSE);
4016
      headerWritten = TRUE;
4017
    }
4018 4019 4020
  }
  else
  {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4021
    if (!projectName.isEmpty())
4022
    {
4023 4024
      ol.startHeaderSection();
      ol.startTitleHead(0);
4025
      ol.parseText(projPrefix+theTranslator->trDocumentation());
4026
      headerWritten = TRUE;
4027
    }
4028
  }
4029 4030 4031 4032 4033
  if (headerWritten)
  {
    ol.endTitleHead(0,0);
    ol.endHeaderSection();
  }
4034

4035
  ol.startContents();
4036 4037
  if (Config_getBool("DISABLE_INDEX") && Doxygen::mainPage==0) 
  {
4038
    ol.writeQuickLinks(FALSE,HLI_Main,0);
4039
  }
4040

4041
  if (Doxygen::mainPage)
4042
  {
4043
    Doxygen::insideMainPage=TRUE;
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4044 4045 4046 4047 4048
    if (Doxygen::mainPage->showToc() && Doxygen::mainPage->hasSections())
    {
      Doxygen::mainPage->writeToc(ol);
    }

Dimitri van Heesch's avatar
Dimitri van Heesch committed
4049
    ol.startTextBlock();
4050
    ol.generateDoc(defFileName,defLine,Doxygen::mainPage,0,
4051
                Doxygen::mainPage->documentation(),TRUE,FALSE
4052
                /*,Doxygen::mainPage->sectionDict*/);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4053
    ol.endTextBlock();
4054

4055
    Doxygen::insideMainPage=FALSE;
4056 4057
  }
  
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4058 4059 4060
  endFile(ol);
  ol.disable(OutputGenerator::Html);
  
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4061
  //--------------------------------------------------------------------
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4062
  // write LaTeX/RTF index
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4063
  //--------------------------------------------------------------------
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4064
  ol.enable(OutputGenerator::Latex);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4065 4066
  ol.enable(OutputGenerator::RTF);

4067
  ol.startFile("refman",0,0);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4068
  ol.startIndexSection(isTitlePageStart);
4069
  if (!Config_getString("LATEX_HEADER").isEmpty()) 
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4070 4071 4072 4073
  {
    ol.disable(OutputGenerator::Latex);
  }

4074 4075 4076 4077 4078 4079 4080 4081 4082
  if (projPrefix.isEmpty())
  {
    ol.parseText(theTranslator->trReferenceManual());
  }
  else
  {
    ol.parseText(projPrefix);
  }

4083
  if (!Config_getString("PROJECT_NUMBER").isEmpty())
4084
  {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4085
    ol.startProjectNumber(); 
4086
    ol.generateDoc(defFileName,defLine,Doxygen::mainPage,0,Config_getString("PROJECT_NUMBER"),FALSE,FALSE);
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4087 4088 4089 4090
    ol.endProjectNumber();
  }
  ol.endIndexSection(isTitlePageStart);
  ol.startIndexSection(isTitlePageAuthor);
4091
  ol.parseText(theTranslator->trGeneratedBy());
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4092
  ol.endIndexSection(isTitlePageAuthor);
4093 4094
  ol.enable(OutputGenerator::Latex);

4095
  ol.lastIndexPage();
4096
  if (Doxygen::mainPage)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4097 4098
  {
    ol.startIndexSection(isMainPage);
4099
    if (mainPageHasTitle())
4100
    {
4101
      ol.parseText(Doxygen::mainPage->title());
4102
    }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4103
    else
4104
    {
4105
      ol.parseText(/*projPrefix+*/theTranslator->trMainPage());
4106
    }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4107
    ol.endIndexSection(isMainPage);
4108
  }
4109 4110 4111 4112 4113 4114 4115 4116 4117
  if (documentedPages>0)
  {
    //ol.parseText(projPrefix+theTranslator->trPageDocumentation());
    //ol.endIndexSection(isPageDocumentation);
    PageSDict::Iterator pdi(*Doxygen::pageSDict);
    PageDef *pd=pdi.toFirst();
    bool first=Doxygen::mainPage==0;
    for (pdi.toFirst();(pd=pdi.current());++pdi)
    {
4118
      if (!pd->getGroupDef() && !pd->isReference() && 
4119 4120
          (!pd->hasParentPage() ||                    // not inside other page
           (Doxygen::mainPage==pd->getOuterScope()))  // or inside main page
4121
         )
4122
      {
4123 4124 4125 4126 4127 4128 4129
        bool isCitationPage = pd->name()=="citelist";
        if (isCitationPage)
        {
          // For LaTeX the bibliograph is already written by \bibliography
          ol.pushGeneratorState();
          ol.disable(OutputGenerator::Latex);
        }
4130 4131 4132 4133 4134
        QCString title = pd->title();
        if (title.isEmpty()) title=pd->name();
        ol.startIndexSection(isPageDocumentation);
        ol.parseText(title);
        ol.endIndexSection(isPageDocumentation);
4135 4136 4137 4138 4139 4140 4141
        ol.pushGeneratorState(); // write TOC title (RTF only)
          ol.disableAllBut(OutputGenerator::RTF);
          ol.startIndexSection(isPageDocumentation2);
          ol.parseText(title);
          ol.endIndexSection(isPageDocumentation2);
          ol.popGeneratorState();
        ol.writeAnchor(0,pd->name());
4142 4143 4144

        ol.writePageLink(pd->getOutputFileBase(),first);
        first=FALSE;
4145 4146 4147 4148 4149

        if (isCitationPage)
        {
          ol.popGeneratorState();
        }
4150 4151 4152
      }
    }
  }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4153

4154
  if (!Config_getBool("LATEX_HIDE_INDICES"))
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4155
  {
4156 4157 4158 4159 4160 4161
    //if (indexedPages>0)
    //{
    //  ol.startIndexSection(isPageIndex);
    //  ol.parseText(/*projPrefix+*/ theTranslator->trPageIndex());
    //  ol.endIndexSection(isPageIndex);
    //}
4162 4163 4164
    if (documentedGroups>0)
    {
      ol.startIndexSection(isModuleIndex);
4165
      ol.parseText(/*projPrefix+*/ theTranslator->trModuleIndex());
4166 4167 4168 4169 4170
      ol.endIndexSection(isModuleIndex);
    }
    if (documentedNamespaces>0)
    {
      ol.startIndexSection(isNamespaceIndex);
4171
      ol.parseText(/*projPrefix+*/(fortranOpt?theTranslator->trModulesIndex():theTranslator->trNamespaceIndex()));
4172 4173 4174 4175 4176
      ol.endIndexSection(isNamespaceIndex);
    }
    if (hierarchyClasses>0)
    {
      ol.startIndexSection(isClassHierarchyIndex);
4177 4178
      ol.parseText(/*projPrefix+*/
          (fortranOpt ? theTranslator->trCompoundIndexFortran() : 
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4179
           vhdlOpt    ? VhdlDocGen::trDesignUnitIndex()         :
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4180
                        theTranslator->trHierarchicalIndex()
4181
          ));
4182 4183
      ol.endIndexSection(isClassHierarchyIndex);
    }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4184
    if (annotatedClassesPrinted>0)
4185 4186
    {
      ol.startIndexSection(isCompoundIndex);
4187
      ol.parseText(/*projPrefix+*/
4188
          (fortranOpt ? theTranslator->trCompoundIndexFortran() :
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4189 4190
              vhdlOpt ? VhdlDocGen::trDesignUnitIndex()         : 
                        theTranslator->trCompoundIndex()
4191
          ));
4192 4193 4194 4195 4196
      ol.endIndexSection(isCompoundIndex);
    }
    if (documentedFiles>0)
    {
      ol.startIndexSection(isFileIndex);
4197
      ol.parseText(/*projPrefix+*/theTranslator->trFileIndex());
4198 4199
      ol.endIndexSection(isFileIndex);
    }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4200
  }
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4201 4202 4203
  if (documentedGroups>0)
  {
    ol.startIndexSection(isModuleDocumentation);
4204
    ol.parseText(/*projPrefix+*/theTranslator->trModuleDocumentation());
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4205 4206
    ol.endIndexSection(isModuleDocumentation);
  }
4207 4208 4209
  if (documentedNamespaces>0)
  {
    ol.startIndexSection(isNamespaceDocumentation);
4210
    ol.parseText(/*projPrefix+*/(fortranOpt?theTranslator->trModuleDocumentation():theTranslator->trNamespaceDocumentation()));
4211 4212
    ol.endIndexSection(isNamespaceDocumentation);
  }
4213
  if (annotatedClassesPrinted>0)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4214 4215
  {
    ol.startIndexSection(isClassDocumentation);
4216
    ol.parseText(/*projPrefix+*/(fortranOpt?theTranslator->trTypeDocumentation():theTranslator->trClassDocumentation()));
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4217 4218 4219 4220 4221
    ol.endIndexSection(isClassDocumentation);
  }
  if (documentedFiles>0)
  {
    ol.startIndexSection(isFileDocumentation);
4222
    ol.parseText(/*projPrefix+*/theTranslator->trFileDocumentation());
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4223 4224
    ol.endIndexSection(isFileDocumentation);
  }
4225
  if (Doxygen::exampleSDict->count()>0)
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4226 4227
  {
    ol.startIndexSection(isExampleDocumentation);
4228
    ol.parseText(/*projPrefix+*/theTranslator->trExampleDocumentation());
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4229 4230 4231 4232 4233
    ol.endIndexSection(isExampleDocumentation);
  }
  ol.endIndexSection(isEndIndex);
  endFile(ol);

4234
  if (Doxygen::mainPage)
4235
  {
4236
    Doxygen::insideMainPage=TRUE;
4237
    ol.disable(OutputGenerator::Man);
4238
    startFile(ol,Doxygen::mainPage->name(),0,Doxygen::mainPage->title());
4239
    ol.startContents();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4240
    ol.startTextBlock();
4241
    ol.generateDoc(defFileName,defLine,Doxygen::mainPage,0,
4242
                Doxygen::mainPage->documentation(),FALSE,FALSE
4243
               );
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4244
    ol.endTextBlock();
4245 4246
    endFile(ol);
    ol.enable(OutputGenerator::Man);
4247
    Doxygen::insideMainPage=FALSE;
4248 4249
  }

Dimitri van Heesch's avatar
Dimitri van Heesch committed
4250
  ol.popGeneratorState();
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4251
}
4252

4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271
static QArray<bool> indexWritten;

static void writeIndexHierarchyEntries(OutputList &ol,const QList<LayoutNavEntry> &entries)
{
  QListIterator<LayoutNavEntry> li(entries);
  LayoutNavEntry *lne;
  for (li.toFirst();(lne=li.current());++li)
  {
    LayoutNavEntry::Kind kind = lne->kind();
    uint index = (uint)kind;
    if (index>=indexWritten.size())
    {
      uint i;
      uint oldSize = indexWritten.size();
      uint newSize = index+1;
      indexWritten.resize(newSize);
      for (i=oldSize;i<newSize;i++) indexWritten.at(i)=FALSE;
    }
    //printf("starting %s kind=%d\n",lne->title().data(),lne->kind());
4272
    bool addToIndex=lne==0 || lne->visible();
4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291
    bool needsClosing=FALSE;
    if (!indexWritten.at(index))
    {
      switch(kind)
      {
        case LayoutNavEntry::MainPage: 
          msg("Generating index page...\n");
          writeIndex(ol); 
          break;
        case LayoutNavEntry::Pages: 
          msg("Generating page index...\n");
          writePageIndex(ol);
          break;
        case LayoutNavEntry::Modules: 
          msg("Generating module index...\n");
          writeGroupIndex(ol);
          break;
        case LayoutNavEntry::Namespaces: 
          {
4292 4293
            static bool showNamespaces = Config_getBool("SHOW_NAMESPACES");
            if (showNamespaces)
4294
            {
4295 4296
              if (documentedNamespaces>0 && addToIndex)
              {
4297 4298
                Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,0,0); 
                Doxygen::indexList->incContentsDepth();
4299 4300 4301 4302 4303 4304 4305
                needsClosing=TRUE;
              }
              if (LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Namespaces)!=lne) // for backward compatibility with old layout file
              {
                msg("Generating namespace index...\n");
                writeNamespaceIndex(ol);
              }
4306
            }
4307 4308 4309 4310 4311 4312
          }
          break;
        case LayoutNavEntry::NamespaceList: 
          {
            static bool showNamespaces = Config_getBool("SHOW_NAMESPACES");
            if (showNamespaces)
4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323
            {
              msg("Generating namespace index...\n");
              writeNamespaceIndex(ol);
            }
          }
          break;
        case LayoutNavEntry::NamespaceMembers: 
          msg("Generating namespace member index...\n");
          writeNamespaceMemberIndex(ol);
          break;
        case LayoutNavEntry::Classes: 
4324
          if (annotatedClasses>0 && addToIndex)
4325
          {
4326 4327
            Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,0,0); 
            Doxygen::indexList->incContentsDepth();
4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358
            needsClosing=TRUE;
          }
          if (LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Classes)!=lne) // for backward compatibility with old layout file
          {
            msg("Generating annotated compound index...\n");
            writeAnnotatedIndex(ol);
          }
          break;
        case LayoutNavEntry::ClassList: 
          msg("Generating annotated compound index...\n");
          writeAnnotatedIndex(ol);
          break;
        case LayoutNavEntry::ClassIndex:
          msg("Generating alphabetical compound index...\n");
          writeAlphabeticalIndex(ol);
          break;
        case LayoutNavEntry::ClassHierarchy: 
          msg("Generating hierarchical class index...\n");
          writeHierarchicalIndex(ol);
          if (Config_getBool("HAVE_DOT") && Config_getBool("GRAPHICAL_HIERARCHY"))
          {
            msg("Generating graphical class hierarchy...\n");
            writeGraphicalClassHierarchy(ol);
          }
          break;
        case LayoutNavEntry::ClassMembers: 
          msg("Generating member index...\n");
          writeClassMemberIndex(ol);
          break;
        case LayoutNavEntry::Files: 
          {
4359 4360 4361 4362 4363
            static bool showFiles = Config_getBool("SHOW_FILES");
            if (showFiles)
            {
              if (documentedHtmlFiles>0 && addToIndex)
              {
4364 4365
                Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,0,0); 
                Doxygen::indexList->incContentsDepth();
4366 4367 4368 4369 4370 4371 4372 4373
                needsClosing=TRUE;
              }
              if (LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Files)!=lne) // for backward compatibility with old layout file
              {
                msg("Generating file index...\n");
                writeFileIndex(ol);
              }
            }
4374 4375 4376
          }
          break;
        case LayoutNavEntry::FileList: 
4377 4378 4379 4380 4381 4382 4383 4384
          {
            static bool showFiles = Config_getBool("SHOW_FILES");
            if (showFiles)
            {
              msg("Generating file index...\n");
              writeFileIndex(ol);
            }
          }
4385 4386 4387 4388 4389 4390 4391 4392 4393 4394
          break;
        case LayoutNavEntry::FileGlobals: 
          msg("Generating file member index...\n");
          writeFileMemberIndex(ol);
          break;
        case LayoutNavEntry::Examples: 
          msg("Generating example index...\n");
          writeExampleIndex(ol);
          break;
        case LayoutNavEntry::User: 
4395 4396 4397
          {
            // prepend a ! or ^ marker to the URL to avoid tampering with it
            QCString url = correctURL(lne->url(),"!"); // add ! to relative URL
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4398 4399
            bool isRelative=url.at(0)=='!';
            if (!url.isEmpty() && !isRelative) // absolute URL
4400 4401 4402 4403
            {
              url.prepend("^"); // prepend ^ to absolute URL
            }
            bool isRef = lne->baseFile().left(4)=="@ref" || lne->baseFile().left(4)=="\\ref";
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4404
            Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,url,0,FALSE,isRef || isRelative); 
4405
          }
4406
          break;
4407 4408 4409
        case LayoutNavEntry::UserGroup:
          if (addToIndex)
          {
Dimitri van Heesch's avatar
Dimitri van Heesch committed
4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431
            QCString url = correctURL(lne->url(),"!"); // add ! to relative URL
            if (!url.isEmpty())
            {
              if (url=="![none]")
              {
                Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,0,0,FALSE,FALSE); 
              }
              else
              {
                bool isRelative=url.at(0)=='!';
                if (!isRelative) // absolute URL
                {
                  url.prepend("^"); // prepend ^ to absolute URL
                }
                bool isRef = lne->baseFile().left(4)=="@ref" || lne->baseFile().left(4)=="\\ref";
                Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,url,0,FALSE,isRef || isRelative); 
              }
            }
            else 
            {
              Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,lne->baseFile(),0,TRUE,TRUE); 
            }
4432
            Doxygen::indexList->incContentsDepth();
4433 4434 4435 4436 4437 4438 4439 4440
            needsClosing=TRUE;
          }
          writeUserGroupStubPage(ol,lne);
          break;
      }
      if (kind!=LayoutNavEntry::User && kind!=LayoutNavEntry::UserGroup) // User entry may appear multiple times
      {
        indexWritten.at(index)=TRUE;
4441 4442 4443 4444 4445 4446 4447 4448 4449 4450
      }
    }
    writeIndexHierarchyEntries(ol,lne->children());
    if (needsClosing)
    {
      switch(kind)
      {
        case LayoutNavEntry::Namespaces: 
        case LayoutNavEntry::Classes: 
        case LayoutNavEntry::Files: 
4451
        case LayoutNavEntry::UserGroup: 
4452
          Doxygen::indexList->decContentsDepth();
4453 4454 4455 4456 4457 4458 4459 4460
          break;
        default:
          break;
      }
    }
    //printf("ending %s kind=%d\n",lne->title().data(),lne->kind());
  }
}
4461

4462 4463 4464 4465 4466 4467 4468 4469
void writeIndexHierarchy(OutputList &ol)
{
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry();
  if (lne)
  {
    writeIndexHierarchyEntries(ol,lne->children());
  }
}
4470