00001 #include "graphvizwrapper.h"
00002 #include "utility/dbglog.h"
00003
00004 #include <QtPlugin>
00005
00006 #include <QPointF>
00007 #include <QString>
00008
00009 #define DBGLOG_GV(x) DBGLOG_("GRAPHVIZ", x)
00010 #define RELLOG_GV(x) RELLOG_("GRAPHVIZ", x)
00011
00012
00013
00014 GVEdge::GVEdge(Agraph_t *graph, Agedge_t *edge)
00015 : m_graph(graph), m_edge(edge)
00016 {
00017
00018 }
00019
00020 GVEdge::~GVEdge()
00021 {
00022 DBGLOG_GV("deleted");
00023 }
00024
00025 QString GVEdge::getHeadName() const
00026 {
00027 return m_edge->head->name;
00028 }
00029
00030 QString GVEdge::getTailName() const
00031 {
00032 return m_edge->tail->name;
00033 }
00034
00035 QString GVEdge::getLabel() const
00036 {
00037 return m_edge->u.label->text;
00038 }
00039
00040 QPoint GVEdge::getLabelPos() const
00041 {
00042 return
00043 #ifdef WIN32
00044 QPointF(m_edge->u.label->pos.x, m_edge->u.label->pos.y).toPoint();
00045 #else
00046 QPoint(m_edge->u.label->p.x, m_edge->u.label->p.y);
00047 #endif
00048 }
00049
00050 QSharedPointer<IGVEdge> GVEdge::getNextOutEdge() const
00051 {
00052 Agedge_t *edge = agnxtout(m_graph, m_edge);
00053 return QSharedPointer<IGVEdge>(edge ? new GVEdge(m_graph, edge) : NULL);
00054 }
00055
00056 IGVEdge::TCPList GVEdge::getControlPoints() const
00057 {
00058 QVector<QPoint> result;
00059
00060 const int count = m_edge->u.spl->list->size;
00061 #ifdef WIN32
00062 pointf *pPoints = m_edge->u.spl->list->list;
00063 #else
00064 point *pPoints = m_edge->u.spl->list->list;
00065 #endif
00066 for (int i=0; i < count; ++i)
00067 {
00068 #ifdef WIN32
00069 result << QPointF((pPoints+i)->x, (pPoints+i)->y).toPoint();
00070 #else
00071 result << QPoint((pPoints+i)->x, (pPoints+i)->y);
00072 #endif
00073 }
00074
00075 return result;
00076 }
00077
00078
00079
00080
00081
00082
00083
00084 GVNode::GVNode(Agraph_t *graph, Agnode_t *node)
00085 : m_graph(graph), m_node(node)
00086 {
00087
00088 }
00089
00090 GVNode::~GVNode()
00091 {
00092 DBGLOG_GV("deleted");
00093 }
00094
00095 QString GVNode::getName() const
00096 {
00097 return m_node->name;
00098 }
00099
00100 QPoint GVNode::getPos() const
00101 {
00102 return QPoint(m_node->u.coord.x, m_node->u.coord.y);
00103 }
00104
00105 QSharedPointer<IGVNode> GVNode::getPrevNode() const
00106 {
00107 Agnode_t *node = agprvnode(m_graph, m_node);
00108 return QSharedPointer<IGVNode>(node ? new GVNode(m_graph, node) : NULL);
00109 }
00110
00111 QSharedPointer<IGVNode> GVNode::getNextNode() const
00112 {
00113 Agnode_t *node = agnxtnode(m_graph, m_node);
00114 return QSharedPointer<IGVNode>(node ? new GVNode(m_graph, node) : NULL);
00115 }
00116
00117 QSharedPointer<IGVEdge> GVNode::getFirstOutEdge() const
00118 {
00119 Agedge_t *edge = agfstout(m_graph, m_node);
00120 return QSharedPointer<IGVEdge>(edge ? new GVEdge(m_graph, edge) : NULL);
00121 }
00122
00123
00124
00125
00126
00127
00128
00129 GVGraph::GVGraph()
00130 : m_layout(false)
00131 {
00132 m_gvc = gvContext();
00133 m_graph = agopen((char*)"G", AGDIGRAPH);
00134 agraphattr(m_graph, (char*)"rankdir", (char*)"LR");
00135 agraphattr(m_graph, (char*)"splines", (char*)"true");
00136 agedgeattr(m_graph, (char*)"label", (char*)"");
00137 }
00138
00139 GVGraph::~GVGraph()
00140 {
00141 DBGLOG_GV("deleted");
00142 if (m_layout)
00143 gvFreeLayout(m_gvc, m_graph);
00144 agclose(m_graph);
00145 gvFreeContext(m_gvc);
00146 }
00147
00148 void GVGraph::layoutGraphUsingDot()
00149 {
00150 if (m_layout)
00151 {
00152 gvFreeLayout(m_gvc, m_graph);
00153 m_layout = false;
00154 }
00155 gvLayout(m_gvc, m_graph, (char*)"dot");
00156 m_layout = true;
00157 }
00158
00159 void GVGraph::renderToFile(const QString &fileName)
00160 {
00161 if (!m_layout)
00162 layoutGraphUsingDot();
00163 gvRenderFilename(m_gvc, m_graph, (char*)"png", const_cast<char*>(fileName.toStdString().c_str()));
00164 }
00165
00166 bool GVGraph::addNode(const QString &name)
00167 {
00168 Agnode_t *n = agnode(m_graph, const_cast<char*>(name.toStdString().c_str()));
00169 if (n)
00170 {
00171 return true;
00172 }
00173 RELLOG_GV("Node couldn't be added!");
00174 return false;
00175 }
00176
00177 int GVGraph::getNodeCount() const
00178 {
00179 return agnnodes(m_graph);
00180 }
00181
00182 QSharedPointer<IGVNode> GVGraph::getNode(const QString &name) const
00183 {
00184 Agnode_t *node = agfindnode(m_graph, const_cast<char*>(name.toStdString().c_str()));
00185 return QSharedPointer<IGVNode>(node ? new GVNode(m_graph, node) : NULL);
00186 }
00187
00188 QSharedPointer<IGVNode> GVGraph::getFirstNode() const
00189 {
00190 Agnode_t *node = agfstnode(m_graph);
00191 return QSharedPointer<IGVNode>(node ? new GVNode(m_graph, node) : NULL);
00192 }
00193
00194 QSharedPointer<IGVNode> GVGraph::getLastNode() const
00195 {
00196 Agnode_t *node = aglstnode(m_graph);
00197 return QSharedPointer<IGVNode>(node ? new GVNode(m_graph, node) : NULL);
00198 }
00199
00200 bool GVGraph::addEdge(const QString &s1, const QString &s2, const QString &l)
00201 {
00202 Agnode_t *n1 = agfindnode(m_graph, const_cast<char*>(s1.toStdString().c_str()));
00203 Agnode_t *n2 = agfindnode(m_graph, const_cast<char*>(s2.toStdString().c_str()));
00204 if (!n1 || !n2)
00205 {
00206 RELLOG_GV("Some node don't exist when adding edge, couldn't be added!");
00207 return false;
00208 }
00209 Agedge_t *e = agedge(m_graph, n1, n2);
00210 if (e)
00211 {
00212 agset(e, (char*)"label", const_cast<char*>(l.toStdString().c_str()));
00213 return true;
00214 }
00215 RELLOG("Edge couldn't be added;!");
00216 return false;
00217 }
00218
00219 int GVGraph::getEdgeCount() const
00220 {
00221 return agnedges(m_graph);
00222 }
00223
00224
00225
00226
00227
00228
00229
00230 GraphVizWrapper::GraphVizWrapper()
00231
00232 {
00233
00234 }
00235
00236 GraphVizWrapper::~GraphVizWrapper()
00237 {
00238 DBGLOG_GV("deleted");
00239 }
00240
00241 QSharedPointer<IGVGraph> GraphVizWrapper::createGraph() const
00242 {
00243 return QSharedPointer<IGVGraph>(new GVGraph());
00244 }
00245
00246 QString GraphVizWrapper::getGraphVizVersion() const
00247 {
00248 GVC_t *gvc = gvContext();
00249 QString versionStr = gvcVersion(gvc);
00250 gvFreeContext(gvc);
00251 return versionStr;
00252 }
00253
00254
00255
00256 Q_EXPORT_PLUGIN2(gvwrapper, GraphVizWrapper)