Doxygen
Loading...
Searching...
No Matches
dotgfxhierarchytable.cpp
Go to the documentation of this file.
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
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;
40 writeGraphHeader(md5stream,theTranslator->trGraphicalHierarchy());
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 {
54 }
55 }
56 writeGraphFooter(md5stream);
57 m_theGraph = md5stream.str();
58}
59
64
66 const QCString &path,const QCString &fileName,int id)
67{
69 m_graphId = id;
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::stable_sort(m_rootSubgraphs.begin(),m_rootSubgraphs.end(),
95 [](auto n1,auto n2) { return qstricmp_sort(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() && classHasVisibleRoot(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 = nullptr;
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(),EdgeInfo::protectionToColor(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>(this,
153 bClass->displayName(),
154 tooltip,
155 tmp_url
156 );
157 n->addChild(bn.get(),EdgeInfo::protectionToColor(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.emplace(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 (!classHasVisibleRoot(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>(this,
210 cd->displayName(),
211 tooltip,
212 tmp_url);
213 DotNode *root = n.get();
214
215 m_usedNodes.emplace(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
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
constexpr auto prefix
Definition anchor.cpp:44
A abstract class representing of a compound symbol.
Definition classdef.h:104
virtual bool isVisibleInHierarchy() const =0
the class is visible in a class diagram, or class hierarchy
virtual const BaseClassList & baseClasses() const =0
Returns the list of base classes from which this class directly inherits.
CompoundType
The various compound types.
Definition classdef.h:109
virtual const BaseClassList & subClasses() const =0
Returns the list of sub classes that directly derive from this class.
virtual bool isLinkable() const =0
virtual QCString anchor() const =0
virtual QCString briefDescriptionAsTooltip() const =0
virtual bool isHidden() const =0
virtual QCString getReference() const =0
virtual QCString displayName(bool includeScope=TRUE) const =0
virtual QCString getOutputFileBase() const =0
virtual const QCString & name() const =0
Class representing a directory in the file system.
Definition dir.h:75
bool exists() const
Definition dir.cpp:257
std::vector< DotNode * > m_rootSubgraphs
QCString getMapLabel() const override
void addClassList(const ClassLinkedMap &cl, ClassDefSet &visited)
DotGfxHierarchyTable(const QCString &prefix="", ClassDef::CompoundType ct=ClassDef::Class)
void addHierarchy(DotNode *n, const ClassDef *cd, ClassDefSet &visited)
void writeGraph(TextStream &t, const QCString &path, const QCString &fileName)
void createGraph(DotNode *rootNode, TextStream &t, const QCString &path, const QCString &fileName, int id)
ClassDef::CompoundType m_classType
QCString getBaseName() const override
std::vector< DotNode * > m_rootNodes
bool m_noDivTag
Definition dotgraph.h:98
static void writeGraphFooter(TextStream &t)
Definition dotgraph.cpp:301
static void writeGraphHeader(TextStream &t, const QCString &title=QCString())
Definition dotgraph.cpp:276
bool m_zoomable
Definition dotgraph.h:99
QCString m_theGraph
Definition dotgraph.h:95
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:115
friend class DotNode
Definition dotgraph.h:36
void addChild(DotNode *n, EdgeInfo::Colors edgeColor=EdgeInfo::Purple, EdgeInfo::Styles edgeStyle=EdgeInfo::Solid, const QCString &edgeLab=QCString(), const QCString &edgeURL=QCString(), int edgeLabCol=-1)
Definition dotnode.cpp:314
const DotNodeRefVector & children() const
Definition dotnode.h:122
static ClassLinkedMap * classLinkedMap
Definition doxygen.h:96
static ClassLinkedMap * hiddenClassLinkedMap
Definition doxygen.h:97
static constexpr Colors protectionToColor(Protection prot)
Definition dotnode.h:44
This is an alternative implementation of QCString.
Definition qcstring.h:101
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:150
const std::string & str() const
Definition qcstring.h:537
QCString & sprintf(const char *format,...)
Definition qcstring.cpp:29
Text streaming class that buffers data.
Definition textstream.h:36
std::string str() const
Return the contents of the buffer as a std::string object.
Definition textstream.h:229
static VhdlClasses convert(Protection prot)
Definition vhdldocgen.h:80
bool classHasVisibleRoot(const BaseClassList &bcl)
std::unordered_set< const ClassDef * > ClassDefSet
Definition classdef.h:95
#define Config_getBool(name)
Definition config.h:33
@ Hierarchy
Definition dotgraph.h:31
Translator * theTranslator
Definition language.cpp:71
#define term(fmt,...)
Definition message.h:94
const char * qPrint(const char *s)
Definition qcstring.h:672
#define TRUE
Definition qcstring.h:37
#define FALSE
Definition qcstring.h:34
QCString escapeCharsInString(const QCString &name, bool allowDots, bool allowUnderscore)
Definition util.cpp:3684
A bunch of utility functions.