From 59eee652c5fea36945a4a8ce2936843bd90d0e1b Mon Sep 17 00:00:00 2001 From: Aleks Kissinger Date: Fri, 20 Jul 2018 11:01:34 +0200 Subject: ... --- src/data/edge.cpp | 826 +++++++++++++++++++------------------- src/data/edge.h | 260 ++++++------ src/data/edgestyle.cpp | 262 ++++++------ src/data/edgestyle.h | 112 +++--- src/data/graph.cpp | 546 ++++++++++++------------- src/data/graph.h | 218 +++++----- src/data/graphelementdata.cpp | 410 +++++++++---------- src/data/graphelementdata.h | 178 ++++---- src/data/graphelementproperty.cpp | 154 +++---- src/data/graphelementproperty.h | 116 +++--- src/data/node.cpp | 236 +++++------ src/data/node.h | 144 +++---- src/data/nodestyle.cpp | 214 +++++----- src/data/nodestyle.h | 102 ++--- src/data/style.cpp | 156 +++---- src/data/style.h | 108 ++--- src/data/tikzassembler.cpp | 144 +++---- src/data/tikzassembler.h | 120 +++--- src/data/tikzdocument.cpp | 382 +++++++++--------- src/data/tikzdocument.h | 138 +++---- src/data/tikzlexer.l | 382 +++++++++--------- src/data/tikzparser.y | 568 +++++++++++++------------- src/data/tikzparserdefs.h | 80 ++-- src/data/tikzstyles.cpp | 142 +++---- src/data/tikzstyles.h | 102 ++--- 25 files changed, 3050 insertions(+), 3050 deletions(-) (limited to 'src/data') diff --git a/src/data/edge.cpp b/src/data/edge.cpp index d741c56..8b2a851 100644 --- a/src/data/edge.cpp +++ b/src/data/edge.cpp @@ -1,413 +1,413 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - 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 3 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 - along with this program. If not, see . -*/ - -#include "edge.h" -#include "tikzit.h" -#include "util.h" - -#include -#include - -Edge::Edge(Node *s, Node *t, QObject *parent) : - QObject(parent), _source(s), _target(t) -{ - _data = new GraphElementData(); - _edgeNode = 0; - _dirty = true; - _basicBendMode = true; - _bend = 0; - _inAngle = 0; - _outAngle = 0; - _weight = 0.4f; - _style = noneEdgeStyle; - updateControls(); -} - -Edge::~Edge() -{ - delete _data; - delete _edgeNode; -} - -/*! - * @brief Edge::copy makes a deep copy of an edge. - * @param nodeTable is an optional pointer to a table mapping the old source/target - * node pointers to their new, copied versions. This is used when making a copy of - * an entire (sub)graph. - * @return a copy of the edge - */ -Edge *Edge::copy(QMap *nodeTable) -{ - Edge *e; - if (nodeTable == 0) e = new Edge(_source, _target); - else e = new Edge(nodeTable->value(_source), nodeTable->value(_target)); - e->setData(_data->copy()); - e->setBasicBendMode(_basicBendMode); - e->setBend(_bend); - e->setInAngle(_inAngle); - e->setOutAngle(_outAngle); - e->setWeight(_weight); - e->attachStyle(); - e->updateControls(); - return e; -} - -Node *Edge::source() const -{ - return _source; -} - -Node *Edge::target() const -{ - return _target; -} - -bool Edge::isSelfLoop() -{ - return (_source == _target); -} - -bool Edge::isStraight() -{ - return (_basicBendMode && _bend == 0); -} - -GraphElementData *Edge::data() const -{ - return _data; -} - -void Edge::setData(GraphElementData *data) -{ - delete _data; - _data = data; - setAttributesFromData(); -} - -QString Edge::styleName() const -{ - QString nm = _data->property("style"); - if (nm.isNull()) return "none"; - else return nm; -} - -void Edge::setStyleName(const QString &styleName) -{ - if (!styleName.isNull() && styleName != "none") _data->setProperty("style", styleName); - else _data->unsetProperty("style"); -} - -QString Edge::sourceAnchor() const -{ - return _sourceAnchor; -} - -void Edge::setSourceAnchor(const QString &sourceAnchor) -{ - _sourceAnchor = sourceAnchor; -} - -QString Edge::targetAnchor() const -{ - return _targetAnchor; -} - -void Edge::setTargetAnchor(const QString &targetAnchor) -{ - _targetAnchor = targetAnchor; -} - -Node *Edge::edgeNode() const -{ - return _edgeNode; -} - -void Edge::setEdgeNode(Node *edgeNode) -{ - if (_edgeNode != 0) delete _edgeNode; - _edgeNode = edgeNode; -} - -bool Edge::hasEdgeNode() -{ - return _edgeNode != 0; -} - -void Edge::updateControls() { - //if (_dirty) { - QPointF src = _source->point(); - QPointF targ = _target->point(); - - float dx = (targ.x() - src.x()); - float dy = (targ.y() - src.y()); - - float outAngleR = 0.0f; - float inAngleR = 0.0f; - - if (_basicBendMode) { - float angle = std::atan2(dy, dx); - float bnd = (float)_bend * (M_PI / 180.0f); - outAngleR = angle - bnd; - inAngleR = M_PI + angle + bnd; - _outAngle = outAngleR * (180.f / M_PI); - _inAngle = inAngleR * (180.f / M_PI); - } else { - outAngleR = (float)_outAngle * (M_PI / 180.0f); - inAngleR = (float)_inAngle * (M_PI / 180.0f); - } - - // TODO: calculate head and tail properly, not just for circles - if (_source->style()->isNone()) { - _tail = src; - } else { - _tail = QPointF(src.x() + std::cos(outAngleR) * 0.2, - src.y() + std::sin(outAngleR) * 0.2); - } - - if (_target->style()->isNone()) { - _head = targ; - } else { - _head = QPointF(targ.x() + std::cos(inAngleR) * 0.2, - targ.y() + std::sin(inAngleR) * 0.2); - } - - // give a default distance for self-loops - _cpDist = (dx==0.0f && dy==0.0f) ? _weight : std::sqrt(dx*dx + dy*dy) * _weight; - - _cp1 = QPointF(src.x() + (_cpDist * std::cos(outAngleR)), - src.y() + (_cpDist * std::sin(outAngleR))); - - _cp2 = QPointF(targ.x() + (_cpDist * std::cos(inAngleR)), - targ.y() + (_cpDist * std::sin(inAngleR))); - - _mid = bezierInterpolateFull (0.5f, _tail, _cp1, _cp2, _head); - _tailTangent = bezierTangent(0.0f, 0.1f); - _headTangent = bezierTangent(1.0f, 0.9f); -} - -void Edge::setAttributesFromData() -{ - _basicBendMode = true; - bool ok = true; - - if (_data->atom("bend left")) { - _bend = -30; - } else if (_data->atom("bend right")) { - _bend = 30; - } else if (_data->property("bend left") != 0) { - _bend = -_data->property("bend left").toInt(&ok); - if (!ok) _bend = -30; - } else if (_data->property("bend right") != 0) { - _bend = _data->property("bend right").toInt(&ok); - if (!ok) _bend = 30; - } else { - _bend = 0; - - if (_data->property("in") != 0 && _data->property("out") != 0) { - _basicBendMode = false; - _inAngle = _data->property("in").toInt(&ok); - if (!ok) _inAngle = 0; - _outAngle = _data->property("out").toInt(&ok); - if (!ok) _outAngle = 180; - } - } - - if (_data->property("looseness") != 0) { - _weight = _data->property("looseness").toFloat(&ok) / 2.5f; - if (!ok) _weight = 0.4f; - } else { - _weight = (isSelfLoop()) ? 1.0f : 0.4f; - } - - //qDebug() << "bend: " << _bend << " in: " << _inAngle << " out: " << _outAngle; - _dirty = true; -} - -void Edge::updateData() -{ - _data->unsetAtom("loop"); - _data->unsetProperty("in"); - _data->unsetProperty("out"); - _data->unsetAtom("bend left"); - _data->unsetAtom("bend right"); - _data->unsetProperty("bend left"); - _data->unsetProperty("bend right"); - _data->unsetProperty("looseness"); - - // TODO: style handling? - - if (_basicBendMode) { - if (_bend != 0) { - QString bendKey; - int b; - if (_bend < 0) { - bendKey = "bend left"; - b = -_bend; - } else { - bendKey = "bend right"; - b = _bend; - } - - if (b == 30) { - _data->setAtom(bendKey); - } else { - _data->setProperty(bendKey, QString::number(b)); - } - } - } else { - _data->setProperty("in", QString::number(_inAngle)); - _data->setProperty("out", QString::number(_outAngle)); - } - - if (_source == _target) _data->setAtom("loop"); - if (!isSelfLoop() && !isStraight() && _weight != 0.4f) - _data->setProperty("looseness", QString::number(_weight*2.5f, 'f', 2)); - if (_source->style()->isNone()) _sourceAnchor = "center"; - if (_target->style()->isNone()) _targetAnchor = "center"; - -} - - -QPointF Edge::head() const -{ - return _head; -} - -QPointF Edge::tail() const -{ - return _tail; -} - -QPointF Edge::cp1() const -{ - return _cp1; -} - -QPointF Edge::cp2() const -{ - return _cp2; -} - -int Edge::bend() const -{ - return _bend; -} - -int Edge::inAngle() const -{ - return _inAngle; -} - -int Edge::outAngle() const -{ - return _outAngle; -} - -float Edge::weight() const -{ - return _weight; -} - -bool Edge::basicBendMode() const -{ - return _basicBendMode; -} - -float Edge::cpDist() const -{ - return _cpDist; -} - -void Edge::setBasicBendMode(bool mode) -{ - _basicBendMode = mode; -} - -void Edge::setBend(int bend) -{ - _bend = bend; -} - -void Edge::setInAngle(int inAngle) -{ - _inAngle = inAngle; -} - -void Edge::setOutAngle(int outAngle) -{ - _outAngle = outAngle; -} - -void Edge::setWeight(float weight) -{ - _weight = weight; -} - -int Edge::tikzLine() const -{ - return _tikzLine; -} - -void Edge::setTikzLine(int tikzLine) -{ - _tikzLine = tikzLine; -} - -QPointF Edge::mid() const -{ - return _mid; -} - -QPointF Edge::headTangent() const -{ - return _headTangent; -} - -QPointF Edge::tailTangent() const -{ - return _tailTangent; -} - -void Edge::attachStyle() -{ - QString nm = styleName(); - if (nm.isNull()) _style = noneEdgeStyle; - else _style = tikzit->styles()->edgeStyle(nm); -} - -EdgeStyle * Edge::style() const -{ - return _style; -} - -QPointF Edge::bezierTangent(float start, float end) const -{ - float dx = bezierInterpolate(end, _tail.x(), _cp1.x(), _cp2.x(), _head.x()) - - bezierInterpolate(start, _tail.x(), _cp1.x(), _cp2.x(), _head.x()); - float dy = bezierInterpolate(end, _tail.y(), _cp1.y(), _cp2.y(), _head.y()) - - bezierInterpolate(start, _tail.y(), _cp1.y(), _cp2.y(), _head.y()); - - // normalise - float len = sqrt(dx*dx + dy * dy); - if (len != 0) { - dx = (dx / len) * 0.1f; - dy = (dy / len) * 0.1f; - } - - return QPointF(dx, dy); -} +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + 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 3 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 + along with this program. If not, see . +*/ + +#include "edge.h" +#include "tikzit.h" +#include "util.h" + +#include +#include + +Edge::Edge(Node *s, Node *t, QObject *parent) : + QObject(parent), _source(s), _target(t) +{ + _data = new GraphElementData(); + _edgeNode = 0; + _dirty = true; + _basicBendMode = true; + _bend = 0; + _inAngle = 0; + _outAngle = 0; + _weight = 0.4f; + _style = noneEdgeStyle; + updateControls(); +} + +Edge::~Edge() +{ + delete _data; + delete _edgeNode; +} + +/*! + * @brief Edge::copy makes a deep copy of an edge. + * @param nodeTable is an optional pointer to a table mapping the old source/target + * node pointers to their new, copied versions. This is used when making a copy of + * an entire (sub)graph. + * @return a copy of the edge + */ +Edge *Edge::copy(QMap *nodeTable) +{ + Edge *e; + if (nodeTable == 0) e = new Edge(_source, _target); + else e = new Edge(nodeTable->value(_source), nodeTable->value(_target)); + e->setData(_data->copy()); + e->setBasicBendMode(_basicBendMode); + e->setBend(_bend); + e->setInAngle(_inAngle); + e->setOutAngle(_outAngle); + e->setWeight(_weight); + e->attachStyle(); + e->updateControls(); + return e; +} + +Node *Edge::source() const +{ + return _source; +} + +Node *Edge::target() const +{ + return _target; +} + +bool Edge::isSelfLoop() +{ + return (_source == _target); +} + +bool Edge::isStraight() +{ + return (_basicBendMode && _bend == 0); +} + +GraphElementData *Edge::data() const +{ + return _data; +} + +void Edge::setData(GraphElementData *data) +{ + delete _data; + _data = data; + setAttributesFromData(); +} + +QString Edge::styleName() const +{ + QString nm = _data->property("style"); + if (nm.isNull()) return "none"; + else return nm; +} + +void Edge::setStyleName(const QString &styleName) +{ + if (!styleName.isNull() && styleName != "none") _data->setProperty("style", styleName); + else _data->unsetProperty("style"); +} + +QString Edge::sourceAnchor() const +{ + return _sourceAnchor; +} + +void Edge::setSourceAnchor(const QString &sourceAnchor) +{ + _sourceAnchor = sourceAnchor; +} + +QString Edge::targetAnchor() const +{ + return _targetAnchor; +} + +void Edge::setTargetAnchor(const QString &targetAnchor) +{ + _targetAnchor = targetAnchor; +} + +Node *Edge::edgeNode() const +{ + return _edgeNode; +} + +void Edge::setEdgeNode(Node *edgeNode) +{ + if (_edgeNode != 0) delete _edgeNode; + _edgeNode = edgeNode; +} + +bool Edge::hasEdgeNode() +{ + return _edgeNode != 0; +} + +void Edge::updateControls() { + //if (_dirty) { + QPointF src = _source->point(); + QPointF targ = _target->point(); + + float dx = (targ.x() - src.x()); + float dy = (targ.y() - src.y()); + + float outAngleR = 0.0f; + float inAngleR = 0.0f; + + if (_basicBendMode) { + float angle = std::atan2(dy, dx); + float bnd = (float)_bend * (M_PI / 180.0f); + outAngleR = angle - bnd; + inAngleR = M_PI + angle + bnd; + _outAngle = outAngleR * (180.f / M_PI); + _inAngle = inAngleR * (180.f / M_PI); + } else { + outAngleR = (float)_outAngle * (M_PI / 180.0f); + inAngleR = (float)_inAngle * (M_PI / 180.0f); + } + + // TODO: calculate head and tail properly, not just for circles + if (_source->style()->isNone()) { + _tail = src; + } else { + _tail = QPointF(src.x() + std::cos(outAngleR) * 0.2, + src.y() + std::sin(outAngleR) * 0.2); + } + + if (_target->style()->isNone()) { + _head = targ; + } else { + _head = QPointF(targ.x() + std::cos(inAngleR) * 0.2, + targ.y() + std::sin(inAngleR) * 0.2); + } + + // give a default distance for self-loops + _cpDist = (dx==0.0f && dy==0.0f) ? _weight : std::sqrt(dx*dx + dy*dy) * _weight; + + _cp1 = QPointF(src.x() + (_cpDist * std::cos(outAngleR)), + src.y() + (_cpDist * std::sin(outAngleR))); + + _cp2 = QPointF(targ.x() + (_cpDist * std::cos(inAngleR)), + targ.y() + (_cpDist * std::sin(inAngleR))); + + _mid = bezierInterpolateFull (0.5f, _tail, _cp1, _cp2, _head); + _tailTangent = bezierTangent(0.0f, 0.1f); + _headTangent = bezierTangent(1.0f, 0.9f); +} + +void Edge::setAttributesFromData() +{ + _basicBendMode = true; + bool ok = true; + + if (_data->atom("bend left")) { + _bend = -30; + } else if (_data->atom("bend right")) { + _bend = 30; + } else if (_data->property("bend left") != 0) { + _bend = -_data->property("bend left").toInt(&ok); + if (!ok) _bend = -30; + } else if (_data->property("bend right") != 0) { + _bend = _data->property("bend right").toInt(&ok); + if (!ok) _bend = 30; + } else { + _bend = 0; + + if (_data->property("in") != 0 && _data->property("out") != 0) { + _basicBendMode = false; + _inAngle = _data->property("in").toInt(&ok); + if (!ok) _inAngle = 0; + _outAngle = _data->property("out").toInt(&ok); + if (!ok) _outAngle = 180; + } + } + + if (_data->property("looseness") != 0) { + _weight = _data->property("looseness").toFloat(&ok) / 2.5f; + if (!ok) _weight = 0.4f; + } else { + _weight = (isSelfLoop()) ? 1.0f : 0.4f; + } + + //qDebug() << "bend: " << _bend << " in: " << _inAngle << " out: " << _outAngle; + _dirty = true; +} + +void Edge::updateData() +{ + _data->unsetAtom("loop"); + _data->unsetProperty("in"); + _data->unsetProperty("out"); + _data->unsetAtom("bend left"); + _data->unsetAtom("bend right"); + _data->unsetProperty("bend left"); + _data->unsetProperty("bend right"); + _data->unsetProperty("looseness"); + + // TODO: style handling? + + if (_basicBendMode) { + if (_bend != 0) { + QString bendKey; + int b; + if (_bend < 0) { + bendKey = "bend left"; + b = -_bend; + } else { + bendKey = "bend right"; + b = _bend; + } + + if (b == 30) { + _data->setAtom(bendKey); + } else { + _data->setProperty(bendKey, QString::number(b)); + } + } + } else { + _data->setProperty("in", QString::number(_inAngle)); + _data->setProperty("out", QString::number(_outAngle)); + } + + if (_source == _target) _data->setAtom("loop"); + if (!isSelfLoop() && !isStraight() && _weight != 0.4f) + _data->setProperty("looseness", QString::number(_weight*2.5f, 'f', 2)); + if (_source->style()->isNone()) _sourceAnchor = "center"; + if (_target->style()->isNone()) _targetAnchor = "center"; + +} + + +QPointF Edge::head() const +{ + return _head; +} + +QPointF Edge::tail() const +{ + return _tail; +} + +QPointF Edge::cp1() const +{ + return _cp1; +} + +QPointF Edge::cp2() const +{ + return _cp2; +} + +int Edge::bend() const +{ + return _bend; +} + +int Edge::inAngle() const +{ + return _inAngle; +} + +int Edge::outAngle() const +{ + return _outAngle; +} + +float Edge::weight() const +{ + return _weight; +} + +bool Edge::basicBendMode() const +{ + return _basicBendMode; +} + +float Edge::cpDist() const +{ + return _cpDist; +} + +void Edge::setBasicBendMode(bool mode) +{ + _basicBendMode = mode; +} + +void Edge::setBend(int bend) +{ + _bend = bend; +} + +void Edge::setInAngle(int inAngle) +{ + _inAngle = inAngle; +} + +void Edge::setOutAngle(int outAngle) +{ + _outAngle = outAngle; +} + +void Edge::setWeight(float weight) +{ + _weight = weight; +} + +int Edge::tikzLine() const +{ + return _tikzLine; +} + +void Edge::setTikzLine(int tikzLine) +{ + _tikzLine = tikzLine; +} + +QPointF Edge::mid() const +{ + return _mid; +} + +QPointF Edge::headTangent() const +{ + return _headTangent; +} + +QPointF Edge::tailTangent() const +{ + return _tailTangent; +} + +void Edge::attachStyle() +{ + QString nm = styleName(); + if (nm.isNull()) _style = noneEdgeStyle; + else _style = tikzit->styles()->edgeStyle(nm); +} + +EdgeStyle * Edge::style() const +{ + return _style; +} + +QPointF Edge::bezierTangent(float start, float end) const +{ + float dx = bezierInterpolate(end, _tail.x(), _cp1.x(), _cp2.x(), _head.x()) - + bezierInterpolate(start, _tail.x(), _cp1.x(), _cp2.x(), _head.x()); + float dy = bezierInterpolate(end, _tail.y(), _cp1.y(), _cp2.y(), _head.y()) - + bezierInterpolate(start, _tail.y(), _cp1.y(), _cp2.y(), _head.y()); + + // normalise + float len = sqrt(dx*dx + dy * dy); + if (len != 0) { + dx = (dx / len) * 0.1f; + dy = (dy / len) * 0.1f; + } + + return QPointF(dx, dy); +} diff --git a/src/data/edge.h b/src/data/edge.h index dd09469..85959bb 100644 --- a/src/data/edge.h +++ b/src/data/edge.h @@ -1,130 +1,130 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - 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 3 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 - along with this program. If not, see . -*/ - -#ifndef EDGE_H -#define EDGE_H - -#include "graphelementdata.h" -#include "node.h" -#include "edgestyle.h" - -#include -#include - -class Edge : public QObject -{ - Q_OBJECT -public: - explicit Edge(Node *s, Node *t, QObject *parent = 0); - ~Edge(); - Edge *copy(QMap *nodeTable = 0); - - Node *source() const; - Node *target() const; - - bool isSelfLoop(); - bool isStraight(); - - GraphElementData *data() const; - void setData(GraphElementData *data); - - QString sourceAnchor() const; - void setSourceAnchor(const QString &sourceAnchor); - - QString targetAnchor() const; - void setTargetAnchor(const QString &targetAnchor); - - Node *edgeNode() const; - void setEdgeNode(Node *edgeNode); - bool hasEdgeNode(); - - void updateControls(); - void setAttributesFromData(); - void updateData(); - - QPointF head() const; - QPointF tail() const; - QPointF cp1() const; - QPointF cp2() const; - QPointF mid() const; - QPointF headTangent() const; - QPointF tailTangent() const; - - int bend() const; - int inAngle() const; - int outAngle() const; - float weight() const; - bool basicBendMode() const; - float cpDist() const; - - void setBasicBendMode(bool mode); - void setBend(int bend); - void setInAngle(int inAngle); - void setOutAngle(int outAngle); - void setWeight(float weight); - - int tikzLine() const; - void setTikzLine(int tikzLine); - - - void attachStyle(); - QString styleName() const; - void setStyleName(const QString & styleName); - EdgeStyle *style() const; - -signals: - -public slots: - -private: - QPointF bezierTangent(float start, float end) const; - QString _sourceAnchor; - QString _targetAnchor; - - // owned - Node *_edgeNode; - GraphElementData *_data; - - // referenced - Node *_source; - Node *_target; - - - EdgeStyle *_style; - - bool _dirty; - bool _basicBendMode; - int _bend; - int _inAngle; - int _outAngle; - float _weight; - float _cpDist; - - QPointF _head; - QPointF _tail; - QPointF _cp1; - QPointF _cp2; - QPointF _mid; - - QPointF _headTangent; - QPointF _tailTangent; - - int _tikzLine; -}; - -#endif // EDGE_H +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + 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 3 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 + along with this program. If not, see . +*/ + +#ifndef EDGE_H +#define EDGE_H + +#include "graphelementdata.h" +#include "node.h" +#include "edgestyle.h" + +#include +#include + +class Edge : public QObject +{ + Q_OBJECT +public: + explicit Edge(Node *s, Node *t, QObject *parent = 0); + ~Edge(); + Edge *copy(QMap *nodeTable = 0); + + Node *source() const; + Node *target() const; + + bool isSelfLoop(); + bool isStraight(); + + GraphElementData *data() const; + void setData(GraphElementData *data); + + QString sourceAnchor() const; + void setSourceAnchor(const QString &sourceAnchor); + + QString targetAnchor() const; + void setTargetAnchor(const QString &targetAnchor); + + Node *edgeNode() const; + void setEdgeNode(Node *edgeNode); + bool hasEdgeNode(); + + void updateControls(); + void setAttributesFromData(); + void updateData(); + + QPointF head() const; + QPointF tail() const; + QPointF cp1() const; + QPointF cp2() const; + QPointF mid() const; + QPointF headTangent() const; + QPointF tailTangent() const; + + int bend() const; + int inAngle() const; + int outAngle() const; + float weight() const; + bool basicBendMode() const; + float cpDist() const; + + void setBasicBendMode(bool mode); + void setBend(int bend); + void setInAngle(int inAngle); + void setOutAngle(int outAngle); + void setWeight(float weight); + + int tikzLine() const; + void setTikzLine(int tikzLine); + + + void attachStyle(); + QString styleName() const; + void setStyleName(const QString & styleName); + EdgeStyle *style() const; + +signals: + +public slots: + +private: + QPointF bezierTangent(float start, float end) const; + QString _sourceAnchor; + QString _targetAnchor; + + // owned + Node *_edgeNode; + GraphElementData *_data; + + // referenced + Node *_source; + Node *_target; + + + EdgeStyle *_style; + + bool _dirty; + bool _basicBendMode; + int _bend; + int _inAngle; + int _outAngle; + float _weight; + float _cpDist; + + QPointF _head; + QPointF _tail; + QPointF _cp1; + QPointF _cp2; + QPointF _mid; + + QPointF _headTangent; + QPointF _tailTangent; + + int _tikzLine; +}; + +#endif // EDGE_H diff --git a/src/data/edgestyle.cpp b/src/data/edgestyle.cpp index 079d4f5..275393e 100644 --- a/src/data/edgestyle.cpp +++ b/src/data/edgestyle.cpp @@ -1,131 +1,131 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - 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 3 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 - along with this program. If not, see . -*/ - -#include "edgestyle.h" - -#include -#include - -EdgeStyle *noneEdgeStyle = new EdgeStyle(); - -EdgeStyle::EdgeStyle() : Style() -{ -} - -EdgeStyle::EdgeStyle(QString name, GraphElementData *data) : Style(name, data) -{ -} - -EdgeStyle::ArrowTipStyle EdgeStyle::arrowHead() const -{ - if (_data == 0) return NoTip; - - if (_data->atom("->") || _data->atom("<->") || _data->atom("|->")) return Pointer; - if (_data->atom("-|") || _data->atom("<-|") || _data->atom("|-|")) return Flat; - return NoTip; -} - -EdgeStyle::ArrowTipStyle EdgeStyle::arrowTail() const -{ - if (_data == 0) return NoTip; - if (_data->atom("<-") || _data->atom("<->") || _data->atom("<-|")) return Pointer; - if (_data->atom("|-") || _data->atom("|->") || _data->atom("|-|")) return Flat; - return NoTip; -} - -EdgeStyle::DrawStyle EdgeStyle::drawStyle() const -{ - if (_data == 0) return Solid; - if (_data->atom("dashed")) return Dashed; - if (_data->atom("dotted")) return Dotted; - return Solid; -} - -QPen EdgeStyle::pen() const -{ - QPen p(strokeColor()); - p.setWidthF((float)strokeThickness() * 2.0f); - - QVector pat; - switch (drawStyle()) { - case Dashed: - pat << 3.0 << 3.0; - p.setDashPattern(pat); - break; - case Dotted: - pat << 1.0 << 1.0; - p.setDashPattern(pat); - break; - } - - return p; -} - -QPainterPath EdgeStyle::path() const -{ - return QPainterPath(); -} - -QPainterPath EdgeStyle::palettePath() const -{ - return QPainterPath(); -} - -QIcon EdgeStyle::icon() const -{ - // draw an icon matching the style - QPixmap px(100,100); - px.fill(Qt::transparent); - QPainter painter(&px); - - if (_data == 0) { - QPen pen(Qt::black); - pen.setWidth(3); - } else { - painter.setPen(pen()); - } - - painter.drawLine(10, 50, 90, 50); - - QPen pn = pen(); - pn.setStyle(Qt::SolidLine); - painter.setPen(pn); - - switch (arrowHead()) { - case Pointer: - painter.drawLine(90,50,80,40); - painter.drawLine(90,50,80,60); - break; - case Flat: - painter.drawLine(90,40,90,60); - break; - } - - switch (arrowTail()) { - case Pointer: - painter.drawLine(10,50,20,40); - painter.drawLine(10,50,20,60); - break; - case Flat: - painter.drawLine(10,40,10,60); - break; - } - - - return QIcon(px); -} +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + 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 3 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 + along with this program. If not, see . +*/ + +#include "edgestyle.h" + +#include +#include + +EdgeStyle *noneEdgeStyle = new EdgeStyle(); + +EdgeStyle::EdgeStyle() : Style() +{ +} + +EdgeStyle::EdgeStyle(QString name, GraphElementData *data) : Style(name, data) +{ +} + +EdgeStyle::ArrowTipStyle EdgeStyle::arrowHead() const +{ + if (_data == 0) return NoTip; + + if (_data->atom("->") || _data->atom("<->") || _data->atom("|->")) return Pointer; + if (_data->atom("-|") || _data->atom("<-|") || _data->atom("|-|")) return Flat; + return NoTip; +} + +EdgeStyle::ArrowTipStyle EdgeStyle::arrowTail() const +{ + if (_data == 0) return NoTip; + if (_data->atom("<-") || _data->atom("<->") || _data->atom("<-|")) return Pointer; + if (_data->atom("|-") || _data->atom("|->") || _data->atom("|-|")) return Flat; + return NoTip; +} + +EdgeStyle::DrawStyle EdgeStyle::drawStyle() const +{ + if (_data == 0) return Solid; + if (_data->atom("dashed")) return Dashed; + if (_data->atom("dotted")) return Dotted; + return Solid; +} + +QPen EdgeStyle::pen() const +{ + QPen p(strokeColor()); + p.setWidthF((float)strokeThickness() * 2.0f); + + QVector pat; + switch (drawStyle()) { + case Dashed: + pat << 3.0 << 3.0; + p.setDashPattern(pat); + break; + case Dotted: + pat << 1.0 << 1.0; + p.setDashPattern(pat); + break; + } + + return p; +} + +QPainterPath EdgeStyle::path() const +{ + return QPainterPath(); +} + +QPainterPath EdgeStyle::palettePath() const +{ + return QPainterPath(); +} + +QIcon EdgeStyle::icon() const +{ + // draw an icon matching the style + QPixmap px(100,100); + px.fill(Qt::transparent); + QPainter painter(&px); + + if (_data == 0) { + QPen pen(Qt::black); + pen.setWidth(3); + } else { + painter.setPen(pen()); + } + + painter.drawLine(10, 50, 90, 50); + + QPen pn = pen(); + pn.setStyle(Qt::SolidLine); + painter.setPen(pn); + + switch (arrowHead()) { + case Pointer: + painter.drawLine(90,50,80,40); + painter.drawLine(90,50,80,60); + break; + case Flat: + painter.drawLine(90,40,90,60); + break; + } + + switch (arrowTail()) { + case Pointer: + painter.drawLine(10,50,20,40); + painter.drawLine(10,50,20,60); + break; + case Flat: + painter.drawLine(10,40,10,60); + break; + } + + + return QIcon(px); +} diff --git a/src/data/edgestyle.h b/src/data/edgestyle.h index cf55d06..069545e 100644 --- a/src/data/edgestyle.h +++ b/src/data/edgestyle.h @@ -1,56 +1,56 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - 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 3 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 - along with this program. If not, see . -*/ - -#ifndef EDGESTYLE_H -#define EDGESTYLE_H - -#include "style.h" - -#include -#include -#include -#include -#include - -class EdgeStyle : public Style -{ -public: - EdgeStyle(); - EdgeStyle(QString name, GraphElementData *data); - - enum ArrowTipStyle { - Flat, Pointer, NoTip - }; - - enum DrawStyle { - Solid, Dotted, Dashed - }; - - ArrowTipStyle arrowHead() const; - ArrowTipStyle arrowTail() const; - DrawStyle drawStyle() const; - - QPen pen() const; - QPainterPath path() const override; - QPainterPath palettePath() const override; - QIcon icon() const override; -}; - -extern EdgeStyle *noneEdgeStyle; - -#endif // EDGESTYLE_H +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + 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 3 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 + along with this program. If not, see . +*/ + +#ifndef EDGESTYLE_H +#define EDGESTYLE_H + +#include "style.h" + +#include +#include +#include +#include +#include + +class EdgeStyle : public Style +{ +public: + EdgeStyle(); + EdgeStyle(QString name, GraphElementData *data); + + enum ArrowTipStyle { + Flat, Pointer, NoTip + }; + + enum DrawStyle { + Solid, Dotted, Dashed + }; + + ArrowTipStyle arrowHead() const; + ArrowTipStyle arrowTail() const; + DrawStyle drawStyle() const; + + QPen pen() const; + QPainterPath path() const override; + QPainterPath palettePath() const override; + QIcon icon() const override; +}; + +extern EdgeStyle *noneEdgeStyle; + +#endif // EDGESTYLE_H diff --git a/src/data/graph.cpp b/src/data/graph.cpp index 00b2dce..7ed3e91 100644 --- a/src/data/graph.cpp +++ b/src/data/graph.cpp @@ -1,273 +1,273 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - 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 3 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 - along with this program. If not, see . -*/ - -#include "graph.h" -#include "util.h" - -#include -#include -#include -#include -#include - -Graph::Graph(QObject *parent) : QObject(parent) -{ - _data = new GraphElementData(this); - _bbox = QRectF(0,0,0,0); -} - -Graph::~Graph() -{ -} - -// add a node. The graph claims ownership. -void Graph::addNode(Node *n) { - n->setParent(this); - _nodes << n; -} - -void Graph::addNode(Node *n, int index) -{ - n->setParent(this); - _nodes.insert(index, n); -} - -void Graph::removeNode(Node *n) { - // the node itself is not deleted, as it may still be referenced in an undo command. It will - // be deleted when graph is, via QObject memory management. - _nodes.removeOne(n); -} - - -void Graph::addEdge(Edge *e) -{ - e->setParent(this); - _edges << e; -} - -void Graph::addEdge(Edge *e, int index) -{ - e->setParent(this); - _edges.insert(index, e); -} - -void Graph::removeEdge(Edge *e) -{ - // the edge itself is not deleted, as it may still be referenced in an undo command. It will - // be deleted when graph is, via QObject memory management. - _edges.removeOne(e); -} - -int Graph::maxIntName() -{ - int max = -1; - int i; - bool ok; - foreach (Node *n, _nodes) { - i = n->name().toInt(&ok); - if (ok && i > max) max = i; - } - return max; -} - -QRectF Graph::realBbox() -{ - //float maxX = 0.0f; - QRectF rect = bbox(); - foreach (Node *n, _nodes) { - rect = rect.united(QRectF(n->point().x()-0.5f, - n->point().y()-0.5f, - 1.0f, 1.0f)); - } - - return rect; -} - -QString Graph::freshNodeName() -{ - return QString::number(maxIntName() + 1); -} - -void Graph::renameApart(Graph *graph) -{ - int i = graph->maxIntName() + 1; - foreach (Node *n, _nodes) { - n->setName(QString::number(i)); - i++; - } -} - -GraphElementData *Graph::data() const -{ - return _data; -} - -void Graph::setData(GraphElementData *data) -{ - delete _data; - _data = data; -} - -const QVector &Graph::nodes() -{ - return _nodes; -} - -const QVector &Graph::edges() -{ - return _edges; -} - -QRectF Graph::bbox() const -{ - return _bbox; -} - -bool Graph::hasBbox() { - return !(_bbox == QRectF(0,0,0,0)); -} - -void Graph::clearBbox() { - _bbox = QRectF(0,0,0,0); -} - -QString Graph::tikz() -{ - QString str; - QTextStream code(&str); - int line = 0; - - code << "\\begin{tikzpicture}" << _data->tikz() << "\n"; - line++; - if (hasBbox()) { - code << "\t\\path [use as bounding box] (" - << _bbox.topLeft().x() << "," << _bbox.topLeft().y() - << ") rectangle (" - << _bbox.bottomRight().x() << "," << _bbox.bottomRight().y() - << ");\n"; - line++; - } - - if (!_nodes.isEmpty()) { - code << "\t\\begin{pgfonlayer}{nodelayer}\n"; - line++; - } - - Node *n; - foreach (n, _nodes) { - n->setTikzLine(line); - code << "\t\t\\node "; - - if (!n->data()->isEmpty()) - code << n->data()->tikz() << " "; - - code << "(" << n->name() << ") at (" - << floatToString(n->point().x()) - << ", " - << floatToString(n->point().y()) - << ") {" << n->label() << "};\n"; - line++; - } - - if (!_nodes.isEmpty()) { - code << "\t\\end{pgfonlayer}\n"; - line++; - } - - if (!_edges.isEmpty()) { - code << "\t\\begin{pgfonlayer}{edgelayer}\n"; - line++; - } - - - Edge *e; - foreach (e, _edges) { - e->setTikzLine(line); - e->updateData(); - code << "\t\t\\draw "; - - if (!e->data()->isEmpty()) - code << e->data()->tikz() << " "; - - code << "(" << e->source()->name(); - if (e->sourceAnchor() != "") - code << "." << e->sourceAnchor(); - code << ") to "; - - if (e->hasEdgeNode()) { - code << "node "; - if (!e->edgeNode()->data()->isEmpty()) - code << e->edgeNode()->data()->tikz() << " "; - code << "{" << e->edgeNode()->label() << "} "; - } - - if (e->source() == e->target()) { - code << "()"; - } else { - code << "(" << e->target()->name(); - if (e->targetAnchor() != "") - code << "." << e->targetAnchor(); - code << ")"; - } - - code << ";\n"; - line++; - } - - if (!_edges.isEmpty()) { - code << "\t\\end{pgfonlayer}\n"; - line++; - } - - code << "\\end{tikzpicture}\n"; - line++; - - code.flush(); - return str; -} - -Graph *Graph::copyOfSubgraphWithNodes(QSet nds) -{ - Graph *g = new Graph(); - g->setData(_data->copy()); - QMap nodeTable; - foreach (Node *n, nds) { - Node *n1 = n->copy(); - nodeTable.insert(n, n1); - g->addNode(n1); - } - foreach (Edge *e, edges()) { - if (nds.contains(e->source()) && nds.contains(e->target())) { - g->addEdge(e->copy(&nodeTable)); - } - } - - return g; -} - -void Graph::insertGraph(Graph *graph) -{ - QMap nodeTable; - foreach (Node *n, graph->nodes()) addNode(n); - foreach (Edge *e, graph->edges()) addEdge(e); -} - -void Graph::setBbox(const QRectF &bbox) -{ - _bbox = bbox; -} +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + 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 3 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 + along with this program. If not, see . +*/ + +#include "graph.h" +#include "util.h" + +#include +#include +#include +#include +#include + +Graph::Graph(QObject *parent) : QObject(parent) +{ + _data = new GraphElementData(this); + _bbox = QRectF(0,0,0,0); +} + +Graph::~Graph() +{ +} + +// add a node. The graph claims ownership. +void Graph::addNode(Node *n) { + n->setParent(this); + _nodes << n; +} + +void Graph::addNode(Node *n, int index) +{ + n->setParent(this); + _nodes.insert(index, n); +} + +void Graph::removeNode(Node *n) { + // the node itself is not deleted, as it may still be referenced in an undo command. It will + // be deleted when graph is, via QObject memory management. + _nodes.removeOne(n); +} + + +void Graph::addEdge(Edge *e) +{ + e->setParent(this); + _edges << e; +} + +void Graph::addEdge(Edge *e, int index) +{ + e->setParent(this); + _edges.insert(index, e); +} + +void Graph::removeEdge(Edge *e) +{ + // the edge itself is not deleted, as it may still be referenced in an undo command. It will + // be deleted when graph is, via QObject memory management. + _edges.removeOne(e); +} + +int Graph::maxIntName() +{ + int max = -1; + int i; + bool ok; + foreach (Node *n, _nodes) { + i = n->name().toInt(&ok); + if (ok && i > max) max = i; + } + return max; +} + +QRectF Graph::realBbox() +{ + //float maxX = 0.0f; + QRectF rect = bbox(); + foreach (Node *n, _nodes) { + rect = rect.united(QRectF(n->point().x()-0.5f, + n->point().y()-0.5f, + 1.0f, 1.0f)); + } + + return rect; +} + +QString Graph::freshNodeName() +{ + return QString::number(maxIntName() + 1); +} + +void Graph::renameApart(Graph *graph) +{ + int i = graph->maxIntName() + 1; + foreach (Node *n, _nodes) { + n->setName(QString::number(i)); + i++; + } +} + +GraphElementData *Graph::data() const +{ + return _data; +} + +void Graph::setData(GraphElementData *data) +{ + delete _data; + _data = data; +} + +const QVector &Graph::nodes() +{ + return _nodes; +} + +const QVector &Graph::edges() +{ + return _edges; +} + +QRectF Graph::bbox() const +{ + return _bbox; +} + +bool Graph::hasBbox() { + return !(_bbox == QRectF(0,0,0,0)); +} + +void Graph::clearBbox() { + _bbox = QRectF(0,0,0,0); +} + +QString Graph::tikz() +{ + QString str; + QTextStream code(&str); + int line = 0; + + code << "\\begin{tikzpicture}" << _data->tikz() << "\n"; + line++; + if (hasBbox()) { + code << "\t\\path [use as bounding box] (" + << _bbox.topLeft().x() << "," << _bbox.topLeft().y() + << ") rectangle (" + << _bbox.bottomRight().x() << "," << _bbox.bottomRight().y() + << ");\n"; + line++; + } + + if (!_nodes.isEmpty()) { + code << "\t\\begin{pgfonlayer}{nodelayer}\n"; + line++; + } + + Node *n; + foreach (n, _nodes) { + n->setTikzLine(line); + code << "\t\t\\node "; + + if (!n->data()->isEmpty()) + code << n->data()->tikz() << " "; + + code << "(" << n->name() << ") at (" + << floatToString(n->point().x()) + << ", " + << floatToString(n->point().y()) + << ") {" << n->label() << "};\n"; + line++; + } + + if (!_nodes.isEmpty()) { + code << "\t\\end{pgfonlayer}\n"; + line++; + } + + if (!_edges.isEmpty()) { + code << "\t\\begin{pgfonlayer}{edgelayer}\n"; + line++; + } + + + Edge *e; + foreach (e, _edges) { + e->setTikzLine(line); + e->updateData(); + code << "\t\t\\draw "; + + if (!e->data()->isEmpty()) + code << e->data()->tikz() << " "; + + code << "(" << e->source()->name(); + if (e->sourceAnchor() != "") + code << "." << e->sourceAnchor(); + code << ") to "; + + if (e->hasEdgeNode()) { + code << "node "; + if (!e->edgeNode()->data()->isEmpty()) + code << e->edgeNode()->data()->tikz() << " "; + code << "{" << e->edgeNode()->label() << "} "; + } + + if (e->source() == e->target()) { + code << "()"; + } else { + code << "(" << e->target()->name(); + if (e->targetAnchor() != "") + code << "." << e->targetAnchor(); + code << ")"; + } + + code << ";\n"; + line++; + } + + if (!_edges.isEmpty()) { + code << "\t\\end{pgfonlayer}\n"; + line++; + } + + code << "\\end{tikzpicture}\n"; + line++; + + code.flush(); + return str; +} + +Graph *Graph::copyOfSubgraphWithNodes(QSet nds) +{ + Graph *g = new Graph(); + g->setData(_data->copy()); + QMap nodeTable; + foreach (Node *n, nds) { + Node *n1 = n->copy(); + nodeTable.insert(n, n1); + g->addNode(n1); + } + foreach (Edge *e, edges()) { + if (nds.contains(e->source()) && nds.contains(e->target())) { + g->addEdge(e->copy(&nodeTable)); + } + } + + return g; +} + +void Graph::insertGraph(Graph *graph) +{ + QMap nodeTable; + foreach (Node *n, graph->nodes()) addNode(n); + foreach (Edge *e, graph->edges()) addEdge(e); +} + +void Graph::setBbox(const QRectF &bbox) +{ + _bbox = bbox; +} diff --git a/src/data/graph.h b/src/data/graph.h index 77af253..82e1f95 100644 --- a/src/data/graph.h +++ b/src/data/graph.h @@ -1,109 +1,109 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - 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 3 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 - along with this program. If not, see . -*/ - -/*! - * A graph defined by tikz code. - */ - -#ifndef GRAPH_H -#define GRAPH_H - -#include "node.h" -#include "edge.h" -#include "graphelementdata.h" - -#include -#include -#include -#include -#include - -class Graph : public QObject -{ - Q_OBJECT -public: - explicit Graph(QObject *parent = 0); - ~Graph(); - void addNode(Node *n); - void addNode(Node *n, int index); - void removeNode(Node *n); - void addEdge(Edge *e); - void addEdge(Edge *e, int index); - void removeEdge(Edge *e); - int maxIntName(); - QString freshNodeName(); - - /*! - * \brief renameApart assigns fresh names to all of the nodes in "this", - * with respect to the given graph - * \param graph - */ - void renameApart(Graph *graph); - - GraphElementData *data() const; - void setData(GraphElementData *data); - - const QVector &nodes(); - const QVector &edges(); - - QRectF bbox() const; - void setBbox(const QRectF &bbox); - bool hasBbox(); - void clearBbox(); - - /*! - * \brief realBbox computes the union of the user-defined - * bounding box, and the bounding boxes of the graph's - * contents. - * - * \return - */ - QRectF realBbox(); - - QString tikz(); - - /*! - * \brief copyOfSubgraphWithNodes produces a copy of the full subgraph - * with the given nodes. Used for cutting and copying to clipboard. - * \param nds - * \return - */ - Graph *copyOfSubgraphWithNodes(QSet nds); - - /*! - * \brief insertGraph inserts the given graph into "this". Prior to calling this - * method, the node names in the given graph should be made fresh via - * "renameApart". Note that the parameter "graph" relinquishes ownership of its - * nodes and edges, so it should be not be allowed to exist longer than "this". - * \param graph - */ - void insertGraph(Graph *graph); -signals: - -public slots: - -private: - QVector _nodes; - QVector _edges; - //QMultiHash inEdges; - //QMultiHash outEdges; - GraphElementData *_data; - QRectF _bbox; -}; - -#endif // GRAPH_H +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + 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 3 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 + along with this program. If not, see . +*/ + +/*! + * A graph defined by tikz code. + */ + +#ifndef GRAPH_H +#define GRAPH_H + +#include "node.h" +#include "edge.h" +#include "graphelementdata.h" + +#include +#include +#include +#include +#include + +class Graph : public QObject +{ + Q_OBJECT +public: + explicit Graph(QObject *parent = 0); + ~Graph(); + void addNode(Node *n); + void addNode(Node *n, int index); + void removeNode(Node *n); + void addEdge(Edge *e); + void addEdge(Edge *e, int index); + void removeEdge(Edge *e); + int maxIntName(); + QString freshNodeName(); + + /*! + * \brief renameApart assigns fresh names to all of the nodes in "this", + * with respect to the given graph + * \param graph + */ + void renameApart(Graph *graph); + + GraphElementData *data() const; + void setData(GraphElementData *data); + + const QVector &nodes(); + const QVector &edges(); + + QRectF bbox() const; + void setBbox(const QRectF &bbox); + bool hasBbox(); + void clearBbox(); + + /*! + * \brief realBbox computes the union of the user-defined + * bounding box, and the bounding boxes of the graph's + * contents. + * + * \return + */ + QRectF realBbox(); + + QString tikz(); + + /*! + * \brief copyOfSubgraphWithNodes produces a copy of the full subgraph + * with the given nodes. Used for cutting and copying to clipboard. + * \param nds + * \return + */ + Graph *copyOfSubgraphWithNodes(QSet nds); + + /*! + * \brief insertGraph inserts the given graph into "this". Prior to calling this + * method, the node names in the given graph should be made fresh via + * "renameApart". Note that the parameter "graph" relinquishes ownership of its + * nodes and edges, so it should be not be allowed to exist longer than "this". + * \param graph + */ + void insertGraph(Graph *graph); +signals: + +public slots: + +private: + QVector _nodes; + QVector _edges; + //QMultiHash inEdges; + //QMultiHash outEdges; + GraphElementData *_data; + QRectF _bbox; +}; + +#endif // GRAPH_H diff --git a/src/data/graphelementdata.cpp b/src/data/graphelementdata.cpp index 5b35f63..fcd90ea 100644 --- a/src/data/graphelementdata.cpp +++ b/src/data/graphelementdata.cpp @@ -1,205 +1,205 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - 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 3 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 - along with this program. If not, see . -*/ - -#include "graphelementdata.h" - -#include -#include - -GraphElementData::GraphElementData(QVector init, QObject *parent) : QAbstractItemModel(parent) -{ - root = new GraphElementProperty(); - _properties = init; -} - -GraphElementData::GraphElementData(QObject *parent) : QAbstractItemModel(parent) { - root = new GraphElementProperty(); -} - -GraphElementData::~GraphElementData() -{ - delete root; -} - -GraphElementData *GraphElementData::copy() -{ - return new GraphElementData(_properties); -} - -void GraphElementData::setProperty(QString key, QString value) -{ - GraphElementProperty m(key, true); - int i = _properties.indexOf(m); - if (i != -1) { - _properties[i].setValue(value); - } else { - GraphElementProperty p(key, value); - _properties << p; - } -} - -void GraphElementData::unsetProperty(QString key) -{ - GraphElementProperty m(key, true); - int i = _properties.indexOf(m); - if (i != -1) - _properties.remove(i); -} - -void GraphElementData::add(GraphElementProperty p) -{ - _properties << p; -} - -void GraphElementData::operator <<(GraphElementProperty p) -{ - add(p); -} - -void GraphElementData::setAtom(QString atom) -{ - GraphElementProperty a(atom); - int i = _properties.indexOf(a); - if (i == -1) - _properties << a; -} - -void GraphElementData::unsetAtom(QString atom) -{ - GraphElementProperty a(atom); - int i = _properties.indexOf(a); - if (i != -1) - _properties.remove(i); -} - -QString GraphElementData::property(QString key) -{ - GraphElementProperty m(key, true); - int i = _properties.indexOf(m); - if (i != -1) { - return _properties[i].value(); - } else { - return QString(); // null QString - } -} - -bool GraphElementData::atom(QString atom) -{ - GraphElementProperty a(atom); - return (_properties.indexOf(a) != -1); -} - -QVariant GraphElementData::data(const QModelIndex &index, int role) const -{ - if (role != Qt::DisplayRole) - return QVariant(); - - if (index.row() >= 0 && index.row() < _properties.length()) { - const GraphElementProperty &p = _properties[index.row()]; - QString s = (index.column() == 0) ? p.key() : p.value(); - return QVariant(s); - } - - return QVariant(); -} - -QVariant GraphElementData::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { - if (section == 0) return QVariant("Key/Atom"); - else return QVariant("Value"); - } - - return QVariant(); -} - -QModelIndex GraphElementData::index(int row, int column, const QModelIndex &parent) const -{ - return createIndex(row, column, (void*)0); -} - -QModelIndex GraphElementData::parent(const QModelIndex &index) const -{ - GraphElementProperty *p = static_cast(index.internalPointer()); - if (p == root) return QModelIndex(); - else return createIndex(0,0,static_cast(root)); -} - -int GraphElementData::rowCount(const QModelIndex &parent) const -{ - if (parent.isValid()) { - return 0; - } else { - return _properties.size(); - } -} - -int GraphElementData::columnCount(const QModelIndex &) const -{ - return 2; -} - -Qt::ItemFlags GraphElementData::flags(const QModelIndex &index) const -{ - return QAbstractItemModel::flags(index); -} - -//bool GraphElementData::setData(const QModelIndex &index, const QVariant &value, int role) -//{ - -//} - -//bool GraphElementData::insertRows(int position, int rows, const QModelIndex &parent) -//{ - -//} - -//bool GraphElementData::removeRows(int position, int rows, const QModelIndex &parent) -//{ - -//} - -QString GraphElementData::tikz() { - if (_properties.length() == 0) return ""; - QString str; - QTextStream code(&str); - code << "["; - - GraphElementProperty p; - bool first = true; - foreach(p, _properties) { - if (!first) code << ", "; - code << p.tikz(); - first = false; - } - - code << "]"; - - code.flush(); - return str; -} - -bool GraphElementData::isEmpty() -{ - return _properties.isEmpty(); -} - -QVector GraphElementData::properties() const -{ - return _properties; -} +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + 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 3 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 + along with this program. If not, see . +*/ + +#include "graphelementdata.h" + +#include +#include + +GraphElementData::GraphElementData(QVector init, QObject *parent) : QAbstractItemModel(parent) +{ + root = new GraphElementProperty(); + _properties = init; +} + +GraphElementData::GraphElementData(QObject *parent) : QAbstractItemModel(parent) { + root = new GraphElementProperty(); +} + +GraphElementData::~GraphElementData() +{ + delete root; +} + +GraphElementData *GraphElementData::copy() +{ + return new GraphElementData(_properties); +} + +void GraphElementData::setProperty(QString key, QString value) +{ + GraphElementProperty m(key, true); + int i = _properties.indexOf(m); + if (i != -1) { + _properties[i].setValue(value); + } else { + GraphElementProperty p(key, value); + _properties << p; + } +} + +void GraphElementData::unsetProperty(QString key) +{ + GraphElementProperty m(key, true); + int i = _properties.indexOf(m); + if (i != -1) + _properties.remove(i); +} + +void GraphElementData::add(GraphElementProperty p) +{ + _properties << p; +} + +void GraphElementData::operator <<(GraphElementProperty p) +{ + add(p); +} + +void GraphElementData::setAtom(QString atom) +{ + GraphElementProperty a(atom); + int i = _properties.indexOf(a); + if (i == -1) + _properties << a; +} + +void GraphElementData::unsetAtom(QString atom) +{ + GraphElementProperty a(atom); + int i = _properties.indexOf(a); + if (i != -1) + _properties.remove(i); +} + +QString GraphElementData::property(QString key) +{ + GraphElementProperty m(key, true); + int i = _properties.indexOf(m); + if (i != -1) { + return _properties[i].value(); + } else { + return QString(); // null QString + } +} + +bool GraphElementData::atom(QString atom) +{ + GraphElementProperty a(atom); + return (_properties.indexOf(a) != -1); +} + +QVariant GraphElementData::data(const QModelIndex &index, int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + if (index.row() >= 0 && index.row() < _properties.length()) { + const GraphElementProperty &p = _properties[index.row()]; + QString s = (index.column() == 0) ? p.key() : p.value(); + return QVariant(s); + } + + return QVariant(); +} + +QVariant GraphElementData::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { + if (section == 0) return QVariant("Key/Atom"); + else return QVariant("Value"); + } + + return QVariant(); +} + +QModelIndex GraphElementData::index(int row, int column, const QModelIndex &parent) const +{ + return createIndex(row, column, (void*)0); +} + +QModelIndex GraphElementData::parent(const QModelIndex &index) const +{ + GraphElementProperty *p = static_cast(index.internalPointer()); + if (p == root) return QModelIndex(); + else return createIndex(0,0,static_cast(root)); +} + +int GraphElementData::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) { + return 0; + } else { + return _properties.size(); + } +} + +int GraphElementData::columnCount(const QModelIndex &) const +{ + return 2; +} + +Qt::ItemFlags GraphElementData::flags(const QModelIndex &index) const +{ + return QAbstractItemModel::flags(index); +} + +//bool GraphElementData::setData(const QModelIndex &index, const QVariant &value, int role) +//{ + +//} + +//bool GraphElementData::insertRows(int position, int rows, const QModelIndex &parent) +//{ + +//} + +//bool GraphElementData::removeRows(int position, int rows, const QModelIndex &parent) +//{ + +//} + +QString GraphElementData::tikz() { + if (_properties.length() == 0) return ""; + QString str; + QTextStream code(&str); + code << "["; + + GraphElementProperty p; + bool first = true; + foreach(p, _properties) { + if (!first) code << ", "; + code << p.tikz(); + first = false; + } + + code << "]"; + + code.flush(); + return str; +} + +bool GraphElementData::isEmpty() +{ + return _properties.isEmpty(); +} + +QVector GraphElementData::properties() const +{ + return _properties; +} diff --git a/src/data/graphelementdata.h b/src/data/graphelementdata.h index 58e57a0..2b27384 100644 --- a/src/data/graphelementdata.h +++ b/src/data/graphelementdata.h @@ -1,89 +1,89 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - 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 3 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 - along with this program. If not, see . -*/ - -#ifndef GRAPHELEMENTDATA_H -#define GRAPHELEMENTDATA_H - -#include "graphelementproperty.h" - -#include -#include -#include -#include -#include - -class GraphElementData : public QAbstractItemModel -{ - Q_OBJECT -public: - explicit GraphElementData(QVector init, - QObject *parent = 0); - explicit GraphElementData(QObject *parent = 0); - ~GraphElementData(); - GraphElementData *copy(); - void setProperty(QString key, QString value); - void unsetProperty(QString key); - void setAtom(QString atom); - void unsetAtom(QString atom); - QString property(QString key); - bool atom(QString atom); - - QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE; - QVariant headerData(int section, Qt::Orientation orientation, - int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; - - QModelIndex index(int row, int column, - const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; - QModelIndex parent(const QModelIndex &index) const Q_DECL_OVERRIDE; - - int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; - int columnCount(const QModelIndex &) const Q_DECL_OVERRIDE; - - Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE; - -// bool setData(const QModelIndex &index, const QVariant &value, -// int role = Qt::EditRole) Q_DECL_OVERRIDE; -// bool setHeaderData(int section, Qt::Orientation orientation, -// const QVariant &value, int role = Qt::EditRole) Q_DECL_OVERRIDE; - -// bool insertColumns(int position, int columns, -// const QModelIndex &parent = QModelIndex()) Q_DECL_OVERRIDE; -// bool removeColumns(int position, int columns, -// const QModelIndex &parent = QModelIndex()) Q_DECL_OVERRIDE; -// bool insertRows(int position, int rows, -// const QModelIndex &parent = QModelIndex()) Q_DECL_OVERRIDE; -// bool removeRows(int position, int rows, -// const QModelIndex &parent = QModelIndex()) Q_DECL_OVERRIDE; - - void operator <<(GraphElementProperty p); - void add(GraphElementProperty p); - - QString tikz(); - bool isEmpty(); - QVector properties() const; - -signals: - -public slots: - -private: - QVector _properties; - GraphElementProperty *root; -}; - -#endif // GRAPHELEMENTDATA_H +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + 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 3 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 + along with this program. If not, see . +*/ + +#ifndef GRAPHELEMENTDATA_H +#define GRAPHELEMENTDATA_H + +#include "graphelementproperty.h" + +#include +#include +#include +#include +#include + +class GraphElementData : public QAbstractItemModel +{ + Q_OBJECT +public: + explicit GraphElementData(QVector init, + QObject *parent = 0); + explicit GraphElementData(QObject *parent = 0); + ~GraphElementData(); + GraphElementData *copy(); + void setProperty(QString key, QString value); + void unsetProperty(QString key); + void setAtom(QString atom); + void unsetAtom(QString atom); + QString property(QString key); + bool atom(QString atom); + + QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const Q_DECL_OVERRIDE; + + QModelIndex index(int row, int column, + const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; + QModelIndex parent(const QModelIndex &index) const Q_DECL_OVERRIDE; + + int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE; + int columnCount(const QModelIndex &) const Q_DECL_OVERRIDE; + + Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE; + +// bool setData(const QModelIndex &index, const QVariant &value, +// int role = Qt::EditRole) Q_DECL_OVERRIDE; +// bool setHeaderData(int section, Qt::Orientation orientation, +// const QVariant &value, int role = Qt::EditRole) Q_DECL_OVERRIDE; + +// bool insertColumns(int position, int columns, +// const QModelIndex &parent = QModelIndex()) Q_DECL_OVERRIDE; +// bool removeColumns(int position, int columns, +// const QModelIndex &parent = QModelIndex()) Q_DECL_OVERRIDE; +// bool insertRows(int position, int rows, +// const QModelIndex &parent = QModelIndex()) Q_DECL_OVERRIDE; +// bool removeRows(int position, int rows, +// const QModelIndex &parent = QModelIndex()) Q_DECL_OVERRIDE; + + void operator <<(GraphElementProperty p); + void add(GraphElementProperty p); + + QString tikz(); + bool isEmpty(); + QVector properties() const; + +signals: + +public slots: + +private: + QVector _properties; + GraphElementProperty *root; +}; + +#endif // GRAPHELEMENTDATA_H diff --git a/src/data/graphelementproperty.cpp b/src/data/graphelementproperty.cpp index 0717952..79a8280 100644 --- a/src/data/graphelementproperty.cpp +++ b/src/data/graphelementproperty.cpp @@ -1,77 +1,77 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - 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 3 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 - along with this program. If not, see . -*/ - -#include "graphelementproperty.h" - -#include - -GraphElementProperty::GraphElementProperty (): - _key(""), _value(""), _atom(false), _keyMatch(false) -{} - -GraphElementProperty::GraphElementProperty(QString key, QString value, bool atom, bool keyMatch) : - _key(key), _value(value), _atom(atom), _keyMatch(keyMatch) -{} - -GraphElementProperty::GraphElementProperty(QString key, QString value) : - _key(key), _value(value), _atom(false), _keyMatch(false) -{} - -GraphElementProperty::GraphElementProperty(QString key, bool keyMatch) : - _key(key), _value(""), _atom(!keyMatch), _keyMatch(keyMatch) -{} - -QString GraphElementProperty::key() const -{ return _key; } - -QString GraphElementProperty::value() const -{ return _value; } - -void GraphElementProperty::setValue(const QString &value) -{ _value = value; } - -bool GraphElementProperty::atom() const -{ return _atom; } - -bool GraphElementProperty::keyMatch() const -{ return _keyMatch; } - -bool GraphElementProperty::matches(const GraphElementProperty &p) -{ - if (p.atom()) return _atom && _key == p.key(); - if (p.keyMatch()) return !_atom && _key == p.key(); - if (_keyMatch) return !p.atom() && _key == p.key(); - return !_atom && _key == p.key() && _value == p.value(); -} - -bool GraphElementProperty::operator==(const GraphElementProperty &p) -{ - return matches(p); -} - -QString GraphElementProperty::tikzEscape(QString str) -{ - QRegExp re("[0-9a-zA-Z<> \\-'.]*"); - if (re.exactMatch(str)) return str; - else return "{" + str + "}"; -} - -QString GraphElementProperty::tikz() { - if (_atom) return tikzEscape(_key); - return tikzEscape(_key) + "=" + tikzEscape(_value); -} +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + 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 3 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 + along with this program. If not, see . +*/ + +#include "graphelementproperty.h" + +#include + +GraphElementProperty::GraphElementProperty (): + _key(""), _value(""), _atom(false), _keyMatch(false) +{} + +GraphElementProperty::GraphElementProperty(QString key, QString value, bool atom, bool keyMatch) : + _key(key), _value(value), _atom(atom), _keyMatch(keyMatch) +{} + +GraphElementProperty::GraphElementProperty(QString key, QString value) : + _key(key), _value(value), _atom(false), _keyMatch(false) +{} + +GraphElementProperty::GraphElementProperty(QString key, bool keyMatch) : + _key(key), _value(""), _atom(!keyMatch), _keyMatch(keyMatch) +{} + +QString GraphElementProperty::key() const +{ return _key; } + +QString GraphElementProperty::value() const +{ return _value; } + +void GraphElementProperty::setValue(const QString &value) +{ _value = value; } + +bool GraphElementProperty::atom() const +{ return _atom; } + +bool GraphElementProperty::keyMatch() const +{ return _keyMatch; } + +bool GraphElementProperty::matches(const GraphElementProperty &p) +{ + if (p.atom()) return _atom && _key == p.key(); + if (p.keyMatch()) return !_atom && _key == p.key(); + if (_keyMatch) return !p.atom() && _key == p.key(); + return !_atom && _key == p.key() && _value == p.value(); +} + +bool GraphElementProperty::operator==(const GraphElementProperty &p) +{ + return matches(p); +} + +QString GraphElementProperty::tikzEscape(QString str) +{ + QRegExp re("[0-9a-zA-Z<> \\-'.]*"); + if (re.exactMatch(str)) return str; + else return "{" + str + "}"; +} + +QString GraphElementProperty::tikz() { + if (_atom) return tikzEscape(_key); + return tikzEscape(_key) + "=" + tikzEscape(_value); +} diff --git a/src/data/graphelementproperty.h b/src/data/graphelementproperty.h index d37f69e..af4ae91 100644 --- a/src/data/graphelementproperty.h +++ b/src/data/graphelementproperty.h @@ -1,58 +1,58 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - 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 3 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 - along with this program. If not, see . -*/ - -#ifndef GRAPHELEMENTPROPERTY_H -#define GRAPHELEMENTPROPERTY_H - -#include - -class GraphElementProperty -{ -public: - GraphElementProperty(); - GraphElementProperty(QString key, QString value, bool atom, bool keyMatch); - - // construct a property - GraphElementProperty(QString key, QString value); - - // construct an atom or keymatch - GraphElementProperty(QString key, bool keyMatch = false); - - QString key() const; - QString value() const; - void setValue(const QString &value); - bool atom() const; - bool keyMatch() const; - - bool matches(const GraphElementProperty &p); - bool operator==(const GraphElementProperty &p); - - static QString tikzEscape(QString str); - QString tikz(); -signals: - -public slots: - -private: - QString _key; - QString _value; - bool _atom; - bool _keyMatch; -}; - -#endif // GRAPHELEMENTPROPERTY_H +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + 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 3 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 + along with this program. If not, see . +*/ + +#ifndef GRAPHELEMENTPROPERTY_H +#define GRAPHELEMENTPROPERTY_H + +#include + +class GraphElementProperty +{ +public: + GraphElementProperty(); + GraphElementProperty(QString key, QString value, bool atom, bool keyMatch); + + // construct a property + GraphElementProperty(QString key, QString value); + + // construct an atom or keymatch + GraphElementProperty(QString key, bool keyMatch = false); + + QString key() const; + QString value() const; + void setValue(const QString &value); + bool atom() const; + bool keyMatch() const; + + bool matches(const GraphElementProperty &p); + bool operator==(const GraphElementProperty &p); + + static QString tikzEscape(QString str); + QString tikz(); +signals: + +public slots: + +private: + QString _key; + QString _value; + bool _atom; + bool _keyMatch; +}; + +#endif // GRAPHELEMENTPROPERTY_H diff --git a/src/data/node.cpp b/src/data/node.cpp index ce4286f..44e3c77 100644 --- a/src/data/node.cpp +++ b/src/data/node.cpp @@ -1,118 +1,118 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - 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 3 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 - along with this program. If not, see . -*/ - -#include "node.h" -#include "tikzit.h" - -#include - -Node::Node(QObject *parent) : QObject(parent), _tikzLine(-1) -{ - _data = new GraphElementData(); - _style = noneStyle; - _data->setProperty("style", "none"); -} - -Node::~Node() -{ - delete _data; -} - -Node *Node::copy() { - Node *n1 = new Node(); - n1->setName(name()); - n1->setData(data()->copy()); - n1->setPoint(point()); - n1->setLabel(label()); - n1->attachStyle(); - n1->setTikzLine(tikzLine()); - return n1; -} - -QPointF Node::point() const -{ - return _point; -} - -void Node::setPoint(const QPointF &point) -{ - _point = point; -} - -QString Node::name() const -{ - return _name; -} - -void Node::setName(const QString &name) -{ - _name = name; -} - -QString Node::label() const -{ - return _label; -} - -void Node::setLabel(const QString &label) -{ - _label = label; -} - -GraphElementData *Node::data() const -{ - return _data; -} - -void Node::setData(GraphElementData *data) -{ - delete _data; - _data = data; -} - -QString Node::styleName() const -{ - return _data->property("style"); -} - -void Node::setStyleName(const QString &styleName) -{ - _data->setProperty("style", styleName); -} - -void Node::attachStyle() -{ - QString nm = styleName(); - if (nm == "none") _style = noneStyle; - else _style = tikzit->styles()->nodeStyle(nm); -} - -NodeStyle *Node::style() const -{ - return _style; -} - -int Node::tikzLine() const -{ - return _tikzLine; -} - -void Node::setTikzLine(int tikzLine) -{ - _tikzLine = tikzLine; -} +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + 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 3 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 + along with this program. If not, see . +*/ + +#include "node.h" +#include "tikzit.h" + +#include + +Node::Node(QObject *parent) : QObject(parent), _tikzLine(-1) +{ + _data = new GraphElementData(); + _style = noneStyle; + _data->setProperty("style", "none"); +} + +Node::~Node() +{ + delete _data; +} + +Node *Node::copy() { + Node *n1 = new Node(); + n1->setName(name()); + n1->setData(data()->copy()); + n1->setPoint(point()); + n1->setLabel(label()); + n1->attachStyle(); + n1->setTikzLine(tikzLine()); + return n1; +} + +QPointF Node::point() const +{ + return _point; +} + +void Node::setPoint(const QPointF &point) +{ + _point = point; +} + +QString Node::name() const +{ + return _name; +} + +void Node::setName(const QString &name) +{ + _name = name; +} + +QString Node::label() const +{ + return _label; +} + +void Node::setLabel(const QString &label) +{ + _label = label; +} + +GraphElementData *Node::data() const +{ + return _data; +} + +void Node::setData(GraphElementData *data) +{ + delete _data; + _data = data; +} + +QString Node::styleName() const +{ + return _data->property("style"); +} + +void Node::setStyleName(const QString &styleName) +{ + _data->setProperty("style", styleName); +} + +void Node::attachStyle() +{ + QString nm = styleName(); + if (nm == "none") _style = noneStyle; + else _style = tikzit->styles()->nodeStyle(nm); +} + +NodeStyle *Node::style() const +{ + return _style; +} + +int Node::tikzLine() const +{ + return _tikzLine; +} + +void Node::setTikzLine(int tikzLine) +{ + _tikzLine = tikzLine; +} diff --git a/src/data/node.h b/src/data/node.h index 4d4beee..2a6627e 100644 --- a/src/data/node.h +++ b/src/data/node.h @@ -1,72 +1,72 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - 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 3 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 - along with this program. If not, see . -*/ - -#ifndef NODE_H -#define NODE_H - -#include "graphelementdata.h" -#include "nodestyle.h" - -#include -#include -#include - -class Node : public QObject -{ - Q_OBJECT -public: - explicit Node(QObject *parent = 0); - ~Node(); - - Node *copy(); - - QPointF point() const; - void setPoint(const QPointF &point); - - QString name() const; - void setName(const QString &name); - - QString label() const; - void setLabel(const QString &label); - - GraphElementData *data() const; - void setData(GraphElementData *data); - - QString styleName() const; - void setStyleName(const QString &styleName); - - void attachStyle(); - NodeStyle *style() const; - - int tikzLine() const; - void setTikzLine(int tikzLine); - -signals: - -public slots: - -private: - QPointF _point; - QString _name; - QString _label; - NodeStyle *_style; - GraphElementData *_data; - int _tikzLine; -}; - -#endif // NODE_H +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + 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 3 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 + along with this program. If not, see . +*/ + +#ifndef NODE_H +#define NODE_H + +#include "graphelementdata.h" +#include "nodestyle.h" + +#include +#include +#include + +class Node : public QObject +{ + Q_OBJECT +public: + explicit Node(QObject *parent = 0); + ~Node(); + + Node *copy(); + + QPointF point() const; + void setPoint(const QPointF &point); + + QString name() const; + void setName(const QString &name); + + QString label() const; + void setLabel(const QString &label); + + GraphElementData *data() const; + void setData(GraphElementData *data); + + QString styleName() const; + void setStyleName(const QString &styleName); + + void attachStyle(); + NodeStyle *style() const; + + int tikzLine() const; + void setTikzLine(int tikzLine); + +signals: + +public slots: + +private: + QPointF _point; + QString _name; + QString _label; + NodeStyle *_style; + GraphElementData *_data; + int _tikzLine; +}; + +#endif // NODE_H diff --git a/src/data/nodestyle.cpp b/src/data/nodestyle.cpp index b22105c..ae9f0f7 100644 --- a/src/data/nodestyle.cpp +++ b/src/data/nodestyle.cpp @@ -1,107 +1,107 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - 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 3 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 - along with this program. If not, see . -*/ - -#include "nodestyle.h" -#include - -NodeStyle *noneStyle = new NodeStyle(); - -NodeStyle::NodeStyle() : Style() -{ -} - - -NodeStyle::NodeStyle(QString name, GraphElementData *data): Style(name, data) -{ -} - -QColor NodeStyle::fillColor() const -{ - if (_data == 0) return Qt::white; - - QString col = propertyWithDefault("fill", "white"); - - QColor namedColor(col); - if (namedColor.isValid()) { - return namedColor; - } else { - // TODO: read RGB colors - return QColor(Qt::white); - } -} - -QBrush NodeStyle::brush() const -{ - return QBrush(fillColor()); -} - -NodeStyle::Shape NodeStyle::shape() const -{ - if (_data == 0) return NodeStyle::Circle; - - QString sh = propertyWithDefault("shape", "circle"); - if (sh == "circle") return NodeStyle::Circle; - else if (sh == "rectangle") return NodeStyle::Rectangle; - else return NodeStyle::Circle; -} - -QPainterPath NodeStyle::path() const -{ - QPainterPath pth; - pth.addEllipse(QPointF(0.0f,0.0f), 30.0f, 30.0f); - return pth; -} - -QPainterPath NodeStyle::palettePath() const -{ - return path(); -} - -QIcon NodeStyle::icon() const -{ - // draw an icon matching the style - QPixmap px(100,100); - px.fill(Qt::transparent); - QPainter painter(&px); - QPainterPath pth = path(); - pth.translate(50.0f, 50.0f); - - if (_data == 0) { - QColor c(180,180,200); - painter.setPen(QPen(c)); - painter.setBrush(QBrush(c)); - painter.drawEllipse(QPointF(50.0f,50.0f), 3,3); - - QPen pen(QColor(180,180,220)); - pen.setWidth(3); - QVector p; - p << 2.0 << 2.0; - pen.setDashPattern(p); - painter.setPen(pen); - painter.setBrush(Qt::NoBrush); - painter.drawPath(pth); - } else { - painter.setPen(pen()); - painter.setBrush(brush()); - painter.drawPath(pth); - } - - - return QIcon(px); -} - +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + 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 3 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 + along with this program. If not, see . +*/ + +#include "nodestyle.h" +#include + +NodeStyle *noneStyle = new NodeStyle(); + +NodeStyle::NodeStyle() : Style() +{ +} + + +NodeStyle::NodeStyle(QString name, GraphElementData *data): Style(name, data) +{ +} + +QColor NodeStyle::fillColor() const +{ + if (_data == 0) return Qt::white; + + QString col = propertyWithDefault("fill", "white"); + + QColor namedColor(col); + if (namedColor.isValid()) { + return namedColor; + } else { + // TODO: read RGB colors + return QColor(Qt::white); + } +} + +QBrush NodeStyle::brush() const +{ + return QBrush(fillColor()); +} + +NodeStyle::Shape NodeStyle::shape() const +{ + if (_data == 0) return NodeStyle::Circle; + + QString sh = propertyWithDefault("shape", "circle"); + if (sh == "circle") return NodeStyle::Circle; + else if (sh == "rectangle") return NodeStyle::Rectangle; + else return NodeStyle::Circle; +} + +QPainterPath NodeStyle::path() const +{ + QPainterPath pth; + pth.addEllipse(QPointF(0.0f,0.0f), 30.0f, 30.0f); + return pth; +} + +QPainterPath NodeStyle::palettePath() const +{ + return path(); +} + +QIcon NodeStyle::icon() const +{ + // draw an icon matching the style + QPixmap px(100,100); + px.fill(Qt::transparent); + QPainter painter(&px); + QPainterPath pth = path(); + pth.translate(50.0f, 50.0f); + + if (_data == 0) { + QColor c(180,180,200); + painter.setPen(QPen(c)); + painter.setBrush(QBrush(c)); + painter.drawEllipse(QPointF(50.0f,50.0f), 3,3); + + QPen pen(QColor(180,180,220)); + pen.setWidth(3); + QVector p; + p << 2.0 << 2.0; + pen.setDashPattern(p); + painter.setPen(pen); + painter.setBrush(Qt::NoBrush); + painter.drawPath(pth); + } else { + painter.setPen(pen()); + painter.setBrush(brush()); + painter.drawPath(pth); + } + + + return QIcon(px); +} + diff --git a/src/data/nodestyle.h b/src/data/nodestyle.h index db38a0a..5eeef9b 100644 --- a/src/data/nodestyle.h +++ b/src/data/nodestyle.h @@ -1,51 +1,51 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - 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 3 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 - along with this program. If not, see . -*/ - -#ifndef NODESTYLE_H -#define NODESTYLE_H - -#include "style.h" - -#include -#include -#include -#include -#include - -class NodeStyle : public Style -{ -public: - enum Shape { - Rectangle, UpTriangle, DownTriangle, Circle - }; - - NodeStyle(); - NodeStyle(QString name, GraphElementData *data); - - QColor fillColor() const; - QBrush brush() const; - QPainterPath path() const; - Shape shape() const; - - QPainterPath palettePath() const override; - QIcon icon() const override; -}; - -extern NodeStyle *noneStyle; - -#endif // NODESTYLE_H +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + 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 3 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 + along with this program. If not, see . +*/ + +#ifndef NODESTYLE_H +#define NODESTYLE_H + +#include "style.h" + +#include +#include +#include +#include +#include + +class NodeStyle : public Style +{ +public: + enum Shape { + Rectangle, UpTriangle, DownTriangle, Circle + }; + + NodeStyle(); + NodeStyle(QString name, GraphElementData *data); + + QColor fillColor() const; + QBrush brush() const; + QPainterPath path() const; + Shape shape() const; + + QPainterPath palettePath() const override; + QIcon icon() const override; +}; + +extern NodeStyle *noneStyle; + +#endif // NODESTYLE_H diff --git a/src/data/style.cpp b/src/data/style.cpp index 2811612..41013c0 100644 --- a/src/data/style.cpp +++ b/src/data/style.cpp @@ -1,78 +1,78 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - 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 3 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 - along with this program. If not, see . -*/ - -#include "style.h" - -Style::Style() : _name("none"), _data(0) -{ -} - -Style::Style(QString name, GraphElementData *data) : _name(name), _data(data) -{ -} - -bool Style::isNone() -{ - return _data == 0; -} - -GraphElementData *Style::data() const -{ - return _data; -} - -QString Style::name() const -{ - return _name; -} - -QColor Style::strokeColor() const -{ - if (_data == 0) return Qt::black; - - QString col = propertyWithDefault("draw", "black"); - - QColor namedColor(col); - if (namedColor.isValid()) { - return namedColor; - } else { - // TODO: read RGB colors - return QColor(Qt::black); - } -} - -// TODO -int Style::strokeThickness() const -{ - return 1; -} - -QPen Style::pen() const -{ - QPen p(strokeColor()); - p.setWidthF((float)strokeThickness() * 3.0f); - return p; -} - -QString Style::propertyWithDefault(QString prop, QString def) const -{ - QString val = _data->property("tikzit " + prop); - if (val.isNull()) val = _data->property(prop); - if (val.isNull()) val = def; - return val; -} +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + 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 3 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 + along with this program. If not, see . +*/ + +#include "style.h" + +Style::Style() : _name("none"), _data(0) +{ +} + +Style::Style(QString name, GraphElementData *data) : _name(name), _data(data) +{ +} + +bool Style::isNone() +{ + return _data == 0; +} + +GraphElementData *Style::data() const +{ + return _data; +} + +QString Style::name() const +{ + return _name; +} + +QColor Style::strokeColor() const +{ + if (_data == 0) return Qt::black; + + QString col = propertyWithDefault("draw", "black"); + + QColor namedColor(col); + if (namedColor.isValid()) { + return namedColor; + } else { + // TODO: read RGB colors + return QColor(Qt::black); + } +} + +// TODO +int Style::strokeThickness() const +{ + return 1; +} + +QPen Style::pen() const +{ + QPen p(strokeColor()); + p.setWidthF((float)strokeThickness() * 3.0f); + return p; +} + +QString Style::propertyWithDefault(QString prop, QString def) const +{ + QString val = _data->property("tikzit " + prop); + if (val.isNull()) val = _data->property(prop); + if (val.isNull()) val = def; + return val; +} diff --git a/src/data/style.h b/src/data/style.h index ac7e606..8315e5a 100644 --- a/src/data/style.h +++ b/src/data/style.h @@ -1,54 +1,54 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - 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 3 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 - along with this program. If not, see . -*/ - -#ifndef STYLE_H -#define STYLE_H - - -#include "graphelementdata.h" - -#include -#include -#include -#include -#include - -class Style -{ -public: - Style(); - Style(QString name, GraphElementData *data); - bool isNone(); - - // properties that both edges and nodes have - GraphElementData *data() const; - QString name() const; - QColor strokeColor() const; - int strokeThickness() const; - - // methods that are implemented differently for edges and nodes - virtual QPen pen() const; - virtual QPainterPath path() const = 0; - virtual QPainterPath palettePath() const = 0; - virtual QIcon icon() const = 0; -protected: - QString propertyWithDefault(QString prop, QString def) const; - QString _name; - GraphElementData *_data; -}; -#endif // STYLE_H +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + 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 3 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 + along with this program. If not, see . +*/ + +#ifndef STYLE_H +#define STYLE_H + + +#include "graphelementdata.h" + +#include +#include +#include +#include +#include + +class Style +{ +public: + Style(); + Style(QString name, GraphElementData *data); + bool isNone(); + + // properties that both edges and nodes have + GraphElementData *data() const; + QString name() const; + QColor strokeColor() const; + int strokeThickness() const; + + // methods that are implemented differently for edges and nodes + virtual QPen pen() const; + virtual QPainterPath path() const = 0; + virtual QPainterPath palettePath() const = 0; + virtual QIcon icon() const = 0; +protected: + QString propertyWithDefault(QString prop, QString def) const; + QString _name; + GraphElementData *_data; +}; +#endif // STYLE_H diff --git a/src/data/tikzassembler.cpp b/src/data/tikzassembler.cpp index fed3c39..cd0b517 100644 --- a/src/data/tikzassembler.cpp +++ b/src/data/tikzassembler.cpp @@ -1,72 +1,72 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - 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 3 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 - along with this program. If not, see . -*/ - -#include "tikzassembler.h" - -#include "tikzparserdefs.h" -#include "tikzparser.parser.hpp" -#include "tikzlexer.h" - -int yyparse(void *scanner); - -TikzAssembler::TikzAssembler(Graph *graph, QObject *parent) : - QObject(parent), _graph(graph), _tikzStyles(0) -{ - yylex_init(&scanner); - yyset_extra(this, scanner); -} - -TikzAssembler::TikzAssembler(TikzStyles *tikzStyles, QObject *parent) : - QObject(parent), _graph(0), _tikzStyles(tikzStyles) -{ - yylex_init(&scanner); - yyset_extra(this, scanner); -} - -void TikzAssembler::addNodeToMap(Node *n) { _nodeMap.insert(n->name(), n); } -Node *TikzAssembler::nodeWithName(QString name) { return _nodeMap[name]; } - -bool TikzAssembler::parse(const QString &tikz) -{ - yy_scan_string(tikz.toLatin1().data(), scanner); - int result = yyparse(scanner); - - if (result == 0) return true; - else return false; -} - -Graph *TikzAssembler::graph() const -{ - return _graph; -} - -TikzStyles *TikzAssembler::tikzStyles() const -{ - return _tikzStyles; -} - -bool TikzAssembler::isGraph() const -{ - return _graph != 0; -} - -bool TikzAssembler::isTikzStyles() const -{ - return _tikzStyles != 0; -} - +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + 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 3 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 + along with this program. If not, see . +*/ + +#include "tikzassembler.h" + +#include "tikzparserdefs.h" +#include "tikzparser.parser.hpp" +#include "tikzlexer.h" + +int yyparse(void *scanner); + +TikzAssembler::TikzAssembler(Graph *graph, QObject *parent) : + QObject(parent), _graph(graph), _tikzStyles(0) +{ + yylex_init(&scanner); + yyset_extra(this, scanner); +} + +TikzAssembler::TikzAssembler(TikzStyles *tikzStyles, QObject *parent) : + QObject(parent), _graph(0), _tikzStyles(tikzStyles) +{ + yylex_init(&scanner); + yyset_extra(this, scanner); +} + +void TikzAssembler::addNodeToMap(Node *n) { _nodeMap.insert(n->name(), n); } +Node *TikzAssembler::nodeWithName(QString name) { return _nodeMap[name]; } + +bool TikzAssembler::parse(const QString &tikz) +{ + yy_scan_string(tikz.toLatin1().data(), scanner); + int result = yyparse(scanner); + + if (result == 0) return true; + else return false; +} + +Graph *TikzAssembler::graph() const +{ + return _graph; +} + +TikzStyles *TikzAssembler::tikzStyles() const +{ + return _tikzStyles; +} + +bool TikzAssembler::isGraph() const +{ + return _graph != 0; +} + +bool TikzAssembler::isTikzStyles() const +{ + return _tikzStyles != 0; +} + diff --git a/src/data/tikzassembler.h b/src/data/tikzassembler.h index f5b580c..7b32224 100644 --- a/src/data/tikzassembler.h +++ b/src/data/tikzassembler.h @@ -1,60 +1,60 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - 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 3 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 - along with this program. If not, see . -*/ - -/*! - * Convenience class to hold the parser state while loading tikz graphs or projects. - */ - -#ifndef TIKZASSEMBLER_H -#define TIKZASSEMBLER_H - -#include "node.h" -#include "graph.h" -#include "tikzstyles.h" - -#include -#include - -class TikzAssembler : public QObject -{ - Q_OBJECT -public: - explicit TikzAssembler(Graph *graph, QObject *parent = 0); - explicit TikzAssembler(TikzStyles *tikzStyles, QObject *parent = 0); - void addNodeToMap(Node *n); - Node *nodeWithName(QString name); - bool parse(const QString &tikz); - - Graph *graph() const; - TikzStyles *tikzStyles() const; - bool isGraph() const; - bool isTikzStyles() const; - - -signals: - -public slots: - -private: - QHash _nodeMap; - Graph *_graph; - TikzStyles *_tikzStyles; - void *scanner; -}; - -#endif // TIKZASSEMBLER_H +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + 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 3 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 + along with this program. If not, see . +*/ + +/*! + * Convenience class to hold the parser state while loading tikz graphs or projects. + */ + +#ifndef TIKZASSEMBLER_H +#define TIKZASSEMBLER_H + +#include "node.h" +#include "graph.h" +#include "tikzstyles.h" + +#include +#include + +class TikzAssembler : public QObject +{ + Q_OBJECT +public: + explicit TikzAssembler(Graph *graph, QObject *parent = 0); + explicit TikzAssembler(TikzStyles *tikzStyles, QObject *parent = 0); + void addNodeToMap(Node *n); + Node *nodeWithName(QString name); + bool parse(const QString &tikz); + + Graph *graph() const; + TikzStyles *tikzStyles() const; + bool isGraph() const; + bool isTikzStyles() const; + + +signals: + +public slots: + +private: + QHash _nodeMap; + Graph *_graph; + TikzStyles *_tikzStyles; + void *scanner; +}; + +#endif // TIKZASSEMBLER_H diff --git a/src/data/tikzdocument.cpp b/src/data/tikzdocument.cpp index f685656..5ddec90 100644 --- a/src/data/tikzdocument.cpp +++ b/src/data/tikzdocument.cpp @@ -1,191 +1,191 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - 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 3 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 - along with this program. If not, see . -*/ - -#include -#include -#include -#include -#include -#include - -#include "tikzit.h" -#include "tikzdocument.h" -#include "tikzassembler.h" -#include "mainwindow.h" - -TikzDocument::TikzDocument(QObject *parent) : QObject(parent) -{ - _graph = new Graph(this); - _parseSuccess = true; - _fileName = ""; - _shortName = ""; - _undoStack = new QUndoStack(); - _undoStack->setClean(); -} - -TikzDocument::~TikzDocument() -{ - delete _graph; - delete _undoStack; -} - -QUndoStack *TikzDocument::undoStack() const -{ - return _undoStack; -} - -Graph *TikzDocument::graph() const -{ - return _graph; -} - -QString TikzDocument::tikz() const -{ - return _tikz; -} - -void TikzDocument::open(QString fileName) -{ - _fileName = fileName; - QFile file(fileName); - QFileInfo fi(file); - _shortName = fi.fileName(); - QSettings settings("tikzit", "tikzit"); - settings.setValue("previous-file-path", fi.absolutePath()); - - if (!file.open(QIODevice::ReadOnly)) { -// QMessageBox::critical(this, tr("Error"), -// tr("Could not open file")); - _parseSuccess = false; - return; - } - - QTextStream in(&file); - _tikz = in.readAll(); - file.close(); - - Graph *newGraph = new Graph(this); - TikzAssembler ass(newGraph); - if (ass.parse(_tikz)) { - delete _graph; - _graph = newGraph; - foreach (Node *n, _graph->nodes()) n->attachStyle(); - foreach (Edge *e, _graph->edges()) e->updateControls(); - _parseSuccess = true; - refreshTikz(); - setClean(); - } else { - delete newGraph; - _parseSuccess = false; - } -} - -void TikzDocument::save() { - if (_fileName == "") { - saveAs(); - } else { - MainWindow *win = tikzit->activeWindow(); - if (win != 0 && !win->tikzScene()->enabled()) { - win->tikzScene()->parseTikz(win->tikzSource()); - if (!win->tikzScene()->enabled()) { - auto resp = QMessageBox::question(0, - tr("Tikz failed to parse"), - tr("Cannot save file with invalid TiKZ source. Revert changes and save?")); - if (resp == QMessageBox::Yes) win->tikzScene()->setEnabled(true); - else return; // ABORT the save - } - } - - refreshTikz(); - QFile file(_fileName); - QFileInfo fi(file); - _shortName = fi.fileName(); - QSettings settings("tikzit", "tikzit"); - settings.setValue("previous-file-path", fi.absolutePath()); - - if (file.open(QIODevice::WriteOnly)) { - QTextStream stream(&file); - stream << _tikz; - file.close(); - setClean(); - } else { - QMessageBox::warning(0, "Save Failed", "Could not open file: '" + _fileName + "' for writing."); - } - } -} - -bool TikzDocument::isClean() const -{ - return _undoStack->isClean(); -} - -void TikzDocument::setClean() -{ - _undoStack->setClean(); -} - -void TikzDocument::setGraph(Graph *graph) -{ - _graph = graph; - refreshTikz(); -} - -void TikzDocument::saveAs() { - MainWindow *win = tikzit->activeWindow(); - if (win != 0 && !win->tikzScene()->enabled()) { - win->tikzScene()->parseTikz(win->tikzSource()); - if (!win->tikzScene()->enabled()) { - auto resp = QMessageBox::question(0, - tr("Tikz failed to parse"), - tr("Cannot save file with invalid TiKZ source. Revert changes and save?")); - if (resp == QMessageBox::Yes) win->tikzScene()->setEnabled(true); - else return; // ABORT the save - } - } - - QSettings settings("tikzit", "tikzit"); - QString fileName = QFileDialog::getSaveFileName(tikzit->activeWindow(), - tr("Save File As"), - settings.value("previous-file-path").toString(), - tr("TiKZ Files (*.tikz)")); - - if (!fileName.isEmpty()) { - _fileName = fileName; - save(); - - // clean state might not change, so update title bar manually - tikzit->activeWindow()->updateFileName(); - } -} - -QString TikzDocument::shortName() const -{ - return _shortName; -} - -bool TikzDocument::parseSuccess() const -{ - return _parseSuccess; -} - -void TikzDocument::refreshTikz() -{ - _tikz = _graph->tikz(); - if (MainWindow *w = dynamic_cast(parent())) - w->refreshTikz(); -} +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + 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 3 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 + along with this program. If not, see . +*/ + +#include +#include +#include +#include +#include +#include + +#include "tikzit.h" +#include "tikzdocument.h" +#include "tikzassembler.h" +#include "mainwindow.h" + +TikzDocument::TikzDocument(QObject *parent) : QObject(parent) +{ + _graph = new Graph(this); + _parseSuccess = true; + _fileName = ""; + _shortName = ""; + _undoStack = new QUndoStack(); + _undoStack->setClean(); +} + +TikzDocument::~TikzDocument() +{ + delete _graph; + delete _undoStack; +} + +QUndoStack *TikzDocument::undoStack() const +{ + return _undoStack; +} + +Graph *TikzDocument::graph() const +{ + return _graph; +} + +QString TikzDocument::tikz() const +{ + return _tikz; +} + +void TikzDocument::open(QString fileName) +{ + _fileName = fileName; + QFile file(fileName); + QFileInfo fi(file); + _shortName = fi.fileName(); + QSettings settings("tikzit", "tikzit"); + settings.setValue("previous-file-path", fi.absolutePath()); + + if (!file.open(QIODevice::ReadOnly)) { +// QMessageBox::critical(this, tr("Error"), +// tr("Could not open file")); + _parseSuccess = false; + return; + } + + QTextStream in(&file); + _tikz = in.readAll(); + file.close(); + + Graph *newGraph = new Graph(this); + TikzAssembler ass(newGraph); + if (ass.parse(_tikz)) { + delete _graph; + _graph = newGraph; + foreach (Node *n, _graph->nodes()) n->attachStyle(); + foreach (Edge *e, _graph->edges()) e->updateControls(); + _parseSuccess = true; + refreshTikz(); + setClean(); + } else { + delete newGraph; + _parseSuccess = false; + } +} + +void TikzDocument::save() { + if (_fileName == "") { + saveAs(); + } else { + MainWindow *win = tikzit->activeWindow(); + if (win != 0 && !win->tikzScene()->enabled()) { + win->tikzScene()->parseTikz(win->tikzSource()); + if (!win->tikzScene()->enabled()) { + auto resp = QMessageBox::question(0, + tr("Tikz failed to parse"), + tr("Cannot save file with invalid TiKZ source. Revert changes and save?")); + if (resp == QMessageBox::Yes) win->tikzScene()->setEnabled(true); + else return; // ABORT the save + } + } + + refreshTikz(); + QFile file(_fileName); + QFileInfo fi(file); + _shortName = fi.fileName(); + QSettings settings("tikzit", "tikzit"); + settings.setValue("previous-file-path", fi.absolutePath()); + + if (file.open(QIODevice::WriteOnly)) { + QTextStream stream(&file); + stream << _tikz; + file.close(); + setClean(); + } else { + QMessageBox::warning(0, "Save Failed", "Could not open file: '" + _fileName + "' for writing."); + } + } +} + +bool TikzDocument::isClean() const +{ + return _undoStack->isClean(); +} + +void TikzDocument::setClean() +{ + _undoStack->setClean(); +} + +void TikzDocument::setGraph(Graph *graph) +{ + _graph = graph; + refreshTikz(); +} + +void TikzDocument::saveAs() { + MainWindow *win = tikzit->activeWindow(); + if (win != 0 && !win->tikzScene()->enabled()) { + win->tikzScene()->parseTikz(win->tikzSource()); + if (!win->tikzScene()->enabled()) { + auto resp = QMessageBox::question(0, + tr("Tikz failed to parse"), + tr("Cannot save file with invalid TiKZ source. Revert changes and save?")); + if (resp == QMessageBox::Yes) win->tikzScene()->setEnabled(true); + else return; // ABORT the save + } + } + + QSettings settings("tikzit", "tikzit"); + QString fileName = QFileDialog::getSaveFileName(tikzit->activeWindow(), + tr("Save File As"), + settings.value("previous-file-path").toString(), + tr("TiKZ Files (*.tikz)")); + + if (!fileName.isEmpty()) { + _fileName = fileName; + save(); + + // clean state might not change, so update title bar manually + tikzit->activeWindow()->updateFileName(); + } +} + +QString TikzDocument::shortName() const +{ + return _shortName; +} + +bool TikzDocument::parseSuccess() const +{ + return _parseSuccess; +} + +void TikzDocument::refreshTikz() +{ + _tikz = _graph->tikz(); + if (MainWindow *w = dynamic_cast(parent())) + w->refreshTikz(); +} diff --git a/src/data/tikzdocument.h b/src/data/tikzdocument.h index 0d6b48c..773f369 100644 --- a/src/data/tikzdocument.h +++ b/src/data/tikzdocument.h @@ -1,69 +1,69 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - 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 3 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 - along with this program. If not, see . -*/ - -/*! - * This class contains a tikz Graph, source code, file info, and undo stack. It serves as the model - * in the MVC triple (TikzDocument, TikzView, TikzScene). - */ - -#ifndef TIKZDOCUMENT_H -#define TIKZDOCUMENT_H - -#include "graph.h" - -#include -#include - -class TikzDocument : public QObject -{ - Q_OBJECT -public: - explicit TikzDocument(QObject *parent = 0); - ~TikzDocument(); - - Graph *graph() const; - void setGraph(Graph *graph); - QString tikz() const; - QUndoStack *undoStack() const; - bool parseSuccess() const; - void refreshTikz(); - - void open(QString fileName); - - QString shortName() const; - - void saveAs(); - void save(); - - bool isClean() const; - void setClean(); - -private: - Graph *_graph; - QString _tikz; - QString _fileName; - QString _shortName; - QUndoStack *_undoStack; - bool _parseSuccess; - -signals: - -public slots: -}; - -#endif // TIKZDOCUMENT_H +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + 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 3 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 + along with this program. If not, see . +*/ + +/*! + * This class contains a tikz Graph, source code, file info, and undo stack. It serves as the model + * in the MVC triple (TikzDocument, TikzView, TikzScene). + */ + +#ifndef TIKZDOCUMENT_H +#define TIKZDOCUMENT_H + +#include "graph.h" + +#include +#include + +class TikzDocument : public QObject +{ + Q_OBJECT +public: + explicit TikzDocument(QObject *parent = 0); + ~TikzDocument(); + + Graph *graph() const; + void setGraph(Graph *graph); + QString tikz() const; + QUndoStack *undoStack() const; + bool parseSuccess() const; + void refreshTikz(); + + void open(QString fileName); + + QString shortName() const; + + void saveAs(); + void save(); + + bool isClean() const; + void setClean(); + +private: + Graph *_graph; + QString _tikz; + QString _fileName; + QString _shortName; + QUndoStack *_undoStack; + bool _parseSuccess; + +signals: + +public slots: +}; + +#endif // TIKZDOCUMENT_H diff --git a/src/data/tikzlexer.l b/src/data/tikzlexer.l index 7d7e990..0a67d1d 100644 --- a/src/data/tikzlexer.l +++ b/src/data/tikzlexer.l @@ -1,191 +1,191 @@ -%{ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger, Chris Heunen, - K. Johan Paulsson, Alex Merry - - 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 3 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 - along with this program. If not, see . -*/ - - -/*! - * \file tikzlexer.l - * - * The lexer for tikz input. - */ - -#include "tikzparserdefs.h" -#include "tikzparser.parser.hpp" - -#include - - -#define YY_USER_ACTION \ - yylloc->first_line = yylloc->last_line; \ - yylloc->first_column = yylloc->last_column + 1; \ - yylloc->last_column = yylloc->first_column + yyleng - 1; - -%} - -%option reentrant bison-bridge bison-locations 8bit -%option bison-locations 8bit -%option nounput -%option yylineno -%option noyywrap -%option header-file="tikzlexer.h" -%option extra-type="TikzAssembler *" - -%s props -%s xcoord -%s ycoord -%s noderef - -FLOAT \-?[0-9]*(\.[0-9]+)? - -%% - - /* whitespace is ignored, except for position counting; we don't - count formfeed and vtab as whitespace, because it's not obvious - how they should be dealt with and no-one actually uses them */ - - /* lex will take the longest-matching string */ -\r\n|\r|\n { - yylloc->first_line += 1; - yylloc->last_line = yylloc->first_line; - yylloc->first_column = yylloc->last_column = 0; -} -[\t ]+ { } -%.*$ { } - -\\begin\{tikzpicture\} { return BEGIN_TIKZPICTURE_CMD; } -\\end\{tikzpicture\} { return END_TIKZPICTURE_CMD; } -\\tikzstyle { return TIKZSTYLE_CMD; } -\\begin\{pgfonlayer\} { return BEGIN_PGFONLAYER_CMD; } -\\end\{pgfonlayer\} { return END_PGFONLAYER_CMD; } -\\draw { return DRAW_CMD; } -\\node { return NODE_CMD; } -\\path { return PATH_CMD; } -; { return SEMICOLON; } -= { return EQUALS; } -rectangle { return RECTANGLE; } -node { return NODE; } -at { return AT; } -to { return TO; } - -\([ ]*{FLOAT}[ ]*,[ ]*{FLOAT}[ ]*\) { - yylloc->last_column = yylloc->first_column + 1; - yyless(1); - BEGIN(xcoord); -} -{FLOAT} { - yylval->pt = new QPointF(); - yylval->pt->setX(strtod(yytext,NULL)); - BEGIN(ycoord); -} -, { } -{FLOAT} { - yylval->pt->setY(strtod(yytext,NULL)); -} -\) { - BEGIN(INITIAL); - return TCOORD; -} - - /* when we see "[", change parsing mode */ -\[ /*syntaxhlfix]*/ { - BEGIN(props); - return LEFTBRACKET; -} -= { return EQUALS; } -, { return COMMA; } - /* technically, it is possible to have newlines in the middle of - property names or values, but in practice this is unlikely and - screws up our line counting */ -[^=,\{\] \t\n]([^=,\{\]\n]*[^=,\{\] \t\n])? { - char *str = (char*)malloc(sizeof(char)*yyleng + 1); - strncpy(str, yytext, yyleng + 1); - yylval->str = str; - return PROPSTRING; -} -\] { - BEGIN(INITIAL); - return RIGHTBRACKET; -} - -\( { - BEGIN(noderef); - return LEFTPARENTHESIS; -} -\. { - return FULLSTOP; -} - /* we assume node names (and anchor names) never contain - newlines */ -[^\.\{\)\n]+ { - //qDebug() << "nodename: " << yytext << " size: " << strlen(yytext); - char *str = (char*)malloc(sizeof(char)*yyleng + 1); - strncpy(str, yytext, yyleng+1); - yylval->str = str; - return REFSTRING; -} -\) { - BEGIN(INITIAL); - return RIGHTPARENTHESIS; -} - -\{ { - std::stringstream buf; - unsigned int brace_depth = 1; - unsigned int escape = 0; - while (1) { - char c = yyinput(yyscanner); - // eof reached before closing brace - if (c == '\0' || c == EOF) { - return UNCLOSED_DELIM_STR; - } - - yylloc->last_column += 1; - yyleng += 1; - if (escape) { - escape = 0; - } else if (c == '\\') { - escape = 1; - } else if (c == '{') { - brace_depth++; - } else if (c == '}') { - brace_depth--; - if (brace_depth == 0) break; - } else if (c == '\n') { - yylloc->last_line += 1; - yylloc->last_column = 0; - } - buf << c; - } - - char *str = (char*)malloc(sizeof(char) * yyleng + 1); - strncpy(str, buf.str().c_str(), yyleng + 1); - //str[len] = 0; - yylval->str = str; - //qDebug() << "got delim string: " << str; - return DELIMITEDSTRING; -} - -\\begin { return UNKNOWN_BEGIN_CMD; } -\\end { return UNKNOWN_END_CMD; } -\\[a-zA-Z0-9]+ { return UNKNOWN_CMD; } -[a-zA-Z0-9]+ { return UNKNOWN_STR; } -. { return UNKNOWN_STR; } - - /* vi:ft=lex:noet:ts=4:sts=4:sw=4: - */ +%{ +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger, Chris Heunen, + K. Johan Paulsson, Alex Merry + + 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 3 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 + along with this program. If not, see . +*/ + + +/*! + * \file tikzlexer.l + * + * The lexer for tikz input. + */ + +#include "tikzparserdefs.h" +#include "tikzparser.parser.hpp" + +#include + + +#define YY_USER_ACTION \ + yylloc->first_line = yylloc->last_line; \ + yylloc->first_column = yylloc->last_column + 1; \ + yylloc->last_column = yylloc->first_column + yyleng - 1; + +%} + +%option reentrant bison-bridge bison-locations 8bit +%option bison-locations 8bit +%option nounput +%option yylineno +%option noyywrap +%option header-file="tikzlexer.h" +%option extra-type="TikzAssembler *" + +%s props +%s xcoord +%s ycoord +%s noderef + +FLOAT \-?[0-9]*(\.[0-9]+)? + +%% + + /* whitespace is ignored, except for position counting; we don't + count formfeed and vtab as whitespace, because it's not obvious + how they should be dealt with and no-one actually uses them */ + + /* lex will take the longest-matching string */ +\r\n|\r|\n { + yylloc->first_line += 1; + yylloc->last_line = yylloc->first_line; + yylloc->first_column = yylloc->last_column = 0; +} +[\t ]+ { } +%.*$ { } + +\\begin\{tikzpicture\} { return BEGIN_TIKZPICTURE_CMD; } +\\end\{tikzpicture\} { return END_TIKZPICTURE_CMD; } +\\tikzstyle { return TIKZSTYLE_CMD; } +\\begin\{pgfonlayer\} { return BEGIN_PGFONLAYER_CMD; } +\\end\{pgfonlayer\} { return END_PGFONLAYER_CMD; } +\\draw { return DRAW_CMD; } +\\node { return NODE_CMD; } +\\path { return PATH_CMD; } +; { return SEMICOLON; } += { return EQUALS; } +rectangle { return RECTANGLE; } +node { return NODE; } +at { return AT; } +to { return TO; } + +\([ ]*{FLOAT}[ ]*,[ ]*{FLOAT}[ ]*\) { + yylloc->last_column = yylloc->first_column + 1; + yyless(1); + BEGIN(xcoord); +} +{FLOAT} { + yylval->pt = new QPointF(); + yylval->pt->setX(strtod(yytext,NULL)); + BEGIN(ycoord); +} +, { } +{FLOAT} { + yylval->pt->setY(strtod(yytext,NULL)); +} +\) { + BEGIN(INITIAL); + return TCOORD; +} + + /* when we see "[", change parsing mode */ +\[ /*syntaxhlfix]*/ { + BEGIN(props); + return LEFTBRACKET; +} += { return EQUALS; } +, { return COMMA; } + /* technically, it is possible to have newlines in the middle of + property names or values, but in practice this is unlikely and + screws up our line counting */ +[^=,\{\] \t\n]([^=,\{\]\n]*[^=,\{\] \t\n])? { + char *str = (char*)malloc(sizeof(char)*yyleng + 1); + strncpy(str, yytext, yyleng + 1); + yylval->str = str; + return PROPSTRING; +} +\] { + BEGIN(INITIAL); + return RIGHTBRACKET; +} + +\( { + BEGIN(noderef); + return LEFTPARENTHESIS; +} +\. { + return FULLSTOP; +} + /* we assume node names (and anchor names) never contain + newlines */ +[^\.\{\)\n]+ { + //qDebug() << "nodename: " << yytext << " size: " << strlen(yytext); + char *str = (char*)malloc(sizeof(char)*yyleng + 1); + strncpy(str, yytext, yyleng+1); + yylval->str = str; + return REFSTRING; +} +\) { + BEGIN(INITIAL); + return RIGHTPARENTHESIS; +} + +\{ { + std::stringstream buf; + unsigned int brace_depth = 1; + unsigned int escape = 0; + while (1) { + char c = yyinput(yyscanner); + // eof reached before closing brace + if (c == '\0' || c == EOF) { + return UNCLOSED_DELIM_STR; + } + + yylloc->last_column += 1; + yyleng += 1; + if (escape) { + escape = 0; + } else if (c == '\\') { + escape = 1; + } else if (c == '{') { + brace_depth++; + } else if (c == '}') { + brace_depth--; + if (brace_depth == 0) break; + } else if (c == '\n') { + yylloc->last_line += 1; + yylloc->last_column = 0; + } + buf << c; + } + + char *str = (char*)malloc(sizeof(char) * yyleng + 1); + strncpy(str, buf.str().c_str(), yyleng + 1); + //str[len] = 0; + yylval->str = str; + //qDebug() << "got delim string: " << str; + return DELIMITEDSTRING; +} + +\\begin { return UNKNOWN_BEGIN_CMD; } +\\end { return UNKNOWN_END_CMD; } +\\[a-zA-Z0-9]+ { return UNKNOWN_CMD; } +[a-zA-Z0-9]+ { return UNKNOWN_STR; } +. { return UNKNOWN_STR; } + + /* vi:ft=lex:noet:ts=4:sts=4:sw=4: + */ diff --git a/src/data/tikzparser.y b/src/data/tikzparser.y index 6e708a3..3dfb66f 100644 --- a/src/data/tikzparser.y +++ b/src/data/tikzparser.y @@ -1,284 +1,284 @@ -%{ -/*! - * \file tikzparser.y - * - * The parser for tikz input. - */ - -/* - * Copyright 2010 Chris Heunen - * Copyright 2010-2017 Aleks Kissinger - * Copyright 2013 K. Johan Paulsson - * Copyright 2013 Alex Merry - * - * 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 - * along with this program. If not, see . - */ - - -#include "tikzparserdefs.h" -%} - -/* we use features added to bison 2.4 */ -%require "2.3" - -%error-verbose -/* enable maintaining locations for better error messages */ -%locations -/* the name of the header file */ -/*%defines "common/tikzparser.h"*/ -/* make it re-entrant (no global variables) */ -%pure-parser -/* We use a pure (re-entrant) lexer. This means yylex - will take a void* (opaque) type to maintain its state */ -%lex-param {void *scanner} -/* Since this parser is also pure, yyparse needs to take - that lexer state as an argument */ -%parse-param {void *scanner} - -/* possible data types for semantic values */ -%union { - char *str; - GraphElementProperty *prop; - GraphElementData *data; - Node *node; - QPointF *pt; - struct noderef noderef; -} - -%{ -#include "node.h" -#include "edge.h" -#include "graphelementdata.h" -#include "graphelementproperty.h" - -#include "tikzlexer.h" -#include "tikzassembler.h" -/* the assembler (used by this parser) is stored in the lexer - state as "extra" data */ -#define assembler yyget_extra(scanner) - -/* pass errors off to the assembler */ -void yyerror(YYLTYPE *yylloc, void *scanner, const char *str) { - // TODO: implement reportError() - //assembler->reportError(str, yylloc); - qDebug() << "\nparse error: " << str << " line:" << yylloc->first_line; -} -%} - -/* yyloc is set up with first_column = last_column = 1 by default; - however, it makes more sense to think of us being "before the - start of the line" before we parse anything */ -%initial-action { - yylloc.first_column = yylloc.last_column = 0; -} - - -%token BEGIN_TIKZPICTURE_CMD "\\begin{tikzpicture}" -%token END_TIKZPICTURE_CMD "\\end{tikzpicture}" -%token TIKZSTYLE_CMD "\\tikzstyle" -%token BEGIN_PGFONLAYER_CMD "\\begin{pgfonlayer}" -%token END_PGFONLAYER_CMD "\\end{pgfonlayer}" -%token DRAW_CMD "\\draw" -%token NODE_CMD "\\node" -%token PATH_CMD "\\path" -%token RECTANGLE "rectangle" -%token NODE "node" -%token AT "at" -%token TO "to" -%token SEMICOLON ";" -%token COMMA "," - -%token LEFTPARENTHESIS "(" -%token RIGHTPARENTHESIS ")" -%token LEFTBRACKET "[" -%token RIGHTBRACKET "]" -%token FULLSTOP "." -%token EQUALS "=" -%token TCOORD "coordinate" -%token PROPSTRING "key/value string" -%token REFSTRING "string" -%token DELIMITEDSTRING "{-delimited string" - -%token UNKNOWN_BEGIN_CMD "unknown \\begin command" -%token UNKNOWN_END_CMD "unknown \\end command" -%token UNKNOWN_CMD "unknown latex command" -%token UNKNOWN_STR "unknown string" -%token UNCLOSED_DELIM_STR "unclosed {-delimited string" - -%type nodename -%type optanchor -%type val -%type property -%type extraproperties -%type properties -%type optproperties -%type optedgenode -%type noderef -%type optnoderef - -%% - - -tikz: tikzstyles | tikzpicture; - -tikzstyles: tikzstyles tikzstyle | ; -tikzstyle: "\\tikzstyle" DELIMITEDSTRING "=" "[" properties "]" - { - if (assembler->isTikzStyles()) { - assembler->tikzStyles()->addStyle(QString($2), $5); - } - } - -tikzpicture: "\\begin{tikzpicture}" optproperties tikzcmds "\\end{tikzpicture}" - { - if (assembler->isGraph() && $2) { - assembler->graph()->setData($2); - } - }; -tikzcmds: tikzcmds tikzcmd | ; -tikzcmd: node | edge | boundingbox | ignore; - -ignore: "\\begin{pgfonlayer}" DELIMITEDSTRING | "\\end{pgfonlayer}"; - -optproperties: - "[" "]" - { $$ = 0; } - | "[" properties "]" - { $$ = $2; } - | { $$ = 0; }; -properties: extraproperties property - { - $1->add(*$2); - delete $2; - $$ = $1; - }; -extraproperties: - extraproperties property "," - { - $1->add(*$2); - delete $2; - $$ = $1; - } - | { $$ = new GraphElementData(); }; -property: - val "=" val - { - GraphElementProperty *p = new GraphElementProperty(QString($1),QString($3)); - free($1); - free($3); - $$ = p; - } - | val - { - GraphElementProperty *a = new GraphElementProperty(QString($1)); - free($1); - $$ = a; - }; -val: PROPSTRING { $$ = $1; } | DELIMITEDSTRING { $$ = $1; }; - -nodename: "(" REFSTRING ")" { $$ = $2; }; -node: "\\node" optproperties nodename "at" TCOORD DELIMITEDSTRING ";" - { - Node *node = new Node(); - - if ($2) { - node->setData($2); - } - //qDebug() << "node name: " << $3; - node->setName(QString($3)); - node->setLabel(QString($6)); - free($3); - free($6); - - node->setPoint(*$5); - delete $5; - - assembler->graph()->addNode(node); - assembler->addNodeToMap(node); - }; - -optanchor: { $$ = 0; } | "." REFSTRING { $$ = $2; }; -noderef: "(" REFSTRING optanchor ")" - { - $$.node = assembler->nodeWithName(QString($2)); - free($2); - $$.anchor = $3; - }; -optnoderef: - noderef { $$ = $1; } - | "(" ")" { $$.node = 0; $$.anchor = 0; } -optedgenode: - { $$ = 0; } - | "node" optproperties DELIMITEDSTRING - { - $$ = new Node(); - if ($2) - $$->setData($2); - $$->setLabel(QString($3)); - free($3); - } -edge: "\\draw" optproperties noderef "to" optedgenode optnoderef ";" - { - Node *s; - Node *t; - - s = $3.node; - - if ($6.node) { - t = $6.node; - } else { - t = s; - } - - // if the source or the target of the edge doesn't exist, quietly ignore it. - if (s != 0 && t != 0) { - Edge *edge = new Edge(s, t); - if ($2) { - edge->setData($2); - edge->setAttributesFromData(); - } - - if ($5) - edge->setEdgeNode($5); - if ($3.anchor) { - edge->setSourceAnchor(QString($3.anchor)); - free($3.anchor); - } - - if ($6.node) { - if ($6.anchor) { - edge->setTargetAnchor(QString($6.anchor)); - free($6.anchor); - } - } else { - edge->setTargetAnchor(edge->sourceAnchor()); - } - - assembler->graph()->addEdge(edge); - } - }; - -ignoreprop: val | val "=" val; -ignoreprops: ignoreprop ignoreprops | ; -optignoreprops: "[" ignoreprops "]"; -boundingbox: - "\\path" optignoreprops TCOORD "rectangle" TCOORD ";" - { - assembler->graph()->setBbox(QRectF(*$3, *$5)); - delete $3; - delete $5; - }; - -/* vi:ft=yacc:noet:ts=4:sts=4:sw=4 -*/ +%{ +/*! + * \file tikzparser.y + * + * The parser for tikz input. + */ + +/* + * Copyright 2010 Chris Heunen + * Copyright 2010-2017 Aleks Kissinger + * Copyright 2013 K. Johan Paulsson + * Copyright 2013 Alex Merry + * + * 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 + * along with this program. If not, see . + */ + + +#include "tikzparserdefs.h" +%} + +/* we use features added to bison 2.4 */ +%require "2.3" + +%error-verbose +/* enable maintaining locations for better error messages */ +%locations +/* the name of the header file */ +/*%defines "common/tikzparser.h"*/ +/* make it re-entrant (no global variables) */ +%pure-parser +/* We use a pure (re-entrant) lexer. This means yylex + will take a void* (opaque) type to maintain its state */ +%lex-param {void *scanner} +/* Since this parser is also pure, yyparse needs to take + that lexer state as an argument */ +%parse-param {void *scanner} + +/* possible data types for semantic values */ +%union { + char *str; + GraphElementProperty *prop; + GraphElementData *data; + Node *node; + QPointF *pt; + struct noderef noderef; +} + +%{ +#include "node.h" +#include "edge.h" +#include "graphelementdata.h" +#include "graphelementproperty.h" + +#include "tikzlexer.h" +#include "tikzassembler.h" +/* the assembler (used by this parser) is stored in the lexer + state as "extra" data */ +#define assembler yyget_extra(scanner) + +/* pass errors off to the assembler */ +void yyerror(YYLTYPE *yylloc, void *scanner, const char *str) { + // TODO: implement reportError() + //assembler->reportError(str, yylloc); + qDebug() << "\nparse error: " << str << " line:" << yylloc->first_line; +} +%} + +/* yyloc is set up with first_column = last_column = 1 by default; + however, it makes more sense to think of us being "before the + start of the line" before we parse anything */ +%initial-action { + yylloc.first_column = yylloc.last_column = 0; +} + + +%token BEGIN_TIKZPICTURE_CMD "\\begin{tikzpicture}" +%token END_TIKZPICTURE_CMD "\\end{tikzpicture}" +%token TIKZSTYLE_CMD "\\tikzstyle" +%token BEGIN_PGFONLAYER_CMD "\\begin{pgfonlayer}" +%token END_PGFONLAYER_CMD "\\end{pgfonlayer}" +%token DRAW_CMD "\\draw" +%token NODE_CMD "\\node" +%token PATH_CMD "\\path" +%token RECTANGLE "rectangle" +%token NODE "node" +%token AT "at" +%token TO "to" +%token SEMICOLON ";" +%token COMMA "," + +%token LEFTPARENTHESIS "(" +%token RIGHTPARENTHESIS ")" +%token LEFTBRACKET "[" +%token RIGHTBRACKET "]" +%token FULLSTOP "." +%token EQUALS "=" +%token TCOORD "coordinate" +%token PROPSTRING "key/value string" +%token REFSTRING "string" +%token DELIMITEDSTRING "{-delimited string" + +%token UNKNOWN_BEGIN_CMD "unknown \\begin command" +%token UNKNOWN_END_CMD "unknown \\end command" +%token UNKNOWN_CMD "unknown latex command" +%token UNKNOWN_STR "unknown string" +%token UNCLOSED_DELIM_STR "unclosed {-delimited string" + +%type nodename +%type optanchor +%type val +%type property +%type extraproperties +%type properties +%type optproperties +%type optedgenode +%type noderef +%type optnoderef + +%% + + +tikz: tikzstyles | tikzpicture; + +tikzstyles: tikzstyles tikzstyle | ; +tikzstyle: "\\tikzstyle" DELIMITEDSTRING "=" "[" properties "]" + { + if (assembler->isTikzStyles()) { + assembler->tikzStyles()->addStyle(QString($2), $5); + } + } + +tikzpicture: "\\begin{tikzpicture}" optproperties tikzcmds "\\end{tikzpicture}" + { + if (assembler->isGraph() && $2) { + assembler->graph()->setData($2); + } + }; +tikzcmds: tikzcmds tikzcmd | ; +tikzcmd: node | edge | boundingbox | ignore; + +ignore: "\\begin{pgfonlayer}" DELIMITEDSTRING | "\\end{pgfonlayer}"; + +optproperties: + "[" "]" + { $$ = 0; } + | "[" properties "]" + { $$ = $2; } + | { $$ = 0; }; +properties: extraproperties property + { + $1->add(*$2); + delete $2; + $$ = $1; + }; +extraproperties: + extraproperties property "," + { + $1->add(*$2); + delete $2; + $$ = $1; + } + | { $$ = new GraphElementData(); }; +property: + val "=" val + { + GraphElementProperty *p = new GraphElementProperty(QString($1),QString($3)); + free($1); + free($3); + $$ = p; + } + | val + { + GraphElementProperty *a = new GraphElementProperty(QString($1)); + free($1); + $$ = a; + }; +val: PROPSTRING { $$ = $1; } | DELIMITEDSTRING { $$ = $1; }; + +nodename: "(" REFSTRING ")" { $$ = $2; }; +node: "\\node" optproperties nodename "at" TCOORD DELIMITEDSTRING ";" + { + Node *node = new Node(); + + if ($2) { + node->setData($2); + } + //qDebug() << "node name: " << $3; + node->setName(QString($3)); + node->setLabel(QString($6)); + free($3); + free($6); + + node->setPoint(*$5); + delete $5; + + assembler->graph()->addNode(node); + assembler->addNodeToMap(node); + }; + +optanchor: { $$ = 0; } | "." REFSTRING { $$ = $2; }; +noderef: "(" REFSTRING optanchor ")" + { + $$.node = assembler->nodeWithName(QString($2)); + free($2); + $$.anchor = $3; + }; +optnoderef: + noderef { $$ = $1; } + | "(" ")" { $$.node = 0; $$.anchor = 0; } +optedgenode: + { $$ = 0; } + | "node" optproperties DELIMITEDSTRING + { + $$ = new Node(); + if ($2) + $$->setData($2); + $$->setLabel(QString($3)); + free($3); + } +edge: "\\draw" optproperties noderef "to" optedgenode optnoderef ";" + { + Node *s; + Node *t; + + s = $3.node; + + if ($6.node) { + t = $6.node; + } else { + t = s; + } + + // if the source or the target of the edge doesn't exist, quietly ignore it. + if (s != 0 && t != 0) { + Edge *edge = new Edge(s, t); + if ($2) { + edge->setData($2); + edge->setAttributesFromData(); + } + + if ($5) + edge->setEdgeNode($5); + if ($3.anchor) { + edge->setSourceAnchor(QString($3.anchor)); + free($3.anchor); + } + + if ($6.node) { + if ($6.anchor) { + edge->setTargetAnchor(QString($6.anchor)); + free($6.anchor); + } + } else { + edge->setTargetAnchor(edge->sourceAnchor()); + } + + assembler->graph()->addEdge(edge); + } + }; + +ignoreprop: val | val "=" val; +ignoreprops: ignoreprop ignoreprops | ; +optignoreprops: "[" ignoreprops "]"; +boundingbox: + "\\path" optignoreprops TCOORD "rectangle" TCOORD ";" + { + assembler->graph()->setBbox(QRectF(*$3, *$5)); + delete $3; + delete $5; + }; + +/* vi:ft=yacc:noet:ts=4:sts=4:sw=4 +*/ diff --git a/src/data/tikzparserdefs.h b/src/data/tikzparserdefs.h index a5e77be..02743fe 100644 --- a/src/data/tikzparserdefs.h +++ b/src/data/tikzparserdefs.h @@ -1,40 +1,40 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - 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 3 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 - along with this program. If not, see . -*/ - -#ifndef TIKZPARSERDEFS_H -#define TIKZPARSERDEFS_H - -#define YY_NO_UNISTD_H 1 - -#include "graphelementproperty.h" -#include "graphelementdata.h" -#include "node.h" -#include "tikzassembler.h" - -#include -#include -#include - -struct noderef { - Node *node; - char *anchor; -}; - -inline int isatty(int) { return 0; } - -#endif // TIKZPARSERDEFS_H +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + 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 3 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 + along with this program. If not, see . +*/ + +#ifndef TIKZPARSERDEFS_H +#define TIKZPARSERDEFS_H + +#define YY_NO_UNISTD_H 1 + +#include "graphelementproperty.h" +#include "graphelementdata.h" +#include "node.h" +#include "tikzassembler.h" + +#include +#include +#include + +struct noderef { + Node *node; + char *anchor; +}; + +inline int isatty(int) { return 0; } + +#endif // TIKZPARSERDEFS_H diff --git a/src/data/tikzstyles.cpp b/src/data/tikzstyles.cpp index a924c01..addd464 100644 --- a/src/data/tikzstyles.cpp +++ b/src/data/tikzstyles.cpp @@ -1,71 +1,71 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - 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 3 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 - along with this program. If not, see . -*/ - -#include "tikzstyles.h" -#include "nodestyle.h" - -#include - -TikzStyles::TikzStyles(QObject *parent) : QObject(parent) -{ - -} - -NodeStyle *TikzStyles::nodeStyle(QString name) const -{ - foreach (NodeStyle *s , _nodeStyles) - if (s->name() == name) return s; - return noneStyle; -} - -EdgeStyle *TikzStyles::edgeStyle(QString name) const -{ - foreach (EdgeStyle *s , _edgeStyles) - if (s->name() == name) return s; - return noneEdgeStyle; -} - -QVector TikzStyles::nodeStyles() const -{ - return _nodeStyles; -} - -void TikzStyles::clear() -{ - _nodeStyles.clear(); - _edgeStyles.clear(); -} - -QVector TikzStyles::edgeStyles() const -{ - return _edgeStyles; -} - -void TikzStyles::addStyle(QString name, GraphElementData *data) -{ - if (data->atom("-") || data->atom("->") || data->atom("-|") || - data->atom("<-") || data->atom("<->") || data->atom("<-|") || - data->atom("|-") || data->atom("|->") || data->atom("|-|")) - { // edge style - qDebug() << "got edge style" << name; - _edgeStyles << new EdgeStyle(name, data); - } else { // node style - qDebug() << "got node style" << name; - _nodeStyles << new NodeStyle(name, data); - } -} +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + 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 3 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 + along with this program. If not, see . +*/ + +#include "tikzstyles.h" +#include "nodestyle.h" + +#include + +TikzStyles::TikzStyles(QObject *parent) : QObject(parent) +{ + +} + +NodeStyle *TikzStyles::nodeStyle(QString name) const +{ + foreach (NodeStyle *s , _nodeStyles) + if (s->name() == name) return s; + return noneStyle; +} + +EdgeStyle *TikzStyles::edgeStyle(QString name) const +{ + foreach (EdgeStyle *s , _edgeStyles) + if (s->name() == name) return s; + return noneEdgeStyle; +} + +QVector TikzStyles::nodeStyles() const +{ + return _nodeStyles; +} + +void TikzStyles::clear() +{ + _nodeStyles.clear(); + _edgeStyles.clear(); +} + +QVector TikzStyles::edgeStyles() const +{ + return _edgeStyles; +} + +void TikzStyles::addStyle(QString name, GraphElementData *data) +{ + if (data->atom("-") || data->atom("->") || data->atom("-|") || + data->atom("<-") || data->atom("<->") || data->atom("<-|") || + data->atom("|-") || data->atom("|->") || data->atom("|-|")) + { // edge style + qDebug() << "got edge style" << name; + _edgeStyles << new EdgeStyle(name, data); + } else { // node style + qDebug() << "got node style" << name; + _nodeStyles << new NodeStyle(name, data); + } +} diff --git a/src/data/tikzstyles.h b/src/data/tikzstyles.h index 0f7cce1..da9a05f 100644 --- a/src/data/tikzstyles.h +++ b/src/data/tikzstyles.h @@ -1,51 +1,51 @@ -/* - TikZiT - a GUI diagram editor for TikZ - Copyright (C) 2018 Aleks Kissinger - - 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 3 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 - along with this program. If not, see . -*/ - -#ifndef PROJECT_H -#define PROJECT_H - -#include "graphelementdata.h" -#include "nodestyle.h" -#include "edgestyle.h" - -#include -#include - -class TikzStyles : public QObject -{ - Q_OBJECT -public: - explicit TikzStyles(QObject *parent = 0); - void addStyle(QString name, GraphElementData *data); - - NodeStyle *nodeStyle(QString name) const; - EdgeStyle *edgeStyle(QString name) const; - QVector nodeStyles() const; - QVector edgeStyles() const; - void clear(); - -signals: - -public slots: - -private: - QVector _nodeStyles; - QVector _edgeStyles; -}; - -#endif // PROJECT_H +/* + TikZiT - a GUI diagram editor for TikZ + Copyright (C) 2018 Aleks Kissinger + + 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 3 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 + along with this program. If not, see . +*/ + +#ifndef PROJECT_H +#define PROJECT_H + +#include "graphelementdata.h" +#include "nodestyle.h" +#include "edgestyle.h" + +#include +#include + +class TikzStyles : public QObject +{ + Q_OBJECT +public: + explicit TikzStyles(QObject *parent = 0); + void addStyle(QString name, GraphElementData *data); + + NodeStyle *nodeStyle(QString name) const; + EdgeStyle *edgeStyle(QString name) const; + QVector nodeStyles() const; + QVector edgeStyles() const; + void clear(); + +signals: + +public slots: + +private: + QVector _nodeStyles; + QVector _edgeStyles; +}; + +#endif // PROJECT_H -- cgit v1.2.3