File indexing completed on 2024-05-19 15:27:47

0001 /* This file is part of KGraphViewer.
0002    Copyright (C) 2005-2007 Gael de Chalendar <kleag@free.fr>
0003 
0004    KGraphViewer is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU General Public
0006    License as published by the Free Software Foundation, version 2.
0007 
0008    This program is distributed in the hope that it will be useful,
0009    but WITHOUT ANY WARRANTY; without even the implied warranty of
0010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0011    General Public License for more details.
0012 
0013    You should have received a copy of the GNU General Public License
0014    along with this program; if not, write to the Free Software
0015    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
0016    02110-1301, USA
0017 */
0018 
0019 /*
0020  * Graphviz DOT graph model
0021  */
0022 
0023 #ifndef DOT_GRAPH_H
0024 #define DOT_GRAPH_H
0025 
0026 #include <QList>
0027 #include <QMutex>
0028 #include <QProcess>
0029 #include <QSet>
0030 #include <QString>
0031 
0032 #include <graphviz/gvc.h>
0033 
0034 #include "dotdefaults.h"
0035 #include "graphedge.h"
0036 #include "graphelement.h"
0037 #include "graphnode.h"
0038 #include "graphsubgraph.h"
0039 #include "kgraphviewer_export.h"
0040 
0041 namespace KGraphViewer
0042 {
0043 /**
0044  * A class representing the model of a Graphviz DOT graph
0045  */
0046 class DotGraph : public GraphElement
0047 {
0048     Q_OBJECT
0049 public:
0050     enum ParsePhase { Initial, Final };
0051 
0052     DotGraph();
0053     DotGraph(const QString &command, const QString &fileName);
0054 
0055     ~DotGraph() override;
0056 
0057     QString chooseLayoutProgramForFile(const QString &str);
0058     bool parseDot(const QString &str);
0059 
0060     /** Constant accessor to the nodes of this graph */
0061     inline const GraphNodeMap &nodes() const
0062     {
0063         return m_nodesMap;
0064     }
0065     /** Constant accessor to the edges of this graph */
0066     inline const GraphEdgeMap &edges() const
0067     {
0068         return m_edgesMap;
0069     }
0070     inline const GraphSubgraphMap &subgraphs() const
0071     {
0072         return m_subgraphsMap;
0073     }
0074     /** Accessor to the nodes of this graph */
0075     inline GraphNodeMap &nodes()
0076     {
0077         return m_nodesMap;
0078     }
0079     /** Accessor to the edges of this graph */
0080     inline GraphEdgeMap &edges()
0081     {
0082         return m_edgesMap;
0083     }
0084     inline GraphSubgraphMap &subgraphs()
0085     {
0086         return m_subgraphsMap;
0087     }
0088     double width() const
0089     {
0090         return m_width;
0091     }
0092     double height() const
0093     {
0094         return m_height;
0095     }
0096     double scale() const
0097     {
0098         return m_scale;
0099     }
0100     void width(double w)
0101     {
0102         m_width = w;
0103     }
0104     void height(double h)
0105     {
0106         m_height = h;
0107     }
0108     void scale(double s)
0109     {
0110         m_scale = s;
0111     }
0112     QString backColor() const override;
0113 
0114     inline void strict(bool s)
0115     {
0116         m_strict = s;
0117     }
0118     inline void directed(bool d)
0119     {
0120         m_directed = d;
0121     }
0122     inline bool strict() const
0123     {
0124         return m_strict;
0125     }
0126     inline bool directed() const
0127     {
0128         return m_directed;
0129     }
0130 
0131     QSet<GraphNode *> &nodesOfCell(unsigned int id);
0132 
0133     inline unsigned int horizCellFactor() const
0134     {
0135         return m_horizCellFactor;
0136     }
0137     inline unsigned int vertCellFactor() const
0138     {
0139         return m_vertCellFactor;
0140     }
0141     inline double wdhcf() const
0142     {
0143         return m_wdhcf;
0144     }
0145     inline double hdvcf() const
0146     {
0147         return m_hdvcf;
0148     }
0149 
0150     inline void layoutCommand(const QString &command)
0151     {
0152         m_layoutCommand = command;
0153     }
0154     inline const QString &layoutCommand()
0155     {
0156         return m_layoutCommand;
0157     }
0158 
0159     inline void dotFileName(const QString &fileName)
0160     {
0161         m_dotFileName = fileName;
0162     }
0163     inline const QString &dotFileName() const
0164     {
0165         return m_dotFileName;
0166     }
0167 
0168     bool update();
0169 
0170     inline void setReadWrite()
0171     {
0172         m_readWrite = true;
0173     }
0174     inline void setReadOnly()
0175     {
0176         m_readWrite = false;
0177     }
0178 
0179     void storeOriginalAttributes() override;
0180 
0181     void KGRAPHVIEWER_EXPORT saveTo(const QString &fileName);
0182 
0183     void updateWithGraph(graph_t *newGraph);
0184     void updateWithGraph(const DotGraph &graph);
0185 
0186     void KGRAPHVIEWER_EXPORT setAttribute(const QString &elementId, const QString &attributeName, const QString &attributeValue);
0187 
0188     GraphElement *elementNamed(const QString &id);
0189 
0190     inline void setUseLibrary(bool value)
0191     {
0192         m_useLibrary = value;
0193     }
0194     inline bool useLibrary()
0195     {
0196         return m_useLibrary;
0197     }
0198 
0199     void KGRAPHVIEWER_EXPORT setGraphAttributes(QMap<QString, QString> attribs);
0200     void KGRAPHVIEWER_EXPORT addNewNode(QMap<QString, QString> attribs);
0201     void KGRAPHVIEWER_EXPORT addNewSubgraph(QMap<QString, QString> attribs);
0202     void KGRAPHVIEWER_EXPORT addNewNodeToSubgraph(QMap<QString, QString> attribs, QString subgraph);
0203     void KGRAPHVIEWER_EXPORT addExistingNodeToSubgraph(QMap<QString, QString> attribs, QString subgraph);
0204     void KGRAPHVIEWER_EXPORT moveExistingNodeToMainGraph(QMap<QString, QString> attribs);
0205     void KGRAPHVIEWER_EXPORT addNewEdge(QString src, QString tgt, QMap<QString, QString> attribs);
0206     using GraphElement::removeAttribute;
0207     void KGRAPHVIEWER_EXPORT removeAttribute(const QString &nodeName, const QString &attribName);
0208     void KGRAPHVIEWER_EXPORT renameNode(const QString &oldNodeName, const QString &newNodeName);
0209     void KGRAPHVIEWER_EXPORT removeNodeNamed(const QString &nodeName);
0210     void KGRAPHVIEWER_EXPORT removeNodeFromSubgraph(const QString &nodeName, const QString &subgraphName);
0211     void KGRAPHVIEWER_EXPORT removeSubgraphNamed(const QString &subgraphName);
0212     void KGRAPHVIEWER_EXPORT removeEdge(const QString &id);
0213     void KGRAPHVIEWER_EXPORT removeElement(const QString &id);
0214 
0215 Q_SIGNALS:
0216     void readyToDisplay();
0217 
0218 private Q_SLOTS:
0219     void slotDotRunningDone(int, QProcess::ExitStatus);
0220     void slotDotRunningError(QProcess::ProcessError);
0221 
0222 private:
0223     unsigned int cellNumber(int x, int y);
0224     void computeCells();
0225     QByteArray getDotResult(int exitCode, QProcess::ExitStatus exitStatus);
0226 
0227     QString m_dotFileName;
0228     GraphSubgraphMap m_subgraphsMap;
0229     GraphNodeMap m_nodesMap;
0230     GraphEdgeMap m_edgesMap;
0231     double m_width, m_height;
0232     double m_scale;
0233     bool m_directed;
0234     bool m_strict;
0235     QString m_layoutCommand;
0236 
0237     unsigned int m_horizCellFactor, m_vertCellFactor;
0238     QVector<QSet<GraphNode *>> m_cells;
0239 
0240     double m_wdhcf, m_hdvcf;
0241 
0242     bool m_readWrite;
0243     QProcess *m_dot;
0244 
0245     ParsePhase m_phase;
0246 
0247     QMutex m_dotProcessMutex;
0248 
0249     bool m_useLibrary;
0250 };
0251 
0252 }
0253 
0254 #endif