My Project
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
dot.h
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  *
4  *
5  *
6  * Copyright (C) 1997-2015 by Dimitri van Heesch.
7  *
8  * Permission to use, copy, modify, and distribute this software and its
9  * documentation under the terms of the GNU General Public License is hereby
10  * granted. No representations are made about the suitability of this software
11  * for any purpose. It is provided "as is" without express or implied warranty.
12  * See the GNU General Public License for more details.
13  *
14  * Documents produced by Doxygen are derivative works derived from the
15  * input used in their production; they are not affected by this license.
16  *
17  */
18 
19 #ifndef _DOT_H
20 #define _DOT_H
21 
22 #include <qlist.h>
23 #include <qdict.h>
24 #include <qwaitcondition.h>
25 #include <qmutex.h>
26 #include <qqueue.h>
27 #include <qthread.h>
28 #include "sortdict.h"
29 
30 class ClassDef;
31 class FileDef;
32 class FTextStream;
33 class DotNodeList;
34 class ClassSDict;
35 class MemberDef;
36 class Definition;
37 class DirDef;
38 class GroupDef;
40 class DotRunnerQueue;
41 
44 
46 struct EdgeInfo
47 {
48  enum Colors { Blue=0, Green=1, Red=2, Purple=3, Grey=4, Orange=5, Orange2=6 };
49  enum Styles { Solid=0, Dashed=1 };
50  EdgeInfo() : m_color(0), m_style(0), m_labColor(0) {}
51  ~EdgeInfo() {}
52  int m_color;
53  int m_style;
54  QCString m_label;
55  QCString m_url;
57 };
58 
60 class DotNode
61 {
62  public:
65  DotNode(int n,const char *lab,const char *tip,const char *url,
66  bool rootNode=FALSE,ClassDef *cd=0);
67  ~DotNode();
68  void addChild(DotNode *n,
69  int edgeColor=EdgeInfo::Purple,
70  int edgeStyle=EdgeInfo::Solid,
71  const char *edgeLab=0,
72  const char *edgeURL=0,
73  int edgeLabCol=-1
74  );
75  void addParent(DotNode *n);
76  void deleteNode(DotNodeList &deletedList,SDict<DotNode> *skipNodes=0);
77  void removeChild(DotNode *n);
78  void removeParent(DotNode *n);
79  int findParent( DotNode *n );
81  bool topDown,bool toChildren,bool backArrows);
83  void clearWriteFlag();
84  void writeXML(FTextStream &t,bool isClassGraph);
85  void writeDocbook(FTextStream &t,bool isClassGraph);
86  void writeDEF(FTextStream &t);
87  QCString label() const { return m_label; }
88  int number() const { return m_number; }
89  bool isVisible() const { return m_visible; }
90  TruncState isTruncated() const { return m_truncated; }
91  int distance() const { return m_distance; }
92  void renumberNodes(int &number);
93 
94  private:
95  void colorConnectedNodes(int curColor);
97  bool hasNonReachableChildren);
99  EdgeInfo *ei,bool topDown, bool pointBack=TRUE);
100  void setDistance(int distance);
101  const DotNode *findDocNode() const; // only works for acyclic graphs!
102  void markAsVisible(bool b=TRUE) { m_visible=b; }
103  void markAsTruncated(bool b=TRUE) { m_truncated=b ? Truncated : Untruncated; }
104  int m_number;
105  QCString m_label;
106  QCString m_tooltip;
107  QCString m_url;
108  QList<DotNode> *m_parents;
109  QList<DotNode> *m_children;
110  QList<EdgeInfo> *m_edgeInfo;
111  bool m_deleted;
112  bool m_written;
113  bool m_hasDoc;
114  bool m_isRoot;
116  bool m_visible;
119 
120  friend class DotGfxHierarchyTable;
121  friend class DotClassGraph;
122  friend class DotInclDepGraph;
123  friend class DotNodeList;
124  friend class DotCallGraph;
125  friend class DotGroupCollaboration;
126  friend class DotInheritanceGraph;
127 
128  friend QCString computeMd5Signature(
129  DotNode *root, GraphType gt,
131  bool lrRank, bool renderParents,
132  bool backArrows,
133  const QCString &title,
134  QCString &graphStr
135  );
136 };
137 
139 class DotNodeList : public QList<DotNode>
140 {
141  public:
142  DotNodeList() : QList<DotNode>() {}
144  private:
145  int compareValues(const DotNode *n1,const DotNode *n2) const;
146 };
147 
150 {
151  public:
154  void writeGraph(FTextStream &t,const char *path, const char *fileName) const;
155  void createGraph(DotNode *rootNode,FTextStream &t,const char *path,const char *fileName,int id) const;
156  const DotNodeList *subGraphs() const { return m_rootSubgraphs; }
157 
158  private:
159  void addHierarchy(DotNode *n,ClassDef *cd,bool hide);
160  void addClassList(ClassSDict *cl);
161 
162  QList<DotNode> *m_rootNodes;
163  QDict<DotNode> *m_usedNodes;
166 };
167 
170 {
171  public:
173  ~DotClassGraph();
174  bool isTrivial() const;
175  bool isTooBig() const;
177  const char *path, const char *fileName, const char *relPath,
178  bool TBRank=TRUE,bool imageMap=TRUE,int graphId=-1) const;
179 
180  void writeXML(FTextStream &t);
181  void writeDocbook(FTextStream &t);
182  void writeDEF(FTextStream &t);
183  static void resetNumbering();
184 
185  private:
186  void buildGraph(ClassDef *cd,DotNode *n,bool base,int distance);
187  bool determineVisibleNodes(DotNode *rootNode,int maxNodes,bool includeParents);
188  void determineTruncatedNodes(QList<DotNode> &queue,bool includeParents);
189  void addClass(ClassDef *cd,DotNode *n,int prot,const char *label,
190  const char *usedName,const char *templSpec,
191  bool base,int distance);
192 
194  QDict<DotNode> * m_usedNodes;
195  static int m_curNodeNumber;
199  bool m_lrRank;
200 };
201 
204 {
205  public:
206  DotInclDepGraph(FileDef *fd,bool inverse);
209  const char *path,const char *fileName,const char *relPath,
210  bool writeImageMap=TRUE,int graphId=-1) const;
211  bool isTrivial() const;
212  bool isTooBig() const;
213  QCString diskName() const;
214  void writeXML(FTextStream &t);
215  void writeDocbook(FTextStream &t);
216  static void resetNumbering();
217 
218  private:
219  void buildGraph(DotNode *n,FileDef *fd,int distance);
220  void determineVisibleNodes(QList<DotNode> &queue,int &maxNodes);
221  void determineTruncatedNodes(QList<DotNode> &queue);
222 
224  QDict<DotNode> *m_usedNodes;
225  static int m_curNodeNumber;
228  bool m_inverse;
229 };
230 
233 {
234  public:
235  DotCallGraph(MemberDef *md,bool inverse);
236  ~DotCallGraph();
238  const char *path,const char *fileName,
239  const char *relPath,bool writeImageMap=TRUE,
240  int graphId=-1) const;
241  void buildGraph(DotNode *n,MemberDef *md,int distance);
242  bool isTrivial() const;
243  bool isTooBig() const;
244  void determineVisibleNodes(QList<DotNode> &queue, int &maxNodes);
245  void determineTruncatedNodes(QList<DotNode> &queue);
246  static void resetNumbering();
247 
248  private:
250  static int m_curNodeNumber;
251  QDict<DotNode> *m_usedNodes;
252  bool m_inverse;
253  QCString m_diskName;
255 };
256 
259 {
260  public:
261  DotDirDeps(DirDef *dir);
262  ~DotDirDeps();
263  bool isTrivial() const;
264  QCString writeGraph(FTextStream &out,
267  const char *path,
268  const char *fileName,
269  const char *relPath,
270  bool writeImageMap=TRUE,
271  int graphId=-1,
272  bool linkRelations=TRUE) const;
273  private:
275 };
276 
279 {
280  public :
281  enum EdgeType
282  { tmember = 0,
289  };
290 
291  class Link
292  {
293  public:
294  Link(const QCString lab,const QCString &u) : label(lab), url(u) {}
295  QCString label;
296  QCString url;
297  };
298 
299  class Edge
300  {
301  public :
302  Edge(DotNode *start,DotNode *end,EdgeType type)
303  : pNStart(start), pNEnd(end), eType(type)
304  { links.setAutoDelete(TRUE); }
305 
309 
310  QList<Link> links;
311  void write( FTextStream &t ) const;
312  };
313 
317  const char *path,const char *fileName,const char *relPath,
318  bool writeImageMap=TRUE,int graphId=-1) const;
319  void buildGraph(GroupDef* gd);
320  bool isTrivial() const;
321  static void resetNumbering();
322 
323  private :
324  void addCollaborationMember( Definition* def, QCString& url, EdgeType eType );
325  void addMemberList( class MemberList* ml );
326  void writeGraphHeader(FTextStream &t,const QCString &title) const;
327  Edge* addEdge( DotNode* _pNStart, DotNode* _pNEnd, EdgeType _eType,
328  const QCString& _label, const QCString& _url );
329 
331  static int m_curNodeNumber;
332  QDict<DotNode> *m_usedNodes;
333  QCString m_diskName;
334  QList<Edge> m_edges;
335 };
336 
339 {
340  public:
342  ~DotConstString() { delete[] m_str; }
343  DotConstString(const QCString &s) : m_str(0) { set(s); }
344  DotConstString(const DotConstString &s) : m_str(0) { set(s.data()); }
345  const char *data() const { return m_str; }
346  bool isEmpty() const { return m_str==0 || m_str[0]=='\0'; }
347  void set(const QCString &s)
348  {
349  delete[] m_str;
350  m_str=0;
351  if (!s.isEmpty())
352  {
353  m_str=new char[s.length()+1];
354  qstrcpy(m_str,s.data());
355  }
356  }
357  private:
359  char *m_str;
360 };
361 
365 {
366  public:
367  struct CleanupItem
368  {
371  };
372 
374  DotRunner(const QCString &file,const QCString &fontPath,bool checkResult,
375  const QCString &imageName = QCString());
376 
380  void addJob(const char *format,const char *output);
381 
382  void addPostProcessing(const char *cmd,const char *args);
383 
384  void preventCleanUp() { m_cleanUp = FALSE; }
385 
387  bool run();
388  const CleanupItem &cleanup() const { return m_cleanupItem; }
389 
390  private:
393  QList<DotConstString> m_jobs;
401  bool m_cleanUp;
403 };
404 
407 {
408  public:
409  struct Map
410  {
411  QCString mapFile;
412  QCString relPath;
413  bool urlOnly;
414  QCString context;
415  QCString label;
416  bool zoomable;
417  int graphId;
418  };
419  DotFilePatcher(const char *patchFile);
420  int addMap(const QCString &mapFile,const QCString &relPath,
421  bool urlOnly,const QCString &context,const QCString &label);
422  int addFigure(const QCString &baseName,
423  const QCString &figureName,bool heightCheck);
424  int addSVGConversion(const QCString &relPath,bool urlOnly,
425  const QCString &context,bool zoomable,int graphId);
426  int addSVGObject(const QCString &baseName, const QCString &figureName,
427  const QCString &relPath);
428  bool run();
429  QCString file() const;
430 
431  private:
432  QList<Map> m_maps;
433  QCString m_patchFile;
434 };
435 
438 {
439  public:
440  void enqueue(DotRunner *runner);
441  DotRunner *dequeue();
442  uint count() const;
443  private:
444  QWaitCondition m_bufferNotEmpty;
445  QQueue<DotRunner> m_queue;
446  mutable QMutex m_mutex;
447 };
448 
450 class DotWorkerThread : public QThread
451 {
452  public:
454  void run();
455  void cleanup();
456  private:
458  QList<DotRunner::CleanupItem> m_cleanupItems;
459 };
460 
463 {
464  public:
465  static DotManager *instance();
466  void addRun(DotRunner *run);
467  int addMap(const QCString &file,const QCString &mapFile,
468  const QCString &relPath,bool urlOnly,
469  const QCString &context,const QCString &label);
470  int addFigure(const QCString &file,const QCString &baseName,
471  const QCString &figureName,bool heightCheck);
472  int addSVGConversion(const QCString &file,const QCString &relPath,
473  bool urlOnly,const QCString &context,bool zoomable,int graphId);
474  int addSVGObject(const QCString &file,const QCString &baseName,
475  const QCString &figureNAme,const QCString &relPath);
476  bool run();
477 
478  private:
479  DotManager();
480  virtual ~DotManager();
481  QList<DotRunner> m_dotRuns;
485  QList<DotWorkerThread> m_workers;
486 };
487 
488 
490 void generateGraphLegend(const char *path);
491 
492 void writeDotGraphFromFile(const char *inFile,const char *outDir,
493  const char *outFile,GraphOutputFormat format);
495  const QCString& inFile, const QCString& outDir,
496  const QCString& relPath,const QCString& baseName,
497  const QCString& context,int graphId=-1);
498 
499 void resetDotNodeNumbering();
500 
501 #endif