⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 diagram.cpp

📁 doxygen(一个自动从源代码生成文档的工具)的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************** * * $Id: diagram.cpp,v 1.30 2001/03/19 19:27:40 root Exp $ * * * Copyright (C) 1997-2001 by Dimitri van Heesch. * * Permission to use, copy, modify, and distribute this software and its * documentation under the terms of the GNU General Public License is hereby  * granted. No representations are made about the suitability of this software  * for any purpose. It is provided "as is" without express or implied warranty. * See the GNU General Public License for more details. * * Documents produced by Doxygen are derivative works derived from the * input used in their production; they are not affected by this license. * */#include "qtbc.h"#include <stdio.h>#include <stdlib.h>#include <qlist.h>#include <qarray.h>#include <qtextstream.h>#include <qfile.h>#include "diagram.h"#include "image.h"#include "classdef.h"#include "config.h"#include "message.h"#include "util.h"#include "latexgen.h"#include "htmlgen.h"#include "doxygen.h"//-----------------------------------------------------------------------------const uint maxTreeWidth = 8;const int gridWidth  = 100;const int gridHeight = 100;const uint labelHorSpacing  = 10;  // horizontal distance between labelsconst uint labelVertSpacing = 32;  // vertical distance between labelsconst uint labelHorMargin   = 6;   // horiz. spacing between label and boxconst uint fontHeight       = 12;  // height of a character//static QCString escapeLatex(const char *s)//{//  QCString result;//  char c;//  while ((c=*s++))//  {//    if (c=='_') result+="\\_";//           else result+=c;//  }//  return result;//}static uint protToMask(Protection p){  switch(p)  {    case Public:    return 0xffffffff;    case Protected: return 0xcccccccc;    case Private:   return 0xaaaaaaaa;  }  return 0;}static uint protToColor(Protection p){  switch(p)  {    case Public:    return 6;    case Protected: return 5;    case Private:   return 4;  }  return 0;}static QCString protToString(Protection p){  switch(p)  {    case Public:    return "solid";    case Protected: return "dashed";    case Private:   return "dotted";  }  return 0;}static uint virtToMask(Specifier p){  switch(p)  {    case Normal:    return 0xffffffff;    case Virtual:   return 0xf0f0f0f0;    default:        return 0;  }  return 0;}// pre: dil is not emptystatic Protection getMinProtectionLevel(DiagramItemList *dil){  DiagramItem *di=dil->first();  Protection result=di->protection();  di=dil->next();  while (di)  {    Protection p=di->protection();    if (p!=result)     {      if (result==Protected && p==Public) result=p;      else if (result==Private) result=p;    }     di=dil->next();  }  return result;}static void writeBitmapBox(DiagramItem *di,Image *image,                           int x,int y,int w,int h,bool firstRow,                           bool hasDocs,bool children=FALSE){  int colFill = hasDocs ? (firstRow ? 0 : 2) : 7;  int colBorder = (firstRow || !hasDocs) ? 1 : 3;  int l = Image::stringLength(di->label());  uint mask=virtToMask(di->virtualness());  image->fillRect(x+1,y+1,w-2,h-2,colFill,mask);  image->drawRect(x,y,w,h,colBorder,mask);  image->writeString(x+(w-l)/2, y+(h-fontHeight)/2, di->label(),1);  if (children)  {    int i;    for (i=0;i<5;i++)      image->drawHorzLine(y+h+i-6,x+w-2-i,x+w-2,firstRow?1:3,0xffffffff);  }}static void writeVectorBox(QTextStream &t,DiagramItem *di,                           float x,float y,bool children=FALSE){  if (di->virtualness()==Virtual) t << "dashed\n";  t << " (" << di->label() << ") " << x << " " << y << " box\n";  if (children) t << x << " " << y << " mark\n";  if (di->virtualness()==Virtual) t << "solid\n";}static void writeMapArea(QTextStream &t,ClassDef *cd,int x,int y,int w,int h){  if (cd->isLinkable())  {    QCString *dest;    QCString ref=cd->getReference();    t << "<area ";    if (!ref.isEmpty())     {      t << "doxygen=\"" << ref << ":";      if ((dest=Doxygen::tagDestinationDict[ref])) t << *dest << "/";      t << "\" ";    }    t << "href=\"";    if (!ref.isEmpty())    {      if ((dest=Doxygen::tagDestinationDict[ref])) t << *dest << "/";    }    t << cd->getOutputFileBase() << ".html\" ";    t << "alt=\"" << cd->name();     t << "\" shape=\"rect\" coords=\"" << x << "," << y << ",";    t << (x+w) << "," << (y+h) << "\">" << endl;  }}//-----------------------------------------------------------------------------DiagramItem::DiagramItem(DiagramItem *p,int number,ClassDef *cd,                         Protection pr,Specifier vi,const char *ts) {   parent=p;   x=y=0;   //name=n;  num=number;  children = new DiagramItemList;  prot=pr;  virt=vi;  inList=FALSE;  classDef=cd;  templSpec=ts;} DiagramItem::~DiagramItem() {   delete children;}QCString DiagramItem::label() const{  QCString result;  if (!templSpec.isEmpty())  {    result=insertTemplateSpecifierInScope(classDef->name(),templSpec);  }  else  {    result=classDef->name();  }  if (Config_getBool("HIDE_SCOPE_NAMES")) result=stripScope(result);  return result;}QCString DiagramItem::fileName() const{  return classDef->getOutputFileBase();}int DiagramItem::avgChildPos() const{  DiagramItem *di;  int c=children->count();  if (c==0) // no children -> don't move    return xPos();  if ((di=children->getFirst())->isInList()) // children should be in a list    return di->xPos();  if (c&1) // odd number of children -> get pos of middle child    return children->at(c/2)->xPos();  else // even number of children -> get middle of most middle children    return (children->at(c/2-1)->xPos()+children->at(c/2)->xPos())/2;}int DiagramItem::numChildren() const{  return children->count();}void DiagramItem::addChild(DiagramItem *di){  children->append(di);}void DiagramRow::insertClass(DiagramItem *parent,ClassDef *cd,bool doBases,                             Protection prot,Specifier virt,const char *ts){  //if (cd->visited) return; // the visit check does not work in case of                             // multiple inheritance of the same class!  DiagramItem *di=new DiagramItem(parent, diagram->at(level)->count(),                                   cd,prot,virt,ts);  //cd->visited=TRUE;  if (parent) parent->addChild(di);  di->move(count()*gridWidth,level*gridHeight);  append(di);  BaseClassList *bcl=doBases ? cd->baseClasses() : cd->subClasses();  /* there are base/sub classes */  int count=0;  BaseClassDef *bcd=bcl->first();  while (bcd)  {    ClassDef *ccd=bcd->classDef;    if (ccd && ccd->isVisibleInHierarchy() /*&& !ccd->visited*/) count++;    bcd=bcl->next();  }  if (count>0 && (prot!=Private || !doBases))  {    DiagramRow *row=0;    if (diagram->count()<=level+1) /* add new row */    {      row = new DiagramRow(diagram,level+1);      diagram->append(row);    }    else /* get next row */    {      row=diagram->at(level+1);    }    /* insert base classes in the next row */    BaseClassDef *bcd=bcl->first();    while (bcd)    {      ClassDef *ccd=bcd->classDef;      if (ccd && ccd->isVisibleInHierarchy() /*&& !ccd->visited*/)      {        row->insertClass(di,ccd,doBases,bcd->prot,            doBases?bcd->virt:Normal,            doBases?bcd->templSpecifiers.data():"");      }      bcd=bcl->next();    }  }}TreeDiagram::TreeDiagram(ClassDef *root,bool doBases){  setAutoDelete(TRUE);   DiagramRow *row=new DiagramRow(this,0);  append(row);  row->insertClass(0,root,doBases,Public,Normal,0);}TreeDiagram::~TreeDiagram(){}void TreeDiagram::moveChildren(DiagramItem *root,int dx){  DiagramItemList *dil=root->getChildren();  DiagramItem *di=dil->first();  while (di)  {    di->move(dx,0);    moveChildren(di,dx);    di=dil->next();  }}bool TreeDiagram::layoutTree(DiagramItem *root,int r){  bool moved=FALSE;  //printf("layoutTree(%s,%d)\n",root->label().data(),r);  DiagramItemList *dil=root->getChildren();   if (dil->count()>0)  {    uint k;    int pPos=root->xPos();    int cPos=root->avgChildPos();    if (pPos>cPos) // move children    {      DiagramRow *row=at(r+1);      //printf("Moving children %d-%d in row %d\n",      //    dil->getFirst()->number(),row->count()-1,r+1);      for (k=dil->getFirst()->number();k<row->count();k++)        row->at(k)->move(pPos-cPos,0);      moved=TRUE;    }    else if (pPos<cPos) // move parent    {      DiagramRow *row=at(r);      //printf("Moving parents %d-%d in row %d\n",      //    root->number(),row->count()-1,r);      for (k=root->number();k<row->count();k++)        row->at(k)->move(cPos-pPos,0);      moved=TRUE;    }    // recurse to children    DiagramItem *di=dil->first();    while (di && !moved && !di->isInList())    {      moved = moved || layoutTree(di,r+1);      di=dil->next();    }  }  return moved;}void TreeDiagram::computeLayout(){  DiagramRow *row=first();  while (row && row->count()<maxTreeWidth) row=next();  if (row)  {    //printf("computeLayout() list row at %d\n",row->number());    DiagramItem *di=row->first();    DiagramItem *opi=0;    int delta=0;    bool first=TRUE;    while (di)    {      DiagramItem *pi=di->parentItem();      if (pi==opi && !first) { delta-=gridWidth; }      first = pi!=opi;      opi=pi;      di->move(delta,0); // collapse all items in the same                          // list (except the first)      di->putInList();      di=row->next();    }  }  // re-organize the diagram items  DiagramItem *root=getFirst()->getFirst();  while (layoutTree(root,0));    // move first items of the lists  if (row)  {    DiagramItem *di=row->first();    while (di)    {      DiagramItem *pi=di->parentItem();      if (pi->getChildren()->count()>1)      {        di->move(gridWidth,0);        while (di && di->parentItem()==pi) di=row->next();      }      else      {        di=row->next();      }    }  }}uint TreeDiagram::computeRows(){  //printf("TreeDiagram::computeRows()=%d\n",count());  int count=0;  DiagramRow *row=first();  while (row && !row->getFirst()->isInList())  {    count++;    row=next();  }  //printf("count=%d row=%p\n",count,row);  if (row)  {    int maxListLen=0;    int curListLen=0;    DiagramItem *di=row->first(),*opi=0;    while (di)    {      if (di->parentItem()!=opi) curListLen=1; else curListLen++;       if (curListLen>maxListLen) maxListLen=curListLen;      opi=di->parentItem();      di=row->next();    }    //printf("maxListLen=%d\n",maxListLen);    count+=maxListLen;  }  return count;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -