Doxygen
Loading...
Searching...
No Matches
DotNode Class Reference

A node in a dot graph. More...

#include <src/dotnode.h>

Collaboration diagram for DotNode:

Public Types

enum class  LabelStyle { Plain , List , Table }
enum  TruncState { Unknown , Truncated , Untruncated }

Public Member Functions

 DotNode (DotGraph *graph, const QCString &lab, const QCString &tip, const QCString &url, bool rootNode=FALSE, const ClassDef *cd=nullptr)
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)
void addParent (DotNode *n)
void deleteNode (DotNodeRefVector &deletedList)
void removeChild (DotNode *n)
void removeParent (DotNode *n)
int findParent (DotNode *n)
void write (TextStream &t, GraphType gt, GraphOutputFormat f, bool topDown, bool toChildren, bool backArrows)
void writeXML (TextStream &t, bool isClassGraph) const
void writeDocbook (TextStream &t, bool isClassGraph) const
void writeDEF (TextStream &t) const
void writeLabel (TextStream &t, GraphType gt) const
void writeUrl (TextStream &t) const
void writeBox (TextStream &t, GraphType gt, GraphOutputFormat f, bool hasNonReachableChildren) const
void writeArrow (TextStream &t, GraphType gt, GraphOutputFormat f, const DotNode *cn, const EdgeInfo *ei, bool topDown, bool pointBack=TRUE) const
QCString label () const
int number () const
bool isVisible () const
TruncState isTruncated () const
int distance () const
int subgraphId () const
bool isRenumbered () const
bool hasDocumentation () const
bool isWritten () const
void clearWriteFlag ()
void renumberNodes (int &number)
void markRenumbered ()
DotNodemarkHasDocumentation ()
void setSubgraphId (int id)
void colorConnectedNodes (int curColor)
void setDistance (int distance)
void markAsVisible (bool b=TRUE)
DotNodemarkAsTruncated (bool b=TRUE)
const DotNodeRefVectorchildren () const
const DotNodeRefVectorparents () const
const EdgeInfoVectoredgeInfo () const
DotNodesetNodeId (int number)

Static Public Member Functions

static void deleteNodes (DotNode *node)
static QCString convertLabel (const QCString &, LabelStyle=LabelStyle::Plain)

Static Public Attributes

static constexpr auto placeholderUrl = "-"

Private Attributes

DotGraphm_graph
int m_number
QCString m_label
 label text
QCString m_tooltip
 node's tooltip
QCString m_url
 url of the node (format: remote$local)
DotNodeRefVector m_parents
 list of parent nodes (incoming arrows)
DotNodeRefVector m_children
 list of child nodes (outgoing arrows)
EdgeInfoVector m_edgeInfo
 edge info for each child
bool m_deleted = false
 used to mark a node as deleted
bool m_written = false
 used to mark a node as written
bool m_hasDoc = false
 used to mark a node as documented
bool m_isRoot
 indicates if this is a root node
const ClassDefm_classDef
 class representing this node (can be 0)
bool m_visible = false
 is the node visible in the output
TruncState m_truncated = Unknown
 does the node have non-visible children/parents
int m_distance = 1000
 shortest path to the root node
bool m_renumbered = false
 indicates if the node has been renumbered (to prevent endless loops)
int m_subgraphId = -1

Detailed Description

A node in a dot graph.

Definition at line 67 of file dotnode.h.

Member Enumeration Documentation

◆ LabelStyle

enum class DotNode::LabelStyle
strong
Enumerator
Plain 
List 
Table 

Definition at line 70 of file dotnode.h.

70{ Plain, List, Table };

◆ TruncState

Enumerator
Unknown 
Truncated 
Untruncated 

Definition at line 77 of file dotnode.h.

@ Truncated
Definition dotnode.h:77
@ Untruncated
Definition dotnode.h:77
@ Unknown
Definition dotnode.h:77

Constructor & Destructor Documentation

◆ DotNode()

DotNode::DotNode ( DotGraph * graph,
const QCString & lab,
const QCString & tip,
const QCString & url,
bool rootNode = FALSE,
const ClassDef * cd = nullptr )

Definition at line 326 of file dotnode.cpp.

328 : m_graph(graph)
329 , m_number(graph->getNextNodeNumber())
330 , m_label(lab)
331 , m_tooltip(tip)
332 , m_url(url)
333 , m_isRoot(isRoot)
334 , m_classDef(cd)
335{
336}
int getNextNodeNumber()
returns the node number.
Definition dotgraph.h:45
int m_number
Definition dotnode.h:130
QCString m_tooltip
node's tooltip
Definition dotnode.h:132
bool m_isRoot
indicates if this is a root node
Definition dotnode.h:140
QCString m_label
label text
Definition dotnode.h:131
const ClassDef * m_classDef
class representing this node (can be 0)
Definition dotnode.h:141
DotGraph * m_graph
Definition dotnode.h:129
QCString m_url
url of the node (format: remote$local)
Definition dotnode.h:133

References m_classDef, m_graph, m_isRoot, m_label, m_number, m_tooltip, and m_url.

Referenced by addChild(), addParent(), deleteNodes(), findParent(), markAsTruncated(), markHasDocumentation(), removeChild(), removeParent(), setNodeId(), and writeArrow().

Member Function Documentation

◆ addChild()

void DotNode::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 at line 338 of file dotnode.cpp.

345{
346 m_children.push_back(n);
347 m_edgeInfo.emplace_back(
348 edgeColor,
349 edgeStyle,
350 edgeLab,
351 edgeURL,
352 edgeLabCol==-1 ? edgeColor : edgeLabCol);
353}
EdgeInfoVector m_edgeInfo
edge info for each child
Definition dotnode.h:136
DotNodeRefVector m_children
list of child nodes (outgoing arrows)
Definition dotnode.h:135

References DotNode(), m_children, and m_edgeInfo.

Referenced by DotClassGraph::addClass(), DotGfxHierarchyTable::addHierarchy(), DotCallGraph::buildGraph(), and DotInclDepGraph::buildGraph().

◆ addParent()

void DotNode::addParent ( DotNode * n)

Definition at line 355 of file dotnode.cpp.

356{
357 m_parents.push_back(n);
358}
DotNodeRefVector m_parents
list of parent nodes (incoming arrows)
Definition dotnode.h:134

References DotNode(), and m_parents.

Referenced by DotClassGraph::addClass(), DotCallGraph::buildGraph(), and DotInclDepGraph::buildGraph().

◆ children()

◆ clearWriteFlag()

void DotNode::clearWriteFlag ( )

Definition at line 887 of file dotnode.cpp.

888{
890 for (const auto &pn : m_parents) if (pn->isWritten()) pn->clearWriteFlag();
891 for (const auto &cn : m_children) if (cn->isWritten()) cn->clearWriteFlag();
892}
bool m_written
used to mark a node as written
Definition dotnode.h:138
#define FALSE
Definition qcstring.h:34

References FALSE, m_children, m_parents, and m_written.

Referenced by DotGraph::computeGraph().

◆ colorConnectedNodes()

void DotNode::colorConnectedNodes ( int curColor)

Definition at line 894 of file dotnode.cpp.

895{
896 for (const auto &cn : m_children)
897 {
898 if (cn->subgraphId()==-1) // uncolored child node
899 {
900 cn->setSubgraphId(curColor);
901 cn->markAsVisible();
902 cn->colorConnectedNodes(curColor);
903 //printf("coloring node %s (%p): %d\n",qPrint(cn->label()),cn,cn->subgraphId());
904 }
905 }
906
907 for (const auto &pn : m_parents)
908 {
909 if (pn->subgraphId()==-1) // uncolored parent node
910 {
911 pn->setSubgraphId(curColor);
912 pn->markAsVisible();
913 pn->colorConnectedNodes(curColor);
914 //printf("coloring node %s (%p): %d\n",qPrint(pn->label()),pn,pn->subgraphId());
915 }
916 }
917}

References m_children, and m_parents.

◆ convertLabel()

QCString DotNode::convertLabel ( const QCString & l,
LabelStyle style = LabelStyle::Plain )
static

Definition at line 196 of file dotnode.cpp.

197{
198 QCString bBefore("\\_/<({[: =-+@%#~?$"); // break before character set
199 QCString bAfter(">]),:;|"); // break after character set
200 if (l.isEmpty()) return QCString();
201 QCString result;
202 char pc=0;
203 uint32_t idx = 0;
204 int charsLeft=static_cast<int>(l.length());
205 int sinceLast=0;
206 int foldLen = Config_getInt(DOT_WRAP_THRESHOLD); // ideal text length
207 QCString br;
208 QCString br1;
209 if (style==LabelStyle::Table)
210 {
211 result += "<<TABLE CELLBORDER=\"0\" BORDER=\"0\"><TR><TD VALIGN=\"top\" ALIGN=\"LEFT\" CELLPADDING=\"1\" CELLSPACING=\"0\">";
212 }
213 if (style==LabelStyle::List)
214 {
215 br = "<BR ALIGN=\"LEFT\"/>";
216 }
217 else if (style==LabelStyle::Table)
218 {
219 br1 = "</TD></TR>\n<TR><TD VALIGN=\"top\" ALIGN=\"LEFT\" CELLPADDING=\"1\" CELLSPACING=\"0\">";
220 br = br1 + "&nbsp;&nbsp;";
221 }
222 else // style==LabelStyle::Plain
223 {
224 br = "\\l";
225 }
226 while (idx < l.length())
227 {
228 char c = l[idx++];
229 char cs[2] = { c, 0 };
230 const char *replacement = cs;
231 if (style!=LabelStyle::Plain)
232 {
233 switch(c)
234 {
235 case '\\': replacement="\\\\"; break;
236 case '\n': replacement="\\n"; break;
237 case '<': replacement="&lt;"; break;
238 case '>': replacement="&gt;"; break;
239 case '"': replacement="&quot;"; break;
240 case '\'': replacement="&apos;"; break;
241 case '&': replacement="&amp;"; break;
242 }
243 }
244 else // style==LabelStyle::Plain
245 {
246 switch(c)
247 {
248 case '\\': replacement="\\\\"; break;
249 case '\n': replacement="\\n"; break;
250 case '<': replacement="\\<"; break;
251 case '>': replacement="\\>"; break;
252 case '"': replacement="\\\""; break;
253 case '|': replacement="\\|"; break;
254 case '{': replacement="\\{"; break;
255 case '}': replacement="\\}"; break;
256 }
257 }
258 // Some heuristics to insert newlines to prevent too long
259 // boxes and at the same time prevent ugly breaks
260 if (c=='\n')
261 {
262 if (style==LabelStyle::Table)
263 {
264 result+=br1;
265 }
266 else
267 {
268 result+=replacement;
269 }
270 foldLen = (3*foldLen+sinceLast+2)/4;
271 sinceLast=1;
272 }
273 else if ((pc!=':' || c!=':') && charsLeft>foldLen/3 && sinceLast>foldLen && bBefore.contains(c))
274 {
275 result+=br;
276 result+=replacement;
277 foldLen = (foldLen+sinceLast+1)/2;
278 sinceLast=1;
279 }
280 else if (charsLeft>1+foldLen/4 && sinceLast>foldLen+foldLen/3 &&
281 !isupper(c) && isupper(l[idx]))
282 {
283 result+=replacement;
284 result+=br;
285 foldLen = (foldLen+sinceLast+1)/2;
286 sinceLast=0;
287 }
288 else if (charsLeft>foldLen/3 && sinceLast>foldLen && bAfter.contains(c) && (c!=':' || l[idx]!=':'))
289 {
290 result+=replacement;
291 result+=br;
292 foldLen = (foldLen+sinceLast+1)/2;
293 sinceLast=0;
294 }
295 else
296 {
297 result+=replacement;
298 sinceLast++;
299 }
300 charsLeft--;
301 pc=c;
302 }
303 if (style==LabelStyle::List)
304 {
305 result = result.stripWhiteSpace();
306 }
307 if (style==LabelStyle::Table)
308 {
309 result += "</TD></TR>\n</TABLE>>";
310 }
311 return result;
312}
size_t length() const
Returns the length of the string, not counting the 0-terminator.
Definition qcstring.h:166
bool isEmpty() const
Returns TRUE iff the string is empty.
Definition qcstring.h:163
QCString stripWhiteSpace() const
returns a copy of this string with leading and trailing whitespace removed
Definition qcstring.h:260
#define Config_getInt(name)
Definition config.h:34

References Config_getInt, QCString::contains(), QCString::isEmpty(), QCString::length(), List, Plain, QCString::stripWhiteSpace(), and Table.

Referenced by drawClusterOpening(), drawDirectory(), DotGroupCollaboration::Edge::write(), writeArrow(), writeBoxMemberList(), and writeLabel().

◆ deleteNode()

void DotNode::deleteNode ( DotNodeRefVector & deletedList)

Definition at line 372 of file dotnode.cpp.

373{
374 if (m_deleted) return; // avoid recursive loops in case the graph has cycles
376 // delete all parent nodes of this node
377 for (const auto &pn : m_parents)
378 {
379 pn->deleteNode(deletedList);
380 }
381 // delete all child nodes of this node
382 for (const auto &cn : m_children)
383 {
384 cn->deleteNode(deletedList);
385 }
386 // add this node to the list of deleted nodes.
387 deletedList.push_back(this);
388}
bool m_deleted
used to mark a node as deleted
Definition dotnode.h:137
#define TRUE
Definition qcstring.h:37

References m_children, m_deleted, m_parents, and TRUE.

Referenced by deleteNodes().

◆ deleteNodes()

void DotNode::deleteNodes ( DotNode * node)
static

helper function that deletes all nodes in a connected graph, given one of the graph's nodes

Definition at line 404 of file dotnode.cpp.

405{
406 DotNodeRefVector deletedNodes;
407 node->deleteNode(deletedNodes); // collect nodes to be deleted.
408 for (const auto &dotNode : deletedNodes)
409 {
410 delete dotNode;
411 }
412}
void deleteNode(DotNodeRefVector &deletedList)
Definition dotnode.cpp:372
std::vector< DotNode * > DotNodeRefVector
Definition dotnode.h:63

References deleteNode(), and DotNode().

Referenced by DotCallGraph::~DotCallGraph(), DotClassGraph::~DotClassGraph(), and DotInclDepGraph::~DotInclDepGraph().

◆ distance()

int DotNode::distance ( ) const
inline

Definition at line 107 of file dotnode.h.

107{ return m_distance; }
int m_distance
shortest path to the root node
Definition dotnode.h:144

References m_distance.

Referenced by DotCallGraph::determineVisibleNodes(), DotClassGraph::determineVisibleNodes(), DotInclDepGraph::determineVisibleNodes(), and setDistance().

◆ edgeInfo()

const EdgeInfoVector & DotNode::edgeInfo ( ) const
inline

Definition at line 125 of file dotnode.h.

125{ return m_edgeInfo; }

References m_edgeInfo.

Referenced by writeDEF(), writeDocbook(), and writeXML().

◆ findParent()

int DotNode::findParent ( DotNode * n)
inline

Definition at line 395 of file dotnode.cpp.

396{
397 auto it = std::find(m_parents.begin(),m_parents.end(),n);
398 return it!=m_parents.end() ? static_cast<int>(it-m_parents.begin()) : -1;
399}

References DotNode(), and m_parents.

◆ hasDocumentation()

bool DotNode::hasDocumentation ( ) const
inline

Definition at line 110 of file dotnode.h.

110{ return m_hasDoc; }
bool m_hasDoc
used to mark a node as documented
Definition dotnode.h:139

References m_hasDoc.

◆ isRenumbered()

bool DotNode::isRenumbered ( ) const
inline

Definition at line 109 of file dotnode.h.

109{ return m_renumbered; }
bool m_renumbered
indicates if the node has been renumbered (to prevent endless loops)
Definition dotnode.h:145

References m_renumbered.

Referenced by renumberNodes().

◆ isTruncated()

TruncState DotNode::isTruncated ( ) const
inline

Definition at line 106 of file dotnode.h.

106{ return m_truncated; }
TruncState m_truncated
does the node have non-visible children/parents
Definition dotnode.h:143

References m_truncated.

Referenced by DotCallGraph::determineTruncatedNodes(), DotClassGraph::determineTruncatedNodes(), and DotInclDepGraph::determineTruncatedNodes().

◆ isVisible()

◆ isWritten()

bool DotNode::isWritten ( ) const
inline

Definition at line 111 of file dotnode.h.

111{ return m_written; }

References m_written.

◆ label()

QCString DotNode::label ( ) const
inline

Definition at line 103 of file dotnode.h.

103{ return m_label; }

References m_label.

Referenced by DotClassGraph::determineVisibleNodes().

◆ markAsTruncated()

DotNode & DotNode::markAsTruncated ( bool b = TRUE)
inline

◆ markAsVisible()

◆ markHasDocumentation()

DotNode & DotNode::markHasDocumentation ( )
inline

Definition at line 116 of file dotnode.h.

116{ m_hasDoc = true; return *this;}

References DotNode(), and m_hasDoc.

◆ markRenumbered()

void DotNode::markRenumbered ( )
inline

Definition at line 115 of file dotnode.h.

115{ m_renumbered = true; }

References m_renumbered.

Referenced by renumberNodes().

◆ number()

int DotNode::number ( ) const
inline

Definition at line 104 of file dotnode.h.

104{ return m_number; }

References m_number.

Referenced by renumberNodes(), setNodeId(), and writeArrow().

◆ parents()

const DotNodeRefVector & DotNode::parents ( ) const
inline

◆ removeChild()

void DotNode::removeChild ( DotNode * n)

Definition at line 360 of file dotnode.cpp.

361{
362 auto it = std::find(m_children.begin(),m_children.end(),n);
363 if (it!=m_children.end()) m_children.erase(it);
364}

References DotNode(), and m_children.

◆ removeParent()

void DotNode::removeParent ( DotNode * n)

Definition at line 366 of file dotnode.cpp.

367{
368 auto it = std::find(m_parents.begin(),m_parents.end(),n);
369 if (it!=m_parents.end()) m_parents.erase(it);
370}

References DotNode(), and m_parents.

◆ renumberNodes()

void DotNode::renumberNodes ( int & number)

Definition at line 921 of file dotnode.cpp.

922{
923 if (!isRenumbered())
924 {
925#if DEBUG_RENUMBERING
926 static int level = 0;
927 printf("%3d: ",subgraphId());
928 for (int i = 0; i < level; i++) printf(" ");
929 printf("> %s old = %d new = %d\n",qPrint(m_label),m_number,number);
930 level++;
931#endif
932 m_number = number++;
934 for (const auto &cn : m_children)
935 {
936 cn->renumberNodes(number);
937 }
938 for (const auto &pn : m_parents)
939 {
940 pn->renumberNodes(number);
941 }
942#if DEBUG_RENUMBERING
943 level--;
944 printf("%3d: ",subgraphId());
945 for (int i = 0; i < level; i++) printf(" ");
946 printf("< %s assigned = %d\n",qPrint(m_label),m_number);
947#endif
948 }
949}
void markRenumbered()
Definition dotnode.h:115
int number() const
Definition dotnode.h:104
bool isRenumbered() const
Definition dotnode.h:109
int subgraphId() const
Definition dotnode.h:108
const char * qPrint(const char *s)
Definition qcstring.h:687

References isRenumbered(), m_children, m_label, m_number, m_parents, markRenumbered(), number(), qPrint(), and subgraphId().

◆ setDistance()

void DotNode::setDistance ( int distance)

Definition at line 390 of file dotnode.cpp.

391{
393}
int distance() const
Definition dotnode.h:107

References distance(), and m_distance.

Referenced by DotClassGraph::addClass(), DotCallGraph::buildGraph(), and DotInclDepGraph::buildGraph().

◆ setNodeId()

DotNode & DotNode::setNodeId ( int number)
inline

Definition at line 126 of file dotnode.h.

126{ m_number=number; return *this; }

References DotNode(), m_number, and number().

◆ setSubgraphId()

void DotNode::setSubgraphId ( int id)
inline

Definition at line 117 of file dotnode.h.

117{ m_subgraphId = id; }
int m_subgraphId
Definition dotnode.h:146

References m_subgraphId.

◆ subgraphId()

int DotNode::subgraphId ( ) const
inline

Definition at line 108 of file dotnode.h.

108{ return m_subgraphId; }

References m_subgraphId.

Referenced by renumberNodes().

◆ write()

void DotNode::write ( TextStream & t,
GraphType gt,
GraphOutputFormat f,
bool topDown,
bool toChildren,
bool backArrows )

Definition at line 654 of file dotnode.cpp.

660{
661 //printf("DotNode::write(%d) name=%s this=%p written=%d visible=%d\n",m_distance,qPrint(m_label),this,m_written,m_visible);
662 if (m_written) return; // node already written to the output
663 if (!m_visible) return; // node is not visible
664 writeBox(t,gt,format,m_truncated==Truncated);
666 if (toChildren)
667 {
668 auto it = m_edgeInfo.begin();
669 for (const auto &cn : m_children)
670 {
671 if (cn->isVisible())
672 {
673 //printf("write arrow %s%s%s\n",qPrint(label()),backArrows?"<-":"->",qPrint(cn->label()));
674 writeArrow(t,gt,format,cn,&(*it),topDown,backArrows);
675 }
676 cn->write(t,gt,format,topDown,toChildren,backArrows);
677 ++it;
678 }
679 }
680 else // render parents
681 {
682 for (const auto &pn : m_parents)
683 {
684 if (pn->isVisible())
685 {
686 const auto &children = pn->children();
687 auto child_it = std::find(children.begin(),children.end(),this);
688 size_t index = child_it - children.begin();
689 //printf("write arrow %s%s%s\n",qPrint(label()),backArrows?"<-":"->",qPrint(pn->label()));
690 writeArrow(t,
691 gt,
692 format,
693 pn,
694 &pn->edgeInfo()[index],
695 FALSE,
696 backArrows
697 );
698 }
699 pn->write(t,gt,format,TRUE,FALSE,backArrows);
700 }
701 }
702 //printf("end DotNode::write(%d) name=%s\n",distance,qPrint(m_label));
703}
void writeBox(TextStream &t, GraphType gt, GraphOutputFormat f, bool hasNonReachableChildren) const
Definition dotnode.cpp:539
const DotNodeRefVector & children() const
Definition dotnode.h:123
void writeArrow(TextStream &t, GraphType gt, GraphOutputFormat f, const DotNode *cn, const EdgeInfo *ei, bool topDown, bool pointBack=TRUE) const
Definition dotnode.cpp:603

References children(), FALSE, m_children, m_edgeInfo, m_parents, m_truncated, m_visible, m_written, TRUE, Truncated, writeArrow(), and writeBox().

Referenced by DotGraph::computeGraph().

◆ writeArrow()

void DotNode::writeArrow ( TextStream & t,
GraphType gt,
GraphOutputFormat f,
const DotNode * cn,
const EdgeInfo * ei,
bool topDown,
bool pointBack = TRUE ) const

Definition at line 603 of file dotnode.cpp.

610{
611 t << " Node";
612 if (topDown)
613 t << cn->number();
614 else
615 t << m_number;
616 t << " -> Node";
617 if (topDown)
618 t << m_number;
619 else
620 t << cn->number();
621 t << " [";
622
623 const EdgeProperties *eProps = Config_getBool(UML_LOOK) ? &umlEdgeProps : &normalEdgeProps;
624 QCString aStyle = eProps->arrowStyleMap[ei->color()];
625 bool umlUseArrow = aStyle=="odiamond";
626
627 t << "id=\"edge" << m_graph->getNextEdgeNumber() <<
628 "_Node" << QCString().sprintf("%06d",m_number) <<
629 "_Node" << QCString().sprintf("%06d",cn->number()) << "\",";
630 if (pointBack && !umlUseArrow) t << "dir=\"back\",";
631 t << "color=\"" << eProps->edgeColorMap[ei->color()] << "\",";
632 t << "style=\"" << eProps->edgeStyleMap[ei->style()] << "\"";
633 t << ",tooltip=\" \""; // space in tooltip is required otherwise still something like 'Node0 -> Node1' is used
634 if (!ei->label().isEmpty())
635 {
636 t << ",label=" << convertLabel(ei->label(),LabelStyle::Table) << " ,fontcolor=\"grey\" ";
637 }
638 if (Config_getBool(UML_LOOK) &&
639 eProps->arrowStyleMap[ei->color()] &&
641 )
642 {
643 bool rev = pointBack;
644 if (umlUseArrow) rev=!rev; // UML use relates has arrow on the start side
645 if (rev)
646 t << ",arrowtail=\"" << eProps->arrowStyleMap[ei->color()] << "\"";
647 else
648 t << ",arrowhead=\"" << eProps->arrowStyleMap[ei->color()] << "\"";
649 }
650
651 t << "];\n";
652}
static QCString convertLabel(const QCString &, LabelStyle=LabelStyle::Plain)
Definition dotnode.cpp:196
int style() const
Definition dotnode.h:40
int color() const
Definition dotnode.h:39
QCString label() const
Definition dotnode.h:41
#define Config_getBool(name)
Definition config.h:33
@ Collaboration
Definition dotgraph.h:31
@ Inheritance
Definition dotgraph.h:31
static EdgeProperties normalEdgeProps
Definition dotnode.cpp:89
static EdgeProperties umlEdgeProps
Definition dotnode.cpp:94
const char *const * arrowStyleMap
Definition dotnode.cpp:30
const char *const * edgeStyleMap
Definition dotnode.cpp:31
const char *const * edgeColorMap
Definition dotnode.cpp:29

References EdgeProperties::arrowStyleMap, Collaboration, EdgeInfo::color(), Config_getBool, convertLabel(), DotNode(), EdgeProperties::edgeColorMap, EdgeProperties::edgeStyleMap, Inheritance, QCString::isEmpty(), EdgeInfo::label(), m_graph, m_number, normalEdgeProps, number(), QCString::sprintf(), EdgeInfo::style(), Table, and umlEdgeProps.

Referenced by DotGraph::computeGraph(), and write().

◆ writeBox()

void DotNode::writeBox ( TextStream & t,
GraphType gt,
GraphOutputFormat f,
bool hasNonReachableChildren ) const

Definition at line 539 of file dotnode.cpp.

543{
544 const char *labCol = nullptr;
545 const char *fillCol = "white";
546 if (m_classDef)
547 {
548 if (m_classDef->hasDocumentation() && hasNonReachableChildren)
549 {
550 labCol = "red";
551 fillCol = "#FFF0F0";
552 }
553 else if (m_classDef->hasDocumentation() && !hasNonReachableChildren)
554 {
555 labCol = "gray40";
556 }
557 else if (!m_classDef->hasDocumentation() && hasNonReachableChildren)
558 {
559 labCol = "orangered";
560 }
561 else // (!m_classDef->hasDocumentation() && !hasNonReachableChildren)
562 {
563 labCol = "grey75";
564 if (m_classDef->templateMaster() && m_classDef->isImplicitTemplateInstance() && m_classDef->templateMaster()->hasDocumentation())
565 {
566 labCol = "gray40";
567 }
568 }
569 }
570 else
571 {
572 labCol = m_url.isEmpty() ? "grey60" : // non link
573 (hasNonReachableChildren ? "red" : "grey40");
574 fillCol = m_url.isEmpty() ? "#E0E0E0" :
575 (hasNonReachableChildren ? "#FFF0F0" : "white");
576 }
577 t << " Node" << m_number << " [";
578 t << "id=\"Node" << QCString().sprintf("%06d",m_number) << "\",";
579 writeLabel(t,gt);
580 t << ",height=0.2,width=0.4";
581 if (m_isRoot)
582 {
583 t << ",color=\"gray40\", fillcolor=\"grey60\", style=\"filled\", fontcolor=\"black\"";
584 }
585 else
586 {
587 t << ",color=\"" << labCol << "\"";
588 t << ", fillcolor=\"" << fillCol << "\"";
589 t << ", style=\"filled\"";
590 writeUrl(t);
591 }
592 if (!m_tooltip.isEmpty())
593 {
594 t << ",tooltip=\"" << escapeTooltip(m_tooltip) << "\"";
595 }
596 else
597 {
598 t << ",tooltip=\" \""; // space in tooltip is required otherwise still something like 'Node0' is used
599 }
600 t << "];\n";
601}
void writeUrl(TextStream &t) const
Definition dotnode.cpp:514
void writeLabel(TextStream &t, GraphType gt) const
Definition dotnode.cpp:414
QCString escapeTooltip(const QCString &tooltip)
Definition dotnode.cpp:99

References escapeTooltip(), m_classDef, m_isRoot, m_number, m_tooltip, m_url, QCString::sprintf(), writeLabel(), and writeUrl().

Referenced by write().

◆ writeDEF()

void DotNode::writeDEF ( TextStream & t) const

Definition at line 830 of file dotnode.cpp.

831{
832 const char* nodePrefix = " node-";
833
834 t << " node = {\n";
835 t << nodePrefix << "id = " << m_number << ";\n";
836 t << nodePrefix << "label = '" << m_label << "';\n";
837
838 if (!m_url.isEmpty())
839 {
840 QCString url(m_url);
841 int dollarPos = url.find('$');
842 if (dollarPos!=-1)
843 {
844 t << nodePrefix << "link = {\n" << " "
845 << nodePrefix << "link-id = '" << url.mid(dollarPos+1) << "';\n";
846 if (dollarPos>0)
847 {
848 t << " " << nodePrefix << "link-external = '"
849 << url.left(dollarPos) << "';\n";
850 }
851 t << " };\n";
852 }
853 }
854 auto it = m_edgeInfo.begin();
855 for (const auto &childNode : m_children)
856 {
857 const EdgeInfo &edgeInfo = *it;
858 t << " node-child = {\n";
859 t << " child-id = '" << childNode->number() << "';\n";
860 t << " relation = ";
861
862 switch (edgeInfo.color())
863 {
864 case EdgeInfo::Blue: t << "public-inheritance"; break;
865 case EdgeInfo::Green: t << "protected-inheritance"; break;
866 case EdgeInfo::Red: t << "private-inheritance"; break;
867 case EdgeInfo::Purple: t << "usage"; break;
868 case EdgeInfo::Orange: t << "template-instance"; break;
869 case EdgeInfo::Orange2: t << "type-constraint"; break;
870 case EdgeInfo::Grey: ASSERT(0); break;
871 }
872 t << ";\n";
873
874 if (!edgeInfo.label().isEmpty())
875 {
876 t << " edgelabel = <<_EnD_oF_dEf_TeXt_\n"
877 << edgeInfo.label() << "\n"
878 << "_EnD_oF_dEf_TeXt_;\n";
879 }
880 t << " }; /* node-child */\n";
881 ++it;
882 }
883 t << " }; /* node */\n";
884}
const EdgeInfoVector & edgeInfo() const
Definition dotnode.h:125
@ Green
Definition dotnode.h:35
@ Purple
Definition dotnode.h:35
@ Orange2
Definition dotnode.h:35
@ Orange
Definition dotnode.h:35
#define ASSERT(x)
Definition qcstring.h:39

References ASSERT, EdgeInfo::Blue, edgeInfo(), QCString::find(), EdgeInfo::Green, EdgeInfo::Grey, QCString::left(), m_children, m_edgeInfo, m_label, m_number, m_url, QCString::mid(), EdgeInfo::Orange, EdgeInfo::Orange2, EdgeInfo::Purple, and EdgeInfo::Red.

◆ writeDocbook()

void DotNode::writeDocbook ( TextStream & t,
bool isClassGraph ) const

Definition at line 767 of file dotnode.cpp.

768{
769 t << " <node id=\"" << m_number << "\">\n";
770 t << " <label>" << convertToXML(m_label) << "</label>\n";
771 if (!m_url.isEmpty())
772 {
773 QCString url(m_url);
774 int dollarPos = url.find('$');
775 if (dollarPos!=-1)
776 {
777 t << " <link refid=\"" << convertToXML(url.mid(dollarPos+1)) << "\"";
778 if (dollarPos>0)
779 {
780 t << " external=\"" << convertToXML(url.left(dollarPos)) << "\"";
781 }
782 t << "/>\n";
783 }
784 }
785 auto it = m_edgeInfo.begin();
786 for (const auto &childNode : m_children)
787 {
788 const EdgeInfo &edgeInfo = *it;
789 t << " <childnode refid=\"" << childNode->number() << "\" relation=\"";
790 if (isClassGraph)
791 {
792 switch(edgeInfo.color())
793 {
794 case EdgeInfo::Blue: t << "public-inheritance"; break;
795 case EdgeInfo::Green: t << "protected-inheritance"; break;
796 case EdgeInfo::Red: t << "private-inheritance"; break;
797 case EdgeInfo::Purple: t << "usage"; break;
798 case EdgeInfo::Orange: t << "template-instance"; break;
799 case EdgeInfo::Orange2: t << "type-constraint"; break;
800 case EdgeInfo::Grey: ASSERT(0); break;
801 }
802 }
803 else // include graph
804 {
805 t << "include";
806 }
807 t << "\">\n";
808 if (!edgeInfo.label().isEmpty())
809 {
810 int p=0;
811 int ni=0;
812 while ((ni=edgeInfo.label().find('\n',p))!=-1)
813 {
814 t << " <edgelabel>"
815 << convertToXML(edgeInfo.label().mid(p,ni-p))
816 << "</edgelabel>\n";
817 p=ni+1;
818 }
819 t << " <edgelabel>"
820 << convertToXML(edgeInfo.label().right(edgeInfo.label().length()-p))
821 << "</edgelabel>\n";
822 }
823 t << " </childnode>\n";
824 ++it;
825 }
826 t << " </node>\n";
827}
QCString convertToXML(const QCString &s, bool keepEntities)
Definition util.cpp:3849

References ASSERT, EdgeInfo::Blue, convertToXML(), edgeInfo(), QCString::find(), EdgeInfo::Green, EdgeInfo::Grey, QCString::left(), m_children, m_edgeInfo, m_label, m_number, m_url, QCString::mid(), EdgeInfo::Orange, EdgeInfo::Orange2, EdgeInfo::Purple, and EdgeInfo::Red.

◆ writeLabel()

void DotNode::writeLabel ( TextStream & t,
GraphType gt ) const

Definition at line 414 of file dotnode.cpp.

415{
417 {
418 // Set shape to the plain type.
419 // the UML properties and methods are rendered using dot' HTML like table format
420 t << "shape=plain,label=";
421 // add names shown as relations to a set, so we don't show
422 // them as attributes as well
423 StringUnorderedSet arrowNames;
424 // for each edge
425 for (const auto &ei : m_edgeInfo)
426 {
427 if (!ei.label().isEmpty()) // labels joined by \n
428 {
429 int i=0;
430 int p=0;
431 QCString lab;
432 while ((i=ei.label().find('\n',p))!=-1)
433 {
434 lab = stripProtectionPrefix(ei.label().mid(p,i-p));
435 arrowNames.insert(lab.str());
436 p=i+1;
437 }
438 lab = stripProtectionPrefix(ei.label().right(ei.label().length()-p));
439 arrowNames.insert(lab.str());
440 }
441 }
442
443 constexpr auto hr_start = "<TR><TD COLSPAN=\"2\" CELLPADDING=\"1\" CELLSPACING=\"0\">";
444 constexpr auto hr_end = "</TD></TR>\n";
445 constexpr auto sep = "<HR/>\n";
446 constexpr auto empty_line = "<TR><TD COLSPAN=\"2\" CELLPADDING=\"1\" CELLSPACING=\"0\">&nbsp;</TD></TR>\n";
447 //printf("DotNode::writeBox for %s\n",qPrint(m_classDef->name()));
448 t << "<<TABLE CELLBORDER=\"0\" BORDER=\"1\">";
449 t << hr_start << convertLabel(m_label,LabelStyle::List) << hr_end;
450 auto dotUmlDetails = Config_getEnum(DOT_UML_DETAILS);
451 if (dotUmlDetails!=DOT_UML_DETAILS_t::NONE)
452 {
453 bool lineWritten = false;
454 t << sep;
455 writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType::PubAttribs()),m_classDef,lineWritten,FALSE,&arrowNames);
456 writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType::PubStaticAttribs()),m_classDef,lineWritten,TRUE,&arrowNames);
457 writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType::Properties()),m_classDef,lineWritten,FALSE,&arrowNames);
458 writeBoxMemberList(t,'~',m_classDef->getMemberList(MemberListType::PacAttribs()),m_classDef,lineWritten,FALSE,&arrowNames);
459 writeBoxMemberList(t,'~',m_classDef->getMemberList(MemberListType::PacStaticAttribs()),m_classDef,lineWritten,TRUE,&arrowNames);
460 writeBoxMemberList(t,'#',m_classDef->getMemberList(MemberListType::ProAttribs()),m_classDef,lineWritten,FALSE,&arrowNames);
461 writeBoxMemberList(t,'#',m_classDef->getMemberList(MemberListType::ProStaticAttribs()),m_classDef,lineWritten,TRUE,&arrowNames);
462 if (Config_getBool(EXTRACT_PRIVATE))
463 {
464 writeBoxMemberList(t,'-',m_classDef->getMemberList(MemberListType::PriAttribs()),m_classDef,lineWritten,FALSE,&arrowNames);
465 writeBoxMemberList(t,'-',m_classDef->getMemberList(MemberListType::PriStaticAttribs()),m_classDef,lineWritten,TRUE,&arrowNames);
466 }
467 if (!lineWritten) t << empty_line;
468 t << sep;
469 lineWritten = false;
470 writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType::PubMethods()),m_classDef,lineWritten);
471 writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType::PubStaticMethods()),m_classDef,lineWritten,TRUE);
472 writeBoxMemberList(t,'+',m_classDef->getMemberList(MemberListType::PubSlots()),m_classDef,lineWritten);
473 writeBoxMemberList(t,'~',m_classDef->getMemberList(MemberListType::PacMethods()),m_classDef,lineWritten);
474 writeBoxMemberList(t,'~',m_classDef->getMemberList(MemberListType::PacStaticMethods()),m_classDef,lineWritten,TRUE);
475 writeBoxMemberList(t,'#',m_classDef->getMemberList(MemberListType::ProMethods()),m_classDef,lineWritten);
476 writeBoxMemberList(t,'#',m_classDef->getMemberList(MemberListType::ProStaticMethods()),m_classDef,lineWritten,TRUE);
477 writeBoxMemberList(t,'#',m_classDef->getMemberList(MemberListType::ProSlots()),m_classDef,lineWritten);
478 if (Config_getBool(EXTRACT_PRIVATE))
479 {
480 writeBoxMemberList(t,'-',m_classDef->getMemberList(MemberListType::PriMethods()),m_classDef,lineWritten);
481 writeBoxMemberList(t,'-',m_classDef->getMemberList(MemberListType::PriStaticMethods()),m_classDef,lineWritten,TRUE);
482 writeBoxMemberList(t,'-',m_classDef->getMemberList(MemberListType::PriSlots()),m_classDef,lineWritten);
483 }
484 if (m_classDef->getLanguage()!=SrcLangExt::Fortran)
485 {
486 for (const auto &mg : m_classDef->getMemberGroups())
487 {
488 if (!mg->members().empty())
489 {
490 writeBoxMemberList(t,'*',&mg->members(),m_classDef,lineWritten,FALSE,&arrowNames);
491 }
492 }
493 }
494 if (!lineWritten) t << empty_line;
495 }
496 t << "</TABLE>>\n";
497 }
498 else if (Config_getString(DOT_NODE_ATTR).contains("shape=plain"))
499 {
500 t << "label=";
501 if (m_isRoot)
502 t << "<<b>" << convertToXML(m_label) << "</b>>";
503 else if (m_truncated == Truncated)
504 t << "<<i>" << convertToXML(m_label) << "</i>>";
505 else
506 t << '"' << convertLabel(m_label,LabelStyle::Plain) << '"';
507 }
508 else // standard look
509 {
510 t << "label=" << '"' << convertLabel(m_label,LabelStyle::Plain) << '"';
511 }
512}
const std::string & str() const
Definition qcstring.h:552
#define Config_getString(name)
Definition config.h:32
#define Config_getEnum(name)
Definition config.h:35
std::unordered_set< std::string > StringUnorderedSet
Definition containers.h:29
static QCString stripProtectionPrefix(const QCString &s)
Definition dotnode.cpp:314
static void writeBoxMemberList(TextStream &t, char prot, const MemberList *ml, const ClassDef *scope, bool &lineWritten, bool isStatic=FALSE, const StringUnorderedSet *skipNames=nullptr)
Definition dotnode.cpp:117

References Collaboration, Config_getBool, Config_getEnum, Config_getString, convertLabel(), convertToXML(), FALSE, Inheritance, List, m_classDef, m_edgeInfo, m_isRoot, m_label, m_truncated, Plain, QCString::str(), stripProtectionPrefix(), TRUE, Truncated, and writeBoxMemberList().

Referenced by writeBox().

◆ writeUrl()

void DotNode::writeUrl ( TextStream & t) const

Definition at line 514 of file dotnode.cpp.

515{
516 if (m_url.isEmpty() || m_url == DotNode::placeholderUrl) return;
517 int tagPos = m_url.findRev('$');
518 t << ",URL=\"";
519 QCString noTagURL = m_url;
520 if (tagPos!=-1)
521 {
522 t << m_url.left(tagPos);
523 noTagURL = m_url.mid(tagPos);
524 }
525 int anchorPos = noTagURL.findRev('#');
526 if (anchorPos==-1)
527 {
529 t << noTagURL << "\"";
530 }
531 else // insert extensiom before anchor
532 {
533 QCString fn = noTagURL.left(anchorPos);
535 t << fn << noTagURL.right(noTagURL.length() - anchorPos) << "\"";
536 }
537}
static constexpr auto placeholderUrl
Definition dotnode.h:71
QCString right(size_t len) const
Definition qcstring.h:234
int findRev(char c, int index=-1, bool cs=TRUE) const
Definition qcstring.cpp:96
QCString left(size_t len) const
Definition qcstring.h:229
void addHtmlExtensionIfMissing(QCString &fName)
Definition util.cpp:4850

References addHtmlExtensionIfMissing(), QCString::findRev(), QCString::left(), QCString::length(), m_url, placeholderUrl, and QCString::right().

Referenced by writeBox().

◆ writeXML()

void DotNode::writeXML ( TextStream & t,
bool isClassGraph ) const

Definition at line 705 of file dotnode.cpp.

706{
707 t << " <node id=\"" << m_number << "\">\n";
708 t << " <label>" << convertToXML(m_label) << "</label>\n";
709 if (!m_url.isEmpty())
710 {
711 QCString url(m_url);
712 int dollarPos = url.find('$');
713 if (dollarPos!=-1)
714 {
715 t << " <link refid=\"" << convertToXML(url.mid(dollarPos+1)) << "\"";
716 if (dollarPos>0)
717 {
718 t << " external=\"" << convertToXML(url.left(dollarPos)) << "\"";
719 }
720 t << "/>\n";
721 }
722 }
723 auto it = m_edgeInfo.begin();
724 for (const auto &childNode : m_children)
725 {
726 const EdgeInfo &edgeInfo = *it;
727 t << " <childnode refid=\"" << childNode->number() << "\" relation=\"";
728 if (isClassGraph)
729 {
730 switch(edgeInfo.color())
731 {
732 case EdgeInfo::Blue: t << "public-inheritance"; break;
733 case EdgeInfo::Green: t << "protected-inheritance"; break;
734 case EdgeInfo::Red: t << "private-inheritance"; break;
735 case EdgeInfo::Purple: t << "usage"; break;
736 case EdgeInfo::Orange: t << "template-instance"; break;
737 case EdgeInfo::Orange2: t << "type-constraint"; break;
738 case EdgeInfo::Grey: ASSERT(0); break;
739 }
740 }
741 else // include graph
742 {
743 t << "include";
744 }
745 t << "\">\n";
746 if (!edgeInfo.label().isEmpty())
747 {
748 int p=0;
749 int ni=0;
750 while ((ni=edgeInfo.label().find('\n',p))!=-1)
751 {
752 t << " <edgelabel>"
753 << convertToXML(edgeInfo.label().mid(p,ni-p))
754 << "</edgelabel>\n";
755 p=ni+1;
756 }
757 t << " <edgelabel>"
758 << convertToXML(edgeInfo.label().right(edgeInfo.label().length()-p))
759 << "</edgelabel>\n";
760 }
761 t << " </childnode>\n";
762 ++it;
763 }
764 t << " </node>\n";
765}

References ASSERT, EdgeInfo::Blue, convertToXML(), edgeInfo(), QCString::find(), EdgeInfo::Green, EdgeInfo::Grey, QCString::left(), m_children, m_edgeInfo, m_label, m_number, m_url, QCString::mid(), EdgeInfo::Orange, EdgeInfo::Orange2, EdgeInfo::Purple, and EdgeInfo::Red.

Member Data Documentation

◆ m_children

DotNodeRefVector DotNode::m_children
private

list of child nodes (outgoing arrows)

Definition at line 135 of file dotnode.h.

Referenced by addChild(), children(), clearWriteFlag(), colorConnectedNodes(), deleteNode(), removeChild(), renumberNodes(), write(), writeDEF(), writeDocbook(), and writeXML().

◆ m_classDef

const ClassDef* DotNode::m_classDef
private

class representing this node (can be 0)

Definition at line 141 of file dotnode.h.

Referenced by DotNode(), writeBox(), and writeLabel().

◆ m_deleted

bool DotNode::m_deleted = false
private

used to mark a node as deleted

Definition at line 137 of file dotnode.h.

Referenced by deleteNode().

◆ m_distance

int DotNode::m_distance = 1000
private

shortest path to the root node

Definition at line 144 of file dotnode.h.

Referenced by distance(), and setDistance().

◆ m_edgeInfo

EdgeInfoVector DotNode::m_edgeInfo
private

edge info for each child

Definition at line 136 of file dotnode.h.

Referenced by addChild(), edgeInfo(), write(), writeDEF(), writeDocbook(), writeLabel(), and writeXML().

◆ m_graph

DotGraph* DotNode::m_graph
private

Definition at line 129 of file dotnode.h.

Referenced by DotNode(), and writeArrow().

◆ m_hasDoc

bool DotNode::m_hasDoc = false
private

used to mark a node as documented

Definition at line 139 of file dotnode.h.

Referenced by hasDocumentation(), and markHasDocumentation().

◆ m_isRoot

bool DotNode::m_isRoot
private

indicates if this is a root node

Definition at line 140 of file dotnode.h.

Referenced by DotNode(), writeBox(), and writeLabel().

◆ m_label

QCString DotNode::m_label
private

label text

Definition at line 131 of file dotnode.h.

Referenced by DotNode(), label(), renumberNodes(), writeDEF(), writeDocbook(), writeLabel(), and writeXML().

◆ m_number

int DotNode::m_number
private

◆ m_parents

DotNodeRefVector DotNode::m_parents
private

list of parent nodes (incoming arrows)

Definition at line 134 of file dotnode.h.

Referenced by addParent(), clearWriteFlag(), colorConnectedNodes(), deleteNode(), findParent(), parents(), removeParent(), renumberNodes(), and write().

◆ m_renumbered

bool DotNode::m_renumbered = false
private

indicates if the node has been renumbered (to prevent endless loops)

Definition at line 145 of file dotnode.h.

Referenced by isRenumbered(), and markRenumbered().

◆ m_subgraphId

int DotNode::m_subgraphId = -1
private

Definition at line 146 of file dotnode.h.

Referenced by setSubgraphId(), and subgraphId().

◆ m_tooltip

QCString DotNode::m_tooltip
private

node's tooltip

Definition at line 132 of file dotnode.h.

Referenced by DotNode(), and writeBox().

◆ m_truncated

TruncState DotNode::m_truncated = Unknown
private

does the node have non-visible children/parents

Definition at line 143 of file dotnode.h.

Referenced by isTruncated(), markAsTruncated(), write(), and writeLabel().

◆ m_url

QCString DotNode::m_url
private

url of the node (format: remote$local)

Definition at line 133 of file dotnode.h.

Referenced by DotNode(), writeBox(), writeDEF(), writeDocbook(), writeUrl(), and writeXML().

◆ m_visible

bool DotNode::m_visible = false
private

is the node visible in the output

Definition at line 142 of file dotnode.h.

Referenced by isVisible(), markAsVisible(), and write().

◆ m_written

bool DotNode::m_written = false
private

used to mark a node as written

Definition at line 138 of file dotnode.h.

Referenced by clearWriteFlag(), isWritten(), and write().

◆ placeholderUrl

auto DotNode::placeholderUrl = "-"
staticconstexpr

Definition at line 71 of file dotnode.h.

Referenced by DotLegendGraph::computeTheGraph(), and writeUrl().


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