📄 dot.cpp
字号:
cn->write(t,format,topDown,toChildren,distance,backArrows); } } else // render parents { QListIterator<DotNode> dnli(*nl); DotNode *pn; for (dnli.toFirst();(pn=dnli.current());++dnli) { if (pn->m_distance<=distance) { writeArrow(t, format, pn, pn->m_edgeInfo->at(pn->m_children->findRef(this)), FALSE, backArrows ); } pn->write(t,format,TRUE,FALSE,distance,backArrows); } } }}void DotNode::writeXML(QTextStream &t){ t << " <node id=\"" << m_number << "\">" << endl; t << " <label>" << convertToXML(m_label) << "</label>" << endl; if (!m_url.isEmpty()) { QCString url(m_url); char *refPtr = url.data(); char *urlPtr = strchr(url.data(),'$'); if (urlPtr) { *urlPtr++='\0'; t << " <link id=\"" << urlPtr << "\""; if (*refPtr!='\0') { t << " external=\"" << refPtr << "\""; } t << "/>" << endl; } } if (m_children) { QListIterator<DotNode> nli(*m_children); QListIterator<EdgeInfo> eli(*m_edgeInfo); DotNode *childNode; EdgeInfo *edgeInfo; for (;(childNode=nli.current());++nli,++eli) { edgeInfo=eli.current(); t << " <childnode id=\"" << childNode->m_number << "\" relation=\""; switch(edgeInfo->m_color) { case EdgeInfo::Blue: t << "public-inheritance"; break; case EdgeInfo::Green: t << "protected-inheritance"; break; case EdgeInfo::Red: t << "private-inheritance"; break; case EdgeInfo::Purple: t << "usage"; break; case EdgeInfo::Orange: t << "template-instance"; break; case EdgeInfo::Grey: ASSERT(0); break; } t << "\">" << endl; if (!edgeInfo->m_label.isEmpty()) { int p=0; int ni; while ((ni=edgeInfo->m_label.find("\\n",p))!=-1) { t << " <edgelabel>" << convertToXML(edgeInfo->m_label.mid(p,ni-p)) << "</edgelabel>" << endl; p=ni+2; } t << " <edgelabel>" << convertToXML(edgeInfo->m_label.right(edgeInfo->m_label.length()-p)) << "</edgelabel>" << endl; } t << " </childnode>" << endl; } } t << " </node>" << endl;}void DotNode::clearWriteFlag(){ m_written=FALSE; if (m_parents!=0) { QListIterator<DotNode> dnlip(*m_parents); DotNode *pn; for (dnlip.toFirst();(pn=dnlip.current());++dnlip) { if (pn->m_written) { pn->clearWriteFlag(); } } } if (m_children!=0) { QListIterator<DotNode> dnlic(*m_children); DotNode *cn; for (dnlic.toFirst();(cn=dnlic.current());++dnlic) { if (cn->m_written) { cn->clearWriteFlag(); } } }}void DotNode::colorConnectedNodes(int curColor){ if (m_children) { QListIterator<DotNode> dnlic(*m_children); DotNode *cn; for (dnlic.toFirst();(cn=dnlic.current());++dnlic) { if (cn->m_subgraphId==-1) // uncolored child node { cn->m_subgraphId=curColor; cn->colorConnectedNodes(curColor); //printf("coloring node %s (%p): %d\n",cn->m_label.data(),cn,cn->m_subgraphId); } } } if (m_parents) { QListIterator<DotNode> dnlip(*m_parents); DotNode *pn; for (dnlip.toFirst();(pn=dnlip.current());++dnlip) { if (pn->m_subgraphId==-1) // uncolored parent node { pn->m_subgraphId=curColor; pn->colorConnectedNodes(curColor); //printf("coloring node %s (%p): %d\n",pn->m_label.data(),pn,pn->m_subgraphId); } } }}const DotNode *DotNode::findDocNode() const{ if (!m_url.isEmpty()) return this; //printf("findDocNode(): `%s'\n",m_label.data()); if (m_parents) { QListIterator<DotNode> dnli(*m_parents); DotNode *pn; for (dnli.toFirst();(pn=dnli.current());++dnli) { if (!pn->m_hasDoc) { pn->m_hasDoc=TRUE; const DotNode *dn = pn->findDocNode(); if (dn) return dn; } } } if (m_children) { QListIterator<DotNode> dnli(*m_children); DotNode *cn; for (dnli.toFirst();(cn=dnli.current());++dnli) { if (!cn->m_hasDoc) { cn->m_hasDoc=TRUE; const DotNode *dn = cn->findDocNode(); if (dn) return dn; } } } return 0;}//--------------------------------------------------------------------int DotGfxHierarchyTable::m_curNodeNumber;void DotGfxHierarchyTable::writeGraph(QTextStream &out,const char *path){ //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("Error: Output dir %s does not exist!\n",path); exit(1); } QCString oldDir = convertToQCString(QDir::currentDirPath()); // go to the html output directory (i.e. path) QDir::setCurrent(d.absPath()); QDir thisDir; 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) { QCString baseName; baseName.sprintf("inherit_graph_%d",count++); baseName = convertNameToFile(baseName); QCString dotName=baseName+".dot"; QCString gifName=baseName+".gif"; QCString mapName=baseName+".map"; QFile f(dotName); if (!f.open(IO_WriteOnly)) return; QTextStream t(&f); t << "digraph inheritance" << endl; t << "{" << endl; t << " rankdir=LR;" << endl; QListIterator<DotNode> dnli2(*m_rootNodes); DotNode *node; for (;(node=dnli2.current());++dnli2) { if (node->m_subgraphId==n->m_subgraphId) node->write(t,GIF,FALSE,TRUE); } t << "}" << endl; f.close(); QCString dotArgs(4096); dotArgs.sprintf("-Tgif \"%s\" -o \"%s\"",dotName.data(),gifName.data()); //printf("Running: dot -Tgif %s -o %s\n",dotName.data(),gifName.data()); if (iSystem(Config_getString("DOT_PATH")+"dot",dotArgs)!=0) { err("Problems running dot. Check your installation!\n"); out << "</table>" << endl; return; } dotArgs.sprintf("-Timap \"%s\" -o \"%s\"",dotName.data(),mapName.data()); //printf("Running: dot -Timap %s -o %s\n",dotName.data(),mapName.data()); if (iSystem(Config_getString("DOT_PATH")+"dot",dotArgs)!=0) { err("Problems running dot. Check your installation!\n"); out << "</table>" << endl; return; } QCString mapLabel = convertNameToFile(n->m_label); out << "<tr><td><img src=\"" << gifName << "\" border=\"0\" usemap=\"#" << mapLabel << "_map\"></td></tr>" << endl; out << "<map name=\"" << mapLabel << "_map\">" << endl; convertMapFile(out,mapName); out << "</map>" << endl; if (Config_getBool("DOT_CLEANUP")) thisDir.remove(dotName); thisDir.remove(mapName); } out << "</table>" << endl; QDir::setCurrent(oldDir);}void DotGfxHierarchyTable::addHierarchy(DotNode *n,ClassDef *cd,bool hideSuper){ //printf("addHierarchy `%s' baseClasses=%d\n",cd->name().data(),cd->baseClasses()->count()); BaseClassListIterator bcli(*cd->subClasses()); BaseClassDef *bcd; for ( ; (bcd=bcli.current()) ; ++bcli ) { ClassDef *bClass=bcd->classDef; //printf("Trying super class=`%s'\n",bClass->name().data()); 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()) tmp_url=bClass->getReference()+"$"+bClass->getOutputFileBase(); bn = new DotNode(m_curNodeNumber++, bClass->displayName(), tmp_url.data() ); //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 // ); n->addChild(bn,bcd->prot); bn->addParent(n); m_usedNodes->insert(bClass->name(),bn); // add node to the used list } if (!bClass->visited && !hideSuper && bClass->subClasses()->count()>0) { bool wasVisited=bClass->visited; bClass->visited=TRUE; addHierarchy(bn,bClass,wasVisited); } } }}void DotGfxHierarchyTable::addClassList(ClassSDict *cl){ ClassSDict::Iterator cli(*cl); ClassDef *cd; for (cli.toLast();(cd=cli.current());--cli) { //printf("Trying %s subClasses=%d\n",cd->name().data(),cd->subClasses()->count()); if (!hasVisibleRoot(cd->baseClasses())) { if (cd->isVisibleInHierarchy()) // root node in the forest { QCString tmp_url=""; if (cd->isLinkable()) tmp_url=cd->getReference()+"$"+cd->getOutputFileBase(); //printf("Inserting root class %s\n",cd->name().data()); DotNode *n = new DotNode(m_curNodeNumber++, cd->displayName(), tmp_url.data() ); //m_usedNodes->clear(); m_usedNodes->insert(cd->name(),n); m_rootNodes->insert(0,n); if (!cd->visited && cd->subClasses()->count()>0) { addHierarchy(n,cd,cd->visited); cd->visited=TRUE; } } } }}DotGfxHierarchyTable::DotGfxHierarchyTable(){ m_curNodeNumber=0; m_rootNodes = new QList<DotNode>; //m_rootNodes->setAutoDelete(TRUE); // rootNodes owns the nodes m_usedNodes = new QDict<DotNode>(1009); // virtualNodes only aliases nodes m_rootSubgraphs = new DotNodeList; // build a graph with each class as a node and the inheritance relations // as edges initClassHierarchy(&Doxygen::classSDict); initClassHierarchy(&Doxygen::hiddenClasses); addClassList(&Doxygen::classSDict); addClassList(&Doxygen::hiddenClasses); // 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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -