My Project
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Public Member Functions | Private Member Functions | Private Attributes | List of all members
DotGfxHierarchyTable Class Reference

#include <dot.h>

Public Member Functions

 DotGfxHierarchyTable ()
 
 ~DotGfxHierarchyTable ()
 
void writeGraph (FTextStream &t, const char *path, const char *fileName) const
 
void createGraph (DotNode *rootNode, FTextStream &t, const char *path, const char *fileName, int id) const
 
const DotNodeListsubGraphs () const
 

Private Member Functions

void addHierarchy (DotNode *n, ClassDef *cd, bool hide)
 
void addClassList (ClassSDict *cl)
 

Private Attributes

QList< DotNode > * m_rootNodes
 
QDict< DotNode > * m_usedNodes
 
int m_curNodeNumber
 
DotNodeListm_rootSubgraphs
 

Detailed Description

Represents a graphical class hierarchy

Definition at line 149 of file dot.h.

Constructor & Destructor Documentation

DotGfxHierarchyTable::DotGfxHierarchyTable ( )

Definition at line 2480 of file dot.cpp.

References addClassList(), Doxygen::classSDict, DotNode::colorConnectedNodes(), DotNode::findDocNode(), Doxygen::hiddenClasses, initClassHierarchy(), m_rootNodes, m_rootSubgraphs, DotNode::m_subgraphId, m_usedNodes, DotNode::markAsVisible(), and DotNode::renumberNodes().

{
m_rootNodes = new QList<DotNode>;
m_usedNodes = new QDict<DotNode>(1009);
m_usedNodes->setAutoDelete(TRUE);
// build a graph with each class as a node and the inheritance relations
// as edges
// m_usedNodes now contains all nodes in the graph
// color the graph into a set of independent subgraphs
bool done=FALSE;
int curColor=0;
QListIterator<DotNode> dnli(*m_rootNodes);
while (!done) // there are still nodes to color
{
DotNode *n;
done=TRUE; // we are done unless there are still uncolored nodes
for (dnli.toLast();(n=dnli.current());--dnli)
{
if (n->m_subgraphId==-1) // not yet colored
{
//printf("Starting at node %s (%p): %d\n",n->m_label.data(),n,curColor);
done=FALSE; // still uncolored nodes
n->m_subgraphId=curColor;
n->colorConnectedNodes(curColor);
curColor++;
const DotNode *dn=n->findDocNode();
if (dn!=0)
m_rootSubgraphs->inSort(dn);
else
m_rootSubgraphs->inSort(n);
}
}
}
//printf("Number of independent subgraphs: %d\n",curColor);
QListIterator<DotNode> dnli2(*m_rootSubgraphs);
DotNode *n;
for (dnli2.toFirst();(n=dnli2.current());++dnli2)
{
//printf("Node %s color=%d (c=%d,p=%d)\n",
// n->m_label.data(),n->m_subgraphId,
// n->m_children?n->m_children->count():0,
// n->m_parents?n->m_parents->count():0);
int number=0;
n->renumberNodes(number);
}
}
DotGfxHierarchyTable::~DotGfxHierarchyTable ( )

Definition at line 2536 of file dot.cpp.

References m_rootNodes, m_rootSubgraphs, and m_usedNodes.

{
//printf("DotGfxHierarchyTable::~DotGfxHierarchyTable\n");
//QDictIterator<DotNode> di(*m_usedNodes);
//DotNode *n;
//for (;(n=di.current());++di)
//{
// printf("Node %p: %s\n",n,n->label().data());
//}
delete m_rootNodes;
delete m_usedNodes;
}

Member Function Documentation

void DotGfxHierarchyTable::addClassList ( ClassSDict cl)
private

Definition at line 2435 of file dot.cpp.

References addHierarchy(), ClassDef::anchor(), ClassDef::baseClasses(), Definition::briefDescriptionAsTooltip(), ClassDef::displayName(), VhdlDocGen::ENTITYCLASS, Definition::getLanguage(), ClassDef::getOutputFileBase(), ClassDef::getReference(), hasVisibleRoot(), Definition::isHidden(), ClassDef::isLinkable(), ClassDef::isVisibleInHierarchy(), SDict< ClassDef >::Iterator, m_curNodeNumber, m_rootNodes, m_usedNodes, Definition::name(), ClassDef::protection(), SrcLangExt_VHDL, ClassDef::subClasses(), and ClassDef::visited.

Referenced by DotGfxHierarchyTable().

{
ClassDef *cd;
for (cli.toLast();(cd=cli.current());--cli)
{
//printf("Trying %s subClasses=%d\n",cd->name().data(),cd->subClasses()->count());
)
{
continue;
}
if (!hasVisibleRoot(cd->baseClasses()) &&
) // root node in the forest
{
QCString tmp_url="";
if (cd->isLinkable() && !cd->isHidden())
{
tmp_url=cd->getReference()+"$"+cd->getOutputFileBase();
if (!cd->anchor().isEmpty())
{
tmp_url+="#"+cd->anchor();
}
}
//printf("Inserting root class %s\n",cd->name().data());
QCString tooltip = cd->briefDescriptionAsTooltip();
cd->displayName(),
tooltip,
tmp_url.data());
//m_usedNodes->clear();
m_usedNodes->insert(cd->name(),n);
m_rootNodes->insert(0,n);
if (!cd->visited && cd->subClasses())
{
addHierarchy(n,cd,cd->visited);
cd->visited=TRUE;
}
}
}
}
void DotGfxHierarchyTable::addHierarchy ( DotNode n,
ClassDef cd,
bool  hide 
)
private

Definition at line 2361 of file dot.cpp.

References DotNode::addChild(), DotNode::addParent(), ClassDef::anchor(), ClassDef::baseClasses(), Definition::briefDescriptionAsTooltip(), ClassDef::displayName(), ClassDef::getOutputFileBase(), ClassDef::getReference(), hasVisibleRoot(), Definition::isHidden(), ClassDef::isLinkable(), ClassDef::isVisibleInHierarchy(), DotNode::m_children, m_curNodeNumber, m_usedNodes, Definition::name(), ClassDef::subClasses(), and ClassDef::visited.

Referenced by addClassList().

{
//printf("addHierarchy `%s' baseClasses=%d\n",cd->name().data(),cd->baseClasses()->count());
if (cd->subClasses())
{
for ( ; (bcd=bcli.current()) ; ++bcli )
{
ClassDef *bClass=bcd->classDef;
//printf(" Trying sub class=`%s' usedNodes=%d\n",bClass->name().data(),m_usedNodes->count());
if (bClass->isVisibleInHierarchy() && hasVisibleRoot(bClass->baseClasses()))
{
DotNode *bn;
//printf(" Node `%s' Found visible class=`%s'\n",n->m_label.data(),
// bClass->name().data());
if ((bn=m_usedNodes->find(bClass->name()))) // node already present
{
if (n->m_children==0 || n->m_children->findRef(bn)==-1) // no arrow yet
{
n->addChild(bn,bcd->prot);
bn->addParent(n);
//printf(" Adding node %s to existing base node %s (c=%d,p=%d)\n",
// n->m_label.data(),
// bn->m_label.data(),
// bn->m_children ? bn->m_children->count() : 0,
// bn->m_parents ? bn->m_parents->count() : 0
// );
}
//else
//{
// printf(" Class already has an arrow!\n");
//}
}
else
{
QCString tmp_url="";
if (bClass->isLinkable() && !bClass->isHidden())
{
tmp_url=bClass->getReference()+"$"+bClass->getOutputFileBase();
if (!bClass->anchor().isEmpty())
{
tmp_url+="#"+bClass->anchor();
}
}
QCString tooltip = bClass->briefDescriptionAsTooltip();
bClass->displayName(),
tooltip,
tmp_url.data()
);
n->addChild(bn,bcd->prot);
bn->addParent(n);
//printf(" Adding node %s to new base node %s (c=%d,p=%d)\n",
// n->m_label.data(),
// bn->m_label.data(),
// bn->m_children ? bn->m_children->count() : 0,
// bn->m_parents ? bn->m_parents->count() : 0
// );
//printf(" inserting %s (%p)\n",bClass->name().data(),bn);
m_usedNodes->insert(bClass->name(),bn); // add node to the used list
}
if (!bClass->visited && !hideSuper && bClass->subClasses())
{
bool wasVisited=bClass->visited;
bClass->visited=TRUE;
addHierarchy(bn,bClass,wasVisited);
}
}
}
}
//printf("end addHierarchy\n");
}
void DotGfxHierarchyTable::createGraph ( DotNode rootNode,
FTextStream t,
const char *  path,
const char *  fileName,
int  id 
) const

Definition at line 2238 of file dot.cpp.

References IndexList::addImageFile(), DotRunner::addJob(), DotManager::addMap(), DotManager::addRun(), DotManager::addSVGConversion(), DotManager::addSVGObject(), checkAndUpdateMd5Signature(), checkDeliverables(), DotNode::clearWriteFlag(), Config_getEnum, endl(), escapeCharsInString(), getDotImageExtension(), GOF_BITMAP, DotNode::Hierarchy, Doxygen::indexList, insertMapFile(), DotManager::instance(), DotNode::m_label, m_rootNodes, DotNode::m_subgraphId, MAP_CMD, removeDotGraph(), theTranslator, Translator::trGraphicalHierarchy(), DotNode::write(), writeGraphFooter(), writeGraphHeader(), and writeSVGFigureLink().

Referenced by InheritanceGraphContext::Private::graph(), and writeGraph().

{
QDir d(path);
QCString baseName;
QCString imgExt = getDotImageExtension();
QCString imgFmt = Config_getEnum(DOT_IMAGE_FORMAT);
baseName.sprintf("inherit_graph_%d",id);
QCString imgName = baseName+"."+ imgExt;
QCString mapName = baseName+".map";
QCString absImgName = QCString(d.absPath().data())+"/"+imgName;
QCString absMapName = QCString(d.absPath().data())+"/"+mapName;
QCString absBaseName = QCString(d.absPath().data())+"/"+baseName;
QListIterator<DotNode> dnli2(*m_rootNodes);
DotNode *node;
// compute md5 checksum of the graph were are about to generate
QGString theGraph;
FTextStream md5stream(&theGraph);
md5stream << " rankdir=\"LR\";" << endl;
for (dnli2.toFirst();(node=dnli2.current());++dnli2)
{
if (node->m_subgraphId==n->m_subgraphId)
{
node->clearWriteFlag();
}
}
for (dnli2.toFirst();(node=dnli2.current());++dnli2)
{
if (node->m_subgraphId==n->m_subgraphId)
{
node->write(md5stream,DotNode::Hierarchy,GOF_BITMAP,FALSE,TRUE,TRUE);
}
}
writeGraphFooter(md5stream);
uchar md5_sig[16];
QCString sigStr(33);
MD5Buffer((const unsigned char *)theGraph.data(),theGraph.length(),md5_sig);
MD5SigToString(md5_sig,sigStr.rawData(),33);
bool regenerate=FALSE;
if (checkAndUpdateMd5Signature(absBaseName,sigStr) ||
!checkDeliverables(absImgName,absMapName))
{
regenerate=TRUE;
// image was new or has changed
QCString dotName=absBaseName+".dot";
QFile f(dotName);
if (!f.open(IO_WriteOnly)) return;
FTextStream t(&f);
t << theGraph;
f.close();
DotRunner *dotRun = new DotRunner(dotName,d.absPath().data(),TRUE,absImgName);
dotRun->addJob(imgFmt,absImgName);
dotRun->addJob(MAP_CMD,absMapName);
}
else
{
removeDotGraph(absBaseName+".dot");
}
// write image and map in a table row
QCString mapLabel = escapeCharsInString(n->m_label,FALSE);
if (imgExt=="svg") // vector graphics
{
if (regenerate || !writeSVGFigureLink(out,QCString(),baseName,absImgName))
{
if (regenerate)
{
DotManager::instance()->addSVGConversion(absImgName,QCString(),
FALSE,QCString(),FALSE,0);
}
int mapId = DotManager::instance()->addSVGObject(fileName,baseName,
absImgName,QCString());
out << "<!-- SVG " << mapId << " -->" << endl;
}
}
else // normal bitmap
{
out << "<img src=\"" << imgName << "\" border=\"0\" alt=\"\" usemap=\"#"
<< mapLabel << "\"/>" << endl;
if (regenerate || !insertMapFile(out,absMapName,QCString(),mapLabel))
{
int mapId = DotManager::instance()->addMap(fileName,absMapName,QCString(),
FALSE,QCString(),mapLabel);
out << "<!-- MAP " << mapId << " -->" << endl;
}
}
}
const DotNodeList* DotGfxHierarchyTable::subGraphs ( ) const
inline

Definition at line 156 of file dot.h.

References m_rootSubgraphs.

Referenced by ClassHierarchyContext::Private::diagrams().

{ return m_rootSubgraphs; }
void DotGfxHierarchyTable::writeGraph ( FTextStream t,
const char *  path,
const char *  fileName 
) const

Definition at line 2331 of file dot.cpp.

References createGraph(), endl(), err(), and m_rootSubgraphs.

Referenced by HtmlGenerator::writeGraphicalHierarchy().

{
//printf("DotGfxHierarchyTable::writeGraph(%s)\n",name);
//printf("m_rootNodes=%p count=%d\n",m_rootNodes,m_rootNodes->count());
if (m_rootSubgraphs->count()==0) return;
QDir d(path);
// store the original directory
if (!d.exists())
{
err("Output dir %s does not exist!\n",path); exit(1);
}
// put each connected subgraph of the hierarchy in a row of the HTML output
out << "<table border=\"0\" cellspacing=\"10\" cellpadding=\"0\">" << endl;
QListIterator<DotNode> dnli(*m_rootSubgraphs);
DotNode *n;
int count=0;
for (dnli.toFirst();(n=dnli.current());++dnli)
{
out << "<tr><td>";
createGraph(n,out,path,fileName,count++);
out << "</td></tr>" << endl;
}
out << "</table>" << endl;
}

Member Data Documentation

int DotGfxHierarchyTable::m_curNodeNumber
private

Definition at line 164 of file dot.h.

Referenced by addClassList(), and addHierarchy().

QList<DotNode>* DotGfxHierarchyTable::m_rootNodes
private

Definition at line 162 of file dot.h.

Referenced by addClassList(), createGraph(), DotGfxHierarchyTable(), and ~DotGfxHierarchyTable().

DotNodeList* DotGfxHierarchyTable::m_rootSubgraphs
private

Definition at line 165 of file dot.h.

Referenced by DotGfxHierarchyTable(), subGraphs(), writeGraph(), and ~DotGfxHierarchyTable().

QDict<DotNode>* DotGfxHierarchyTable::m_usedNodes
private

Definition at line 163 of file dot.h.

Referenced by addClassList(), addHierarchy(), DotGfxHierarchyTable(), and ~DotGfxHierarchyTable().


The documentation for this class was generated from the following files: