gmlfileformat.cpp 5.05 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
    This file is part of Rocs.
    Copyright 2010       Tomaz Canabrava <tomaz.canabrava@gmail.com>
    Copyright 2010       Wagner Reck <wagner.reck@gmail.com>
    Copyright 2012-2014  Andreas Cord-Landwehr <cordlandwehr@kde.org>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
    published by the Free Software Foundation; either version 2 of
    the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
18
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
19
20
21
22
23
24
*/

#include "gmlfileformat.h"
#include "gmlgrammarhelper.h"
#include "gmlgrammar.h"
#include "fileformats/fileformatinterface.h"
25
#include "modifiers/topology.h"
26
27
28
29
30
31
32
33
#include "graphdocument.h"
#include "node.h"
#include "edge.h"
#include <KLocalizedString>
#include <KPluginFactory>
#include <QFile>
#include <QTextStream>
#include <QUrl>
34
#include <QVector>
35
36
37

using namespace GraphTheory;

38
39
40
static QString processEdge(const EdgePtr &e);
static QString processNode(const NodePtr &n);

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
extern GmlParser::GmlGrammarHelper* phelper;

K_PLUGIN_FACTORY_WITH_JSON( FilePluginFactory,
                            "gmlfileformat.json",
                            registerPlugin<GmlFileFormat>();)

GmlFileFormat::GmlFileFormat(QObject *parent, const QList<QVariant>&) :
    FileFormatInterface("rocs_gmlfileformat", parent)
{
}

GmlFileFormat::~GmlFileFormat()
{
}

const QStringList GmlFileFormat::extensions() const
{
    return QStringList()
        << i18n("Graph Markup Language Format (%1)", QString("*.gml"));
}

void GmlFileFormat::readFile()
{
    GraphDocumentPtr document = GraphDocument::create();
    setGraphDocument(document);

    QList < QPair<QString, QString> > edges;
    QFile fileHandle(file().toLocalFile());
    if (!fileHandle.open(QFile::ReadOnly)) {
        setError(CouldNotOpenFile, i18n("Could not open file \"%1\" in read mode: %2", file().toLocalFile(), fileHandle.errorString()));
        document->destroy();
        return;
    }
    QString content = fileHandle.readAll();
    if (!GmlParser::parse(content, document)) { //TODO change interface and pass graph structure
        setError(EncodingProblem, i18n("Could not parse file \"%1\".", file().toLocalFile()));
        document->destroy();
        return;
    }
80
81

    Topology::directedGraphDefaultTopology(document);
82
    setGraphDocument(document);
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
    setError(None);
}

void GmlFileFormat::writeFile(GraphDocumentPtr document)
{
    QFile fileHandle(file().toLocalFile());
    QVariantList subgraphs;
    if (!fileHandle.open(QFile::WriteOnly | QFile::Text)) {
        setError(FileIsReadOnly, i18n("Cannot open file %1 to write document. Error: %2", file().fileName(), fileHandle.errorString()));
        return;
    } else {
        QTextStream out(&fileHandle);
//FIXME uncommented following directed() check since this is moved to subclass
//need to add toggle
//             out << QString("graph [\n directed %1 \n").arg(g->directed()?"1":"0");
        out << QString("id \"%1\" \n").arg("graph"); //TODO support export of name

100
        for(const NodePtr &n : document->nodes()) {
101
102
103
104
105
106
107
108
            out << QString("node [\n id \"%1\" \n").arg(n->dynamicProperty("name").toString());
//                 foreach (QByteArray p, n->dynamicPropertyNames()){
//                    out << p << " " << n->property(p).toString() << "\n";
//                  }
            out << processNode(n);
            out << "]\n";

        }
109
        for (auto const &edge : document->edges()) {
110
111
112
113
            out << "edge [\n";
//                  foreach (QByteArray p, e->dynamicPropertyNames()){
//                    out << p << " " << e->property(p).toString() << "\n";
//                  }
114
            out << processEdge(edge);
115
116
117
118
119
120
121
122
123
124

            out << "]\n";
        }
        out << "]\n";
    }
    setError(None);
    return;
}


125
static QString processEdge(const EdgePtr &e)
126
127
128
129
130
{
    QString edge;
    edge.append(QString("source \"%1\"\n target \"%2\"\n").arg(e->from()->dynamicProperty("name").toString(), e->to()->dynamicProperty("name").toString()));
//     edge.append (QString(" color \"%1\"\n").arg(e->color())); //Problem with comments (both starts by '#')

131
    for(const QString &property : e->dynamicProperties()) {
132
133
134
135
136
137
        edge.append(QString("%1 %2\n").arg(property).arg(e->dynamicProperty(property).toString()));
    }

    return edge;
}

138
static QString processNode(const NodePtr &n)
139
140
141
142
143
{
    QString node;
    node.append(QString("  x %1 \n  y %2 \n").arg(n->x()).arg(n->y()));
//       node.append (QString(" color \"%1\"\n").arg(n->color())); //Problem with comments (both starts by '#')

144
    for(const QString &property : n->dynamicProperties()) {
145
146
147
148
149
150
151
        node.append(QString("%1 %2\n").arg(property).arg(n->dynamicProperty(property).toString()));
    }

    return node;
}

#include "gmlfileformat.moc"