00001 /****************************************************************************** 00002 * 00003 * $Id: dot.h,v 1.14 2001/03/19 19:27:40 root Exp $ 00004 * 00005 * 00006 * Copyright (C) 1997-2008 by Dimitri van Heesch. 00007 * 00008 * Permission to use, copy, modify, and distribute this software and its 00009 * documentation under the terms of the GNU General Public License is hereby 00010 * granted. No representations are made about the suitability of this software 00011 * for any purpose. It is provided "as is" without express or implied warranty. 00012 * See the GNU General Public License for more details. 00013 * 00014 * Documents produced by Doxygen are derivative works derived from the 00015 * input used in their production; they are not affected by this license. 00016 * 00017 */ 00018 00019 #ifndef _DOT_H 00020 #define _DOT_H 00021 00022 #include "qtbc.h" 00023 #include <qlist.h> 00024 #include <qdict.h> 00025 #include "sortdict.h" 00026 00027 class ClassDef; 00028 class FileDef; 00029 class QTextStream; 00030 class DotNodeList; 00031 class ClassSDict; 00032 class MemberDef; 00033 class Definition; 00034 class DirDef; 00035 class GroupDef; 00036 class DotGroupCollaboration; 00037 00038 enum GraphOutputFormat { BITMAP , EPS }; 00039 00041 struct EdgeInfo 00042 { 00043 enum Colors { Blue=0, Green=1, Red=2, Purple=3, Grey=4, Orange=5 }; 00044 enum Styles { Solid=0, Dashed=1 }; 00045 EdgeInfo() : m_color(0), m_style(0), m_labColor(0) {} 00046 ~EdgeInfo() {} 00047 int m_color; 00048 int m_style; 00049 QCString m_label; 00050 QCString m_url; 00051 int m_labColor; 00052 }; 00053 00055 class DotNode 00056 { 00057 public: 00058 enum GraphType { Dependency, Inheritance, Collaboration, Hierarchy, CallGraph }; 00059 enum TruncState { Unknown, Truncated, Untruncated }; 00060 DotNode(int n,const char *lab,const char *tip,const char *url, 00061 bool rootNode=FALSE,ClassDef *cd=0); 00062 ~DotNode(); 00063 void addChild(DotNode *n, 00064 int edgeColor=EdgeInfo::Purple, 00065 int edgeStyle=EdgeInfo::Solid, 00066 const char *edgeLab=0, 00067 const char *edgeURL=0, 00068 int edgeLabCol=-1 00069 ); 00070 void addParent(DotNode *n); 00071 void deleteNode(DotNodeList &deletedList,SDict<DotNode> *skipNodes=0); 00072 void removeChild(DotNode *n); 00073 void removeParent(DotNode *n); 00074 int findParent( DotNode *n ); 00075 void write(QTextStream &t,GraphType gt,GraphOutputFormat f, 00076 bool topDown,bool toChildren,bool backArrows,bool reNumber); 00077 int m_subgraphId; 00078 void clearWriteFlag(); 00079 void writeXML(QTextStream &t,bool isClassGraph); 00080 void writeDEF(QTextStream &t); 00081 QCString label() const { return m_label; } 00082 int number() const { return m_number; } 00083 bool isVisible() const { return m_visible; } 00084 TruncState isTruncated() const { return m_truncated; } 00085 int distance() const { return m_distance; } 00086 00087 private: 00088 void colorConnectedNodes(int curColor); 00089 void writeBox(QTextStream &t,GraphType gt,GraphOutputFormat f, 00090 bool hasNonReachableChildren, bool reNumber=FALSE); 00091 void writeArrow(QTextStream &t,GraphType gt,GraphOutputFormat f,DotNode *cn, 00092 EdgeInfo *ei,bool topDown, bool pointBack=TRUE, bool reNumber=FALSE); 00093 void setDistance(int distance); 00094 const DotNode *findDocNode() const; // only works for acyclic graphs! 00095 void markAsVisible(bool b=TRUE) { m_visible=b; } 00096 void markAsTruncated(bool b=TRUE) { m_truncated=b ? Truncated : Untruncated; } 00097 int m_number; 00098 QCString m_label; 00099 QCString m_tooltip; 00100 QCString m_url; 00101 QList<DotNode> *m_parents; 00102 QList<DotNode> *m_children; 00103 QList<EdgeInfo> *m_edgeInfo; 00104 bool m_deleted; 00105 bool m_written; 00106 bool m_hasDoc; 00107 bool m_isRoot; 00108 ClassDef * m_classDef; 00109 bool m_visible; 00110 TruncState m_truncated; 00111 int m_distance; 00112 00113 friend class DotGfxHierarchyTable; 00114 friend class DotClassGraph; 00115 friend class DotInclDepGraph; 00116 friend class DotNodeList; 00117 friend class DotCallGraph; 00118 friend class DotGroupCollaboration; 00119 00120 friend QCString computeMd5Signature( 00121 DotNode *root, GraphType gt, 00122 GraphOutputFormat f, 00123 bool lrRank, bool renderParents, 00124 bool backArrows, 00125 QCString &graphStr 00126 ); 00127 }; 00128 00129 inline int DotNode::findParent( DotNode *n ) 00130 { 00131 if( !m_parents ) 00132 return -1; 00133 return m_parents->find(n); 00134 } 00135 00137 class DotGfxHierarchyTable 00138 { 00139 public: 00140 DotGfxHierarchyTable(); 00141 ~DotGfxHierarchyTable(); 00142 void writeGraph(QTextStream &t,const char *path) const; 00143 00144 private: 00145 void addHierarchy(DotNode *n,ClassDef *cd,bool hide); 00146 void addClassList(ClassSDict *cl); 00147 00148 QList<DotNode> *m_rootNodes; 00149 QDict<DotNode> *m_usedNodes; 00150 static int m_curNodeNumber; 00151 DotNodeList *m_rootSubgraphs; 00152 }; 00153 00155 class DotClassGraph 00156 { 00157 public: 00158 DotClassGraph(ClassDef *cd,DotNode::GraphType t); 00159 ~DotClassGraph(); 00160 bool isTrivial() const; 00161 bool isTooBig() const; 00162 QCString writeGraph(QTextStream &t,GraphOutputFormat f,const char *path, 00163 const char *relPath, bool TBRank=TRUE,bool imageMap=TRUE) const; 00164 00165 void writeXML(QTextStream &t); 00166 void writeDEF(QTextStream &t); 00167 QCString diskName() const; 00168 00169 private: 00170 void buildGraph(ClassDef *cd,DotNode *n,bool base,int distance); 00171 bool determineVisibleNodes(DotNode *rootNode,int maxNodes,bool includeParents); 00172 void determineTruncatedNodes(QList<DotNode> &queue,bool includeParents); 00173 void addClass(ClassDef *cd,DotNode *n,int prot,const char *label, 00174 const char *usedName,const char *templSpec, 00175 bool base,int distance); 00176 00177 DotNode * m_startNode; 00178 QDict<DotNode> * m_usedNodes; 00179 static int m_curNodeNumber; 00180 DotNode::GraphType m_graphType; 00181 QCString m_diskName; 00182 bool m_lrRank; 00183 }; 00184 00186 class DotInclDepGraph 00187 { 00188 public: 00189 DotInclDepGraph(FileDef *fd,bool inverse); 00190 ~DotInclDepGraph(); 00191 QCString writeGraph(QTextStream &t, GraphOutputFormat f,const char *path, 00192 const char *relPath, 00193 bool writeImageMap=TRUE) const; 00194 bool isTrivial() const; 00195 bool isTooBig() const; 00196 QCString diskName() const; 00197 void writeXML(QTextStream &t); 00198 00199 private: 00200 void buildGraph(DotNode *n,FileDef *fd,int distance); 00201 void determineVisibleNodes(QList<DotNode> &queue,int &maxNodes); 00202 void determineTruncatedNodes(QList<DotNode> &queue); 00203 00204 DotNode *m_startNode; 00205 QDict<DotNode> *m_usedNodes; 00206 static int m_curNodeNumber; 00207 QCString m_diskName; 00208 int m_maxDistance; 00209 bool m_inverse; 00210 }; 00211 00213 class DotCallGraph 00214 { 00215 public: 00216 DotCallGraph(MemberDef *md,bool inverse); 00217 ~DotCallGraph(); 00218 QCString writeGraph(QTextStream &t, GraphOutputFormat f, 00219 const char *path,const char *relPath,bool writeImageMap=TRUE) const; 00220 void buildGraph(DotNode *n,MemberDef *md,int distance); 00221 bool isTrivial() const; 00222 bool isTooBig() const; 00223 void determineVisibleNodes(QList<DotNode> &queue, int &maxNodes); 00224 void determineTruncatedNodes(QList<DotNode> &queue); 00225 00226 private: 00227 DotNode *m_startNode; 00228 static int m_curNodeNumber; 00229 QDict<DotNode> *m_usedNodes; 00230 int m_maxDistance; 00231 int m_recDepth; 00232 bool m_inverse; 00233 QCString m_diskName; 00234 Definition * m_scope; 00235 }; 00236 00238 class DotDirDeps 00239 { 00240 public: 00241 DotDirDeps(DirDef *dir); 00242 ~DotDirDeps(); 00243 bool isTrivial() const; 00244 QCString writeGraph(QTextStream &out, 00245 GraphOutputFormat format, 00246 const char *path, 00247 const char *relPath, 00248 bool writeImageMap=TRUE) const; 00249 private: 00250 DirDef *m_dir; 00251 }; 00252 00254 class DotGroupCollaboration 00255 { 00256 public : 00257 enum EdgeType 00258 { tmember = 0, 00259 tclass, 00260 tnamespace, 00261 tfile, 00262 tpages, 00263 tdir, 00264 thierarchy 00265 }; 00266 00267 class Link 00268 { 00269 public: 00270 Link(const QCString lab,const QCString &u) : label(lab), url(u) {} 00271 QCString label; 00272 QCString url; 00273 }; 00274 00275 class Edge 00276 { 00277 public : 00278 Edge(DotNode *start,DotNode *end,EdgeType type) 00279 : pNStart(start), pNEnd(end), eType(type) 00280 { links.setAutoDelete(TRUE); } 00281 00282 DotNode* pNStart; 00283 DotNode* pNEnd; 00284 EdgeType eType; 00285 00286 QList<Link> links; 00287 void write( QTextStream &t ) const; 00288 }; 00289 00290 DotGroupCollaboration(GroupDef* gd); 00291 ~DotGroupCollaboration(); 00292 QCString writeGraph(QTextStream &t, GraphOutputFormat format, 00293 const char *path,const char *relPath, 00294 bool writeImageMap=TRUE) const; 00295 void buildGraph(GroupDef* gd); 00296 bool isTrivial() const; 00297 private : 00298 void addCollaborationMember( Definition* def, QCString& url, EdgeType eType ); 00299 void addMemberList( class MemberList* ml ); 00300 void writeGraphHeader(QTextStream &t) const; 00301 Edge* addEdge( DotNode* _pNStart, DotNode* _pNEnd, EdgeType _eType, 00302 const QCString& _label, const QCString& _url ); 00303 00304 DotNode *m_rootNode; 00305 int m_curNodeId; 00306 QDict<DotNode> *m_usedNodes; 00307 QCString m_diskName; 00308 QList<Edge> m_edges; 00309 }; 00310 00313 class DotRunner 00314 { 00315 public: 00317 DotRunner(const char *file); 00318 00322 void addJob(const char *format,const char *output); 00323 00325 bool run(); 00326 private: 00327 QList<QCString> m_jobs; 00328 QCString m_file; 00329 }; 00330 00331 00333 void generateGraphLegend(const char *path); 00334 00335 void writeDotGraphFromFile(const char *inFile,const char *outDir, 00336 const char *outFile,GraphOutputFormat format); 00337 QString getDotImageMapFromFile(const QString& inFile, const QString& outDir, 00338 const QCString& relPath,const QString &context); 00339 00340 void writeDotDirDepGraph(QTextStream &t,DirDef *dd); 00341 00342 #endif