Orb/Doxygen/src/groupdef.cpp
changeset 0 42188c7ea2d9
child 4 468f4c8d3d5b
equal deleted inserted replaced
-1:000000000000 0:42188c7ea2d9
       
     1 /******************************************************************************
       
     2  *
       
     3  * 
       
     4  *
       
     5  * Copyright (C) 1997-2008 by Dimitri van Heesch.
       
     6  *
       
     7  * Permission to use, copy, modify, and distribute this software and its
       
     8  * documentation under the terms of the GNU General Public License is hereby 
       
     9  * granted. No representations are made about the suitability of this software 
       
    10  * for any purpose. It is provided "as is" without express or implied warranty.
       
    11  * See the GNU General Public License for more details.
       
    12  *
       
    13  * Documents produced by Doxygen are derivative works derived from the
       
    14  * input used in their production; they are not affected by this license.
       
    15  *
       
    16  */
       
    17 
       
    18 #include <ctype.h>
       
    19 #include <qregexp.h>
       
    20 #include "qtbc.h"
       
    21 #include "groupdef.h"
       
    22 #include "classdef.h"
       
    23 #include "filedef.h"
       
    24 #include "classlist.h"
       
    25 #include "outputlist.h"
       
    26 #include "namespacedef.h"
       
    27 #include "language.h"
       
    28 #include "util.h"
       
    29 #include "memberlist.h"
       
    30 #include "message.h"
       
    31 #include "membergroup.h"
       
    32 #include "doxygen.h"
       
    33 #include "pagedef.h"
       
    34 #include "docparser.h"
       
    35 #include "searchindex.h"
       
    36 #include "dot.h"
       
    37 #include "vhdldocgen.h"
       
    38 #include "layout.h"
       
    39 
       
    40 //---------------------------------------------------------------------------
       
    41 
       
    42 GroupDef::GroupDef(const char *df,int dl,const char *na,const char *t,
       
    43                    const char *refFileName) : Definition(df,dl,na)
       
    44 {
       
    45   fileList = new FileList;
       
    46   classSDict = new ClassSDict(17);
       
    47   groupList = new GroupList;
       
    48   namespaceSDict = new NamespaceSDict(17);
       
    49   pageDict = new PageSDict(17);
       
    50   exampleDict = new PageSDict(17);
       
    51   dirList = new DirList;
       
    52   allMemberNameInfoSDict = new MemberNameInfoSDict(17);
       
    53   if (refFileName)
       
    54   {
       
    55     fileName=stripExtension(refFileName);
       
    56   }
       
    57   else
       
    58   {
       
    59     fileName = (QCString)"group_"+na;
       
    60   }
       
    61   setGroupTitle( t );
       
    62   memberGroupSDict = new MemberGroupSDict;
       
    63   memberGroupSDict->setAutoDelete(TRUE);
       
    64 
       
    65   allMemberList = new MemberList(MemberList::allMembersList);
       
    66 
       
    67   visited = 0;
       
    68   groupScope = 0;
       
    69 }
       
    70 
       
    71 GroupDef::~GroupDef()
       
    72 {
       
    73   delete fileList;
       
    74   delete classSDict;
       
    75   delete groupList;
       
    76   delete namespaceSDict;
       
    77   delete pageDict;
       
    78   delete exampleDict;
       
    79   delete allMemberList;
       
    80   delete allMemberNameInfoSDict;
       
    81   delete memberGroupSDict;
       
    82   delete dirList;
       
    83 }
       
    84 
       
    85 void GroupDef::setGroupTitle( const char *t )
       
    86 {
       
    87   if ( t && strlen(t) )
       
    88   {
       
    89     title = t;
       
    90     titleSet = TRUE;
       
    91   }
       
    92   else
       
    93   {
       
    94     title = name();
       
    95     title.at(0)=toupper(title.at(0));
       
    96     titleSet = FALSE;
       
    97   }
       
    98 }
       
    99 
       
   100 
       
   101 void GroupDef::distributeMemberGroupDocumentation()
       
   102 {
       
   103   MemberGroupSDict::Iterator mgli(*memberGroupSDict);
       
   104   MemberGroup *mg;
       
   105   for (;(mg=mgli.current());++mgli)
       
   106   {
       
   107     mg->distributeMemberGroupDocumentation();
       
   108   }
       
   109 }
       
   110 
       
   111 void GroupDef::findSectionsInDocumentation()
       
   112 {
       
   113   docFindSections(documentation(),this,0,docFile());
       
   114   MemberGroupSDict::Iterator mgli(*memberGroupSDict);
       
   115   MemberGroup *mg;
       
   116   for (;(mg=mgli.current());++mgli)
       
   117   {
       
   118     mg->findSectionsInDocumentation();
       
   119   }
       
   120 
       
   121   QListIterator<MemberList> mli(m_memberLists);
       
   122   MemberList *ml;
       
   123   for (mli.toFirst();(ml=mli.current());++mli)
       
   124   {
       
   125     if (ml->listType()&MemberList::declarationLists)
       
   126     {
       
   127       ml->findSectionsInDocumentation();
       
   128     }
       
   129   }
       
   130 }
       
   131 
       
   132 void GroupDef::addFile(const FileDef *def)
       
   133 {
       
   134   if (def->isHidden()) return;
       
   135   if (Config_getBool("SORT_BRIEF_DOCS"))
       
   136     fileList->inSort(def);
       
   137   else
       
   138     fileList->append(def);
       
   139 }
       
   140 
       
   141 bool GroupDef::addClass(const ClassDef *cd)
       
   142 {
       
   143   if (cd->isHidden()) return FALSE;
       
   144   if (classSDict->find(cd->name())==0)
       
   145   {
       
   146     if (Config_getBool("SORT_BRIEF_DOCS"))
       
   147       classSDict->inSort(cd->name(),cd);
       
   148     else
       
   149       classSDict->append(cd->name(),cd);
       
   150     return TRUE;
       
   151   }
       
   152   return FALSE;
       
   153 }
       
   154 
       
   155 bool GroupDef::addNamespace(const NamespaceDef *def)
       
   156 {
       
   157   if (def->isHidden()) return FALSE;
       
   158   if (namespaceSDict->find(def->name())==0)
       
   159   {
       
   160     if (Config_getBool("SORT_BRIEF_DOCS"))
       
   161       namespaceSDict->inSort(def->name(),def);  
       
   162     else
       
   163       namespaceSDict->append(def->name(),def);
       
   164     return TRUE;
       
   165   }
       
   166   return FALSE;
       
   167 }
       
   168 
       
   169 void GroupDef::addDir(const DirDef *def)
       
   170 {
       
   171   if (def->isHidden()) return;
       
   172   if (Config_getBool("SORT_BRIEF_DOCS"))
       
   173     dirList->inSort(def);  
       
   174   else
       
   175     dirList->append(def);
       
   176 }
       
   177 
       
   178 void GroupDef::addPage(PageDef *def)
       
   179 {
       
   180   if (def->isHidden()) return;
       
   181   //printf("Making page %s part of a group\n",def->name.data());
       
   182   pageDict->append(def->name(),def);
       
   183   def->makePartOfGroup(this);
       
   184 }
       
   185 
       
   186 void GroupDef::addExample(const PageDef *def)
       
   187 {
       
   188   if (def->isHidden()) return;
       
   189   exampleDict->append(def->name(),def);
       
   190 }
       
   191 
       
   192 
       
   193 void GroupDef::addMembersToMemberGroup()
       
   194 {
       
   195   QListIterator<MemberList> mli(m_memberLists);
       
   196   MemberList *ml;
       
   197   for (mli.toFirst();(ml=mli.current());++mli)
       
   198   {
       
   199     if (ml->listType()&MemberList::declarationLists)
       
   200     {
       
   201       ::addMembersToMemberGroup(ml,&memberGroupSDict,this);
       
   202     }
       
   203   }
       
   204 
       
   205   //printf("GroupDef::addMembersToMemberGroup() memberGroupList=%d\n",memberGroupList->count());
       
   206   MemberGroupSDict::Iterator mgli(*memberGroupSDict);
       
   207   MemberGroup *mg;
       
   208   for (;(mg=mgli.current());++mgli)
       
   209   {
       
   210     mg->setInGroup(TRUE);
       
   211   }
       
   212 }
       
   213 
       
   214 
       
   215 bool GroupDef::insertMember(MemberDef *md,bool docOnly)
       
   216 {
       
   217   if (md->isHidden()) return FALSE;
       
   218   //printf("GroupDef(%s)::insertMember(%s)\n", title.data(), md->name().data());
       
   219   MemberNameInfo *mni=0;
       
   220   if ((mni=(*allMemberNameInfoSDict)[md->name()]))
       
   221   { // member with this name already found
       
   222     MemberNameInfoIterator srcMnii(*mni); 
       
   223     MemberInfo *srcMi;
       
   224     for ( ; (srcMi=srcMnii.current()) ; ++srcMnii )
       
   225     {
       
   226       MemberDef *srcMd = srcMi->memberDef;
       
   227       if (srcMd==md) return FALSE; // already added before!
       
   228 
       
   229       bool sameScope = srcMd->getOuterScope()==md->getOuterScope() || // same class or namespace
       
   230           // both inside a file => definition and declaration do not have to be in the same file
       
   231            (srcMd->getOuterScope()->definitionType()==Definition::TypeFile &&
       
   232             md->getOuterScope()->definitionType()==Definition::TypeFile); 
       
   233 
       
   234       LockingPtr<ArgumentList> srcMdAl = srcMd->argumentList();
       
   235       LockingPtr<ArgumentList> mdAl    = md->argumentList();
       
   236       
       
   237       if (srcMd->isFunction() && md->isFunction() && 
       
   238           matchArguments2(srcMd->getOuterScope(),srcMd->getFileDef(),srcMdAl.pointer(),
       
   239                           md->getOuterScope(),md->getFileDef(),mdAl.pointer(),
       
   240                           TRUE
       
   241                          ) &&
       
   242           sameScope
       
   243          )
       
   244       {
       
   245         if (srcMd->getGroupAlias()==0) 
       
   246         {
       
   247           md->setGroupAlias(srcMd); 
       
   248         }
       
   249         else
       
   250         {
       
   251           md->setGroupAlias(srcMd->getGroupAlias()); 
       
   252         }
       
   253         return FALSE; // member is the same as one that is already added
       
   254       }
       
   255     }
       
   256     mni->append(new MemberInfo(md,md->protection(),md->virtualness(),FALSE));
       
   257   }
       
   258   else
       
   259   {
       
   260     mni = new MemberNameInfo(md->name());
       
   261     mni->append(new MemberInfo(md,md->protection(),md->virtualness(),FALSE));
       
   262     allMemberNameInfoSDict->append(mni->memberName(),mni);
       
   263   }
       
   264   //printf("Added member!\n");
       
   265   allMemberList->append(md); 
       
   266   switch(md->memberType())
       
   267   {
       
   268     case MemberDef::Variable:     
       
   269       if (!docOnly)
       
   270       {
       
   271         addMemberToList(MemberList::decVarMembers,md);
       
   272       }
       
   273       addMemberToList(MemberList::docVarMembers,md);
       
   274       break;
       
   275     case MemberDef::Function: 
       
   276       if (!docOnly)
       
   277       {
       
   278         addMemberToList(MemberList::decFuncMembers,md);
       
   279       }
       
   280       addMemberToList(MemberList::docFuncMembers,md);
       
   281       break;
       
   282     case MemberDef::Typedef:      
       
   283       if (!docOnly)
       
   284       {
       
   285         addMemberToList(MemberList::decTypedefMembers,md);
       
   286       }
       
   287       addMemberToList(MemberList::docTypedefMembers,md);
       
   288       break;
       
   289     case MemberDef::Enumeration:  
       
   290       if (!docOnly)
       
   291       {
       
   292         addMemberToList(MemberList::decEnumMembers,md);
       
   293       }
       
   294       addMemberToList(MemberList::docEnumMembers,md);
       
   295       break;
       
   296     case MemberDef::EnumValue:    
       
   297       if (!docOnly)
       
   298       {
       
   299         addMemberToList(MemberList::decEnumValMembers,md);
       
   300       }
       
   301       addMemberToList(MemberList::docEnumValMembers,md);
       
   302       break;
       
   303     case MemberDef::Define:       
       
   304       if (!docOnly)
       
   305       {
       
   306         addMemberToList(MemberList::decDefineMembers,md);
       
   307       }
       
   308       addMemberToList(MemberList::docDefineMembers,md);
       
   309       break;
       
   310     case MemberDef::Signal:       
       
   311       if (!docOnly)
       
   312       {
       
   313         addMemberToList(MemberList::decSignalMembers,md);
       
   314       }
       
   315       addMemberToList(MemberList::docSignalMembers,md);
       
   316       break;
       
   317     case MemberDef::Slot:       
       
   318       if (md->protection()==Public)
       
   319       {
       
   320         if (!docOnly)
       
   321         {
       
   322           addMemberToList(MemberList::decPubSlotMembers,md);
       
   323         }
       
   324         addMemberToList(MemberList::docPubSlotMembers,md);
       
   325       }
       
   326       else if (md->protection()==Protected)
       
   327       {
       
   328         if (!docOnly)
       
   329         {
       
   330           addMemberToList(MemberList::decProSlotMembers,md);
       
   331         }
       
   332         addMemberToList(MemberList::docProSlotMembers,md);
       
   333       }
       
   334       else
       
   335       {
       
   336         if (!docOnly)
       
   337         {
       
   338           addMemberToList(MemberList::decPriSlotMembers,md);
       
   339         }
       
   340         addMemberToList(MemberList::docPriSlotMembers,md);
       
   341       }
       
   342       break;
       
   343     case MemberDef::Event:       
       
   344       if (!docOnly)
       
   345       {
       
   346         addMemberToList(MemberList::decEventMembers,md);
       
   347       }
       
   348       addMemberToList(MemberList::docEventMembers,md);
       
   349       break;
       
   350     case MemberDef::Property:       
       
   351       if (!docOnly)
       
   352       {
       
   353         addMemberToList(MemberList::decPropMembers,md);
       
   354       }
       
   355       addMemberToList(MemberList::docPropMembers,md);
       
   356       break;
       
   357     case MemberDef::Friend:       
       
   358       if (!docOnly)
       
   359       {
       
   360         addMemberToList(MemberList::decFriendMembers,md);
       
   361       }
       
   362       addMemberToList(MemberList::docFriendMembers,md);
       
   363       break;
       
   364     default:
       
   365       err("GroupDef::insertMembers(): "
       
   366            "member `%s' (typeid=%d) with scope `%s' inserted in group scope `%s'!\n",
       
   367            md->name().data(),md->memberType(),
       
   368            md->getClassDef() ? md->getClassDef()->name().data() : "",
       
   369            name().data());
       
   370   }
       
   371   return TRUE;
       
   372 }
       
   373 
       
   374 void GroupDef::removeMember(MemberDef *md)
       
   375 {
       
   376   // fprintf(stderr, "GroupDef(%s)::removeMember( %s )\n", title.data(), md->name().data());
       
   377   MemberNameInfo *mni = allMemberNameInfoSDict->find(md->name());
       
   378   if (mni)
       
   379   {
       
   380     MemberNameInfoIterator mnii(*mni);
       
   381     while( mnii.current() )
       
   382     {
       
   383       if( mnii.current()->memberDef == md )
       
   384       {
       
   385 	mni->remove(mnii.current());
       
   386         break;
       
   387       }
       
   388       ++mnii;
       
   389     }
       
   390     if( mni->isEmpty() )
       
   391     {
       
   392       allMemberNameInfoSDict->remove(md->name());
       
   393       delete mni;
       
   394     }
       
   395 
       
   396     removeMemberFromList(MemberList::allMembersList,md);
       
   397     switch(md->memberType())
       
   398     {
       
   399       case MemberDef::Variable:
       
   400 	removeMemberFromList(MemberList::decVarMembers,md);
       
   401         removeMemberFromList(MemberList::docVarMembers,md);
       
   402         break;
       
   403       case MemberDef::Function: 
       
   404         removeMemberFromList(MemberList::decFuncMembers,md);
       
   405         removeMemberFromList(MemberList::docFuncMembers,md);
       
   406         break;
       
   407       case MemberDef::Typedef:      
       
   408         removeMemberFromList(MemberList::decTypedefMembers,md);
       
   409         removeMemberFromList(MemberList::docTypedefMembers,md);
       
   410         break;
       
   411       case MemberDef::Enumeration:  
       
   412         removeMemberFromList(MemberList::decEnumMembers,md);
       
   413         removeMemberFromList(MemberList::docEnumMembers,md);
       
   414         break;
       
   415       case MemberDef::EnumValue:    
       
   416         removeMemberFromList(MemberList::decEnumValMembers,md);
       
   417         removeMemberFromList(MemberList::docEnumValMembers,md);
       
   418         break;
       
   419       case MemberDef::Define:       
       
   420         removeMemberFromList(MemberList::decDefineMembers,md);
       
   421         removeMemberFromList(MemberList::docDefineMembers,md);
       
   422         break;
       
   423       case MemberDef::Signal:       
       
   424         removeMemberFromList(MemberList::decSignalMembers,md);
       
   425         removeMemberFromList(MemberList::docSignalMembers,md);
       
   426         break;
       
   427       case MemberDef::Slot:       
       
   428         if (md->protection()==Public)
       
   429         {
       
   430           removeMemberFromList(MemberList::decPubSlotMembers,md);
       
   431           removeMemberFromList(MemberList::docPubSlotMembers,md);
       
   432         }
       
   433         else if (md->protection()==Protected)
       
   434         {
       
   435           removeMemberFromList(MemberList::decProSlotMembers,md);
       
   436           removeMemberFromList(MemberList::docProSlotMembers,md);
       
   437         }
       
   438         else
       
   439         {
       
   440           removeMemberFromList(MemberList::decPriSlotMembers,md);
       
   441           removeMemberFromList(MemberList::docPriSlotMembers,md);
       
   442         }
       
   443         break;
       
   444       case MemberDef::Event:       
       
   445         removeMemberFromList(MemberList::decEventMembers,md);
       
   446         removeMemberFromList(MemberList::docEventMembers,md);
       
   447         break;
       
   448       case MemberDef::Property:       
       
   449         removeMemberFromList(MemberList::decPropMembers,md);
       
   450         removeMemberFromList(MemberList::docPropMembers,md);
       
   451         break;
       
   452       case MemberDef::Friend:       
       
   453         removeMemberFromList(MemberList::decFriendMembers,md);
       
   454         removeMemberFromList(MemberList::docFriendMembers,md);
       
   455         break;
       
   456       default:
       
   457         err("GroupDef::removeMember(): unexpected member remove in file!\n");
       
   458     }
       
   459   }
       
   460 }
       
   461 
       
   462 bool GroupDef::containsGroup(const GroupDef *def)
       
   463 {
       
   464     return this==def || groupList->find(def) >= 0;
       
   465 }
       
   466 
       
   467 void GroupDef::addGroup(const GroupDef *def)
       
   468 {
       
   469   //printf("adding group `%s' to group `%s'\n",def->name().data(),name().data());
       
   470   //if (Config_getBool("SORT_MEMBER_DOCS"))
       
   471   //  groupList->inSort(def);
       
   472   //else
       
   473   groupList->append(def);
       
   474 }
       
   475 
       
   476 bool GroupDef::isASubGroup() const
       
   477 {
       
   478   LockingPtr<GroupList> groups = partOfGroups();
       
   479   return groups!=0 && groups->count()!=0;
       
   480 }
       
   481 
       
   482 int GroupDef::countMembers() const
       
   483 {
       
   484   return fileList->count()+
       
   485          classSDict->count()+
       
   486          namespaceSDict->count()+
       
   487          groupList->count()+
       
   488          allMemberList->count()+
       
   489          pageDict->count()+
       
   490          exampleDict->count();
       
   491 }
       
   492 
       
   493 /*! Compute the HTML anchor names for all members in the group */ 
       
   494 void GroupDef::computeAnchors()
       
   495 {
       
   496   //printf("GroupDef::computeAnchors()\n");
       
   497   setAnchors(0,'a',allMemberList);
       
   498 }
       
   499 
       
   500 void GroupDef::writeDetailedDescription(OutputList &ol,const QCString &title)
       
   501 {
       
   502   if ((!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF")) 
       
   503       || !documentation().isEmpty() || !inbodyDocumentation().isEmpty()
       
   504      )
       
   505   {
       
   506     if (pageDict->count()!=countMembers()) // not only pages -> classical layout
       
   507     {
       
   508       ol.writeRuler();
       
   509       ol.pushGeneratorState();
       
   510       ol.disableAllBut(OutputGenerator::Html);
       
   511         ol.writeAnchor(0,"_details");
       
   512       ol.popGeneratorState();
       
   513       ol.startGroupHeader();
       
   514       ol.parseText(title);
       
   515       ol.endGroupHeader();
       
   516     }
       
   517 
       
   518     // repeat brief description
       
   519     if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF"))
       
   520     {
       
   521       ol.parseDoc(briefFile(),briefLine(),this,0,briefDescription(),FALSE,FALSE);
       
   522     }
       
   523     // write separator between brief and details
       
   524     if (!briefDescription().isEmpty() && Config_getBool("REPEAT_BRIEF") &&
       
   525         !documentation().isEmpty())
       
   526     {
       
   527       ol.pushGeneratorState();
       
   528       ol.disable(OutputGenerator::Man);
       
   529       ol.disable(OutputGenerator::RTF);
       
   530       // ol.newParagraph(); // FIXME:PARA
       
   531       ol.enableAll();
       
   532       ol.disableAllBut(OutputGenerator::Man);
       
   533       ol.writeString("\n\n");
       
   534       ol.popGeneratorState();
       
   535     }
       
   536 
       
   537     // write detailed documentation
       
   538     if (!documentation().isEmpty())
       
   539     {
       
   540       ol.parseDoc(docFile(),docLine(),this,0,documentation()+"\n",TRUE,FALSE);
       
   541     }
       
   542 
       
   543     // write inbody documentation
       
   544     if (!inbodyDocumentation().isEmpty())
       
   545     {
       
   546       ol.parseDoc(inbodyFile(),inbodyLine(),this,0,inbodyDocumentation()+"\n",TRUE,FALSE);
       
   547     }
       
   548   }
       
   549 }
       
   550 
       
   551 void GroupDef::writeBriefDescription(OutputList &ol)
       
   552 {
       
   553   if (!briefDescription().isEmpty())
       
   554   {
       
   555     ol.startParagraph();
       
   556     ol.parseDoc(briefFile(),briefLine(),this,0,
       
   557                 briefDescription(),TRUE,FALSE,0,TRUE,FALSE);
       
   558     ol.pushGeneratorState();
       
   559     ol.disable(OutputGenerator::RTF);
       
   560     ol.writeString(" \n");
       
   561     ol.enable(OutputGenerator::RTF);
       
   562 
       
   563     if (Config_getBool("REPEAT_BRIEF") ||
       
   564         !documentation().isEmpty()
       
   565        )
       
   566     {
       
   567       ol.disableAllBut(OutputGenerator::Html);
       
   568       ol.startTextLink(0,"_details");
       
   569       ol.parseText(theTranslator->trMore());
       
   570       ol.endTextLink();
       
   571     }
       
   572     ol.popGeneratorState();
       
   573 
       
   574     //ol.pushGeneratorState();
       
   575     //ol.disable(OutputGenerator::RTF);
       
   576     //ol.newParagraph();
       
   577     //ol.popGeneratorState();
       
   578     ol.endParagraph();
       
   579   }
       
   580 }
       
   581 
       
   582 void GroupDef::writeGroupGraph(OutputList &ol)
       
   583 {
       
   584   if (Config_getBool("HAVE_DOT") /*&& Config_getBool("GROUP_GRAPHS")*/ )
       
   585   {
       
   586     DotGroupCollaboration graph(this);
       
   587     if (!graph.isTrivial())
       
   588     {
       
   589       msg("Generating dependency graph for group %s\n",qualifiedName().data());
       
   590       ol.pushGeneratorState();
       
   591       ol.disable(OutputGenerator::Man);
       
   592       ol.startParagraph();
       
   593       ol.startGroupCollaboration();
       
   594       ol.parseText(theTranslator->trCollaborationDiagram(title));
       
   595       ol.endGroupCollaboration(graph);
       
   596       ol.endParagraph();
       
   597       ol.popGeneratorState();
       
   598     }
       
   599   }
       
   600 }
       
   601 
       
   602 void GroupDef::writeFiles(OutputList &ol,const QCString &title)
       
   603 {
       
   604   // write list of files
       
   605   if (fileList->count()>0)
       
   606   {
       
   607     ol.startMemberHeader();
       
   608     ol.parseText(title);
       
   609     ol.endMemberHeader();
       
   610     ol.startMemberList();
       
   611     FileDef *fd=fileList->first();
       
   612     while (fd)
       
   613     {
       
   614       ol.startMemberItem(0);
       
   615       ol.docify(theTranslator->trFile(FALSE,TRUE)+" ");
       
   616       ol.insertMemberAlign();
       
   617       ol.writeObjectLink(fd->getReference(),fd->getOutputFileBase(),0,fd->name());
       
   618       if (!Config_getString("GENERATE_TAGFILE").isEmpty()) 
       
   619       {
       
   620         Doxygen::tagFile << "    <file>" << convertToXML(fd->name()) << "</file>" << endl;
       
   621       }
       
   622       ol.endMemberItem();
       
   623       if (!fd->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC"))
       
   624       {
       
   625         ol.startParagraph();
       
   626         ol.startMemberDescription();
       
   627         ol.parseDoc(briefFile(),briefLine(),fd,0,fd->briefDescription(),FALSE,FALSE);
       
   628         ol.endMemberDescription();
       
   629         ol.endParagraph();
       
   630       }
       
   631       fd=fileList->next();
       
   632     }
       
   633     ol.endMemberList();
       
   634   }
       
   635 }
       
   636 
       
   637 void GroupDef::writeNamespaces(OutputList &ol,const QCString &title)
       
   638 {
       
   639   // write list of namespaces
       
   640   namespaceSDict->writeDeclaration(ol,title);
       
   641 }
       
   642 
       
   643 void GroupDef::writeNestedGroups(OutputList &ol,const QCString &title)
       
   644 {
       
   645   // write list of groups
       
   646   if (groupList->count()>0)
       
   647   {
       
   648     ol.startMemberHeader();
       
   649     ol.parseText(title);
       
   650     ol.endMemberHeader();
       
   651     ol.startMemberList();
       
   652     GroupDef *gd=groupList->first();
       
   653     while (gd)
       
   654     {
       
   655       ol.startMemberItem(0);
       
   656       //ol.docify(theTranslator->trGroup(FALSE,TRUE));
       
   657       //ol.docify(" ");
       
   658       ol.insertMemberAlign();
       
   659       ol.writeObjectLink(gd->getReference(),gd->getOutputFileBase(),0,gd->groupTitle());
       
   660       if (!Config_getString("GENERATE_TAGFILE").isEmpty()) 
       
   661       {
       
   662         Doxygen::tagFile << "    <subgroup>" << convertToXML(gd->name()) << "</subgroup>" << endl;
       
   663       }
       
   664       ol.endMemberItem();
       
   665       if (!gd->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC"))
       
   666       {
       
   667         ol.startParagraph();
       
   668         ol.startMemberDescription();
       
   669         ol.parseDoc(briefFile(),briefLine(),gd,0,gd->briefDescription(),FALSE,FALSE);
       
   670         ol.endMemberDescription();
       
   671         ol.endParagraph();
       
   672       }
       
   673       gd=groupList->next();
       
   674     }
       
   675     ol.endMemberList();
       
   676   }
       
   677 }
       
   678 
       
   679 void GroupDef::writeDirs(OutputList &ol,const QCString &title)
       
   680 {
       
   681   // write list of directories
       
   682   if (dirList->count()>0)
       
   683   {
       
   684     ol.startMemberHeader();
       
   685     ol.parseText(title);
       
   686     ol.endMemberHeader();
       
   687     ol.startMemberList();
       
   688     DirDef *dd=dirList->first();
       
   689     while (dd)
       
   690     {
       
   691       ol.startMemberItem(0);
       
   692       ol.parseText(theTranslator->trDir(FALSE,TRUE));
       
   693       ol.insertMemberAlign();
       
   694       ol.writeObjectLink(dd->getReference(),dd->getOutputFileBase(),0,dd->shortName());
       
   695       ol.endMemberItem();
       
   696       if (!Config_getString("GENERATE_TAGFILE").isEmpty()) 
       
   697       {
       
   698         Doxygen::tagFile << "    <dir>" << convertToXML(dd->displayName()) << "</dir>" << endl;
       
   699       }
       
   700       if (!dd->briefDescription().isEmpty() && Config_getBool("BRIEF_MEMBER_DESC"))
       
   701       {
       
   702         ol.startParagraph();
       
   703         ol.startMemberDescription();
       
   704         ol.parseDoc(briefFile(),briefLine(),dd,0,dd->briefDescription(),FALSE,FALSE);
       
   705         ol.endMemberDescription();
       
   706         ol.endParagraph();
       
   707       }
       
   708       dd=dirList->next();
       
   709     }
       
   710 
       
   711     ol.endMemberList();
       
   712   }
       
   713 }
       
   714 
       
   715 void GroupDef::writeClasses(OutputList &ol,const QCString &title)
       
   716 {
       
   717   // write list of classes
       
   718   classSDict->writeDeclaration(ol,0,title,FALSE);
       
   719 }
       
   720 
       
   721 void GroupDef::writePageDocumentation(OutputList &ol)
       
   722 {
       
   723   PageDef *pd=0;
       
   724   PageSDict::Iterator pdi(*pageDict);
       
   725   for (pdi.toFirst();(pd=pdi.current());++pdi)
       
   726   {
       
   727     if (!pd->isReference())
       
   728     {
       
   729       QCString pageName = pd->getOutputFileBase();
       
   730 
       
   731       if (!Config_getString("GENERATE_TAGFILE").isEmpty()) 
       
   732       {
       
   733         Doxygen::tagFile << "    <page>" << convertToXML(pageName) << "</page>" << endl;
       
   734       }
       
   735 
       
   736       SectionInfo *si=0;
       
   737       if (!pd->title().isEmpty() && !pd->name().isEmpty() &&
       
   738           (si=Doxygen::sectionDict[pd->name()])!=0)
       
   739       {
       
   740         ol.startSection(si->label,si->title,SectionInfo::Subsection);
       
   741         ol.docify(si->title);
       
   742         ol.endSection(si->label,SectionInfo::Subsection);
       
   743       }
       
   744       ol.startTextBlock();
       
   745       ol.parseDoc(pd->docFile(),pd->docLine(),pd,0,pd->documentation()+pd->inbodyDocumentation(),TRUE,FALSE);
       
   746       ol.endTextBlock();
       
   747     }
       
   748   }
       
   749 }
       
   750 
       
   751 void GroupDef::writeMemberGroups(OutputList &ol)
       
   752 {
       
   753   /* write user defined member groups */
       
   754   if (memberGroupSDict)
       
   755   {
       
   756     /* write user defined member groups */
       
   757     MemberGroupSDict::Iterator mgli(*memberGroupSDict);
       
   758     MemberGroup *mg;
       
   759     for (;(mg=mgli.current());++mgli)
       
   760     {
       
   761       mg->writeDeclarations(ol,0,0,0,this);
       
   762     }
       
   763   }
       
   764 }
       
   765 
       
   766 void GroupDef::startMemberDeclarations(OutputList &ol)
       
   767 {
       
   768   ol.startMemberSections();
       
   769 }
       
   770 
       
   771 void GroupDef::endMemberDeclarations(OutputList &ol)
       
   772 {
       
   773   ol.endMemberSections();
       
   774 }
       
   775 
       
   776 void GroupDef::startMemberDocumentation(OutputList &ol)
       
   777 {
       
   778   if (Config_getBool("SEPARATE_MEMBER_PAGES"))
       
   779   {
       
   780     ol.disable(OutputGenerator::Html);
       
   781     Doxygen::suppressDocWarnings = TRUE;
       
   782   }
       
   783 }
       
   784 
       
   785 void GroupDef::endMemberDocumentation(OutputList &ol)
       
   786 {
       
   787   if (Config_getBool("SEPARATE_MEMBER_PAGES"))
       
   788   {
       
   789     ol.enable(OutputGenerator::Html);
       
   790     Doxygen::suppressDocWarnings = FALSE;
       
   791   }
       
   792 }
       
   793 
       
   794 void GroupDef::writeAuthorSection(OutputList &ol)
       
   795 {
       
   796   // write Author section (Man only)
       
   797   ol.pushGeneratorState();
       
   798   ol.disableAllBut(OutputGenerator::Man);
       
   799   ol.startGroupHeader();
       
   800   ol.parseText(theTranslator->trAuthor(TRUE,TRUE));
       
   801   ol.endGroupHeader();
       
   802   ol.parseText(theTranslator->trGeneratedAutomatically(Config_getString("PROJECT_NAME")));
       
   803   ol.popGeneratorState();
       
   804 }
       
   805 
       
   806 void GroupDef::writeDocumentation(OutputList &ol)
       
   807 {
       
   808   ol.pushGeneratorState();
       
   809   startFile(ol,getOutputFileBase(),name(),title);
       
   810   startTitle(ol,getOutputFileBase());
       
   811   ol.parseText(title);
       
   812   addGroupListToTitle(ol,this);
       
   813   endTitle(ol,getOutputFileBase(),title);
       
   814 
       
   815   if (Doxygen::searchIndex)
       
   816   {
       
   817     Doxygen::searchIndex->setCurrentDoc(title,getOutputFileBase());
       
   818     static QRegExp we("[a-zA-Z_][-a-zA-Z_0-9]*");
       
   819     int i=0,p=0,l=0;
       
   820     while ((i=we.match(title,p,&l))!=-1) // foreach word in the title
       
   821     {
       
   822       Doxygen::searchIndex->addWord(title.mid(i,l),TRUE);
       
   823       p=i+l;
       
   824     }
       
   825   }
       
   826 
       
   827   Doxygen::indexList.addIndexItem(this,0,0,title);
       
   828 
       
   829   if (!Config_getString("GENERATE_TAGFILE").isEmpty()) 
       
   830   {
       
   831     Doxygen::tagFile << "  <compound kind=\"group\">" << endl;
       
   832     Doxygen::tagFile << "    <name>" << convertToXML(name()) << "</name>" << endl;
       
   833     Doxygen::tagFile << "    <title>" << convertToXML(title) << "</title>" << endl;
       
   834     Doxygen::tagFile << "    <filename>" << convertToXML(getOutputFileBase()) << Doxygen::htmlFileExtension << "</filename>" << endl;
       
   835   }
       
   836   
       
   837 
       
   838   //---------------------------------------- start flexible part -------------------------------
       
   839 
       
   840   QListIterator<LayoutDocEntry> eli(
       
   841       LayoutDocManager::instance().docEntries(LayoutDocManager::Group));
       
   842   LayoutDocEntry *lde;
       
   843   for (eli.toFirst();(lde=eli.current());++eli)
       
   844   {
       
   845     switch (lde->kind())
       
   846     {
       
   847       case LayoutDocEntry::BriefDesc: 
       
   848         writeBriefDescription(ol);
       
   849         break; 
       
   850       case LayoutDocEntry::MemberDeclStart: 
       
   851         startMemberDeclarations(ol);
       
   852         break; 
       
   853       case LayoutDocEntry::GroupClasses: 
       
   854         {
       
   855           LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
       
   856           writeClasses(ol,ls->title);
       
   857         }
       
   858         break; 
       
   859       case LayoutDocEntry::GroupNamespaces: 
       
   860         {
       
   861           LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
       
   862           writeNamespaces(ol,ls->title);
       
   863         }
       
   864         break; 
       
   865       case LayoutDocEntry::MemberGroups: 
       
   866         writeMemberGroups(ol);
       
   867         break; 
       
   868       case LayoutDocEntry::MemberDecl: 
       
   869         {
       
   870           LayoutDocEntryMemberDecl *lmd = (LayoutDocEntryMemberDecl*)lde;
       
   871           writeMemberDeclarations(ol,lmd->type,lmd->title);
       
   872         }
       
   873         break; 
       
   874       case LayoutDocEntry::MemberDeclEnd: 
       
   875         endMemberDeclarations(ol);
       
   876         break;
       
   877       case LayoutDocEntry::DetailedDesc: 
       
   878         {
       
   879           LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
       
   880           writeDetailedDescription(ol,ls->title);
       
   881         }
       
   882         break;
       
   883       case LayoutDocEntry::MemberDefStart: 
       
   884         startMemberDocumentation(ol);
       
   885         break; 
       
   886       case LayoutDocEntry::MemberDef: 
       
   887         {
       
   888           LayoutDocEntryMemberDef *lmd = (LayoutDocEntryMemberDef*)lde;
       
   889           writeMemberDocumentation(ol,lmd->type,lmd->title);
       
   890         }
       
   891         break;
       
   892       case LayoutDocEntry::MemberDefEnd: 
       
   893         endMemberDocumentation(ol);
       
   894         break;
       
   895       case LayoutDocEntry::GroupNestedGroups: 
       
   896         {
       
   897           LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
       
   898           writeNestedGroups(ol,ls->title);
       
   899         }
       
   900         break;
       
   901       case LayoutDocEntry::GroupPageDocs: 
       
   902         writePageDocumentation(ol);
       
   903         break;
       
   904       case LayoutDocEntry::GroupDirs: 
       
   905         {
       
   906           LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
       
   907           writeDirs(ol,ls->title);
       
   908         }
       
   909         break;
       
   910       case LayoutDocEntry::GroupFiles: 
       
   911         {
       
   912           LayoutDocEntrySection *ls = (LayoutDocEntrySection*)lde;
       
   913           writeFiles(ol,ls->title);
       
   914         }
       
   915         break;
       
   916       case LayoutDocEntry::GroupGraph: 
       
   917         writeGroupGraph(ol);
       
   918         break;
       
   919       case LayoutDocEntry::AuthorSection: 
       
   920         writeAuthorSection(ol);
       
   921         break;
       
   922       case LayoutDocEntry::ClassIncludes:
       
   923       case LayoutDocEntry::ClassInheritanceGraph:
       
   924       case LayoutDocEntry::ClassNestedClasses:
       
   925       case LayoutDocEntry::ClassCollaborationGraph:
       
   926       case LayoutDocEntry::ClassAllMembersLink:
       
   927       case LayoutDocEntry::ClassUsedFiles:
       
   928       case LayoutDocEntry::NamespaceNestedNamespaces:
       
   929       case LayoutDocEntry::NamespaceClasses:
       
   930       case LayoutDocEntry::FileClasses:
       
   931       case LayoutDocEntry::FileNamespaces:
       
   932       case LayoutDocEntry::FileIncludes:
       
   933       case LayoutDocEntry::FileIncludeGraph:
       
   934       case LayoutDocEntry::FileIncludedByGraph: 
       
   935       case LayoutDocEntry::FileSourceLink:
       
   936       case LayoutDocEntry::DirSubDirs:
       
   937       case LayoutDocEntry::DirFiles:
       
   938       case LayoutDocEntry::DirGraph:
       
   939         err("Internal inconsistency: member %d should not be part of "
       
   940             "LayoutDocManager::Group entry list\n",lde->kind());
       
   941         break;
       
   942     }
       
   943   }
       
   944 
       
   945   //---------------------------------------- end flexible part -------------------------------
       
   946 
       
   947   endFile(ol); 
       
   948   ol.popGeneratorState();
       
   949 
       
   950   if (!Config_getString("GENERATE_TAGFILE").isEmpty()) 
       
   951   {
       
   952     writeDocAnchorsToTagFile();
       
   953     Doxygen::tagFile << "  </compound>" << endl;
       
   954   }
       
   955 
       
   956   if (Config_getBool("SEPARATE_MEMBER_PAGES"))
       
   957   {
       
   958     allMemberList->sort();
       
   959     writeMemberPages(ol);
       
   960   }
       
   961 
       
   962 }
       
   963 
       
   964 void GroupDef::writeMemberPages(OutputList &ol)
       
   965 {
       
   966   ol.pushGeneratorState();
       
   967   ol.disableAllBut(OutputGenerator::Html);
       
   968   
       
   969   QListIterator<MemberList> mli(m_memberLists);
       
   970   MemberList *ml;
       
   971   for (mli.toFirst();(ml=mli.current());++mli)
       
   972   {
       
   973     if (ml->listType()&MemberList::documentationLists)
       
   974     {
       
   975        ml->writeDocumentationPage(ol,name(),this);
       
   976     }
       
   977   }
       
   978 
       
   979   ol.popGeneratorState();
       
   980 }
       
   981 
       
   982 void GroupDef::writeQuickMemberLinks(OutputList &ol,MemberDef *currentMd) const
       
   983 {
       
   984   static bool createSubDirs=Config_getBool("CREATE_SUBDIRS");
       
   985 
       
   986   ol.writeString("      <div class=\"navtab\">\n");
       
   987   ol.writeString("        <table>\n");
       
   988 
       
   989   MemberListIterator mli(*allMemberList);
       
   990   MemberDef *md;
       
   991   for (mli.toFirst();(md=mli.current());++mli)
       
   992   {
       
   993     if (md->getGroupDef()==this && md->isLinkable())
       
   994     {
       
   995       ol.writeString("          <tr><td class=\"navtab\">");
       
   996       if (md->isLinkableInProject())
       
   997       {
       
   998         if (md==currentMd) // selected item => highlight
       
   999         {
       
  1000           ol.writeString("<a class=\"qindexHL\" ");
       
  1001         }
       
  1002         else
       
  1003         {
       
  1004           ol.writeString("<a class=\"qindex\" ");
       
  1005         }
       
  1006         ol.writeString("href=\"");
       
  1007         if (createSubDirs) ol.writeString("../../");
       
  1008         ol.writeString(md->getOutputFileBase()+Doxygen::htmlFileExtension+"#"+md->anchor());
       
  1009         ol.writeString("\">");
       
  1010         ol.writeString(md->localName());
       
  1011         ol.writeString("</a>");
       
  1012       }
       
  1013       ol.writeString("</td></tr>\n");
       
  1014     }
       
  1015   }
       
  1016 
       
  1017   ol.writeString("        </table>\n");
       
  1018   ol.writeString("      </div>\n");
       
  1019 }
       
  1020 
       
  1021 
       
  1022 
       
  1023 //---- helper functions ------------------------------------------------------
       
  1024 
       
  1025 void addClassToGroups(Entry *root,ClassDef *cd)
       
  1026 {
       
  1027   QListIterator<Grouping> gli(*root->groups);
       
  1028   Grouping *g;
       
  1029   for (;(g=gli.current());++gli)
       
  1030   {
       
  1031     GroupDef *gd=0;
       
  1032     if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g->groupname)))
       
  1033     {
       
  1034       if (gd->addClass(cd)) cd->makePartOfGroup(gd);
       
  1035       //printf("Compound %s: in group %s\n",cd->name().data(),s->data());
       
  1036     }
       
  1037   }
       
  1038 }
       
  1039 
       
  1040 void addNamespaceToGroups(Entry *root,NamespaceDef *nd)
       
  1041 {
       
  1042   //printf("root->groups->count()=%d\n",root->groups->count());
       
  1043   QListIterator<Grouping> gli(*root->groups);
       
  1044   Grouping *g;
       
  1045   for (;(g=gli.current());++gli)
       
  1046   {
       
  1047     GroupDef *gd=0;
       
  1048     //printf("group `%s'\n",s->data());
       
  1049     if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g->groupname)))
       
  1050     {
       
  1051       if (gd->addNamespace(nd)) nd->makePartOfGroup(gd);
       
  1052       //printf("Namespace %s: in group %s\n",nd->name().data(),s->data());
       
  1053     }
       
  1054   }
       
  1055 }
       
  1056 
       
  1057 void addDirToGroups(Entry *root,DirDef *dd)
       
  1058 {
       
  1059   //printf("*** root->groups->count()=%d\n",root->groups->count());
       
  1060   QListIterator<Grouping> gli(*root->groups);
       
  1061   Grouping *g;
       
  1062   for (;(g=gli.current());++gli)
       
  1063   {
       
  1064     GroupDef *gd=0;
       
  1065     //printf("group `%s'\n",g->groupname.data());
       
  1066     if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g->groupname)))
       
  1067     {
       
  1068       gd->addDir(dd);
       
  1069       dd->makePartOfGroup(gd);
       
  1070       //printf("Dir %s: in group %s\n",dd->name().data(),g->groupname.data());
       
  1071     }
       
  1072   }
       
  1073 }
       
  1074 
       
  1075 void addGroupToGroups(Entry *root,GroupDef *subGroup)
       
  1076 {
       
  1077   //printf("addGroupToGroups for %s groups=%d\n",root->name.data(),
       
  1078   //    root->groups?root->groups->count():-1);
       
  1079   QListIterator<Grouping> gli(*root->groups);
       
  1080   Grouping *g;
       
  1081   for (;(g=gli.current());++gli)
       
  1082   {
       
  1083     GroupDef *gd=0;
       
  1084     if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g->groupname)) &&
       
  1085 	!gd->containsGroup(subGroup) )
       
  1086     {
       
  1087       gd->addGroup(subGroup);
       
  1088       subGroup->makePartOfGroup(gd);
       
  1089     }
       
  1090     else if (gd==subGroup)
       
  1091     {
       
  1092       warn(root->fileName,root->startLine,"Trying to add group %s to itself!",
       
  1093           gd->name().data());
       
  1094     }
       
  1095   }
       
  1096 }
       
  1097 
       
  1098 /*! Add a member to the group with the highest priority */
       
  1099 void addMemberToGroups(Entry *root,MemberDef *md)
       
  1100 {
       
  1101   //printf("addMemberToGroups:  Root %p = %s, md %p=%s groups=%d\n", 
       
  1102   //    root, root->name.data(), md, md->name().data(), root->groups->count() );
       
  1103   QListIterator<Grouping> gli(*root->groups);
       
  1104   Grouping *g;
       
  1105 
       
  1106   // Search entry's group list for group with highest pri.
       
  1107   Grouping::GroupPri_t pri = Grouping::GROUPING_LOWEST;
       
  1108   GroupDef *fgd=0;
       
  1109   for (;(g=gli.current());++gli)
       
  1110   {
       
  1111     GroupDef *gd=0;
       
  1112     if (!g->groupname.isEmpty() &&
       
  1113         (gd=Doxygen::groupSDict->find(g->groupname)) &&
       
  1114 	g->pri >= pri)
       
  1115     {
       
  1116       if (fgd && gd!=fgd && g->pri==pri) 
       
  1117       {
       
  1118          warn(root->fileName.data(), root->startLine,
       
  1119            "Warning: Member %s found in multiple %s groups! "
       
  1120            "The member will be put in group %s, and not in group %s",
       
  1121 	   md->name().data(), Grouping::getGroupPriName( pri ),
       
  1122 	   gd->name().data(), fgd->name().data()
       
  1123           );
       
  1124       }
       
  1125 
       
  1126       fgd = gd;
       
  1127       pri = g->pri;
       
  1128     }
       
  1129   }
       
  1130   //printf("fgd=%p\n",fgd);
       
  1131 
       
  1132   // put member into group defined by this entry?
       
  1133   if (fgd)
       
  1134   {
       
  1135     GroupDef *mgd = md->getGroupDef();
       
  1136     //printf("mgd=%p\n",mgd);
       
  1137     bool insertit = FALSE;
       
  1138     if (mgd==0)
       
  1139     {
       
  1140       insertit = TRUE;
       
  1141     }
       
  1142     else if (mgd!=fgd)
       
  1143     {
       
  1144       bool moveit = FALSE;
       
  1145 
       
  1146       // move member from one group to another if 
       
  1147       // - the new one has a higher priority
       
  1148       // - the new entry has the same priority, but with docs where the old one had no docs
       
  1149       if (md->getGroupPri()<pri)
       
  1150       {
       
  1151         moveit = TRUE;
       
  1152       }
       
  1153       else
       
  1154       {
       
  1155         if (md->getGroupPri()==pri)
       
  1156         {
       
  1157           if (!root->doc.isEmpty() && !md->getGroupHasDocs())
       
  1158           {
       
  1159             moveit = TRUE;
       
  1160           }
       
  1161           else if (!root->doc.isEmpty() && md->getGroupHasDocs())
       
  1162           {
       
  1163             warn(md->getGroupFileName(),md->getGroupStartLine(),
       
  1164                 "Warning: Member documentation for %s found several times in %s groups!\n"
       
  1165                 "%s:%d: The member will remain in group %s, and won't be put into group %s",
       
  1166                 md->name().data(), Grouping::getGroupPriName( pri ),
       
  1167                 root->fileName.data(), root->startLine,
       
  1168                 mgd->name().data(),
       
  1169                 fgd->name().data()
       
  1170                 );
       
  1171           }
       
  1172         }
       
  1173       }
       
  1174 
       
  1175       if (moveit)
       
  1176       {
       
  1177         //printf("removeMember\n");
       
  1178         mgd->removeMember(md);
       
  1179         insertit = TRUE;
       
  1180       }
       
  1181     }
       
  1182 
       
  1183     if (insertit)
       
  1184     {
       
  1185       //printf("insertMember found at %s line %d\n",md->getDefFileName().data(),md->getDefLine());
       
  1186       bool success = fgd->insertMember(md);
       
  1187       if (success)
       
  1188       {
       
  1189         //printf("insertMember successful\n");
       
  1190         md->setGroupDef(fgd,pri,root->fileName,root->startLine,
       
  1191                         !root->doc.isEmpty());
       
  1192         ClassDef *cd = md->getClassDefOfAnonymousType();
       
  1193         if (cd) cd->setGroupDefForAllMembers(fgd,pri,root->fileName,root->startLine,root->doc.length() != 0);
       
  1194       }
       
  1195     }
       
  1196   }
       
  1197 }
       
  1198 
       
  1199 
       
  1200 void addExampleToGroups(Entry *root,PageDef *eg)
       
  1201 {
       
  1202   QListIterator<Grouping> gli(*root->groups);
       
  1203   Grouping *g;
       
  1204   for (;(g=gli.current());++gli)
       
  1205   {
       
  1206     GroupDef *gd=0;
       
  1207     if (!g->groupname.isEmpty() && (gd=Doxygen::groupSDict->find(g->groupname)))
       
  1208     {
       
  1209       gd->addExample(eg);
       
  1210       eg->makePartOfGroup(gd);
       
  1211       //printf("Example %s: in group %s\n",eg->name().data(),s->data());
       
  1212     }
       
  1213   }
       
  1214 }
       
  1215 
       
  1216 QCString GroupDef::getOutputFileBase() const 
       
  1217 { 
       
  1218   if (isReference())
       
  1219   {
       
  1220     return fileName;
       
  1221   }
       
  1222   else
       
  1223   {
       
  1224     return convertNameToFile(fileName); 
       
  1225   }
       
  1226 }
       
  1227 
       
  1228 void GroupDef::addListReferences()
       
  1229 {
       
  1230   {
       
  1231     LockingPtr< QList<ListItemInfo> > xrefItems = xrefListItems();
       
  1232     addRefItem(xrefItems.pointer(),
       
  1233              getOutputFileBase(),
       
  1234              theTranslator->trGroup(TRUE,TRUE),
       
  1235              getOutputFileBase(),name(),
       
  1236              0
       
  1237             );
       
  1238   }
       
  1239   MemberGroupSDict::Iterator mgli(*memberGroupSDict);
       
  1240   MemberGroup *mg;
       
  1241   for (;(mg=mgli.current());++mgli)
       
  1242   {
       
  1243     mg->addListReferences(this);
       
  1244   }
       
  1245   QListIterator<MemberList> mli(m_memberLists);
       
  1246   MemberList *ml;
       
  1247   for (mli.toFirst();(ml=mli.current());++mli)
       
  1248   {
       
  1249     if (ml->listType()&MemberList::documentationLists)
       
  1250     {
       
  1251       ml->addListReferences(this);
       
  1252     }
       
  1253   }
       
  1254 }
       
  1255 
       
  1256 MemberList *GroupDef::createMemberList(MemberList::ListType lt)
       
  1257 {
       
  1258   m_memberLists.setAutoDelete(TRUE);
       
  1259   QListIterator<MemberList> mli(m_memberLists);
       
  1260   MemberList *ml;
       
  1261   for (mli.toFirst();(ml=mli.current());++mli)
       
  1262   {
       
  1263     if (ml->listType()==lt)
       
  1264     {
       
  1265       return ml;
       
  1266     }
       
  1267   }
       
  1268   // not found, create a new member list
       
  1269   ml = new MemberList(lt);
       
  1270   m_memberLists.append(ml);
       
  1271   ml->setInGroup(TRUE);
       
  1272   return ml;
       
  1273 }
       
  1274 
       
  1275 void GroupDef::addMemberToList(MemberList::ListType lt,MemberDef *md)
       
  1276 {
       
  1277   static bool sortBriefDocs = Config_getBool("SORT_BRIEF_DOCS");
       
  1278   static bool sortMemberDocs = Config_getBool("SORT_MEMBER_DOCS");
       
  1279   MemberList *ml = createMemberList(lt);
       
  1280   if (((ml->listType()&MemberList::declarationLists) && sortBriefDocs) ||
       
  1281       ((ml->listType()&MemberList::documentationLists) && sortMemberDocs)
       
  1282      )
       
  1283     ml->inSort(md);
       
  1284   else
       
  1285     ml->append(md);
       
  1286 }
       
  1287 
       
  1288 MemberList *GroupDef::getMemberList(MemberList::ListType lt) const
       
  1289 {
       
  1290   GroupDef *that = (GroupDef*)this;
       
  1291   MemberList *ml = that->m_memberLists.first();
       
  1292   while (ml)
       
  1293   {
       
  1294     if (ml->listType()==lt)
       
  1295     {
       
  1296       return ml;
       
  1297     }
       
  1298     ml = that->m_memberLists.next();
       
  1299   }
       
  1300   return 0;
       
  1301 }
       
  1302 
       
  1303 void GroupDef::writeMemberDeclarations(OutputList &ol,MemberList::ListType lt,const QCString &title)
       
  1304 {
       
  1305   static bool optimizeVhdl = Config_getBool("OPTIMIZE_OUTPUT_VHDL");
       
  1306 
       
  1307   MemberList * ml = getMemberList(lt);
       
  1308   if (optimizeVhdl && ml) 
       
  1309   {
       
  1310     VhdlDocGen::writeVhdlDeclarations(ml,ol,this,0,0);
       
  1311     return;
       
  1312   }
       
  1313   if (ml) 
       
  1314   {
       
  1315     ml->writeDeclarations(ol,0,0,0,this,title,0);
       
  1316   }
       
  1317 }
       
  1318 
       
  1319 void GroupDef::writeMemberDocumentation(OutputList &ol,MemberList::ListType lt,const QCString &title)
       
  1320 {
       
  1321   MemberList * ml = getMemberList(lt);
       
  1322   if (ml) ml->writeDocumentation(ol,name(),this,title);
       
  1323 }
       
  1324 
       
  1325 void GroupDef::removeMemberFromList(MemberList::ListType lt,MemberDef *md)
       
  1326 {
       
  1327     MemberList *ml = getMemberList(lt);
       
  1328     if (ml) ml->remove(md); 
       
  1329 }
       
  1330