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