My Project
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
index.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  *
4  *
5  * Copyright (C) 1997-2015 by Dimitri van Heesch.
6  *
7  * Permission to use, copy, modify, and distribute this software and its
8  * documentation under the terms of the GNU General Public License is hereby
9  * granted. No representations are made about the suitability of this software
10  * for any purpose. It is provided "as is" without express or implied warranty.
11  * See the GNU General Public License for more details.
12  *
13  * Documents produced by Doxygen are derivative works derived from the
14  * input used in their production; they are not affected by this license.
15  *
16  */
17 
22 #include <stdlib.h>
23 
24 #include <qtextstream.h>
25 #include <qdatetime.h>
26 #include <qdir.h>
27 #include <qregexp.h>
28 
29 #include "message.h"
30 #include "index.h"
31 #include "doxygen.h"
32 #include "config.h"
33 #include "filedef.h"
34 #include "outputlist.h"
35 #include "util.h"
36 #include "groupdef.h"
37 #include "language.h"
38 #include "htmlgen.h"
39 #include "htmlhelp.h"
40 #include "ftvhelp.h"
41 #include "dot.h"
42 #include "pagedef.h"
43 #include "dirdef.h"
44 #include "vhdldocgen.h"
45 #include "layout.h"
46 #include "memberlist.h"
47 #include "classlist.h"
48 #include "namespacedef.h"
49 #include "filename.h"
50 
51 #define MAX_ITEMS_BEFORE_MULTIPAGE_INDEX 200
52 #define MAX_ITEMS_BEFORE_QUICK_INDEX 30
53 
54 
68 
69 static int countClassHierarchy();
70 static void countFiles(int &htmlFiles,int &files);
71 static int countGroups();
72 static int countDirs();
73 static int countNamespaces();
74 static int countAnnotatedClasses(int *cp);
75 static void countRelatedPages(int &docPages,int &indexPages);
76 
78 {
79  annotatedClasses = countAnnotatedClasses(&annotatedClassesPrinted); // "classes" + "annotated"
80  hierarchyClasses = countClassHierarchy(); // "hierarchy"
83  documentedGroups = countGroups(); // "modules"
84  documentedNamespaces = countNamespaces(); // "namespaces"
85  documentedDirs = countDirs(); // "dirs"
86  // "globals"
87  // "namespacemembers"
88  // "functions"
89 }
90 
91 static void startIndexHierarchy(OutputList &ol,int level)
92 {
93  ol.pushGeneratorState();
96  if (level<6) ol.startIndexList();
97  ol.enableAll();
100  ol.startItemList();
101  ol.popGeneratorState();
102 }
103 
104 static void endIndexHierarchy(OutputList &ol,int level)
105 {
106  ol.pushGeneratorState();
109  if (level<6) ol.endIndexList();
110  ol.enableAll();
113  ol.endItemList();
114  ol.popGeneratorState();
115 }
116 
117 //----------------------------------------------------------------------------
118 
119 class MemberIndexList : public QList<MemberDef>
120 {
121  public:
123  MemberIndexList(uint letter) : QList<MemberDef>(), m_letter(letter) {}
125  int compareValues(const MemberDef *md1, const MemberDef *md2) const
126  {
127  int result = qstricmp(md1->name(),md2->name());
128  if (result==0)
129  {
130  result = qstricmp(md1->qualifiedName(),md2->qualifiedName());
131  }
132  return result;
133  }
134  uint letter() const { return m_letter; }
135  private:
136  uint m_letter;
137 };
138 
142 
144 
145 //----------------------------------------------------------------------------
146 
147 //----------------------------------------------------------------------------
148 
149 static void startQuickIndexList(OutputList &ol,bool letterTabs=FALSE)
150 {
151  bool fancyTabs = TRUE;
152  if (fancyTabs)
153  {
154  if (letterTabs)
155  {
156  ol.writeString(" <div id=\"navrow4\" class=\"tabs3\">\n");
157  }
158  else
159  {
160  ol.writeString(" <div id=\"navrow3\" class=\"tabs2\">\n");
161  }
162  ol.writeString(" <ul class=\"tablist\">\n");
163  }
164  else
165  {
166  ol.writeString(" <div class=\"qindex\">");
167  }
168 }
169 
171 {
172  bool fancyTabs = TRUE;
173  if (fancyTabs)
174  {
175  ol.writeString(" </ul>\n");
176  }
177  ol.writeString(" </div>\n");
178 }
179 
180 static void startQuickIndexItem(OutputList &ol,const char *l,
181  bool hl,bool compact,bool &first)
182 {
183  bool fancyTabs = TRUE;
184  if (!first && compact && !fancyTabs) ol.writeString(" | ");
185  first=FALSE;
186  if (fancyTabs)
187  {
188  ol.writeString(" <li");
189  if (hl) ol.writeString(" class=\"current\"");
190  ol.writeString("><a ");
191  }
192  else
193  {
194  if (!compact) ol.writeString("<li>");
195  if (hl && compact)
196  {
197  ol.writeString("<a class=\"qindexHL\" ");
198  }
199  else
200  {
201  ol.writeString("<a class=\"qindex\" ");
202  }
203  }
204  ol.writeString("href=\"");
205  ol.writeString(l);
206  ol.writeString("\">");
207  if (fancyTabs)
208  {
209  ol.writeString("<span>");
210  }
211 }
212 
214 {
215  bool fancyTabs=TRUE;
216  if (fancyTabs) ol.writeString("</span>");
217  ol.writeString("</a>");
218  if (fancyTabs) ol.writeString("</li>\n");
219 }
220 
221 // don't make this static as it is called from a template function and some
222 // old compilers don't support calls to static functions from a template.
223 QCString fixSpaces(const QCString &s)
224 {
225  return substitute(s," ","&#160;");
226 }
227 
228 void startTitle(OutputList &ol,const char *fileName,Definition *def)
229 {
230  ol.startHeaderSection();
231  if (def) def->writeSummaryLinks(ol);
232  ol.startTitleHead(fileName);
233  ol.pushGeneratorState();
235 }
236 
237 void endTitle(OutputList &ol,const char *fileName,const char *name)
238 {
239  ol.popGeneratorState();
240  ol.endTitleHead(fileName,name);
241  ol.endHeaderSection();
242 }
243 
244 void startFile(OutputList &ol,const char *name,const char *manName,
245  const char *title,HighlightedItem hli,bool additionalIndices,
246  const char *altSidebarName)
247 {
248  static bool disableIndex = Config_getBool(DISABLE_INDEX);
249  ol.startFile(name,manName,title);
250  ol.startQuickIndices();
251  if (!disableIndex)
252  {
253  ol.writeQuickLinks(TRUE,hli,name);
254  }
255  if (!additionalIndices)
256  {
257  ol.endQuickIndices();
258  }
259  ol.writeSplitBar(altSidebarName ? altSidebarName : name);
260  ol.writeSearchInfo();
262 }
263 
264 void endFile(OutputList &ol,bool skipNavIndex,bool skipEndContents,
265  const QCString &navPath)
266 {
267  static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
268  ol.pushGeneratorState();
270  if (!skipNavIndex)
271  {
272  if (!skipEndContents) ol.endContents();
273  if (generateTreeView)
274  {
275  ol.writeString("</div><!-- doc-content -->\n");
276  }
277  }
278  ol.writeFooter(navPath); // write the footer
279  ol.popGeneratorState();
280  ol.endFile();
281 }
282 
284 {
285  static bool generateTreeView = Config_getBool(GENERATE_TREEVIEW);
286  QCString navPath;
287  if (generateTreeView)
288  {
289  ol.pushGeneratorState();
291  ol.writeString("</div><!-- doc-content -->\n");
292  ol.popGeneratorState();
293  navPath = d->navigationPathAsString();
294  }
295  endFile(ol,generateTreeView,TRUE,navPath);
296 }
297 
298 //----------------------------------------------------------------------
299 template<class T>
301  const QCString &name,const QCString &anchor,
302  bool addToIndex=TRUE,bool preventSeparateIndex=FALSE)
303 {
304  bool hasMembers = def->getMemberLists().count()>0 || def->getMemberGroupSDict()!=0;
305  Doxygen::indexList->addContentsItem(hasMembers,name,
306  def->getReference(),def->getOutputFileBase(),anchor,
307  hasMembers && !preventSeparateIndex,
308  addToIndex,
309  def);
310  int numClasses=0;
311  ClassSDict *classes = def->getClassSDict();
312  if (classes)
313  {
314  ClassDef *cd;
315  ClassSDict::Iterator it(*classes);
316  for (;(cd=it.current());++it)
317  {
318  if (cd->isLinkable()) numClasses++;
319  }
320  }
321  //printf("addMembersToIndex(def=%s hasMembers=%d numClasses=%d)\n",def->name().data(),hasMembers,numClasses);
322  if (hasMembers || numClasses>0)
323  {
325  QListIterator<LayoutDocEntry> eli(LayoutDocManager::instance().docEntries(part));
326  LayoutDocEntry *lde;
327  for (eli.toFirst();(lde=eli.current());++eli)
328  {
329  if (lde->kind()==LayoutDocEntry::MemberDef)
330  {
332  MemberList *ml = def->getMemberList(lmd->type);
333  if (ml)
334  {
335  MemberListIterator mi(*ml);
336  MemberDef *md;
337  for (mi.toFirst();(md=mi.current());++mi)
338  {
339  MemberList *enumList = md->enumFieldList();
340  bool isDir = enumList!=0 && md->isEnumerate();
341  bool isAnonymous = md->name().find('@')!=-1;
342  static bool hideUndocMembers = Config_getBool(HIDE_UNDOC_MEMBERS);
343  static bool extractStatic = Config_getBool(EXTRACT_STATIC);
344  if (!isAnonymous &&
345  (!hideUndocMembers || md->hasDocumentation()) &&
346  (!md->isStatic() || extractStatic)
347  )
348  {
349  if (md->getOuterScope()==def || md->getOuterScope()==Doxygen::globalScope)
350  {
352  md->name(),md->getReference(),md->getOutputFileBase(),md->anchor(),FALSE,addToIndex);
353  }
354  else // inherited member
355  {
357  md->name(),def->getReference(),def->getOutputFileBase(),md->anchor(),FALSE,addToIndex);
358  }
359  }
360  if (isDir)
361  {
362  if (!isAnonymous)
363  {
365  }
366  MemberListIterator emli(*enumList);
367  MemberDef *emd;
368  for (emli.toFirst();(emd=emli.current());++emli)
369  {
370  if (!hideUndocMembers || emd->hasDocumentation())
371  {
372  if (emd->getOuterScope()==def || emd->getOuterScope()==Doxygen::globalScope)
373  {
375  emd->name(),emd->getReference(),emd->getOutputFileBase(),emd->anchor(),FALSE,addToIndex);
376  }
377  else // inherited member
378  {
380  emd->name(),def->getReference(),def->getOutputFileBase(),emd->anchor(),FALSE,addToIndex);
381  }
382  }
383  }
384  if (!isAnonymous)
385  {
387  }
388  }
389  }
390  }
391  }
392  else if (lde->kind()==LayoutDocEntry::NamespaceClasses ||
395  )
396  {
397  if (classes)
398  {
399  ClassDef *cd;
400  ClassSDict::Iterator it(*classes);
401  for (;(cd=it.current());++it)
402  {
403  if (cd->isLinkable() && (cd->partOfGroups()==0 || def->definitionType()==Definition::TypeGroup))
404  {
405  static bool inlineSimpleStructs = Config_getBool(INLINE_SIMPLE_STRUCTS);
406  bool isNestedClass = def->definitionType()==Definition::TypeClass;
408  addToIndex && (isNestedClass || (cd->isSimple() && inlineSimpleStructs)),
409  preventSeparateIndex || cd->isEmbeddedInOuterScope());
410  }
411  }
412  }
413  }
414  }
415 
417  }
418 }
419 
420 
421 //----------------------------------------------------------------------------
424 static void writeClassTree(OutputList &ol,const BaseClassList *bcl,bool hideSuper,int level,FTVHelp* ftv,bool addToIndex)
425 {
426  if (bcl==0) return;
427  BaseClassListIterator bcli(*bcl);
428  bool started=FALSE;
429  for ( ; bcli.current() ; ++bcli)
430  {
431  ClassDef *cd=bcli.current()->classDef;
433  {
434  continue;
435  }
436 
437  bool b;
438  if (cd->getLanguage()==SrcLangExt_VHDL)
439  {
440  b=hasVisibleRoot(cd->subClasses());
441  }
442  else
443  {
444  b=hasVisibleRoot(cd->baseClasses());
445  }
446 
447  if (cd->isVisibleInHierarchy() && b) // hasVisibleRoot(cd->baseClasses()))
448  {
449  if (!started)
450  {
451  startIndexHierarchy(ol,level);
452  if (addToIndex)
453  {
455  }
456  if (ftv)
457  {
458  ftv->incContentsDepth();
459  }
460  started=TRUE;
461  }
462  ol.startIndexListItem();
463  //printf("Passed...\n");
464  bool hasChildren = !cd->visited && !hideSuper && classHasVisibleChildren(cd);
465  //printf("tree4: Has children %s: %d\n",cd->name().data(),hasChildren);
466  if (cd->isLinkable())
467  {
468  //printf("Writing class %s\n",cd->displayName().data());
470  ol.parseText(cd->displayName());
472  if (cd->isReference())
473  {
474  ol.startTypewriter();
475  ol.docify(" [external]");
476  ol.endTypewriter();
477  }
478  if (addToIndex)
479  {
481  }
482  if (ftv)
483  {
484  if (cd->getLanguage()==SrcLangExt_VHDL)
485  {
486  ftv->addContentsItem(hasChildren,bcli.current()->usedName,cd->getReference(),cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE,cd);
487  }
488  else
489  {
490  ftv->addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE,cd);
491  }
492  }
493  }
494  else
495  {
496  ol.startIndexItem(0,0);
497  ol.parseText(cd->name());
498  ol.endIndexItem(0,0);
499  if (addToIndex)
500  {
501  Doxygen::indexList->addContentsItem(hasChildren,cd->displayName(),0,0,0);
502  }
503  if (ftv)
504  {
505  ftv->addContentsItem(hasChildren,cd->displayName(),0,0,0,FALSE,FALSE,cd);
506  }
507  }
508  if (hasChildren)
509  {
510  //printf("Class %s at %p visited=%d\n",cd->name().data(),cd,cd->visited);
511  bool wasVisited=cd->visited;
512  cd->visited=TRUE;
513  if (cd->getLanguage()==SrcLangExt_VHDL)
514  {
515  writeClassTree(ol,cd->baseClasses(),wasVisited,level+1,ftv,addToIndex);
516  }
517  else
518  {
519  writeClassTree(ol,cd->subClasses(),wasVisited,level+1,ftv,addToIndex);
520  }
521  }
522  ol.endIndexListItem();
523  }
524  }
525  if (started)
526  {
527  endIndexHierarchy(ol,level);
528  if (addToIndex)
529  {
531  }
532  if (ftv)
533  {
534  ftv->decContentsDepth();
535  }
536  }
537 }
538 
539 //----------------------------------------------------------------------------
540 
542 {
543  if (dd->hasDocumentation()) return TRUE;
544 
545  QListIterator<FileDef> fli(*dd->getFiles());
546  FileDef *fd;
547  for (fli.toFirst();(fd=fli.current());++fli)
548  {
549  bool genSourceFile;
550  if (fileVisibleInIndex(fd,genSourceFile))
551  {
552  return TRUE;
553  }
554  if (genSourceFile)
555  {
556  return TRUE;
557  }
558  }
559 
560  QListIterator<DirDef> dli(dd->subDirs());
561  DirDef *subdd;
562  for (dli.toFirst();(subdd=dli.current());++dli)
563  {
564  if (dirHasVisibleChildren(subdd))
565  {
566  return TRUE;
567  }
568  }
569  return FALSE;
570 }
571 
572 //----------------------------------------------------------------------------
573 static void writeDirTreeNode(OutputList &ol, DirDef *dd, int level, FTVHelp* ftv,bool addToIndex)
574 {
575  if (level>20)
576  {
577  warn(dd->getDefFileName(),dd->getDefLine(),
578  "maximum nesting level exceeded for directory %s: "
579  "check for possible recursive directory relation!\n",dd->name().data()
580  );
581  return;
582  }
583 
584  if (!dirHasVisibleChildren(dd))
585  {
586  return;
587  }
588 
589  static bool tocExpand = TRUE; //Config_getBool(TOC_EXPAND);
590  bool isDir = dd->subDirs().count()>0 || // there are subdirs
591  (tocExpand && // or toc expand and
592  dd->getFiles() && dd->getFiles()->count()>0 // there are files
593  );
594  //printf("gd=`%s': pageDict=%d\n",gd->name().data(),gd->pageDict->count());
595  if (addToIndex)
596  {
597  Doxygen::indexList->addContentsItem(isDir,dd->shortName(),dd->getReference(),dd->getOutputFileBase(),0,TRUE,TRUE);
599  }
600  if (ftv)
601  {
602  ftv->addContentsItem(isDir,dd->shortName(),dd->getReference(),
603  dd->getOutputFileBase(),0,FALSE,TRUE,dd);
604  ftv->incContentsDepth();
605  }
606 
607  ol.startIndexListItem();
609  ol.parseText(dd->shortName());
611  if (dd->isReference())
612  {
613  ol.startTypewriter();
614  ol.docify(" [external]");
615  ol.endTypewriter();
616  }
617 
618  // write sub directories
619  if (dd->subDirs().count()>0)
620  {
621  startIndexHierarchy(ol,level+1);
622  QListIterator<DirDef> dli(dd->subDirs());
623  DirDef *subdd = 0;
624  for (dli.toFirst();(subdd=dli.current());++dli)
625  {
626  writeDirTreeNode(ol,subdd,level+1,ftv,addToIndex);
627  }
628  endIndexHierarchy(ol,level+1);
629  }
630 
631  FileList *fileList=dd->getFiles();
632  int fileCount=0;
633  if (fileList && fileList->count()>0)
634  {
635  QListIterator<FileDef> it(*fileList);
636  FileDef *fd;
637  for (;(fd=it.current());++it)
638  {
639  //static bool allExternals = Config_getBool(ALLEXTERNALS);
640  //if ((allExternals && fd->isLinkable()) || fd->isLinkableInProject())
641  //{
642  // fileCount++;
643  //}
644  bool genSourceFile;
645  if (fileVisibleInIndex(fd,genSourceFile))
646  {
647  fileCount++;
648  }
649  else if (genSourceFile)
650  {
651  fileCount++;
652  }
653  }
654  if (fileCount>0)
655  {
656  startIndexHierarchy(ol,level+1);
657  for (it.toFirst();(fd=it.current());++it)
658  {
659  bool doc,src;
660  doc = fileVisibleInIndex(fd,src);
661  QCString reference;
662  QCString outputBase;
663  if (doc)
664  {
665  reference = fd->getReference();
666  outputBase = fd->getOutputFileBase();
667  }
668  if (doc || src)
669  {
670  ol.startIndexListItem();
671  ol.startIndexItem(reference,outputBase);
672  ol.parseText(fd->displayName());
673  ol.endIndexItem(reference,outputBase);
674  ol.endIndexListItem();
675  if (ftv && (src || doc))
676  {
677  ftv->addContentsItem(FALSE,
678  fd->displayName(),
679  reference,outputBase,
680  0,FALSE,FALSE,fd);
681  }
682  }
683  }
684  endIndexHierarchy(ol,level+1);
685  }
686  }
687 
688  if (tocExpand && addToIndex)
689  {
690  // write files of this directory
691  if (fileCount>0)
692  {
693  QListIterator<FileDef> it(*fileList);
694  FileDef *fd;
695  for (;(fd=it.current());++it)
696  {
697  //static bool allExternals = Config_getBool(ALLEXTERNALS);
698  //if ((allExternals && fd->isLinkable()) || fd->isLinkableInProject())
699  bool doc,src;
700  doc = fileVisibleInIndex(fd,src);
701  if (doc)
702  {
703  addMembersToIndex(fd,LayoutDocManager::File,fd->displayName(),QCString(),TRUE);
704  }
705  else if (src)
706  {
708  FALSE, convertToHtml(fd->name(),TRUE), 0,
709  fd->getSourceFileBase(), 0, FALSE, TRUE, fd);
710  }
711  }
712  }
713  }
714  ol.endIndexListItem();
715 
716  if (addToIndex)
717  {
719  }
720  if (ftv)
721  {
722  ftv->decContentsDepth();
723  }
724 }
725 
726 static void writeDirHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex)
727 {
728  if (ftv)
729  {
730  ol.pushGeneratorState();
732  }
733  static bool fullPathNames = Config_getBool(FULL_PATH_NAMES);
734  startIndexHierarchy(ol,0);
735  if (fullPathNames)
736  {
738  DirDef *dd;
739  for (dli.toFirst();(dd=dli.current());++dli)
740  {
742  {
743  writeDirTreeNode(ol,dd,0,ftv,addToIndex);
744  }
745  }
746  }
747  if (ftv)
748  {
750  FileName *fn;
751  for (fnli.toFirst();(fn=fnli.current());++fnli)
752  {
753  FileNameIterator fni(*fn);
754  FileDef *fd;
755  for (;(fd=fni.current());++fni)
756  {
757  static bool fullPathNames = Config_getBool(FULL_PATH_NAMES);
758  if (!fullPathNames || fd->getDirDef()==0) // top level file
759  {
760  bool doc,src;
761  doc = fileVisibleInIndex(fd,src);
762  QCString reference, outputBase;
763  if (doc)
764  {
765  reference = fd->getReference();
766  outputBase = fd->getOutputFileBase();
767  }
768  if (doc || src)
769  {
770  ftv->addContentsItem(FALSE,fd->displayName(),
771  reference, outputBase, 0,
772  FALSE,FALSE,fd);
773  }
774  if (addToIndex)
775  {
776  if (doc)
777  {
778  addMembersToIndex(fd,LayoutDocManager::File,fd->displayName(),QCString(),TRUE);
779  }
780  else if (src)
781  {
783  FALSE, convertToHtml(fd->name(),TRUE), 0,
784  fd->getSourceFileBase(), 0, FALSE, TRUE, fd);
785  }
786  }
787  }
788  }
789  }
790  }
791  endIndexHierarchy(ol,0);
792  if (ftv)
793  {
794  ol.popGeneratorState();
795  }
796 }
797 
798 
799 //----------------------------------------------------------------------------
800 
801 static void writeClassTreeForList(OutputList &ol,ClassSDict *cl,bool &started,FTVHelp* ftv,bool addToIndex)
802 {
803  ClassSDict::Iterator cli(*cl);
804  ClassDef *cd;
805  for (;(cd=cli.current());++cli)
806  {
807  //printf("class %s hasVisibleRoot=%d isVisibleInHierarchy=%d\n",
808  // cd->name().data(),
809  // hasVisibleRoot(cd->baseClasses()),
810  // cd->isVisibleInHierarchy()
811  // );
812  bool b;
813  if (cd->getLanguage()==SrcLangExt_VHDL)
814  {
816  {
817  continue;
818  }
819  b=!hasVisibleRoot(cd->subClasses());
820  }
821  else
822  {
823  b=!hasVisibleRoot(cd->baseClasses());
824  }
825 
826  if (b) //filter on root classes
827  {
828  if (cd->isVisibleInHierarchy()) // should it be visible
829  {
830  if (!started)
831  {
832  startIndexHierarchy(ol,0);
833  if (addToIndex)
834  {
836  }
837  started=TRUE;
838  }
839  ol.startIndexListItem();
840  bool hasChildren = !cd->visited && classHasVisibleChildren(cd);
841  //printf("list: Has children %s: %d\n",cd->name().data(),hasChildren);
842  if (cd->isLinkable())
843  {
844  //printf("Writing class %s isLinkable()=%d isLinkableInProject()=%d cd->templateMaster()=%p\n",
845  // cd->displayName().data(),cd->isLinkable(),cd->isLinkableInProject(),cd->templateMaster());
847  ol.parseText(cd->displayName());
849  if (cd->isReference())
850  {
851  ol.startTypewriter();
852  ol.docify(" [external]");
853  ol.endTypewriter();
854  }
855  if (addToIndex)
856  {
857  if (cd->getLanguage()!=SrcLangExt_VHDL) // prevents double insertion in Design Unit List
858  Doxygen::indexList->addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE);
859  }
860  if (ftv)
861  {
862  ftv->addContentsItem(hasChildren,cd->displayName(),cd->getReference(),cd->getOutputFileBase(),cd->anchor(),FALSE,FALSE,cd);
863  }
864  }
865  else
866  {
867  ol.startIndexItem(0,0);
868  ol.parseText(cd->displayName());
869  ol.endIndexItem(0,0);
870  if (addToIndex)
871  {
872  Doxygen::indexList->addContentsItem(hasChildren,cd->displayName(),0,0,0,FALSE,FALSE);
873  }
874  if (ftv)
875  {
876  ftv->addContentsItem(hasChildren,cd->displayName(),0,0,0,FALSE,FALSE,cd);
877  }
878  }
879  if (cd->getLanguage()==SrcLangExt_VHDL && hasChildren)
880  {
881  writeClassTree(ol,cd->baseClasses(),cd->visited,1,ftv,addToIndex);
882  cd->visited=TRUE;
883  }
884  else if (hasChildren)
885  {
886  writeClassTree(ol,cd->subClasses(),cd->visited,1,ftv,addToIndex);
887  cd->visited=TRUE;
888  }
889  ol.endIndexListItem();
890  }
891  }
892  }
893 }
894 
895 static void writeClassHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex)
896 {
899  if (ftv)
900  {
901  ol.pushGeneratorState();
903  }
904  bool started=FALSE;
905  writeClassTreeForList(ol,Doxygen::classSDict,started,ftv,addToIndex);
906  writeClassTreeForList(ol,Doxygen::hiddenClasses,started,ftv,addToIndex);
907  if (started)
908  {
909  endIndexHierarchy(ol,0);
910  if (addToIndex)
911  {
913  }
914  }
915  if (ftv)
916  {
917  ol.popGeneratorState();
918  }
919 }
920 
921 //----------------------------------------------------------------------------
922 
923 static int countClassesInTreeList(const ClassSDict &cl)
924 {
925  int count=0;
926  ClassSDict::Iterator cli(cl);
927  ClassDef *cd;
928  for (;(cd=cli.current());++cli)
929  {
930  if (!hasVisibleRoot(cd->baseClasses())) // filter on root classes
931  {
932  if (cd->isVisibleInHierarchy()) // should it be visible
933  {
934  if (cd->subClasses()) // should have sub classes
935  {
936  count++;
937  }
938  }
939  }
940  }
941  return count;
942 }
943 
945 {
946  int count=0;
951  return count;
952 }
953 
954 //----------------------------------------------------------------------------
955 
957 {
958  if (hierarchyClasses==0) return;
959  ol.pushGeneratorState();
960  //1.{
962 
964  QCString title = lne ? lne->title() : theTranslator->trClassHierarchy();
965  bool addToIndex = lne==0 || lne->visible();
966 
967  startFile(ol,"hierarchy",0, title, HLI_Hierarchy);
968  startTitle(ol,0);
969  ol.parseText(title);
970  endTitle(ol,0,0);
971  ol.startContents();
972  ol.startTextBlock();
973 
974  if (Config_getBool(HAVE_DOT) && Config_getBool(GRAPHICAL_HIERARCHY))
975  {
978  ol.startParagraph();
979  ol.startTextLink("inherits",0);
981  ol.endTextLink();
982  ol.endParagraph();
985  }
987  ol.endTextBlock();
988 
989  // ---------------
990  // Static class hierarchy for Latex/RTF
991  // ---------------
992  ol.pushGeneratorState();
993  //2.{
996 
997  writeClassHierarchy(ol,0,addToIndex);
998 
1000  ol.popGeneratorState();
1001  //2.}
1002 
1003  // ---------------
1004  // Dynamic class hierarchical index for HTML
1005  // ---------------
1006  ol.pushGeneratorState();
1007  //2.{
1009 
1010  {
1011  if (addToIndex)
1012  {
1013  Doxygen::indexList->addContentsItem(TRUE,title,0,"hierarchy",0,TRUE,TRUE);
1014  }
1015  FTVHelp* ftv = new FTVHelp(FALSE);
1016  writeClassHierarchy(ol,ftv,addToIndex);
1017  QGString outStr;
1018  FTextStream t(&outStr);
1019  ftv->generateTreeViewInline(t);
1020  ol.pushGeneratorState();
1022  ol.writeString(outStr);
1023  ol.popGeneratorState();
1024  delete ftv;
1025  }
1026  ol.popGeneratorState();
1027  //2.}
1028  // ------
1029 
1030  endFile(ol);
1031  ol.popGeneratorState();
1032  //1.}
1033 }
1034 
1035 //----------------------------------------------------------------------------
1036 
1038 {
1039  if (hierarchyClasses==0) return;
1042  QCString title = lne ? lne->title() : theTranslator->trClassHierarchy();
1043  startFile(ol,"inherits",0,title,HLI_Hierarchy,FALSE,"hierarchy");
1044  startTitle(ol,0);
1045  ol.parseText(title);
1046  endTitle(ol,0,0);
1047  ol.startContents();
1048  ol.startTextBlock();
1049  ol.startParagraph();
1050  ol.startTextLink("hierarchy",0);
1052  ol.endTextLink();
1053  ol.endParagraph();
1054  ol.endTextBlock();
1057  endFile(ol);
1058  ol.enableAll();
1059 }
1060 
1061 //----------------------------------------------------------------------------
1062 
1063 static void countFiles(int &htmlFiles,int &files)
1064 {
1065  htmlFiles=0;
1066  files=0;
1068  FileName *fn;
1069  for (;(fn=fnli.current());++fnli)
1070  {
1071  FileNameIterator fni(*fn);
1072  FileDef *fd;
1073  for (;(fd=fni.current());++fni)
1074  {
1075  bool doc,src;
1076  doc = fileVisibleInIndex(fd,src);
1077  if (doc || src)
1078  {
1079  htmlFiles++;
1080  }
1081  if (doc)
1082  {
1083  files++;
1084  }
1085  }
1086  }
1087 }
1088 
1090 {
1091  //printf("Found filedef %s\n",fd->name().data());
1092  bool doc = fd->isLinkableInProject();
1093  bool src = fd->generateSourceFile();
1094  bool nameOk = !fd->isDocumentationFile();
1095  if (nameOk && (doc || src) && !fd->isReference())
1096  {
1097  QCString path;
1098  if (Config_getBool(FULL_PATH_NAMES))
1099  {
1100  path=stripFromPath(fd->getPath().copy());
1101  }
1102  QCString fullName=fd->name();
1103  if (!path.isEmpty())
1104  {
1105  if (path.at(path.length()-1)!='/') fullName.prepend("/");
1106  fullName.prepend(path);
1107  }
1108 
1109  ol.startIndexKey();
1110  ol.docify(path);
1111  if (doc)
1112  {
1113  ol.writeObjectLink(0,fd->getOutputFileBase(),0,fd->name());
1114  //if (addToIndex)
1115  //{
1116  // addMembersToIndex(fd,LayoutDocManager::File,fullName,QCString());
1117  //}
1118  }
1119  else
1120  {
1121  ol.startBold();
1122  ol.docify(fd->name());
1123  ol.endBold();
1124  //if (addToIndex)
1125  //{
1126  // Doxygen::indexList->addContentsItem(FALSE,fullName,0,0,0);
1127  //}
1128  }
1129  if (src)
1130  {
1131  ol.pushGeneratorState();
1133  ol.docify(" ");
1134  ol.startTextLink(fd->includeName(),0);
1135  ol.docify("[");
1137  ol.docify("]");
1138  ol.endTextLink();
1139  ol.popGeneratorState();
1140  }
1141  ol.endIndexKey();
1142  bool hasBrief = !fd->briefDescription().isEmpty();
1143  ol.startIndexValue(hasBrief);
1144  if (hasBrief)
1145  {
1146  //ol.docify(" (");
1147  ol.generateDoc(
1148  fd->briefFile(),fd->briefLine(),
1149  fd,0,
1150  fd->briefDescription(TRUE),
1151  FALSE, // index words
1152  FALSE, // isExample
1153  0, // example name
1154  TRUE, // single line
1155  TRUE // link from index
1156  );
1157  //ol.docify(")");
1158  }
1159  ol.endIndexValue(fd->getOutputFileBase(),hasBrief);
1160  //ol.popGeneratorState();
1161  // --------------------------------------------------------
1162  }
1163 }
1164 
1165 //----------------------------------------------------------------------------
1166 
1167 static void writeFileIndex(OutputList &ol)
1168 {
1169  if (documentedHtmlFiles==0) return;
1170 
1171  ol.pushGeneratorState();
1174 
1176  if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Files); // fall back
1177  QCString title = lne ? lne->title() : theTranslator->trFileList();
1178  bool addToIndex = lne==0 || lne->visible();
1179 
1180  startFile(ol,"files",0,title,HLI_Files);
1181  startTitle(ol,0);
1182  //if (!Config_getString(PROJECT_NAME).isEmpty())
1183  //{
1184  // title.prepend(Config_getString(PROJECT_NAME)+" ");
1185  //}
1186  ol.parseText(title);
1187  endTitle(ol,0,0);
1188  ol.startContents();
1189  ol.startTextBlock();
1190 
1191  if (addToIndex)
1192  {
1193  Doxygen::indexList->addContentsItem(TRUE,title,0,"files",0,TRUE,TRUE);
1195  }
1196 
1197  ol.parseText(lne ? lne->intro() : theTranslator->trFileListDescription(Config_getBool(EXTRACT_ALL)));
1198  ol.endTextBlock();
1199 
1200  // ---------------
1201  // Flat file index
1202  // ---------------
1203 
1204  // 1. {
1205  ol.pushGeneratorState();
1207 
1208  OutputNameDict outputNameDict(1009);
1209  OutputNameList outputNameList;
1210  outputNameList.setAutoDelete(TRUE);
1211 
1212  if (Config_getBool(FULL_PATH_NAMES))
1213  {
1214  // re-sort input files in (dir,file) output order instead of (file,dir) input order
1216  FileName *fn;
1217  for (fnli.toFirst();(fn=fnli.current());++fnli)
1218  {
1219  FileNameIterator fni(*fn);
1220  FileDef *fd;
1221  for (;(fd=fni.current());++fni)
1222  {
1223  QCString path=fd->getPath();
1224  if (path.isEmpty()) path="[external]";
1225  FileList *fl = outputNameDict.find(path);
1226  if (fl)
1227  {
1228  fl->append(fd);
1229  //printf("+ inserting %s---%s\n",fd->getPath().data(),fd->name().data());
1230  }
1231  else
1232  {
1233  //printf("o inserting %s---%s\n",fd->getPath().data(),fd->name().data());
1234  fl = new FileList(path);
1235  fl->append(fd);
1236  outputNameList.append(fl);
1237  outputNameDict.insert(path,fl);
1238  }
1239  }
1240  }
1241  }
1242 
1243  ol.startIndexList();
1244  if (Config_getBool(FULL_PATH_NAMES))
1245  {
1246  outputNameList.sort();
1247  QListIterator<FileList> fnli(outputNameList);
1248  FileList *fl;
1249  for (fnli.toFirst();(fl=fnli.current());++fnli)
1250  {
1251  fl->sort();
1252  QListIterator<FileDef> it(*fl);
1253  FileDef *fd;
1254  for (;(fd=it.current());++it)
1255  {
1256  writeSingleFileIndex(ol,fd);
1257  }
1258  }
1259  }
1260  else
1261  {
1263  FileName *fn;
1264  for (fnli.toFirst();(fn=fnli.current());++fnli)
1265  {
1266  FileNameIterator fni(*fn);
1267  FileDef *fd;
1268  for (;(fd=fni.current());++fni)
1269  {
1270  writeSingleFileIndex(ol,fd);
1271  }
1272  }
1273  }
1274  ol.endIndexList();
1275 
1276  // 1. }
1277  ol.popGeneratorState();
1278 
1279  // ---------------
1280  // Hierarchical file index for HTML
1281  // ---------------
1282  ol.pushGeneratorState();
1284 
1285  FTVHelp* ftv = new FTVHelp(FALSE);
1286  writeDirHierarchy(ol,ftv,addToIndex);
1287  QGString outStr;
1288  FTextStream t(&outStr);
1289  ftv->generateTreeViewInline(t);
1290  ol.writeString(outStr);
1291  delete ftv;
1292 
1293  ol.popGeneratorState();
1294  // ------
1295 
1296  if (addToIndex)
1297  {
1299  }
1300 
1301  endFile(ol);
1302  ol.popGeneratorState();
1303 }
1304 
1305 //----------------------------------------------------------------------------
1306 static int countNamespaces()
1307 {
1308  int count=0;
1310  NamespaceDef *nd;
1311  for (;(nd=nli.current());++nli)
1312  {
1313  if (nd->isLinkableInProject()) count++;
1314  }
1315  return count;
1316 }
1317 
1318 //----------------------------------------------------------------------------
1319 
1320 void writeClassTree(ClassSDict *clDict,FTVHelp *ftv,bool addToIndex,bool globalOnly)
1321 {
1322  if (clDict)
1323  {
1324  ClassSDict::Iterator cli(*clDict);
1325  ClassDef *cd;
1326  for (;(cd=cli.current());++cli)
1327  {
1328  if (cd->getLanguage()==SrcLangExt_VHDL)
1329  {
1332  )// no architecture
1333  {
1334  continue;
1335  }
1337  {
1338  QCString n=cd->name();
1339  cd->setClassName(n.data());
1340  }
1341  }
1342 
1343  if (!globalOnly ||
1344  cd->getOuterScope()==0 ||
1346  )
1347  {
1348  int count=0;
1349  if (cd->getClassSDict())
1350  {
1351  ClassSDict::Iterator ccit(*cd->getClassSDict());
1352  ClassDef *ccd;
1353  for (;(ccd=ccit.current());++ccit)
1354  {
1355  if (ccd->isLinkableInProject() && ccd->templateMaster()==0)
1356  {
1357  count++;
1358  }
1359  }
1360  }
1361  if (classVisibleInIndex(cd) && cd->templateMaster()==0)
1362  {
1363  ftv->addContentsItem(count>0,cd->displayName(FALSE),cd->getReference(),
1364  cd->getOutputFileBase(),cd->anchor(),FALSE,TRUE,cd);
1365  if (addToIndex &&
1366  /*cd->partOfGroups()==0 &&*/
1367  (cd->getOuterScope()==0 ||
1369  )
1370  )
1371  {
1373  cd->displayName(FALSE),
1374  cd->anchor(),
1375  cd->partOfGroups()==0 && !cd->isSimple());
1376  }
1377  if (count>0)
1378  {
1379  ftv->incContentsDepth();
1380  writeClassTree(cd->getClassSDict(),ftv,addToIndex,FALSE);
1381  ftv->decContentsDepth();
1382  }
1383  }
1384  }
1385  }
1386  }
1387 }
1388 
1389 static void writeNamespaceTree(NamespaceSDict *nsDict,FTVHelp *ftv,
1390  bool rootOnly,bool showClasses,bool addToIndex)
1391 {
1392  if (nsDict)
1393  {
1394  NamespaceSDict::Iterator nli(*nsDict);
1395  NamespaceDef *nd;
1396  for (nli.toFirst();(nd=nli.current());++nli)
1397  {
1398  if (nd->localName().find('@')==-1 &&
1399  (!rootOnly || nd->getOuterScope()==Doxygen::globalScope))
1400  {
1401 
1402  bool hasChildren = namespaceHasVisibleChild(nd,showClasses);
1403  bool isLinkable = nd->isLinkableInProject();
1404 
1405  QCString ref;
1406  QCString file;
1407  if (isLinkable)
1408  {
1409  ref = nd->getReference();
1410  file = nd->getOutputFileBase();
1411  if (nd->getLanguage()==SrcLangExt_VHDL) // UGLY HACK
1412  {
1413  file=file.replace(0,qstrlen("namespace"),"class");
1414  }
1415  }
1416 
1417  if ((isLinkable && !showClasses) || hasChildren)
1418  {
1419  ftv->addContentsItem(hasChildren,nd->localName(),ref,file,0,FALSE,TRUE,nd);
1420 
1421  if (addToIndex)
1422  {
1423  Doxygen::indexList->addContentsItem(hasChildren,nd->localName(),ref,file,QCString(),
1424  hasChildren && !file.isEmpty(),addToIndex);
1425  }
1426 
1427  //printf("*** writeNamespaceTree count=%d addToIndex=%d showClasses=%d classCount=%d\n",
1428  // count,addToIndex,showClasses,classCount);
1429  if (hasChildren)
1430  {
1431  if (addToIndex) Doxygen::indexList->incContentsDepth();
1432  ftv->incContentsDepth();
1433  writeNamespaceTree(nd->getNamespaceSDict(),ftv,FALSE,showClasses,addToIndex);
1434  if (showClasses)
1435  {
1436  writeClassTree(nd->getClassSDict(),ftv,addToIndex,FALSE);
1437  }
1438  ftv->decContentsDepth();
1439  if (addToIndex) Doxygen::indexList->decContentsDepth();
1440  }
1441  }
1442  }
1443  }
1444  }
1445 }
1446 
1447 
1449 {
1450  if (documentedNamespaces==0) return;
1451  ol.pushGeneratorState();
1454  if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Namespaces); // fall back
1455  QCString title = lne ? lne->title() : theTranslator->trNamespaceList();
1456  bool addToIndex = lne==0 || lne->visible();
1457  startFile(ol,"namespaces",0,title,HLI_Namespaces);
1458  startTitle(ol,0);
1459  ol.parseText(title);
1460  endTitle(ol,0,0);
1461  ol.startContents();
1462  ol.startTextBlock();
1463  ol.parseText(lne ? lne->intro() : theTranslator->trNamespaceListDescription(Config_getBool(EXTRACT_ALL)));
1464  ol.endTextBlock();
1465 
1466  bool first=TRUE;
1467 
1468  // ---------------
1469  // Linear namespace index for Latex/RTF
1470  // ---------------
1471  ol.pushGeneratorState();
1473 
1475  NamespaceDef *nd;
1476  for (nli.toFirst();(nd=nli.current());++nli)
1477  {
1478  if (nd->isLinkableInProject())
1479  {
1480  if (first)
1481  {
1482  ol.startIndexList();
1483  first=FALSE;
1484  }
1485  //ol.writeStartAnnoItem("namespace",nd->getOutputFileBase(),0,nd->name());
1486  ol.startIndexKey();
1487  if (nd->getLanguage()==SrcLangExt_VHDL)
1488  {
1489  ol.writeObjectLink(0, nd->getOutputFileBase().replace(0,qstrlen("namespace"),"class"),0,nd->displayName());
1490  }
1491  else
1492  {
1493  ol.writeObjectLink(0,nd->getOutputFileBase(),0,nd->displayName());
1494  }
1495  ol.endIndexKey();
1496 
1497  bool hasBrief = !nd->briefDescription().isEmpty();
1498  ol.startIndexValue(hasBrief);
1499  if (hasBrief)
1500  {
1501  //ol.docify(" (");
1502  ol.generateDoc(
1503  nd->briefFile(),nd->briefLine(),
1504  nd,0,
1505  nd->briefDescription(TRUE),
1506  FALSE, // index words
1507  FALSE, // isExample
1508  0, // example name
1509  TRUE, // single line
1510  TRUE // link from index
1511  );
1512  //ol.docify(")");
1513  }
1514  ol.endIndexValue(nd->getOutputFileBase(),hasBrief);
1515 
1516  }
1517  }
1518  if (!first) ol.endIndexList();
1519 
1520  ol.popGeneratorState();
1521 
1522  // ---------------
1523  // Hierarchical namespace index for HTML
1524  // ---------------
1525  ol.pushGeneratorState();
1527 
1528  {
1529  if (addToIndex)
1530  {
1531  Doxygen::indexList->addContentsItem(TRUE,title,0,"namespaces",0,TRUE,TRUE);
1533  }
1534  FTVHelp* ftv = new FTVHelp(FALSE);
1535  writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,FALSE,addToIndex);
1536  QGString outStr;
1537  FTextStream t(&outStr);
1538  ftv->generateTreeViewInline(t);
1539  ol.writeString(outStr);
1540  delete ftv;
1541  if (addToIndex)
1542  {
1544  }
1545  }
1546 
1547  ol.popGeneratorState();
1548  // ------
1549 
1550  endFile(ol);
1551  ol.popGeneratorState();
1552 }
1553 
1554 //----------------------------------------------------------------------------
1555 
1556 static int countAnnotatedClasses(int *cp)
1557 {
1558  int count=0;
1559  int countPrinted=0;
1561  ClassDef *cd;
1562  for (;(cd=cli.current());++cli)
1563  {
1564  if (cd->isLinkableInProject() && cd->templateMaster()==0)
1565  {
1566  if (!cd->isEmbeddedInOuterScope())
1567  {
1568  countPrinted++;
1569  }
1570  count++;
1571  }
1572  }
1573  *cp = countPrinted;
1574  return count;
1575 }
1576 
1577 
1579 {
1580  //LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::ClassList);
1581  //bool addToIndex = lne==0 || lne->visible();
1582 
1583  ol.startIndexList();
1585  ClassDef *cd;
1586 
1587  for (cli.toFirst();(cd=cli.current());++cli)
1588  {
1589  if (cd->getLanguage()==SrcLangExt_VHDL &&
1592  ) // no architecture
1593  {
1594  continue;
1595  }
1596 
1597  ol.pushGeneratorState();
1598  if (cd->isEmbeddedInOuterScope())
1599  {
1602  }
1603  if (cd->isLinkableInProject() && cd->templateMaster()==0)
1604  {
1605  ol.startIndexKey();
1606  if (cd->getLanguage()==SrcLangExt_VHDL)
1607  {
1609  ol.docify(prot.data());
1610  ol.writeString(" ");
1611  }
1612  ol.writeObjectLink(0,cd->getOutputFileBase(),cd->anchor(),cd->displayName());
1613  ol.endIndexKey();
1614  bool hasBrief = !cd->briefDescription().isEmpty();
1615  ol.startIndexValue(hasBrief);
1616  if (hasBrief)
1617  {
1618  ol.generateDoc(
1619  cd->briefFile(),cd->briefLine(),
1620  cd,0,
1621  cd->briefDescription(TRUE),
1622  FALSE, // indexWords
1623  FALSE, // isExample
1624  0, // example name
1625  TRUE, // single line
1626  TRUE // link from index
1627  );
1628  }
1629  ol.endIndexValue(cd->getOutputFileBase(),hasBrief);
1630 
1631  //if (addToIndex)
1632  //{
1633  // addMembersToIndex(cd,LayoutDocManager::Class,cd->displayName(),cd->anchor());
1634  //}
1635  }
1636  ol.popGeneratorState();
1637  }
1638  ol.endIndexList();
1639 }
1640 
1641 static QCString letterToLabel(uint startLetter)
1642 {
1643  char s[11]; // max 0x12345678 + '\0'
1644  if (isId(startLetter)) // printable ASCII character
1645  {
1646  s[0]=(char)startLetter;
1647  s[1]=0;
1648  }
1649  else
1650  {
1651  const char hex[]="0123456789abcdef";
1652  int i=0;
1653  s[i++]='0';
1654  s[i++]='x';
1655  if (startLetter>(1<<24)) // 4 byte character
1656  {
1657  s[i++]=hex[(startLetter>>28)&0xf];
1658  s[i++]=hex[(startLetter>>24)&0xf];
1659  }
1660  if (startLetter>(1<<16)) // 3 byte character
1661  {
1662  s[i++]=hex[(startLetter>>20)&0xf];
1663  s[i++]=hex[(startLetter>>16)&0xf];
1664  }
1665  if (startLetter>(1<<8)) // 2 byte character
1666  {
1667  s[i++]=hex[(startLetter>>12)&0xf];
1668  s[i++]=hex[(startLetter>>8)&0xf];
1669  }
1670  // one byte character
1671  s[i++]=hex[(startLetter>>4)&0xf];
1672  s[i++]=hex[(startLetter>>0)&0xf];
1673  s[i++]=0;
1674  }
1675  return s;
1676 }
1677 
1678 //----------------------------------------------------------------------------
1679 
1682 {
1683  public:
1686  uint letter() const { return m_letter; }
1687  private:
1688  virtual int compareValue(const ClassDef *c1, const ClassDef *c2) const
1689  {
1690  QCString n1 = c1->className();
1691  QCString n2 = c2->className();
1692  return qstricmp (n1.data()+getPrefixIndex(n1), n2.data()+getPrefixIndex(n2));
1693  }
1694  uint m_letter;
1695 };
1696 
1699 {
1700  public:
1701  AlphaIndexTableCell(int row,int col,uint letter,ClassDef *cd) :
1702  m_letter(letter), m_class(cd), m_row(row), m_col(col)
1703  { //printf("AlphaIndexTableCell(%d,%d,%c,%s)\n",row,col,letter!=0 ? letter: '-',
1704  // cd!=(ClassDef*)0x8 ? cd->name().data() : "<null>");
1705  }
1706 
1707  ClassDef *classDef() const { return m_class; }
1708  uint letter() const { return m_letter; }
1709  int row() const { return m_row; }
1710  int column() const { return m_col; }
1711 
1712  private:
1713  uint m_letter;
1715  int m_row;
1716  int m_col;
1717 };
1718 
1720 class AlphaIndexTableRows : public QList<AlphaIndexTableCell>
1721 {
1722  public:
1723  AlphaIndexTableRows() { setAutoDelete(TRUE); }
1724 };
1725 
1727 class AlphaIndexTableRowsIterator : public QListIterator<AlphaIndexTableCell>
1728 {
1729  public:
1731  QListIterator<AlphaIndexTableCell>(list) {}
1732 };
1733 
1735 class AlphaIndexTableColumns : public QList<AlphaIndexTableRows>
1736 {
1737  public:
1738  AlphaIndexTableColumns() { setAutoDelete(TRUE); }
1739 };
1740 
1741 class UsedIndexLetters : public SIntDict<uint>
1742 {
1743  public:
1744  UsedIndexLetters() : SIntDict<uint>(257) { setAutoDelete(TRUE); }
1745  void add(uint letter)
1746  {
1747  uint *v = find(letter);
1748  if (v==0)
1749  {
1750  append(letter,new uint(letter));
1751  }
1752  }
1753  private:
1754  int compareValues( const uint *p1, const uint *p2) const
1755  {
1756  return (int)*p1 - (int)*p2; // subtracting is done by int not uint.
1757  }
1758 };
1759 
1760 // write an alphabetical index of all class with a header for each letter
1762 {
1763  // What starting letters are used
1764  UsedIndexLetters indexLettersUsed;
1765 
1766  // first count the number of headers
1768  ClassDef *cd;
1769  uint startLetter=0;
1770  int headerItems=0;
1771  for (;(cd=cli.current());++cli)
1772  {
1773  if (cd->isLinkableInProject() && cd->templateMaster()==0)
1774  {
1775  if (cd->getLanguage()==SrcLangExt_VHDL && !((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS ))// no architecture
1776  continue;
1777 
1778  int index = getPrefixIndex(cd->className());
1779  //printf("name=%s index=%d %d\n",cd->className().data(),index,cd->protection());
1780  startLetter=getUtf8CodeToLower(cd->className(),index);
1781  indexLettersUsed.add(startLetter);
1782  }
1783  }
1784  indexLettersUsed.sort();
1785 
1786  // write quick link index (row of letters)
1787  QCString alphaLinks = "<div class=\"qindex\">";
1788  SIntDict<uint>::Iterator it(indexLettersUsed);
1789  uint *pLetter;
1790  for (it.toFirst();(pLetter=it.current());++it)
1791  {
1792  if (headerItems) alphaLinks += "&#160;|&#160;";
1793  headerItems++;
1794  QCString li = letterToLabel(*pLetter);
1795  QCString ls = QString(QChar(*pLetter)).utf8();
1796  alphaLinks += (QCString)"<a class=\"qindex\" href=\"#letter_" +
1797  li + "\">" +
1798  ls + "</a>";
1799  }
1800  alphaLinks += "</div>\n";
1801  ol.writeString(alphaLinks);
1802 
1803 
1804  // the number of columns in the table
1805  const int columns = Config_getInt(COLS_IN_ALPHA_INDEX);
1806 
1807  int i,j;
1808  int totalItems = headerItems*2 + annotatedClasses; // number of items in the table (headers span 2 items)
1809  int rows = (totalItems + columns - 1)/columns; // number of rows in the table
1810 
1811  //printf("headerItems=%d totalItems=%d columns=%d rows=%d itemsInLastRow=%d\n",
1812  // headerItems,totalItems,columns,rows,itemsInLastRow);
1813 
1814  // Keep a list of classes for each starting letter
1816  AlphaIndexTableColumns tableColumns;
1817 
1818  // fill the columns with the class list (row elements in each column,
1819  // expect for the columns with number >= itemsInLastRow, which get one
1820  // item less.
1821  //int icount=0;
1822  startLetter=0;
1823  for (cli.toFirst();(cd=cli.current());++cli)
1824  {
1825  if (cd->getLanguage()==SrcLangExt_VHDL && !((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS ))// no architecture
1826  continue;
1827 
1828  if (cd->isLinkableInProject() && cd->templateMaster()==0)
1829  {
1830  int index = getPrefixIndex(cd->className());
1831  startLetter=getUtf8CodeToLower(cd->className(),index);
1832  // Do some sorting again, since the classes are sorted by name with
1833  // prefix, which should be ignored really.
1834  if (cd->getLanguage()==SrcLangExt_VHDL)
1835  {
1836  if ((VhdlDocGen::VhdlClasses)cd->protection()==VhdlDocGen::ENTITYCLASS )// no architecture
1837  {
1838  classesByLetter.append(startLetter,cd);
1839  }
1840  }
1841  else
1842  {
1843  classesByLetter.append(startLetter,cd);
1844  }
1845  }
1846  }
1847 
1848  #define NEXT_ROW() \
1849  do \
1850  { \
1851  if (row>maxRows) maxRows=row; \
1852  if (row>=rows && col<columns) \
1853  { \
1854  col++; \
1855  row=0; \
1856  tableRows = new AlphaIndexTableRows; \
1857  tableColumns.append(tableRows); \
1858  } \
1859  } \
1860  while(0) \
1861 
1862  AlphaIndexTableRows *tableRows = new AlphaIndexTableRows;
1863  tableColumns.append(tableRows);
1864  int col=0,row=0,maxRows=0;
1866  SIntDict<PrefixIgnoreClassList>::Iterator lit(classesByLetter);
1867  for (lit.toFirst();(cl=lit.current());++lit)
1868  {
1869  uint l = cl->letter();
1870  // add special header cell
1871  tableRows->append(new AlphaIndexTableCell(row,col,l,(ClassDef*)0x8));
1872  row++;
1873  tableRows->append(new AlphaIndexTableCell(row,col,0,(ClassDef*)0x8));
1874  row++;
1875  ClassListIterator cit(*cl);
1876  cit.toFirst();
1877  ClassDef *cd = cit.current();
1878  ++cit;
1879  tableRows->append(new AlphaIndexTableCell(row,col,0,cd));
1880  row++;
1881  NEXT_ROW();
1882  for (;(cd=cit.current()); ++cit)
1883  {
1884  // add normal cell
1885  tableRows->append(new AlphaIndexTableCell(row,col,0,cd));
1886  row++;
1887  NEXT_ROW();
1888  }
1889  }
1890 
1891  // create row iterators for each column
1892  AlphaIndexTableRowsIterator **colIterators = new AlphaIndexTableRowsIterator*[columns];
1893  for (i=0;i<columns;i++)
1894  {
1895  if (i<(int)tableColumns.count())
1896  {
1897  colIterators[i] = new AlphaIndexTableRowsIterator(*tableColumns.at(i));
1898  }
1899  else // empty column
1900  {
1901  colIterators[i] = 0;
1902  }
1903  }
1904 
1905  ol.writeString("<table class=\"classindex\">\n");
1906  // generate table
1907  for (i=0;i<=maxRows;i++) // foreach table row
1908  {
1909  //printf("writing row %d\n",i);
1910  //ol.nextTableRow();
1911  ol.writeString("<tr>");
1912  // the last column may contain less items then the others
1913  //int colsInRow = (i<rows-1) ? columns : itemsInLastRow;
1914  //printf("row [%d]\n",i);
1915  for (j=0;j<columns;j++) // foreach table column
1916  {
1917  if (colIterators[j])
1918  {
1919  AlphaIndexTableCell *cell = colIterators[j]->current();
1920  if (cell)
1921  {
1922  if (cell->row()==i)
1923  {
1924  if (cell->letter()!=0)
1925  {
1926  QCString s = letterToLabel(cell->letter());
1927  ol.writeString("<td rowspan=\"2\" valign=\"bottom\">");
1928  ol.writeString("<a name=\"letter_");
1929  ol.writeString(s);
1930  ol.writeString("\"></a>");
1931  ol.writeString("<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">"
1932  "<tr>"
1933  "<td><div class=\"ah\">&#160;&#160;");
1934  ol.writeString(QString(QChar(cell->letter())).utf8());
1935  ol.writeString( "&#160;&#160;</div>"
1936  "</td>"
1937  "</tr>"
1938  "</table>\n");
1939  }
1940  else if (cell->classDef()!=(ClassDef*)0x8)
1941  {
1942  cd = cell->classDef();
1943  ol.writeString("<td valign=\"top\">");
1944  QCString namesp,cname;
1945  //if (cd->getNamespaceDef()) namesp=cd->getNamespaceDef()->displayName();
1946  //QCString cname=cd->className();
1947  extractNamespaceName(cd->name(),cname,namesp);
1948  QCString nsDispName;
1949  SrcLangExt lang = cd->getLanguage();
1950  QCString sep = getLanguageSpecificSeparator(lang);
1951  if (sep!="::")
1952  {
1953  nsDispName=substitute(namesp,"::",sep);
1954  cname=substitute(cname,"::",sep);
1955  }
1956  else
1957  {
1958  nsDispName=namesp;
1959  }
1960 
1961  ol.writeObjectLink(cd->getReference(),
1962  cd->getOutputFileBase(),cd->anchor(),cname);
1963  if (!namesp.isEmpty())
1964  {
1965  ol.docify(" (");
1966  NamespaceDef *nd = getResolvedNamespace(namesp);
1967  if (nd && nd->isLinkable())
1968  {
1969  ol.writeObjectLink(nd->getReference(),
1970  nd->getOutputFileBase(),0,nsDispName);
1971  }
1972  else
1973  {
1974  ol.docify(nsDispName);
1975  }
1976  ol.docify(")");
1977  }
1978  ol.writeNonBreakableSpace(3);
1979  }
1980  ++(*colIterators[j]);
1981  if (cell->letter()!=0 || cell->classDef()!=(ClassDef*)0x8)
1982  {
1983  ol.writeString("</td>");
1984  }
1985  }
1986  }
1987  else
1988  {
1989  ol.writeString("<td></td>");
1990  }
1991  }
1992  }
1993  ol.writeString("</tr>\n");
1994  }
1995  ol.writeString("</table>\n");
1996 
1997  ol.writeString(alphaLinks);
1998 
1999  // release the temporary memory
2000  for (i=0;i<columns;i++)
2001  {
2002  delete colIterators[i];
2003  }
2004  delete[] colIterators;
2005 }
2006 
2007 //----------------------------------------------------------------------------
2008 
2010 {
2011  if (annotatedClasses==0) return;
2012  ol.pushGeneratorState();
2015  QCString title = lne ? lne->title() : theTranslator->trCompoundIndex();
2016  bool addToIndex = lne==0 || lne->visible();
2017 
2018  startFile(ol,"classes",0,title,HLI_Classes);
2019 
2020  startTitle(ol,0);
2021  ol.parseText(title);
2022  endTitle(ol,0,0);
2023 
2024  if (addToIndex)
2025  {
2026  Doxygen::indexList->addContentsItem(FALSE,title,0,"classes",0,FALSE,TRUE);
2027  }
2028 
2029  ol.startContents();
2031  endFile(ol); // contains ol.endContents()
2032 
2033  ol.popGeneratorState();
2034 }
2035 
2036 //----------------------------------------------------------------------------
2037 
2039 {
2040  //printf("writeAnnotatedIndex: count=%d printed=%d\n",
2041  // annotatedClasses,annotatedClassesPrinted);
2042  if (annotatedClasses==0) return;
2043 
2044  ol.pushGeneratorState();
2046  if (annotatedClassesPrinted==0)
2047  {
2050  }
2052  if (lne==0) lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Classes); // fall back
2053  QCString title = lne ? lne->title() : theTranslator->trCompoundList();
2054  bool addToIndex = lne==0 || lne->visible();
2055 
2056 
2057  startFile(ol,"annotated",0,title,HLI_Annotated);
2058 
2059  startTitle(ol,0);
2060  ol.parseText(title);
2061  endTitle(ol,0,0);
2062 
2063  ol.startContents();
2064 
2065  ol.startTextBlock();
2067  ol.endTextBlock();
2068 
2069  // ---------------
2070  // Linear class index for Latex/RTF
2071  // ---------------
2072  ol.pushGeneratorState();
2075 
2077 
2079  ol.popGeneratorState();
2080 
2081  // ---------------
2082  // Hierarchical class index for HTML
2083  // ---------------
2084  ol.pushGeneratorState();
2086 
2087  {
2088  if (addToIndex)
2089  {
2090  Doxygen::indexList->addContentsItem(TRUE,title,0,"annotated",0,TRUE,TRUE);
2092  }
2093  FTVHelp* ftv = new FTVHelp(FALSE);
2094  writeNamespaceTree(Doxygen::namespaceSDict,ftv,TRUE,TRUE,addToIndex);
2095  writeClassTree(Doxygen::classSDict,ftv,addToIndex,TRUE);
2096  QGString outStr;
2097  FTextStream t(&outStr);
2098  ftv->generateTreeViewInline(t);
2099  ol.writeString(outStr);
2100  delete ftv;
2101  if (addToIndex)
2102  {
2104  }
2105  }
2106 
2107  ol.popGeneratorState();
2108  // ------
2109 
2110  endFile(ol); // contains ol.endContents()
2111  ol.popGeneratorState();
2112 }
2113 
2114 //----------------------------------------------------------------------------
2115 static void writeClassLinkForMember(OutputList &ol,MemberDef *md,const char *separator,
2116  QCString &prevClassName)
2117 {
2118  ClassDef *cd=md->getClassDef();
2119  if ( cd && prevClassName!=cd->displayName())
2120  {
2121  ol.docify(separator);
2123  cd->displayName());
2124  ol.writeString("\n");
2125  prevClassName = cd->displayName();
2126  }
2127 }
2128 
2129 static void writeFileLinkForMember(OutputList &ol,MemberDef *md,const char *separator,
2130  QCString &prevFileName)
2131 {
2132  FileDef *fd=md->getFileDef();
2133  if (fd && prevFileName!=fd->name())
2134  {
2135  ol.docify(separator);
2137  fd->name());
2138  ol.writeString("\n");
2139  prevFileName = fd->name();
2140  }
2141 }
2142 
2143 static void writeNamespaceLinkForMember(OutputList &ol,MemberDef *md,const char *separator,
2144  QCString &prevNamespaceName)
2145 {
2146  NamespaceDef *nd=md->getNamespaceDef();
2147  if (nd && prevNamespaceName!=nd->displayName())
2148  {
2149  ol.docify(separator);
2151  nd->displayName());
2152  ol.writeString("\n");
2153  prevNamespaceName = nd->displayName();
2154  }
2155 }
2156 
2157 static void writeMemberList(OutputList &ol,bool useSections,int page,
2158  const LetterToIndexMap<MemberIndexList> &memberLists,
2160 {
2161  int index = (int)type;
2162  ASSERT(index<3);
2163 
2164  typedef void (*writeLinkForMember_t)(OutputList &ol,MemberDef *md,const char *separator,
2165  QCString &prevNamespaceName);
2166 
2167  // each index tab has its own write function
2168  static writeLinkForMember_t writeLinkForMemberMap[3] =
2169  {
2173  };
2174  QCString prevName;
2175  QCString prevDefName;
2176  bool first=TRUE;
2177  bool firstSection=TRUE;
2178  bool firstItem=TRUE;
2179  MemberIndexList *ml;
2180  SIntDict<MemberIndexList>::Iterator it(memberLists);
2181  for (it.toFirst();(ml=it.current());++it)
2182  {
2183  if (page!=-1)
2184  {
2185  ml = memberLists[page];
2186  it.toLast();
2187  }
2188  if (ml==0 || ml->count()==0) continue;
2189  ml->sort();
2190  QListIterator<MemberDef> mli(*ml);
2191  MemberDef *md;
2192  for (mli.toFirst();(md=mli.current());++mli)
2193  {
2194  const char *sep;
2195  bool isFunc=!md->isObjCMethod() &&
2196  (md->isFunction() || md->isSlot() || md->isSignal());
2197  QCString name=md->name();
2198  int startIndex = getPrefixIndex(name);
2199  if (QCString(name.data()+startIndex)!=prevName) // new entry
2200  {
2201  if ((prevName.isEmpty() ||
2202  tolower(name.at(startIndex))!=tolower(prevName.at(0))) &&
2203  useSections) // new section
2204  {
2205  if (!firstItem) ol.endItemListItem();
2206  if (!firstSection) ol.endItemList();
2207  QCString cs = letterToLabel(ml->letter());
2208  QCString cl = QString(QChar(ml->letter())).utf8();
2209  QCString anchor=(QCString)"index_"+cs;
2210  QCString title=(QCString)"- "+cl+" -";
2211  ol.startSection(anchor,title,SectionInfo::Subsection);
2212  ol.docify(title);
2213  ol.endSection(anchor,SectionInfo::Subsection);
2214  ol.startItemList();
2215  firstSection=FALSE;
2216  firstItem=TRUE;
2217  }
2218  else if (!useSections && first)
2219  {
2220  ol.startItemList();
2221  first=FALSE;
2222  }
2223 
2224  // member name
2225  if (!firstItem) ol.endItemListItem();
2226  ol.startItemListItem();
2227  firstItem=FALSE;
2228  ol.docify(name);
2229  if (isFunc) ol.docify("()");
2230  ol.writeString("\n");
2231 
2232  // link to class
2233  prevDefName="";
2234  sep = ": ";
2235  prevName = name.data()+startIndex;
2236  }
2237  else // same entry
2238  {
2239  sep = ", ";
2240  // link to class for other members with the same name
2241  }
2242  if (index<3)
2243  {
2244  // write the link for the specific list type
2245  writeLinkForMemberMap[index](ol,md,sep,prevDefName);
2246  }
2247  }
2248  }
2249  if (!firstItem) ol.endItemListItem();
2250  ol.endItemList();
2251 }
2252 
2253 //----------------------------------------------------------------------------
2254 
2256 {
2257  int j=0;
2258  for (j=0;j<CMHL_Total;j++)
2259  {
2261  g_memberIndexLetterUsed[j].clear();
2262  }
2263 }
2264 
2266 {
2267  static bool hideFriendCompounds = Config_getBool(HIDE_FRIEND_COMPOUNDS);
2268  ClassDef *cd=0;
2269 
2270 
2271 
2272  if (md->isLinkableInProject() &&
2273  (cd=md->getClassDef()) &&
2274  cd->isLinkableInProject() &&
2275  cd->templateMaster()==0)
2276  {
2277  QCString n = md->name();
2278  int index = getPrefixIndex(n);
2279  uint letter = getUtf8CodeToLower(n,index);
2280  if (!n.isEmpty())
2281  {
2282  bool isFriendToHide = hideFriendCompounds &&
2283  (QCString(md->typeString())=="friend class" ||
2284  QCString(md->typeString())=="friend struct" ||
2285  QCString(md->typeString())=="friend union");
2286  if (!(md->isFriend() && isFriendToHide) &&
2287  (!md->isEnumValue() || (md->getEnumScope() && !md->getEnumScope()->isStrong()))
2288  )
2289  {
2290  g_memberIndexLetterUsed[CMHL_All].append(letter,md);
2292  }
2293  if (md->isFunction() || md->isSlot() || md->isSignal())
2294  {
2295  g_memberIndexLetterUsed[CMHL_Functions].append(letter,md);
2297  }
2298  else if (md->isVariable())
2299  {
2300  g_memberIndexLetterUsed[CMHL_Variables].append(letter,md);
2302  }
2303  else if (md->isTypedef())
2304  {
2305  g_memberIndexLetterUsed[CMHL_Typedefs].append(letter,md);
2307  }
2308  else if (md->isEnumerate())
2309  {
2310  g_memberIndexLetterUsed[CMHL_Enums].append(letter,md);
2312  }
2313  else if (md->isEnumValue() && md->getEnumScope() && !md->getEnumScope()->isStrong())
2314  {
2315  g_memberIndexLetterUsed[CMHL_EnumValues].append(letter,md);
2317  }
2318  else if (md->isProperty())
2319  {
2320  g_memberIndexLetterUsed[CMHL_Properties].append(letter,md);
2322  }
2323  else if (md->isEvent())
2324  {
2325  g_memberIndexLetterUsed[CMHL_Events].append(letter,md);
2327  }
2328  else if (md->isRelated() || md->isForeign() ||
2329  (md->isFriend() && !isFriendToHide))
2330  {
2331  g_memberIndexLetterUsed[CMHL_Related].append(letter,md);
2333  }
2334  }
2335  }
2336 }
2337 
2338 //----------------------------------------------------------------------------
2339 
2341 {
2342  int j=0;
2343  for (j=0;j<NMHL_Total;j++)
2344  {
2346  g_namespaceIndexLetterUsed[j].clear();
2347  }
2348 }
2349 
2351 {
2352  NamespaceDef *nd=md->getNamespaceDef();
2353  if (nd && nd->isLinkableInProject() && md->isLinkableInProject())
2354  {
2355  QCString n = md->name();
2356  int index = getPrefixIndex(n);
2357  uint letter = getUtf8CodeToLower(n,index);
2358  if (!n.isEmpty())
2359  {
2360  if (!md->isEnumValue() || (md->getEnumScope() && !md->getEnumScope()->isStrong()))
2361  {
2362  g_namespaceIndexLetterUsed[NMHL_All].append(letter,md);
2364  }
2365 
2366  if (md->isFunction())
2367  {
2368  g_namespaceIndexLetterUsed[NMHL_Functions].append(letter,md);
2370  }
2371  else if (md->isVariable())
2372  {
2373  g_namespaceIndexLetterUsed[NMHL_Variables].append(letter,md);
2375  }
2376  else if (md->isTypedef())
2377  {
2378  g_namespaceIndexLetterUsed[NMHL_Typedefs].append(letter,md);
2380  }
2381  else if (md->isEnumerate())
2382  {
2383  g_namespaceIndexLetterUsed[NMHL_Enums].append(letter,md);
2385  }
2386  else if (md->isEnumValue() && md->getEnumScope() && !md->getEnumScope()->isStrong())
2387  {
2388  g_namespaceIndexLetterUsed[NMHL_EnumValues].append(letter,md);
2390  }
2391  }
2392  }
2393 }
2394 
2395 //----------------------------------------------------------------------------
2396 
2398 {
2399  int j=0;
2400  for (j=0;j<NMHL_Total;j++)
2401  {
2402  documentedFileMembers[j]=0;
2403  g_fileIndexLetterUsed[j].clear();
2404  }
2405 }
2406 
2408 {
2409  FileDef *fd=md->getFileDef();
2410  if (fd && fd->isLinkableInProject() && md->isLinkableInProject())
2411  {
2412  QCString n = md->name();
2413  int index = getPrefixIndex(n);
2414  uint letter = getUtf8CodeToLower(n,index);
2415  if (!n.isEmpty())
2416  {
2417  if (!md->isEnumValue() || (md->getEnumScope() && !md->getEnumScope()->isStrong()))
2418  {
2419  g_fileIndexLetterUsed[FMHL_All].append(letter,md);
2421  }
2422 
2423  if (md->isFunction())
2424  {
2425  g_fileIndexLetterUsed[FMHL_Functions].append(letter,md);
2427  }
2428  else if (md->isVariable())
2429  {
2430  g_fileIndexLetterUsed[FMHL_Variables].append(letter,md);
2432  }
2433  else if (md->isTypedef())
2434  {
2435  g_fileIndexLetterUsed[FMHL_Typedefs].append(letter,md);
2437  }
2438  else if (md->isEnumerate())
2439  {
2440  g_fileIndexLetterUsed[FMHL_Enums].append(letter,md);
2442  }
2443  else if (md->isEnumValue() && md->getEnumScope() && !md->getEnumScope()->isStrong())
2444  {
2445  g_fileIndexLetterUsed[FMHL_EnumValues].append(letter,md);
2447  }
2448  else if (md->isDefine())
2449  {
2450  g_fileIndexLetterUsed[FMHL_Defines].append(letter,md);
2452  }
2453  }
2454  }
2455 }
2456 
2457 //----------------------------------------------------------------------------
2458 
2460  const LetterToIndexMap<MemberIndexList> &charUsed,uint page,
2461  QCString fullName,bool multiPage)
2462 {
2463  bool first=TRUE;
2464  startQuickIndexList(ol,TRUE);
2466  MemberIndexList *ml;
2467  for (it.toFirst();(ml=it.current());++it)
2468  {
2469  uint i = ml->letter();
2470  QCString is = letterToLabel(i);
2471  QCString ci = QString(QChar(i)).utf8();
2472  QCString anchor;
2473  QCString extension=Doxygen::htmlFileExtension;
2474  if (!multiPage)
2475  anchor="#index_";
2476  else if (first)
2477  anchor=fullName+extension+"#index_";
2478  else
2479  anchor=fullName+"_"+letterToLabel(i)+extension+"#index_";
2480  startQuickIndexItem(ol,anchor+is,i==page,TRUE,first);
2481  ol.writeString(ci);
2482  endQuickIndexItem(ol);
2483  first=FALSE;
2484  }
2485  endQuickIndexList(ol);
2486 }
2487 
2488 //----------------------------------------------------------------------------
2489 
2491 struct CmhlInfo
2492 {
2493  CmhlInfo(const char *fn,const char *t) : fname(fn), title(t) {}
2494  const char *fname;
2495  QCString title;
2496 };
2497 
2498 static const CmhlInfo *getCmhlInfo(int hl)
2499 {
2500  static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
2501  static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
2502  static CmhlInfo cmhlInfo[] =
2503  {
2504  CmhlInfo("functions", theTranslator->trAll()),
2505  CmhlInfo("functions_func",
2506  fortranOpt ? theTranslator->trSubprograms() :
2507  vhdlOpt ? VhdlDocGen::trFunctionAndProc() :
2509  CmhlInfo("functions_vars",theTranslator->trVariables()),
2510  CmhlInfo("functions_type",theTranslator->trTypedefs()),
2511  CmhlInfo("functions_enum",theTranslator->trEnumerations()),
2512  CmhlInfo("functions_eval",theTranslator->trEnumerationValues()),
2513  CmhlInfo("functions_prop",theTranslator->trProperties()),
2514  CmhlInfo("functions_evnt",theTranslator->trEvents()),
2515  CmhlInfo("functions_rela",theTranslator->trRelatedFunctions())
2516  };
2517  return &cmhlInfo[hl];
2518 }
2519 
2521 {
2522  if (documentedClassMembers[hl]==0) return;
2523 
2524  static bool disableIndex = Config_getBool(DISABLE_INDEX);
2525 
2526  bool multiPageIndex=FALSE;
2528  {
2529  multiPageIndex=TRUE;
2530  }
2531 
2532  ol.pushGeneratorState();
2534 
2535  QCString extension=Doxygen::htmlFileExtension;
2537  QCString title = lne ? lne->title() : theTranslator->trCompoundMembers();
2538  if (hl!=CMHL_All) title+=(QCString)" - "+getCmhlInfo(hl)->title;
2539  bool addToIndex = lne==0 || lne->visible();
2540 
2541  if (addToIndex)
2542  {
2543  Doxygen::indexList->addContentsItem(multiPageIndex,getCmhlInfo(hl)->title,0,
2544  getCmhlInfo(hl)->fname,0,multiPageIndex,TRUE);
2545  if (multiPageIndex) Doxygen::indexList->incContentsDepth();
2546  }
2547 
2548  bool first=TRUE;
2549  SIntDict<MemberIndexList>::Iterator it(g_memberIndexLetterUsed[hl]);
2550  MemberIndexList *ml;
2551  for (it.toFirst();(ml=it.current());++it)
2552  {
2553  uint page = ml->letter();
2554  QCString fileName = getCmhlInfo(hl)->fname;
2555  if (multiPageIndex)
2556  {
2557  if (!first)
2558  {
2559  fileName+="_"+letterToLabel(page);
2560  }
2561  QCString cs = QString(QChar(page)).utf8();
2562  if (addToIndex)
2563  {
2564  Doxygen::indexList->addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE);
2565  }
2566  }
2567  bool quickIndex = documentedClassMembers[hl]>maxItemsBeforeQuickIndex;
2568 
2569  ol.startFile(fileName+extension,0,title);
2570  ol.startQuickIndices();
2571  if (!disableIndex)
2572  {
2573  ol.writeQuickLinks(TRUE,HLI_Functions,0);
2574 #if 0
2575  startQuickIndexList(ol);
2576 
2577  // index item for global member list
2579  getCmhlInfo(0)->fname+Doxygen::htmlFileExtension,hl==CMHL_All,TRUE,first);
2580  ol.writeString(fixSpaces(getCmhlInfo(0)->title));
2581  endQuickIndexItem(ol);
2582 
2583  int i;
2584  // index items per category member lists
2585  for (i=1;i<CMHL_Total;i++)
2586  {
2587  if (documentedClassMembers[i]>0)
2588  {
2589  startQuickIndexItem(ol,getCmhlInfo(i)->fname+Doxygen::htmlFileExtension,hl==i,TRUE,first);
2590  ol.writeString(fixSpaces(getCmhlInfo(i)->title));
2591  //printf("multiPageIndex=%d first=%d fileName=%s file=%s title=%s\n",
2592  // multiPageIndex,first,fileName.data(),getCmhlInfo(i)->fname,getCmhlInfo(i)->title.data());
2593  endQuickIndexItem(ol);
2594  }
2595  }
2596 
2597  endQuickIndexList(ol);
2598 
2599  // quick alphabetical index
2600  if (quickIndex)
2601  {
2602  writeQuickMemberIndex(ol,g_memberIndexLetterUsed[hl],page,
2603  getCmhlInfo(hl)->fname,multiPageIndex);
2604  }
2605 #endif
2606  }
2607  ol.endQuickIndices();
2608  ol.writeSplitBar(fileName);
2609  ol.writeSearchInfo();
2610 
2611  ol.startContents();
2612 
2613  if (hl==CMHL_All)
2614  {
2615  ol.startTextBlock();
2616  ol.parseText(lne ? lne->intro() : theTranslator->trCompoundMembersDescription(Config_getBool(EXTRACT_ALL)));
2617  ol.endTextBlock();
2618  }
2619  else
2620  {
2621  // hack to work around a mozilla bug, which refuses to switch to
2622  // normal lists otherwise
2623  ol.writeString("&#160;");
2624  }
2625 
2626  writeMemberList(ol,quickIndex,
2627  multiPageIndex?page:-1,
2628  g_memberIndexLetterUsed[hl],
2630  endFile(ol);
2631  first=FALSE;
2632  }
2633 
2634  if (multiPageIndex && addToIndex) Doxygen::indexList->decContentsDepth();
2635 
2636  ol.popGeneratorState();
2637 }
2638 
2640 {
2642  bool addToIndex = lne==0 || lne->visible();
2643 
2644  if (documentedClassMembers[CMHL_All]>0 && addToIndex)
2645  {
2646  Doxygen::indexList->addContentsItem(TRUE,lne ? lne->title() : theTranslator->trCompoundMembers(),0,"functions",0);
2648  }
2658  if (documentedClassMembers[CMHL_All]>0 && addToIndex)
2659  {
2661  }
2662 
2663 }
2664 
2665 //----------------------------------------------------------------------------
2666 
2668 struct FmhlInfo
2669 {
2670  FmhlInfo(const char *fn,const char *t) : fname(fn), title(t) {}
2671  const char *fname;
2672  QCString title;
2673 };
2674 
2675 static const FmhlInfo *getFmhlInfo(int hl)
2676 {
2677  static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
2678  static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
2679  static FmhlInfo fmhlInfo[] =
2680  {
2681  FmhlInfo("globals", theTranslator->trAll()),
2682  FmhlInfo("globals_func",
2683  fortranOpt ? theTranslator->trSubprograms() :
2684  vhdlOpt ? VhdlDocGen::trFunctionAndProc() :
2686  FmhlInfo("globals_vars",theTranslator->trVariables()),
2687  FmhlInfo("globals_type",theTranslator->trTypedefs()),
2688  FmhlInfo("globals_enum",theTranslator->trEnumerations()),
2689  FmhlInfo("globals_eval",theTranslator->trEnumerationValues()),
2690  FmhlInfo("globals_defs",theTranslator->trDefines())
2691  };
2692  return &fmhlInfo[hl];
2693 }
2694 
2696 {
2697  if (documentedFileMembers[hl]==0) return;
2698 
2699  static bool disableIndex = Config_getBool(DISABLE_INDEX);
2700 
2701  bool multiPageIndex=FALSE;
2703  {
2704  multiPageIndex=TRUE;
2705  }
2706 
2707  ol.pushGeneratorState();
2709 
2710  QCString extension=Doxygen::htmlFileExtension;
2712  QCString title = lne ? lne->title() : theTranslator->trFileMembers();
2713  bool addToIndex = lne==0 || lne->visible();
2714 
2715  if (addToIndex)
2716  {
2717  Doxygen::indexList->addContentsItem(multiPageIndex,getFmhlInfo(hl)->title,0,
2718  getFmhlInfo(hl)->fname,0,multiPageIndex,TRUE);
2719  if (multiPageIndex) Doxygen::indexList->incContentsDepth();
2720  }
2721 
2722  bool first=TRUE;
2723  SIntDict<MemberIndexList>::Iterator it(g_fileIndexLetterUsed[hl]);
2724  MemberIndexList *ml;
2725  for (it.toFirst();(ml=it.current());++it)
2726  {
2727  uint page = ml->letter();
2728  QCString fileName = getFmhlInfo(hl)->fname;
2729  if (multiPageIndex)
2730  {
2731  if (!first)
2732  {
2733  fileName+="_"+letterToLabel(page);
2734  }
2735  QCString cs = QString(QChar(page)).utf8();
2736  if (addToIndex)
2737  {
2738  Doxygen::indexList->addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE);
2739  }
2740  }
2741  bool quickIndex = documentedFileMembers[hl]>maxItemsBeforeQuickIndex;
2742 
2743  ol.startFile(fileName+extension,0,title);
2744  ol.startQuickIndices();
2745  if (!disableIndex)
2746  {
2747  ol.writeQuickLinks(TRUE,HLI_Globals,0);
2748 #if 0
2749  startQuickIndexList(ol);
2750 
2751  // index item for all file member lists
2753  getFmhlInfo(0)->fname+Doxygen::htmlFileExtension,hl==FMHL_All,TRUE,first);
2754  ol.writeString(fixSpaces(getFmhlInfo(0)->title));
2755  endQuickIndexItem(ol);
2756 
2757  int i;
2758  // index items for per category member lists
2759  for (i=1;i<FMHL_Total;i++)
2760  {
2761  if (documentedFileMembers[i]>0)
2762  {
2764  getFmhlInfo(i)->fname+Doxygen::htmlFileExtension,hl==i,TRUE,first);
2765  ol.writeString(fixSpaces(getFmhlInfo(i)->title));
2766  endQuickIndexItem(ol);
2767  }
2768  }
2769 
2770  endQuickIndexList(ol);
2771 
2772  if (quickIndex)
2773  {
2774  writeQuickMemberIndex(ol,g_fileIndexLetterUsed[hl],page,
2775  getFmhlInfo(hl)->fname,multiPageIndex);
2776  }
2777 #endif
2778  }
2779  ol.endQuickIndices();
2780  ol.writeSplitBar(fileName);
2781  ol.writeSearchInfo();
2782 
2783  ol.startContents();
2784 
2785  if (hl==FMHL_All)
2786  {
2787  ol.startTextBlock();
2788  ol.parseText(lne ? lne->intro() : theTranslator->trFileMembersDescription(Config_getBool(EXTRACT_ALL)));
2789  ol.endTextBlock();
2790  }
2791  else
2792  {
2793  // hack to work around a mozilla bug, which refuses to switch to
2794  // normal lists otherwise
2795  ol.writeString("&#160;");
2796  }
2797 
2798  writeMemberList(ol,quickIndex,
2799  multiPageIndex?page:-1,
2800  g_fileIndexLetterUsed[hl],
2802  endFile(ol);
2803  first=FALSE;
2804  }
2805  if (multiPageIndex && addToIndex) Doxygen::indexList->decContentsDepth();
2806  ol.popGeneratorState();
2807 }
2808 
2810 {
2812  bool addToIndex = lne==0 || lne->visible();
2813  if (documentedFileMembers[FMHL_All]>0 && addToIndex)
2814  {
2815  Doxygen::indexList->addContentsItem(FALSE,lne ? lne->title() : theTranslator->trFileMembers(),0,"globals",0);
2817  }
2825  if (documentedFileMembers[FMHL_All]>0 && addToIndex)
2826  {
2828  }
2829 
2830 }
2831 
2832 //----------------------------------------------------------------------------
2833 
2835 struct NmhlInfo
2836 {
2837  NmhlInfo(const char *fn,const char *t) : fname(fn), title(t) {}
2838  const char *fname;
2839  QCString title;
2840 };
2841 
2842 static const NmhlInfo *getNmhlInfo(int hl)
2843 {
2844  static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
2845  static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
2846  static NmhlInfo nmhlInfo[] =
2847  {
2848  NmhlInfo("namespacemembers", theTranslator->trAll()),
2849  NmhlInfo("namespacemembers_func",
2850  fortranOpt ? theTranslator->trSubprograms() :
2851  vhdlOpt ? VhdlDocGen::trFunctionAndProc() :
2853  NmhlInfo("namespacemembers_vars",theTranslator->trVariables()),
2854  NmhlInfo("namespacemembers_type",theTranslator->trTypedefs()),
2855  NmhlInfo("namespacemembers_enum",theTranslator->trEnumerations()),
2856  NmhlInfo("namespacemembers_eval",theTranslator->trEnumerationValues())
2857  };
2858  return &nmhlInfo[hl];
2859 }
2860 
2861 //----------------------------------------------------------------------------
2862 
2865 {
2866  if (documentedNamespaceMembers[hl]==0) return;
2867 
2868  static bool disableIndex = Config_getBool(DISABLE_INDEX);
2869 
2870 
2871  bool multiPageIndex=FALSE;
2873  {
2874  multiPageIndex=TRUE;
2875  }
2876 
2877  ol.pushGeneratorState();
2879 
2880  QCString extension=Doxygen::htmlFileExtension;
2882  QCString title = lne ? lne->title() : theTranslator->trNamespaceMembers();
2883  bool addToIndex = lne==0 || lne->visible();
2884 
2885  if (addToIndex)
2886  {
2887  Doxygen::indexList->addContentsItem(multiPageIndex,getNmhlInfo(hl)->title,0,
2888  getNmhlInfo(hl)->fname,0,multiPageIndex,TRUE);
2889  if (multiPageIndex) Doxygen::indexList->incContentsDepth();
2890  }
2891 
2892  bool first=TRUE;
2893  SIntDict<MemberIndexList>::Iterator it(g_namespaceIndexLetterUsed[hl]);
2894  MemberIndexList *ml;
2895  for (it.toFirst();(ml=it.current());++it)
2896  {
2897  uint page = ml->letter();
2898  QCString fileName = getNmhlInfo(hl)->fname;
2899  if (multiPageIndex)
2900  {
2901  if (!first)
2902  {
2903  fileName+="_"+letterToLabel(page);
2904  }
2905  QCString cs = QString(QChar(page)).utf8();
2906  if (addToIndex)
2907  {
2908  Doxygen::indexList->addContentsItem(FALSE,cs,0,fileName,0,FALSE,TRUE);
2909  }
2910  }
2912 
2913  ol.startFile(fileName+extension,0,title);
2914  ol.startQuickIndices();
2915  if (!disableIndex)
2916  {
2918 #if 0
2919  startQuickIndexList(ol);
2920 
2921  // index item for all namespace member lists
2923  getNmhlInfo(0)->fname+Doxygen::htmlFileExtension,hl==NMHL_All,TRUE,first);
2924  ol.writeString(fixSpaces(getNmhlInfo(0)->title));
2925  endQuickIndexItem(ol);
2926 
2927  int i;
2928  // index items per category member lists
2929  for (i=1;i<NMHL_Total;i++)
2930  {
2931  if (documentedNamespaceMembers[i]>0)
2932  {
2934  getNmhlInfo(i)->fname+Doxygen::htmlFileExtension,hl==i,TRUE,first);
2935  ol.writeString(fixSpaces(getNmhlInfo(i)->title));
2936  endQuickIndexItem(ol);
2937  }
2938  }
2939 
2940  endQuickIndexList(ol);
2941 
2942  if (quickIndex)
2943  {
2944  writeQuickMemberIndex(ol,g_namespaceIndexLetterUsed[hl],page,
2945  getNmhlInfo(hl)->fname,multiPageIndex);
2946  }
2947 #endif
2948  }
2949  ol.endQuickIndices();
2950  ol.writeSplitBar(fileName);
2951  ol.writeSearchInfo();
2952 
2953  ol.startContents();
2954 
2955  if (hl==NMHL_All)
2956  {
2957  ol.startTextBlock();
2958  ol.parseText(lne ? lne->intro() : theTranslator->trNamespaceMemberDescription(Config_getBool(EXTRACT_ALL)));
2959  ol.endTextBlock();
2960  }
2961  else
2962  {
2963  // hack to work around a mozilla bug, which refuses to switch to
2964  // normal lists otherwise
2965  ol.writeString("&#160;");
2966  }
2967 
2968  writeMemberList(ol,quickIndex,
2969  multiPageIndex?page:-1,
2970  g_namespaceIndexLetterUsed[hl],
2972  endFile(ol);
2973  }
2974  if (multiPageIndex && addToIndex) Doxygen::indexList->decContentsDepth();
2975  ol.popGeneratorState();
2976 }
2977 
2979 {
2981  bool addToIndex = lne==0 || lne->visible();
2982  if (documentedNamespaceMembers[NMHL_All]>0 && addToIndex)
2983  {
2984  Doxygen::indexList->addContentsItem(FALSE,lne ? lne->title() : theTranslator->trNamespaceMembers(),0,"namespacemembers",0);
2986  }
2987  //bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
2994  if (documentedNamespaceMembers[NMHL_All]>0 && addToIndex)
2995  {
2997  }
2998 
2999 }
3000 
3001 //----------------------------------------------------------------------------
3002 
3003 //----------------------------------------------------------------------------
3004 
3006 {
3007  if (Doxygen::exampleSDict->count()==0) return;
3008  ol.pushGeneratorState();
3011  QCString title = lne ? lne->title() : theTranslator->trExamples();
3012  bool addToIndex = lne==0 || lne->visible();
3013 
3014  startFile(ol,"examples",0,title,HLI_Examples);
3015 
3016  startTitle(ol,0);
3017  ol.parseText(title);
3018  endTitle(ol,0,0);
3019 
3020  ol.startContents();
3021 
3022  if (addToIndex)
3023  {
3024  Doxygen::indexList->addContentsItem(TRUE,title,0,"examples",0,TRUE,TRUE);
3026  }
3027 
3028  ol.startTextBlock();
3029  ol.parseText(lne ? lne->intro() : theTranslator->trExamplesDescription());
3030  ol.endTextBlock();
3031 
3032  ol.startItemList();
3034  PageDef *pd=0;
3035  for (pdi.toFirst();(pd=pdi.current());++pdi)
3036  {
3037  ol.startItemListItem();
3038  QCString n=pd->getOutputFileBase();
3039  if (!pd->title().isEmpty())
3040  {
3041  ol.writeObjectLink(0,n,0,pd->title());
3042  if (addToIndex)
3043  {
3044  Doxygen::indexList->addContentsItem(FALSE,filterTitle(pd->title()),pd->getReference(),n,0,FALSE,TRUE);
3045  }
3046  }
3047  else
3048  {
3049  ol.writeObjectLink(0,n,0,pd->name());
3050  if (addToIndex)
3051  {
3052  Doxygen::indexList->addContentsItem(FALSE,pd->name(),pd->getReference(),n,0,FALSE,TRUE);
3053  }
3054  }
3055  ol.endItemListItem();
3056  ol.writeString("\n");
3057  }
3058  ol.endItemList();
3059 
3060  if (addToIndex)
3061  {
3063  }
3064  endFile(ol);
3065  ol.popGeneratorState();
3066 }
3067 
3068 
3069 //----------------------------------------------------------------------------
3070 
3071 static void countRelatedPages(int &docPages,int &indexPages)
3072 {
3073  docPages=indexPages=0;
3075  PageDef *pd=0;
3076  for (pdi.toFirst();(pd=pdi.current());++pdi)
3077  {
3078  if ( pd->visibleInIndex())
3079  {
3080  indexPages++;
3081  }
3082  if ( pd->documentedPage())
3083  {
3084  docPages++;
3085  }
3086  }
3087 }
3088 
3089 //----------------------------------------------------------------------------
3090 
3091 static bool mainPageHasOwnTitle()
3092 {
3093  static QCString projectName = Config_getString(PROJECT_NAME);
3094  QCString title;
3095  if (Doxygen::mainPage)
3096  {
3097  title = filterTitle(Doxygen::mainPage->title());
3098  }
3099  return !projectName.isEmpty() && mainPageHasTitle() && qstricmp(title,projectName)!=0;
3100 }
3101 
3102 static void writePages(PageDef *pd,FTVHelp *ftv)
3103 {
3104  //printf("writePages()=%s pd=%p mainpage=%p\n",pd->name().data(),pd,Doxygen::mainPage);
3106  bool addToIndex = lne==0 || lne->visible();
3107  if (!addToIndex) return;
3108 
3109  bool hasSubPages = pd->hasSubPages();
3110  bool hasSections = pd->hasSections();
3111 
3112  if (pd->visibleInIndex())
3113  {
3114  QCString pageTitle;
3115 
3116  if (pd->title().isEmpty())
3117  pageTitle=pd->name();
3118  else
3119  pageTitle=filterTitle(pd->title());
3120 
3121  if (ftv)
3122  {
3123  //printf("*** adding %s hasSubPages=%d hasSections=%d\n",pageTitle.data(),hasSubPages,hasSections);
3124  ftv->addContentsItem(
3125  hasSubPages,pageTitle,
3126  pd->getReference(),pd->getOutputFileBase(),
3127  0,hasSubPages,TRUE,pd);
3128  }
3129  if (addToIndex && pd!=Doxygen::mainPage)
3130  {
3132  hasSubPages || hasSections,pageTitle,
3133  pd->getReference(),pd->getOutputFileBase(),
3134  0,hasSubPages,TRUE);
3135  }
3136  }
3137  if (hasSubPages && ftv) ftv->incContentsDepth();
3138  bool doIndent = (hasSections || hasSubPages) &&
3140  if (doIndent)
3141  {
3143  }
3144  if (hasSections)
3145  {
3146  pd->addSectionsToIndex();
3147  }
3148  PageSDict *subPages = pd->getSubPages();
3149  if (subPages)
3150  {
3151  PageSDict::Iterator pi(*subPages);
3152  PageDef *subPage;
3153  for (pi.toFirst();(subPage=pi.current());++pi)
3154  {
3155  writePages(subPage,ftv);
3156  }
3157  }
3158  if (hasSubPages && ftv) ftv->decContentsDepth();
3159  if (doIndent)
3160  {
3162  }
3163  //printf("end writePages()=%s\n",pd->title().data());
3164 }
3165 
3166 //----------------------------------------------------------------------------
3167 
3168 static void writePageIndex(OutputList &ol)
3169 {
3170  if (indexedPages==0) return;
3171  ol.pushGeneratorState();
3174  QCString title = lne ? lne->title() : theTranslator->trRelatedPages();
3175  startFile(ol,"pages",0,title,HLI_Pages);
3176  startTitle(ol,0);
3177  ol.parseText(title);
3178  endTitle(ol,0,0);
3179  ol.startContents();
3180  ol.startTextBlock();
3182  ol.endTextBlock();
3183 
3184  {
3185  FTVHelp* ftv = new FTVHelp(FALSE);
3187  PageDef *pd=0;
3188  for (pdi.toFirst();(pd=pdi.current());++pdi)
3189  {
3190  if ((pd->getOuterScope()==0 ||
3191  pd->getOuterScope()->definitionType()!=Definition::TypePage) && // not a sub page
3192  !pd->isReference() // not an external page
3193  )
3194  {
3195  writePages(pd,ftv);
3196  }
3197  }
3198  QGString outStr;
3199  FTextStream t(&outStr);
3200  ftv->generateTreeViewInline(t);
3201  ol.writeString(outStr);
3202  delete ftv;
3203  }
3204 
3205 // ol.popGeneratorState();
3206  // ------
3207 
3208  endFile(ol);
3209  ol.popGeneratorState();
3210 }
3211 
3212 //----------------------------------------------------------------------------
3213 
3214 static int countGroups()
3215 {
3216  int count=0;
3218  GroupDef *gd;
3219  for (gli.toFirst();(gd=gli.current());++gli)
3220  {
3221  if (!gd->isReference())
3222  {
3223  gd->visited=FALSE;
3224  count++;
3225  }
3226  }
3227  return count;
3228 }
3229 
3230 //----------------------------------------------------------------------------
3231 
3232 static int countDirs()
3233 {
3234  int count=0;
3236  DirDef *dd;
3237  for (dli.toFirst();(dd=dli.current());++dli)
3238  {
3239  if (dd->isLinkableInProject())
3240  {
3241  dd->visited=FALSE;
3242  count++;
3243  }
3244  }
3245  return count;
3246 }
3247 
3248 
3249 //----------------------------------------------------------------------------
3250 
3252 {
3253  if (!Config_getBool(HAVE_DOT) || !Config_getBool(GENERATE_HTML)) return;
3254  ol.pushGeneratorState();
3256  generateGraphLegend(Config_getString(HTML_OUTPUT));
3257 
3258  bool &stripCommentsStateRef = Config_getBool(STRIP_CODE_COMMENTS);
3259  bool oldStripCommentsState = stripCommentsStateRef;
3260  bool &createSubdirs = Config_getBool(CREATE_SUBDIRS);
3261  bool oldCreateSubdirs = createSubdirs;
3262  // temporarily disable the stripping of comments for our own code example!
3263  stripCommentsStateRef = FALSE;
3264  // temporarily disable create subdirs for linking to our example
3265  createSubdirs = FALSE;
3266 
3267  startFile(ol,"graph_legend",0,theTranslator->trLegendTitle().data());
3268  startTitle(ol,0);
3270  endTitle(ol,0,0);
3271  ol.startContents();
3272  QCString legendDocs = theTranslator->trLegendDocs();
3273  int s = legendDocs.find("<center>");
3274  int e = legendDocs.find("</center>");
3275  QCString imgExt = getDotImageExtension();
3276  if (imgExt=="svg" && s!=-1 && e!=-1)
3277  {
3278  legendDocs = legendDocs.left(s+8) + "[!-- SVG 0 --]\n" + legendDocs.mid(e);
3279  //printf("legendDocs=%s\n",legendDocs.data());
3280  }
3281  FileDef fd("","graph_legend");
3282  ol.generateDoc("graph_legend",1,&fd,0,legendDocs,FALSE,FALSE);
3283 
3284  // restore config settings
3285  stripCommentsStateRef = oldStripCommentsState;
3286  createSubdirs = oldCreateSubdirs;
3287 
3288  endFile(ol);
3289  ol.popGeneratorState();
3290 }
3291 
3292 
3293 
3294 //----------------------------------------------------------------------------
3298 static void writeGroupTreeNode(OutputList &ol, GroupDef *gd, int level, FTVHelp* ftv, bool addToIndex)
3299 {
3300  //bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
3301  //bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
3302  if (level>20)
3303  {
3304  warn(gd->getDefFileName(),gd->getDefLine(),
3305  "maximum nesting level exceeded for group %s: check for possible recursive group relation!\n",gd->name().data()
3306  );
3307  return;
3308  }
3309 
3310  /* Some groups should appear twice under different parent-groups.
3311  * That is why we should not check if it was visited
3312  */
3313  if ( (!gd->isASubGroup() || level>0) &&
3314  gd->isVisible() &&
3315  (!gd->isReference() || Config_getBool(EXTERNAL_GROUPS)) // hide external groups by default
3316  )
3317  {
3318  //printf("gd->name()=%s #members=%d\n",gd->name().data(),gd->countMembers());
3319  // write group info
3320  bool hasSubGroups = gd->getSubGroups()->count()>0;
3321  bool hasSubPages = gd->getPages()->count()>0;
3322  int numSubItems = 0;
3323  if (1 /*Config_getBool(TOC_EXPAND)*/)
3324  {
3325  QListIterator<MemberList> mli(gd->getMemberLists());
3326  MemberList *ml;
3327  for (mli.toFirst();(ml=mli.current());++mli)
3328  {
3329  if (ml->listType()&MemberListType_documentationLists)
3330  {
3331  numSubItems += ml->count();
3332  }
3333  }
3334  numSubItems += gd->getNamespaces()->count();
3335  numSubItems += gd->getClasses()->count();
3336  numSubItems += gd->getFiles()->count();
3337  numSubItems += gd->getDirs()->count();
3338  numSubItems += gd->getPages()->count();
3339  }
3340 
3341  bool isDir = hasSubGroups || hasSubPages || numSubItems>0;
3342  //printf("gd=`%s': pageDict=%d\n",gd->name().data(),gd->pageDict->count());
3343  if (addToIndex)
3344  {
3345  Doxygen::indexList->addContentsItem(isDir,gd->groupTitle(),gd->getReference(),gd->getOutputFileBase(),0,isDir,TRUE);
3347  }
3348  if (ftv)
3349  {
3350  ftv->addContentsItem(hasSubGroups,gd->groupTitle(),
3351  gd->getReference(),gd->getOutputFileBase(),0,
3352  FALSE,FALSE,gd);
3353  ftv->incContentsDepth();
3354  }
3355 
3356  //ol.writeListItem();
3357  //ol.startTextLink(gd->getOutputFileBase(),0);
3358  //parseText(ol,gd->groupTitle());
3359  //ol.endTextLink();
3360 
3361  ol.startIndexListItem();
3363  ol.parseText(gd->groupTitle());
3365  if (gd->isReference())
3366  {
3367  ol.startTypewriter();
3368  ol.docify(" [external]");
3369  ol.endTypewriter();
3370  }
3371 
3372  QListIterator<LayoutDocEntry> eli(LayoutDocManager::instance().docEntries(LayoutDocManager::Group));
3373  LayoutDocEntry *lde;
3374  for (eli.toFirst();(lde=eli.current());++eli)
3375  {
3376  if (lde->kind()==LayoutDocEntry::MemberDef && addToIndex)
3377  {
3379  MemberList *ml = gd->getMemberList(lmd->type);
3380  if (ml)
3381  {
3382  MemberListIterator mi(*ml);
3383  MemberDef *md;
3384  for (mi.toFirst();(md=mi.current());++mi)
3385  {
3386  MemberList *enumList = md->enumFieldList();
3387  bool isDir = enumList!=0 && md->isEnumerate();
3388  if (md->isVisible() && md->name().find('@')==-1)
3389  {
3391  md->name(),md->getReference(),
3392  md->getOutputFileBase(),md->anchor(),FALSE,addToIndex);
3393  }
3394  if (isDir)
3395  {
3397  MemberListIterator emli(*enumList);
3398  MemberDef *emd;
3399  for (emli.toFirst();(emd=emli.current());++emli)
3400  {
3401  if (emd->isVisible())
3402  {
3404  emd->name(),emd->getReference(),emd->getOutputFileBase(),
3405  emd->anchor(),FALSE,addToIndex);
3406  }
3407  }
3409  }
3410  }
3411  }
3412  }
3413  else if (lde->kind()==LayoutDocEntry::GroupClasses && addToIndex)
3414  {
3415  ClassSDict::Iterator it(*gd->getClasses());
3416  ClassDef *cd;
3417  for (;(cd=it.current());++it)
3418  {
3419  //bool nestedClassInSameGroup =
3420  // cd->getOuterScope() && cd->getOuterScope()->definitionType()==Definition::TypeClass &&
3421  // cd->getOuterScope()->partOfGroups()!=0 && cd->getOuterScope()->partOfGroups()->contains(gd);
3422  //printf("===== GroupClasses: %s visible=%d nestedClassInSameGroup=%d\n",cd->name().data(),cd->isVisible(),nestedClassInSameGroup);
3423  if (cd->isVisible() /*&& !nestedClassInSameGroup*/)
3424  {
3425  //if (cd->isEmbeddedInOuterScope())
3426  //{
3427  //printf("add class & members %d\n",addToIndex);
3428  addMembersToIndex(cd,LayoutDocManager::Class,cd->displayName(FALSE),cd->anchor(),addToIndex,TRUE);
3429  //}
3430  //else // only index the class, not its members
3431  //{
3432  // printf("%s: add class only\n",cd->name().data());
3433  // Doxygen::indexList->addContentsItem(FALSE,
3434  // cd->displayName(TRUE),cd->getReference(),
3435  // cd->getOutputFileBase(),cd->anchor(),addToIndex,TRUE);
3436  //}
3437  }
3438  }
3439  }
3440  else if (lde->kind()==LayoutDocEntry::GroupNamespaces && addToIndex)
3441  {
3443  NamespaceDef *nd;
3444  for (;(nd=it.current());++it)
3445  {
3446  if (nd->isVisible())
3447  {
3449  nd->localName(),nd->getReference(),
3450  nd->getOutputFileBase(),0,FALSE,FALSE);
3451  }
3452  }
3453  }
3454  else if (lde->kind()==LayoutDocEntry::GroupFiles && addToIndex)
3455  {
3456  QListIterator<FileDef> it(*gd->getFiles());
3457  FileDef *fd;
3458  for (;(fd=it.current());++it)
3459  {
3460  if (fd->isVisible())
3461  {
3463  fd->displayName(),fd->getReference(),
3464  fd->getOutputFileBase(),0,FALSE,FALSE);
3465  }
3466  }
3467  }
3468  else if (lde->kind()==LayoutDocEntry::GroupDirs && addToIndex)
3469  {
3470  QListIterator<DirDef> it(*gd->getDirs());
3471  DirDef *dd;
3472  for (;(dd=it.current());++it)
3473  {
3474  if (dd->isVisible())
3475  {
3477  dd->shortName(),dd->getReference(),
3478  dd->getOutputFileBase(),0,FALSE,FALSE);
3479  }
3480  }
3481  }
3482  else if (lde->kind()==LayoutDocEntry::GroupPageDocs && addToIndex)
3483  {
3485  PageDef *pd;
3486  for (;(pd=it.current());++it)
3487  {
3488  SectionInfo *si=0;
3489  if (!pd->name().isEmpty()) si=Doxygen::sectionDict->find(pd->name());
3490  bool hasSubPages = pd->hasSubPages();
3491  bool hasSections = pd->hasSections();
3493  hasSubPages || hasSections,
3494  convertToHtml(pd->title(),TRUE),
3495  gd->getReference(),
3496  gd->getOutputFileBase(),
3497  si ? si->label.data() : 0,
3498  hasSubPages || hasSections,
3499  TRUE); // addToNavIndex
3500  if (hasSections || hasSubPages)
3501  {
3503  }
3504  if (hasSections)
3505  {
3506  pd->addSectionsToIndex();
3507  }
3508  writePages(pd,0);
3509  if (hasSections || hasSubPages)
3510  {
3512  }
3513  }
3514  }
3515  else if (lde->kind()==LayoutDocEntry::GroupNestedGroups)
3516  {
3517  if (gd->getSubGroups()->count()>0)
3518  {
3519  startIndexHierarchy(ol,level+1);
3520  QListIterator<GroupDef> gli(*gd->getSubGroups());
3521  GroupDef *subgd = 0;
3522  for (gli.toFirst();(subgd=gli.current());++gli)
3523  {
3524  writeGroupTreeNode(ol,subgd,level+1,ftv,addToIndex);
3525  }
3526  endIndexHierarchy(ol,level+1);
3527  }
3528  }
3529  }
3530 
3531  ol.endIndexListItem();
3532 
3533  if (addToIndex)
3534  {
3536  }
3537  if (ftv)
3538  {
3539  ftv->decContentsDepth();
3540  }
3541  //gd->visited=TRUE;
3542  }
3543 }
3544 
3545 static void writeGroupHierarchy(OutputList &ol, FTVHelp* ftv,bool addToIndex)
3546 {
3547  if (ftv)
3548  {
3549  ol.pushGeneratorState();
3551  }
3552  startIndexHierarchy(ol,0);
3554  GroupDef *gd;
3555  for (gli.toFirst();(gd=gli.current());++gli)
3556  {
3557  writeGroupTreeNode(ol,gd,0,ftv,addToIndex);
3558  }
3559  endIndexHierarchy(ol,0);
3560  if (ftv)
3561  {
3562  ol.popGeneratorState();
3563  }
3564 }
3565 
3566 #if 0
3567 static void writeGroupTree(GroupDef *gd,FTVHelp *ftv,int level,bool addToIndex)
3568 {
3569  static bool externalGroups = Config_getBool(EXTERNAL_GROUPS);
3570  /* Some groups should appear twice under different parent-groups.
3571  * That is why we should not check if it was visited
3572  */
3573  if ((!gd->isASubGroup() || level>0) &&
3574  gd->isVisible() &&
3575  (!gd->isReference() || externalGroups) // hide external groups by default
3576  )
3577  {
3578  if (ftv)
3579  {
3580  ftv->addContentsItem(hasSubGroups,gd->groupTitle(),gd->getReference(),gd->getOutputFileBase(),0);
3581  ftv->incContentsDepth();
3582  }
3583  if (ftv)
3584  {
3585  ftv->decContentsDepth();
3586  }
3587  }
3588 }
3589 
3590 static void writeGroupTree(FTVHelp *ftv,bool addToIndex)
3591 {
3593  GroupDef *gd;
3594  for (gli.toFirst();(gd=gli.current());++gli)
3595  {
3596  writeGroupTree(gd,ftv,0,addToIndex);
3597  }
3598 }
3599 #endif
3600 
3601 //----------------------------------------------------------------------------
3602 
3603 static void writeGroupIndex(OutputList &ol)
3604 {
3605  if (documentedGroups==0) return;
3606  ol.pushGeneratorState();
3607  // 1.{
3610  QCString title = lne ? lne->title() : theTranslator->trModules();
3611  bool addToIndex = lne==0 || lne->visible();
3612 
3613  startFile(ol,"modules",0,title,HLI_Modules);
3614  startTitle(ol,0);
3615  ol.parseText(title);
3616  endTitle(ol,0,0);
3617  ol.startContents();
3618  ol.startTextBlock();
3619  ol.parseText(lne ? lne->intro() : theTranslator->trModulesDescription());
3620  ol.endTextBlock();
3621 
3622  // ---------------
3623  // Normal group index for Latex/RTF
3624  // ---------------
3625  // 2.{
3626  ol.pushGeneratorState();
3629 
3630  writeGroupHierarchy(ol,0,FALSE);
3631 
3633  ol.popGeneratorState();
3634  // 2.}
3635 
3636  // ---------------
3637  // interactive group index for HTML
3638  // ---------------
3639  // 2.{
3640  ol.pushGeneratorState();
3642 
3643  {
3644  if (addToIndex)
3645  {
3646  Doxygen::indexList->addContentsItem(TRUE,title,0,"modules",0,TRUE,TRUE);
3648  }
3649  FTVHelp* ftv = new FTVHelp(FALSE);
3650  writeGroupHierarchy(ol,ftv,addToIndex);
3651  QGString outStr;
3652  FTextStream t(&outStr);
3653  ftv->generateTreeViewInline(t);
3655  ol.writeString(outStr);
3656  delete ftv;
3657  if (addToIndex)
3658  {
3660  }
3661  }
3662  ol.popGeneratorState();
3663  // 2.}
3664 
3665  endFile(ol);
3666  ol.popGeneratorState();
3667  // 1.}
3668 }
3669 
3670 //----------------------------------------------------------------------------
3671 
3672 #if 0
3673 static void writeDirIndex(OutputList &ol)
3674 {
3675  if (documentedDirs==0) return;
3676  ol.pushGeneratorState();
3678  LayoutNavEntry *lne = LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Dirs);
3679  QCString title = lne ? lne->title() : theTranslator->trDirectories();
3680  bool addToIndex=FALSE; //lne==0 || lne->visible();
3681 
3682  startFile(ol,"dirs",0,title,HLI_Directories);
3683  startTitle(ol,0);
3684  ol.parseText(title);
3685  endTitle(ol,0,0);
3686  ol.startContents();
3687  ol.startTextBlock();
3688 
3689  if (addToIndex)
3690  {
3691  Doxygen::indexList->addContentsItem(TRUE,title,0,"dirs",0,TRUE,TRUE);
3693  }
3694  ol.parseText(lne ? lne->intro() : theTranslator->trDirDescription());
3695  ol.endTextBlock();
3696 
3697  FTVHelp* ftv = 0;
3698  bool treeView=Config_getBool(USE_INLINE_TREES);
3699  if (treeView)
3700  {
3701  ftv = new FTVHelp(FALSE);
3702  }
3703 
3704  writeDirHierarchy(ol,ftv,addToIndex);
3705 
3706  if (ftv)
3707  {
3708  QGString outStr;
3709  FTextStream t(&outStr);
3710  ftv->generateTreeViewInline(t);
3711  ol.pushGeneratorState();
3713  ol.writeString(outStr);
3714  ol.popGeneratorState();
3715  delete ftv;
3716  }
3717  if (addToIndex)
3718  {
3720  }
3721  endFile(ol);
3722  ol.popGeneratorState();
3723 }
3724 #endif
3725 
3726 //----------------------------------------------------------------------------
3727 
3729 {
3730  if (lne->baseFile().left(9)=="usergroup")
3731  {
3732  ol.pushGeneratorState();
3734  startFile(ol,lne->baseFile(),0,lne->title(),HLI_UserGroup);
3735  startTitle(ol,0);
3736  ol.parseText(lne->title());
3737  endTitle(ol,0,0);
3738  ol.startContents();
3739  QListIterator<LayoutNavEntry> li(lne->children());
3740  LayoutNavEntry *entry;
3741  int count=0;
3742  for (li.toFirst();(entry=li.current());++li)
3743  {
3744  if (entry->visible()) count++;
3745  }
3746  if (count>0)
3747  {
3748  ol.writeString("<ul>\n");
3749  for (li.toFirst();(entry=li.current());++li)
3750  {
3751  if (entry->visible())
3752  {
3753  ol.writeString("<li><a href=\""+entry->url()+"\"><span>"+
3754  fixSpaces(entry->title())+"</span></a></li>\n");
3755  }
3756  }
3757  ol.writeString("</ul>\n");
3758  }
3759  endFile(ol);
3760  ol.popGeneratorState();
3761  }
3762 }
3763 
3764 //----------------------------------------------------------------------------
3765 
3766 
3767 static void writeIndex(OutputList &ol)
3768 {
3769  static bool fortranOpt = Config_getBool(OPTIMIZE_FOR_FORTRAN);
3770  static bool vhdlOpt = Config_getBool(OPTIMIZE_OUTPUT_VHDL);
3771  static QCString projectName = Config_getString(PROJECT_NAME);
3772  // save old generator state
3773  ol.pushGeneratorState();
3774 
3775  QCString projPrefix;
3776  if (!projectName.isEmpty())
3777  {
3778  projPrefix=projectName+" ";
3779  }
3780 
3781  //--------------------------------------------------------------------
3782  // write HTML index
3783  //--------------------------------------------------------------------
3785 
3786  QCString defFileName =
3787  Doxygen::mainPage ? Doxygen::mainPage->docFile().data() : "[generated]";
3788  int defLine =
3790 
3791  QCString title;
3792  if (!mainPageHasTitle())
3793  {
3794  title = theTranslator->trMainPage();
3795  }
3796  else if (Doxygen::mainPage)
3797  {
3798  title = filterTitle(Doxygen::mainPage->title());
3799  }
3800 
3801  QCString indexName="index";
3802  ol.startFile(indexName,0,title);
3803 
3804  if (Doxygen::mainPage)
3805  {
3806  if (
3807  (!projectName.isEmpty() && mainPageHasTitle() && qstricmp(title,projectName)!=0)
3808  ) // to avoid duplicate entries in the treeview
3809  {
3810  Doxygen::indexList->addContentsItem(Doxygen::mainPage->hasSubPages(),title,0,indexName,0,Doxygen::mainPage->hasSubPages(),TRUE);
3811  }
3812  if (Doxygen::mainPage->hasSubPages() || Doxygen::mainPage->hasSections())
3813  {
3815  }
3816  }
3817 
3818  ol.startQuickIndices();
3819  if (!Config_getBool(DISABLE_INDEX))
3820  {
3821  ol.writeQuickLinks(TRUE,HLI_Main,0);
3822  }
3823  ol.endQuickIndices();
3824  ol.writeSplitBar(indexName);
3825  ol.writeSearchInfo();
3826  bool headerWritten=FALSE;
3827  if (Doxygen::mainPage && !Doxygen::mainPage->title().isEmpty())
3828  {
3829  if (Doxygen::mainPage->title().lower()!="notitle")
3830  {
3831  ol.startHeaderSection();
3832  ol.startTitleHead(0);
3833  ol.generateDoc(Doxygen::mainPage->docFile(),Doxygen::mainPage->docLine(),
3835  TRUE,FALSE,0,TRUE,FALSE);
3836  headerWritten = TRUE;
3837  }
3838  }
3839  else
3840  {
3841  if (!projectName.isEmpty())
3842  {
3843  ol.startHeaderSection();
3844  ol.startTitleHead(0);
3845  ol.parseText(projPrefix+theTranslator->trDocumentation());
3846  headerWritten = TRUE;
3847  }
3848  }
3849  if (headerWritten)
3850  {
3851  ol.endTitleHead(0,0);
3852  ol.endHeaderSection();
3853  }
3854 
3855  ol.startContents();
3856  if (Config_getBool(DISABLE_INDEX) && Doxygen::mainPage==0)
3857  {
3858  ol.writeQuickLinks(FALSE,HLI_Main,0);
3859  }
3860 
3861  if (Doxygen::mainPage)
3862  {
3864  if (Doxygen::mainPage->showToc() && Doxygen::mainPage->hasSections())
3865  {
3867  }
3868 
3869  ol.startTextBlock();
3870  ol.generateDoc(defFileName,defLine,Doxygen::mainPage,0,
3871  Doxygen::mainPage->documentation(),TRUE,FALSE
3872  /*,Doxygen::mainPage->sectionDict*/);
3873  ol.endTextBlock();
3874 
3876  }
3877 
3878  endFile(ol);
3880 
3881  //--------------------------------------------------------------------
3882  // write LaTeX/RTF index
3883  //--------------------------------------------------------------------
3886 
3887  ol.startFile("refman",0,0);
3889  if (!Config_getString(LATEX_HEADER).isEmpty())
3890  {
3892  }
3893 
3894  if (projPrefix.isEmpty())
3895  {
3897  }
3898  else
3899  {
3900  ol.parseText(projPrefix);
3901  }
3902 
3903  if (!Config_getString(PROJECT_NUMBER).isEmpty())
3904  {
3905  ol.startProjectNumber();
3906  ol.generateDoc(defFileName,defLine,Doxygen::mainPage,0,Config_getString(PROJECT_NUMBER),FALSE,FALSE);
3907  ol.endProjectNumber();
3908  }
3914 
3915  ol.lastIndexPage();
3916  if (Doxygen::mainPage)
3917  {
3919  if (mainPageHasTitle())
3920  {
3921  ol.parseText(Doxygen::mainPage->title());
3922  }
3923  else
3924  {
3925  ol.parseText(/*projPrefix+*/theTranslator->trMainPage());
3926  }
3928  }
3929  if (documentedPages>0)
3930  {
3931  //ol.parseText(projPrefix+theTranslator->trPageDocumentation());
3932  //ol.endIndexSection(isPageDocumentation);
3934  PageDef *pd=pdi.toFirst();
3935  bool first=Doxygen::mainPage==0;
3936  for (pdi.toFirst();(pd=pdi.current());++pdi)
3937  {
3938  if (!pd->getGroupDef() && !pd->isReference() &&
3939  (!pd->hasParentPage() || // not inside other page
3940  (Doxygen::mainPage==pd->getOuterScope())) // or inside main page
3941  )
3942  {
3943  bool isCitationPage = pd->name()=="citelist";
3944  if (isCitationPage)
3945  {
3946  // For LaTeX the bibliograph is already written by \bibliography
3947  ol.pushGeneratorState();
3949  }
3950  QCString title = pd->title();
3951  if (title.isEmpty()) title=pd->name();
3952 
3954  ol.parseText(title);
3956 
3957  ol.pushGeneratorState(); // write TOC title (RTF only)
3960  ol.parseText(title);
3962  ol.popGeneratorState();
3963 
3964  ol.writeAnchor(0,pd->getOutputFileBase());
3965 
3966  ol.writePageLink(pd->getOutputFileBase(),first);
3967  first=FALSE;
3968 
3969  if (isCitationPage)
3970  {
3971  ol.popGeneratorState();
3972  }
3973  }
3974  }
3975  }
3976 
3977  if (!Config_getBool(LATEX_HIDE_INDICES))
3978  {
3979  //if (indexedPages>0)
3980  //{
3981  // ol.startIndexSection(isPageIndex);
3982  // ol.parseText(/*projPrefix+*/ theTranslator->trPageIndex());
3983  // ol.endIndexSection(isPageIndex);
3984  //}
3985  if (documentedGroups>0)
3986  {
3988  ol.parseText(/*projPrefix+*/ theTranslator->trModuleIndex());
3990  }
3991  if (documentedNamespaces>0)
3992  {
3994  ol.parseText(/*projPrefix+*/(fortranOpt?theTranslator->trModulesIndex():theTranslator->trNamespaceIndex()));
3996  }
3997  if (hierarchyClasses>0)
3998  {
4000  ol.parseText(/*projPrefix+*/
4001  (fortranOpt ? theTranslator->trCompoundIndexFortran() :
4002  vhdlOpt ? VhdlDocGen::trDesignUnitIndex() :
4004  ));
4006  }
4008  {
4010  ol.parseText(/*projPrefix+*/
4011  (fortranOpt ? theTranslator->trCompoundIndexFortran() :
4012  vhdlOpt ? VhdlDocGen::trDesignUnitIndex() :
4014  ));
4016  }
4017  if (documentedFiles>0)
4018  {
4020  ol.parseText(/*projPrefix+*/theTranslator->trFileIndex());
4022  }
4023  }
4024  if (documentedGroups>0)
4025  {
4027  ol.parseText(/*projPrefix+*/theTranslator->trModuleDocumentation());
4029  }
4030  if (documentedNamespaces>0)
4031  {
4035  }
4037  {
4039  ol.parseText(/*projPrefix+*/(fortranOpt?theTranslator->trTypeDocumentation():theTranslator->trClassDocumentation()));
4041  }
4042  if (documentedFiles>0)
4043  {
4045  ol.parseText(/*projPrefix+*/theTranslator->trFileDocumentation());
4047  }
4048  if (Doxygen::exampleSDict->count()>0)
4049  {
4051  ol.parseText(/*projPrefix+*/theTranslator->trExampleDocumentation());
4053  }
4055  endFile(ol);
4056 
4057  if (Doxygen::mainPage)
4058  {
4061  startFile(ol,Doxygen::mainPage->name(),0,Doxygen::mainPage->title());
4062  ol.startContents();
4063  ol.startTextBlock();
4064  ol.generateDoc(defFileName,defLine,Doxygen::mainPage,0,
4065  Doxygen::mainPage->documentation(),FALSE,FALSE
4066  );
4067  ol.endTextBlock();
4068  endFile(ol);
4071  }
4072 
4073  ol.popGeneratorState();
4074 }
4075 
4076 static QArray<bool> indexWritten;
4077 
4078 static void writeIndexHierarchyEntries(OutputList &ol,const QList<LayoutNavEntry> &entries)
4079 {
4080  QListIterator<LayoutNavEntry> li(entries);
4081  LayoutNavEntry *lne;
4082  for (li.toFirst();(lne=li.current());++li)
4083  {
4084  LayoutNavEntry::Kind kind = lne->kind();
4085  uint index = (uint)kind;
4086  if (index>=indexWritten.size())
4087  {
4088  uint i;
4089  uint oldSize = indexWritten.size();
4090  uint newSize = index+1;
4091  indexWritten.resize(newSize);
4092  for (i=oldSize;i<newSize;i++) indexWritten.at(i)=FALSE;
4093  }
4094  //printf("starting %s kind=%d\n",lne->title().data(),lne->kind());
4095  bool addToIndex=lne->visible();
4096  bool needsClosing=FALSE;
4097  if (!indexWritten.at(index))
4098  {
4099  switch(kind)
4100  {
4102  msg("Generating index page...\n");
4103  writeIndex(ol);
4104  break;
4105  case LayoutNavEntry::Pages:
4106  msg("Generating page index...\n");
4107  writePageIndex(ol);
4108  break;
4110  msg("Generating module index...\n");
4111  writeGroupIndex(ol);
4112  break;
4114  {
4115  static bool showNamespaces = Config_getBool(SHOW_NAMESPACES);
4116  if (showNamespaces)
4117  {
4118  if (documentedNamespaces>0 && addToIndex)
4119  {
4120  Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,0,0);
4122  needsClosing=TRUE;
4123  }
4124  if (LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Namespaces)!=lne) // for backward compatibility with old layout file
4125  {
4126  msg("Generating namespace index...\n");
4127  writeNamespaceIndex(ol);
4128  }
4129  }
4130  }
4131  break;
4133  {
4134  static bool showNamespaces = Config_getBool(SHOW_NAMESPACES);
4135  if (showNamespaces)
4136  {
4137  msg("Generating namespace index...\n");
4138  writeNamespaceIndex(ol);
4139  }
4140  }
4141  break;
4143  msg("Generating namespace member index...\n");
4145  break;
4147  if (annotatedClasses>0 && addToIndex)
4148  {
4149  Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,"annotated",0);
4151  needsClosing=TRUE;
4152  }
4153  if (LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Classes)!=lne) // for backward compatibility with old layout file
4154  {
4155  msg("Generating annotated compound index...\n");
4156  writeAnnotatedIndex(ol);
4157  }
4158  break;
4160  msg("Generating annotated compound index...\n");
4161  writeAnnotatedIndex(ol);
4162  break;
4164  msg("Generating alphabetical compound index...\n");
4166  break;
4168  msg("Generating hierarchical class index...\n");
4170  if (Config_getBool(HAVE_DOT) && Config_getBool(GRAPHICAL_HIERARCHY))
4171  {
4172  msg("Generating graphical class hierarchy...\n");
4174  }
4175  break;
4177  msg("Generating member index...\n");
4179  break;
4180  case LayoutNavEntry::Files:
4181  {
4182  static bool showFiles = Config_getBool(SHOW_FILES);
4183  if (showFiles)
4184  {
4185  if (documentedHtmlFiles>0 && addToIndex)
4186  {
4187  Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,0,0);
4189  needsClosing=TRUE;
4190  }
4191  if (LayoutDocManager::instance().rootNavEntry()->find(LayoutNavEntry::Files)!=lne) // for backward compatibility with old layout file
4192  {
4193  msg("Generating file index...\n");
4194  writeFileIndex(ol);
4195  }
4196  }
4197  }
4198  break;
4200  {
4201  static bool showFiles = Config_getBool(SHOW_FILES);
4202  if (showFiles)
4203  {
4204  msg("Generating file index...\n");
4205  writeFileIndex(ol);
4206  }
4207  }
4208  break;
4210  msg("Generating file member index...\n");
4212  break;
4214  msg("Generating example index...\n");
4215  writeExampleIndex(ol);
4216  break;
4217  case LayoutNavEntry::User:
4218  {
4219  // prepend a ! or ^ marker to the URL to avoid tampering with it
4220  QCString url = correctURL(lne->url(),"!"); // add ! to relative URL
4221  bool isRelative=url.at(0)=='!';
4222  if (!url.isEmpty() && !isRelative) // absolute URL
4223  {
4224  url.prepend("^"); // prepend ^ to absolute URL
4225  }
4226  bool isRef = lne->baseFile().left(4)=="@ref" || lne->baseFile().left(4)=="\\ref";
4227  Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,url,0,FALSE,isRef || isRelative);
4228  }
4229  break;
4231  if (addToIndex)
4232  {
4233  QCString url = correctURL(lne->url(),"!"); // add ! to relative URL
4234  if (!url.isEmpty())
4235  {
4236  if (url=="![none]")
4237  {
4238  Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,0,0,FALSE,FALSE);
4239  }
4240  else
4241  {
4242  bool isRelative=url.at(0)=='!';
4243  if (!isRelative) // absolute URL
4244  {
4245  url.prepend("^"); // prepend ^ to absolute URL
4246  }
4247  bool isRef = lne->baseFile().left(4)=="@ref" || lne->baseFile().left(4)=="\\ref";
4248  Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,url,0,FALSE,isRef || isRelative);
4249  }
4250  }
4251  else
4252  {
4253  Doxygen::indexList->addContentsItem(TRUE,lne->title(),0,lne->baseFile(),0,TRUE,TRUE);
4254  }
4256  needsClosing=TRUE;
4257  }
4258  writeUserGroupStubPage(ol,lne);
4259  break;
4260  }
4261  if (kind!=LayoutNavEntry::User && kind!=LayoutNavEntry::UserGroup) // User entry may appear multiple times
4262  {
4263  indexWritten.at(index)=TRUE;
4264  }
4265  }
4267  if (needsClosing)
4268  {
4269  switch(kind)
4270  {
4273  case LayoutNavEntry::Files:
4276  break;
4277  default:
4278  break;
4279  }
4280  }
4281  //printf("ending %s kind=%d\n",lne->title().data(),lne->kind());
4282  }
4283 }
4284 
4286 {
4287  static bool showFiles = Config_getBool(SHOW_FILES);
4288  static bool showNamespaces = Config_getBool(SHOW_NAMESPACES);
4289  switch (kind)
4290  {
4291  case LayoutNavEntry::MainPage: return TRUE;
4292  case LayoutNavEntry::User: return TRUE;
4293  case LayoutNavEntry::UserGroup: return TRUE;
4294  case LayoutNavEntry::Pages: return indexedPages>0;
4296  case LayoutNavEntry::Namespaces: return documentedNamespaces>0 && showNamespaces;
4297  case LayoutNavEntry::NamespaceList: return documentedNamespaces>0 && showNamespaces;
4304  case LayoutNavEntry::Files: return documentedHtmlFiles>0 && showFiles;
4305  case LayoutNavEntry::FileList: return documentedHtmlFiles>0 && showFiles;
4307  //case LayoutNavEntry::Dirs: return documentedDirs>0;
4309  }
4310  return FALSE;
4311 }
4312 
4313 template<class T>
4315  int total,const int *numDocumented,const LetterToIndexMap<MemberIndexList> *memberLists,
4316  const T *(*getInfo)(int hl))
4317 {
4318  // index items per category member lists
4319  bool firstMember=TRUE;
4320  for (int i=0;i<total;i++)
4321  {
4322  if (numDocumented[i]>0)
4323  {
4324  t << ",";
4325  if (firstMember)
4326  {
4327  t << "children:[";
4328  firstMember=FALSE;
4329  }
4330  t << endl << "{text:'" << convertToJSString(getInfo(i)->title) << "',url:'"
4331  << convertToJSString(getInfo(i)->fname+Doxygen::htmlFileExtension) << "'";
4332 
4333  // Check if we have many members, then add sub entries per letter...
4334  // quick alphabetical index
4335  bool quickIndex = numDocumented[i]>maxItemsBeforeQuickIndex;
4336  if (quickIndex)
4337  {
4338  bool multiPageIndex=FALSE;
4339  if (numDocumented[i]>MAX_ITEMS_BEFORE_MULTIPAGE_INDEX)
4340  {
4341  multiPageIndex=TRUE;
4342  }
4343  t << ",children:[" << endl;
4344  bool firstLetter=TRUE;
4345  SIntDict<MemberIndexList>::Iterator it(memberLists[i]);
4346  MemberIndexList *ml;
4347  for (it.toFirst();(ml=it.current());++it)
4348  {
4349  if (!firstLetter) t << "," << endl;
4350  uint letter = ml->letter();
4351  QCString is = letterToLabel(letter);
4352  QCString ci = QString(QChar(letter)).utf8();
4353  QCString anchor;
4354  QCString extension=Doxygen::htmlFileExtension;
4355  QCString fullName = getInfo(i)->fname;
4356  if (!multiPageIndex || firstLetter)
4357  anchor=fullName+extension+"#index_";
4358  else // other pages of multi page index
4359  anchor=fullName+"_"+is+extension+"#index_";
4360  t << "{text:'" << convertToJSString(ci) << "',url:'"
4361  << convertToJSString(anchor+is) << "'}";
4362  firstLetter=FALSE;
4363  }
4364  t << "]";
4365  }
4366  t << "}";
4367  }
4368  }
4369  if (!firstMember)
4370  {
4371  t << "]";
4372  }
4373 }
4374 
4375 static bool renderQuickLinksAsJs(FTextStream &t,LayoutNavEntry *root,bool first)
4376 {
4377  QListIterator<LayoutNavEntry> li(root->children());
4378  LayoutNavEntry *entry;
4379  int count=0;
4380  for (li.toFirst();(entry=li.current());++li)
4381  {
4382  if (entry->visible() && quickLinkVisible(entry->kind())) count++;
4383  }
4384  if (count>0) // at least one item is visible
4385  {
4386  bool firstChild = TRUE;
4387  if (!first) t << ",";
4388  t << "children:[" << endl;
4389  for (li.toFirst();(entry=li.current());++li)
4390  {
4391  if (entry->visible() && quickLinkVisible(entry->kind()))
4392  {
4393  if (!firstChild) t << "," << endl;
4394  firstChild=FALSE;
4395  QCString url = entry->url();
4396  t << "{text:'" << convertToJSString(entry->title()) << "',url:'"
4397  << convertToJSString(url) << "'";
4398  bool hasChildren=FALSE;
4399  if (entry->kind()==LayoutNavEntry::NamespaceMembers)
4400  {
4402  g_namespaceIndexLetterUsed,getNmhlInfo);
4403  }
4404  else if (entry->kind()==LayoutNavEntry::ClassMembers)
4405  {
4407  g_memberIndexLetterUsed,getCmhlInfo);
4408  }
4409  else if (entry->kind()==LayoutNavEntry::FileGlobals)
4410  {
4412  g_fileIndexLetterUsed,getFmhlInfo);
4413  }
4414  else // recursive into child list
4415  {
4416  hasChildren = renderQuickLinksAsJs(t,entry,FALSE);
4417  }
4418  if (hasChildren) t << "]";
4419  t << "}";
4420  }
4421  }
4422  }
4423  return count>0;
4424 }
4425 
4426 static void writeMenuData()
4427 {
4428  if (!Config_getBool(GENERATE_HTML) || Config_getBool(DISABLE_INDEX)) return;
4429  QCString outputDir = Config_getBool(HTML_OUTPUT);
4430  QFile f(outputDir+"/menudata.js");
4432  if (f.open(IO_WriteOnly))
4433  {
4434  FTextStream t(&f);
4435  t << "var menudata={";
4436  bool hasChildren = renderQuickLinksAsJs(t,root,TRUE);
4437  if (hasChildren) t << "]";
4438  t << "}" << endl;
4439  }
4440 }
4441 
4443 {
4444  writeMenuData();
4446  if (lne)
4447  {
4449  }
4450 }
4451