Skip to content

Commit

Permalink
ArsMasiuk#141 merged back
Browse files Browse the repository at this point in the history
  • Loading branch information
ArsMasiuk committed Feb 14, 2021
1 parent 7cc1f11 commit d7a7e3b
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 45 deletions.
7 changes: 7 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
QVGE 0.6.x.Master
-------------------------------------------------------------------------------
Bugfixes:
- #130, #139, #140, #141



QVGE 0.6.2
-------------------------------------------------------------------------------
New features/improvements:
Expand Down
148 changes: 107 additions & 41 deletions src/qvgeio/CFormatPlainDOT.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
This file is a part of
QVGE - Qt Visual Graph Editor
(c) 2016-2020 Ars L. Masiuk ([email protected])
(c) 2016-2021 Ars L. Masiuk ([email protected])
It can be used freely, maintaining the information above.
*/
Expand Down Expand Up @@ -48,36 +48,10 @@ static void fromDotNodeStyle(const QString& style, GraphAttributes& nodeAttr)
}


static QVector<QStringRef> tokenize(const QString& str)
{
QVector<QStringRef> refs;

// split on quotes keeping empties
auto tempRefs = str.splitRef('"', QString::KeepEmptyParts);

// split every even ref on spaces
for (int i = 0; i < tempRefs.count(); i++)
{
if (i & 1)
{
refs << tempRefs.at(i);
}
else
{
auto tempSpaced = tempRefs.at(i).split(' ', QString::SkipEmptyParts);
for (auto ref : tempSpaced)
refs << ref;
}
}

return refs;
}


class QStringRefsConstIterator
{
public:
QStringRefsConstIterator(const QVector<QStringRef>& refs): m_refs(refs)
QStringRefsConstIterator(const QStringList& refs): m_refs(refs)
{
m_pos = (m_refs.size()) ? 0 : -1;
}
Expand Down Expand Up @@ -144,7 +118,7 @@ class QStringRefsConstIterator
{
if (canNext())
{
s = m_refs.at(m_pos++).toString();
s = m_refs.at(m_pos++);
return true;
}

Expand All @@ -163,11 +137,97 @@ class QStringRefsConstIterator
}

private:
const QVector<QStringRef>& m_refs;
const QStringList& m_refs;
int m_pos = -1;
};


// parsing plain dot

static QStringList parseLine(QTextStream &ts)
{
QStringList tokens;

// normal mode
while (!ts.atEnd())
{
QString line = ts.readLine().trimmed();
if (line.isEmpty())
continue;

// add EOL
line += '\0';

int i = 0;

_loop:
// skip to next token
while (line[i].isSpace())
i++;
if (line[i] == '\0')
break;

// check for "
if (line[i] == '"')
{
i++;
QString token;
while (line[i] != '"' && line[i] != '\0')
token += line[i++];
tokens << token;

goto _loop;
}

// check for < + eol
if (line[i] == '<' && line[i+1] == '\0')
{
QString token;
while (!ts.atEnd())
{
QString l = ts.readLine();
QString lt = l.trimmed() + '\0';
if (lt[0] == '>' && (lt[1].isSpace() || lt[1] == '\0'))
{
tokens << token;
line = lt;
i = 1;
goto _loop;
}
else
{
token += l + "\n";
}
}
}

// read normal tokens
QString token;
while (line[i] != '\0' && !line[i].isSpace())
token += line[i++];

tokens << token;
goto _loop;
}

return tokens;
}


static void splitEdgePortIds(QByteArray& nodeId, QByteArray& portId)
{
int index = nodeId.indexOf(':');
if (index <= 0)
{
portId.clear();
return;
}

portId = nodeId.mid(index + 1);
nodeId = nodeId.left(index);
}


// reimp

bool CFormatPlainDOT::load(const QString& fileName, Graph& g, QString* lastError) const
Expand All @@ -185,31 +245,28 @@ bool CFormatPlainDOT::load(const QString& fileName, Graph& g, QString* lastError
}

QTextStream ts(&f);

while (!ts.atEnd())
{
QString line = ts.readLine();
if (line.isEmpty())
continue;

auto refs = tokenize(line);
auto refs = parseLine(ts);
if (refs.first() == "stop")
break;

if (refs.first() == "graph")
{
parseGraph(line, refs, gi);
parseGraph(refs, gi);
continue;
}

if (refs.first() == "node")
{
parseNode(line, refs, gi);
parseNode(refs, gi);
continue;
}

if (refs.first() == "edge")
{
parseEdge(line, refs, gi);
parseEdge(refs, gi);
continue;
}
}
Expand All @@ -229,7 +286,7 @@ bool CFormatPlainDOT::save(const QString& fileName, Graph& g, QString* lastError

// privates

bool CFormatPlainDOT::parseGraph(QString& line, const QVector<QStringRef> &refs, GraphInternal &gi) const
bool CFormatPlainDOT::parseGraph(const QStringList &refs, GraphInternal &gi) const
{
QStringRefsConstIterator rit(refs);
rit.next(); // skip header
Expand All @@ -241,7 +298,7 @@ bool CFormatPlainDOT::parseGraph(QString& line, const QVector<QStringRef> &refs,
}


bool CFormatPlainDOT::parseNode(QString& line, const QVector<QStringRef> &refs, GraphInternal &gi) const
bool CFormatPlainDOT::parseNode(const QStringList &refs, GraphInternal &gi) const
{
QStringRefsConstIterator rit(refs);
rit.next(); // skip header
Expand All @@ -268,6 +325,7 @@ bool CFormatPlainDOT::parseNode(QString& line, const QVector<QStringRef> &refs,
node.attrs["width"] = width * 72.0 * gi.g_scale;
node.attrs["height"] = height * 72.0 * gi.g_scale;

label = label.replace("\\n", "\n");
node.attrs["label"] = label;
node.attrs["shape"] = fromDotNodeShape(shape);
fromDotNodeStyle(style, node.attrs);
Expand All @@ -280,7 +338,7 @@ bool CFormatPlainDOT::parseNode(QString& line, const QVector<QStringRef> &refs,
}


bool CFormatPlainDOT::parseEdge(QString& line, const QVector<QStringRef> &refs, GraphInternal &gi) const
bool CFormatPlainDOT::parseEdge(const QStringList &refs, GraphInternal &gi) const
{
QStringRefsConstIterator rit(refs);
rit.next(); // skip header
Expand Down Expand Up @@ -311,6 +369,8 @@ bool CFormatPlainDOT::parseEdge(QString& line, const QVector<QStringRef> &refs,
{
QString label;
rit.next(label);
label = label.replace("\\n", "\n");

rit.next(x);
rit.next(y);
edge.attrs["label"] = label;
Expand Down Expand Up @@ -339,6 +399,12 @@ bool CFormatPlainDOT::parseEdge(QString& line, const QVector<QStringRef> &refs,
edge.id = edge.startNodeId + "-" + edge.endNodeId;
}


// split ports if any
splitEdgePortIds(edge.startNodeId, edge.startPortId);
splitEdgePortIds(edge.endNodeId, edge.endPortId);


gi.g->edges << edge;

return true;
Expand Down
8 changes: 4 additions & 4 deletions src/qvgeio/CFormatPlainDOT.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
This file is a part of
QVGE - Qt Visual Graph Editor
(c) 2016-2020 Ars L. Masiuk ([email protected])
(c) 2016-2021 Ars L. Masiuk ([email protected])
It can be used freely, maintaining the information above.
*/
Expand All @@ -28,9 +28,9 @@ class CFormatPlainDOT
Graph* g = nullptr;
};

bool parseGraph(QString& line, const QVector<QStringRef>& refs, GraphInternal &gi) const;
bool parseNode(QString& line, const QVector<QStringRef>& refs, GraphInternal &gi) const;
bool parseEdge(QString& line, const QVector<QStringRef>& refs, GraphInternal &gi) const;
bool parseGraph(const QStringList& refs, GraphInternal &gi) const;
bool parseNode(const QStringList& refs, GraphInternal &gi) const;
bool parseEdge(const QStringList& refs, GraphInternal &gi) const;
};


Expand Down

0 comments on commit d7a7e3b

Please sign in to comment.