Doxygen
dotgfxhierarchytable.cpp
浏览该文件的文档.
1 /******************************************************************************
2 *
3 * Copyright (C) 1997-2019 by Dimitri van Heesch.
4 *
5 * Permission to use, copy, modify, and distribute this software and its
6 * documentation under the terms of the GNU General Public License is hereby
7 * granted. No representations are made about the suitability of this software
8 * for any purpose. It is provided "as is" without express or implied warranty.
9 * See the GNU General Public License for more details.
10 *
11 * Documents produced by Doxygen are derivative works derived from the
12 * input used in their production; they are not affected by this license.
13 *
14 */
15 
16 #include <sstream>
17 
18 #include "dotgfxhierarchytable.h"
19 #include "language.h"
20 #include "util.h"
21 #include "message.h"
22 #include "doxygen.h"
23 #include "classlist.h"
24 #include "dir.h"
25 #include "vhdldocgen.h"
26 
28 {
29  QCString baseName;
30  if (m_prefix.isEmpty())
31  baseName.sprintf("inherit_graph_%d", m_graphId);
32  else
33  baseName.sprintf("%sinherit_graph_%d",qPrint(m_prefix), m_graphId);
34  return baseName;
35 }
36 
38 {
39  TextStream md5stream;
41  md5stream << " rankdir=\"LR\";\n";
42  for (auto node : m_rootNodes)
43  {
44  if (node->subgraphId()==m_rootSubgraphNode->subgraphId())
45  {
46  node->clearWriteFlag();
47  }
48  }
49  for (auto node : m_rootNodes)
50  {
51  if (node->subgraphId()==m_rootSubgraphNode->subgraphId())
52  {
53  node->write(md5stream,Hierarchy,GOF_BITMAP,FALSE,TRUE,TRUE);
54  }
55  }
56  writeGraphFooter(md5stream);
57  m_theGraph = md5stream.str();
58 }
59 
61 {
63 }
64 
66  const QCString &path,const QCString &fileName,int id)
67 {
69  m_graphId = id;
70  m_noDivTag = TRUE;
71  m_zoomable = FALSE;
72  DotGraph::writeGraph(out, GOF_BITMAP, EOF_Html, path, fileName, "", TRUE, 0);
73 }
74 
76  const QCString &path,const QCString &fileName)
77 {
78  //printf("DotGfxHierarchyTable::writeGraph(%s)\n",name);
79  //printf("m_rootNodes=%p count=%d\n",m_rootNodes,m_rootNodes->count());
80 
81  if (m_rootSubgraphs.empty()) return;
82 
83  Dir d(path.str());
84  // store the original directory
85  if (!d.exists())
86  {
87  term("Output dir %s does not exist!\n",qPrint(path));
88  }
89 
90  // put each connected subgraph of the hierarchy in a row of the HTML output
91  out << "<table border=\"0\" cellspacing=\"10\" cellpadding=\"0\">\n";
92 
93  int count=0;
94  std::sort(m_rootSubgraphs.begin(),m_rootSubgraphs.end(),
95  [](auto n1,auto n2) { return qstricmp(n1->label(),n2->label())<0; });
96  for (auto n : m_rootSubgraphs)
97  {
98  out << "<tr><td>";
99  createGraph(n,out,path,fileName,count++);
100  out << "</td></tr>\n";
101  }
102  out << "</table>\n";
103 }
104 
106 {
107  //printf("addHierarchy '%s' baseClasses=%d\n",qPrint(cd->name()),cd->baseClasses()->count());
108  for (const auto &bcd : cd->subClasses())
109  {
110  ClassDef *bClass=bcd.classDef;
111  //printf(" Trying sub class='%s' usedNodes=%d\n",qPrint(bClass->name()),m_usedNodes->count());
112  if (bClass && bClass->isVisibleInHierarchy() && hasVisibleRoot(bClass->baseClasses()))
113  {
114  auto it = m_usedNodes.find(bClass->name().str());
115  //printf(" Node '%s' Found visible class='%s'\n",qPrint(n->label()),
116  // qPrint(bClass->name()));
117  DotNode *root = 0;
118  if (it!=m_usedNodes.end()) // node already present
119  {
120  const auto &bn = it->second;
121  root = bn.get();
122  const auto &children = n->children();
123  auto child_it = std::find(children.begin(),children.end(),bn.get());
124  if (child_it==children.end()) // no arrow yet
125  {
126  n->addChild(bn.get(),bcd.prot);
127  bn->addParent(n);
128  //printf(" Adding node %s to existing base node %s (c=%d,p=%d)\n",
129  // qPrint(n->label()),
130  // qPrint(bn->label()),
131  // bn->children() ? bn->children()->count() : 0,
132  // bn->parents() ? bn->parents()->count() : 0
133  // );
134  }
135  //else
136  //{
137  // printf(" Class already has an arrow!\n");
138  //}
139  }
140  else
141  {
142  QCString tmp_url="";
143  if (bClass->isLinkable() && !bClass->isHidden())
144  {
145  tmp_url=bClass->getReference()+"$"+bClass->getOutputFileBase();
146  if (!bClass->anchor().isEmpty())
147  {
148  tmp_url+="#"+bClass->anchor();
149  }
150  }
151  QCString tooltip = bClass->briefDescriptionAsTooltip();
152  auto bn = std::make_unique<DotNode>(getNextNodeNumber(),
153  bClass->displayName(),
154  tooltip,
155  tmp_url
156  );
157  n->addChild(bn.get(),bcd.prot);
158  bn->addParent(n);
159  root = bn.get();
160  //printf(" Adding node %s to new base node %s (c=%d,p=%d)\n",
161  // qPrint(n->label()),
162  // qPrint(bn->label()),
163  // bn->children() ? bn->children()->count() : 0,
164  // bn->parents() ? bn->parents()->count() : 0
165  // );
166  //printf(" inserting %s (%p)\n",qPrint(bClass->name()),bn);
167  m_usedNodes.insert(std::make_pair(bClass->name().str(),std::move(bn))); // add node to the used list
168  }
169  if (visitedClasses.find(bClass)==visitedClasses.end() && !bClass->subClasses().empty())
170  {
171  visitedClasses.insert(bClass);
172  addHierarchy(root,bClass,visitedClasses);
173  }
174  }
175  }
176  //printf("end addHierarchy\n");
177 }
178 
180 {
181  for (const auto &cd : cl)
182  {
183  //printf("Trying %s subClasses=%d\n",qPrint(cd->name()),cd->subClasses()->count());
184  if (cd->getLanguage()==SrcLangExt_VHDL &&
186  )
187  {
188  continue;
189  }
190  if (Config_getBool(OPTIMIZE_OUTPUT_SLICE) && cd->compoundType() != m_classType)
191  {
192  continue;
193  }
194  if (!hasVisibleRoot(cd->baseClasses()) &&
195  cd->isVisibleInHierarchy()
196  ) // root node in the forest
197  {
198  QCString tmp_url="";
199  if (cd->isLinkable() && !cd->isHidden())
200  {
201  tmp_url=cd->getReference()+"$"+cd->getOutputFileBase();
202  if (!cd->anchor().isEmpty())
203  {
204  tmp_url+="#"+cd->anchor();
205  }
206  }
207  //printf("Inserting root class %s\n",qPrint(cd->name()));
208  QCString tooltip = cd->briefDescriptionAsTooltip();
209  auto n = std::make_unique<DotNode>(getNextNodeNumber(),
210  cd->displayName(),
211  tooltip,
212  tmp_url);
213  DotNode *root = n.get();
214 
215  m_usedNodes.insert(std::make_pair(cd->name().str(),std::move(n)));
216  m_rootNodes.push_back(root);
217  if (visitedClasses.find(cd.get())==visitedClasses.end() && !cd->subClasses().empty())
218  {
219  addHierarchy(root,cd.get(),visitedClasses);
220  visitedClasses.insert(cd.get());
221  }
222  }
223  }
224 }
225 
227  : m_prefix(prefix)
228  , m_classType(ct)
229 {
230  // build a graph with each class as a node and the inheritance relations
231  // as edges
232  ClassDefSet visitedClasses;
233  addClassList(*Doxygen::classLinkedMap,visitedClasses);
235  // m_usedNodes now contains all nodes in the graph
236 
237  // color the graph into a set of independent subgraphs
238  bool done=FALSE;
239  int curColor=0;
240  while (!done) // there are still nodes to color
241  {
242  done=TRUE; // we are done unless there are still uncolored nodes
243  for (auto n : m_rootNodes)
244  {
245  if (n->subgraphId()==-1) // not yet colored
246  {
247  //printf("Starting at node %s (%p): %d\n",qPrint(n->label()),n,curColor);
248  done=FALSE; // still uncolored nodes
249  n->setSubgraphId(curColor);
250  n->markAsVisible();
251  n->colorConnectedNodes(curColor);
252  curColor++;
253  m_rootSubgraphs.push_back(n);
254  }
255  }
256  }
257 
258  //printf("Number of independent subgraphs: %d\n",curColor);
259  for (auto n : m_rootSubgraphs)
260  {
261  //printf("Node %s color=%d (c=%d,p=%d)\n",
262  // qPrint(n->label()),n->m_subgraphId,
263  // n->children()?n->children()->count():0,
264  // n->parents()?n->parents()->count():0);
265  int number=0;
266  n->renumberNodes(number);
267  }
268 }
269 
DotGfxHierarchyTable::createGraph
void createGraph(DotNode *rootNode, TextStream &t, const QCString &path, const QCString &fileName, int id)
Definition: dotgfxhierarchytable.cpp:65
DotNode::addChild
void addChild(DotNode *n, int edgeColor=EdgeInfo::Purple, int edgeStyle=EdgeInfo::Solid, const QCString &edgeLab=QCString(), const QCString &edgeURL=QCString(), int edgeLabCol=-1)
Definition: dotnode.cpp:281
hasVisibleRoot
bool hasVisibleRoot(const BaseClassList &bcl)
Definition: classdef.cpp:4980
DotGfxHierarchyTable::addClassList
void addClassList(const ClassLinkedMap &cl, ClassDefSet &visited)
Definition: dotgfxhierarchytable.cpp:179
DotGfxHierarchyTable::m_rootNodes
std::vector< DotNode * > m_rootNodes
Definition: dotgfxhierarchytable.h:53
DotGfxHierarchyTable::m_classType
ClassDef::CompoundType m_classType
Definition: dotgfxhierarchytable.h:52
DotGraph::m_theGraph
QCString m_theGraph
Definition: dotgraph.h:89
Dir
Class representing a directory in the file system
Definition: dir.h:68
DotGfxHierarchyTable::m_usedNodes
DotNodeMap m_usedNodes
Definition: dotgfxhierarchytable.h:54
Doxygen::hiddenClassLinkedMap
static ClassLinkedMap * hiddenClassLinkedMap
Definition: doxygen.h:79
DotGfxHierarchyTable::m_rootSubgraphNode
DotNode * m_rootSubgraphNode
Definition: dotgfxhierarchytable.h:56
QCString::isEmpty
bool isEmpty() const
Returns TRUE iff the string is empty
Definition: qcstring.h:144
dotgfxhierarchytable.h
ClassDef::CompoundType
CompoundType
The various compound types
Definition: classdef.h:107
DotGfxHierarchyTable::m_rootSubgraphs
std::vector< DotNode * > m_rootSubgraphs
Definition: dotgfxhierarchytable.h:55
DotGfxHierarchyTable::writeGraph
void writeGraph(TextStream &t, const QCString &path, const QCString &fileName)
Definition: dotgfxhierarchytable.cpp:75
DotGraph::writeGraphFooter
static void writeGraphFooter(TextStream &t)
Definition: dotgraph.cpp:300
QCString::str
std::string str() const
Definition: qcstring.h:442
Definition::isHidden
virtual bool isHidden() const =0
DotGraph::getNextNodeNumber
int getNextNodeNumber()
returns node numbers.
Definition: dotgraph.h:41
Translator::trGraphicalHierarchy
virtual QCString trGraphicalHierarchy()=0
ClassDef::isVisibleInHierarchy
virtual bool isVisibleInHierarchy() const =0
the class is visible in a class diagram, or class hierarchy
TextStream
Text streaming class that buffers data.
Definition: textstream.h:33
DotGraph::writeGraphHeader
static void writeGraphHeader(TextStream &t, const QCString &title=QCString())
Definition: dotgraph.cpp:268
DotGfxHierarchyTable::addHierarchy
void addHierarchy(DotNode *n, const ClassDef *cd, ClassDefSet &visited)
Definition: dotgfxhierarchytable.cpp:105
DotGfxHierarchyTable::DotGfxHierarchyTable
DotGfxHierarchyTable(const QCString &prefix="", ClassDef::CompoundType ct=ClassDef::Class)
Definition: dotgfxhierarchytable.cpp:226
DotNode
A node in a dot graph
Definition: dotnode.h:56
ClassDef
A abstract class representing of a compound symbol.
Definition: classdef.h:103
classlist.h
message.h
ClassDef::getOutputFileBase
virtual QCString getOutputFileBase() const =0
Returns the unique base name (without extension) of the class's file on disk
DotGfxHierarchyTable::computeTheGraph
virtual void computeTheGraph()
Definition: dotgfxhierarchytable.cpp:37
ClassDef::baseClasses
virtual const BaseClassList & baseClasses() const =0
Returns the list of base classes from which this class directly inherits.
DotGfxHierarchyTable::getMapLabel
virtual QCString getMapLabel() const
Definition: dotgfxhierarchytable.cpp:60
VhdlDocGen::ENTITYCLASS
@ ENTITYCLASS
Definition: vhdldocgen.h:74
theTranslator
Translator * theTranslator
Definition: language.cpp:156
Definition::name
virtual QCString name() const =0
DotNode::label
QCString label() const
Definition: dotnode.h:89
doxygen.h
language.h
DotNode::subgraphId
int subgraphId() const
Definition: dotnode.h:94
VhdlDocGen::VhdlClasses
VhdlClasses
Definition: vhdldocgen.h:72
TRUE
#define TRUE
Definition: qcstring.h:36
TextStream::str
std::string str() const
Return the contents of the buffer as a std::string object
Definition: textstream.h:208
Hierarchy
@ Hierarchy
Definition: dotgraph.h:29
ClassDef::subClasses
virtual const BaseClassList & subClasses() const =0
Returns the list of sub classes that directly derive from this class
DotGraph::writeGraph
QCString writeGraph(TextStream &t, GraphOutputFormat gf, EmbeddedOutputFormat ef, const QCString &path, const QCString &fileName, const QCString &relPath, bool writeImageMap=TRUE, int graphId=-1)
Definition: dotgraph.cpp:111
DotGraph::m_zoomable
bool m_zoomable
Definition: dotgraph.h:93
GOF_BITMAP
@ GOF_BITMAP
Definition: dotgraph.h:27
Config_getBool
#define Config_getBool(name)
Definition: config.h:33
ClassDef::getReference
virtual QCString getReference() const =0
If this class originated from a tagfile, this will return the tag file reference
DotGfxHierarchyTable::m_graphId
int m_graphId
Definition: dotgfxhierarchytable.h:50
escapeCharsInString
QCString escapeCharsInString(const QCString &name, bool allowDots, bool allowUnderscore)
Definition: util.cpp:3442
term
void term(const char *fmt,...)
Definition: message.cpp:220
qPrint
const char * qPrint(const char *s)
Definition: qcstring.h:589
ClassDef::displayName
virtual QCString displayName(bool includeScope=TRUE) const =0
Returns the name as it is appears in the documentation
Dir::exists
bool exists() const
Definition: dir.cpp:199
SrcLangExt_VHDL
@ SrcLangExt_VHDL
Definition: types.h:54
DotGfxHierarchyTable::m_prefix
QCString m_prefix
Definition: dotgfxhierarchytable.h:51
DotGraph::m_noDivTag
bool m_noDivTag
Definition: dotgraph.h:92
EOF_Html
@ EOF_Html
Definition: dotgraph.h:28
Definition::briefDescriptionAsTooltip
virtual QCString briefDescriptionAsTooltip() const =0
DotGfxHierarchyTable::getBaseName
virtual QCString getBaseName() const
Definition: dotgfxhierarchytable.cpp:27
dir.h
ClassLinkedMap
Definition: classlist.h:26
Doxygen::classLinkedMap
static ClassLinkedMap * classLinkedMap
Definition: doxygen.h:78
util.h
A bunch of utility functions.
ClassDef::isLinkable
virtual bool isLinkable() const =0
return TRUE iff a link to this class is possible (either within this project, or as a cross-reference...
QCString::sprintf
QCString & sprintf(const char *format,...)
Definition: qcstring.cpp:24
ClassDefSet
std::set< const ClassDef * > ClassDefSet
Definition: classdef.h:95
vhdldocgen.h
DotNode::children
const DotNodeRefVector & children() const
Definition: dotnode.h:109
FALSE
#define FALSE
Definition: qcstring.h:33
ClassDef::anchor
virtual QCString anchor() const =0
TextStream::write
void write(const char *buf, size_t len)
Adds a array of character to the stream
Definition: textstream.h:180
QCString
This is an alternative implementation of QCString.
Definition: qcstring.h:108