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

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 /* This file was callgraphview.cpp, part of KCachegrind.
0020    Copyright (C) 2003 Josef Weidendorfer <Josef.Weidendorfer@gmx.de>
0021 
0022    KCachegrind is free software; you can redistribute it and/or
0023    modify it under the terms of the GNU General Public
0024    License as published by the Free Software Foundation, version 2.
0025 */
0026 
0027 #include "graphexporter.h"
0028 #include "dotgraph.h"
0029 #include "kgraphviewerlib_debug.h"
0030 
0031 #include <QFile>
0032 #include <QTextStream>
0033 
0034 #include <QDebug>
0035 #include <QTemporaryFile>
0036 
0037 namespace KGraphViewer
0038 {
0039 GraphExporter::GraphExporter()
0040 {
0041 }
0042 
0043 GraphExporter::~GraphExporter()
0044 {
0045 }
0046 
0047 QString GraphExporter::writeDot(const DotGraph *graph, const QString &fileName)
0048 {
0049     qCDebug(KGRAPHVIEWERLIB_LOG) << fileName;
0050 
0051     QString actualFileName = fileName;
0052 
0053     if (fileName.isEmpty()) {
0054         QTemporaryFile tempFile;
0055         tempFile.setFileTemplate("XXXXXX.dot");
0056         if (!tempFile.open()) {
0057             qCWarning(KGRAPHVIEWERLIB_LOG) << "Unable to open for temp file for writing " << tempFile.fileName();
0058             exit(2);
0059         }
0060         actualFileName = tempFile.fileName();
0061         qCDebug(KGRAPHVIEWERLIB_LOG) << "using " << actualFileName;
0062     }
0063 
0064     QFile f(actualFileName);
0065     if (!f.open(QIODevice::WriteOnly | QIODevice::Text)) {
0066         qCWarning(KGRAPHVIEWERLIB_LOG) << "Unable to open file for writing " << fileName;
0067         exit(2);
0068     }
0069 
0070     QTextStream stream(&f);
0071 
0072     stream << "digraph \"";
0073     if (graph->id() != "\"\"") {
0074         stream << graph->id();
0075     }
0076     stream << "\" {\n";
0077 
0078     stream << "graph [" << *graph << "]" << Qt::endl;
0079 
0080     /// @TODO Subgraph are not represented as needed in DotGraph, so it is not
0081     /// possible to save them back : to be changed !
0082     //   qCDebug(KGRAPHVIEWERLIB_LOG) << "writing subgraphs";
0083     GraphSubgraphMap::const_iterator sit;
0084     for (sit = graph->subgraphs().begin(); sit != graph->subgraphs().end(); ++sit) {
0085         const GraphSubgraph &s = **sit;
0086         (stream) << s;
0087     }
0088 
0089     //   qCDebug(KGRAPHVIEWERLIB_LOG) << "writing nodes";
0090     GraphNodeMap::const_iterator nit;
0091     for (nit = graph->nodes().begin(); nit != graph->nodes().end(); ++nit) {
0092         (stream) << **nit;
0093     }
0094 
0095     qCDebug(KGRAPHVIEWERLIB_LOG) << "writing edges";
0096     GraphEdgeMap::const_iterator eit;
0097     for (eit = graph->edges().begin(); eit != graph->edges().end(); ++eit) {
0098         qCDebug(KGRAPHVIEWERLIB_LOG) << "writing edge" << (*eit)->id();
0099         stream << **eit;
0100     }
0101 
0102     stream << "}\n";
0103 
0104     f.close();
0105     return actualFileName;
0106 }
0107 
0108 graph_t *GraphExporter::exportToGraphviz(const DotGraph *graph)
0109 {
0110     Agdesc_t type = Agstrictundirected;
0111     type.directed = graph->directed();
0112     type.strict = graph->strict();
0113 
0114     graph_t *agraph = agopen((graph->id() != "\"\"") ? graph->id().toUtf8().data() : QString("unnamed").toUtf8().data(), type, nullptr);
0115 
0116     QTextStream stream;
0117     graph->exportToGraphviz(agraph);
0118     /// @TODO Subgraph are not represented as needed in DotGraph, so it is not
0119     /// possible to save them back : to be changed !
0120     //   qCDebug(KGRAPHVIEWERLIB_LOG) << "writing subgraphs";
0121     GraphSubgraphMap::const_iterator sit;
0122     for (sit = graph->subgraphs().begin(); sit != graph->subgraphs().end(); ++sit) {
0123         const GraphSubgraph &s = **sit;
0124         graph_t *subgraph = agsubg(agraph, s.id().toUtf8().data(), 1);
0125         s.exportToGraphviz(subgraph);
0126     }
0127 
0128     //   qCDebug(KGRAPHVIEWERLIB_LOG) << "writing nodes";
0129     GraphNodeMap::const_iterator nit;
0130     for (GraphNode *n : graph->nodes()) {
0131         node_t *node = agnode(agraph, n->id().toUtf8().data(), 1);
0132         n->exportToGraphviz(node);
0133     }
0134 
0135     qCDebug(KGRAPHVIEWERLIB_LOG) << "writing edges";
0136     GraphEdgeMap::const_iterator eit;
0137     for (GraphEdge *e : graph->edges()) {
0138         qCDebug(KGRAPHVIEWERLIB_LOG) << "writing edge" << e->id();
0139         edge_t *edge = agedge(agraph, agnode(agraph, e->fromNode()->id().toUtf8().data(), 0), agnode(agraph, e->toNode()->id().toUtf8().data(), 0), nullptr, 1);
0140         e->exportToGraphviz(edge);
0141     }
0142 
0143     return agraph;
0144 }
0145 
0146 }