index.cpp 125 KB
Newer Older
mueller's avatar
mueller committed
1 2
/******************************************************************************
 *
dimitri's avatar
dimitri committed
3
 * 
mueller's avatar
mueller committed
4
 *
dimitri's avatar
dimitri committed
5
 * Copyright (C) 1997-2012 by Dimitri van Heesch.
mueller's avatar
mueller 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's avatar
dimitri 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.
mueller's avatar
mueller committed
15 16 17
 *
 */

dimitri's avatar
dimitri committed
18 19 20 21
/** @file
 *  @brief This file contains functions for the various index pages.
 */

mueller's avatar
mueller committed
22 23
#include <stdlib.h>

mueller's avatar
mueller committed
24 25 26
#include <qtextstream.h>
#include <qdatetime.h>
#include <qdir.h>
dimitri's avatar
dimitri committed
27
#include <qregexp.h>
mueller's avatar
mueller committed
28

mueller's avatar
mueller 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"
dimitri's avatar
dimitri committed
38
#include "htmlgen.h"
mueller's avatar
mueller committed
39
#include "htmlhelp.h"
dimitri's avatar
dimitri committed
40
#include "ftvhelp.h"
dimitri's avatar
dimitri committed
41
#include "dot.h"
dimitri's avatar
dimitri committed
42
#include "pagedef.h"
dimitri's avatar
dimitri committed
43
#include "dirdef.h"
dimitri's avatar
dimitri committed
44
#include "vhdldocgen.h"
dimitri's avatar
dimitri committed
45
#include "layout.h"
mueller's avatar
mueller committed
46

dimitri's avatar
dimitri committed
47 48 49
#define MAX_ITEMS_BEFORE_MULTIPAGE_INDEX 200
#define MAX_ITEMS_BEFORE_QUICK_INDEX 30

dimitri's avatar
dimitri committed
50

dimitri's avatar
dimitri committed
51
int annotatedClasses;
dimitri's avatar
dimitri committed
52
int annotatedClassesPrinted;
dimitri's avatar
dimitri committed
53 54 55 56 57 58 59 60
int hierarchyClasses;
int documentedFiles;
int documentedGroups;
int documentedNamespaces;
int indexedPages;
int documentedClassMembers[CMHL_Total];
int documentedFileMembers[FMHL_Total];
int documentedNamespaceMembers[NMHL_Total];
dimitri's avatar
dimitri committed
61 62
int documentedHtmlFiles;
int documentedPages;
dimitri's avatar
dimitri committed
63
int documentedDirs;
dimitri's avatar
dimitri committed
64

dimitri's avatar
dimitri committed
65 66 67 68 69 70 71
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);
dimitri's avatar
dimitri committed
72 73 74

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

dimitri's avatar
dimitri committed
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
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();
}

mueller's avatar
mueller committed
113 114
//----------------------------------------------------------------------------

dimitri's avatar
dimitri committed
115 116 117 118 119 120 121 122 123 124 125 126 127
class MemberIndexList : public QList<MemberDef>
{
  public:
    MemberIndexList() : QList<MemberDef>() {}
    ~MemberIndexList() {}
    int compareItems(GCI item1, GCI item2)
    {
      MemberDef *md1=(MemberDef *)item1;
      MemberDef *md2=(MemberDef *)item2;
      return stricmp(md1->name(),md2->name());
    }
};

dimitri's avatar
dimitri committed
128
#define MEMBER_INDEX_ENTRIES 256
dimitri's avatar
dimitri committed
129 130 131 132 133

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];

dimitri's avatar
dimitri committed
134
//static bool g_classIndexLetterUsed[CHL_Total][256];
dimitri's avatar
dimitri committed
135

dimitri's avatar
dimitri committed
136
const int maxItemsBeforeQuickIndex = MAX_ITEMS_BEFORE_QUICK_INDEX;
dimitri's avatar
dimitri committed
137

dimitri's avatar
dimitri committed
138 139
//----------------------------------------------------------------------------

mueller's avatar
mueller committed
140 141
//----------------------------------------------------------------------------

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

static void endQuickIndexList(OutputList &ol)
{
  bool fancyTabs = TRUE;
  if (fancyTabs)
  {
dimitri's avatar
dimitri committed
168
    ol.writeString("    </ul>\n");
dimitri's avatar
dimitri committed
169
  }
dimitri's avatar
dimitri committed
170
  ol.writeString("  </div>\n");
dimitri's avatar
dimitri committed
171 172
}

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

static void endQuickIndexItem(OutputList &ol)
{
dimitri's avatar
dimitri committed
208 209
  bool fancyTabs=TRUE;
  if (fancyTabs) ol.writeString("</span>");
dimitri's avatar
dimitri committed
210
  ol.writeString("</a>");
dimitri's avatar
dimitri committed
211
  if (fancyTabs) ol.writeString("</li>\n");
dimitri's avatar
dimitri committed
212 213
}

dimitri's avatar
dimitri committed
214 215 216
// 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)
dimitri's avatar
dimitri committed
217
{
dimitri's avatar
dimitri committed
218
  return substitute(s," ","&#160;");
dimitri's avatar
dimitri committed
219 220
}

dimitri's avatar
dimitri committed
221
void startTitle(OutputList &ol,const char *fileName,Definition *def)
dimitri's avatar
dimitri committed
222
{
dimitri's avatar
dimitri committed
223 224
  ol.startHeaderSection();
  if (def) def->writeSummaryLinks(ol);
dimitri's avatar
dimitri committed
225
  ol.startTitleHead(fileName);
dimitri's avatar
dimitri committed
226 227
  ol.pushGeneratorState();
  ol.disable(OutputGenerator::Man);
dimitri's avatar
dimitri committed
228 229 230 231
}

void endTitle(OutputList &ol,const char *fileName,const char *name)
{
dimitri's avatar
dimitri committed
232
  ol.popGeneratorState();
dimitri's avatar
dimitri committed
233
  ol.endTitleHead(fileName,name);
dimitri's avatar
dimitri committed
234
  ol.endHeaderSection();
dimitri's avatar
dimitri committed
235 236
}

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

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

dimitri's avatar
dimitri committed
275 276 277
void endFileWithNavPath(Definition *d,OutputList &ol)
{
  static bool generateTreeView = Config_getBool("GENERATE_TREEVIEW");
dimitri's avatar
dimitri committed
278
  QCString navPath;
dimitri's avatar
dimitri committed
279 280
  if (generateTreeView)
  {
dimitri's avatar
dimitri committed
281 282
    ol.writeString("</div><!-- doc-content -->\n");
    navPath = d->navigationPathAsString();
dimitri's avatar
dimitri committed
283
  }
dimitri's avatar
dimitri committed
284
  endFile(ol,generateTreeView,TRUE,navPath);
dimitri's avatar
dimitri committed
285 286
}

dimitri's avatar
dimitri committed
287
//----------------------------------------------------------------------
dimitri's avatar
dimitri committed
288
template<class T> void addMembersToIndex(T *def,LayoutDocManager::LayoutPart part,const QCString &name,const QCString &anchor,bool addToIndex=TRUE)
dimitri's avatar
dimitri committed
289 290
{
  bool hasMembers = def->getMemberLists().count()>0 || def->getMemberGroupSDict()!=0;
dimitri's avatar
dimitri committed
291 292 293 294 295 296 297 298 299 300 301 302 303
  Doxygen::indexList.addContentsItem(hasMembers,name,def->getReference(),def->getOutputFileBase(),anchor,hasMembers,addToIndex);
  int numClasses=0;
  ClassSDict *classes = def->getClassSDict();
  if (classes)
  {
     ClassDef *cd;
     ClassSDict::Iterator it(*classes);
     for (;(cd=it.current());++it)
     {
       if (cd->isLinkable()) numClasses++;
     }
  }
  if (hasMembers || numClasses>0)
dimitri's avatar
dimitri committed
304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
  {
    Doxygen::indexList.incContentsDepth();
    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)
          {
            if (md->name().find('@')==-1)
            {
              Doxygen::indexList.addContentsItem(FALSE,
dimitri's avatar
dimitri committed
323
                  md->name(),md->getReference(),md->getOutputFileBase(),md->anchor(),FALSE,addToIndex);
dimitri's avatar
dimitri committed
324 325 326 327 328
            }
          }
        }
      }
      else if (lde->kind()==LayoutDocEntry::NamespaceClasses || 
dimitri's avatar
dimitri committed
329 330 331
               lde->kind()==LayoutDocEntry::FileClasses || 
               lde->kind()==LayoutDocEntry::ClassNestedClasses
              )
dimitri's avatar
dimitri committed
332 333 334 335 336 337 338
      {
        if (classes)
        {
          ClassDef *cd;
          ClassSDict::Iterator it(*classes);
          for (;(cd=it.current());++it)
          {
dimitri's avatar
dimitri committed
339
            if (cd->isLinkable())
dimitri's avatar
dimitri committed
340
            {
dimitri's avatar
dimitri committed
341 342 343
              bool isNestedClass = def->definitionType()==Definition::TypeClass;
              addMembersToIndex(cd,LayoutDocManager::Class,cd->className(),cd->anchor(),
                                addToIndex && isNestedClass);
dimitri's avatar
dimitri committed
344 345 346 347 348 349 350 351 352 353
            }
          }
        }
      }
    }

    Doxygen::indexList.decContentsDepth();
  }
}

dimitri's avatar
dimitri committed
354 355
//----------------------------------------------------------------------------

dimitri's avatar
dimitri committed
356 357
static bool classHasVisibleChildren(ClassDef *cd)
{
dimitri's avatar
dimitri committed
358 359
  BaseClassList *bcl;

dimitri's avatar
dimitri committed
360
  if (cd->getLanguage()==SrcLangExt_VHDL) // reverse baseClass/subClass relation
dimitri's avatar
dimitri committed
361 362 363 364 365 366 367 368 369 370
  {
    if (cd->baseClasses()==0) return FALSE;
    bcl=cd->baseClasses();
  }
  else 
  {
    if (cd->subClasses()==0) return FALSE;
    bcl=cd->subClasses();
  }

dimitri's avatar
dimitri committed
371 372 373 374 375 376 377 378 379 380 381
  BaseClassListIterator bcli(*bcl);
  for ( ; bcli.current() ; ++bcli)
  {
    if (bcli.current()->classDef->isVisibleInHierarchy())
    {
      return TRUE;
    }
  }
  return FALSE;
}

dimitri's avatar
dimitri committed
382 383 384 385
//----------------------------------------------------------------------------
/*! Generates HTML Help tree of classes */

static void writeClassTree(OutputList &ol,BaseClassList *bcl,bool hideSuper,int level,FTVHelp* ftv,bool addToIndex)
mueller's avatar
mueller committed
386
{
dimitri's avatar
dimitri committed
387
  if (bcl==0) return;
mueller's avatar
mueller committed
388 389 390 391 392
  BaseClassListIterator bcli(*bcl);
  bool started=FALSE;
  for ( ; bcli.current() ; ++bcli)
  {
    ClassDef *cd=bcli.current()->classDef;
dimitri's avatar
dimitri committed
393 394 395 396 397
    if (cd->getLanguage()==SrcLangExt_VHDL && (VhdlDocGen::VhdlClasses)cd->protection()!=VhdlDocGen::ENTITYCLASS)
    {
      continue;
    }

dimitri's avatar
dimitri committed
398
    bool b;
dimitri's avatar
dimitri committed
399
    if (cd->getLanguage()==SrcLangExt_VHDL)
dimitri's avatar
dimitri committed
400 401 402 403 404 405 406 407 408
    {
      b=hasVisibleRoot(cd->subClasses());
    }
    else
    {
      b=hasVisibleRoot(cd->baseClasses());
    }

    if (cd->isVisibleInHierarchy() && b) // hasVisibleRoot(cd->baseClasses()))
mueller's avatar
mueller committed
409 410 411
    {
      if (!started)
      {
dimitri's avatar
dimitri committed
412
        startIndexHierarchy(ol,level);
dimitri's avatar
dimitri committed
413 414 415 416
        if (addToIndex)
        {
          Doxygen::indexList.incContentsDepth();
        }
dimitri's avatar
dimitri committed
417
        if (ftv)
dimitri's avatar
dimitri committed
418
        {
dimitri's avatar
dimitri committed
419
          ftv->incContentsDepth();
dimitri's avatar
dimitri committed
420
        }
mueller's avatar
mueller committed
421 422
        started=TRUE;
      }
dimitri's avatar
dimitri committed
423
      ol.startIndexListItem();
mueller's avatar
mueller committed
424
      //printf("Passed...\n");
dimitri's avatar
dimitri committed
425 426
      bool hasChildren = !cd->visited && !hideSuper && classHasVisibleChildren(cd);
      //printf("tree4: Has children %s: %d\n",cd->name().data(),hasChildren);
dimitri's avatar
dimitri committed
427
      if (cd->isLinkable())
mueller's avatar
mueller committed
428
      {
dimitri's avatar
dimitri committed
429
        //printf("Writing class %s\n",cd->displayName().data());
dimitri's avatar
dimitri committed
430 431 432
        ol.startIndexItem(cd->getReference(),cd->getOutputFileBase());
        ol.parseText(cd->displayName());
        ol.endIndexItem(cd->getReference(),cd->getOutputFileBase());
mueller's avatar
mueller committed
433 434 435 436 437 438
        if (cd->isReference()) 
        { 
          ol.startTypewriter(); 
          ol.docify(" [external]");
          ol.endTypewriter();
        }
dimitri's avatar
dimitri committed
439 440 441 442
        if (addToIndex)
        {
          Doxygen::indexList.addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor());
        }
dimitri's avatar
dimitri committed
443
        if (ftv)
dimitri's avatar
dimitri committed
444
        {
dimitri's avatar
dimitri committed
445 446 447 448 449 450 451 452
          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);
          }
dimitri's avatar
dimitri committed
453
        }
mueller's avatar
mueller committed
454 455 456
      }
      else
      {
dimitri's avatar
dimitri committed
457 458 459
        ol.startIndexItem(0,0);
        ol.parseText(cd->name());
        ol.endIndexItem(0,0);
dimitri's avatar
dimitri committed
460 461 462 463
        if (addToIndex)
        {
          Doxygen::indexList.addContentsItem(hasChildren,cd->displayName(),0,0,0);
        }
dimitri's avatar
dimitri committed
464
        if (ftv)
dimitri's avatar
dimitri committed
465
        {
dimitri's avatar
dimitri committed
466
          ftv->addContentsItem(hasChildren,cd->displayName(),0,0,0,FALSE,FALSE,cd);
dimitri's avatar
dimitri committed
467
        }
mueller's avatar
mueller committed
468
      }
dimitri's avatar
dimitri committed
469
      if (hasChildren)
mueller's avatar
mueller committed
470
      {
dimitri's avatar
dimitri committed
471 472
        //printf("Class %s at %p visited=%d\n",cd->name().data(),cd,cd->visited);
        bool wasVisited=cd->visited;
mueller's avatar
mueller committed
473
        cd->visited=TRUE;
dimitri's avatar
dimitri committed
474
        if (cd->getLanguage()==SrcLangExt_VHDL)	
dimitri's avatar
dimitri committed
475
        {
dimitri's avatar
dimitri committed
476
          writeClassTree(ol,cd->baseClasses(),wasVisited,level+1,ftv,addToIndex);
dimitri's avatar
dimitri committed
477 478 479
        }
        else       
        {
dimitri's avatar
dimitri committed
480
          writeClassTree(ol,cd->subClasses(),wasVisited,level+1,ftv,addToIndex);
dimitri's avatar
dimitri committed
481
        }
mueller's avatar
mueller committed
482
      }
dimitri's avatar
dimitri committed
483
      ol.endIndexListItem();
mueller's avatar
mueller committed
484 485
    }
  }
mueller's avatar
mueller committed
486 487
  if (started) 
  {
dimitri's avatar
dimitri committed
488
    endIndexHierarchy(ol,level);
dimitri's avatar
dimitri committed
489 490 491 492
    if (addToIndex)
    {
      Doxygen::indexList.decContentsDepth();
    }
dimitri's avatar
dimitri committed
493
    if (ftv)
dimitri's avatar
dimitri committed
494
    {
dimitri's avatar
dimitri committed
495
      ftv->decContentsDepth();
dimitri's avatar
dimitri committed
496 497 498 499
    }
  }
}

dimitri's avatar
dimitri committed
500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 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 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 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 665 666 667 668 669
//----------------------------------------------------------------------------
static void writeDirTreeNode(OutputList &ol, DirDef *dd, int level, FTVHelp* ftv,bool addToIndex)
{
  if (level>20)
  {
    warn(dd->getDefFileName(),dd->getDefLine(),
        "warning: maximum nesting level exceeded for directory %s: "
        "check for possible recursive directory relation!\n",dd->name().data()
        );
    return;
  }

  static bool tocExpand = TRUE; //Config_getBool("TOC_EXPAND");
  bool isDir = dd->subDirs().count()>0 || // there are subdirs
               (tocExpand &&              // or toc expand and
                dd->getFiles() && dd->getFiles()->count()>0 // there are files
               );
  //printf("gd=`%s': pageDict=%d\n",gd->name().data(),gd->pageDict->count());
  if (addToIndex)
  {
    Doxygen::indexList.addContentsItem(isDir,dd->shortName(),dd->getReference(),dd->getOutputFileBase(),0,TRUE,TRUE); 
    Doxygen::indexList.incContentsDepth();
  }
  if (ftv)
  {
    ftv->addContentsItem(isDir,dd->shortName(),dd->getReference(),
                         dd->getOutputFileBase(),0,FALSE,TRUE,dd); 
    ftv->incContentsDepth();
  }

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

  // write sub directories
  if (dd->subDirs().count()>0)
  {
    startIndexHierarchy(ol,level+1);
    QListIterator<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)
    {
      if (fd->isLinkable())
      {
        fileCount++;
      }
      fd=fileList->next();
    }
    if (fileCount>0)
    {
      startIndexHierarchy(ol,level+1);
      fd=fileList->first();
      while (fd)
      {
        if (fd->isLinkable())
        {
          ol.startIndexListItem();
          ol.startIndexItem(fd->getReference(),fd->getOutputFileBase());
          ol.parseText(fd->displayName());
          ol.endIndexItem(fd->getReference(),fd->getOutputFileBase());
          ol.endIndexListItem();
          if (ftv)
            ftv->addContentsItem(FALSE,fd->displayName(),
                fd->getReference(),fd->getOutputFileBase(),0,
                FALSE,FALSE,fd); 
        }
        fd=fileList->next();
      }
      endIndexHierarchy(ol,level+1); 
    }
  }

  if (tocExpand && addToIndex)
  {
    // write files of this directory
    if (fileCount>0)
    {
      FileDef *fd=fileList->first();
      while (fd)
      {
        if (fd->isLinkable())
        {
          //Doxygen::indexList.addContentsItem(FALSE, convertToHtml(fd->name(),TRUE),fd->getReference(), fd->getOutputFileBase(), 0);
          addMembersToIndex(fd,LayoutDocManager::File,fd->displayName(),QCString());
        }
        fd=fileList->next();
      }
    }
  }
  ol.endIndexListItem();

  if (addToIndex)
  {
    Doxygen::indexList.decContentsDepth();
  }
  if (ftv)
  {
    ftv->decContentsDepth();
  }
}

static void writeDirHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex)
{
  if (ftv)
  {
    ol.pushGeneratorState(); 
    ol.disable(OutputGenerator::Html);
  }
  startIndexHierarchy(ol,0);
  SDict<DirDef>::Iterator dli(*Doxygen::directories);
  DirDef *dd;
  for (dli.toFirst();(dd=dli.current());++dli)
  {
    if (dd->getOuterScope()==Doxygen::globalScope) 
    {
      writeDirTreeNode(ol,dd,0,ftv,addToIndex);
    }
  }
  if (ftv)
  {
    FileNameListIterator fnli(*Doxygen::inputNameList); 
    FileName *fn;
    for (fnli.toFirst();(fn=fnli.current());++fnli)
    {
      FileNameIterator fni(*fn);
      FileDef *fd;
      for (;(fd=fni.current());++fni)
      {
        DirDef *dd = fd->getDirDef();
        if (dd==0 && fd->isLinkableInProject() && !fd->isDocumentationFile())
        {
          ftv->addContentsItem(FALSE,fd->displayName(),
              fd->getReference(),fd->getOutputFileBase(),0,
              FALSE,FALSE,fd); 
          if (addToIndex)
          {
            addMembersToIndex(fd,LayoutDocManager::File,
                              fd->displayName(),QCString());
          }
        }
      }
    }
  }
  endIndexHierarchy(ol,0); 
  if (ftv)
  {
    ol.popGeneratorState(); 
  }
}


mueller's avatar
mueller committed
670 671
//----------------------------------------------------------------------------

dimitri's avatar
dimitri committed
672
static void writeClassTreeForList(OutputList &ol,ClassSDict *cl,bool &started,FTVHelp* ftv,bool addToIndex)
mueller's avatar
mueller committed
673
{
dimitri's avatar
dimitri committed
674
  ClassSDict::Iterator cli(*cl);
mueller's avatar
mueller committed
675 676 677
  for (;cli.current(); ++cli)
  {
    ClassDef *cd=cli.current();
dimitri's avatar
dimitri committed
678 679 680 681 682
    //printf("class %s hasVisibleRoot=%d isVisibleInHierarchy=%d\n",
    //             cd->name().data(),
    //              hasVisibleRoot(cd->baseClasses()),
    //              cd->isVisibleInHierarchy()
    //      );
dimitri's avatar
dimitri committed
683
    bool b;
dimitri's avatar
dimitri committed
684
    if (cd->getLanguage()==SrcLangExt_VHDL)
dimitri's avatar
dimitri committed
685
    {
dimitri's avatar
dimitri committed
686
      if (!(VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS)      
dimitri's avatar
dimitri committed
687 688 689 690 691 692 693 694 695 696 697
      {
        continue;
      }
      b=!hasVisibleRoot(cd->subClasses());
    }
    else
    {
      b=!hasVisibleRoot(cd->baseClasses());
    }

    if (b)  //filter on root classes
mueller's avatar
mueller committed
698
    {
dimitri's avatar
dimitri committed
699
      if (cd->isVisibleInHierarchy()) // should it be visible
mueller's avatar
mueller committed
700 701 702
      {
        if (!started)
        {
dimitri's avatar
dimitri committed
703
          startIndexHierarchy(ol,0);
dimitri's avatar
dimitri committed
704 705 706 707
          if (addToIndex)
          {
            Doxygen::indexList.incContentsDepth();
          }
mueller's avatar
mueller committed
708 709
          started=TRUE;
        }
dimitri's avatar
dimitri committed
710
        ol.startIndexListItem();
dimitri's avatar
dimitri committed
711 712
        bool hasChildren = !cd->visited && classHasVisibleChildren(cd); 
        //printf("list: Has children %s: %d\n",cd->name().data(),hasChildren);
dimitri's avatar
dimitri committed
713
        if (cd->isLinkable())
mueller's avatar
mueller committed
714
        {
dimitri's avatar
dimitri committed
715 716
          //printf("Writing class %s isLinkable()=%d isLinkableInProject()=%d cd->templateMaster()=%p\n",
          //    cd->displayName().data(),cd->isLinkable(),cd->isLinkableInProject(),cd->templateMaster());
dimitri's avatar
dimitri committed
717 718 719
          ol.startIndexItem(cd->getReference(),cd->getOutputFileBase());
          ol.parseText(cd->displayName());
          ol.endIndexItem(cd->getReference(),cd->getOutputFileBase());
mueller's avatar
mueller committed
720 721 722 723 724 725
          if (cd->isReference()) 
          {
            ol.startTypewriter(); 
            ol.docify(" [external]");
            ol.endTypewriter();
          }
dimitri's avatar
dimitri committed
726 727 728 729
          if (addToIndex)
          {
            Doxygen::indexList.addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE);
          }
dimitri's avatar
dimitri committed
730
          if (ftv)
dimitri's avatar
dimitri committed
731
          {
dimitri's avatar
dimitri committed
732 733 734 735
            if (cd->getLanguage()!=SrcLangExt_VHDL) // prevents double insertion in Design Unit List
            {
              ftv->addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE,cd); 
            }
dimitri's avatar
dimitri committed
736
          }
mueller's avatar
mueller committed
737 738 739
        }
        else
        {
dimitri's avatar
dimitri committed
740 741 742
          ol.startIndexItem(0,0);
          ol.parseText(cd->displayName());
          ol.endIndexItem(0,0);
dimitri's avatar
dimitri committed
743 744 745 746
          if (addToIndex)
          {
            Doxygen::indexList.addContentsItem(hasChildren,cd->displayName(),0,0,0,FALSE,FALSE);
          }
dimitri's avatar
dimitri committed
747
          if (ftv)
dimitri's avatar
dimitri committed
748
          {
dimitri's avatar
dimitri committed
749
            ftv->addContentsItem(hasChildren,cd->displayName(),0,0,0,FALSE,FALSE,cd); 
dimitri's avatar
dimitri committed
750
          }
mueller's avatar
mueller committed
751
        }
dimitri's avatar
dimitri committed
752
        if (cd->getLanguage()==SrcLangExt_VHDL && hasChildren) 
dimitri's avatar
dimitri committed
753
        {
dimitri's avatar
dimitri committed
754
          writeClassTree(ol,cd->baseClasses(),cd->visited,1,ftv,addToIndex);
dimitri's avatar
dimitri committed
755 756 757
          cd->visited=TRUE;
        }
        else if (hasChildren)
dimitri's avatar
dimitri committed
758
        {
dimitri's avatar
dimitri committed
759
          writeClassTree(ol,cd->subClasses(),cd->visited,1,ftv,addToIndex);
dimitri's avatar
dimitri committed
760 761
          cd->visited=TRUE;
        }
dimitri's avatar
dimitri committed
762
        ol.endIndexListItem();
mueller's avatar
mueller committed
763 764 765
      }
    }
  }
dimitri's avatar
dimitri committed
766 767
}

dimitri's avatar
dimitri committed
768
static void writeClassHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex)
dimitri's avatar
dimitri committed
769
{
dimitri's avatar
dimitri committed
770 771
  initClassHierarchy(Doxygen::classSDict);
  initClassHierarchy(Doxygen::hiddenClasses);
dimitri's avatar
dimitri committed
772 773 774 775 776
  if (ftv)
  {
    ol.pushGeneratorState(); 
    ol.disable(OutputGenerator::Html);
  }
dimitri's avatar
dimitri committed
777
  bool started=FALSE;
dimitri's avatar
dimitri committed
778 779
  writeClassTreeForList(ol,Doxygen::classSDict,started,ftv,addToIndex);
  writeClassTreeForList(ol,Doxygen::hiddenClasses,started,ftv,addToIndex);
mueller's avatar
mueller committed
780 781
  if (started) 
  {
dimitri's avatar
dimitri committed
782
    endIndexHierarchy(ol,0);
dimitri's avatar
dimitri committed
783 784 785 786
    if (addToIndex)
    {
      Doxygen::indexList.decContentsDepth();
    }
mueller's avatar
mueller committed
787
  }
dimitri's avatar
dimitri committed
788
  if (ftv)
dimitri's avatar
dimitri committed
789
  {
dimitri's avatar
dimitri committed
790
    ol.popGeneratorState(); 
dimitri's avatar
dimitri committed
791
  }
mueller's avatar
mueller committed
792 793 794 795
}

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

dimitri's avatar
dimitri committed
796 797 798 799 800 801 802 803 804 805 806
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
      {
dimitri's avatar
dimitri committed
807
        if (cd->subClasses()) // should have sub classes
dimitri's avatar
dimitri committed
808 809 810
        {
          count++;
        }
dimitri's avatar
dimitri committed
811 812 813 814 815 816
      }
    }
  }
  return count;
}

dimitri's avatar
dimitri committed
817
static int countClassHierarchy()
mueller's avatar
mueller committed
818
{
dimitri's avatar
dimitri committed
819
  int count=0;
dimitri's avatar
dimitri committed
820 821 822 823
  initClassHierarchy(Doxygen::classSDict);
  initClassHierarchy(Doxygen::hiddenClasses);
  count+=countClassesInTreeList(*Doxygen::classSDict);
  count+=countClassesInTreeList(*Doxygen::hiddenClasses);
dimitri's avatar
dimitri committed
824
  return count;
mueller's avatar
mueller committed
825 826 827 828
}

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

dimitri's avatar
dimitri committed
829
static void writeHierarchicalIndex(OutputList &ol)
mueller's avatar
mueller committed
830 831
{
  if (hierarchyClasses==0) return;
dimitri's avatar
dimitri committed
832
  ol.pushGeneratorState();
dimitri's avatar
dimitri committed
833
  //1.{
mueller's avatar
mueller committed
834
  ol.disable(OutputGenerator::Man);
dimitri's avatar
dimitri committed
835

dimitri's avatar
dimitri committed
836
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassHierarchy);
dimitri's avatar
dimitri committed
837
  QCString title = lne ? lne->title() : theTranslator->trClassHierarchy();
dimitri's avatar
dimitri committed
838 839
  bool addToIndex = lne==0 || lne->visible();

dimitri's avatar
dimitri committed
840
  startFile(ol,"hierarchy",0, title, HLI_Hierarchy);
mueller's avatar
mueller committed
841
  startTitle(ol,0);
dimitri's avatar
dimitri committed
842
  ol.parseText(title);
mueller's avatar
mueller committed
843
  endTitle(ol,0,0);
dimitri's avatar
dimitri committed
844
  ol.startContents();
dimitri's avatar
dimitri committed
845
  ol.startTextBlock();
dimitri's avatar
dimitri committed
846

dimitri's avatar
dimitri committed
847
  if (Config_getBool("HAVE_DOT") && Config_getBool("GRAPHICAL_HIERARCHY"))
dimitri's avatar
dimitri committed
848 849 850
  {
    ol.disable(OutputGenerator::Latex);
    ol.disable(OutputGenerator::RTF);
dimitri's avatar
dimitri committed
851
    ol.startParagraph();
dimitri's avatar
dimitri committed
852
    ol.startTextLink("inherits",0);
dimitri's avatar
dimitri committed
853
    ol.parseText(theTranslator->trGotoGraphicalHierarchy());
dimitri's avatar
dimitri committed
854
    ol.endTextLink();
dimitri's avatar
dimitri committed
855
    ol.endParagraph();
dimitri's avatar
dimitri committed
856 857 858
    ol.enable(OutputGenerator::Latex);
    ol.enable(OutputGenerator::RTF);
  }
dimitri's avatar
dimitri committed
859
  ol.parseText(lne ? lne->intro() : theTranslator->trClassHierarchyDescription());
dimitri's avatar
dimitri committed
860
  ol.endTextBlock();
dimitri's avatar
dimitri committed
861

dimitri's avatar
dimitri committed
862 863 864 865 866 867
  // ---------------
  // Static class hierarchy for Latex/RTF
  // ---------------
  ol.pushGeneratorState();
  //2.{
  ol.disable(OutputGenerator::Html);
dimitri's avatar
dimitri committed
868

dimitri's avatar
dimitri committed
869 870 871 872 873 874 875 876 877 878 879
  writeClassHierarchy(ol,0,addToIndex);

  ol.popGeneratorState();
  //2.}

  // ---------------
  // Dynamic class hierarchical index for HTML
  // ---------------
  ol.pushGeneratorState(); 
  //2.{
  ol.disableAllBut(OutputGenerator::Html);
dimitri's avatar
dimitri committed
880 881

  {
dimitri's avatar
dimitri committed
882 883 884 885 886 887
    if (addToIndex)
    {
      Doxygen::indexList.addContentsItem(TRUE,title,0,"hierarchy",0,TRUE,TRUE); 
    }
    FTVHelp* ftv = new FTVHelp(FALSE);
    writeClassHierarchy(ol,ftv,addToIndex);
dimitri's avatar
dimitri committed
888 889 890
    QGString outStr;
    FTextStream t(&outStr);
    ftv->generateTreeViewInline(t);
dimitri's avatar
dimitri committed
891 892
    ol.pushGeneratorState(); 
    ol.disableAllBut(OutputGenerator::Html);
dimitri's avatar
dimitri committed
893
    ol.writeString(outStr);
dimitri's avatar
dimitri committed
894 895 896
    ol.popGeneratorState();
    delete ftv;
  }
dimitri's avatar
dimitri committed
897 898 899 900
  ol.popGeneratorState();
  //2.}
  // ------

mueller's avatar
mueller committed
901
  endFile(ol);
dimitri's avatar
dimitri committed
902
  ol.popGeneratorState();
dimitri's avatar
dimitri committed
903
  //1.}
dimitri's avatar
dimitri committed
904 905 906 907
}

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

dimitri's avatar
dimitri committed
908
static void writeGraphicalClassHierarchy(OutputList &ol)
dimitri's avatar
dimitri committed
909 910 911
{
  if (hierarchyClasses==0) return;
  ol.disableAllBut(OutputGenerator::Html);
dimitri's avatar
dimitri committed
912
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassHierarchy);
dimitri's avatar
dimitri committed
913
  QCString title = lne ? lne->title() : theTranslator->trClassHierarchy();
dimitri's avatar
dimitri committed
914
  startFile(ol,"inherits",0,title,HLI_Hierarchy,FALSE,"hierarchy");
dimitri's avatar
dimitri committed
915
  startTitle(ol,0);
dimitri's avatar
dimitri committed
916
  ol.parseText(title);
dimitri's avatar
dimitri committed
917
  endTitle(ol,0,0);
dimitri's avatar
dimitri committed
918
  ol.startContents();
dimitri's avatar
dimitri committed
919
  ol.startTextBlock();
dimitri's avatar
dimitri committed
920
  ol.startParagraph();
dimitri's avatar
dimitri committed
921
  ol.startTextLink("hierarchy",0);
dimitri's avatar
dimitri committed
922
  ol.parseText(theTranslator->trGotoTextualHierarchy());
dimitri's avatar
dimitri committed
923
  ol.endTextLink();
dimitri's avatar
dimitri committed
924
  ol.endParagraph();
dimitri's avatar
dimitri committed
925 926 927 928 929
  ol.endTextBlock();
  DotGfxHierarchyTable g;
  ol.writeGraphicalHierarchy(g);
  endFile(ol);
  ol.enableAll();
mueller's avatar
mueller committed
930 931 932 933
}

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

dimitri's avatar
dimitri committed
934
static void countFiles(int &htmlFiles,int &files)
mueller's avatar
mueller committed
935
{
dimitri's avatar
dimitri committed
936 937
  htmlFiles=0;
  files=0;
dimitri's avatar
dimitri committed
938
  FileNameListIterator fnli(*Doxygen::inputNameList);
mueller's avatar
mueller committed
939 940 941 942 943 944 945
  FileName *fn;
  for (;(fn=fnli.current());++fnli)
  {
    FileNameIterator fni(*fn);
    FileDef *fd;
    for (;(fd=fni.current());++fni)
    {
dimitri's avatar
dimitri committed
946
      bool doc = fd->isLinkableInProject();
dimitri's avatar
dimitri committed
947
      bool src = fd->generateSourceFile();
dimitri's avatar
dimitri committed
948
      bool nameOk = !fd->isDocumentationFile();
dimitri's avatar
dimitri committed
949
      if (nameOk)
dimitri's avatar
dimitri committed
950
      {
dimitri's avatar
dimitri committed
951 952 953 954 955 956 957 958
        if (doc || src)
        {
          htmlFiles++;
        }
        if (doc)
        {
          files++;
        }
dimitri's avatar
dimitri committed
959
      }
mueller's avatar
mueller committed
960 961 962 963 964 965
    }
  }
}

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

dimitri's avatar
dimitri committed
966
static void writeFileIndex(OutputList &ol)
mueller's avatar
mueller committed
967
{
dimitri's avatar
dimitri committed
968
  if (documentedHtmlFiles==0) return;
dimitri's avatar
dimitri committed
969

dimitri's avatar
dimitri committed
970
  ol.pushGeneratorState();
mueller's avatar
mueller committed
971
  ol.disable(OutputGenerator::Man);
dimitri's avatar
dimitri committed
972
  if (documentedFiles==0) ol.disableAllBut(OutputGenerator::Html);
dimitri's avatar
dimitri committed
973 974 975
  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();
dimitri's avatar
dimitri committed
976 977
  bool addToIndex = lne==0 || lne->visible();

dimitri's avatar
dimitri committed
978
  startFile(ol,"files",0,title,HLI_Files);
mueller's avatar
mueller committed
979
  startTitle(ol,0);
dimitri's avatar
dimitri committed
980 981 982 983
  //if (!Config_getString("PROJECT_NAME").isEmpty()) 
  //{
  //  title.prepend(Config_getString("PROJECT_NAME")+" ");
  //}
dimitri's avatar
dimitri committed
984
  ol.parseText(title);
mueller's avatar
mueller committed
985
  endTitle(ol,0,0);
dimitri's avatar
dimitri committed
986
  ol.startContents();
dimitri's avatar
dimitri committed
987
  ol.startTextBlock();
dimitri's avatar
dimitri committed
988 989 990 991 992 993 994

  if (addToIndex)
  {
    Doxygen::indexList.addContentsItem(TRUE,title,0,"files",0,TRUE,TRUE); 
    Doxygen::indexList.incContentsDepth();
  }

dimitri's avatar
dimitri committed
995
  ol.parseText(lne ? lne->intro() : theTranslator->trFileListDescription(Config_getBool("EXTRACT_ALL")));
dimitri's avatar
dimitri committed
996
  ol.endTextBlock();
mueller's avatar
mueller committed
997

dimitri's avatar
dimitri committed
998 999 1000 1001 1002 1003 1004 1005
  // ---------------
  // Flat file index
  // ---------------

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

dimitri's avatar
dimitri committed
1006 1007 1008 1009
  OutputNameDict outputNameDict(1009);
  OutputNameList outputNameList;
  outputNameList.setAutoDelete(TRUE);
  
dimitri's avatar
dimitri committed
1010
  if (Config_getBool("FULL_PATH_NAMES"))
mueller's avatar
mueller committed
1011
  {
dimitri's avatar
dimitri committed
1012
    // re-sort input files in (dir,file) output order instead of (file,dir) input order 
dimitri's avatar
dimitri committed
1013
    FileName *fn=Doxygen::inputNameList->first();
dimitri's avatar
dimitri committed
1014
    while (fn)
mueller's avatar
mueller committed
1015
    {
dimitri's avatar
dimitri committed
1016 1017
      FileDef *fd=fn->first();
      while (fd)
dimitri's avatar
dimitri committed
1018
      {
dimitri's avatar
dimitri committed
1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035
        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();
dimitri's avatar
dimitri committed
1036
      }
dimitri's avatar
dimitri committed
1037
      fn=Doxygen::inputNameList->next();
dimitri's avatar
dimitri committed
1038 1039 1040 1041
    }
  }
  
  ol.startIndexList();
dimitri's avatar
dimitri committed
1042
  FileList *fl=0;
dimitri's avatar
dimitri committed
1043
  if (Config_getBool("FULL_PATH_NAMES"))
dimitri's avatar
dimitri committed
1044 1045 1046 1047 1048
  {
    fl = outputNameList.first();
  }
  else
  {
dimitri's avatar
dimitri committed
1049
    fl = Doxygen::inputNameList->first();
dimitri's avatar
dimitri committed
1050
  }
dimitri's avatar
dimitri committed
1051 1052 1053 1054 1055 1056
  while (fl)
  {
    FileDef *fd=fl->first();
    while (fd)
    {
      //printf("Found filedef %s\n",fd->name().data());
dimitri's avatar
dimitri committed
1057
      bool doc = fd->isLinkableInProject();
dimitri's avatar
dimitri committed
1058
      bool src = fd->generateSourceFile();
dimitri's avatar
dimitri committed
1059
      bool nameOk = !fd->isDocumentationFile();
dimitri's avatar
dimitri committed
1060 1061
      if (nameOk && (doc || src) && 
              !fd->isReference())
mueller's avatar
mueller committed
1062
      {
mueller's avatar
mueller committed
1063
        QCString path;
dimitri's avatar
dimitri committed
1064
        if (Config_getBool("FULL_PATH_NAMES")) 
mueller's avatar
mueller committed
1065
        {
mueller's avatar
mueller committed
1066
          path=stripFromPath(fd->getPath().copy());
mueller's avatar
mueller committed
1067
        }
dimitri's avatar
dimitri committed
1068
        QCString fullName=fd->name();
dimitri's avatar
dimitri committed
1069 1070 1071 1072 1073
        if (!path.isEmpty()) 
        {
          if (path.at(path.length()-1)!='/') fullName.prepend("/");
          fullName.prepend(path);
        }
mueller's avatar
mueller committed
1074

dimitri's avatar
dimitri committed
1075
        ol.startIndexKey();
dimitri's avatar
dimitri committed
1076 1077 1078 1079
        ol.docify(path);
        if (doc)
        {
          ol.writeObjectLink(0,fd->getOutputFileBase(),0,fd->name());
dimitri's avatar
dimitri committed
1080 1081 1082 1083
          //if (addToIndex)
          //{
          //  addMembersToIndex(fd,LayoutDocManager::File,fullName,QCString());
          //}
mueller's avatar
mueller committed
1084 1085 1086
        }
        else
        {
dimitri's avatar
dimitri committed
1087 1088 1089
          ol.startBold();
          ol.docify(fd->name());
          ol.endBold();
dimitri's avatar
dimitri committed
1090 1091 1092 1093
          //if (addToIndex)
          //{
          //  Doxygen::indexList.addContentsItem(FALSE,fullName,0,0,0);
          //}
mueller's avatar
mueller committed
1094
        }
dimitri's avatar
dimitri committed
1095 1096
        if (src)
        {
dimitri's avatar
dimitri committed
1097 1098
          ol.pushGeneratorState();
          ol.disableAllBut(OutputGenerator::Html);
dimitri's avatar
dimitri committed
1099 1100 1101
          ol.docify(" ");
          ol.startTextLink(fd->includeName(),0);
          ol.docify("[");
dimitri's avatar
dimitri committed
1102
          ol.parseText(theTranslator->trCode());
dimitri's avatar
dimitri committed
1103 1104
          ol.docify("]");
          ol.endTextLink();
dimitri's avatar
dimitri committed
1105
          ol.popGeneratorState();
dimitri's avatar
dimitri committed
1106
        }
dimitri's avatar
dimitri committed
1107
        ol.endIndexKey();
dimitri's avatar
dimitri committed
1108 1109 1110
        bool hasBrief = !fd->briefDescription().isEmpty();
        ol.startIndexValue(hasBrief);
        if (hasBrief)
dimitri's avatar
dimitri committed
1111
        {
dimitri's avatar
dimitri committed
1112
          //ol.docify(" (");
dimitri's avatar
dimitri committed
1113
          ol.parseDoc(
dimitri's avatar
dimitri committed
1114
              fd->briefFile(),fd->briefLine(),
dimitri's avatar
dimitri committed
1115
              fd,0,
dimitri's avatar
dimitri committed
1116
              fd->briefDescription(TRUE),
dimitri's avatar
dimitri committed
1117
              FALSE, // index words
dimitri's avatar
dimitri committed
1118 1119
              FALSE, // isExample
              0,     // example name
dimitri's avatar
dimitri committed
1120 1121
              TRUE,  // single line
              TRUE   // link from index
dimitri's avatar
dimitri committed
1122
             );
dimitri's avatar
dimitri committed
1123
          //ol.docify(")");
dimitri's avatar
dimitri committed
1124
        }
dimitri's avatar
dimitri committed
1125
        ol.endIndexValue(fd->getOutputFileBase(),hasBrief);
dimitri's avatar
dimitri committed
1126
        //ol.popGeneratorState();
dimitri's avatar
dimitri committed
1127
        // --------------------------------------------------------
mueller's avatar
mueller committed
1128
      }
dimitri's avatar
dimitri committed
1129
      fd=fl->next();
mueller's avatar
mueller committed
1130
    }
dimitri's avatar
dimitri committed
1131
    if (Config_getBool("FULL_PATH_NAMES"))
dimitri's avatar
dimitri committed
1132 1133 1134 1135 1136
    {
      fl=outputNameList.next();
    }
    else
    {
dimitri's avatar
dimitri committed
1137
      fl=Doxygen::inputNameList->next();
dimitri's avatar
dimitri committed
1138
    }
mueller's avatar
mueller committed
1139 1140
  }
  ol.endIndexList();
dimitri's avatar
dimitri committed
1141

dimitri's avatar
dimitri committed
1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161
  // 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();
  // ------

dimitri's avatar
dimitri committed
1162 1163 1164 1165 1166
  if (addToIndex)
  {
    Doxygen::indexList.decContentsDepth();
  }

mueller's avatar
mueller committed
1167
  endFile(ol);
dimitri's avatar
dimitri committed
1168
  ol.popGeneratorState();
mueller's avatar
mueller committed
1169 1170
}

mueller's avatar
mueller committed
1171
//----------------------------------------------------------------------------
dimitri's avatar
dimitri committed
1172
static int countNamespaces()
mueller's avatar
mueller committed
1173 1174
{
  int count=0;
dimitri's avatar
dimitri committed
1175
  NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
mueller's avatar
mueller committed
1176 1177 1178
  NamespaceDef *nd;
  for (;(nd=nli.current());++nli)
  {
dimitri's avatar
dimitri committed
1179
    if (nd->isLinkableInProject()) count++;
mueller's avatar
mueller committed
1180 1181 1182 1183 1184 1185
  }
  return count;
}

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

dimitri's avatar
dimitri committed
1186 1187 1188 1189 1190 1191 1192 1193
void writeClassTree(ClassSDict *clDict,FTVHelp *ftv,bool addToIndex,bool globalOnly)
{
  if (clDict)
  {
    ClassSDict::Iterator cli(*clDict);
    ClassDef *cd;
    for (;(cd=cli.current());++cli)
    {
dimitri's avatar
dimitri committed
1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208
      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());
        }         
      }

dimitri's avatar
dimitri committed
1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290
      if (!globalOnly || 
          cd->getOuterScope()==0 || 
          cd->getOuterScope()==Doxygen::globalScope 
         )
      {
        int count=0;
        if (cd->getClassSDict())
        {
          ClassSDict::Iterator ccit(*cd->getClassSDict());
          ClassDef *ccd;
          for (;(ccd=ccit.current());++ccit)
          {
            if (ccd->isLinkableInProject() && ccd->templateMaster()==0) 
            {
              count++;
            }
          }
        }
        if (cd->isLinkableInProject() && cd->templateMaster()==0) 
        { 
          ftv->addContentsItem(count>0,cd->className(),cd->getReference(),
              cd->getOutputFileBase(),0,FALSE,TRUE,cd); 
          if (addToIndex && 
              (cd->getOuterScope()==0 || cd->getOuterScope()->definitionType()!=Definition::TypeClass))
          {
            addMembersToIndex(cd,LayoutDocManager::Class,cd->className(),cd->anchor());
          }
          if (count>0)
          {
            ftv->incContentsDepth();
            writeClassTree(cd->getClassSDict(),ftv,addToIndex,FALSE);
            ftv->decContentsDepth();
          }
        }
      }
    }
  }
}

static void writeNamespaceTree(NamespaceSDict *nsDict,FTVHelp *ftv,
                               bool rootOnly,bool showClasses,bool addToIndex)
{
  if (nsDict)
  {
    NamespaceSDict::Iterator nli(*nsDict);
    NamespaceDef *nd;
    for (nli.toFirst();(nd=nli.current());++nli)
    {
      if (!rootOnly || (nd->isLinkableInProject() && 
                        nd->getOuterScope()==Doxygen::globalScope))
      {
        int count=0;
        if (nd->getNamespaceSDict())
        {
          NamespaceSDict::Iterator cnli(*nd->getNamespaceSDict());
          NamespaceDef *cnd;
          for (cnli.toFirst();(cnd=cnli.current());++cnli)
          {
            if (cnd->isLinkable())
            {
              count++;
            }
          }
        }
        int classCount=0;
        if (nd->getClassSDict())
        {
          ClassSDict::Iterator cli(*nd->getClassSDict());
          ClassDef *cd;
          for (;(cd=cli.current());++cli)
          {
            if (cd->isLinkableInProject() && cd->templateMaster()==0) 
            { 
              classCount++;
            }
          }
        }
        if (showClasses)
        {
          count+=classCount;
        }

dimitri's avatar
dimitri committed
1291 1292 1293 1294 1295 1296 1297 1298 1299 1300
        if (nd->getLanguage()==SrcLangExt_VHDL)
        {
          QCString q=nd->getOutputFileBase().replace(0,strlen("namespace"),"class");
          ftv->addContentsItem(count>0,nd->localName(),nd->getReference(),q,0,FALSE,TRUE,nd);
        }
        else
        {
          ftv->addContentsItem(count>0,nd->localName(),nd->getReference(),
              nd->getOutputFileBase(),0,FALSE,TRUE,nd); 
        }
dimitri's avatar
dimitri committed
1301 1302 1303 1304 1305

        if (addToIndex)
        {
          if (nd->getLanguage()==SrcLangExt_VHDL) // UGLY HACK
          {
dimitri's avatar
dimitri committed
1306 1307
            QCString q=nd->getOutputFileBase().replace(0,strlen("namespace"),"class");
            Doxygen::indexList.addContentsItem(count>0,nd->localName(),nd->getReference(),q,QCString(),count>0,showClasses);
dimitri's avatar
dimitri committed
1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332
          }
          else
          {
            Doxygen::indexList.addContentsItem(count>0,nd->localName(),nd->getReference(),nd->getOutputFileBase(),QCString(),count>0,showClasses);
          }
        }

        if (count>0)
        {
          if (addToIndex) Doxygen::indexList.incContentsDepth();
          ftv->incContentsDepth();
          writeNamespaceTree(nd->getNamespaceSDict(),ftv,FALSE,showClasses,addToIndex);
          if (showClasses) 
          {
            writeClassTree(nd->getClassSDict(),ftv,addToIndex,FALSE);
          }
          ftv->decContentsDepth();
          if (addToIndex) Doxygen::indexList.decContentsDepth();
        }
      }
    }
  }
}


dimitri's avatar
dimitri committed
1333
static void writeNamespaceIndex(OutputList &ol)
mueller's avatar
mueller committed
1334 1335
{
  if (documentedNamespaces==0) return;
dimitri's avatar
dimitri committed
1336
  ol.pushGeneratorState();
mueller's avatar
mueller committed
1337
  ol.disable(OutputGenerator::Man);
dimitri's avatar
dimitri committed
1338 1339 1340
  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();
dimitri's avatar
dimitri committed
1341
  bool addToIndex = lne==0 || lne->visible();
dimitri's avatar
dimitri committed
1342
  startFile(ol,"namespaces",0,title,HLI_Namespaces);
mueller's avatar
mueller committed
1343
  startTitle(ol,0);
dimitri's avatar
dimitri committed
1344
  ol.parseText(title);
mueller's avatar
mueller committed
1345
  endTitle(ol,0,0);
dimitri's avatar
dimitri committed
1346
  ol.startContents();
dimitri's avatar
dimitri committed
1347
  ol.startTextBlock();
dimitri's avatar
dimitri committed
1348
  ol.parseText(lne ? lne->intro() : theTranslator->trNamespaceListDescription(Config_getBool("EXTRACT_ALL")));
dimitri's avatar
dimitri committed
1349
  ol.endTextBlock();
mueller's avatar
mueller committed
1350

dimitri's avatar
dimitri committed
1351
  bool first=TRUE;
dimitri's avatar
dimitri committed
1352

dimitri's avatar
dimitri committed
1353 1354 1355 1356 1357 1358
  // ---------------
  // Linear namespace index for Latex/RTF
  // ---------------
  ol.pushGeneratorState();
  ol.disable(OutputGenerator::Html);
  
dimitri's avatar
dimitri committed
1359
  NamespaceSDict::Iterator nli(*Doxygen::namespaceSDict);
dimitri's avatar
dimitri committed
1360 1361
  NamespaceDef *nd;
  for (nli.toFirst();(nd=nli.current());++nli)
mueller's avatar
mueller committed
1362
  {
dimitri's avatar
dimitri committed
1363
    if (nd->isLinkableInProject())
mueller's avatar
mueller committed
1364
    {
dimitri's avatar
dimitri committed
1365 1366 1367 1368 1369
      if (first)
      {
        ol.startIndexList();
        first=FALSE;
      }
dimitri's avatar
dimitri committed
1370 1371
      //ol.writeStartAnnoItem("namespace",nd->getOutputFileBase(),0,nd->name());
      ol.startIndexKey();
dimitri's avatar
dimitri committed
1372 1373
      if (nd->getLanguage()==SrcLangExt_VHDL)
      {
dimitri's avatar
dimitri committed
1374
        ol.writeObjectLink(0, nd->getOutputFileBase().replace(0,strlen("namespace"),"class"),0,nd->displayName());
dimitri's avatar
dimitri committed
1375 1376 1377 1378 1379
      }
      else
      {
        ol.writeObjectLink(0,nd->getOutputFileBase(),0,nd->displayName());
      }
dimitri's avatar
dimitri committed
1380
      ol.endIndexKey();
dimitri's avatar
dimitri committed
1381

dimitri's avatar
dimitri committed
1382 1383 1384
      bool hasBrief = !nd->briefDescription().isEmpty();
      ol.startIndexValue(hasBrief);
      if (hasBrief)
mueller's avatar
mueller committed
1385
      {
dimitri's avatar
dimitri committed
1386
        //ol.docify(" (");
dimitri's avatar
dimitri committed
1387
        ol.parseDoc(
dimitri's avatar
dimitri committed
1388
                 nd->briefFile(),nd->briefLine(),
dimitri's avatar
dimitri committed
1389
                 nd,0,
dimitri's avatar
dimitri committed
1390
                 nd->briefDescription(TRUE),
dimitri's avatar
dimitri committed
1391
                 FALSE, // index words
dimitri's avatar
dimitri committed
1392 1393 1394 1395
                 FALSE, // isExample
                 0,     // example name
                 TRUE,  // single line
                 TRUE   // link from index
dimitri's avatar
dimitri committed
1396
                );
dimitri's avatar
dimitri committed
1397
        //ol.docify(")");
mueller's avatar
mueller committed
1398
      }
dimitri's avatar
dimitri committed
1399
      ol.endIndexValue(nd->getOutputFileBase(),hasBrief);
dimitri's avatar
dimitri committed
1400

mueller's avatar
mueller committed
1401 1402
    }
  }
dimitri's avatar
dimitri committed
1403
  if (!first) ol.endIndexList();
dimitri's avatar
dimitri committed
1404 1405 1406 1407 1408 1409 1410 1411 1412

  ol.popGeneratorState();

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

dimitri's avatar
dimitri committed
1413
  {
dimitri's avatar
dimitri committed
1414 1415 1416 1417 1418 1419
    if (addToIndex)
    {
      Doxygen::indexList.addContentsItem(TRUE,title,0,"namespaces",0,TRUE,TRUE); 
      Doxygen::indexList.incContentsDepth();
    }
    FTVHelp* ftv = new FTVHelp(FALSE);
dimitri's avatar
dimitri committed
1420 1421 1422 1423 1424
    static bool optimizeOutputVhdl = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
    if (!optimizeOutputVhdl) // prevents double insertions (Packages/Design Unit List)
    {
      writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,FALSE,addToIndex);
    }
dimitri's avatar
dimitri committed
1425 1426 1427 1428 1429 1430 1431 1432 1433
    QGString outStr;
    FTextStream t(&outStr);
    ftv->generateTreeViewInline(t);
    ol.writeString(outStr);
    delete ftv;
    if (addToIndex)
    {
      Doxygen::indexList.decContentsDepth();
    }
dimitri's avatar
dimitri committed
1434
  }
dimitri's avatar
dimitri committed
1435 1436 1437 1438

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

mueller's avatar
mueller committed
1439
  endFile(ol);
dimitri's avatar
dimitri committed
1440
  ol.popGeneratorState();
mueller's avatar
mueller committed
1441 1442 1443 1444
}

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

dimitri's avatar
dimitri committed
1445
static int countAnnotatedClasses(int *cp)
mueller's avatar
mueller committed
1446 1447
{
  int count=0;
dimitri's avatar
dimitri committed
1448
  int countPrinted=0;
dimitri's avatar
dimitri committed
1449
  ClassSDict::Iterator cli(*Doxygen::classSDict);
mueller's avatar
mueller committed
1450 1451 1452
  ClassDef *cd;
  for (;(cd=cli.current());++cli)
  {
dimitri's avatar
dimitri committed
1453
    if (cd->isLinkableInProject() && cd->templateMaster()==0) 
mueller's avatar
mueller committed
1454
    { 
dimitri's avatar
dimitri committed
1455
      if (!cd->isEmbeddedInOuterScope())
dimitri's avatar
dimitri committed
1456 1457 1458
      {
        countPrinted++;
      }
mueller's avatar
mueller committed
1459 1460 1461
      count++; 
    }
  }
dimitri's avatar
dimitri committed
1462
  *cp = countPrinted;
mueller's avatar
mueller committed
1463 1464 1465
  return count;
}

dimitri's avatar
dimitri committed
1466

dimitri's avatar
dimitri committed
1467
static void writeAnnotatedClassList(OutputList &ol)
mueller's avatar
mueller committed
1468
{
dimitri's avatar
dimitri committed
1469 1470
  //LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassList);
  //bool addToIndex = lne==0 || lne->visible();
dimitri's avatar
dimitri committed
1471

mueller's avatar
mueller committed
1472
  ol.startIndexList(); 
dimitri's avatar
dimitri committed
1473
  ClassSDict::Iterator cli(*Doxygen::classSDict);
mueller's avatar
mueller committed
1474
  ClassDef *cd;
dimitri's avatar
dimitri committed
1475 1476 1477
  
  for (cli.toFirst();(cd=cli.current());++cli)
  {
dimitri's avatar
dimitri committed
1478 1479 1480 1481 1482
    if (cd->getLanguage()==SrcLangExt_VHDL && 
        ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKAGECLASS || 
         (VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::PACKBODYCLASS)
       ) // no architecture
    {
dimitri's avatar
dimitri committed
1483
      continue;
dimitri's avatar
dimitri committed
1484
    }
dimitri's avatar
dimitri committed
1485
 
dimitri's avatar
dimitri committed
1486
    ol.pushGeneratorState();
dimitri's avatar
dimitri committed
1487
    if (cd->isEmbeddedInOuterScope())
dimitri's avatar
dimitri committed
1488 1489 1490 1491
    {
      ol.disable(OutputGenerator::Latex);
      ol.disable(OutputGenerator::RTF);
    }
dimitri's avatar
dimitri committed
1492
    if (cd->isLinkableInProject() && cd->templateMaster()==0)
mueller's avatar
mueller committed
1493
    {
dimitri's avatar
dimitri committed
1494
      QCString type=cd->compoundTypeString();
dimitri's avatar
dimitri committed
1495
      ol.startIndexKey();
dimitri's avatar
dimitri committed
1496
      if (cd->getLanguage()==SrcLangExt_VHDL)
dimitri's avatar
dimitri committed
1497 1498 1499
      {
        QCString prot= VhdlDocGen::getProtectionName((VhdlDocGen::VhdlClasses)cd->protection());
        ol.docify(prot.data());
dimitri's avatar
dimitri committed
1500
        ol.writeString(" ");
dimitri's avatar
dimitri committed
1501
      }
dimitri's avatar
dimitri committed
1502
      ol.writeObjectLink(0,cd->getOutputFileBase(),cd->anchor(),cd->displayName());
dimitri's avatar
dimitri committed
1503
      ol.endIndexKey();
dimitri's avatar
dimitri committed
1504 1505 1506
      bool hasBrief = !cd->briefDescription().isEmpty();
      ol.startIndexValue(hasBrief);
      if (hasBrief)
mueller's avatar
mueller committed
1507
      {
dimitri's avatar
dimitri committed
1508
        ol.parseDoc(
dimitri's avatar
dimitri committed
1509
                 cd->briefFile(),cd->briefLine(),
dimitri's avatar
dimitri committed
1510
                 cd,0,
dimitri's avatar
dimitri committed
1511
                 cd->briefDescription(TRUE),
dimitri's avatar
dimitri committed
1512
                 FALSE,  // indexWords
dimitri's avatar
dimitri committed
1513 1514 1515 1516
                 FALSE,  // isExample
                 0,     // example name
                 TRUE,  // single line
                 TRUE   // link from index
dimitri's avatar
dimitri committed
1517
                );
mueller's avatar
mueller committed
1518
      }
dimitri's avatar
dimitri committed
1519
      ol.endIndexValue(cd->getOutputFileBase(),hasBrief);
dimitri's avatar
dimitri committed
1520

dimitri's avatar
dimitri committed
1521 1522 1523 1524
      //if (addToIndex)
      //{
      //  addMembersToIndex(cd,LayoutDocManager::Class,cd->displayName(),cd->anchor());
      //}
mueller's avatar
mueller committed
1525
    }
dimitri's avatar
dimitri committed
1526
    ol.popGeneratorState();
dimitri's avatar
dimitri committed
1527 1528 1529 1530
  }
  ol.endIndexList();
}

dimitri's avatar
dimitri committed
1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549
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;
}

dimitri's avatar
dimitri committed
1550 1551
//----------------------------------------------------------------------------

dimitri's avatar
dimitri committed
1552 1553 1554 1555 1556 1557 1558 1559 1560 1561
class PrefixIgnoreClassList : public ClassList
{
public:
  virtual int compareItems(GCI item1, GCI item2)
  {
    ClassDef *c1=(ClassDef *)item1;
    ClassDef *c2=(ClassDef *)item2;

    QCString n1 = c1->className();
    QCString n2 = c2->className();
dimitri's avatar
dimitri committed
1562
    return stricmp (n1.data()+getPrefixIndex(n1), n2.data()+getPrefixIndex(n2));
dimitri's avatar
dimitri committed
1563 1564 1565
  }
};

dimitri's avatar
dimitri committed
1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605
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;
};

class AlphaIndexTableRows : public QList<AlphaIndexTableCell>
{
  public:
    AlphaIndexTableRows() { setAutoDelete(TRUE); }
};

class AlphaIndexTableRowsIterator : public QListIterator<AlphaIndexTableCell>
{
  public:
    AlphaIndexTableRowsIterator(const AlphaIndexTableRows &list) : 
      QListIterator<AlphaIndexTableCell>(list) {}
};

class AlphaIndexTableColumns : public QList<AlphaIndexTableRows>
{
  public:
    AlphaIndexTableColumns() { setAutoDelete(TRUE); }
};

mueller's avatar
mueller committed
1606
// write an alphabetical index of all class with a header for each letter
dimitri's avatar
dimitri committed
1607
static void writeAlphabeticalClassList(OutputList &ol)
mueller's avatar
mueller committed
1608
{
dimitri's avatar
dimitri committed
1609 1610 1611
  // What starting letters are used
  bool indexLetterUsed[256];
  memset (indexLetterUsed, 0, sizeof (indexLetterUsed));
mueller's avatar
mueller committed
1612 1613

  // first count the number of headers
dimitri's avatar
dimitri committed
1614
  ClassSDict::Iterator cli(*Doxygen::classSDict);
mueller's avatar
mueller committed
1615
  ClassDef *cd;
dimitri's avatar
dimitri committed
1616
  uint startLetter=0;
mueller's avatar
mueller committed
1617
  int headerItems=0;
mueller's avatar
mueller committed
1618
  for (;(cd=cli.current());++cli)
mueller's avatar
mueller committed
1619
  {
dimitri's avatar
dimitri committed
1620
    if (cd->isLinkableInProject() && cd->templateMaster()==0)
mueller's avatar
mueller committed
1621
    {
dimitri's avatar
dimitri committed
1622 1623 1624
      if (cd->getLanguage()==SrcLangExt_VHDL && !((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS ))// no architecture
        continue;
	     
dimitri's avatar
dimitri committed
1625
      int index = getPrefixIndex(cd->className());
dimitri's avatar
dimitri committed
1626
      //printf("name=%s index=%d %d\n",cd->className().data(),index,cd->protection());
dimitri's avatar
dimitri committed
1627
      startLetter=toupper(cd->className().at(index))&0xFF;
dimitri's avatar
dimitri committed
1628 1629 1630 1631
      indexLetterUsed[startLetter] = true;
    }
  }

dimitri's avatar
dimitri committed
1632
  // write quick link index (row of letters)
dimitri's avatar
dimitri committed
1633
  QCString alphaLinks = "<div class=\"qindex\">";
dimitri's avatar
dimitri committed
1634
  int l;
dimitri's avatar
dimitri committed
1635
  for (l=0; l<256; l++)
dimitri's avatar
dimitri committed
1636 1637 1638
  {
    if (indexLetterUsed[l])
    {
dimitri's avatar
dimitri committed
1639
      if (headerItems) alphaLinks += "&#160;|&#160;";
dimitri's avatar
dimitri committed
1640 1641 1642 1643
      headerItems++;
      alphaLinks += (QCString)"<a class=\"qindex\" href=\"#letter_" + 
                    (char)l + "\">" + 
                    (char)l + "</a>";
mueller's avatar
mueller committed
1644 1645
    }
  }
dimitri's avatar
dimitri committed
1646
  alphaLinks += "</div>\n";
dimitri's avatar
dimitri committed
1647 1648
  ol.writeString(alphaLinks);

mueller's avatar
mueller committed
1649 1650

  // the number of columns in the table
dimitri's avatar
dimitri committed
1651
  const int columns = Config_getInt("COLS_IN_ALPHA_INDEX");
mueller's avatar
mueller committed
1652 1653

  int i,j;
dimitri's avatar
dimitri committed
1654
  int totalItems = headerItems*2 + annotatedClasses;      // number of items in the table (headers span 2 items)
dimitri's avatar
dimitri committed
1655
  int rows = (totalItems + columns - 1)/columns;          // number of rows in the table
mueller's avatar
mueller committed
1656 1657 1658 1659

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

dimitri's avatar
dimitri committed
1660 1661
  // Keep a list of classes for each starting letter
  PrefixIgnoreClassList classesByLetter[256];
dimitri's avatar
dimitri committed
1662
  AlphaIndexTableColumns tableColumns;
mueller's avatar
mueller committed
1663 1664

  // fill the columns with the class list (row elements in each column,
dimitri's avatar
dimitri committed
1665
  // expect for the columns with number >= itemsInLastRow, which get one
mueller's avatar
mueller committed
1666 1667 1668 1669
  // item less.
  //int icount=0;
  startLetter=0;
  for (cli.toFirst();(cd=cli.current());++cli)
mueller's avatar
mueller committed
1670
  {
dimitri's avatar
dimitri committed
1671 1672 1673
    if (cd->getLanguage()==SrcLangExt_VHDL && !((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS ))// no architecture
      continue;
    
dimitri's avatar
dimitri committed
1674
    if (cd->isLinkableInProject() && cd->templateMaster()==0)
mueller's avatar
mueller committed
1675
    {
dimitri's avatar
dimitri committed
1676
      int index = getPrefixIndex(cd->className());
dimitri's avatar
dimitri committed
1677
      startLetter=toupper(cd->className().at(index))&0xFF;
dimitri's avatar
dimitri committed
1678 1679
      // Do some sorting again, since the classes are sorted by name with 
      // prefix, which should be ignored really.
dimitri's avatar
dimitri committed
1680 1681 1682 1683 1684 1685
      if (cd->getLanguage()==SrcLangExt_VHDL)
      {
        if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS )// no architecture
          classesByLetter[startLetter].inSort(cd);
      }
      else
dimitri's avatar
dimitri committed
1686
      classesByLetter[startLetter].inSort(cd);
dimitri's avatar
dimitri committed
1687 1688 1689
    }
  }

dimitri's avatar
dimitri committed
1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714
  #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));
mueller's avatar
mueller committed
1715
      row++;
dimitri's avatar
dimitri committed
1716 1717 1718 1719 1720 1721 1722 1723 1724 1725
      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();
      }
mueller's avatar
mueller committed
1726 1727
    }
  }
mueller's avatar
mueller committed
1728

dimitri's avatar
dimitri committed
1729 1730
  // create row iterators for each column
  AlphaIndexTableRowsIterator **colIterators = new AlphaIndexTableRowsIterator*[columns];
mueller's avatar
mueller committed
1731 1732
  for (i=0;i<columns;i++)
  {
dimitri's avatar
dimitri committed
1733 1734 1735 1736 1737 1738 1739 1740
    if (i<(int)tableColumns.count())
    {
      colIterators[i] = new AlphaIndexTableRowsIterator(*tableColumns.at(i));
    }
    else // empty column
    {
      colIterators[i] = 0;
    }
mueller's avatar
mueller committed
1741 1742
  }

dimitri's avatar
dimitri committed
1743
  ol.writeString("<table style=\"margin: 10px; white-space: nowrap;\" align=\"center\" width=\"95%\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n");
mueller's avatar
mueller committed
1744
  // generate table
dimitri's avatar
dimitri committed
1745
  for (i=0;i<=maxRows;i++) // foreach table row
mueller's avatar
mueller committed
1746
  {
dimitri's avatar
dimitri committed
1747
    //printf("writing row %d\n",i);
dimitri's avatar
dimitri committed
1748 1749
    //ol.nextTableRow();
    ol.writeString("<tr>");
mueller's avatar
mueller committed
1750
    // the last column may contain less items then the others
dimitri's avatar
dimitri committed
1751
    //int colsInRow = (i<rows-1) ? columns : itemsInLastRow; 
mueller's avatar
mueller committed
1752
    //printf("row [%d]\n",i);
dimitri's avatar
dimitri committed
1753
    for (j=0;j<columns;j++) // foreach table column
mueller's avatar
mueller committed
1754
    {
dimitri's avatar
dimitri committed
1755
      if (colIterators[j])
mueller's avatar
mueller committed
1756
      {
dimitri's avatar
dimitri committed
1757 1758
        AlphaIndexTableCell *cell = colIterators[j]->current();
        if (cell)
mueller's avatar
mueller committed
1759
        {
dimitri's avatar
dimitri committed
1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786
          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's avatar
dimitri committed
1787 1788 1789
              SrcLangExt lang = cd->getLanguage();
              QCString sep = getLanguageSpecificSeparator(lang);
              if (sep!="::")
dimitri's avatar
dimitri committed
1790
              {
dimitri's avatar
dimitri committed
1791
                nsDispName=substitute(namesp,"::",sep);
dimitri's avatar
dimitri committed
1792 1793 1794
              }
              else
              {
dimitri's avatar
dimitri committed
1795
                nsDispName=namesp;
dimitri's avatar
dimitri committed
1796 1797 1798 1799 1800
              }
              if (cname.right(2)=="-g" || cname.right(2)=="-p")
              {
                cname = cname.left(cname.length()-2);
              }
dimitri's avatar
dimitri committed
1801

dimitri's avatar
dimitri committed
1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826
              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's avatar
dimitri committed
1827 1828 1829
        }
        else
        {
dimitri's avatar
dimitri committed
1830
          ol.writeString("<td></td>");
dimitri's avatar
dimitri committed
1831
        }
mueller's avatar
mueller committed
1832 1833
      }
    }
dimitri's avatar
dimitri committed
1834
    ol.writeString("</tr>\n");
mueller's avatar
mueller committed
1835
  }
dimitri's avatar
dimitri committed
1836
  ol.writeString("</table>\n");
dimitri's avatar
dimitri committed
1837 1838
  
  ol.writeString(alphaLinks);
mueller's avatar
mueller committed
1839 1840 1841 1842 1843 1844 1845

  // release the temporary memory
  for (i=0;i<columns;i++)
  {
    delete colIterators[i];
  }
  delete[] colIterators;
mueller's avatar
mueller committed
1846 1847 1848 1849
}

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

dimitri's avatar
dimitri committed
1850
static void writeAlphabeticalIndex(OutputList &ol)
mueller's avatar
mueller committed
1851 1852
{
  if (annotatedClasses==0) return;
dimitri's avatar
dimitri committed
1853 1854
  ol.pushGeneratorState();
  ol.disableAllBut(OutputGenerator::Html);
dimitri's avatar
dimitri committed
1855 1856
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassIndex);
  QCString title = lne ? lne->title() : theTranslator->trCompoundIndex();
dimitri's avatar
dimitri committed
1857 1858
  bool addToIndex = lne==0 || lne->visible();

dimitri's avatar
dimitri committed
1859
  startFile(ol,"classes",0,title,HLI_Classes); 
dimitri's avatar
dimitri committed
1860

mueller's avatar
mueller committed
1861
  startTitle(ol,0);
dimitri's avatar
dimitri committed
1862
  ol.parseText(title);
mueller's avatar
mueller committed
1863
  endTitle(ol,0,0);
dimitri's avatar
dimitri committed
1864

dimitri's avatar
dimitri committed
1865 1866 1867 1868 1869
  if (addToIndex)
  {
    Doxygen::indexList.addContentsItem(TRUE,title,0,"classes",0,TRUE,TRUE); 
  }

dimitri's avatar
dimitri committed
1870
  ol.startContents();
mueller's avatar
mueller committed
1871
  writeAlphabeticalClassList(ol);
dimitri's avatar
dimitri committed
1872
  endFile(ol); // contains ol.endContents()
dimitri's avatar
dimitri committed
1873

dimitri's avatar
dimitri committed
1874
  ol.popGeneratorState();
mueller's avatar
mueller committed
1875 1876 1877 1878
}

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

dimitri's avatar
dimitri committed
1879
static void writeAnnotatedIndex(OutputList &ol)
mueller's avatar
mueller committed
1880
{
dimitri's avatar
dimitri committed
1881 1882
  //printf("writeAnnotatedIndex: count=%d printed=%d\n",
  //    annotatedClasses,annotatedClassesPrinted);
mueller's avatar
mueller committed
1883 1884
  if (annotatedClasses==0) return;
  
dimitri's avatar
dimitri committed
1885
  ol.pushGeneratorState();
mueller's avatar
mueller committed
1886
  ol.disable(OutputGenerator::Man);
dimitri's avatar
dimitri committed
1887 1888 1889 1890 1891
  if (annotatedClassesPrinted==0)
  {
    ol.disable(OutputGenerator::Latex);
    ol.disable(OutputGenerator::RTF);
  }
dimitri's avatar
dimitri committed
1892 1893 1894
  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();
dimitri's avatar
dimitri committed
1895 1896 1897 1898 1899 1900 1901
  bool addToIndex = lne==0 || lne->visible();

  if (Config_getBool("OPTIMIZE_OUTPUT_VHDL")) 
  {
    VhdlDocGen::findConstraintFile(lne);
  }
  
dimitri's avatar
dimitri committed
1902
  startFile(ol,"annotated",0,title,HLI_Annotated);
dimitri's avatar
dimitri committed
1903

dimitri's avatar
dimitri committed
1904
  startTitle(ol,0);
dimitri's avatar
dimitri committed
1905
  ol.parseText(title);
mueller's avatar
mueller committed
1906
  endTitle(ol,0,0);
dimitri's avatar
dimitri committed
1907

dimitri's avatar
dimitri committed
1908
  ol.startContents();
dimitri's avatar
dimitri committed
1909

dimitri's avatar
dimitri committed
1910
  ol.startTextBlock();
dimitri's avatar
dimitri committed
1911
  ol.parseText(lne ? lne->intro() : theTranslator->trCompoundListDescription());
dimitri's avatar
dimitri committed
1912
  ol.endTextBlock();
dimitri's avatar
dimitri committed
1913

dimitri's avatar
dimitri committed
1914 1915 1916 1917 1918 1919
  // ---------------
  // Linear class index for Latex/RTF
  // ---------------
  ol.pushGeneratorState();
  ol.disable(OutputGenerator::Html);

mueller's avatar
mueller committed
1920
  writeAnnotatedClassList(ol);
dimitri's avatar
dimitri committed
1921

dimitri's avatar
dimitri committed
1922 1923 1924 1925 1926 1927 1928 1929
  ol.popGeneratorState();

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

dimitri's avatar
dimitri committed
1930
  {
dimitri's avatar
dimitri committed
1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947
    if (addToIndex)
    {
      Doxygen::indexList.addContentsItem(TRUE,title,0,"annotated",0,TRUE,TRUE); 
      Doxygen::indexList.incContentsDepth();
    }
    FTVHelp* ftv = new FTVHelp(FALSE);
    writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,TRUE,addToIndex);
    writeClassTree(Doxygen::classSDict,ftv,addToIndex,TRUE);
    QGString outStr;
    FTextStream t(&outStr);
    ftv->generateTreeViewInline(t);
    ol.writeString(outStr);
    delete ftv;
    if (addToIndex)
    {
      Doxygen::indexList.decContentsDepth();
    }
dimitri's avatar
dimitri committed
1948
  }
dimitri's avatar
dimitri committed
1949 1950 1951

  ol.popGeneratorState();
  // ------
mueller's avatar
mueller committed
1952
  
dimitri's avatar
dimitri committed
1953
  endFile(ol); // contains ol.endContents()
dimitri's avatar
dimitri committed
1954 1955 1956 1957
  ol.popGeneratorState();
}

//----------------------------------------------------------------------------
dimitri's avatar
dimitri committed
1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970
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();
  }
}
dimitri's avatar
dimitri committed
1971

dimitri's avatar
dimitri committed
1972 1973
static void writeFileLinkForMember(OutputList &ol,MemberDef *md,const char *separator,
                             QCString &prevFileName)
mueller's avatar
mueller committed
1974
{
dimitri's avatar
dimitri committed
1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004
  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;
dimitri's avatar
dimitri committed
2005 2006
  // 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)
dimitri's avatar
dimitri committed
2007 2008 2009
  int startIndex = page==-1 ? 0                      : page;
  int endIndex   = page==-1 ? MEMBER_INDEX_ENTRIES-1 : page;
  ASSERT((int)type<3);
dimitri's avatar
dimitri committed
2010 2011 2012 2013 2014

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

  // each index tab has its own write function
dimitri's avatar
dimitri committed
2015 2016 2017 2018 2019 2020 2021 2022 2023 2024
  static writeLinkForMember_t writeLinkForMemberMap[3] = 
  { 
    &writeClassLinkForMember, 
    &writeFileLinkForMember,
    &writeNamespaceLinkForMember
  };
  QCString prevName;
  QCString prevDefName;
  bool first=TRUE;
  bool firstSection=TRUE;
dimitri's avatar
dimitri committed
2025
  bool firstItem=TRUE;
dimitri's avatar
dimitri committed
2026 2027 2028 2029 2030 2031 2032 2033 2034
  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)
    {
dimitri's avatar
dimitri committed
2035
      const char *sep;
dimitri's avatar
dimitri committed
2036 2037 2038
      bool isFunc=!md->isObjCMethod() && 
        (md->isFunction() || md->isSlot() || md->isSignal()); 
      QCString name=md->name();
dimitri's avatar
dimitri committed
2039 2040
      int startIndex = getPrefixIndex(name);
      if (QCString(name.data()+startIndex)!=prevName) // new entry
dimitri's avatar
dimitri committed
2041
      {
dimitri's avatar
dimitri committed
2042 2043 2044
        if ((prevName.isEmpty() || 
            tolower(name.at(startIndex))!=tolower(prevName.at(0))) && 
            useSections) // new section
dimitri's avatar
dimitri committed
2045
        {
dimitri's avatar
dimitri committed
2046
          if (!firstItem)    ol.endItemListItem();
dimitri's avatar
dimitri committed
2047
          if (!firstSection) ol.endItemList();
dimitri's avatar
dimitri committed
2048 2049 2050 2051
          char cl[2];
          cl[0] = tolower(name.at(startIndex));
          cl[1] = 0;
          QCString cs = letterToLabel(cl[0]);
dimitri's avatar
dimitri committed
2052
          QCString anchor=(QCString)"index_"+cs;
dimitri's avatar
dimitri committed
2053
          QCString title=(QCString)"- "+cl+" -";
dimitri's avatar
dimitri committed
2054 2055 2056 2057 2058
          ol.startSection(anchor,title,SectionInfo::Subsection);
          ol.docify(title);
          ol.endSection(anchor,SectionInfo::Subsection);
          ol.startItemList();
          firstSection=FALSE;
dimitri's avatar
dimitri committed
2059
          firstItem=TRUE;
dimitri's avatar
dimitri committed
2060 2061 2062 2063 2064 2065 2066 2067
        }
        else if (!useSections && first)
        {
          ol.startItemList();
          first=FALSE;
        }

        // member name
dimitri's avatar
dimitri committed
2068 2069 2070
        if (!firstItem) ol.endItemListItem();
        ol.startItemListItem();
        firstItem=FALSE;
dimitri's avatar
dimitri committed
2071 2072 2073 2074 2075 2076 2077
        ol.docify(name);
        if (isFunc) ol.docify("()");
        ol.writeString("\n");

        // link to class
        prevDefName="";
        sep = ": ";
dimitri's avatar
dimitri committed
2078
        prevName = name.data()+startIndex;
dimitri's avatar
dimitri committed
2079 2080 2081 2082 2083 2084
      }
      else // same entry
      {
        sep = ", ";
        // link to class for other members with the same name
      }
dimitri's avatar
dimitri committed
2085
      // write the link for the specific list type
dimitri's avatar
dimitri committed
2086 2087 2088
      writeLinkForMemberMap[(int)type](ol,md,sep,prevDefName);
    }
  }
dimitri's avatar
dimitri committed
2089
  if (!firstItem) ol.endItemListItem();
dimitri's avatar
dimitri committed
2090
  ol.endItemList();
mueller's avatar
mueller committed
2091 2092 2093 2094
}

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

dimitri's avatar
dimitri committed
2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111
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");
dimitri's avatar
dimitri committed
2112 2113
  ClassDef *cd=0;

dimitri's avatar
dimitri committed
2114
 
dimitri's avatar
dimitri committed
2115
  
dimitri's avatar
dimitri committed
2116
  if (md->isLinkableInProject() && 
dimitri's avatar
dimitri committed
2117
      (cd=md->getClassDef())    && 
dimitri's avatar
dimitri committed
2118 2119 2120 2121
      cd->isLinkableInProject() &&
      cd->templateMaster()==0)
  {
    QCString n = md->name();
dimitri's avatar
dimitri committed
2122
    int index = getPrefixIndex(n);
dimitri's avatar
dimitri committed
2123 2124
    uchar charCode = (uchar)n.at(index);
    uint letter = charCode<128 ? tolower(charCode) : charCode;
dimitri's avatar
dimitri committed
2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 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
    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]++;
      }
dimitri's avatar
dimitri committed
2171 2172
      else if (md->isRelated() || md->isForeign() ||
               (md->isFriend() && !isFriendToHide))
dimitri's avatar
dimitri committed
2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202
      {
        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();
dimitri's avatar
dimitri committed
2203
    int index = getPrefixIndex(n);
dimitri's avatar
dimitri committed
2204 2205
    uchar charCode = (uchar)n.at(index);
    uint letter = charCode<128 ? tolower(charCode) : charCode;
dimitri's avatar
dimitri committed
2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239
    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]++;
      }
    }
  }
}

mueller's avatar
mueller committed
2240 2241
//----------------------------------------------------------------------------

dimitri's avatar
dimitri committed
2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261
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();
dimitri's avatar
dimitri committed
2262
    int index = getPrefixIndex(n);
dimitri's avatar
dimitri committed
2263 2264
    uchar charCode = (uchar)n.at(index);
    uint letter = charCode<128 ? tolower(charCode) : charCode;
dimitri's avatar
dimitri committed
2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305
    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]++;
      }
    }
  }
}

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

dimitri's avatar
dimitri committed
2306
static void writeQuickMemberIndex(OutputList &ol,
dimitri's avatar
dimitri committed
2307
    MemberIndexList charUsed[MEMBER_INDEX_ENTRIES],int page,
dimitri's avatar
dimitri committed
2308
    QCString fullName,bool multiPage)
dimitri's avatar
dimitri committed
2309 2310 2311
{
  bool first=TRUE;
  int i;
dimitri's avatar
dimitri committed
2312
  startQuickIndexList(ol,TRUE);
dimitri's avatar
dimitri committed
2313 2314 2315
  for (i=33;i<127;i++)
  {
    char is[2];is[0]=(char)i;is[1]='\0';
dimitri's avatar
dimitri committed
2316
    QCString ci = letterToLabel((char)i);
dimitri's avatar
dimitri committed
2317
    if (charUsed[i].count()>0)
dimitri's avatar
dimitri committed
2318
    {
dimitri's avatar
dimitri committed
2319 2320 2321 2322 2323 2324 2325 2326
      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_";
dimitri's avatar
dimitri committed
2327
      startQuickIndexItem(ol,anchor+ci,i==page,TRUE,first);
dimitri's avatar
dimitri committed
2328
      ol.writeString(is);
dimitri's avatar
dimitri committed
2329
      endQuickIndexItem(ol);
dimitri's avatar
dimitri committed
2330 2331 2332
      first=FALSE;
    }
  }
dimitri's avatar
dimitri committed
2333
  endQuickIndexList(ol);
dimitri's avatar
dimitri committed
2334 2335 2336 2337
}

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

dimitri's avatar
dimitri committed
2338 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
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's avatar
dimitri committed
2367
static void writeClassMemberIndexFiltered(OutputList &ol, ClassMemberHighlight hl)
mueller's avatar
mueller committed
2368
{
dimitri's avatar
dimitri committed
2369
  if (documentedClassMembers[hl]==0) return;
dimitri's avatar
dimitri committed
2370
  
dimitri's avatar
dimitri committed
2371
  static bool disableIndex     = Config_getBool("DISABLE_INDEX");
dimitri's avatar
dimitri committed
2372 2373 2374 2375 2376 2377 2378 2379 2380

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

dimitri's avatar
dimitri committed
2381 2382
  ol.pushGeneratorState();
  ol.disableAllBut(OutputGenerator::Html);
dimitri's avatar
dimitri committed
2383

dimitri's avatar
dimitri committed
2384
  QCString extension=Doxygen::htmlFileExtension;
dimitri's avatar
dimitri committed
2385
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassMembers);
dimitri's avatar
dimitri committed
2386
  QCString title = lne ? lne->title() : theTranslator->trCompoundMembers();
dimitri's avatar
dimitri committed
2387
  if (hl!=CMHL_All) title+=(QCString)" - "+getCmhlInfo(hl)->title;
dimitri's avatar
dimitri committed
2388
  bool addToIndex = lne==0 || lne->visible();
dimitri's avatar
dimitri committed
2389

dimitri's avatar
dimitri committed
2390 2391 2392 2393 2394 2395
  if (addToIndex)
  {
    Doxygen::indexList.addContentsItem(multiPageIndex,getCmhlInfo(hl)->title,0,
                                       getCmhlInfo(hl)->fname,0,multiPageIndex,TRUE);
    if (multiPageIndex) Doxygen::indexList.incContentsDepth();
  }
dimitri's avatar
dimitri committed
2396

dimitri's avatar
dimitri committed
2397
  int page;
dimitri's avatar
dimitri committed
2398
  bool first=TRUE;
dimitri's avatar
dimitri committed
2399
  for (page=0;page<numPages;page++)
dimitri's avatar
dimitri committed
2400
  {
dimitri's avatar
dimitri committed
2401
    if (!multiPageIndex || g_memberIndexLetterUsed[hl][page].count()>0)
dimitri's avatar
dimitri committed
2402
    {
dimitri's avatar
dimitri committed
2403
      QCString fileName = getCmhlInfo(hl)->fname;
dimitri's avatar
dimitri committed
2404
      if (multiPageIndex)
dimitri's avatar
dimitri committed
2405
      { 
dimitri's avatar
dimitri committed
2406 2407 2408 2409 2410 2411 2412
        if (!first)
        {
          fileName+=QCString().sprintf("_0x%02x",page);
        }
        char cs[2];
        cs[0]=page;
        cs[1]=0;
dimitri's avatar
dimitri committed
2413 2414 2415 2416
        if (addToIndex)
        {
          Doxygen::indexList.addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE);
        }
dimitri's avatar
dimitri committed
2417
      }
dimitri's avatar
dimitri committed
2418
      bool quickIndex = documentedClassMembers[hl]>maxItemsBeforeQuickIndex;
dimitri's avatar
dimitri committed
2419
      
dimitri's avatar
dimitri committed
2420 2421 2422 2423
      ol.startFile(fileName+extension,0,title);
      ol.startQuickIndices();
      if (!disableIndex)
      {
dimitri's avatar
dimitri committed
2424
        ol.writeQuickLinks(TRUE,HLI_Functions,0);
dimitri's avatar
dimitri committed
2425
        startQuickIndexList(ol);
dimitri's avatar
dimitri committed
2426

dimitri's avatar
dimitri committed
2427 2428 2429 2430 2431
        // 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);
dimitri's avatar
dimitri committed
2432

dimitri's avatar
dimitri committed
2433 2434 2435
        int i;
        // index items per category member lists
        for (i=1;i<CMHL_Total;i++)
dimitri's avatar
dimitri committed
2436
        {
dimitri's avatar
dimitri committed
2437 2438 2439 2440 2441 2442 2443 2444
          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);
          }
dimitri's avatar
dimitri committed
2445 2446
        }

dimitri's avatar
dimitri committed
2447
        endQuickIndexList(ol);
dimitri's avatar
dimitri committed
2448

dimitri's avatar
dimitri committed
2449 2450 2451 2452 2453 2454
        // quick alphabetical index
        if (quickIndex)
        {
          writeQuickMemberIndex(ol,g_memberIndexLetterUsed[hl],page,
              getCmhlInfo(hl)->fname,multiPageIndex);
        }
dimitri's avatar
dimitri committed
2455
      }
dimitri's avatar
dimitri committed
2456
      ol.endQuickIndices();
dimitri's avatar
dimitri committed
2457 2458
      ol.writeSplitBar(fileName);
      ol.writeSearchInfo();
dimitri's avatar
dimitri committed
2459

dimitri's avatar
dimitri committed
2460 2461
      ol.startContents();

dimitri's avatar
dimitri committed
2462 2463
      if (hl==CMHL_All)
      {
dimitri's avatar
dimitri committed
2464
        ol.startTextBlock();
dimitri's avatar
dimitri committed
2465
        ol.parseText(lne ? lne->intro() : theTranslator->trCompoundMembersDescription(Config_getBool("EXTRACT_ALL")));
dimitri's avatar
dimitri committed
2466
        ol.endTextBlock();
dimitri's avatar
dimitri committed
2467
      }
dimitri's avatar
dimitri committed
2468 2469 2470 2471
      else
      {
        // hack to work around a mozilla bug, which refuses to switch to
        // normal lists otherwise
dimitri's avatar
dimitri committed
2472
        ol.writeString("&#160;");
dimitri's avatar
dimitri committed
2473
      }
dimitri's avatar
dimitri committed
2474
      //ol.newParagraph();  // FIXME:PARA
dimitri's avatar
dimitri committed
2475 2476 2477 2478
      writeMemberList(ol,quickIndex,
                      multiPageIndex?page:-1,
                      g_memberIndexLetterUsed[hl],
                      Definition::TypeClass);
dimitri's avatar
dimitri committed
2479 2480
      endFile(ol);
      first=FALSE;
dimitri's avatar
dimitri committed
2481
    }
dimitri's avatar
dimitri committed
2482
  }
dimitri's avatar
dimitri committed
2483

dimitri's avatar
dimitri committed
2484
  if (multiPageIndex && addToIndex) Doxygen::indexList.decContentsDepth();
dimitri's avatar
dimitri committed
2485
  
dimitri's avatar
dimitri committed
2486
  ol.popGeneratorState();
mueller's avatar
mueller committed
2487 2488
}

dimitri's avatar
dimitri committed
2489
static void writeClassMemberIndex(OutputList &ol)
dimitri's avatar
dimitri committed
2490
{
dimitri's avatar
dimitri committed
2491 2492 2493 2494
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassMembers);
  bool addToIndex = lne==0 || lne->visible();

  if (documentedClassMembers[CMHL_All]>0 && addToIndex)
dimitri's avatar
dimitri committed
2495 2496 2497 2498
  {
    Doxygen::indexList.addContentsItem(TRUE,lne ? lne->title() : theTranslator->trCompoundMembers(),0,"functions",0); 
    Doxygen::indexList.incContentsDepth();
  }
dimitri's avatar
dimitri committed
2499 2500 2501 2502 2503 2504 2505 2506 2507
  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);
dimitri's avatar
dimitri committed
2508
  if (documentedClassMembers[CMHL_All]>0 && addToIndex)
dimitri's avatar
dimitri committed
2509
  {
dimitri's avatar
dimitri committed
2510
    Doxygen::indexList.decContentsDepth();
dimitri's avatar
dimitri committed
2511
  }
dimitri's avatar
dimitri committed
2512

dimitri's avatar
dimitri committed
2513 2514
}

mueller's avatar
mueller committed
2515 2516
//----------------------------------------------------------------------------

dimitri's avatar
dimitri committed
2517
struct FmhlInfo 
mueller's avatar
mueller committed
2518
{
dimitri's avatar
dimitri committed
2519 2520 2521 2522
  FmhlInfo(const char *fn,const char *t) : fname(fn), title(t) {}
  const char *fname;
  QCString title;
};
dimitri's avatar
dimitri committed
2523

dimitri's avatar
dimitri committed
2524 2525 2526 2527 2528
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[] = 
dimitri's avatar
dimitri committed
2529
  {
dimitri's avatar
dimitri committed
2530
    FmhlInfo("globals",     theTranslator->trAll()),
dimitri's avatar
dimitri committed
2531 2532 2533 2534
    FmhlInfo("globals_func",
         fortranOpt ? theTranslator->trSubprograms()  : 
         vhdlOpt    ? VhdlDocGen::trFunctionAndProc() : 
                      theTranslator->trFunctions()),
dimitri's avatar
dimitri committed
2535 2536 2537 2538 2539
    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())
dimitri's avatar
dimitri committed
2540
  };
dimitri's avatar
dimitri committed
2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556
  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;
  }
dimitri's avatar
dimitri committed
2557

dimitri's avatar
dimitri committed
2558 2559 2560 2561
  ol.pushGeneratorState();
  ol.disableAllBut(OutputGenerator::Html);

  QCString extension=Doxygen::htmlFileExtension;
dimitri's avatar
dimitri committed
2562
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::FileGlobals);
dimitri's avatar
dimitri committed
2563
  QCString title = lne ? lne->title() : theTranslator->trFileMembers();
dimitri's avatar
dimitri committed
2564
  bool addToIndex = lne==0 || lne->visible();
dimitri's avatar
dimitri committed
2565

dimitri's avatar
dimitri committed
2566 2567 2568 2569 2570 2571
  if (addToIndex)
  {
    Doxygen::indexList.addContentsItem(multiPageIndex,getFmhlInfo(hl)->title,0,
                                       getFmhlInfo(hl)->fname,0,multiPageIndex,TRUE);
    if (multiPageIndex) Doxygen::indexList.incContentsDepth();
  }
dimitri's avatar
dimitri committed
2572 2573 2574 2575

  int page;
  bool first=TRUE;
  for (page=0;page<numPages;page++)
dimitri's avatar
dimitri committed
2576
  {
dimitri's avatar
dimitri committed
2577
    if (!multiPageIndex || g_fileIndexLetterUsed[hl][page].count()>0)
dimitri's avatar
dimitri committed
2578
    {
dimitri's avatar
dimitri committed
2579
      QCString fileName = getFmhlInfo(hl)->fname;
dimitri's avatar
dimitri committed
2580
      if (multiPageIndex)
dimitri's avatar
dimitri committed
2581
      {
dimitri's avatar
dimitri committed
2582 2583 2584 2585 2586 2587 2588
        if (!first)
        {
          fileName+=QCString().sprintf("_0x%02x",page);
        }
        char cs[2];
        cs[0]=page;
        cs[1]=0;
dimitri's avatar
dimitri committed
2589 2590 2591 2592
        if (addToIndex)
        {
          Doxygen::indexList.addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE);
        }
dimitri's avatar
dimitri committed
2593
      }
dimitri's avatar
dimitri committed
2594
      bool quickIndex = documentedFileMembers[hl]>maxItemsBeforeQuickIndex;
dimitri's avatar
dimitri committed
2595
      
dimitri's avatar
dimitri committed
2596 2597 2598 2599
      ol.startFile(fileName+extension,0,title);
      ol.startQuickIndices();
      if (!disableIndex)
      {
dimitri's avatar
dimitri committed
2600
        ol.writeQuickLinks(TRUE,HLI_Globals,0);
dimitri's avatar
dimitri committed
2601
        startQuickIndexList(ol);
dimitri's avatar
dimitri committed
2602

dimitri's avatar
dimitri committed
2603 2604 2605 2606 2607
        // 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);
dimitri's avatar
dimitri committed
2608

dimitri's avatar
dimitri committed
2609 2610 2611
        int i;
        // index items for per category member lists
        for (i=1;i<FMHL_Total;i++)
dimitri's avatar
dimitri committed
2612
        {
dimitri's avatar
dimitri committed
2613 2614 2615 2616 2617 2618 2619
          if (documentedFileMembers[i]>0)
          {
            startQuickIndexItem(ol,
                getFmhlInfo(i)->fname+Doxygen::htmlFileExtension,hl==i,TRUE,first);
            ol.writeString(fixSpaces(getFmhlInfo(i)->title));
            endQuickIndexItem(ol);
          }
dimitri's avatar
dimitri committed
2620 2621
        }

dimitri's avatar
dimitri committed
2622
        endQuickIndexList(ol);
dimitri's avatar
dimitri committed
2623

dimitri's avatar
dimitri committed
2624 2625 2626 2627 2628
        if (quickIndex)
        {
          writeQuickMemberIndex(ol,g_fileIndexLetterUsed[hl],page,
              getFmhlInfo(hl)->fname,multiPageIndex);
        }
dimitri's avatar
dimitri committed
2629
      }
dimitri's avatar
dimitri committed
2630
      ol.endQuickIndices();
dimitri's avatar
dimitri committed
2631 2632
      ol.writeSplitBar(fileName);
      ol.writeSearchInfo();
dimitri's avatar
dimitri committed
2633

dimitri's avatar
dimitri committed
2634 2635
      ol.startContents();

dimitri's avatar
dimitri committed
2636 2637
      if (hl==FMHL_All)
      {
dimitri's avatar
dimitri committed
2638
        ol.startTextBlock();
dimitri's avatar
dimitri committed
2639
        ol.parseText(lne ? lne->intro() : theTranslator->trFileMembersDescription(Config_getBool("EXTRACT_ALL")));
dimitri's avatar
dimitri committed
2640
        ol.endTextBlock();
dimitri's avatar
dimitri committed
2641
      }
dimitri's avatar
dimitri committed
2642 2643 2644 2645
      else
      {
        // hack to work around a mozilla bug, which refuses to switch to
        // normal lists otherwise
dimitri's avatar
dimitri committed
2646
        ol.writeString("&#160;");
dimitri's avatar
dimitri committed
2647
      }
dimitri's avatar
dimitri committed
2648
      //ol.newParagraph();  // FIXME:PARA
dimitri's avatar
dimitri committed
2649 2650
      //writeFileMemberList(ol,quickIndex,hl,page);
      writeMemberList(ol,quickIndex,
dimitri's avatar
dimitri committed
2651 2652 2653
          multiPageIndex?page:-1,
          g_fileIndexLetterUsed[hl],
          Definition::TypeFile);
dimitri's avatar
dimitri committed
2654 2655
      endFile(ol);
      first=FALSE;
dimitri's avatar
dimitri committed
2656
    }
dimitri's avatar
dimitri committed
2657
  }
dimitri's avatar
dimitri committed
2658
  if (multiPageIndex && addToIndex) Doxygen::indexList.decContentsDepth();
dimitri's avatar
dimitri committed
2659
  ol.popGeneratorState();
mueller's avatar
mueller committed
2660 2661
}

dimitri's avatar
dimitri committed
2662
static void writeFileMemberIndex(OutputList &ol)
dimitri's avatar
dimitri committed
2663
{
dimitri's avatar
dimitri committed
2664 2665 2666
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::FileGlobals);
  bool addToIndex = lne==0 || lne->visible();
  if (documentedFileMembers[FMHL_All]>0 && addToIndex)
dimitri's avatar
dimitri committed
2667 2668 2669 2670
  {
    Doxygen::indexList.addContentsItem(FALSE,lne ? lne->title() : theTranslator->trFileMembers(),0,"globals",0); 
    Doxygen::indexList.incContentsDepth();
  }
dimitri's avatar
dimitri committed
2671 2672 2673 2674 2675 2676 2677
  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);
dimitri's avatar
dimitri committed
2678
  if (documentedFileMembers[FMHL_All]>0 && addToIndex)
dimitri's avatar
dimitri committed
2679
  {
dimitri's avatar
dimitri committed
2680
    Doxygen::indexList.decContentsDepth();
dimitri's avatar
dimitri committed
2681
  }
dimitri's avatar
dimitri committed
2682

dimitri's avatar
dimitri committed
2683 2684
}

dimitri's avatar
dimitri committed
2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711
//----------------------------------------------------------------------------

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];
}
dimitri's avatar
dimitri committed
2712

mueller's avatar
mueller committed
2713 2714
//----------------------------------------------------------------------------

dimitri's avatar
dimitri committed
2715
static void writeNamespaceMemberIndexFiltered(OutputList &ol,
dimitri's avatar
dimitri committed
2716
                                        NamespaceMemberHighlight hl)
mueller's avatar
mueller committed
2717
{
dimitri's avatar
dimitri committed
2718 2719
  if (documentedNamespaceMembers[hl]==0) return;

dimitri's avatar
dimitri committed
2720
  static bool disableIndex     = Config_getBool("DISABLE_INDEX");
dimitri's avatar
dimitri committed
2721

dimitri's avatar
dimitri committed
2722

dimitri's avatar
dimitri committed
2723 2724 2725
  bool multiPageIndex=FALSE;
  int numPages=1;
  if (documentedNamespaceMembers[hl]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX)
dimitri's avatar
dimitri committed
2726
  {
dimitri's avatar
dimitri committed
2727 2728
    multiPageIndex=TRUE;
    numPages=127;
dimitri's avatar
dimitri committed
2729
  }
dimitri's avatar
dimitri committed
2730 2731 2732 2733 2734

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

  QCString extension=Doxygen::htmlFileExtension;
dimitri's avatar
dimitri committed
2735
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::NamespaceMembers);
dimitri's avatar
dimitri committed
2736
  QCString title = lne ? lne->title() : theTranslator->trNamespaceMembers();
dimitri's avatar
dimitri committed
2737
  bool addToIndex = lne==0 || lne->visible();
dimitri's avatar
dimitri committed
2738

dimitri's avatar
dimitri committed
2739 2740 2741 2742 2743 2744
  if (addToIndex)
  {
    Doxygen::indexList.addContentsItem(multiPageIndex,getNmhlInfo(hl)->title,0,
                                       getNmhlInfo(hl)->fname,0,multiPageIndex,TRUE);
    if (multiPageIndex) Doxygen::indexList.incContentsDepth();
  }
dimitri's avatar
dimitri committed
2745 2746 2747 2748

  int page;
  bool first=TRUE;
  for (page=0;page<numPages;page++)
dimitri's avatar
dimitri committed
2749
  {
dimitri's avatar
dimitri committed
2750
    if (!multiPageIndex || g_namespaceIndexLetterUsed[hl][page].count()>0)
dimitri's avatar
dimitri committed
2751
    {
dimitri's avatar
dimitri committed
2752
      QCString fileName = getNmhlInfo(hl)->fname;
dimitri's avatar
dimitri committed
2753
      if (multiPageIndex)
dimitri's avatar
dimitri committed
2754
      {
dimitri's avatar
dimitri committed
2755 2756 2757 2758 2759 2760 2761
        if (!first)
        {
          fileName+=QCString().sprintf("_0x%02x",page);
        }
        char cs[2];
        cs[0]=page;
        cs[1]=0;
dimitri's avatar
dimitri committed
2762 2763 2764 2765
        if (addToIndex)
        {
          Doxygen::indexList.addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE);
        }
dimitri's avatar
dimitri committed
2766
      }
dimitri's avatar
dimitri committed
2767
      bool quickIndex = documentedNamespaceMembers[hl]>maxItemsBeforeQuickIndex;
dimitri's avatar
dimitri committed
2768
      
dimitri's avatar
dimitri committed
2769 2770 2771 2772
      ol.startFile(fileName+extension,0,title);
      ol.startQuickIndices();
      if (!disableIndex)
      {
dimitri's avatar
dimitri committed
2773
        ol.writeQuickLinks(TRUE,HLI_NamespaceMembers,0);
dimitri's avatar
dimitri committed
2774
        startQuickIndexList(ol);
dimitri's avatar
dimitri committed
2775

dimitri's avatar
dimitri committed
2776 2777 2778 2779 2780
        // 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);
dimitri's avatar
dimitri committed
2781

dimitri's avatar
dimitri committed
2782 2783 2784
        int i;
        // index items per category member lists
        for (i=1;i<NMHL_Total;i++)
dimitri's avatar
dimitri committed
2785
        {
dimitri's avatar
dimitri committed
2786 2787 2788 2789 2790 2791 2792
          if (documentedNamespaceMembers[i]>0)
          {
            startQuickIndexItem(ol,
                getNmhlInfo(i)->fname+Doxygen::htmlFileExtension,hl==i,TRUE,first);
            ol.writeString(fixSpaces(getNmhlInfo(i)->title));
            endQuickIndexItem(ol);
          }
dimitri's avatar
dimitri committed
2793 2794
        }

dimitri's avatar
dimitri committed
2795
        endQuickIndexList(ol);
dimitri's avatar
dimitri committed
2796

dimitri's avatar
dimitri committed
2797 2798 2799 2800 2801
        if (quickIndex)
        {
          writeQuickMemberIndex(ol,g_namespaceIndexLetterUsed[hl],page,
              getNmhlInfo(hl)->fname,multiPageIndex);
        }
dimitri's avatar
dimitri committed
2802

dimitri's avatar
dimitri committed
2803
      }
dimitri's avatar
dimitri committed
2804
      ol.endQuickIndices();
dimitri's avatar
dimitri committed
2805 2806
      ol.writeSplitBar(fileName);
      ol.writeSearchInfo();
dimitri's avatar
dimitri committed
2807

dimitri's avatar
dimitri committed
2808 2809
      ol.startContents();

dimitri's avatar
dimitri committed
2810 2811
      if (hl==NMHL_All)
      {
dimitri's avatar
dimitri committed
2812
        ol.startTextBlock();
dimitri's avatar
dimitri committed
2813
        ol.parseText(lne ? lne->intro() : theTranslator->trNamespaceMemberDescription(Config_getBool("EXTRACT_ALL")));
dimitri's avatar
dimitri committed
2814
        ol.endTextBlock();
dimitri's avatar
dimitri committed
2815
      }
dimitri's avatar
dimitri committed
2816 2817 2818 2819
      else
      {
        // hack to work around a mozilla bug, which refuses to switch to
        // normal lists otherwise
dimitri's avatar
dimitri committed
2820
        ol.writeString("&#160;");
dimitri's avatar
dimitri committed
2821
      }
dimitri's avatar
dimitri committed
2822
      //ol.newParagraph(); // FIXME:PARA
dimitri's avatar
dimitri committed
2823

dimitri's avatar
dimitri committed
2824 2825 2826 2827 2828
      //writeNamespaceMemberList(ol,quickIndex,hl,page);
      writeMemberList(ol,quickIndex,
                      multiPageIndex?page:-1,
                      g_namespaceIndexLetterUsed[hl],
                      Definition::TypeNamespace);
dimitri's avatar
dimitri committed
2829
      endFile(ol);
dimitri's avatar
dimitri committed
2830
    }
dimitri's avatar
dimitri committed
2831
  }
dimitri's avatar
dimitri committed
2832
  if (multiPageIndex && addToIndex) Doxygen::indexList.decContentsDepth();
dimitri's avatar
dimitri committed
2833
  ol.popGeneratorState();
mueller's avatar
mueller committed
2834 2835
}

dimitri's avatar
dimitri committed
2836
static void writeNamespaceMemberIndex(OutputList &ol)
dimitri's avatar
dimitri committed
2837
{
dimitri's avatar
dimitri committed
2838 2839 2840
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::NamespaceMembers);
  bool addToIndex = lne==0 || lne->visible();
  if (documentedNamespaceMembers[NMHL_All]>0 && addToIndex)
dimitri's avatar
dimitri committed
2841 2842 2843 2844
  {
    Doxygen::indexList.addContentsItem(FALSE,lne ? lne->title() : theTranslator->trNamespaceMembers(),0,"namespacemembers",0); 
    Doxygen::indexList.incContentsDepth();
  }
dimitri's avatar
dimitri committed
2845
  //bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
dimitri's avatar
dimitri committed
2846 2847 2848 2849 2850 2851
  writeNamespaceMemberIndexFiltered(ol,NMHL_All);
  writeNamespaceMemberIndexFiltered(ol,NMHL_Functions);
  writeNamespaceMemberIndexFiltered(ol,NMHL_Variables);
  writeNamespaceMemberIndexFiltered(ol,NMHL_Typedefs);
  writeNamespaceMemberIndexFiltered(ol,NMHL_Enums);
  writeNamespaceMemberIndexFiltered(ol,NMHL_EnumValues);
dimitri's avatar
dimitri committed
2852
  if (documentedNamespaceMembers[NMHL_All]>0 && addToIndex)
dimitri's avatar
dimitri committed
2853
  {
dimitri's avatar
dimitri committed
2854
    Doxygen::indexList.decContentsDepth();
dimitri's avatar
dimitri committed
2855
  }
dimitri's avatar
dimitri committed
2856

dimitri's avatar
dimitri committed
2857 2858
}

mueller's avatar
mueller committed
2859 2860
//----------------------------------------------------------------------------

dimitri's avatar
dimitri committed
2861 2862
//----------------------------------------------------------------------------

dimitri's avatar
dimitri committed
2863
static void writeExampleIndex(OutputList &ol)
mueller's avatar
mueller committed
2864
{
dimitri's avatar
dimitri committed
2865
  if (Doxygen::exampleSDict->count()==0) return;
dimitri's avatar
dimitri committed
2866
  ol.pushGeneratorState();
mueller's avatar
mueller committed
2867
  ol.disable(OutputGenerator::Man);
dimitri's avatar
dimitri committed
2868
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Examples);
dimitri's avatar
dimitri committed
2869
  QCString title = lne ? lne->title() : theTranslator->trExamples();
dimitri's avatar
dimitri committed
2870 2871
  bool addToIndex = lne==0 || lne->visible();

dimitri's avatar
dimitri committed
2872
  startFile(ol,"examples",0,title,HLI_Examples);
dimitri's avatar
dimitri committed
2873

dimitri's avatar
dimitri committed
2874
  startTitle(ol,0);
dimitri's avatar
dimitri committed
2875
  ol.parseText(title);
mueller's avatar
mueller committed
2876
  endTitle(ol,0,0);
dimitri's avatar
dimitri committed
2877

dimitri's avatar
dimitri committed
2878
  ol.startContents();
dimitri's avatar
dimitri committed
2879 2880 2881 2882 2883 2884 2885

  if (addToIndex)
  {
    Doxygen::indexList.addContentsItem(TRUE,title,0,"examples",0,TRUE,TRUE); 
    Doxygen::indexList.incContentsDepth();
  }

dimitri's avatar
dimitri committed
2886
  ol.startTextBlock();
dimitri's avatar
dimitri committed
2887
  ol.parseText(lne ? lne->intro() : theTranslator->trExamplesDescription());
dimitri's avatar
dimitri committed
2888
  ol.endTextBlock();
dimitri's avatar
dimitri committed
2889

dimitri's avatar
dimitri committed
2890
  ol.startItemList();
dimitri's avatar
dimitri committed
2891
  PageSDict::Iterator pdi(*Doxygen::exampleSDict);
dimitri's avatar
dimitri committed
2892 2893
  PageDef *pd=0;
  for (pdi.toFirst();(pd=pdi.current());++pdi)
mueller's avatar
mueller committed
2894
  {
dimitri's avatar
dimitri committed
2895
    ol.startItemListItem();
dimitri's avatar
dimitri committed
2896 2897
    QCString n=pd->getOutputFileBase();
    if (!pd->title().isEmpty())
mueller's avatar
mueller committed
2898
    {
dimitri's avatar
dimitri committed
2899
      ol.writeObjectLink(0,n,0,pd->title());
dimitri's avatar
dimitri committed
2900 2901 2902 2903
      if (addToIndex)
      {
        Doxygen::indexList.addContentsItem(FALSE,filterTitle(pd->title()),pd->getReference(),n,0,FALSE,TRUE);
      }
mueller's avatar
mueller committed
2904 2905 2906
    }
    else
    {
dimitri's avatar
dimitri committed
2907
      ol.writeObjectLink(0,n,0,pd->name());
dimitri's avatar
dimitri committed
2908 2909 2910 2911
      if (addToIndex)
      {
        Doxygen::indexList.addContentsItem(FALSE,pd->name(),pd->getReference(),n,0,FALSE,TRUE);
      }
mueller's avatar
mueller committed
2912
    }
dimitri's avatar
dimitri committed
2913
    ol.endItemListItem();
mueller's avatar
mueller committed
2914 2915
    ol.writeString("\n");
  }
dimitri's avatar
dimitri committed
2916
  ol.endItemList();
dimitri's avatar
dimitri committed
2917 2918 2919 2920 2921

  if (addToIndex)
  {
    Doxygen::indexList.decContentsDepth();
  }
mueller's avatar
mueller committed
2922
  endFile(ol);
dimitri's avatar
dimitri committed
2923
  ol.popGeneratorState();
mueller's avatar
mueller committed
2924 2925
}

dimitri's avatar
dimitri committed
2926 2927 2928

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

dimitri's avatar
dimitri committed
2929 2930 2931 2932 2933 2934 2935 2936 2937 2938
template<typename T>
bool writeMemberNavIndex(FTextStream &t,
                         int indent,
                         int n,
                         int documentedMembers[],
                         MemberIndexList indexLetterUsed[][MEMBER_INDEX_ENTRIES],
                         const T *(*getInfo)(int),
                         bool &first
                        )

dimitri's avatar
dimitri committed
2939
{
dimitri's avatar
dimitri committed
2940
  bool found=FALSE;
dimitri's avatar
dimitri committed
2941 2942
  QCString indentStr;
  indentStr.fill(' ',indent*2);
dimitri's avatar
dimitri committed
2943 2944 2945
  // index items per category member lists
  int i;
  for (i=0;i<n;i++)
dimitri's avatar
dimitri committed
2946
  {
dimitri's avatar
dimitri committed
2947 2948 2949 2950
    bool hasIndex       = documentedMembers[i]>0;
    bool quickIndex     = documentedMembers[i]>maxItemsBeforeQuickIndex;
    bool multiIndexPage = documentedMembers[i]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX;
    if (hasIndex)
dimitri's avatar
dimitri committed
2951
    {
dimitri's avatar
dimitri committed
2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971
      // 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++)
dimitri's avatar
dimitri committed
2972
        {
dimitri's avatar
dimitri committed
2973
          if (indexLetterUsed[i][j].count()>0)
dimitri's avatar
dimitri committed
2974
          {
dimitri's avatar
dimitri committed
2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988
            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;
dimitri's avatar
dimitri committed
2989 2990
          }
        }
dimitri's avatar
dimitri committed
2991
        t << endl << indentStr << "  ] ]";
dimitri's avatar
dimitri committed
2992
      }
dimitri's avatar
dimitri committed
2993
      else
dimitri's avatar
dimitri committed
2994
      {
dimitri's avatar
dimitri committed
2995
        t << "null" << " ]";
dimitri's avatar
dimitri committed
2996
      }
dimitri's avatar
dimitri committed
2997 2998 2999 3000 3001 3002 3003
    }
  }
  return found;
}

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

dimitri's avatar
dimitri committed
3004
static bool writeFullNavIndex(FTextStream &t, LayoutNavEntry *root,int indent,bool &first)
dimitri's avatar
dimitri committed
3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015
{
  static struct NavEntryCountMap 
  {
    LayoutNavEntry::Kind kind;
    bool hasItems;
  } navEntryCountMap[] =
  {
    { LayoutNavEntry::MainPage,         TRUE                                   },
    { LayoutNavEntry::Pages,            indexedPages>0                         },
    { LayoutNavEntry::Modules,          documentedGroups>0                     },
    { LayoutNavEntry::Namespaces,       documentedNamespaces>0                 },
dimitri's avatar
dimitri committed
3016
    { LayoutNavEntry::NamespaceList,    documentedNamespaces>0                 },
dimitri's avatar
dimitri committed
3017 3018
    { LayoutNavEntry::NamespaceMembers, documentedNamespaceMembers[NMHL_All]>0 },
    { LayoutNavEntry::Classes,          annotatedClasses>0                     },
dimitri's avatar
dimitri committed
3019 3020
    { LayoutNavEntry::ClassList,        annotatedClasses>0                     },
    { LayoutNavEntry::ClassIndex,       annotatedClasses>0                     },
dimitri's avatar
dimitri committed
3021 3022 3023
    { LayoutNavEntry::ClassHierarchy,   hierarchyClasses>0                     },
    { LayoutNavEntry::ClassMembers,     documentedClassMembers[CMHL_All]>0     },
    { LayoutNavEntry::Files,            documentedFiles>0                      },
dimitri's avatar
dimitri committed
3024
    { LayoutNavEntry::FileList,         documentedFiles>0                      },
dimitri's avatar
dimitri committed
3025
    { LayoutNavEntry::FileGlobals,      documentedFileMembers[FMHL_All]>0      },
dimitri's avatar
dimitri committed
3026
    //{ LayoutNavEntry::Dirs,             documentedDirs>0                       },
dimitri's avatar
dimitri committed
3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039
    { 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())
dimitri's avatar
dimitri committed
3040
      {
dimitri's avatar
dimitri committed
3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079
        // 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 << "  ] ]";
dimitri's avatar
dimitri committed
3080 3081 3082
      }
    }
  }
dimitri's avatar
dimitri committed
3083
  return found;
dimitri's avatar
dimitri committed
3084 3085
}

mueller's avatar
mueller committed
3086 3087
//----------------------------------------------------------------------------

dimitri's avatar
dimitri committed
3088
static void countRelatedPages(int &docPages,int &indexPages)
dimitri's avatar
dimitri committed
3089
{
dimitri's avatar
dimitri committed
3090
  docPages=indexPages=0;
dimitri's avatar
dimitri committed
3091
  PageSDict::Iterator pdi(*Doxygen::pageSDict);
dimitri's avatar
dimitri committed
3092 3093
  PageDef *pd=0;
  for (pdi.toFirst();(pd=pdi.current());++pdi)
dimitri's avatar
dimitri committed
3094
  {
dimitri's avatar
dimitri committed
3095
    if ( pd->visibleInIndex())
dimitri's avatar
dimitri committed
3096
    {
dimitri's avatar
dimitri committed
3097
      indexPages++; 
dimitri's avatar
dimitri committed
3098 3099 3100 3101
    }
    if ( pd->documentedPage())
    {
      docPages++;
dimitri's avatar
dimitri committed
3102
    }
dimitri's avatar
dimitri committed
3103 3104 3105 3106 3107
  }
}

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

dimitri's avatar
dimitri committed
3108 3109
static void writeSubPages(PageDef *pd)
{
dimitri's avatar
dimitri committed
3110 3111
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Pages);
  bool addToIndex = lne==0 || lne->visible();
dimitri's avatar
dimitri committed
3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127
  //printf("Write subpages(%s #=%d)\n",pd->name().data(),pd->getSubPages() ? pd->getSubPages()->count() : 0 );
  PageSDict *subPages = pd->getSubPages();
  if (subPages)
  {
    PageSDict::Iterator pi(*subPages);
    PageDef *subPage;
    for (pi.toFirst();(subPage=pi.current());++pi)
    {
      QCString pageTitle;

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

      bool hasSubPages = subPage->hasSubPages();
dimitri's avatar
dimitri committed
3128
      bool hasSections = subPage->hasSections();
dimitri's avatar
dimitri committed
3129

dimitri's avatar
dimitri committed
3130 3131
      //printf("subpage %s: addToIndex=%d hasSubPages=%d hasSections=%d\n",
      //    pd->name().data(),addToIndex,hasSubPages,hasSections);
dimitri's avatar
dimitri committed
3132 3133
      if (addToIndex)
      {
dimitri's avatar
dimitri committed
3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144
        Doxygen::indexList.addContentsItem(hasSubPages,pageTitle,
            subPage->getReference(),subPage->getOutputFileBase(),
            0,hasSubPages,TRUE);
        if (hasSections || hasSubPages)
        {
          Doxygen::indexList.incContentsDepth();
        }
        if (hasSections)
        {
          subPage->addSectionsToIndex();
        }
dimitri's avatar
dimitri committed
3145
      }
dimitri's avatar
dimitri committed
3146
      writeSubPages(subPage);
dimitri's avatar
dimitri committed
3147 3148 3149 3150
      if (addToIndex && (hasSections || hasSubPages))
      {
        Doxygen::indexList.decContentsDepth();
      }
dimitri's avatar
dimitri committed
3151 3152 3153
    }
  }
}
dimitri's avatar
dimitri committed
3154

dimitri's avatar
dimitri committed
3155
static void writePageIndex(OutputList &ol)
mueller's avatar
mueller committed
3156
{
dimitri's avatar
dimitri committed
3157
  if (indexedPages==0) return;
dimitri's avatar
dimitri committed
3158
  ol.pushGeneratorState();
dimitri's avatar
dimitri committed
3159
  ol.disableAllBut(OutputGenerator::Html);
dimitri's avatar
dimitri committed
3160
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Pages);
dimitri's avatar
dimitri committed
3161
  QCString title = lne ? lne->title() : theTranslator->trRelatedPages();
dimitri's avatar
dimitri committed
3162
  startFile(ol,"pages",0,title,HLI_Pages);
mueller's avatar
mueller committed
3163
  startTitle(ol,0);
dimitri's avatar
dimitri committed
3164
  ol.parseText(title);
mueller's avatar
mueller committed
3165
  endTitle(ol,0,0);
dimitri's avatar
dimitri committed
3166
  ol.startContents();
dimitri's avatar
dimitri committed
3167
  ol.startTextBlock();
dimitri's avatar
dimitri committed
3168
  bool addToIndex = lne==0 || lne->visible();
dimitri's avatar
dimitri committed
3169
  if (0 /*addToIndex*/) // skip Related Pages section in navigation index
dimitri's avatar
dimitri committed
3170 3171 3172 3173
  {
    Doxygen::indexList.addContentsItem(TRUE,title,0,"pages",0,TRUE,TRUE); 
    Doxygen::indexList.incContentsDepth();
  }
dimitri's avatar
dimitri committed
3174
  ol.parseText(lne ? lne->intro() : theTranslator->trRelatedPagesDescription());
dimitri's avatar
dimitri committed
3175
  ol.endTextBlock();
dimitri's avatar
dimitri committed
3176
  startIndexHierarchy(ol,0);
dimitri's avatar
dimitri committed
3177
  PageSDict::Iterator pdi(*Doxygen::pageSDict);
dimitri's avatar
dimitri committed
3178 3179
  PageDef *pd=0;
  for (pdi.toFirst();(pd=pdi.current());++pdi)
mueller's avatar
mueller committed
3180
  {
dimitri's avatar
dimitri committed
3181
    if (pd->visibleInIndex())
dimitri's avatar
dimitri committed
3182
    {
dimitri's avatar
dimitri committed
3183
      QCString pageTitle;
dimitri's avatar
dimitri committed
3184

dimitri's avatar
dimitri committed
3185 3186
      if (pd->title().isEmpty())
        pageTitle=pd->name();
dimitri's avatar
dimitri committed
3187
      else
dimitri's avatar
dimitri committed
3188
        pageTitle=pd->title();
dimitri's avatar
dimitri committed
3189

dimitri's avatar
dimitri committed
3190
      bool hasSubPages = pd->hasSubPages();
dimitri's avatar
dimitri committed
3191
      bool hasSections = pd->hasSections();
dimitri's avatar
dimitri committed
3192

dimitri's avatar
dimitri committed
3193
      ol.startIndexListItem();
dimitri's avatar
dimitri committed
3194 3195 3196
      ol.startIndexItem(pd->getReference(),pd->getOutputFileBase());
      ol.parseText(pageTitle);
      ol.endIndexItem(pd->getReference(),pd->getOutputFileBase());
dimitri's avatar
dimitri committed
3197
      if (pd->isReference()) 
dimitri's avatar
dimitri committed
3198 3199 3200 3201 3202
      { 
        ol.startTypewriter(); 
        ol.docify(" [external]");
        ol.endTypewriter();
      }
dimitri's avatar
dimitri committed
3203
      ol.writeString("\n");
dimitri's avatar
dimitri committed
3204 3205
      if (addToIndex)
      {
dimitri's avatar
dimitri committed
3206 3207 3208 3209 3210 3211 3212 3213
        Doxygen::indexList.addContentsItem(
               hasSubPages || hasSections,   // isDir
               filterTitle(pageTitle),       // name
               pd->getReference(),           // ref
               pd->getOutputFileBase(),      // file
               0,                            // anchor
               hasSubPages || hasSections,   // separateIndex
               TRUE);                        // addToNavIndex
dimitri's avatar
dimitri committed
3214 3215 3216 3217
        if (hasSections || hasSubPages)
        {
          Doxygen::indexList.incContentsDepth();
        }
dimitri's avatar
dimitri committed
3218 3219 3220 3221
        if (hasSections)
        {
          pd->addSectionsToIndex();
        }
dimitri's avatar
dimitri committed
3222
      }
dimitri's avatar
dimitri committed
3223
      writeSubPages(pd);
dimitri's avatar
dimitri committed
3224 3225 3226 3227
      if (addToIndex && (hasSections || hasSubPages))
      {
        Doxygen::indexList.decContentsDepth();
      }
dimitri's avatar
dimitri committed
3228
      ol.endIndexListItem();
dimitri's avatar
dimitri committed
3229
    }
mueller's avatar
mueller committed
3230
  }
dimitri's avatar
dimitri committed
3231
  endIndexHierarchy(ol,0);
dimitri's avatar
dimitri committed
3232
  if (0 /*addToIndex*/) // skip Related Pages section in navigation index
dimitri's avatar
dimitri committed
3233 3234 3235
  {
    Doxygen::indexList.decContentsDepth();
  }
mueller's avatar
mueller committed
3236
  endFile(ol);
dimitri's avatar
dimitri committed
3237
  ol.popGeneratorState();
mueller's avatar
mueller committed
3238 3239 3240 3241
}

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

dimitri's avatar
dimitri committed
3242
static int countGroups()
mueller's avatar
mueller committed
3243 3244
{
  int count=0;
dimitri's avatar
dimitri committed
3245
  GroupSDict::Iterator gli(*Doxygen::groupSDict);
mueller's avatar
mueller committed
3246
  GroupDef *gd;
dimitri's avatar
dimitri committed
3247
  for (gli.toFirst();(gd=gli.current());++gli)
mueller's avatar
mueller committed
3248
  {
dimitri's avatar
dimitri committed
3249 3250 3251 3252 3253
    if (!gd->isReference())
    {
      gd->visited=FALSE;
      count++;
    }
mueller's avatar
mueller committed
3254 3255 3256 3257
  }
  return count;
}

dimitri's avatar
dimitri committed
3258 3259
//----------------------------------------------------------------------------

dimitri's avatar
dimitri committed
3260
static int countDirs()
dimitri's avatar
dimitri committed
3261 3262
{
  int count=0;
dimitri's avatar
dimitri committed
3263
  SDict<DirDef>::Iterator dli(*Doxygen::directories);
dimitri's avatar
dimitri committed
3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275
  DirDef *dd;
  for (dli.toFirst();(dd=dli.current());++dli)
  {
    if (dd->isLinkableInProject())
    {
      dd->visited=FALSE;
      count++;
    }
  }
  return count;
}

dimitri's avatar
dimitri committed
3276 3277 3278 3279 3280

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

void writeGraphInfo(OutputList &ol)
{
dimitri's avatar
dimitri committed
3281
  if (!Config_getBool("HAVE_DOT") || !Config_getBool("GENERATE_HTML")) return;
dimitri's avatar
dimitri committed
3282 3283
  ol.pushGeneratorState();
  ol.disableAllBut(OutputGenerator::Html);
dimitri's avatar
dimitri committed
3284
  generateGraphLegend(Config_getString("HTML_OUTPUT"));
dimitri's avatar
dimitri committed
3285
  startFile(ol,"graph_legend",0,theTranslator->trLegendTitle().data());
dimitri's avatar
dimitri committed
3286
  startTitle(ol,0);
dimitri's avatar
dimitri committed
3287
  ol.parseText(theTranslator->trLegendTitle());
dimitri's avatar
dimitri committed
3288
  endTitle(ol,0,0);
dimitri's avatar
dimitri committed
3289
  ol.startContents();
dimitri's avatar
dimitri committed
3290 3291
  bool &stripCommentsStateRef = Config_getBool("STRIP_CODE_COMMENTS");
  bool oldStripCommentsState = stripCommentsStateRef;
dimitri's avatar
dimitri committed
3292
  // temporarily disable the stripping of comments for our own code example!
dimitri's avatar
dimitri committed
3293
  stripCommentsStateRef = FALSE;
dimitri's avatar
dimitri committed
3294 3295 3296 3297 3298 3299 3300 3301 3302
  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());
  }
  ol.parseDoc("graph_legend",1,0,0,legendDocs,FALSE,FALSE);
dimitri's avatar
dimitri committed
3303
  stripCommentsStateRef = oldStripCommentsState;
dimitri's avatar
dimitri committed
3304 3305 3306 3307
  endFile(ol);
  ol.popGeneratorState();
}

dimitri's avatar
dimitri committed
3308 3309


dimitri's avatar
dimitri committed
3310 3311
//----------------------------------------------------------------------------
/*!
dimitri's avatar
dimitri committed
3312
 * write groups as hierarchical trees
dimitri's avatar
dimitri committed
3313
 */
dimitri's avatar
dimitri committed
3314
static void writeGroupTreeNode(OutputList &ol, GroupDef *gd, int level, FTVHelp* ftv, bool addToIndex)
dimitri's avatar
dimitri committed
3315
{
dimitri's avatar
dimitri committed
3316 3317
  //bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
  //bool vhdlOpt    = Config_getBool("OPTIMIZE_OUTPUT_VHDL");  
dimitri's avatar
dimitri committed
3318 3319 3320
  if (level>20)
  {
    warn(gd->getDefFileName(),gd->getDefLine(),
dimitri's avatar
dimitri committed
3321
        "warning: maximum nesting level exceeded for group %s: check for possible recursive group relation!\n",gd->name().data()
dimitri's avatar
dimitri committed
3322 3323 3324
        );
    return;
  }
dimitri's avatar
dimitri committed
3325

dimitri's avatar
dimitri committed
3326 3327 3328
  /* Some groups should appear twice under different parent-groups.
   * That is why we should not check if it was visited 
   */
dimitri's avatar
dimitri committed
3329
  if (/*!gd->visited &&*/ (!gd->isASubGroup() || level>0) &&
dimitri's avatar
dimitri committed
3330
      gd->isVisible() &&
dimitri's avatar
dimitri committed
3331 3332
      (!gd->isReference() || Config_getBool("EXTERNAL_GROUPS")) // hide external groups by default
     )
dimitri's avatar
dimitri committed
3333 3334 3335
  {
    //printf("gd->name()=%s #members=%d\n",gd->name().data(),gd->countMembers());
    // write group info
dimitri's avatar
dimitri committed
3336 3337
    bool hasSubGroups = gd->getSubGroups()->count()>0;
    bool hasSubPages = gd->getPages()->count()>0;
dimitri's avatar
dimitri committed
3338
    int numSubItems = 0;
dimitri's avatar
dimitri committed
3339
    if (1 /*Config_getBool("TOC_EXPAND")*/)
dimitri's avatar
dimitri committed
3340
    {
dimitri's avatar
dimitri committed
3341 3342 3343 3344 3345 3346 3347 3348 3349
      QListIterator<MemberList> mli(gd->getMemberLists());
      MemberList *ml;
      for (mli.toFirst();(ml=mli.current());++mli)
      {
        if (ml->listType()&MemberList::documentationLists)
        {
          numSubItems += ml->count();
        }
      }
dimitri's avatar
dimitri committed
3350 3351 3352
      numSubItems += gd->getNamespaces()->count();
      numSubItems += gd->getClasses()->count();
      numSubItems += gd->getFiles()->count();
dimitri's avatar
dimitri committed
3353 3354
      numSubItems += gd->getDirs()->count();
      numSubItems += gd->getPages()->count();
dimitri's avatar
dimitri committed
3355 3356 3357
    }

    bool isDir = hasSubGroups || hasSubPages || numSubItems>0;
dimitri's avatar
dimitri committed
3358
    //printf("gd=`%s': pageDict=%d\n",gd->name().data(),gd->pageDict->count());
dimitri's avatar
dimitri committed
3359 3360 3361 3362 3363
    if (addToIndex)
    {
      Doxygen::indexList.addContentsItem(isDir,gd->groupTitle(),gd->getReference(),gd->getOutputFileBase(),0,isDir,TRUE); 
      Doxygen::indexList.incContentsDepth();
    }
dimitri's avatar
dimitri committed
3364 3365
    if (ftv)
    {
dimitri's avatar
dimitri committed
3366 3367 3368
      ftv->addContentsItem(hasSubGroups,gd->groupTitle(),
                           gd->getReference(),gd->getOutputFileBase(),0,
                           FALSE,FALSE,gd); 
dimitri's avatar
dimitri committed
3369 3370 3371
      ftv->incContentsDepth();
    }
    
dimitri's avatar
dimitri committed
3372 3373 3374 3375
    //ol.writeListItem();
    //ol.startTextLink(gd->getOutputFileBase(),0);
    //parseText(ol,gd->groupTitle());
    //ol.endTextLink();
dimitri's avatar
dimitri committed
3376

dimitri's avatar
dimitri committed
3377
    ol.startIndexListItem();
dimitri's avatar
dimitri committed
3378 3379 3380
    ol.startIndexItem(gd->getReference(),gd->getOutputFileBase());
    ol.parseText(gd->groupTitle());
    ol.endIndexItem(gd->getReference(),gd->getOutputFileBase());
dimitri's avatar
dimitri committed
3381 3382 3383 3384 3385 3386
    if (gd->isReference()) 
    { 
      ol.startTypewriter(); 
      ol.docify(" [external]");
      ol.endTypewriter();
    }
dimitri's avatar
dimitri committed
3387

dimitri's avatar
dimitri committed
3388 3389 3390
    QListIterator<LayoutDocEntry> eli(LayoutDocManager::instance().docEntries(LayoutDocManager::Group));
    LayoutDocEntry *lde;
    for (eli.toFirst();(lde=eli.current());++eli)
dimitri's avatar
dimitri committed
3391
    {
dimitri's avatar
dimitri committed
3392
      if (lde->kind()==LayoutDocEntry::MemberDef && addToIndex)
dimitri's avatar
dimitri committed
3393
      {
dimitri's avatar
dimitri committed
3394 3395 3396
        LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde;
        MemberList *ml = gd->getMemberList(lmd->type);
        if (ml)
dimitri's avatar
dimitri committed
3397
        {
dimitri's avatar
dimitri committed
3398 3399 3400 3401
          MemberListIterator mi(*ml);
          MemberDef *md;
          for (mi.toFirst();(md=mi.current());++mi)
          {
dimitri's avatar
dimitri committed
3402
            if (md->isVisible() && md->name().find('@')==-1)
dimitri's avatar
dimitri committed
3403 3404 3405 3406 3407 3408
            {
              Doxygen::indexList.addContentsItem(FALSE,
                  md->name(),md->getReference(),
                  md->getOutputFileBase(),md->anchor(),FALSE);
            }
          }
dimitri's avatar
dimitri committed
3409 3410
        }
      }
dimitri's avatar
dimitri committed
3411
      else if (lde->kind()==LayoutDocEntry::GroupClasses && addToIndex)
dimitri's avatar
dimitri committed
3412
      {
dimitri's avatar
dimitri committed
3413
        ClassSDict::Iterator it(*gd->getClasses());
dimitri's avatar
dimitri committed
3414
        ClassDef *cd;
dimitri's avatar
dimitri committed
3415 3416
        for (;(cd=it.current());++it)
        {
dimitri's avatar
dimitri committed
3417 3418 3419 3420 3421 3422
          if (cd->isVisible())
          {
            Doxygen::indexList.addContentsItem(FALSE,
                cd->localName(),cd->getReference(),
                cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE);
          }
dimitri's avatar
dimitri committed
3423 3424 3425 3426 3427 3428 3429 3430
        }
      }
      else if (lde->kind()==LayoutDocEntry::GroupNamespaces && addToIndex)
      {
        NamespaceSDict::Iterator it(*gd->getNamespaces());
        NamespaceDef *nd;
        for (;(nd=it.current());++it)
        {
dimitri's avatar
dimitri committed
3431 3432 3433 3434 3435 3436
          if (nd->isVisible())
          {
            Doxygen::indexList.addContentsItem(FALSE,
                nd->localName(),nd->getReference(),
                nd->getOutputFileBase(),0,FALSE,FALSE);
          }
dimitri's avatar
dimitri committed
3437 3438 3439 3440 3441 3442 3443 3444
        }
      }
      else if (lde->kind()==LayoutDocEntry::GroupFiles && addToIndex)
      {
        QListIterator<FileDef> it(*gd->getFiles());
        FileDef *fd;
        for (;(fd=it.current());++it)
        {
dimitri's avatar
dimitri committed
3445 3446 3447 3448 3449 3450
          if (fd->isVisible())
          {
            Doxygen::indexList.addContentsItem(FALSE,
                fd->displayName(),fd->getReference(),
                fd->getOutputFileBase(),0,FALSE,FALSE);
          }
dimitri's avatar
dimitri committed
3451 3452 3453 3454
        }
      }
      else if (lde->kind()==LayoutDocEntry::GroupDirs && addToIndex)
      {
dimitri's avatar
dimitri committed
3455 3456 3457
        QListIterator<DirDef> it(*gd->getDirs());
        DirDef *dd;
        for (;(dd=it.current());++it)
dimitri's avatar
dimitri committed
3458
        {
dimitri's avatar
dimitri committed
3459
          if (dd->isVisible())
dimitri's avatar
dimitri committed
3460
          {
dimitri's avatar
dimitri committed
3461 3462 3463
            Doxygen::indexList.addContentsItem(FALSE,
                dd->shortName(),dd->getReference(),
                dd->getOutputFileBase(),0,FALSE,FALSE);
dimitri's avatar
dimitri committed
3464 3465
          }
        }
dimitri's avatar
dimitri committed
3466
      }
dimitri's avatar
dimitri committed
3467
      else if (lde->kind()==LayoutDocEntry::GroupPageDocs && addToIndex)
dimitri's avatar
dimitri committed
3468
      {
dimitri's avatar
dimitri committed
3469 3470 3471
        SDict<PageDef>::Iterator it(*gd->getPages());
        PageDef *pd;
        for (;(pd=it.current());++it)
dimitri's avatar
dimitri committed
3472
        {
dimitri's avatar
dimitri committed
3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497
          SectionInfo *si=0;
          if (!pd->name().isEmpty()) si=Doxygen::sectionDict[pd->name()];
          bool hasSubPages = pd->hasSubPages();
          bool hasSections = pd->hasSections();
          Doxygen::indexList.addContentsItem(
              hasSubPages || hasSections,
              convertToHtml(pd->title(),TRUE),
              gd->getReference(),
              gd->getOutputFileBase(),
              si ? si->label.data() : 0,
              hasSubPages || hasSections,
              TRUE); // addToNavIndex
          if (hasSections || hasSubPages)
          {
            Doxygen::indexList.incContentsDepth();
          }
          if (hasSections)
          {
            pd->addSectionsToIndex();
          }
          writeSubPages(pd);
          if (hasSections || hasSubPages)
          {
            Doxygen::indexList.decContentsDepth();
          }
dimitri's avatar
dimitri committed
3498
        }
dimitri's avatar
dimitri committed
3499
      }
dimitri's avatar
dimitri committed
3500
      else if (lde->kind()==LayoutDocEntry::GroupNestedGroups)
dimitri's avatar
dimitri committed
3501
      {
dimitri's avatar
dimitri committed
3502
        if (gd->getSubGroups()->count()>0)
dimitri's avatar
dimitri committed
3503
        {
dimitri's avatar
dimitri committed
3504 3505 3506 3507 3508 3509 3510 3511 3512
          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); 
dimitri's avatar
dimitri committed
3513
        }
dimitri's avatar
dimitri committed
3514 3515
      }
    }
dimitri's avatar
dimitri committed
3516

dimitri's avatar
dimitri committed
3517
    ol.endIndexListItem();
dimitri's avatar
dimitri committed
3518
    
dimitri's avatar
dimitri committed
3519 3520 3521 3522
    if (addToIndex)
    {
      Doxygen::indexList.decContentsDepth();
    }
dimitri's avatar
dimitri committed
3523
    if (ftv)
dimitri's avatar
dimitri committed
3524
    {
dimitri's avatar
dimitri committed
3525
      ftv->decContentsDepth();
dimitri's avatar
dimitri committed
3526
    }
dimitri's avatar
dimitri committed
3527
    //gd->visited=TRUE;
dimitri's avatar
dimitri committed
3528 3529 3530
  }
}

dimitri's avatar
dimitri committed
3531
static void writeGroupHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex)
dimitri's avatar
dimitri committed
3532
{
dimitri's avatar
dimitri committed
3533 3534 3535 3536 3537
  if (ftv)
  {
    ol.pushGeneratorState(); 
    ol.disable(OutputGenerator::Html);
  }
dimitri's avatar
dimitri committed
3538
  startIndexHierarchy(ol,0);
dimitri's avatar
dimitri committed
3539
  if (Config_getBool("SORT_GROUP_NAMES"))
dimitri's avatar
dimitri committed
3540
  {
dimitri's avatar
dimitri committed
3541
    Doxygen::groupSDict->sort();
dimitri's avatar
dimitri committed
3542
  }
dimitri's avatar
dimitri committed
3543
  GroupSDict::Iterator gli(*Doxygen::groupSDict);
dimitri's avatar
dimitri committed
3544
  GroupDef *gd;
dimitri's avatar
dimitri committed
3545
  for (gli.toFirst();(gd=gli.current());++gli)
dimitri's avatar
dimitri committed
3546
  {
dimitri's avatar
dimitri committed
3547
    writeGroupTreeNode(ol,gd,0,ftv,addToIndex);
dimitri's avatar
dimitri committed
3548
  }
dimitri's avatar
dimitri committed
3549
  endIndexHierarchy(ol,0); 
dimitri's avatar
dimitri committed
3550
  if (ftv)
dimitri's avatar
dimitri committed
3551
  {
dimitri's avatar
dimitri committed
3552
    ol.popGeneratorState(); 
dimitri's avatar
dimitri committed
3553
  }
dimitri's avatar
dimitri committed
3554 3555
}

dimitri's avatar
dimitri committed
3556 3557
#if 0
static void writeGroupTree(GroupDef *gd,FTVHelp *ftv,int level,bool addToIndex)
dimitri's avatar
dimitri committed
3558
{
dimitri's avatar
dimitri committed
3559 3560 3561 3562 3563 3564 3565 3566
  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
     )
dimitri's avatar
dimitri committed
3567
  {
dimitri's avatar
dimitri committed
3568
    if (ftv)
dimitri's avatar
dimitri committed
3569
    {
dimitri's avatar
dimitri committed
3570 3571
      ftv->addContentsItem(hasSubGroups,gd->groupTitle(),gd->getReference(),gd->getOutputFileBase(),0); 
      ftv->incContentsDepth();
dimitri's avatar
dimitri committed
3572
    }
dimitri's avatar
dimitri committed
3573
    if (ftv)
dimitri's avatar
dimitri committed
3574
    {
dimitri's avatar
dimitri committed
3575
      ftv->decContentsDepth();
dimitri's avatar
dimitri committed
3576 3577 3578 3579
    }
  }
}

dimitri's avatar
dimitri committed
3580
static void writeGroupTree(FTVHelp *ftv,bool addToIndex)
dimitri's avatar
dimitri committed
3581
{
dimitri's avatar
dimitri committed
3582 3583 3584
  GroupSDict::Iterator gli(*Doxygen::groupSDict);
  GroupDef *gd;
  for (gli.toFirst();(gd=gli.current());++gli)
dimitri's avatar
dimitri committed
3585
  {
dimitri's avatar
dimitri committed
3586
    writeGroupTree(gd,ftv,0,addToIndex);
dimitri's avatar
dimitri committed
3587
  }
dimitri's avatar
dimitri committed
3588
}
dimitri's avatar
dimitri committed
3589
#endif
dimitri's avatar
dimitri committed
3590

mueller's avatar
mueller committed
3591 3592
//----------------------------------------------------------------------------

dimitri's avatar
dimitri committed
3593
static void writeGroupIndex(OutputList &ol)
mueller's avatar
mueller committed
3594 3595
{
  if (documentedGroups==0) return; 
dimitri's avatar
dimitri committed
3596
  ol.pushGeneratorState(); 
dimitri's avatar
dimitri committed
3597
  // 1.{
mueller's avatar
mueller committed
3598
  ol.disable(OutputGenerator::Man);
dimitri's avatar
dimitri committed
3599
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Modules);
dimitri's avatar
dimitri committed
3600
  QCString title = lne ? lne->title() : theTranslator->trModules();
dimitri's avatar
dimitri committed
3601 3602
  bool addToIndex = lne==0 || lne->visible();

dimitri's avatar
dimitri committed
3603
  startFile(ol,"modules",0,title,HLI_Modules);
mueller's avatar
mueller committed
3604
  startTitle(ol,0);
dimitri's avatar
dimitri committed
3605
  ol.parseText(title);
mueller's avatar
mueller committed
3606
  endTitle(ol,0,0);
dimitri's avatar
dimitri committed
3607
  ol.startContents();
dimitri's avatar
dimitri committed
3608
  ol.startTextBlock();
dimitri's avatar
dimitri committed
3609
  ol.parseText(lne ? lne->intro() : theTranslator->trModulesDescription());
dimitri's avatar
dimitri committed
3610
  ol.endTextBlock();
dimitri's avatar
dimitri committed
3611

dimitri's avatar
dimitri committed
3612 3613 3614 3615 3616 3617
  // ---------------
  // Normal group index for Latex/RTF
  // ---------------
  // 2.{
  ol.pushGeneratorState();
  ol.disable(OutputGenerator::Html);
dimitri's avatar
dimitri committed
3618

dimitri's avatar
dimitri committed
3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629
  writeGroupHierarchy(ol,0,FALSE);

  ol.popGeneratorState();
  // 2.}

  // ---------------
  // interactive group index for HTML
  // ---------------
  // 2.{
  ol.pushGeneratorState(); 
  ol.disableAllBut(OutputGenerator::Html);
dimitri's avatar
dimitri committed
3630 3631

  {
dimitri's avatar
dimitri committed
3632 3633 3634 3635 3636 3637 3638
    if (addToIndex)
    {
      Doxygen::indexList.addContentsItem(TRUE,title,0,"modules",0,TRUE,TRUE); 
      Doxygen::indexList.incContentsDepth();
    }
    FTVHelp* ftv = new FTVHelp(FALSE);
    writeGroupHierarchy(ol,ftv,addToIndex);
dimitri's avatar
dimitri committed
3639 3640 3641
    QGString outStr;
    FTextStream t(&outStr);
    ftv->generateTreeViewInline(t);
dimitri's avatar
dimitri committed
3642
    ol.disableAllBut(OutputGenerator::Html);
dimitri's avatar
dimitri committed
3643
    ol.writeString(outStr);
dimitri's avatar
dimitri committed
3644
    delete ftv;
dimitri's avatar
dimitri committed
3645 3646 3647 3648
    if (addToIndex)
    {
      Doxygen::indexList.decContentsDepth();
    }
dimitri's avatar
dimitri committed
3649
  }
dimitri's avatar
dimitri committed
3650 3651 3652
  ol.popGeneratorState();
  // 2.}

mueller's avatar
mueller committed
3653
  endFile(ol);
dimitri's avatar
dimitri committed
3654
  ol.popGeneratorState();
dimitri's avatar
dimitri committed
3655
  // 1.}
mueller's avatar
mueller committed
3656 3657
}

dimitri's avatar
dimitri committed
3658 3659
//----------------------------------------------------------------------------

dimitri's avatar
dimitri committed
3660
#if 0
dimitri's avatar
dimitri committed
3661
static void writeDirIndex(OutputList &ol)
dimitri's avatar
dimitri committed
3662 3663 3664 3665
{
  if (documentedDirs==0) return; 
  ol.pushGeneratorState(); 
  ol.disable(OutputGenerator::Man);
dimitri's avatar
dimitri committed
3666
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Dirs);
dimitri's avatar
dimitri committed
3667
  QCString title = lne ? lne->title() : theTranslator->trDirectories();
dimitri's avatar
dimitri committed
3668
  bool addToIndex=FALSE; //lne==0 || lne->visible();
dimitri's avatar
dimitri committed
3669

dimitri's avatar
dimitri committed
3670
  startFile(ol,"dirs",0,title,HLI_Directories);
dimitri's avatar
dimitri committed
3671 3672 3673
  startTitle(ol,0);
  ol.parseText(title);
  endTitle(ol,0,0);
dimitri's avatar
dimitri committed
3674
  ol.startContents();
dimitri's avatar
dimitri committed
3675
  ol.startTextBlock();
dimitri's avatar
dimitri committed
3676 3677 3678 3679 3680 3681

  if (addToIndex)
  {
    Doxygen::indexList.addContentsItem(TRUE,title,0,"dirs",0,TRUE,TRUE); 
    Doxygen::indexList.incContentsDepth();
  }
dimitri's avatar
dimitri committed
3682
  ol.parseText(lne ? lne->intro() : theTranslator->trDirDescription());
dimitri's avatar
dimitri committed
3683 3684
  ol.endTextBlock();

dimitri's avatar
dimitri committed
3685 3686 3687
  FTVHelp* ftv = 0;
  bool treeView=Config_getBool("USE_INLINE_TREES");
  if (treeView)
dimitri's avatar
dimitri committed
3688 3689 3690
  {
    ftv = new FTVHelp(FALSE);
  }
dimitri's avatar
dimitri committed
3691

dimitri's avatar
dimitri committed
3692
  writeDirHierarchy(ol,ftv,addToIndex);
dimitri's avatar
dimitri committed
3693 3694 3695

  if (ftv)
  {
dimitri's avatar
dimitri committed
3696 3697 3698
    QGString outStr;
    FTextStream t(&outStr);
    ftv->generateTreeViewInline(t);
dimitri's avatar
dimitri committed
3699 3700
    ol.pushGeneratorState(); 
    ol.disableAllBut(OutputGenerator::Html);
dimitri's avatar
dimitri committed
3701
    ol.writeString(outStr);
dimitri's avatar
dimitri committed
3702 3703 3704
    ol.popGeneratorState();
    delete ftv;
  }
dimitri's avatar
dimitri committed
3705 3706 3707 3708 3709 3710 3711
  if (addToIndex)
  {
    Doxygen::indexList.decContentsDepth();
  }
  endFile(ol);
  ol.popGeneratorState();
}
dimitri's avatar
dimitri committed
3712
#endif
dimitri's avatar
dimitri committed
3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743

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

static void writeUserGroupStubPage(OutputList &ol,LayoutNavEntry *lne)
{
  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);
  QListIterator<LayoutNavEntry> li(lne->children());
  LayoutNavEntry *entry;
  int count=0;
  for (li.toFirst();(entry=li.current());++li)
  {
    if (entry->visible()) count++;
  }
  if (count>0)
  {
    ol.writeString("<ul>\n");
    for (li.toFirst();(entry=li.current());++li)
    {
      if (entry->visible())
      {
        ol.writeString("<li><a href=\""+entry->url()+"\"><span>"+
            fixSpaces(entry->title())+"</span></a></li>\n");
      }
    }
    ol.writeString("</ul>\n");
  }
dimitri's avatar
dimitri committed
3744 3745 3746 3747 3748 3749
  endFile(ol);
  ol.popGeneratorState();
}

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

dimitri's avatar
dimitri committed
3750 3751 3752 3753 3754 3755 3756 3757 3758 3759
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's avatar
dimitri committed
3760
static void writeIndex(OutputList &ol)
mueller's avatar
mueller committed
3761
{
dimitri's avatar
dimitri committed
3762 3763
  static bool fortranOpt = Config_getBool("OPTIMIZE_FOR_FORTRAN");
  static bool vhdlOpt    = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
mueller's avatar
mueller committed
3764
  // save old generator state
dimitri's avatar
dimitri committed
3765
  ol.pushGeneratorState();
mueller's avatar
mueller committed
3766

mueller's avatar
mueller committed
3767
  QCString projPrefix;
dimitri's avatar
dimitri committed
3768
  if (!Config_getString("PROJECT_NAME").isEmpty())
mueller's avatar
mueller committed
3769
  {
dimitri's avatar
dimitri committed
3770
    projPrefix=Config_getString("PROJECT_NAME")+" ";
mueller's avatar
mueller committed
3771
  }
dimitri's avatar
dimitri committed
3772 3773

  //--------------------------------------------------------------------
mueller's avatar
mueller committed
3774
  // write HTML index
dimitri's avatar
dimitri committed
3775
  //--------------------------------------------------------------------
dimitri's avatar
dimitri committed
3776
  ol.disableAllBut(OutputGenerator::Html);
mueller's avatar
mueller committed
3777

dimitri's avatar
dimitri committed
3778
  QCString defFileName = 
dimitri's avatar
dimitri committed
3779
    Doxygen::mainPage ? Doxygen::mainPage->docFile().data() : "[generated]";
dimitri's avatar
dimitri committed
3780
  int defLine =
dimitri's avatar
dimitri committed
3781
    Doxygen::mainPage ? Doxygen::mainPage->docLine() : -1;
dimitri's avatar
dimitri committed
3782

dimitri's avatar
dimitri committed
3783
  QCString title;
dimitri's avatar
dimitri committed
3784
  if (!mainPageHasTitle())
dimitri's avatar
dimitri committed
3785
  {
dimitri's avatar
dimitri committed
3786
    title = theTranslator->trMainPage();
dimitri's avatar
dimitri committed
3787
  }
dimitri's avatar
dimitri committed
3788
  else 
dimitri's avatar
dimitri committed
3789
  {
dimitri's avatar
dimitri committed
3790
    title = filterTitle(Doxygen::mainPage->title());
dimitri's avatar
dimitri committed
3791 3792
  }

dimitri's avatar
dimitri committed
3793
  QCString indexName="index";
dimitri's avatar
dimitri committed
3794
  ol.startFile(indexName,0,title);
dimitri's avatar
dimitri committed
3795
  
dimitri's avatar
dimitri committed
3796
  if (Doxygen::mainPage)
dimitri's avatar
dimitri committed
3797
  {
dimitri's avatar
dimitri committed
3798 3799 3800 3801 3802 3803
    if (Doxygen::mainPage->hasSubPages() || 
        (!Config_getString("PROJECT_NAME").isEmpty() && mainPageHasTitle())
       ) // to avoid duplicate entries in the treeview
    {
      Doxygen::indexList.addContentsItem(Doxygen::mainPage->hasSubPages(),title,0,indexName,0,Doxygen::mainPage->hasSubPages(),TRUE); 
    }
dimitri's avatar
dimitri committed
3804 3805 3806 3807
    if (Doxygen::mainPage->hasSubPages())
    {
      writeSubPages(Doxygen::mainPage);
    }
dimitri's avatar
dimitri committed
3808
  }
mueller's avatar
mueller committed
3809

dimitri's avatar
dimitri committed
3810
  ol.startQuickIndices();
dimitri's avatar
dimitri committed
3811 3812
  if (!Config_getBool("DISABLE_INDEX")) 
  {
dimitri's avatar
dimitri committed
3813
    ol.writeQuickLinks(TRUE,HLI_Main,0);
dimitri's avatar
dimitri committed
3814 3815
  }
  ol.endQuickIndices();
dimitri's avatar
dimitri committed
3816 3817
  ol.writeSplitBar(indexName);
  ol.writeSearchInfo();
dimitri's avatar
dimitri committed
3818
  bool headerWritten=FALSE;
dimitri's avatar
dimitri committed
3819
  if (Doxygen::mainPage && !Doxygen::mainPage->title().isEmpty())
mueller's avatar
mueller committed
3820
  {
dimitri's avatar
dimitri committed
3821 3822
    if (Doxygen::mainPage->title().lower()!="notitle")
    {
dimitri's avatar
dimitri committed
3823 3824
      ol.startHeaderSection();
      ol.startTitleHead(0);
dimitri's avatar
dimitri committed
3825 3826 3827
      ol.parseDoc(Doxygen::mainPage->docFile(),Doxygen::mainPage->docLine(),
                  Doxygen::mainPage,0,Doxygen::mainPage->title(),
                  TRUE,FALSE,0,TRUE,FALSE);
dimitri's avatar
dimitri committed
3828
      headerWritten = TRUE;
dimitri's avatar
dimitri committed
3829
    }
mueller's avatar
mueller committed
3830 3831 3832
  }
  else
  {
dimitri's avatar
dimitri committed
3833 3834
    if (!Config_getString("PROJECT_NAME").isEmpty())
    {
dimitri's avatar
dimitri committed
3835 3836
      ol.startHeaderSection();
      ol.startTitleHead(0);
dimitri's avatar
dimitri committed
3837
      ol.parseText(projPrefix+theTranslator->trDocumentation());
dimitri's avatar
dimitri committed
3838
      headerWritten = TRUE;
dimitri's avatar
dimitri committed
3839
    }
mueller's avatar
mueller committed
3840
  }
dimitri's avatar
dimitri committed
3841 3842 3843 3844 3845
  if (headerWritten)
  {
    ol.endTitleHead(0,0);
    ol.endHeaderSection();
  }
dimitri's avatar
dimitri committed
3846

dimitri's avatar
dimitri committed
3847
  ol.startContents();
dimitri's avatar
dimitri committed
3848 3849
  if (Config_getBool("DISABLE_INDEX") && Doxygen::mainPage==0) 
  {
dimitri's avatar
dimitri committed
3850
    ol.writeQuickLinks(FALSE,HLI_Main,0);
dimitri's avatar
dimitri committed
3851
  }
mueller's avatar
mueller committed
3852

dimitri's avatar
dimitri committed
3853
  if (Doxygen::mainPage)
mueller's avatar
mueller committed
3854
  {
dimitri's avatar
dimitri committed
3855
    Doxygen::insideMainPage=TRUE;
dimitri's avatar
dimitri committed
3856 3857 3858 3859 3860
    if (Doxygen::mainPage->showToc() && Doxygen::mainPage->hasSections())
    {
      Doxygen::mainPage->writeToc(ol);
    }

dimitri's avatar
dimitri committed
3861
    ol.startTextBlock();
dimitri's avatar
dimitri committed
3862 3863
    ol.parseDoc(defFileName,defLine,Doxygen::mainPage,0,
                Doxygen::mainPage->documentation(),TRUE,FALSE
dimitri's avatar
dimitri committed
3864
                /*,Doxygen::mainPage->sectionDict*/);
dimitri's avatar
dimitri committed
3865
    ol.endTextBlock();
dimitri's avatar
dimitri committed
3866 3867 3868 3869 3870

    if (!Config_getString("GENERATE_TAGFILE").isEmpty())
    {
       Doxygen::tagFile << "  <compound kind=\"page\">" << endl
                        << "    <name>"
dimitri's avatar
dimitri committed
3871
                        << convertToXML(Doxygen::mainPage->name())
dimitri's avatar
dimitri committed
3872 3873 3874 3875 3876 3877 3878
                        << "</name>" << endl
                        << "    <title>"
                        << convertToXML(Doxygen::mainPage->title())
                        << "</title>" << endl
                        << "    <filename>"
                        << convertToXML(Doxygen::mainPage->getOutputFileBase())
                        << "</filename>" << endl;
dimitri's avatar
dimitri committed
3879 3880 3881 3882

       Doxygen::mainPage->writeDocAnchorsToTagFile();
       Doxygen::tagFile << "  </compound>" << endl;
    }
dimitri's avatar
dimitri committed
3883
    Doxygen::insideMainPage=FALSE;
mueller's avatar
mueller committed
3884 3885
  }
  
mueller's avatar
mueller committed
3886 3887 3888
  endFile(ol);
  ol.disable(OutputGenerator::Html);
  
dimitri's avatar
dimitri committed
3889
  //--------------------------------------------------------------------
dimitri's avatar
dimitri committed
3890
  // write LaTeX/RTF index
dimitri's avatar
dimitri committed
3891
  //--------------------------------------------------------------------
mueller's avatar
mueller committed
3892
  ol.enable(OutputGenerator::Latex);
dimitri's avatar
dimitri committed
3893 3894
  ol.enable(OutputGenerator::RTF);

dimitri's avatar
dimitri committed
3895
  ol.startFile("refman",0,0);
mueller's avatar
mueller committed
3896
  ol.startIndexSection(isTitlePageStart);
dimitri's avatar
dimitri committed
3897
  if (!Config_getString("LATEX_HEADER").isEmpty()) 
dimitri's avatar
dimitri committed
3898 3899 3900 3901
  {
    ol.disable(OutputGenerator::Latex);
  }

dimitri's avatar
dimitri committed
3902 3903 3904 3905 3906 3907 3908 3909 3910
  if (projPrefix.isEmpty())
  {
    ol.parseText(theTranslator->trReferenceManual());
  }
  else
  {
    ol.parseText(projPrefix);
  }

dimitri's avatar
dimitri committed
3911
  if (!Config_getString("PROJECT_NUMBER").isEmpty())
mueller's avatar
mueller committed
3912
  {
dimitri's avatar
dimitri committed
3913
    ol.startProjectNumber(); 
dimitri's avatar
dimitri committed
3914
    ol.parseDoc(defFileName,defLine,Doxygen::mainPage,0,Config_getString("PROJECT_NUMBER"),FALSE,FALSE);
dimitri's avatar
dimitri committed
3915 3916 3917 3918
    ol.endProjectNumber();
  }
  ol.endIndexSection(isTitlePageStart);
  ol.startIndexSection(isTitlePageAuthor);
dimitri's avatar
dimitri committed
3919
  ol.parseText(theTranslator->trGeneratedBy());
dimitri's avatar
dimitri committed
3920
  ol.endIndexSection(isTitlePageAuthor);
dimitri's avatar
dimitri committed
3921 3922
  ol.enable(OutputGenerator::Latex);

dimitri's avatar
dimitri committed
3923
  ol.lastIndexPage();
dimitri's avatar
dimitri committed
3924
  if (Doxygen::mainPage)
dimitri's avatar
dimitri committed
3925 3926
  {
    ol.startIndexSection(isMainPage);
dimitri's avatar
dimitri committed
3927
    if (mainPageHasTitle())
mueller's avatar
mueller committed
3928
    {
dimitri's avatar
dimitri committed
3929
      ol.parseText(Doxygen::mainPage->title());
mueller's avatar
mueller committed
3930
    }
dimitri's avatar
dimitri committed
3931
    else
mueller's avatar
mueller committed
3932
    {
dimitri's avatar
dimitri committed
3933
      ol.parseText(/*projPrefix+*/theTranslator->trMainPage());
mueller's avatar
mueller committed
3934
    }
dimitri's avatar
dimitri committed
3935
    ol.endIndexSection(isMainPage);
mueller's avatar
mueller committed
3936
  }
dimitri's avatar
dimitri committed
3937 3938 3939 3940 3941 3942 3943 3944 3945
  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)
    {
dimitri's avatar
dimitri committed
3946
      if (!pd->getGroupDef() && !pd->isReference() && 
dimitri's avatar
dimitri committed
3947 3948
          (!pd->hasParentPage() ||                    // not inside other page
           (Doxygen::mainPage==pd->getOuterScope()))  // or inside main page
dimitri's avatar
dimitri committed
3949
         )
dimitri's avatar
dimitri committed
3950
      {
dimitri's avatar
dimitri committed
3951 3952 3953 3954 3955 3956 3957
        bool isCitationPage = pd->name()=="citelist";
        if (isCitationPage)
        {
          // For LaTeX the bibliograph is already written by \bibliography
          ol.pushGeneratorState();
          ol.disable(OutputGenerator::Latex);
        }
dimitri's avatar
dimitri committed
3958 3959 3960 3961 3962
        QCString title = pd->title();
        if (title.isEmpty()) title=pd->name();
        ol.startIndexSection(isPageDocumentation);
        ol.parseText(title);
        ol.endIndexSection(isPageDocumentation);
dimitri's avatar
dimitri committed
3963 3964 3965 3966 3967 3968 3969
        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());
dimitri's avatar
dimitri committed
3970 3971 3972

        ol.writePageLink(pd->getOutputFileBase(),first);
        first=FALSE;
dimitri's avatar
dimitri committed
3973 3974 3975 3976 3977

        if (isCitationPage)
        {
          ol.popGeneratorState();
        }
dimitri's avatar
dimitri committed
3978 3979 3980
      }
    }
  }
dimitri's avatar
dimitri committed
3981

dimitri's avatar
dimitri committed
3982
  if (!Config_getBool("LATEX_HIDE_INDICES"))
dimitri's avatar
dimitri committed
3983
  {
dimitri's avatar
dimitri committed
3984 3985 3986 3987 3988 3989
    //if (indexedPages>0)
    //{
    //  ol.startIndexSection(isPageIndex);
    //  ol.parseText(/*projPrefix+*/ theTranslator->trPageIndex());
    //  ol.endIndexSection(isPageIndex);
    //}
dimitri's avatar
dimitri committed
3990 3991 3992
    if (documentedGroups>0)
    {
      ol.startIndexSection(isModuleIndex);
dimitri's avatar
dimitri committed
3993
      ol.parseText(/*projPrefix+*/ theTranslator->trModuleIndex());
dimitri's avatar
dimitri committed
3994 3995 3996 3997 3998
      ol.endIndexSection(isModuleIndex);
    }
    if (documentedNamespaces>0)
    {
      ol.startIndexSection(isNamespaceIndex);
dimitri's avatar
dimitri committed
3999
      ol.parseText(/*projPrefix+*/(fortranOpt?theTranslator->trModulesIndex():theTranslator->trNamespaceIndex()));
dimitri's avatar
dimitri committed
4000 4001 4002 4003 4004
      ol.endIndexSection(isNamespaceIndex);
    }
    if (hierarchyClasses>0)
    {
      ol.startIndexSection(isClassHierarchyIndex);
dimitri's avatar
dimitri committed
4005 4006
      ol.parseText(/*projPrefix+*/
          (fortranOpt ? theTranslator->trCompoundIndexFortran() : 
dimitri's avatar
dimitri committed
4007
           vhdlOpt    ? VhdlDocGen::trDesignUnitIndex()         :
dimitri's avatar
dimitri committed
4008 4009
                        theTranslator->trCompoundIndex()
          ));
dimitri's avatar
dimitri committed
4010 4011
      ol.endIndexSection(isClassHierarchyIndex);
    }
dimitri's avatar
dimitri committed
4012
    if (annotatedClassesPrinted>0)
dimitri's avatar
dimitri committed
4013 4014
    {
      ol.startIndexSection(isCompoundIndex);
dimitri's avatar
dimitri committed
4015
      ol.parseText(/*projPrefix+*/
dimitri's avatar
dimitri committed
4016
          (fortranOpt ? theTranslator->trCompoundIndexFortran() :
dimitri's avatar
dimitri committed
4017 4018
              vhdlOpt ? VhdlDocGen::trDesignUnitIndex()         : 
                        theTranslator->trCompoundIndex()
dimitri's avatar
dimitri committed
4019
          ));
dimitri's avatar
dimitri committed
4020 4021 4022 4023 4024
      ol.endIndexSection(isCompoundIndex);
    }
    if (documentedFiles>0)
    {
      ol.startIndexSection(isFileIndex);
dimitri's avatar
dimitri committed
4025
      ol.parseText(/*projPrefix+*/theTranslator->trFileIndex());
dimitri's avatar
dimitri committed
4026 4027
      ol.endIndexSection(isFileIndex);
    }
dimitri's avatar
dimitri committed
4028
  }
mueller's avatar
mueller committed
4029 4030 4031
  if (documentedGroups>0)
  {
    ol.startIndexSection(isModuleDocumentation);
dimitri's avatar
dimitri committed
4032
    ol.parseText(/*projPrefix+*/theTranslator->trModuleDocumentation());
mueller's avatar
mueller committed
4033 4034
    ol.endIndexSection(isModuleDocumentation);
  }
mueller's avatar
mueller committed
4035 4036 4037
  if (documentedNamespaces>0)
  {
    ol.startIndexSection(isNamespaceDocumentation);
dimitri's avatar
dimitri committed
4038
    ol.parseText(/*projPrefix+*/(fortranOpt?theTranslator->trModuleDocumentation():theTranslator->trNamespaceDocumentation()));
mueller's avatar
mueller committed
4039 4040
    ol.endIndexSection(isNamespaceDocumentation);
  }
dimitri's avatar
dimitri committed
4041
  if (annotatedClassesPrinted>0)
mueller's avatar
mueller committed
4042 4043
  {
    ol.startIndexSection(isClassDocumentation);
dimitri's avatar
dimitri committed
4044
    ol.parseText(/*projPrefix+*/(fortranOpt?theTranslator->trTypeDocumentation():theTranslator->trClassDocumentation()));
mueller's avatar
mueller committed
4045 4046 4047 4048 4049
    ol.endIndexSection(isClassDocumentation);
  }
  if (documentedFiles>0)
  {
    ol.startIndexSection(isFileDocumentation);
dimitri's avatar
dimitri committed
4050
    ol.parseText(/*projPrefix+*/theTranslator->trFileDocumentation());
mueller's avatar
mueller committed
4051 4052
    ol.endIndexSection(isFileDocumentation);
  }
dimitri's avatar
dimitri committed
4053
  if (Doxygen::exampleSDict->count()>0)
mueller's avatar
mueller committed
4054 4055
  {
    ol.startIndexSection(isExampleDocumentation);
dimitri's avatar
dimitri committed
4056
    ol.parseText(/*projPrefix+*/theTranslator->trExampleDocumentation());
mueller's avatar
mueller committed
4057 4058 4059 4060 4061
    ol.endIndexSection(isExampleDocumentation);
  }
  ol.endIndexSection(isEndIndex);
  endFile(ol);

dimitri's avatar
dimitri committed
4062
  if (Doxygen::mainPage)
mueller's avatar
mueller committed
4063
  {
dimitri's avatar
dimitri committed
4064
    Doxygen::insideMainPage=TRUE;
mueller's avatar
mueller committed
4065
    ol.disable(OutputGenerator::Man);
dimitri's avatar
dimitri committed
4066
    startFile(ol,Doxygen::mainPage->name(),0,Doxygen::mainPage->title());
dimitri's avatar
dimitri committed
4067
    ol.startContents();
dimitri's avatar
dimitri committed
4068
    ol.startTextBlock();
dimitri's avatar
dimitri committed
4069 4070
    ol.parseDoc(defFileName,defLine,Doxygen::mainPage,0,
                Doxygen::mainPage->documentation(),FALSE,FALSE
dimitri's avatar
dimitri committed
4071
               );
dimitri's avatar
dimitri committed
4072
    ol.endTextBlock();
mueller's avatar
mueller committed
4073 4074
    endFile(ol);
    ol.enable(OutputGenerator::Man);
dimitri's avatar
dimitri committed
4075
    Doxygen::insideMainPage=FALSE;
mueller's avatar
mueller committed
4076 4077
  }

dimitri's avatar
dimitri committed
4078
  ol.popGeneratorState();
mueller's avatar
mueller committed
4079
}
dimitri's avatar
dimitri committed
4080

dimitri's avatar
dimitri committed
4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099
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());
dimitri's avatar
dimitri committed
4100
    bool addToIndex=lne==0 || lne->visible();
dimitri's avatar
dimitri committed
4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119
    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: 
          {
dimitri's avatar
dimitri committed
4120 4121
            static bool showNamespaces = Config_getBool("SHOW_NAMESPACES");
            if (showNamespaces)
dimitri's avatar
dimitri committed
4122
            {
dimitri's avatar
dimitri committed
4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133
              if (documentedNamespaces>0 && addToIndex)
              {
                Doxygen::indexList.addContentsItem(TRUE,lne->title(),0,0,0); 
                Doxygen::indexList.incContentsDepth();
                needsClosing=TRUE;
              }
              if (LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Namespaces)!=lne) // for backward compatibility with old layout file
              {
                msg("Generating namespace index...\n");
                writeNamespaceIndex(ol);
              }
dimitri's avatar
dimitri committed
4134
            }
dimitri's avatar
dimitri committed
4135 4136 4137 4138 4139 4140
          }
          break;
        case LayoutNavEntry::NamespaceList: 
          {
            static bool showNamespaces = Config_getBool("SHOW_NAMESPACES");
            if (showNamespaces)
dimitri's avatar
dimitri committed
4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151
            {
              msg("Generating namespace index...\n");
              writeNamespaceIndex(ol);
            }
          }
          break;
        case LayoutNavEntry::NamespaceMembers: 
          msg("Generating namespace member index...\n");
          writeNamespaceMemberIndex(ol);
          break;
        case LayoutNavEntry::Classes: 
dimitri's avatar
dimitri committed
4152
          if (annotatedClasses>0 && addToIndex)
dimitri's avatar
dimitri committed
4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186
          {
            Doxygen::indexList.addContentsItem(TRUE,lne->title(),0,0,0); 
            Doxygen::indexList.incContentsDepth();
            needsClosing=TRUE;
          }
          if (LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Classes)!=lne) // for backward compatibility with old layout file
          {
            msg("Generating annotated compound index...\n");
            writeAnnotatedIndex(ol);
          }
          break;
        case LayoutNavEntry::ClassList: 
          msg("Generating annotated compound index...\n");
          writeAnnotatedIndex(ol);
          break;
        case LayoutNavEntry::ClassIndex:
          msg("Generating alphabetical compound index...\n");
          writeAlphabeticalIndex(ol);
          break;
        case LayoutNavEntry::ClassHierarchy: 
          msg("Generating hierarchical class index...\n");
          writeHierarchicalIndex(ol);
          if (Config_getBool("HAVE_DOT") && Config_getBool("GRAPHICAL_HIERARCHY"))
          {
            msg("Generating graphical class hierarchy...\n");
            writeGraphicalClassHierarchy(ol);
          }
          break;
        case LayoutNavEntry::ClassMembers: 
          msg("Generating member index...\n");
          writeClassMemberIndex(ol);
          break;
        case LayoutNavEntry::Files: 
          {
dimitri's avatar
dimitri committed
4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201
            static bool showFiles = Config_getBool("SHOW_FILES");
            if (showFiles)
            {
              if (documentedHtmlFiles>0 && addToIndex)
              {
                Doxygen::indexList.addContentsItem(TRUE,lne->title(),0,0,0); 
                Doxygen::indexList.incContentsDepth();
                needsClosing=TRUE;
              }
              if (LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Files)!=lne) // for backward compatibility with old layout file
              {
                msg("Generating file index...\n");
                writeFileIndex(ol);
              }
            }
dimitri's avatar
dimitri committed
4202 4203 4204
          }
          break;
        case LayoutNavEntry::FileList: 
dimitri's avatar
dimitri committed
4205 4206 4207 4208 4209 4210 4211 4212
          {
            static bool showFiles = Config_getBool("SHOW_FILES");
            if (showFiles)
            {
              msg("Generating file index...\n");
              writeFileIndex(ol);
            }
          }
dimitri's avatar
dimitri committed
4213 4214 4215 4216 4217 4218 4219 4220 4221 4222
          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: 
dimitri's avatar
dimitri committed
4223 4224 4225 4226 4227 4228 4229 4230 4231 4232
          {
            // prepend a ! or ^ marker to the URL to avoid tampering with it
            QCString url = correctURL(lne->url(),"!"); // add ! to relative URL
            if (!url.isEmpty() && url.at(0)!='!') // 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); 
          }
dimitri's avatar
dimitri committed
4233
          break;
dimitri's avatar
dimitri committed
4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246
        case LayoutNavEntry::UserGroup:
          if (addToIndex)
          {
            Doxygen::indexList.addContentsItem(TRUE,lne->title(),0,lne->baseFile(),0,TRUE,TRUE); 
            Doxygen::indexList.incContentsDepth();
            needsClosing=TRUE;
          }
          writeUserGroupStubPage(ol,lne);
          break;
      }
      if (kind!=LayoutNavEntry::User && kind!=LayoutNavEntry::UserGroup) // User entry may appear multiple times
      {
        indexWritten.at(index)=TRUE;
dimitri's avatar
dimitri committed
4247 4248 4249 4250 4251 4252 4253 4254 4255 4256
      }
    }
    writeIndexHierarchyEntries(ol,lne->children());
    if (needsClosing)
    {
      switch(kind)
      {
        case LayoutNavEntry::Namespaces: 
        case LayoutNavEntry::Classes: 
        case LayoutNavEntry::Files: 
dimitri's avatar
dimitri committed
4257
        case LayoutNavEntry::UserGroup: 
dimitri's avatar
dimitri committed
4258 4259 4260 4261 4262 4263 4264 4265 4266
          Doxygen::indexList.decContentsDepth();
          break;
        default:
          break;
      }
    }
    //printf("ending %s kind=%d\n",lne->title().data(),lne->kind());
  }
}
dimitri's avatar
dimitri committed
4267

dimitri's avatar
dimitri committed
4268 4269 4270 4271 4272 4273 4274 4275
void writeIndexHierarchy(OutputList &ol)
{
  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry();
  if (lne)
  {
    writeIndexHierarchyEntries(ol,lne->children());
  }
}
dimitri's avatar
dimitri committed
4276